Re: surface fitting question
- To: mathgroup at smc.vnet.net
- Subject: [mg61341] Re: surface fitting question
- From: Jean-Marc Gulliet <jeanmarc.gulliet at gmail.com>
- Date: Sun, 16 Oct 2005 00:17:56 -0400 (EDT)
- Organization: The Open University, Milton Keynes, UK
- References: <diprth$hpc$1@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
Ralph Smith wrote: > I have this data in a file. It is a 2D table that 26 rows and 17 columns. > > | > ----------------------------------------------------------------------- > | 0.000 0.000 0.000 ... 0.000 0.000 0.000 > | 0.050 0.050 0.155 ... 16.409 19.375 20.156 > | . > | . > | . > | 47.500 50.000 55.000 ... 2017.500 2075.580 2182.765 > ----------------------------------------------------------------------- > | > > I would like to find an equation that describes this surface using > mathematica. I think that 3rd degree polynomials would be what I'm looking > for. So, maybe > data[x,y] = ax^3 + bx^2 + cx + d + ey^3 + fy^2 + gy > > I've seen and example that uses Fit[], so I think this can be done, but I'm > a novice at mathematica and don't know how to set this problem up. I have been > able to fit a polynomial to curve data, but now I need to fit a surface. > > thanks, > Ralph > > > Hi Ralph, Just to complete my previous answer. Assuming that the x-, y-coordinates are the row and column numbers respectively, you could use the following process -- summarized as one line at the end -- to transform your data set into a list of three coordinates as required by *Fit*. First we define two parameters containing the max number of rows and columns to be found in the data set: In[1]:= nRow = 5; nCol = 4; Then we generate some sample data In[3]:= data = Table[Table[Random[Real, {0, 2500}], {nCol}], {nRow}] Out[3]= {{1069.45,1951.84,2288.3,1903.68},{1031.85,2048.23,1035.9,1059.63},{ 893.347,883.253,423.135,514.3},{1729.97,1901.79,1513.78,2397.94},{ 2402.13,1341.47,1300.56,883.788}} Then we use several built-in Mathematica function to insert the x- and y-coordinates In[4]:= Flatten[data] Out[4]= {1069.45,1951.84,2288.3,1903.68,1031.85,2048.23,1035.9,1059.63,893.347,883.\ 253,423.135,514.3,1729.97,1901.79,1513.78,2397.94,2402.13,1341.47,1300.56,883.\ 788} In[5]:= xycoord = Table[Table[{i, j}, {j, nCol}], {i, nRow}] Out[5]= {{{1,1},{1,2},{1,3},{1,4}},{{2,1},{2,2},{2,3},{2,4}},{{3,1},{3,2},{ 3,3},{3,4}},{{4,1},{4,2},{4,3},{4,4}},{{5,1},{5,2},{5,3},{5,4}}} In[6]:= Flatten[xycoord, 1] Out[6]= {{1,1},{1,2},{1,3},{1,4},{2,1},{2,2},{2,3},{2,4},{3,1},{3,2},{3,3},{3,4},{ 4,1},{4,2},{4,3},{4,4},{5,1},{5,2},{5,3},{5,4}} In[7]:= MapThread[List, {Flatten[xycoord, 1], Flatten[data]}] Out[7]= {{{1,1},1069.45},{{1,2},1951.84},{{1,3},2288.3},{{1,4},1903.68},{{ 2,1},1031.85},{{2,2},2048.23},{{2,3}, 1035.9},{{2,4},1059.63},{{3,1},893.347},{{3,2},883.253},{{3,3},423.135},\ {{3,4},514.3},{{4,1},1729.97},{{4,2},1901.79},{{4,3},1513.78},{{4,4},2397.94},\ {{5,1},2402.13},{{5,2},1341.47},{{5,3},1300.56},{{5,4},883.788}} In[8]:= Flatten[%, 2] Out[8]= {1,1,1069.45,1,2,1951.84,1,3,2288.3,1,4,1903.68,2,1,1031.85,2,2,2048.23,2,3,\ 1035.9,2,4,1059.63,3,1,893.347,3,2,883.253,3,3,423.135,3,4,514.3,4,1,1729.97,\ 4,2,1901.79,4,3,1513.78,4,4,2397.94,5,1,2402.13,5,2,1341.47,5,3,1300.56,5,4,\ 883.788} In[9]:= Partition[%, 3] Out[9]= {{1,1,1069.45},{1,2,1951.84},{ 1,3,2288.3},{1,4,1903.68},{2,1,1031.85},{2,2,2048.23},{2,3, 1035.9},{2,4,1059.63},{3,1,893.347},{3,2,883.253},{ 3,3,423.135},{3,4,514.3},{4,1,1729.97},{4,2,1901.79},{ 4,3,1513.78},{4,4,2397.94},{5,1,2402.13},{5,2,1341.47},{ 5,3,1300.56},{5,4,883.788}} Okay! Now we have the correct structure that can be used by *Fit* We can do all these operations in just one line, as follows In[10]:= Partition[Flatten[MapThread[List, {Flatten[Table[Table[{i, j}, {j, nCol}], {i, nRow}], 1], Flatten[data]}], 2], 3] Out[10]= {{1,1,1069.45},{1,2,1951.84},{ 1,3,2288.3},{1,4,1903.68},{2,1,1031.85},{2,2,2048.23},{2,3, 1035.9},{2,4,1059.63},{3,1,893.347},{3,2,883.253},{ 3,3,423.135},{3,4,514.3},{4,1,1729.97},{4,2,1901.79},{ 4,3,1513.78},{4,4,2397.94},{5,1,2402.13},{5,2,1341.47},{ 5,3,1300.56},{5,4,883.788}} and check that *Fit* works correctly with them In[11]:= Fit[%, {x^3, x^2, x, 1, y^3, y^2, y}, {x, y}] Out[11]= 2986.4585080606907 - 3837.065481375177*x + 1274.2243266436349*x^2 - 125.43912287672083*x^3 + 2556.0734957643067*y - 1121.9379403564901*y^2 + 144.24393149981609*y^3 Hope this helps, /J.M.