Having trouble pulling boundary data points from input file

I have an input file that consists of data in the form "Celsius,Resistance", for example one point is "5,12700" which stands for a temperature of 5 degrees Celsius, my resistance is 12700. This input file consists of multiple sets of data each on their individual line.

Here's a small part of the data:
-4,20080
-3,19060
-2,18100
-1,17190
0,16330
1,15520
2,14750
3,14030
4,13340
5,12700
6,12090

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

Celsius = resis1 + (resistance - temp1) * ((resis2 - resis1) / (temp2 - temp1))

with temp1,resis1 being the data point below and temp2,resis2 being the data point above my inputted resistance.

Anything helps! Thanks for taking the time to help!

Here is a rough start to what I have.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
 #include "stdafx.h"
#include <iostream>
#include <string>
#include <cmath>
#include <map>
#include <cstdlib>
#include <ctime>
#include <iomanip>
#include <fstream>

using namespace std;

int main()
{
	int resistance, celsius, temp1, temp2, resis1, resis2;
	ifstream data;

	data.open("e:/TempResisData.txt");

	if (data.fail())
		cout << "Problem opening input file";

	do
	{
		cout << "Enter your resistance (enter -1 to quit): ";
		cin >> resistance;

// Here is where I am stuck. I am unsure on how to search through my input file to obtain the boundary points that are above and below my inputted resistance

		celsius = resis1 + (resistance - temp1) * ((resis2 - resis1) / (temp2 - temp1));

		cout << "For a resistance of " << resistance << " the corresponding temperature is ";
		cout << celsius << " degrees Celcius.";
	} while (resistance != -1);

	data.close();

	system("pause");
    return 0;
}


Also, here is the project I am attempting to complete.


I will provide you with 6 resistance values and you will calculate the corresponding temperature values (in Celsius). You will need to linearly interpolate, as needed, to assure accurate results where the given resistance
may fall between two data points.
You are to reject any resistance values that are
less than/greater than the high and low values in the data table.
Your task is to read in the thermistor data (unknown number of data points . . .) and prompt for the 5 test resistance values that I provide. For each resistance value you will produce a temperature
value.
Last edited on
Well first in main() where do you assign values to all of the variables in your calculation?

What is the purpose of your parse_data() function? Don't you need to "search" your data to find the most correct temperature for the given resistance? Don't you actually need to call this function?

By the way it would be much less problems if you read your data file placed the data into a vector of your structure and then use that vector to find the match.
I am trying to use the data boundaries from my input file for my values of "temp1, temp2, resis1, resis2". Also, yes, I have not called it back to the main function yet, like I said this is a very rough start as I try to learn more about parse, structures, and vectors.
Well in order to "learn" about parse, structures and vectors perhaps you should be trying to use them. Also you need to first "load" the vector from the data file then use that vector to locate the proper temperature based on the resistance.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <vector>
#include <algorithm>
using namespace std;


struct data
{
   double resistance;
   double temperature;
};


//======================================================================


vector<data> readData( istream &strm )         // read data from stream strm
{
   vector<data> result;
   char comma;
   for ( data d; strm >> d.temperature >> comma >> d.resistance; ) result.push_back( d );
   return result;
}


//======================================================================


// Interpolates from parallel arrays X[] and Y[]
// X is the independent variable; the arrays are assumed sorted so that X is monotonic increasing
// Returns false if interpolation point xval is outside the data range

bool interpolate( const vector<double> &X, const vector<double> &Y, double xval, double &yval )
{
   int N = X.size();
   if ( xval < X[0] || xval > X[N-1] ) return false;        // outside data range

   int i = 0;
   while( xval > X[i+1] && i < N - 2 ) i++;                 // X[i] and X[i+1] must span xval

   double dYdX = ( Y[i+1] - Y[i] ) / ( X[i+1] - X[i] );     // gradient of interval
   yval = Y[i] + ( xval - X[i] ) * dYdX;

   return true;
}


//======================================================================


