Go Down

### Topic: Problems passing an array to a function for 2d interpolation (Read 6790 times)previous topic - next topic

#### rgb32

##### Jan 29, 2013, 11:21 am
Hi. I've been trying to write a sketch to interpolate between points from a table. The stumbling block at the moment is a compiling problem where error message " cannot convert 'int (*)[10]' to 'int*' for argument '5' to 'int multimap2d(int, int, int*, int*, int*)' " you'll see that this relates to an array being passed to function "multimap2d".

I'm running an Uno 3

Can anyone advise a fix to get this running?

Although the numbers in the array are all the same (by column) at this point this is for ease of generating a starting point. Every point could be unique. Likewise the tpsaxis and rpmaxis do need necessarily have regular spacing.

Code: [Select]
`// 2d interpolationvoid setup() {  Serial.begin(9600);}void loop() {  int tpsaxis[] = { 0, 5, 10, 50, 60, 80, 90, 95, 97, 100,};  // 10  int rpmaxis[]  = {1000,2000,3000,4000,5000,7000,8000,10000,12000,13500}; // 10  int tpso[10][10] = {      100, 100, 100, 100, 100, 100, 100, 100, 100, 100,      97, 97, 97, 97, 97, 97, 97, 97, 97, 97,      97, 97, 97, 97, 97, 97, 97, 97, 97, 97,      97, 97, 97, 97, 97, 97, 97, 97, 97, 97,      40, 40, 40, 40, 40, 40, 40, 40, 40, 40,      30, 30, 30, 30, 30, 30, 30, 30, 30, 30,      30, 30, 30, 30, 30, 30, 30, 30, 30, 30,      30, 30, 30, 30, 30, 30, 30, 30, 30, 30,      30, 30, 30, 30, 30, 30, 30, 30, 30, 30,      0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // [ 9 x 9 ] matrix    int tpsout;     tpsout = multimap2d(4000, 50, rpmaxis, tpsaxis, tpso);Serial.println(tpsout);  }int multimap2d(int xval, int yval, int* xaxis, int* yaxis, int* zvalues){  byte xpos = 1;  byte xi = 0;  byte ypos = 1;  byte yi = 0;  // deal with special cases first  if (xval <= xaxis[0])    {    xpos = 0 ;    xi=0 ; // then no interpolation is required.     }  else if (xval >= xaxis[9])     {    xpos = 9;    xi=0;  // then no interpolation is required.     }  else     {//search right interval  //  uint8_t pos = 1; // have already established that we're not at xaxis[0] use xpos=1  while(xval > xaxis[xpos]) xpos++; // search until xpos found  // this will handle all exact "points" in the xaxis array      if (xval == xaxis[xpos])      {      xi=0; // no interpolation is required in x.      }      else      {      xi=1; // If above doesn't solve then interpolation is required using xpos and xpos-1      }    }// do the same for yaxis// deal with special cases first  if (yval <= yaxis[0])    {    ypos = 0;    yi=0; // then no interpolation is required.     }   else if (yval >= yaxis[9])    {    ypos = 9;    yi=0 ;// then no interpolation is required.     }  else    {    //search right interval  // have already established that we're not at yaxis[0] use ypos = 1    while(yval > yaxis[ypos]) ypos++; // search until ypos found      // this will handle all exact "points" in the _in array      if (yval == yaxis[ypos])        {        yi=0; // no interpolation is required in y.        }      else        {        yi=1; // If above doesn't solve then interpolation is required using ypos and ypos-1        }     }// case 1. There is an exact point in the table    if(xi==0 && yi==0) return zvalues[xpos,ypos];// case 2. Interpolate in x only. i.e. yval corresponds to bounds or a breakpoint    if(xi==1 && yi==0)       {      return map(xval, xaxis[xpos-1], xaxis[xpos], zvalues[xpos-1,ypos], zvalues[xpos,ypos]);      }// case 3.    if(xi==0 && yi==1)       {      return map(yval, yaxis[ypos-1],yaxis[ypos], zvalues[xpos,ypos-1], zvalues[xpos,ypos]);      }//case 4. Interpolate both. x first    // if(xi==1 & yi==1)     else      {      int _high = map(xval, xaxis[xpos-1],xaxis[xpos], zvalues[xpos-1,ypos], zvalues[xpos,ypos]);      int _low = map(xval, xaxis[xpos-1],xaxis[xpos], zvalues[xpos-1,ypos-1], zvalues[xpos,ypos-1]);      return map(yval, yaxis[ypos-1],yaxis[ypos],_low,_high);      }}`

