I have an input file that consists of data in the form "Celsius,Resistance", for example one point is "9,10440" which stands for a temperature of 9 degrees Celsius, my resistance is 10440. This input file consists of multiple sets of data each on their individual line.
I am trying to enter a resistance value of my choice, and return a temperature that corresponds to the resistance I entered. However, the resistance I input might not be an exact data set in the input file so I'm trying to linearly interpolate to assure accurate results where my inputted resistance value falls between two data points.
I'm unsure on how to get the two data points which fall both above and below my inputted resistance so I can linearly interpolate both sets of data as well as my inputted resistance to return the corresponding degrees Celsius. My linear interpolation formula I'm using is
I'm asking because I am having trouble seeking & pulling out the two sets of boundary data from my input file. Once i'm able to retrieve both sets of data, i will have no problem completing the linear interpolation.
#include <map>
#include <cmath>
using resistance_temperature_map = std::map<int,int> ;
// get the data in the stream into a map
resistance_temperature_map get_map( std::istream& stm )
{
resistance_temperature_map result ;
int temperature ;
int resistance ;
while( stm >> temperature >> resistance ) result.emplace( resistance, temperature ) ;
return result ;
}
double interpolate( const resistance_temperature_map& data_points, int resistance )
{
// get the iterator to the data point with resistance equal to or just higher
// https://en.cppreference.com/w/cpp/container/map/lower_boundconstauto next = data_points.lower_bound(resistance) ;
if( next->first == resistance ) return next->second ; // got a precise match
// out of range, can't interpolate; return NaN
if( next == data_points.begin() || next == data_points.end() ) return NAN ;
// get the iterator to the data point for the just lower resistance
auto previous = next ;
--previous ;
// get the resistance and temperature from the iterators and interpolate
constauto [x1,y1] = *previous ;
constauto [x2,y2] = *next ;
return y1 + (resistance - x1) * ( double(y2 - y1) / (x2 - x1) ) ;
}
@ksolo7,
Is your problem that you can't read the data from file in the first place? If so, what do your input files look like (give the first few lines).
On the assumption that you might want to interpolate either way (resistance to temperature or temperature to resistance) then read the data into a vector of structs, each struct containing a temperature and resistance.
Then sort the vector of structs on the independent variable (resistance in your original post).
For any input resistance find the last data point with resistance less than or equal to this, which will be the x1,y1 pair. The next data point in the sorted sequence will be the x2,y2 pair. You can then linearly interpolate.
You will have to decide what to do if your input resistance lies outside the data range: either flag an unreconcileable value or do zeroth or first-order extrapolation: your choice, but you need to make it.
Personally, I tend to write the linear "interpolation" formula as
y = y1 + ( x - x1) * dy/dx
with dy/dx = (y2-y1)/(x2-x1) the gradient of the chord for interpolation. This permits you also to extrapolate if interpolation is not possible.