Commit 3b012a8086d550433188cebbf95746d2455f0b6f

Authored by David Mayerich
1 parent 7731cf24

added code for command-line arguments

math/complex.h
... ... @@ -143,8 +143,8 @@ struct complex
143 143 }
144 144 CUDA_CALLABLE complex<T> & operator=(const T &rhs)
145 145 {
146   - this->r = rhs;
147   - this->i = 0;
  146 + this->r = rhs;
  147 + this->i = 0;
148 148  
149 149 return *this;
150 150 }
... ... @@ -153,34 +153,34 @@ struct complex
153 153 CUDA_CALLABLE complex<T> operator+=(const complex<T> &rhs)
154 154 {
155 155 *this = *this + rhs;
156   - return *this;
  156 + return *this;
157 157 }
158 158 CUDA_CALLABLE complex<T> operator+=(const T &rhs)
159 159 {
160 160 *this = *this + rhs;
161   - return *this;
  161 + return *this;
162 162 }
163 163  
164 164 CUDA_CALLABLE complex<T> operator*=(const complex<T> &rhs)
165 165 {
166 166 *this = *this * rhs;
167   - return *this;
  167 + return *this;
168 168 }
169 169 CUDA_CALLABLE complex<T> operator*=(const T &rhs)
170 170 {
171 171 *this = *this * rhs;
172   - return *this;
  172 + return *this;
173 173 }
174 174 //divide and assign
175 175 CUDA_CALLABLE complex<T> operator/=(const complex<T> &rhs)
176 176 {
177 177 *this = *this / rhs;
178   - return *this;
  178 + return *this;
179 179 }
180 180 CUDA_CALLABLE complex<T> operator/=(const T &rhs)
181 181 {
182 182 *this = *this / rhs;
183   - return *this;
  183 + return *this;
184 184 }
185 185  
186 186 //absolute value operator (returns the absolute value of the complex number)
... ... @@ -191,23 +191,23 @@ struct complex
191 191  
192 192 CUDA_CALLABLE complex<T> log()
193 193 {
194   - complex<T> result;
195   - result.r = std::log(std::sqrt(r * r + i * i));
196   - result.i = std::atan2(i, r);
  194 + complex<T> result;
  195 + result.r = (T)std::log(std::sqrt(r * r + i * i));
  196 + result.i = (T)std::atan2(i, r);
197 197  
198 198  
199   - return result;
  199 + return result;
200 200 }
201 201  
202 202 CUDA_CALLABLE complex<T> exp()
203 203 {
204   - complex<T> result;
  204 + complex<T> result;
205 205  
206   - T e_r = std::exp(r);
207   - result.r = e_r * std::cos(i);
208   - result.i = e_r * std::sin(i);
  206 + T e_r = std::exp(r);
  207 + result.r = e_r * (T)std::cos(i);
  208 + result.i = e_r * (T)std::sin(i);
209 209  
210   - return result;
  210 + return result;
211 211 }
212 212  
213 213 /*CUDA_CALLABLE complex<T> pow(int y)
... ... @@ -218,11 +218,11 @@ struct complex
218 218  
219 219 CUDA_CALLABLE complex<T> pow(T y)
220 220 {
221   - complex<T> result;
  221 + complex<T> result;
222 222  
223   - result = log() * y;
  223 + result = (T)log() * y;
224 224  
225   - return result.exp();
  225 + return result.exp();
226 226 }
227 227  
228 228 CUDA_CALLABLE complex<T> sqrt()
... ... @@ -275,14 +275,14 @@ struct complex
275 275 template<typename T>
276 276 CUDA_CALLABLE static rts::complex<T> operator+(const double a, const rts::complex<T> b)
277 277 {
278   - return rts::complex<T>(a + b.r, b.i);
  278 + return rts::complex<T>((T)a + b.r, b.i);
279 279 }
280 280  
281 281 //subtraction with a real value
282 282 template<typename T>
283 283 CUDA_CALLABLE static rts::complex<T> operator-(const double a, const rts::complex<T> b)
284 284 {
285   - return rts::complex<T>(a - b.r, -b.i);
  285 + return rts::complex<T>((T)a - b.r, -b.i);
286 286 }
287 287  
288 288 //minus sign
... ... @@ -303,23 +303,16 @@ CUDA_CALLABLE static rts::complex&lt;T&gt; operator*(const double a, const rts::comple
303 303 template<typename T>
304 304 CUDA_CALLABLE static rts::complex<T> operator/(const double a, const rts::complex<T> b)
305 305 {
306   - //return complex<T>(a * b.r, a * b.i);
307 306 rts::complex<T> result;
308 307  
309 308 T denom = b.r * b.r + b.i * b.i;
310 309  
311   - result.r = (a * b.r) / denom;
312   - result.i = -(a * b.i) / denom;
  310 + result.r = ((T)a * b.r) / denom;
  311 + result.i = -((T)a * b.i) / denom;
313 312  
314 313 return result;
315 314 }
316 315  
317   -//POW function
318   -/*template<typename T>
319   -CUDA_CALLABLE static complex<T> pow(complex<T> x, int y)
320   -{
321   - return x.pow(y);
322   -}*/
323 316  
324 317 template<typename T>
325 318 CUDA_CALLABLE static rts::complex<T> pow(rts::complex<T> x, T y)
... ... @@ -374,22 +367,43 @@ CUDA_CALLABLE static T imag(rts::complex&lt;T&gt; a)
374 367 }
375 368  
376 369 //trigonometric functions
  370 +//template<class A>
  371 +/*CUDA_CALLABLE static rts::complex<float> sinf(const rts::complex<float> x)
  372 +{
  373 + rts::complex<float> result;
  374 + result.r = sinf(x.r) * coshf(x.i);
  375 + result.i = cosf(x.r) * sinhf(x.i);
  376 +
  377 + return result;
  378 +}*/
  379 +
