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
|