# fit a curve in a three dimensional space

I have a list of points of a curve in a three dimensional space, like

myData =
{{1.6251942652167208, 3414.632234882431, 3.248326448352207},
{0.195563463104691, 32.18966154343482, 1.1454060351007385},
{0.17904199044243319, 14.25108939238815, 0.9423477799753123},
{0.170816821901991, 8.653164633472851, 0.7958880823665402},
{0.15676037756308206, 5.631156542779637, 0.67467521725227},
{0.1548948722263085, 4.270874169070245, 0.6275611866853114},
{0.1876950201556172, 4.308999312640106, 0.6090637255823652},
{0.16188251254916763, 2.9764924022024317, 0.5292892925723116},
{0.17262610022897934, 2.739111371641244, 0.52653513586836},
{0.16954431585785373, 2.3070638999549393, 0.49560804724631763},
{0.2097961985882085, 2.6534757543854317, 0.5487657657669014},
{0.19081633352127408, 2.0852454796400357, 0.514435548916157},
{0.19563129613920563, 1.917093872159669, 0.4743406166681895},
{0.21254024573386504, 1.9251337728677473, 0.485236735240245},
{0.21896472970440534, 1.8147535334973488, 0.46531629302089494},
{0.20466136180653818, 1.513876366963674, 0.4249037110237554},
{0.21855394267841366, 1.519108716384235, 0.4380750296933395},
{0.23565318703002316, 1.5488572100526539, 0.44631964709969185},
{0.2380818528018018, 1.4529671243699986, 0.42553379428103266},
{0.2424842011874948, 1.389721482236748, 0.4345346021692877},
{0.2647317878191315, 1.4605691656957687, 0.43267419256049483},
{0.2632502748033041, 1.3557447019366855, 0.4286184053606104},
{0.27205729604073775, 1.334394688581283, 0.44259414855715523},
{0.2793705082711959, 1.302387809445032, 0.4336404208867536},
{0.2837573939406187, 1.2544604741697558, 0.42970441420505734},
{0.2948407139307023, 1.251503834903687, 0.4289108411034688},
{0.29600086351343347, 1.1920618765471473, 0.42889878404407833},
{0.29465197778349606, 1.1243426155800962, 0.4276172983591667},
{0.30183374846249794, 1.1064964396078605, 0.42772557494175767},
{0.30918455260251276, 1.0893160114201885, 0.4275101914583863},
{0.3170183678910846, 1.0761991260380923, 0.4251450946217794},
{0.3170471652361686, 1.028070998453355, 0.4231589533788725},
{0.33509119696542056, 1.062744456154385, 0.4233345521815623},
{0.32971337187673616, 0.9954325606304446, 0.4231326015290622},
{0.33595705730728015, 0.979557033300735, 0.4236769992893109},
{0.3436253098086924, 0.9714372846864234, 0.4241910609852374},
{0.34812463781047914, 0.949934939902976, 0.42012852465803996},
{0.3563732253707738, 0.9443465112229241, 0.4204752685781463},
{0.35992684291158533, 0.9221331266260643, 0.41804460944990646},
{0.36120796960334306, 0.893126929139083, 0.41819781912012344},
{0.3694695389695183, 0.8578713443146384, 0.4150160053145223},
{0.37334083248099226, 0.8414330588993054, 0.4145221485938744},
{0.3766063600562105, 0.8812611721272469, 0.45266007028291844},
{0.3835672074215254, 0.8426364383173903, 0.44224264257818485},
{0.3925576360242645, 0.8145071347303069, 0.441619765516166},
{0.3952083972535039, 0.7698172682169502, 0.4289584794098478},
{0.40767794715674194, 0.7561905560105875, 0.42830082380993906},
{0.4139609495348973, 0.7284690866030674, 0.42802517746189234},
{0.4199909107710205, 0.7017646393366863, 0.4245332938666336},
{0.42517695763043706, 0.6756040929172838, 0.41901542028878747},
{0.438909457948436, 0.6699655678281783, 0.41733783818556264},
{0.44563579799220726, 0.6499029238980055, 0.4129281969548992},
{0.4473498530318954, 0.6211332659501384, 0.4089614451608291},
{0.45464041389498117, 0.6051969313774956, 0.4050849964713832},
{0.46156953220721025, 0.5899702211293141, 0.4029806473833252},
{0.47141055300556484, 0.5805373200701324, 0.39970427922756985},
{0.4792326437523886, 0.5681016242905145, 0.39694835543120627},
{0.4853330654106727, 0.553725319161017, 0.393182829103135},
{0.49135512137375686, 0.5399417830238199, 0.3901371989617769},
{0.5006324150392757, 0.5320562690230357, 0.3875692692973447},
{0.5064951595246885, 0.5194105475320817, 0.3832282043244645},
{0.5115547319598217, 0.5062662671288428, 0.3811347260859499},
{0.51504804958564, 0.4917529304140576, 0.3775795425712839},
{0.5220718511737211, 0.48266019418477496, 0.37470445520090895},
{0.5312779766503062, 0.47705149397591645, 0.37098468508988963},
{0.5324554882538403, 0.4612891859386048, 0.36767364179185347},
{0.5377840374755473, 0.451700594900957, 0.3651018926671713},
{0.5450134070805016, 0.44432218995571343, 0.3621032659850748},
{0.5532192176564933, 0.438742917967833, 0.35988610407498006},
{0.5559200803701375, 0.4272035754877022, 0.3562923772639558},
{0.5632612273324766, 0.42125311233985596, 0.35442749937954365},
{0.5695771900612702, 0.4143325143071145, 0.35207878660073166}}