377 380 template<class A>
378 381 CUDA_CALLABLE rts::complex<A> sin(const rts::complex<A> x)
379 382 {
380 383 rts::complex<A> result;
381   - result.r = std::sin(x.r) * std::cosh(x.i);
382   - result.i = std::cos(x.r) * std::sinh(x.i);
  384 + result.r = (A)std::sin(x.r) * (A)std::cosh(x.i);
  385 + result.i = (A)std::cos(x.r) * (A)std::sinh(x.i);
383 386  
384 387 return result;
385 388 }
386 389  
  390 +//floating point template
  391 +//template<class A>
  392 +/*CUDA_CALLABLE static rts::complex<float> cosf(const rts::complex<float> x)
  393 +{
  394 + rts::complex<float> result;
  395 + result.r = cosf(x.r) * coshf(x.i);
  396 + result.i = -(sinf(x.r) * sinhf(x.i));
  397 +
  398 + return result;
  399 +}*/
  400 +
387 401 template<class A>
388 402 CUDA_CALLABLE rts::complex<A> cos(const rts::complex<A> x)
389 403 {
390 404 rts::complex<A> result;
391   - result.r = std::cos(x.r) * std::cosh(x.i);
392   - result.i = -(std::sin(x.r) * std::sinh(x.i));
  405 + result.r = (A)std::cos(x.r) * (A)std::cosh(x.i);
  406 + result.i = -((A)std::sin(x.r) * (A)std::sinh(x.i));
393 407  
394 408 return result;
395 409 }
... ...
math/quad.h
... ... @@ -192,7 +192,7 @@ struct quad
192 192 T dc = (A+Y - p).len();
193 193 T dd = (A+X+Y - p).len();
194 194  
195   - return fmax( da, fmax(db, fmax(dc, dd) ) );
  195 + return std::max( da, std::max(db, std::max(dc, dd) ) );
