Blame view

math/function.h 5.11 KB
7006df5f   David Mayerich   reformat of direc...
1
2
3
4
  #ifndef RTS_FUNCTION_H

  #define RTS_FUNCTION_H

  

  #include <string>

7006df5f   David Mayerich   reformat of direc...
5
6
7
  

  namespace rts{

  

2418bcc3   David Mayerich   optimized functio...
8
9
  //template class for a one-dimensional function

  template <class Tx, class Ty>

7006df5f   David Mayerich   reformat of direc...
10
11
  class function

  {

0ef519a4   David Mayerich   optimized materia...
12
13
  protected:

  

2418bcc3   David Mayerich   optimized functio...
14
15
  	std::vector<Tx> X;

  	std::vector<Ty> Y;

0ef519a4   David Mayerich   optimized materia...
16
17
  	Ty range[2];

  	Ty bounding[2];

7006df5f   David Mayerich   reformat of direc...
18
  

a9275be5   David Mayerich   added vector fiel...
19
  	//comparison function for searching lambda

2418bcc3   David Mayerich   optimized functio...
20
21
22
  	static bool findCeiling(Tx ax, Tx bx){

  	    return (ax > bx);

  	}

7006df5f   David Mayerich   reformat of direc...
23
  

2418bcc3   David Mayerich   optimized functio...
24
25
26
  	//process a string to extract a function (generally delimited by tabs, commas, spaces, etc.)

  	void process_string(std::string s){

  		std::stringstream ss(s);

7006df5f   David Mayerich   reformat of direc...
27
  

2418bcc3   David Mayerich   optimized functio...
28
29
30
  		Tx x;

  		Ty y;

  		std::string line;

a9275be5   David Mayerich   added vector fiel...
31
  

2418bcc3   David Mayerich   optimized functio...
32
33
34
35
36
37
38
39
40
41
  		while(!ss.eof()){

  			

  			std::getline(ss, line);

  			if(line[0] == '#') continue;

  

  			std::stringstream lstream(line);

  

  			lstream>>x;			//read the x value

  			lstream>>y;			//read the y value

  

2418bcc3   David Mayerich   optimized functio...
42
43
  			if(ss.eof()) break;

  			insert(x, y);			//insert the read value into the function

2418bcc3   David Mayerich   optimized functio...
44
  		}	

7006df5f   David Mayerich   reformat of direc...
45
46
  	}

  

0ef519a4   David Mayerich   optimized materia...
47
48
49
50
51
52
53
54
55
56
57
  	void update_range(Ty y){

  		//if the function is empty, just set the range to the given value

  		if(X.size() == 0){

  			range[0] = range[1] = y;

  		}

  

  		//otherwise compare the values and set them appropriately

  		if(y < range[0]) range[0] = y;

  		if(y > range[1]) range[1] = y;

  	}

  

2418bcc3   David Mayerich   optimized functio...
58
59
  

  public:

0ef519a4   David Mayerich   optimized materia...
60
  	function(){

180d7f3a   David Mayerich   added binary file...
61
  		range[0] = range[1] = 0;

0ef519a4   David Mayerich   optimized materia...
62
63
  		bounding[0] = bounding[1] = 0;

  	}

2418bcc3   David Mayerich   optimized functio...
64
65
66
  

  	//linear interpolation

  	Ty linear(Tx x) const

7006df5f   David Mayerich   reformat of direc...
67
  	{

0ef519a4   David Mayerich   optimized materia...
68
69
70
71
  		if(X.size() == 0)	return bounding[0];	//return zero if the function is empty

  		//return bounding values if x is outside the sample domain

  		if(x < X[0]) return bounding[0];

  		if(x > X.back()) return bounding[1];

a9275be5   David Mayerich   added vector fiel...
72
  

2418bcc3   David Mayerich   optimized functio...
73
  		unsigned int N = X.size();			//number of sample points

a9275be5   David Mayerich   added vector fiel...
74
75
  

  		//declare an iterator

2418bcc3   David Mayerich   optimized functio...
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
102
103
104
105
106
107
  		typedef typename std::vector< Tx >::iterator f_iter;	//declare an iterator

  		f_iter it;

  

  		//find the first X-coordinate that is greater than x

  		unsigned int i;

  		for(i = 0; i<N; i++){

  			if(X[i] > x)

  				break;

  		}

  		//i currently holds the ceiling

  

  		//if the wavelength is past the end of the list, return the last sample point

  		if(i == N) return Y[N];

  		//if the wavelength is before the beginning of the list, return the front

  		else if(i == 0) return Y[0];

  		//otherwise interpolate

  		else{

  		    Tx xMax = X[i];

  		    Tx xMin = X[i-1];

  

  		    Tx a = (x - xMin) / (xMax - xMin);

  		    Ty riMin = Y[i - 1];

  		    Ty riMax = Y[i];

  		    Ty interp = riMax * a + riMin * (1 - a);

  		    return interp;

  		}

  	}

  

  	///add a data point to a function

  	void insert(Tx x, Ty y)

  	{

  		unsigned int N = X.size();		//number of sample points

a9275be5   David Mayerich   added vector fiel...
108
  

0ef519a4   David Mayerich   optimized materia...
109
110
  		update_range(y);			//update the range of the function

  

2418bcc3   David Mayerich   optimized functio...
111
112
113
114
115
  		if(N == 0 || X[N-1] < x){

  			X.push_back(x);

  			Y.push_back(y);

  			return;

  		}

a9275be5   David Mayerich   added vector fiel...
116
  

2418bcc3   David Mayerich   optimized functio...
117
118
119
  		//declare an iterator and search for the x value

          typename std::vector< Tx >::iterator it;		

          it = search(X.begin(), X.end(), &x, &x + 1, &function<Tx, Ty>::findCeiling);

a9275be5   David Mayerich   added vector fiel...
120
121
  

          //if the function value is past the end of the vector, add it to the back

2418bcc3   David Mayerich   optimized functio...
122
123
124
125
          if(*it == N){

          	X.push_back(x);

          	Y.push_back(y);

          }

a9275be5   David Mayerich   added vector fiel...
126
          //otherwise add the value at the iterator position

2418bcc3   David Mayerich   optimized functio...
127
128
129
          else{

  			X.insert(it, x);

  			Y.insert(Y.begin() + *it, y);

7006df5f   David Mayerich   reformat of direc...
130
131
132
133
  		}

  

  	}

  

2418bcc3   David Mayerich   optimized functio...
134
135
  	Tx getX(unsigned int i) const{

  		return X[i];

7006df5f   David Mayerich   reformat of direc...
136
137
  	}

  

2418bcc3   David Mayerich   optimized functio...
138
139
  	Ty getY(unsigned int i) const{

  		return Y[i];

7006df5f   David Mayerich   reformat of direc...
140
141
  	}

  

a9275be5   David Mayerich   added vector fiel...
142
  	///get the number of data points in the function

2418bcc3   David Mayerich   optimized functio...
143
144
  	unsigned int getN() const{

  		return X.size();

7006df5f   David Mayerich   reformat of direc...
145
146
  	}

  

a9275be5   David Mayerich   added vector fiel...
147
  	//look up an indexed component

2418bcc3   David Mayerich   optimized functio...
148
149
150
151
152
153
  	Ty operator[](int i) const{

  		if(i <= X.size()){

  			std::cout<<"ERROR: accessing non-existing sample point in 'function'"<<std::endl;

  			exit(1);

  		}

  		return Y[i];

7006df5f   David Mayerich   reformat of direc...
154
155
  	}

  

a9275be5   David Mayerich   added vector fiel...
156
  	///linear interpolation

2418bcc3   David Mayerich   optimized functio...
157
  	Tx operator()(Tx x) const{

a9275be5   David Mayerich   added vector fiel...
158
159
160
  		return linear(x);

  	}

  

2418bcc3   David Mayerich   optimized functio...
161
162
163
164
  	//add a constant to the function

  	function<Tx, Ty> operator+(Ty r) const{

  

  		function<Tx, Ty> result;

7006df5f   David Mayerich   reformat of direc...
165
  

2418bcc3   David Mayerich   optimized functio...
166
167
168
169
170
171
172
173
174
175
  		//if there are points in the function

  		if(X.size() > 0){

  			//add r to every point in f

  			for(unsigned int i=0; i<X.size(); i++){

  				result.X.push_back(X[i]);

  				result.Y.push_back(Y[i] + r);

  			}

  		}

  		else{

  			result = r;

7006df5f   David Mayerich   reformat of direc...
176
177
178
179
180
  		}

  

  		return result;

  	}

  

2418bcc3   David Mayerich   optimized functio...
181
182
183
  	function<Tx, Ty> & operator= (const Ty & rhs){		

  		X.clear();

  		Y.clear();

180d7f3a   David Mayerich   added binary file...
184
185
  		bounding[0] = bounding[1] = rhs;	//set the boundary values to rhs

  		if(rhs != 0)						//if the RHS is zero, just clear, otherwise add one value of RHS

8d4f0940   David Mayerich   ERROR in plane wa...
186
187
188
  			insert(0, rhs);

  

  		return *this;

a9275be5   David Mayerich   added vector fiel...
189
190
  	}

  

7006df5f   David Mayerich   reformat of direc...
191
  

0ef519a4   David Mayerich   optimized materia...
192
  	//output a string description of the function (used for console output and debugging)

2418bcc3   David Mayerich   optimized functio...
193
  	std::string str(){

0ef519a4   David Mayerich   optimized materia...
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
  		unsigned int N = X.size();

  

  		std::stringstream ss;

  		ss<<"# of samples: "<<N<<std::endl;

  

  		if(N == 0) return ss.str();

  

  		ss<<"domain: ["<<X[0]<<", "<<X[X.size()-1]<<"]"<<std::endl;

  		ss<<"range: ["<<range[0]<<", "<<range[1]<<"]"<<std::endl;

  

  

  		return ss.str();

  

  	}

  	std::string str_vals(){

  		std::stringstream ss;

2418bcc3   David Mayerich   optimized functio...
210
211
212
213
  

  		unsigned int N = X.size();		//number of sample points

  		//output each function value

  		for(unsigned int i = 0; i<N; i++){

0ef519a4   David Mayerich   optimized materia...
214
215
  			if(i != 0) ss<<std::endl;

  			ss<<X[i]<<", "<<Y[i];

2418bcc3   David Mayerich   optimized functio...
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
  		}

  

  		return ss.str();

  

  	}

  

  	void load(std::string filename){

  		std::ifstream t(filename.c_str());

  		std::string str((std::istreambuf_iterator<char>(t)),

  		std::istreambuf_iterator<char>());

  

  		process_string(str);

  	}

  

  

7006df5f   David Mayerich   reformat of direc...
231
232
233
234
235
  };

  

  }	//end namespace rts

  

  

a9275be5   David Mayerich   added vector fiel...
236
  #endif