#### nickgammon

#1
##### Jan 29, 2013, 11:26 am
Code: [Select]
`      int _high = map(xval, xaxis[xpos-1],xaxis[xpos], zvalues[xpos-1,ypos], zvalues[xpos,ypos]);`

This isn't the right way to index into a 2-dimensional array:

Code: [Select]
`zvalues[xpos,ypos]`
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

#### nickgammon

#2
##### Jan 29, 2013, 11:27 am
This makes it compile, but I doubt it will do what you expect because of my earlier comment:

Code: [Select]
`  tpsout = multimap2d(4000, 50, rpmaxis, tpsaxis, (int *) tpso);`
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

#### rgb32

#3
##### Jan 29, 2013, 11:28 am
Nice one. that bit is now fixed....

seems I have matlab in my head......

#### nickgammon

#4
##### Jan 29, 2013, 11:31 am
This compiles and might be better:

Code: [Select]
`// 2d interpolationvoid setup() {  Serial.begin(9600);}void loop() {  int tpsaxis[] = { 0, 5, 10, 50, 60, 80, 90, 95, 97, 100,};  // 10  int rpmaxis[]  = {1000,2000,3000,4000,5000,7000,8000,10000,12000,13500}; // 10  int tpso[10][10] = {      100, 100, 100, 100, 100, 100, 100, 100, 100, 100,      97, 97, 97, 97, 97, 97, 97, 97, 97, 97,      97, 97, 97, 97, 97, 97, 97, 97, 97, 97,      97, 97, 97, 97, 97, 97, 97, 97, 97, 97,      40, 40, 40, 40, 40, 40, 40, 40, 40, 40,      30, 30, 30, 30, 30, 30, 30, 30, 30, 30,      30, 30, 30, 30, 30, 30, 30, 30, 30, 30,      30, 30, 30, 30, 30, 30, 30, 30, 30, 30,      30, 30, 30, 30, 30, 30, 30, 30, 30, 30,      0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // [ 9 x 9 ] matrix    int tpsout;     tpsout = multimap2d(4000, 50, rpmaxis, tpsaxis, tpso);Serial.println(tpsout);  }int multimap2d(int xval, int yval, int* xaxis, int* yaxis, int zvalues [10] [10] ){  byte xpos = 1;  byte xi = 0;  byte ypos = 1;  byte yi = 0;  // deal with special cases first  if (xval <= xaxis[0])    {    xpos = 0 ;    xi=0 ; // then no interpolation is required.     }  else if (xval >= xaxis[9])     {    xpos = 9;    xi=0;  // then no interpolation is required.     }  else     {//search right interval  //  uint8_t pos = 1; // have already established that we're not at xaxis[0] use xpos=1  while(xval > xaxis[xpos]) xpos++; // search until xpos found  // this will handle all exact "points" in the xaxis array      if (xval == xaxis[xpos])      {      xi=0; // no interpolation is required in x.      }      else      {      xi=1; // If above doesn't solve then interpolation is required using xpos and xpos-1      }    }// do the same for yaxis// deal with special cases first  if (yval <= yaxis[0])    {    ypos = 0;    yi=0; // then no interpolation is required.     }   else if (yval >= yaxis[9])    {    ypos = 9;    yi=0 ;// then no interpolation is required.     }  else    {    //search right interval  // have already established that we're not at yaxis[0] use ypos = 1    while(yval > yaxis[ypos]) ypos++; // search until ypos found      // this will handle all exact "points" in the _in array      if (yval == yaxis[ypos])        {        yi=0; // no interpolation is required in y.        }      else        {        yi=1; // If above doesn't solve then interpolation is required using ypos and ypos-1        }     }// case 1. There is an exact point in the table    if(xi==0 && yi==0) return zvalues[xpos] [ypos];// case 2. Interpolate in x only. i.e. yval corresponds to bounds or a breakpoint    if(xi==1 && yi==0)       {      return map(xval, xaxis[xpos-1], xaxis[xpos], zvalues[xpos-1] [ypos], zvalues[xpos] [ypos]);      }// case 3.    if(xi==0 && yi==1)       {      return map(yval, yaxis[ypos-1],yaxis[ypos], zvalues[xpos] [ypos-1], zvalues[xpos] [ypos]);      }//case 4. Interpolate both. x first    // if(xi==1 & yi==1)     else      {      int _high = map(xval, xaxis[xpos-1],xaxis[xpos], zvalues[xpos-1] [ypos], zvalues[xpos] [ypos]);      int _low = map(xval, xaxis[xpos-1],xaxis[xpos], zvalues[xpos-1] [ypos-1], zvalues[xpos] [ypos-1]);      return map(yval, yaxis[ypos-1],yaxis[ypos],_low,_high);      }}`
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

