Blame view

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

  #define RTS_FUNCTION_H

  

  #include <string>

  

  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

  {

2418bcc3   David Mayerich   optimized functio...
12
13
  	std::vector<Tx> X;

  	std::vector<Ty> Y;

7006df5f   David Mayerich   reformat of direc...
14
  

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

2418bcc3   David Mayerich   optimized functio...
16
17
18
  	static bool findCeiling(Tx ax, Tx bx){

  	    return (ax > bx);

  	}

7006df5f   David Mayerich   reformat of direc...
19
  

2418bcc3   David Mayerich   optimized functio...
20
21
22
  	//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...
23
  

2418bcc3   David Mayerich   optimized functio...
24
25
26
27
  		//std::string test;

  		//std::getline(ss, test);

  		//std::cout<<test;

  		//exit(1);

a9275be5   David Mayerich   added vector fiel...
28
  

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

  		Ty y;

  		std::string line;

a9275be5   David Mayerich   added vector fiel...
32
  

2418bcc3   David Mayerich   optimized functio...
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
  		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

  

  			//std::cout<<x<<", "<<y<<std::endl;

  

  			if(ss.eof()) break;

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

  			

  		}	

7006df5f   David Mayerich   reformat of direc...
49
50
  	}

  

2418bcc3   David Mayerich   optimized functio...
51
52
53
54
55
  

  public:

  

  	//linear interpolation

  	Ty linear(Tx x) const

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

2418bcc3   David Mayerich   optimized functio...
57
  		if(X.size() == 0)	return (Ty)0;	//return zero if the function is empty

a9275be5   David Mayerich   added vector fiel...
58
  

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

a9275be5   David Mayerich   added vector fiel...
60
61
  

  		//declare an iterator

2418bcc3   David Mayerich   optimized functio...
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
  		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...
94
  

2418bcc3   David Mayerich   optimized functio...
95
96
97
98
99
  		if(N == 0 || X[N-1] < x){

  			X.push_back(x);

  			Y.push_back(y);

  			return;

  		}

a9275be5   David Mayerich   added vector fiel...
100
  

2418bcc3   David Mayerich   optimized functio...
101
102
103
  		//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...
104
105
  

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

2418bcc3   David Mayerich   optimized functio...
106
107
108
109
          if(*it == N){

          	X.push_back(x);

          	Y.push_back(y);

          }

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

2418bcc3   David Mayerich   optimized functio...
111
112
113
          else{

  			X.insert(it, x);

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

7006df5f   David Mayerich   reformat of direc...
114
115
116
117
  		}

  

  	}

  

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

  		return X[i];

7006df5f   David Mayerich   reformat of direc...
120
121
  	}

  

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

  		return Y[i];

7006df5f   David Mayerich   reformat of direc...
124
125
  	}

  

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

2418bcc3   David Mayerich   optimized functio...
127
128
  	unsigned int getN() const{

  		return X.size();

7006df5f   David Mayerich   reformat of direc...
129
130
  	}

  

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

2418bcc3   David Mayerich   optimized functio...
132
133
134
135
136
137
  	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...
138
139
  	}

  

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

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

a9275be5   David Mayerich   added vector fiel...
142
143
144
  		return linear(x);

  	}

  

2418bcc3   David Mayerich   optimized functio...
145
146
147
148
  	//add a constant to the function

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

  

  		function<Tx, Ty> result;

7006df5f   David Mayerich   reformat of direc...
149
  

2418bcc3   David Mayerich   optimized functio...
150
151
152
153
154
155
156
157
158
159
  		//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...
160
161
162
163
164
  		}

  

  		return result;

  	}

  

2418bcc3   David Mayerich   optimized functio...
165
166
167
  	function<Tx, Ty> & operator= (const Ty & rhs){		

  		X.clear();

  		Y.clear();

8d4f0940   David Mayerich   ERROR in plane wa...
168
169
170
171
  		if(rhs != 0)			//if the RHS is zero, just clear, otherwise add one value of RHS

  			insert(0, rhs);

  

  		return *this;

a9275be5   David Mayerich   added vector fiel...
172
173
  	}

  

7006df5f   David Mayerich   reformat of direc...
174
  

2418bcc3   David Mayerich   optimized functio...
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
  

  	std::string str(){

  		stringstream ss;

  

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

  		//output each function value

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

  			ss<<X[i]<<", "<<Y[i]<<std::endl;

  		}

  

  		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...
198
199
200
201
202
  };

  

  }	//end namespace rts

  

  

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