Blame view

stim/math/function.h 5.12 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
  

8a86bd56   David Mayerich   changed rts names...
6
  namespace stim{

7006df5f   David Mayerich   reformat of direc...
7
  

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
  		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

5f461a5d   David Mayerich   fixed mirst-based...
88
  		if(i == N) return Y.back();

2418bcc3   David Mayerich   optimized functio...
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
  		//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