Basic table lookup and interpolation/extrapolation
Posted: Mon Feb 04, 2008 1:40 pm
Because of the embedded nature of the code I'll be writing, we can't just use an array object and get a value back from a pair of coordinates. Well, at least not without implementing it from the ground up in an efficient accurate way.
An array for us has two dimensions, so we'll need to size references, X and Y.
We'll need a single 1 by (X*Y) table to hold the data
We'll also need two separate tables, 1xX and 1xY to hold the position data for each axises location.
In case our look up values are off the table we want a single bit that tells us if we are going to just use the edge value, or extrapolate outward from the last two rows.
For each axis there will be a two use cases :
The look up is exactly on an axis value
The look up value lies between two axis values
The first case is of course trivial, the latter will be handled in the following way
Retrieve both bounding values and interpolate between them.
In the case where the value rests between points on both axis then we will end up retrieving four values and doing 3 interpolations. Two vertical and one horizontal or vice versa.
This final value will be returned to the caller.
This function can then be used with appropriate addressing information (probably including the page of ram to read from) to read a value from any table.
short getValue(Xsize, Ysize, XaxisAddress, YaxisAddress, MainAddress, RPAGE, Xlookup, Ylookup, edgeBehaviour)
This function should always return a valid value within the confines of the units used. It should never error. It is the responsibility of the coder to ensure the data is where its supposed to be.
A matching setValue function can be defined to match the getValue one, it might look like this :
void setValue(Xsize, Ysize, XaxisAddress, YaxisAddress, MainAddress, RPAGE, Xvalue, Yvalue, cellValue)
This function should return quietly in code terms in all cases, but should report an error to the logging facility if the Xvalue or Yvalue is not valid in the X or Y 1 wide tables respectively.
In order to prevent this method being misused, I propose that a further abstraction could be done such that the required figures themselves except the last three are given by a lookup table based on a unique identifier number and stored in flash from the initial burn. This style of interface would ensure a good level of layer separation and safety from bad addresses being passed into the code from external tuning utilities etc.
Additionally we will need similar but more simple methods for setting the values in a 1xY table that represents the axis spacing.
void setAxisValue(axisSize, axisAddress, RPAGE, position, value)
short getAxisValue(axisSize, axisAddress, RPAGE, position)
Both of these should return quietly in code and log an error with the logging service if the position index is out of range (0 to (size - 1)).
get should return with a predictable and reasonable default value such as the top or bottom figure or an extreme figure to signify an error if the position index is out of range.
set should do nothing other than log if the position index is out of range.
A similar lookup scheme could keep this abstracted away too.
All implementation details and mistakes/gotchas should be commented on. I know Java pretty well, but not C, so I'm learning fast and mistakes are likely.
Admin.
An array for us has two dimensions, so we'll need to size references, X and Y.
We'll need a single 1 by (X*Y) table to hold the data
We'll also need two separate tables, 1xX and 1xY to hold the position data for each axises location.
In case our look up values are off the table we want a single bit that tells us if we are going to just use the edge value, or extrapolate outward from the last two rows.
For each axis there will be a two use cases :
The look up is exactly on an axis value
The look up value lies between two axis values
The first case is of course trivial, the latter will be handled in the following way
Retrieve both bounding values and interpolate between them.
In the case where the value rests between points on both axis then we will end up retrieving four values and doing 3 interpolations. Two vertical and one horizontal or vice versa.
This final value will be returned to the caller.
This function can then be used with appropriate addressing information (probably including the page of ram to read from) to read a value from any table.
short getValue(Xsize, Ysize, XaxisAddress, YaxisAddress, MainAddress, RPAGE, Xlookup, Ylookup, edgeBehaviour)
This function should always return a valid value within the confines of the units used. It should never error. It is the responsibility of the coder to ensure the data is where its supposed to be.
A matching setValue function can be defined to match the getValue one, it might look like this :
void setValue(Xsize, Ysize, XaxisAddress, YaxisAddress, MainAddress, RPAGE, Xvalue, Yvalue, cellValue)
This function should return quietly in code terms in all cases, but should report an error to the logging facility if the Xvalue or Yvalue is not valid in the X or Y 1 wide tables respectively.
In order to prevent this method being misused, I propose that a further abstraction could be done such that the required figures themselves except the last three are given by a lookup table based on a unique identifier number and stored in flash from the initial burn. This style of interface would ensure a good level of layer separation and safety from bad addresses being passed into the code from external tuning utilities etc.
Additionally we will need similar but more simple methods for setting the values in a 1xY table that represents the axis spacing.
void setAxisValue(axisSize, axisAddress, RPAGE, position, value)
short getAxisValue(axisSize, axisAddress, RPAGE, position)
Both of these should return quietly in code and log an error with the logging service if the position index is out of range (0 to (size - 1)).
get should return with a predictable and reasonable default value such as the top or bottom figure or an extreme figure to signify an error if the position index is out of range.
set should do nothing other than log if the position index is out of range.
A similar lookup scheme could keep this abstracted away too.
All implementation details and mistakes/gotchas should be commented on. I know Java pretty well, but not C, so I'm learning fast and mistakes are likely.
Admin.