196 196 }
197 197 };
198 198  
... ...
math/spherical_bessel.h
... ... @@ -5,20 +5,20 @@
5 5  
6 6 namespace rts{
7 7  
8   -#define RTS_BESSEL_CONVERGENCE_MIN 0.0145
9   -#define RTS_BESSEL_CONVERGENCE_MAX 0.4
10   -#define RTS_BESSEL_MAXIMUM_FLOAT -1e33
  8 +#define RTS_BESSEL_CONVERGENCE_MIN 0.0145f
  9 +#define RTS_BESSEL_CONVERGENCE_MAX 0.4f
  10 +#define RTS_BESSEL_MAXIMUM_FLOAT -1e33f
11 11  
12 12 template <typename T>
13 13 CUDA_CALLABLE void sbesselj(int n, complex<T> x, complex<T>* j)
14 14 {
15 15 //compute the first bessel function
16 16 if(n >= 0)
17   - j[0] = sin(x) / x;
  17 + j[0] = (T)sin(x) / x;
18 18  
19 19 //compute the second bessel function
20 20 if(n >= 1)
21   - j[1] = j[0] / x - cos(x) / x;
  21 + j[1] = j[0] / x - (T)cos(x) / x;
22 22  
23 23 //use the recurrence relation to compute the rest
24 24 for(int i = 2; i <= n; i++)
... ... @@ -40,11 +40,11 @@ CUDA_CALLABLE void sbessely(int n, complex&lt;T&gt; x, complex&lt;T&gt;* y)
40 40 {
41 41 //compute the first bessel function
42 42 if(n >= 0)
43   - y[0] = -cos(x) / x;
  43 + y[0] = -(T)cos(x) / x;
44 44  
45 45 //compute the second bessel function
46 46 if(n >= 1)
47   - y[1] = y[0] / x - sin(x) / x;
  47 + y[1] = y[0] / x - (T)sin(x) / x;
48 48  
49 49 //use the recurrence relation to compute the rest
50 50 for(int i = 2; i <= n; i++)
... ... @@ -85,18 +85,18 @@ template &lt;typename T&gt;
85 85 CUDA_CALLABLE void init_sbesselj(T x, T* j)
86 86 {
87 87 //compute the first 2 bessel functions
88   - j[0] = sin(x) / x;
  88 + j[0] = (T)sin(x) / x;
89 89  
90   - j[1] = j[0] / x - cos(x) / x;
  90 + j[1] = j[0] / x - (T)cos(x) / x;
91 91 }
92 92  
93 93 template <typename T>
94 94 CUDA_CALLABLE void init_sbessely(T x, T* y)
95 95 {
96 96 //compute the first 2 bessel functions
97   - y[0] = -cos(x) / x;
  97 + y[0] = -(T)cos(x) / x;
98 98  
99   - y[1] = y[0] / x - sin(x) / x;
  99 + y[1] = y[0] / x - (T)sin(x) / x;
100 100 }
101 101  
102 102 template <typename T>
... ...
optics/material.h
... ... @@ -11,7 +11,7 @@
11 11 #include "rts/math/complex.h"
12 12 #include "rts/math/function.h"
13 13  
14   -#define PI 3.14159
  14 +#define PI 3.14159f
15 15  
16 16 namespace rts{
17 17  
... ... @@ -144,6 +144,8 @@ namespace rts{
144 144 case field_A:
145 145 newRI.n.imag(_A(val * scaleA, newRI.lambda));
146 146 break;
  147 + default:
  148 + break;
147 149 }
148 150 }
149 151  
... ...
tools/arguments.h 0 → 100644
  1 +#ifndef RTS_ARGUMENTS
  2 +#define RTS_ARGUMENTS
  3 +
  4 +#include <string>
  5 +#include <vector>
  6 +#include <iostream>
  7 +#include <iomanip>
  8 +#include <sstream>
  9 +#include <iterator>
  10 +#include <algorithm>
  11 +
  12 +#ifdef _WIN32
  13 +#include <Windows.h>
  14 +#endif
  15 +
  16 +namespace rts{
  17 +
  18 + class argument
  19 + {
  20 + private:
  21 + bool ansi;
  22 +
  23 + //argument name
  24 + std::string name;
  25 +
  26 + //description of the argument
  27 + std::vector<std::string> desc;
  28 +
  29 + //argument values
  30 + std::vector<std::string> vals;
  31 +
  32 + //range or example
  33 + std::string range;
  34 +
  35 + //flag is true when the argument is user-specified
  36 + bool flag;
  37 +
  38 + void parse_val(const std::string &s){
  39 +
  40 + vals.clear();
  41 +
  42 + std::stringstream ss(s);
  43 + std::string item;
  44 + while (std::getline(ss, item, ' ')) {
  45 + vals.push_back(item);
  46 + }
  47 + }
  48 +
  49 + void parse_desc(const std::string &s){
  50 +
  51 + desc.clear();
  52 +
  53 + std::stringstream ss(s);
  54 + std::string item;
  55 + while (std::getline(ss, item, '\n')) {
  56 + desc.push_back(item);
  57 + }
  58 + }
  59 +
  60 + public:
  61 + void set_ansi(bool b){ ansi = b; }
  62 + //create an argument with a given name, description, and default value
  63 + argument(std::string _name, std::string _desc, std::string _default = "", std::string _range = "")
  64 + {
  65 + name = _name;
  66 + parse_desc(_desc);
  67 + parse_val(_default);
  68 +
  69 + //if a default value is provided, set the flag
  70 + if(_default != "")
  71 + flag = true;
  72 + else flag = false;
  73 +
  74 + range = _range;
  75 +
  76 +
  77 + }
  78 +
  79 + int nargs()
  80 + {
  81 + return vals.size();
  82 + }
  83 +
  84 + //return the value of a text argument
  85 + std::string as_text(int n = 0)
  86 + {
  87 + if(!flag)
  88 + {
  89 + std::cout<<"ERROR - Argument requested without being set: "<<name<<std::endl;
  90 + exit(1);
  91 + }
  92 +
  93 + if(vals.size() > n)
  94 + return vals[n];
  95 +
  96 + else return "";
  97 + }
  98 +
  99 + //return the value of a floating point argument
  100 + float as_float(int n = 0)
  101 + {
  102 + if(!flag)
  103 + {
  104 + std::cout<<"ERROR - Argument requested without being set: "<<name<<std::endl;
  105 + exit(1);
  106 + }
  107 +
  108 + if(vals.size() > n)
  109 + {
  110 + float r;
  111 + if ( ! (istringstream(vals[n]) >> r) ) r = 0;
  112 + return r;
  113 + }
  114 +
  115 + else return 0;
  116 + }
  117 +
  118 + //return the value of an integer argument
  119 + int as_int(int n = 0)
  120 + {
  121 + if(!flag)
  122 + {
  123 + std::cout<<"ERROR - Argument requested without being set: "<<name<<std::endl;
  124 + exit(1);
  125 + }
  126 +
  127 + if(vals.size() > n)
  128 + {
  129 + int r;
  130 + if ( ! (istringstream(vals[n]) >> r) ) r = 0;
  131 + return r;
  132 + }
  133 +
  134 + else return 0;
  135 + }
  136 +
  137 + //get the width of the left column
  138 + int col_width()
  139 + {
  140 + int n = 3;
  141 + //add the length of the argument name
  142 + n += name.size();
  143 +
  144 + //if there are any default parameters
  145 + if(vals.size() > 0)
  146 + {
  147 + //padding (parenthesis, =, etc.)
  148 + n += 6;
  149 +
  150 + //for each default argument value
  151 + for(int v=0; v<vals.size(); v++)
  152 + n += vals[v].size() + 1;
  153 + }
  154 +
  155 + //add a buffer of 4 characters
  156 + n += 4;
  157 +
  158 + return n;
  159 + }
  160 +
  161 +
  162 + //string output
  163 + std::string toStr(int width = 0)
  164 + {
  165 + std::stringstream ss;
  166 +
  167 + int color_size = 0;
  168 +
  169 +
  170 + //create the left column
  171 + std::string left_part = std::string(" --") + name;
  172 + if(vals.size() != 0)
  173 + {
  174 + if(ansi)
  175 + left_part += "\033[1;32m";
  176 + left_part += " ( = ";
  177 + for(int v=0; v<vals.size(); v++)
  178 + left_part += vals[v] + std::string(" ");
  179 + left_part += ")";
  180 + if(ansi)
  181 + left_part += "\033[0m";
  182 + if(ansi)
  183 + color_size = 11;
  184 + }
  185 + else
  186 + color_size = 0;
  187 +
  188 + //if no width is passed, put 4 spaces between left and right columns
  189 + if(width == 0) width = col_width();
  190 +
  191 + ss<<std::left<<std::setw(width + color_size)<<left_part;
  192 +
  193 + //output right column
  194 + for(int d=0; d<desc.size(); d++)
  195 + {
  196 + if(d == 0)
  197 + ss<<desc[0];
  198 + else
  199 + ss<<std::endl<<setfill(' ')<<setw(width)<<" "<<desc[d];
  200 +
  201 + }
  202 +
  203 + //output the range in the right column
  204 + if(range != "" && ansi)
  205 + ss<<std::endl<<setfill(' ')<<setw(width)<<" "<<" "<<std::string("\033[1;36m") + range + "\033[0m";
  206 + else if(range != "")
  207 + ss<<std::endl<<setfill(' ')<<setw(width)<<" "<<" "<<range;
  208 +
  209 + return ss.str();
  210 + }
  211 +
  212 + //compare the name of the argument to a string
  213 + bool operator==(std::string rhs)
  214 + {
  215 + return (name == rhs);
  216 + }
  217 +
  218 + //set the argument to a given value
  219 + void set(std::string _value)
  220 + {
  221 + parse_val(_value);
  222 +
  223 + //set the flag
  224 + flag = true;
  225 + }
  226 +
  227 + bool is_set()
  228 + {
  229 + return flag;
  230 + }
  231 +
  232 + };
  233 +
  234 + struct argsection
  235 + {
  236 + std::string name;
  237 + unsigned int index;
  238 + };
  239 +
  240 + class arglist
  241 + {
  242 + private:
  243 + bool ansi;
  244 +
  245 + //vector of arguments
  246 + std::vector<argument> args;
  247 +
  248 + //column width of the longest argument
  249 + int col_width;
  250 +
  251 + //list of sections
  252 + std::vector<argsection> sections;
  253 +
  254 + public:
  255 +
  256 + arglist(){ col_width = 0; }
  257 +
  258 + void set_ansi(bool b)
  259 + {
  260 + ansi = b;
  261 + for(int i=0; i<args.size(); i++)
  262 + args[i].set_ansi(ansi);
  263 + }
  264 +
  265 + void add(std::string _name, std::string _desc, std::string _default = "", std::string _range = "")
  266 + {
  267 + argument arg(_name, _desc, _default, _range);
  268 + arg.set_ansi(ansi);
  269 + args.push_back(arg);
  270 +
  271 + col_width = std::max<int>(col_width, arg.col_width());
  272 + }
  273 +
  274 + void section(std::string _name)
  275 + {
  276 + argsection s;
  277 + s.name = _name;
  278 + s.index = args.size();
  279 + sections.push_back(s);
  280 + }
  281 +
  282 + //output the arguments (generally in response to --help)
  283 + std::string toStr()
  284 + {
  285 + std::stringstream ss;
  286 +
  287 + int si = -1;
  288 +
  289 + if(sections.size() > 0)
  290 + si = 0;
  291 +
  292 + //for each argument
  293 + for(int a=0; a<args.size(); a++)
  294 + {
  295 + if(si != -1 && a == sections[si].index)
  296 + {
  297 + if(ansi)
  298 + ss<<std::endl<<std::left<<setfill('=')<<setw(col_width)<<std::string("\033[1;31m") + sections[si].name<<"\033[0m"<<std::endl;
  299 + else
  300 + ss<<std::endl<<std::left<<setfill('=')<<setw(col_width)<<sections[si].name<<std::endl;
  301 + si++;
  302 + if(si == sections.size()) si = -1;
  303 + }
  304 +
  305 + ss<<args[a].toStr(col_width)<<std::endl;
  306 + }
  307 +
  308 + return ss.str();
  309 + }
  310 +
  311 + int index(std::string _name)
  312 + {
  313 + int i = find(args.begin(), args.end(), _name) - args.begin();
  314 +
  315 + if(i >= args.size())
  316 + i = -1;
  317 +
  318 + return i;
  319 + }
  320 +
  321 + void set(std::string _name, std::string _value)
  322 + {
  323 + int i = index(_name);
  324 +
  325 + if(i != -1)
  326 + {
  327 + args[i].set(_value);
  328 + //adjust the column width if necessary
  329 + col_width = max(col_width, args[i].col_width());
  330 + }
  331 + else
  332 + std::cout<<"ERROR - Argument not recognized: "<<_name<<std::endl;
  333 + }
  334 +
  335 + //parse a parameter string
  336 + void parse(int argc, char* argv[])
  337 + {
  338 + //if the number of arguments is 1, we're done
  339 + if(argc <= 1) return;
  340 +
  341 + std::string name;
  342 + std::string params;
  343 +
  344 + for(int i=1; i<argc; i++)
  345 + {
  346 + //if the argument is a parameter name
  347 + if(argv[i][0] == '-' && argv[i][1] == '-')
  348 + {
  349 + //add any previous arguments
  350 + if(name != "")
  351 + set(name, params);
  352 + //set the current argument to this name
  353 + name = argv[i]+2;
  354 + //clear the parameters list
  355 + params = "";
  356 + }
  357 + else
  358 + {
  359 + if(params != "")
  360 + params += " ";
  361 + params += argv[i];
  362 + }
  363 + }
  364 +
  365 + //set the last argument
  366 + set(name, params);
  367 + }
  368 +
  369 + //determine if a parameter has been set (either specified by the user or with a default value)
  370 + bool operator()(std::string _name)
  371 + {
  372 + int i = find(args.begin(), args.end(), _name) - args.begin();
  373 +
  374 + if(i < 0)
  375 + {
  376 + std::cout<<"ERROR - Unspecified parameter name: "<<_name<<std::endl;
  377 + exit(1);
  378 + }
  379 +
  380 + return args[i].is_set();
  381 + }
  382 +
  383 + int nargs(std::string _name)
  384 + {
  385 + int i = find(args.begin(), args.end(), _name) - args.begin();
  386 +
  387 + if(i < 0)
  388 + {
  389 + std::cout<<"ERROR - Unspecified parameter name: "<<_name<<std::endl;
  390 + exit(1);
  391 + }
  392 +
  393 + return args[i].nargs();
  394 + }
  395 +
  396 + argument operator[](std::string _name)
  397 + {
  398 + int i = find(args.begin(), args.end(), _name) - args.begin();
  399 +
  400 + if(i < 0)
  401 + {
  402 + std::cout<<"ERROR - Unspecified parameter name: "<<_name<<std::endl;
  403 + exit(1);
  404 + }
  405 +
  406 + return args[i];
  407 + }
  408 +
  409 +
  410 + };
  411 +
  412 +
  413 +
  414 +} //end namespace rts
  415 +
  416 +#endif
... ...