int main()
{
   // Read data (just faked here for demonstration)
// ifstream in( "data.in" );
   stringstream in( "-4,20080\n"
                    "-3,19060\n"
                    "-2,18100\n"
                    "-1,17190\n"
                    " 0,16330\n"
                    " 1,15520\n"
                    " 2,14750\n"
                    " 3,14030\n"
                    " 4,13340\n"
                    " 5,12700\n"
                    " 6,12090\n" );
   vector<data> pts = readData( in );

   // Sort on independent variable (here, resistance)
   sort( pts.begin(), pts.end(), []( data a, data b ){ return a.resistance < b.resistance; } );


   // Then split into parallel arrays X, Y (for generality of an interpolation routine)
   vector<double> X, Y;
   for ( data d : pts )
   {
      X.push_back( d.resistance  );
      Y.push_back( d.temperature );
   }


   // Confirm initial data
   #define SW << setw( 10 ) <<
   cout << "Initial data (" << pts.size() << " points)" << '\n';
   cout << right SW "X" SW "Y" << '\n';
   for ( int i = 0; i < pts.size(); i++ ) cout SW X[i] SW Y[i] << '\n';
   cout << '\n';


   // Interpolate from the independent variable
   while ( true )
   {
      double xval, yval;
      cout << "Enter resistance (negative to stop):\n";
      cin >> xval;   if ( xval < 0 ) break;
      if ( interpolate( X, Y, xval, yval ) ) cout << "Temperature is " << yval << "\n\n";
      else                                   cout << "Invalid resistance\n\n";
   }
}

Initial data (11 points)
         X         Y
     12090         6
     12700         5
     13340         4
     14030         3
     14750         2
     15520         1
     16330         0
     17190        -1
     18100        -2
     19060        -3
     20080        -4

Enter resistance (negative to stop): 20080
Temperature is -4

Enter resistance (negative to stop): 12090
Temperature is 6

Enter resistance (negative to stop): 15000
Temperature is 1.67532

Enter resistance (negative to stop): 14000
Temperature is 3.04348

Enter resistance (negative to stop): -1
Thank you for the help @lastchance however, most of that is far too advanced for me to understand. Here is what I currently have. This code will work if the inputted resistance is an exact number on the data file. I'm stuck on how to pull the upper values and lower values if the user inputs a resistance between two points from the data file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include "stdafx.h"
#include <iostream>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iomanip>
#include <fstream>

using namespace std;


int main()
{
	ifstream infile;
	string delimiter = ",";
	string resistanceString, cel;
	string resistance, temperature;


	do
	{
		infile.open("e:/Data.txt");

		bool foundAnswer = false;

		cout << " Enter the measured thermistor resistance value (Enter 'Q' to quit): ";
		cin >> resistance;

		if (resistance > resistanceString || resistance < resistanceString)
			cout << "Thermistor resistance value is out of data range. Please re-enter value." << endl;

		while (!infile.eof() && !foundAnswer)
		{
			getline(infile, resistanceString);

			cel = (resistanceString.substr(0, resistanceString.find(delimiter)));

			resistanceString = resistanceString.substr(resistanceString.find(delimiter) + 1, resistanceString.length());

			if (resistance == resistanceString)
			{
				cout << endl;

				cout << " For a resistance of " << resistanceString << ", the temperature is " << cel << " celsius.";
				cout << endl << endl;
				foundAnswer = true;
			}
		}

		infile.close();
	} while (resistance != "Q");

	cout << endl << endl;

	return 0;
}
@ksolo7,
If you are going to interpolate then you should be reading values into variables of type 'double', not 'string'.

If you are going to interpolate several times you would be better reading all your data into some sort of array(s), not reading the file multiple times.

For those two main reasons your code is never going to work. I don't want to sound harsh but you should start again.

I suggest that you tackle the program in stages. The first is simply to read the data file into either parallel arrays of doubles, or an array of structs containing two doubles (as in my code). Write this back out to screen to check it is read correctly. (By 'array' I mean any sort of container, but I think a std::vector would be best here.)

Once (and only once) you have got your file reading and numerical arrays correctly then start thinking about how you would interpolate. At this point imagine you had your set of points on an XY graph and ask how you would be doing the interpolation by hand.
Last edited on
Topic archived. No new replies allowed.