I want to find and plot a find of this curve in the space.

I don't have a explicit form of the real function, but I know that it is regular enough to allow a polynomial expansion in the interval of interest.

Is this possible?

If you don't have a clue about the underlying model of your data, why don't you interpolate it then?

With[{ip = ListInterpolation[#, {{0, 1}}] & /@ Transpose[myData]},
func[t_] := Through[ip[t]]
];

ParametricPlot3D[func[t], {t, 0, 1}, BoxRatios -> 1]


With this you have a function and you can evaluate your curve everywhere inside the defined interval.

• sorry, I was inaccurate. I indeed have equations for that curve, but are so complex that I can't get an explicit form to fit. I know that the curve is indeed very regular in that interval, and a polynomial expansion is surely possible. Nevertheless I do not know how many terms I need to include in the fit, but in my case I have other fixed point in that space, so I can get the accuracy of the result a posteriori. Oct 21, 2013 at 12:21
• @Fabrizio What "other fixed point" do you have? Oct 21, 2013 at 14:07
• @belisarius I have two points (with much more accuracy) that I know must belong to the curve, but I don't want necessarily include them in the fit, because are obtained with a different method. But because they are far enough apart, I can use them to evaluate in some sense the accuracy of the fit. Oct 21, 2013 at 18:20
• @Fabrizio But you should include them in your question. It's the only way to let us check the fit ... Oct 21, 2013 at 18:33
• @belisarius I partially disagree. I asked just for a good fit of that list of points, that it is in general different from a good fit of the underlying model (and that it's not part of my question). Oct 21, 2013 at 18:42

I am not sure I understand what the problem is with @hairutan's answer. If you want to visually inspect the data and select a model to fit it based on the model not being too complex (rather than the goodness of the fit), you can find a parametric curve that does that by fitting each dimension separately and experiment how many terms to include in each dimension.

p[order1_, order2_, order3_] := Block[{f1, f2, f3, model},
model[order_] := Flatten@Table[{x^n, x^(-n)}, {n, 0, order}];
f1 = Fit[myData[[All, 1]], model[order1], x];
f2 = Fit[myData[[All, 2]], model[order2], x];
f3 = Fit[myData[[All, 3]], model[order3], x];
{f1, f2, f3}];


Here, I've added negative powers to improve the fit.

Manipulate[
TableForm@{Show[{ListPointPlot3D[myData, PlotRange -> All,
PlotStyle -> Directive[{Red, PointSize[.015]}]],
ParametricPlot3D[
Evaluate@p[n1, n2, n3], {x, 1, Length[myData]},
PlotStyle -> Thick]},
BoxRatios -> 1, PlotRange -> All],
"{n1,n2,n3}=" <> ToString@{n1, n2, n3}},
{n1, 1, 6, 1}, {n2, 1, 6, 1}, {n3, 1, 6, 1}]


After some experimentation p[3,4,3] seems to fit OK:

but I think that's deceptive (owing to the aspect ratio of the box etc). In fact, The difference in variance between columns of your data suggests you may want to take their logarithm before fitting. In any case, unless you give a little more on what model you expect I can't see how any answer will be better than ListInterpolation (unless someone finds a way to do something really fancy)

• the problem with @hairutan's answer it's that it is incomplete and I misunderstood his hint. Your answer made it clear to me, and yes, it's enough to solve my problem. Oct 21, 2013 at 18:35