#### rgb32

#5
##### Jan 29, 2013, 11:39 am

This compiles and might be better:

Code: [Select]
`// 2d interpolationvoid setup() {  Serial.begin(9600);}void loop() {  int tpsaxis[] = { 0, 5, 10, 50, 60, 80, 90, 95, 97, 100,};  // 10  int rpmaxis[]  = {1000,2000,3000,4000,5000,7000,8000,10000,12000,13500}; // 10  int tpso[10][10] = {      100, 100, 100, 100, 100, 100, 100, 100, 100, 100,      97, 97, 97, 97, 97, 97, 97, 97, 97, 97,      97, 97, 97, 97, 97, 97, 97, 97, 97, 97,      97, 97, 97, 97, 97, 97, 97, 97, 97, 97,      40, 40, 40, 40, 40, 40, 40, 40, 40, 40,      30, 30, 30, 30, 30, 30, 30, 30, 30, 30,      30, 30, 30, 30, 30, 30, 30, 30, 30, 30,      30, 30, 30, 30, 30, 30, 30, 30, 30, 30,      30, 30, 30, 30, 30, 30, 30, 30, 30, 30,      0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // [ 9 x 9 ] matrix    int tpsout;     tpsout = multimap2d(4000, 50, rpmaxis, tpsaxis, tpso);Serial.println(tpsout);  }int multimap2d(int xval, int yval, int* xaxis, int* yaxis, int zvalues [10] [10] ){  byte xpos = 1;  byte xi = 0;  byte ypos = 1;  byte yi = 0;  // deal with special cases first  if (xval <= xaxis[0])    {    xpos = 0 ;    xi=0 ; // then no interpolation is required.     }  else if (xval >= xaxis[9])     {    xpos = 9;    xi=0;  // then no interpolation is required.     }  else     {//search right interval  //  uint8_t pos = 1; // have already established that we're not at xaxis[0] use xpos=1  while(xval > xaxis[xpos]) xpos++; // search until xpos found  // this will handle all exact "points" in the xaxis array      if (xval == xaxis[xpos])      {      xi=0; // no interpolation is required in x.      }      else      {      xi=1; // If above doesn't solve then interpolation is required using xpos and xpos-1      }    }// do the same for yaxis// deal with special cases first  if (yval <= yaxis[0])    {    ypos = 0;    yi=0; // then no interpolation is required.     }   else if (yval >= yaxis[9])    {    ypos = 9;    yi=0 ;// then no interpolation is required.     }  else    {    //search right interval  // have already established that we're not at yaxis[0] use ypos = 1    while(yval > yaxis[ypos]) ypos++; // search until ypos found      // this will handle all exact "points" in the _in array      if (yval == yaxis[ypos])        {        yi=0; // no interpolation is required in y.        }      else        {        yi=1; // If above doesn't solve then interpolation is required using ypos and ypos-1        }     }// case 1. There is an exact point in the table    if(xi==0 && yi==0) return zvalues[xpos] [ypos];// case 2. Interpolate in x only. i.e. yval corresponds to bounds or a breakpoint    if(xi==1 && yi==0)       {      return map(xval, xaxis[xpos-1], xaxis[xpos], zvalues[xpos-1] [ypos], zvalues[xpos] [ypos]);      }// case 3.    if(xi==0 && yi==1)       {      return map(yval, yaxis[ypos-1],yaxis[ypos], zvalues[xpos] [ypos-1], zvalues[xpos] [ypos]);      }//case 4. Interpolate both. x first    // if(xi==1 & yi==1)     else      {      int _high = map(xval, xaxis[xpos-1],xaxis[xpos], zvalues[xpos-1] [ypos], zvalues[xpos] [ypos]);      int _low = map(xval, xaxis[xpos-1],xaxis[xpos], zvalues[xpos-1] [ypos-1], zvalues[xpos] [ypos-1]);      return map(yval, yaxis[ypos-1],yaxis[ypos],_low,_high);      }}`

It does  . Need to try it on the Uno now. Thankyou very much Nick

#### PaulS

#6
##### Jan 29, 2013, 11:42 am
Why are you storing 10 rows and 10 columns of data in your 9 x 9 array? Does that comment really add anything useful? Or even correct?

Why are the arrays declared in loop()? Are you planning on changing them?

Why is tpso, containing byte sized values, an int array?

Why are the arrays not const?
The art of getting good answers lies in asking good questions.

#### rgb32

#7
##### Jan 29, 2013, 05:39 pm
The answer to all these is that the base function I copied and turned into multimap2d was setup like this. I will make all the changes you outlined + tpsaxis...

#### robtillaart

#8
##### Jan 29, 2013, 08:31 pm
Interesting variation of multimap. I added a link to this discussion on the multimap page - http://playground.arduino.cc//Main/MultiMap -
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

#### JimboZA

#9
##### Dec 08, 2014, 03:14 pm
Hmmm, this is probably what I need to look up the comfort level given the temperature and humidity, where the comfort level is just Red, Blue, Yellow or Green as here.
Johannesburg hams call me: ZS6JMB on Highveld rep 145.7875 (-600 & 88.5 tone)
Dr Perry Cox: "Help me to help you, help me to help you...."
Your answer may already be here: https://forum.arduino.cc/index.php?topic=384198.0

#### JimboZA

#10
##### Dec 09, 2014, 05:39 am
And indeed it proves easy enough. One wrinkle is that I think I have my values typed in back-asswards or confusing the axes, since I'm not getting the right values out: probably reading say cell (3,4) when I should be at (4,3). But I daresay I'll figure that out.

Next step is an RGB led to produce the colour.
Johannesburg hams call me: ZS6JMB on Highveld rep 145.7875 (-600 & 88.5 tone)
Dr Perry Cox: "Help me to help you, help me to help you...."
Your answer may already be here: https://forum.arduino.cc/index.php?topic=384198.0

#### issadjay

#11
##### Jun 10, 2016, 07:07 pm
I am doing the same task with a larger array. can anyone tell me why I am not getting the result from from serial monitor. my code is given below
Do I have to use the Flash memory to complete this task. If so how do i retrieve data from Flash memory

#### PaulS

#12
##### Jun 10, 2016, 09:05 pm
Code: [Select]
`  float x_sun[] = { 1};  // 11`
A one element array is useless.

Code: [Select]
`  float y_voltage[]  = {}; // 501  float current[1][501] = {}; // [ 1 x 501 ] matrix`
These 2 arrays are taking up 4008 bytes of SRAM. Do you have that much SRAM?
The art of getting good answers lies in asking good questions.

#### KeithRB

#13
##### Jun 10, 2016, 10:29 pm
and a "1x501" matrix makes no sense in C, more MATLAB speak.

Go Up