Commit 03c403facb572c7df53e36dd20ef6b73ea1290e3

Authored by Pavel Govyadinov
2 parents c0e09133 ad2123e6

Merge branch 'master' of git.stim.ee.uh.edu:codebase/stimlib

stim/biomodels/network.h
... ... @@ -8,7 +8,7 @@
8 8 #include <algorithm>
9 9 #include <string.h>
10 10 #include <math.h>
11   -#include <stim/math/vector.h>
  11 +#include <stim/math/vec3.h>
12 12 #include <stim/visualization/obj.h>
13 13 #include <stim/visualization/cylinder.h>
14 14 #include <ANN/ANN.h>
... ... @@ -37,7 +37,7 @@ class network{
37 37 /// Constructor - creates an edge from a list of points by calling the stim::fiber constructor
38 38  
39 39 ///@param p is an array of positions in space
40   - edge(std::vector< stim::vec<T> > p) : cylinder<T>(p){}
  40 + edge(std::vector< stim::vec3<T> > p) : cylinder<T>(p){}
41 41  
42 42 /// Copy constructor creates an edge from a fiber
43 43 edge(stim::cylinder<T> f) : cylinder<T>(f) {}
... ... @@ -61,20 +61,20 @@ class network{
61 61 };
62 62  
63 63 ///Node class that stores the physical position of the node as well as the edges it is connected to (edges that connect to it), As well as any additional data necessary.
64   - class vertex : public stim::vec<T>
  64 + class vertex : public stim::vec3<T>
65 65 {
66 66 public:
67 67 //std::vector<unsigned int> edges; //indices of edges connected to this node.
68 68 std::vector<unsigned int> e[2]; //indices of edges going out (e[0]) and coming in (e[1])
69   - //stim::vec<T> p; //position of this node in physical space.
  69 + //stim::vec3<T> p; //position of this node in physical space.
70 70  
71 71 //constructor takes a stim::vec
72   - vertex(stim::vec<T> p) : stim::vec<T>(p){}
  72 + vertex(stim::vec3<T> p) : stim::vec3<T>(p){}
73 73  
74 74 /// Output the vertex information as a string
75 75 std::string str(){
76 76 std::stringstream ss;
77   - ss<<"\t(x, y, z) = "<<stim::vec<T>::str();
  77 + ss<<"\t(x, y, z) = "<<stim::vec3<T>::str();
78 78  
79 79 if(e[0].size() > 0){
80 80 ss<<"\t> ";
... ... @@ -129,7 +129,11 @@ public:
129 129 std::vector< stim::vec<T> > c; //allocate an array of points for the vessel centerline
130 130 O.getLine(l, c); //get the fiber centerline
131 131  
132   - edge new_edge = c; //create an edge from the given centerline
  132 + std::vector< stim::vec3<T> > c3(c.size());
  133 + for(size_t j = 0; j < c.size(); j++)
  134 + c3[j] = c[j];
  135 +
  136 + edge new_edge = c3; //create an edge from the given centerline
133 137 unsigned int I = new_edge.size(); //calculate the number of points on the centerline
134 138  
135 139 //get the first and last vertex IDs for the line
... ... @@ -222,7 +226,7 @@ public:
222 226 float gaussianFunction(float x, float std=25){ return exp(-x/(2*std*std));} // by default std = 25
223 227  
224 228 // stim 3d vector to annpoint of 3 dimensions
225   - void stim2ann(ANNpoint &a, stim::vec<T> b){
  229 + void stim2ann(ANNpoint &a, stim::vec3<T> b){
226 230 a[0] = b[0];
227 231 a[1] = b[1];
228 232 a[2] = b[2];
... ... @@ -278,10 +282,9 @@ public:
278 282 ANNdistArray dists = new ANNdist[1]; // near neighbor distances
279 283 ANNidxArray nnIdx = new ANNidx[1]; // near neighbor indices // allocate near neigh indices
280 284  
281   - stim::vec<T> p0, p1;
282   - float m0, m1;
  285 + stim::vec3<T> p0, p1;
  286 + float m1;
283 287 float M = 0; //stores the total metric value
284   - float l; //stores the segment length
285 288 float L = 0; //stores the total network length
286 289 ANNpoint queryPt = annAllocPt(3);
287 290 for(unsigned e = 0; e < R.E.size(); e++){ //for each edge in A
... ... @@ -292,7 +295,7 @@ public:
292 295 p1 = R.E[e][p]; //get the next point in the edge
293 296 stim2ann(queryPt, p1);
294 297 kdt->annkSearch( queryPt, 1, nnIdx, dists, eps); //find the distance between A and the current network
295   - m1 = 1.0f - gaussianFunction(dists[0], sigma); //calculate the metric value based on the distance
  298 + m1 = 1.0f - gaussianFunction((float)dists[0], sigma); //calculate the metric value based on the distance
296 299 R.E[e].set_mag(m1, p, 1); //set the error for the second point in the segment
297 300  
298 301 }
... ...
stim/cuda/cudatools/callable.h
... ... @@ -2,7 +2,7 @@
2 2  
3 3 //define the CUDA_CALLABLE macro (will prefix all members)
4 4 #ifdef __CUDACC__
5   -#define CUDA_CALLABLE __host__ __device__
  5 +#define CUDA_CALLABLE __host__ __device__ inline
6 6 #else
7 7 #define CUDA_CALLABLE
8 8 #endif
... ...
stim/cuda/cudatools/devices.h
... ... @@ -15,7 +15,7 @@ int maxThreadsPerBlock()
15 15 }
16 16  
17 17 extern "C"
18   -int sharedMemPerBlock()
  18 +size_t sharedMemPerBlock()
19 19 {
20 20 int device;
21 21 cudaGetDevice(&device); //get the id of the current device
... ... @@ -23,6 +23,16 @@ int sharedMemPerBlock()
23 23 cudaGetDeviceProperties(&props, device);
24 24 return props.sharedMemPerBlock;
25 25 }
  26 +
  27 +extern "C"
  28 +size_t constMem()
  29 +{
  30 + int device;
  31 + cudaGetDevice(&device); //get the id of the current device
  32 + cudaDeviceProp props; //device property structure
  33 + cudaGetDeviceProperties(&props, device);
  34 + return props.totalConstMem;
  35 +}
26 36 } //end namespace rts
27 37  
28 38 #endif
... ...
stim/cuda/sharedmem.cuh
... ... @@ -5,7 +5,7 @@
5 5 namespace stim{
6 6 namespace cuda{
7 7  
8   - // Copies values from global memory to shared memory, optimizing threads
  8 + // Copies values from texture memory to shared memory, optimizing threads
9 9 template<typename T>
10 10 __device__ void sharedMemcpy_tex2D(T* dest, cudaTextureObject_t src,
11 11 unsigned int x, unsigned int y, unsigned int X, unsigned int Y,
... ... @@ -35,6 +35,19 @@ namespace stim{
35 35 }
36 36 }
37 37  
  38 + // Copies values from global memory to shared memory, optimizing threads
  39 + template<typename T>
  40 + __device__ void sharedMemcpy(T* dest, T* src, size_t N, size_t tid, size_t nt){
  41 +
  42 + size_t I = N / nt + 1; //calculate the number of iterations required to make the copy
  43 + size_t xi = tid; //initialize the source and destination index to the thread ID
  44 + for(size_t i = 0; i < I; i++){ //for each iteration
  45 + if(xi < N) //if the index is within the copy region
  46 + dest[xi] = src[xi]; //perform the copy
  47 + xi += nt;
  48 + }
  49 + }
  50 +
38 51  
39 52 }
40 53 }
... ...
stim/envi/bil.h
... ... @@ -884,7 +884,7 @@ public:
884 884 /// using the following indexing: i = p*B + b
885 885 /// @param matrix is the destination for the pixel data
886 886 /// @param mask is the mask
887   - bool sift(T* matrix, unsigned char* mask = NULL){
  887 + bool sift(T* matrix, unsigned char* mask = NULL, bool PROGRESS = false){
888 888 size_t Lbytes = sizeof(T) * X();
889 889 T* line = (T*) malloc( Lbytes ); //allocate space for a line
890 890  
... ... @@ -903,6 +903,7 @@ public:
903 903 pl++; //increment the pixel pointer
904 904 }
905 905 }
  906 + if(PROGRESS) progress = (double)( (y+1)*Z() + 1) / (double)(Y() * Z()) * 100;
906 907 }
907 908 p += pl; //add the line increment to the running pixel index
908 909 }
... ...
stim/envi/bip.h
... ... @@ -817,7 +817,7 @@ public:
817 817 /// using the following indexing: i = p*B + b
818 818 /// @param matrix is the destination for the pixel data
819 819 /// @param mask is the mask
820   - bool sift(T* matrix, unsigned char* mask = NULL){
  820 + bool sift(T* matrix, unsigned char* mask = NULL, bool PROGRESS = false){
821 821 size_t Bbytes = sizeof(T) * Z();
822 822 size_t XY = X() * Y();
823 823 T* band = (T*) malloc( Bbytes ); //allocate space for a line
... ... @@ -836,6 +836,7 @@ public:
836 836 }
837 837 else
838 838 file.seekg(Bbytes, std::ios::cur); //otherwise skip this band
  839 + if(PROGRESS) progress = (double)(xy+1) / (double)XY * 100;
839 840 }
840 841 return true;
841 842 }
... ...
stim/envi/bsq.h
... ... @@ -809,7 +809,7 @@ public:
809 809 /// using the following indexing: i = p*B + b
810 810 /// @param matrix is the destination for the pixel data
811 811 /// @param mask is the mask
812   - bool sift(T* matrix, unsigned char* mask = NULL){
  812 + bool sift(T* matrix, unsigned char* mask = NULL, bool PROGRESS = false){
813 813 unsigned long long XY = X() * Y(); //Number of XY pixels
814 814 unsigned long long L = XY * sizeof(T); //size of XY plane (in bytes)
815 815  
... ... @@ -827,9 +827,8 @@ public:
827 827 if(mask == NULL || mask[xy] != 0){ //if the pixel is valid
828 828 matrix[i*Z() + b] = band_image[xy]; //copy it to the appropriate point in the values[] array
829 829 i++;
830   - //std::cout<<i<<std::endl;
831 830 }
832   -
  831 + if(PROGRESS) progress = (double)(xy+1) / (double)XY * 100;
833 832 }
834 833 }
835 834  
... ...
stim/envi/envi.h
... ... @@ -670,13 +670,13 @@ public:
670 670 /// using the following indexing: i = b*P + p
671 671 /// @param matrix is the destination for the pixel data
672 672 /// @param p is the mask
673   - bool sift(void* matrix, unsigned char* p = NULL){
  673 + bool sift(void* matrix, unsigned char* p = NULL, bool PROGRESS = false){
674 674  
675 675 if (header.interleave == envi_header::BSQ){ //if the infile is bsq file
676 676 if (header.data_type == envi_header::float32)
677   - return ((bsq<float>*)file)->sift((float*)matrix, p);
  677 + return ((bsq<float>*)file)->sift((float*)matrix, p, PROGRESS);
678 678 else if (header.data_type == envi_header::float64)
679   - return ((bsq<double>*)file)->sift((double*)matrix, p);
  679 + return ((bsq<double>*)file)->sift((double*)matrix, p, PROGRESS);
680 680 else{
681 681 std::cout << "ERROR: unidentified data type" << std::endl;
682 682 exit(1);
... ... @@ -685,9 +685,9 @@ public:
685 685  
686 686 if (header.interleave == envi_header::BIP){
687 687 if (header.data_type == envi_header::float32)
688   - return ((bip<float>*)file)->sift((float*)matrix, p);
  688 + return ((bip<float>*)file)->sift((float*)matrix, p, PROGRESS);
689 689 else if (header.data_type == envi_header::float64)
690   - return ((bip<double>*)file)->sift((double*)matrix, p);
  690 + return ((bip<double>*)file)->sift((double*)matrix, p, PROGRESS);
691 691 else{
692 692 std::cout << "ERROR: unidentified data type" << std::endl;
693 693 exit(1);
... ... @@ -695,9 +695,9 @@ public:
695 695 }
696 696 if (header.interleave == envi_header::BIL){
697 697 if (header.data_type == envi_header::float32)
698   - return ((bil<float>*)file)->sift((float*)matrix, p);
  698 + return ((bil<float>*)file)->sift((float*)matrix, p, PROGRESS);
699 699 else if (header.data_type == envi_header::float64)
700   - return ((bil<double>*)file)->sift((double*)matrix, p);
  700 + return ((bil<double>*)file)->sift((double*)matrix, p, PROGRESS);
701 701 else{
702 702 std::cout << "ERROR: unidentified data type" << std::endl;
703 703 exit(1);
... ...
stim/image/image.h
... ... @@ -6,6 +6,7 @@
6 6 #include <vector>
7 7 #include <iostream>
8 8 #include <limits>
  9 +#include <typeinfo>
9 10  
10 11 namespace stim{
11 12 /// This static class provides the STIM interface for loading, saving, and storing 2D images.
... ... @@ -24,8 +25,6 @@ class image{
24 25 size_t Y() const { return R[2]; }
25 26 size_t C() const { return R[0]; }
26 27  
27   - size_t bytes(){ return size() * sizeof(T); }
28   -
29 28 void init(){ //initializes all variables, assumes no memory is allocated
30 29 memset(R, 0, sizeof(size_t) * 3); //set the resolution and number of channels to zero
31 30 img = NULL;
... ... @@ -33,7 +32,6 @@ class image{
33 32  
34 33 void unalloc(){ //frees any resources associated with the image
35 34 if(img) free(img); //if memory has been allocated, free it
36   - img=NULL;
37 35 }
38 36  
39 37  
... ... @@ -44,16 +42,15 @@ class image{
44 42  
45 43 void allocate(){
46 44 unalloc();
47   - img = (T*) malloc( bytes() ); //allocate memory
48   - memset(img, 0, bytes());
  45 + img = (T*) malloc( sizeof(T) * R[0] * R[1] * R[2] ); //allocate memory
49 46 }
50 47  
51 48 void allocate(size_t x, size_t y, size_t c){ //allocate memory based on the resolution
52   - unalloc();
53 49 R[0] = c; R[1] = x; R[2] = y; //set the resolution
54 50 allocate(); //allocate memory
55 51 }
56 52  
  53 + size_t bytes(){ return size() * sizeof(T); }
57 54  
58 55 size_t idx(size_t x, size_t y, size_t c = 0){
59 56 return y * C() * X() + x * C() + c;
... ... @@ -61,13 +58,23 @@ class image{
61 58  
62 59  
63 60 int cv_type(){
64   - if(std::is_same<T, unsigned char>::value) return CV_MAKETYPE(CV_8U, (int)C());
65   - if(std::is_same<T, char>::value) return CV_MAKETYPE(CV_8S, (int)C());
66   - if(std::is_same<T, unsigned short>::value) return CV_MAKETYPE(CV_16U, (int)C());
67   - if(std::is_same<T, short>::value) return CV_MAKETYPE(CV_16S, (int)C());
68   - if(std::is_same<T, int>::value) return CV_MAKETYPE(CV_32S, (int)C());
69   - if(std::is_same<T, float>::value) return CV_MAKETYPE(CV_32F, (int)C());
70   - if(std::is_same<T, double>::value) return CV_MAKETYPE(CV_64F, (int)C());
  61 + // The following is C++ 11 code, but causes problems on some compilers (ex. nvcc). Below is my best approximation to a solution
  62 +
  63 + //if(std::is_same<T, unsigned char>::value) return CV_MAKETYPE(CV_8U, (int)C());
  64 + //if(std::is_same<T, char>::value) return CV_MAKETYPE(CV_8S, (int)C());
  65 + //if(std::is_same<T, unsigned short>::value) return CV_MAKETYPE(CV_16U, (int)C());
  66 + //if(std::is_same<T, short>::value) return CV_MAKETYPE(CV_16S, (int)C());
  67 + //if(std::is_same<T, int>::value) return CV_MAKETYPE(CV_32S, (int)C());
  68 + //if(std::is_same<T, float>::value) return CV_MAKETYPE(CV_32F, (int)C());
  69 + //if(std::is_same<T, double>::value) return CV_MAKETYPE(CV_64F, (int)C());
  70 +
  71 + if(typeid(T) == typeid(unsigned char)) return CV_MAKETYPE(CV_8U, (int)C());
  72 + if(typeid(T) == typeid(char)) return CV_MAKETYPE(CV_8S, (int)C());
  73 + if(typeid(T) == typeid(unsigned short)) return CV_MAKETYPE(CV_16U, (int)C());
  74 + if(typeid(T) == typeid(short)) return CV_MAKETYPE(CV_16S, (int)C());
  75 + if(typeid(T) == typeid(int)) return CV_MAKETYPE(CV_32S, (int)C());
  76 + if(typeid(T) == typeid(float)) return CV_MAKETYPE(CV_32F, (int)C());
  77 + if(typeid(T) == typeid(double)) return CV_MAKETYPE(CV_64F, (int)C());
71 78  
72 79 std::cout<<"ERROR in stim::image::cv_type - no valid data type found"<<std::endl;
73 80 exit(1);
... ... @@ -75,15 +82,26 @@ class image{
75 82  
76 83 /// Returns the value for "white" based on the dynamic range (assumes white is 1.0 for floating point images)
77 84 T white(){
78   - if(std::is_same<T, unsigned char>::value) return UCHAR_MAX;
79   - if(std::is_same<T, unsigned short>::value) return SHRT_MAX;
80   - if(std::is_same<T, unsigned>::value) return UINT_MAX;
81   - if(std::is_same<T, unsigned long>::value) return ULONG_MAX;
82   - if(std::is_same<T, unsigned long long>::value) return ULLONG_MAX;
83   - if(std::is_same<T, float>::value) return 1.0f;
84   - if(std::is_same<T, double>::value) return 1.0;
  85 + // The following is C++ 11 code, but causes problems on some compilers (ex. nvcc). Below is my best approximation to a solution
  86 +
  87 + //if(std::is_same<T, unsigned char>::value) return UCHAR_MAX;
  88 + //if(std::is_same<T, unsigned short>::value) return SHRT_MAX;
  89 + //if(std::is_same<T, unsigned>::value) return UINT_MAX;
  90 + //if(std::is_same<T, unsigned long>::value) return ULONG_MAX;
  91 + //if(std::is_same<T, unsigned long long>::value) return ULLONG_MAX;
  92 + //if(std::is_same<T, float>::value) return 1.0f;
  93 + //if(std::is_same<T, double>::value) return 1.0;
  94 +
  95 + if(typeid(T) == typeid(unsigned char)) return UCHAR_MAX;
  96 + if(typeid(T) == typeid(unsigned short)) return SHRT_MAX;
  97 + if(typeid(T) == typeid(unsigned)) return UINT_MAX;
  98 + if(typeid(T) == typeid(unsigned long)) return ULONG_MAX;
  99 + if(typeid(T) == typeid(unsigned long long)) return ULLONG_MAX;
  100 + if(typeid(T) == typeid(float)) return 1.0f;
  101 + if(typeid(T) == typeid(double)) return 1.0;
85 102  
86 103 std::cout<<"ERROR in stim::image::white - no white value known for this data type"<<std::endl;
  104 + exit(1);
87 105  
88 106 }
89 107  
... ... @@ -91,9 +109,7 @@ class image{
91 109 public:
92 110  
93 111 /// Default constructor - creates an empty image object
94   - image(){
95   - init(); //initialize all variables to zero, don't allocate any memory
96   - }
  112 + image(){ init(); } //initialize all variables to zero, don't allocate any memory
97 113  
98 114 /// Constructor with a filename - loads the specified file
99 115 image(std::string filename){ //constructor initialize the image with an image file
... ... @@ -115,7 +131,7 @@ public:
115 131 }
116 132  
117 133 /// Copy constructor - duplicates an image object
118   - image(const stim::image<T> &I){
  134 + image(const stim::image<T>& I){
119 135 init();
120 136 allocate(I.X(), I.Y(), I.C());
121 137 memcpy(img, I.img, bytes());
... ... @@ -127,6 +143,7 @@ public:
127 143 }
128 144  
129 145 stim::image<T>& operator=(const stim::image<T>& I){
  146 + init();
130 147 if(&I == this) //handle self-assignment
131 148 return *this;
132 149 allocate(I.X(), I.Y(), I.C());
... ... @@ -139,22 +156,15 @@ public:
139 156  
140 157 cv::Mat cvImage = cv::imread(filename, CV_LOAD_IMAGE_UNCHANGED); //use OpenCV to open the image file
141 158 if(!cvImage.data){
142   - std::cout<<"ERROR stim::image::load() - unable to find image "<<filename<<" ["<<__FILE__<<" (line "<<__LINE__<<")]"<<std::endl;
  159 + std::cout<<"ERROR stim::image::load() - unable to find image "<<filename<<std::endl;
143 160 exit(1);
144 161 }
145 162 allocate(cvImage.cols, cvImage.rows, cvImage.channels()); //allocate space for the image
146   - T* cv_ptr = (T*) cvImage.data;
147   - if(C() == 1)
148   - {
149   - //if this is a single-color image, just copy the data
150   - memcpy(img, cv_ptr, bytes());
151   - }
152   - if(C() == 3)
153   - { //if this is a 3-color image, OpenCV uses BGR interleaving
  163 + T* cv_ptr = (T*)cvImage.data;
  164 + if(C() == 1) //if this is a single-color image, just copy the data
  165 + memcpy(img, cv_ptr, bytes());
  166 + if(C() == 3) //if this is a 3-color image, OpenCV uses BGR interleaving
154 167 set_interleaved_bgr(cv_ptr, X(), Y());
155   - }
156   -
157   - cvImage.release();
158 168 }
159 169  
160 170 //save a file
... ... @@ -168,18 +178,16 @@ public:
168 178 get_interleaved_bgr(buffer);
169 179 cv::Mat cvImage((int)Y(), (int)X(), cv_type(), buffer);
170 180 cv::imwrite(filename, cvImage);
171   - cvImage.release();
172   - free(buffer);
173 181 }
174 182  
175 183 //create an image from an interleaved buffer
176   - void set_interleaved_rgb(T* buffer, size_t width, size_t height, size_t channels = 3){
177   - allocate(width, height, channels);
  184 + void set_interleaved_rgb(T* buffer, size_t width, size_t height){
  185 + allocate(width, height, 3);
178 186 memcpy(img, buffer, bytes());
179 187 }
180 188  
181   - void set_interleaved_bgr(T* buffer, size_t width, size_t height, size_t channels = 3){
182   - allocate(width, height, channels);
  189 + void set_interleaved_bgr(T* buffer, size_t width, size_t height){
  190 + allocate(width, height, 3);
183 191 for(size_t c = 0; c < C(); c++){ //copy directly
184 192 for(size_t y = 0; y < Y(); y++){
185 193 for(size_t x = 0; x < X(); x++){
... ... @@ -359,34 +367,6 @@ public:
359 367  
360 368 return r; //return the inverted image
361 369 }
362   -
363   - /// Invert an image by calculating I1 = alpha - I0, where alpha is the maximum image value
364   - image<T> invert(){
365   - size_t N = size(); //calculate the total number of values in the image
366   - image<T> r(X(), Y(), C()); //allocate space for the resulting image
367   - T white_val = maxv();
368   - for(size_t n = 0; n < N; n++)
369   - r.img[n] = white_val - img[n]; //perform the inversion
370   -
371   - return r; //return the inverted image
372   - }
373   -
374   - ///crops the image from x1 to x0 and y1 to y0 and returns a new (smaller) image.
375   - image<T> crop(int x0, int x1, int y0, int y1)
376   - {
377   -
378   - image<T> ret(x1-x0, y1-y0, C());
379   - int newWidth = x1-x0;
380   - int destidx, srcidx;
381   - ///for each row, cut what amount of data from the original and put it into the new copy.
382   - for(int i = 0; i < (y1-y0); i++)
383   - {
384   - destidx = i*newWidth*C(); ///destination index one per each row
385   - srcidx = ((i+(y0))*X()+x0)*C(); ///source index, one per each row.
386   - memcpy(&ret.img[destidx], &img[srcidx], sizeof(T)*newWidth*C());
387   - }
388   - return ret;
389   - }
390 370  
391 371 image<T> srgb2lab(){
392 372 std::cout<<"ERROR stim::image::srgb2lab - function has been broken, re-implement."<<std::endl;
... ... @@ -405,7 +385,6 @@ public:
405 385 exit(1);
406 386 }
407 387  
408   -
409 388 // leila's code for non_interleaving data in 3D
410 389 //create an data set from an interleaved buffer
411 390 void set_interleaved3(T* buffer, size_t width, size_t height, size_t depth, size_t channels = 3){
... ...
stim/math/bessel.h
... ... @@ -17,6 +17,11 @@ static complex&lt;double&gt; czero(0.0,0.0);
17 17 template< typename P >
18 18 P gamma(P x)
19 19 {
  20 + const P EPS = numeric_limits<P>::epsilon();
  21 + const P FPMIN_MAG = numeric_limits<P>::min();
  22 + const P FPMIN = numeric_limits<P>::lowest();
  23 + const P FPMAX = numeric_limits<P>::max();
  24 +
20 25 int i,k,m;
21 26 P ga,gr,r,z;
22 27  
... ... @@ -47,7 +52,7 @@ P gamma(P x)
47 52 -0.54e-14,
48 53 0.14e-14};
49 54  
50   - if (x > 171.0) return 1e308; // This value is an overflow flag.
  55 + if (x > 171.0) return FPMAX; // This value is an overflow flag.
51 56 if (x == (int)x) {
52 57 if (x > 0.0) {
53 58 ga = 1.0; // use factorial
... ... @@ -56,7 +61,7 @@ P gamma(P x)
56 61 }
57 62 }
58 63 else
59   - ga = 1e308;
  64 + ga = FPMAX;
60 65 }
61 66 else {
62 67 if (fabs(x) > 1.0) {
... ... @@ -89,6 +94,11 @@ template&lt;typename P&gt;
89 94 int bessjy01a(P x,P &j0,P &j1,P &y0,P &y1,
90 95 P &j0p,P &j1p,P &y0p,P &y1p)
91 96 {
  97 + const P EPS = numeric_limits<P>::epsilon();
  98 + const P FPMIN_MAG = numeric_limits<P>::min();
  99 + const P FPMIN = numeric_limits<P>::lowest();
  100 + const P FPMAX = numeric_limits<P>::max();
  101 +
92 102 P x2,r,ec,w0,w1,r0,r1,cs0,cs1;
93 103 P cu,p0,q0,p1,q1,t1,t2;
94 104 int k,kz;
... ... @@ -157,12 +167,12 @@ int bessjy01a(P x,P &amp;j0,P &amp;j1,P &amp;y0,P &amp;y1,
157 167 if (x == 0.0) {
158 168 j0 = 1.0;
159 169 j1 = 0.0;
160   - y0 = -1e308;
161   - y1 = -1e308;
  170 + y0 = -FPMIN;
  171 + y1 = -FPMIN;
162 172 j0p = 0.0;
163 173 j1p = 0.5;
164   - y0p = 1e308;
165   - y1p = 1e308;
  174 + y0p = FPMAX;
  175 + y1p = FPMAX;
166 176 return 0;
167 177 }
168 178 x2 = x*x;
... ... @@ -329,7 +339,7 @@ int msta1(P x,int mp)
329 339 for (i=0;i<20;i++) {
330 340 nn = (int)(n1-(n1-n0)/(1.0-f0/f1));
331 341 f = 0.5*log10(6.28*nn)-nn*log10(1.36*a0/nn)-mp;
332   - if (abs(nn-n1) < 1) break;
  342 + if (std::abs(nn-n1) < 1) break;
333 343 n0 = n1;
334 344 f0 = f1;
335 345 n1 = nn;
... ... @@ -361,7 +371,7 @@ int msta2(P x,int n,int mp)
361 371 for (i=0;i<20;i++) {
362 372 nn = (int)(n1-(n1-n0)/(1.0-f0/f1));
363 373 f = 0.5*log10(6.28*nn)-nn*log10(1.36*a0/nn)-obj;
364   - if (abs(nn-n1) < 1) break;
  374 + if (std::abs(nn-n1) < 1) break;
365 375 n0 = n1;
366 376 f0 = f1;
367 377 n1 = nn;
... ... @@ -596,21 +606,26 @@ int bessjyv(P v,P x,P &amp;vm,P *jv,P *yv,
596 606 P b,ec,w0,w1,bju0,bju1,pv0,pv1,byvk;
597 607 int j,k,l,m,n,kz;
598 608  
  609 + const P EPS = numeric_limits<P>::epsilon();
  610 + const P FPMIN_MAG = numeric_limits<P>::min();
  611 + const P FPMIN = numeric_limits<P>::lowest();
  612 + const P FPMAX = numeric_limits<P>::max();
  613 +
599 614 x2 = x*x;
600 615 n = (int)v;
601 616 v0 = v-n;
602 617 if ((x < 0.0) || (v < 0.0)) return 1;
603   - if (x < 1e-15) {
  618 + if (x < EPS) {
604 619 for (k=0;k<=n;k++) {
605 620 jv[k] = 0.0;
606   - yv[k] = -1e308;
  621 + yv[k] = FPMIN;
607 622 djv[k] = 0.0;
608   - dyv[k] = 1e308;
  623 + dyv[k] = FPMAX;
609 624 if (v0 == 0.0) {
610 625 jv[0] = 1.0;
611 626 djv[1] = 0.5;
612 627 }
613   - else djv[0] = 1e308;
  628 + else djv[0] = FPMAX;
614 629 }
615 630 vm = v;
616 631 return 0;
... ... @@ -623,7 +638,7 @@ int bessjyv(P v,P x,P &amp;vm,P *jv,P *yv,
623 638 for (k=1;k<=40;k++) {
624 639 r *= -0.25*x2/(k*(k+vl));
625 640 bjvl += r;
626   - if (fabs(r) < fabs(bjvl)*1e-15) break;
  641 + if (fabs(r) < fabs(bjvl)*EPS) break;
627 642 }
628 643 vg = 1.0 + vl;
629 644 a = pow(0.5*x,vl)/gamma(vg);
... ... @@ -686,7 +701,7 @@ int bessjyv(P v,P x,P &amp;vm,P *jv,P *yv,
686 701 if (m < n) n = m;
687 702 else m = msta2(x,n,15);
688 703 f2 = 0.0;
689   - f1 = 1.0e-100;
  704 + f1 = FPMIN_MAG;
690 705 for (k=m;k>=0;k--) {
691 706 f = 2.0*(v0+k+1.0)*f1/x-f2;
692 707 if (k <= n) jv[k] = f;
... ... @@ -763,20 +778,26 @@ int bessjyv(P v,P x,P &amp;vm,P *jv,P *yv,
763 778  
764 779 template<typename P>
765 780 int bessjyv_sph(int v, P z, P &vm, P* cjv,
766   - P* cyv, P* cjvp, P* cyvp)
767   -{
  781 + P* cyv, P* cjvp, P* cyvp){
  782 +
768 783 //first, compute the bessel functions of fractional order
769   - bessjyv(v + 0.5, z, vm, cjv, cyv, cjvp, cyvp);
  784 + bessjyv<P>(v + (P)0.5, z, vm, cjv, cyv, cjvp, cyvp);
  785 +
  786 + if(z == 0){ //handle degenerate case of z = 0
  787 + memset(cjv, 0, sizeof(P) * (v+1));
  788 + cjv[0] = 1;
  789 + }
770 790  
771 791 //iterate through each and scale
772   - for(int n = 0; n<=v; n++)
773   - {
  792 + for(int n = 0; n<=v; n++){
774 793  
775   - cjv[n] = cjv[n] * sqrt(rtsPI/(z * 2.0));
776   - cyv[n] = cyv[n] * sqrt(rtsPI/(z * 2.0));
  794 + if(z != 0){ //handle degenerate case of z = 0
  795 + cjv[n] = cjv[n] * sqrt(stim::PI/(z * 2.0));
  796 + cyv[n] = cyv[n] * sqrt(stim::PI/(z * 2.0));
  797 + }
777 798  
778   - cjvp[n] = -1.0 / (z * 2.0) * cjv[n] + cjvp[n] * sqrt(rtsPI / (z * 2.0));
779   - cyvp[n] = -1.0 / (z * 2.0) * cyv[n] + cyvp[n] * sqrt(rtsPI / (z * 2.0));
  799 + cjvp[n] = -1.0 / (z * 2.0) * cjv[n] + cjvp[n] * sqrt(stim::PI / (z * 2.0));
  800 + cyvp[n] = -1.0 / (z * 2.0) * cyv[n] + cyvp[n] * sqrt(stim::PI / (z * 2.0));
780 801 }
781 802  
782 803 return 0;
... ... @@ -1237,7 +1258,7 @@ int cbessjyva(P v,complex&lt;P&gt; z,P &amp;vm,complex&lt;P&gt;*cjv,
1237 1258 P a0,v0,pv0,pv1,vl,ga,gb,vg,vv,w0,w1,ya0,yak,ya1,wa;
1238 1259 int j,n,k,kz,l,lb,lb0,m;
1239 1260  
1240   - a0 = abs(z);
  1261 + a0 = ::abs(z);
1241 1262 z1 = z;
1242 1263 z2 = z*z;
1243 1264 n = (int)v;
... ... @@ -1265,7 +1286,7 @@ int cbessjyva(P v,complex&lt;P&gt; z,P &amp;vm,complex&lt;P&gt;*cjv,
1265 1286 vm = v;
1266 1287 return 0;
1267 1288 }
1268   - if (real(z1) < 0.0) z1 = -z;
  1289 + if (::real(z1) < 0.0) z1 = -z;
1269 1290 if (a0 <= 12.0) {
1270 1291 for (l=0;l<2;l++) {
1271 1292 vl = v0+l;
... ... @@ -1274,7 +1295,7 @@ int cbessjyva(P v,complex&lt;P&gt; z,P &amp;vm,complex&lt;P&gt;*cjv,
1274 1295 for (k=1;k<=40;k++) {
1275 1296 cr *= -0.25*z2/(k*(k+vl));
1276 1297 cjvl += cr;
1277   - if (abs(cr) < abs(cjvl)*eps) break;
  1298 + if (::abs(cr) < ::abs(cjvl)*eps) break;
1278 1299 }
1279 1300 vg = 1.0 + vl;
1280 1301 ga = gamma(vg);
... ... @@ -1327,7 +1348,7 @@ int cbessjyva(P v,complex&lt;P&gt; z,P &amp;vm,complex&lt;P&gt;*cjv,
1327 1348 for (k=1;k<=40;k++) {
1328 1349 cr *= -0.25*z2/(k*(k-vl));
1329 1350 cjvl += cr;
1330   - if (abs(cr) < abs(cjvl)*eps) break;
  1351 + if (::abs(cr) < ::abs(cjvl)*eps) break;
1331 1352 }
1332 1353 vg = 1.0-vl;
1333 1354 gb = gamma(vg);
... ... @@ -1360,16 +1381,16 @@ int cbessjyva(P v,complex&lt;P&gt; z,P &amp;vm,complex&lt;P&gt;*cjv,
1360 1381 cyv1 = M_2_PI*(cec*cjv1-1.0/z1-0.25*z1*cs1);
1361 1382 }
1362 1383 }
1363   - if (real(z) < 0.0) {
  1384 + if (::real(z) < 0.0) {
1364 1385 cfac0 = exp(pv0*cii);
1365 1386 cfac1 = exp(pv1*cii);
1366   - if (imag(z) < 0.0) {
  1387 + if (::imag(z) < 0.0) {
1367 1388 cyv0 = cfac0*cyv0-(P)2.0*(complex<P>)cii*cos(pv0)*cjv0;
1368 1389 cyv1 = cfac1*cyv1-(P)2.0*(complex<P>)cii*cos(pv1)*cjv1;
1369 1390 cjv0 /= cfac0;
1370 1391 cjv1 /= cfac1;
1371 1392 }
1372   - else if (imag(z) > 0.0) {
  1393 + else if (::imag(z) > 0.0) {
1373 1394 cyv0 = cyv0/cfac0+(P)2.0*(complex<P>)cii*cos(pv0)*cjv0;
1374 1395 cyv1 = cyv1/cfac1+(P)2.0*(complex<P>)cii*cos(pv1)*cjv1;
1375 1396 cjv0 *= cfac0;
... ... @@ -1400,7 +1421,7 @@ int cbessjyva(P v,complex&lt;P&gt; z,P &amp;vm,complex&lt;P&gt;*cjv,
1400 1421 cf2 = cf1;
1401 1422 cf1 = cf;
1402 1423 }
1403   - if (abs(cjv0) > abs(cjv1)) cs = cjv0/cf;
  1424 + if (::abs(cjv0) > ::abs(cjv1)) cs = cjv0/cf;
1404 1425 else cs = cjv1/cf2;
1405 1426 for (k=0;k<=n;k++) {
1406 1427 cjv[k] *= cs;
... ... @@ -1412,21 +1433,21 @@ int cbessjyva(P v,complex&lt;P&gt; z,P &amp;vm,complex&lt;P&gt;*cjv,
1412 1433 }
1413 1434 cyv[0] = cyv0;
1414 1435 cyv[1] = cyv1;
1415   - ya0 = abs(cyv0);
  1436 + ya0 = ::abs(cyv0);
1416 1437 lb = 0;
1417 1438 cg0 = cyv0;
1418 1439 cg1 = cyv1;
1419 1440 for (k=2;k<=n;k++) {
1420 1441 cyk = 2.0*(v0+k-1.0)*cg1/z-cg0;
1421   - yak = abs(cyk);
1422   - ya1 = abs(cg0);
  1442 + yak = ::abs(cyk);
  1443 + ya1 = ::abs(cg0);
1423 1444 if ((yak < ya0) && (yak< ya1)) lb = k;
1424 1445 cyv[k] = cyk;
1425 1446 cg0 = cg1;
1426 1447 cg1 = cyk;
1427 1448 }
1428 1449 lb0 = 0;
1429   - if ((lb > 4) && (imag(z) != 0.0)) {
  1450 + if ((lb > 4) && (::imag(z) != 0.0)) {
1430 1451 while(lb != lb0) {
1431 1452 ch2 = cone;
1432 1453 ch1 = czero;
... ... @@ -1449,7 +1470,7 @@ int cbessjyva(P v,complex&lt;P&gt; z,P &amp;vm,complex&lt;P&gt;*cjv,
1449 1470 cp21 = ch2;
1450 1471 if (lb == n)
1451 1472 cjv[lb+1] = 2.0*(lb+v0)*cjv[lb]/z-cjv[lb-1];
1452   - if (abs(cjv[0]) > abs(cjv[1])) {
  1473 + if (::abs(cjv[0]) > ::abs(cjv[1])) {
1453 1474 cyv[lb+1] = (cjv[lb+1]*cyv0-2.0*cp11/(M_PI*z))/cjv[0];
1454 1475 cyv[lb] = (cjv[lb]*cyv0+2.0*cp12/(M_PI*z))/cjv[0];
1455 1476 }
... ... @@ -1474,8 +1495,8 @@ int cbessjyva(P v,complex&lt;P&gt; z,P &amp;vm,complex&lt;P&gt;*cjv,
1474 1495 cyl2 = cylk;
1475 1496 }
1476 1497 for (k=2;k<=n;k++) {
1477   - wa = abs(cyv[k]);
1478   - if (wa < abs(cyv[k-1])) lb = k;
  1498 + wa = ::abs(cyv[k]);
  1499 + if (wa < ::abs(cyv[k-1])) lb = k;
1479 1500 }
1480 1501 }
1481 1502 }
... ... @@ -1494,15 +1515,21 @@ int cbessjyva_sph(int v,complex&lt;P&gt; z,P &amp;vm,complex&lt;P&gt;*cjv,
1494 1515 //first, compute the bessel functions of fractional order
1495 1516 cbessjyva<P>(v + 0.5, z, vm, cjv, cyv, cjvp, cyvp);
1496 1517  
  1518 + if(z == 0){ //handle degenerate case of z = 0
  1519 + memset(cjv, 0, sizeof(P) * (v+1));
  1520 + cjv[0] = 1;
  1521 + }
  1522 +
1497 1523 //iterate through each and scale
1498 1524 for(int n = 0; n<=v; n++)
1499 1525 {
  1526 + if(z != 0){ //handle degenerate case of z = 0
  1527 + cjv[n] = cjv[n] * sqrt(stim::PI/(z * 2.0));
  1528 + cyv[n] = cyv[n] * sqrt(stim::PI/(z * 2.0));
  1529 + }
1500 1530  
1501   - cjv[n] = cjv[n] * sqrt(rtsPI/(z * 2.0));
1502   - cyv[n] = cyv[n] * sqrt(rtsPI/(z * 2.0));
1503   -
1504   - cjvp[n] = -1.0 / (z * 2.0) * cjv[n] + cjvp[n] * sqrt(rtsPI / (z * 2.0));
1505   - cyvp[n] = -1.0 / (z * 2.0) * cyv[n] + cyvp[n] * sqrt(rtsPI / (z * 2.0));
  1531 + cjvp[n] = -1.0 / (z * 2.0) * cjv[n] + cjvp[n] * sqrt(stim::PI / (z * 2.0));
  1532 + cyvp[n] = -1.0 / (z * 2.0) * cyv[n] + cyvp[n] * sqrt(stim::PI / (z * 2.0));
1506 1533 }
1507 1534  
1508 1535 return 0;
... ...
stim/math/circle.h
... ... @@ -17,7 +17,7 @@ class circle : plane&lt;T&gt;
17 17  
18 18 private:
19 19  
20   - stim::vec<T> Y;
  20 + stim::vec3<T> Y;
21 21  
22 22 CUDA_CALLABLE void
23 23 init()
... ... @@ -48,7 +48,7 @@ public:
48 48 circle(T size, T z_pos = (T)0) : plane<T>()
49 49 {
50 50 init();
51   - center(stim::vec<T>(0,0,z_pos));
  51 + center(stim::vec3<T>(0,0,z_pos));
52 52 scale(size);
53 53 }
54 54  
... ... @@ -56,7 +56,7 @@ public:
56 56 ///@param c: x,y,z location of the center.
57 57 ///@param n: x,y,z direction of the normal.
58 58 CUDA_CALLABLE
59   - circle(vec<T> c, vec<T> n = vec<T>(0,0,1)) : plane<T>()
  59 + circle(vec3<T> c, vec3<T> n = vec3<T>(0,0,1)) : plane<T>()
60 60 {
61 61 center(c);
62 62 normal(n);
... ... @@ -68,7 +68,7 @@ public:
68 68 ///@param s: size of the rectangle.
69 69 ///@param n: x,y,z direction of the normal.
70 70 CUDA_CALLABLE
71   - circle(vec<T> c, T s, vec<T> n = vec<T>(0,0,1)) : plane<T>()
  71 + circle(vec3<T> c, T s, vec3<T> n = vec3<T>(0,0,1)) : plane<T>()
72 72 {
73 73 init();
74 74 center(c);
... ... @@ -82,7 +82,7 @@ public:
82 82 ///@param n: x,y,z direction of the normal.
83 83 ///@param u: x,y,z direction for the zero vector (from where the rotation starts)
84 84 CUDA_CALLABLE
85   - circle(vec<T> c, T s, vec<T> n = vec<T>(0,0,1), vec<T> u = vec<T>(1, 0, 0)) : plane<T>()
  85 + circle(vec3<T> c, T s, vec3<T> n = vec3<T>(0,0,1), vec3<T> u = vec3<T>(1, 0, 0)) : plane<T>()
86 86 {
87 87 init();
88 88 setU(u);
... ... @@ -103,16 +103,15 @@ public:
103 103 ///sets the normal for the cirlce
104 104 ///@param n: x,y,z direction of the normal.
105 105 CUDA_CALLABLE void
106   - normal(vec<T> n)
  106 + normal(vec3<T> n)
107 107 {
108 108 rotate(n, Y);
109 109 }
110 110  
111 111 ///sets the center of the circle.
112 112 ///@param n: x,y,z location of the center.
113   - CUDA_CALLABLE T
114   - center(vec<T> p)
115   - {
  113 + CUDA_CALLABLE void
  114 + center(vec3<T> p){
116 115 this->P = p;
117 116 }
118 117  
... ... @@ -127,17 +126,17 @@ public:
127 126 }
128 127  
129 128 ///get the world space value given the planar coordinates a, b in [0, 1]
130   - CUDA_CALLABLE stim::vec<T> p(T a, T b)
  129 + CUDA_CALLABLE stim::vec3<T> p(T a, T b)
131 130 {
132   - stim::vec<T> result;
  131 + stim::vec3<T> result;
133 132  
134   - vec<T> A = this->P - this->U * (T)0.5 - Y * (T)0.5;
  133 + vec3<T> A = this->P - this->U * (T)0.5 - Y * (T)0.5;
135 134 result = A + this->U * a + Y * b;
136 135 return result;
137 136 }
138 137  
139 138 ///parenthesis operator returns the world space given rectangular coordinates a and b in [0 1]
140   - CUDA_CALLABLE stim::vec<T> operator()(T a, T b)
  139 + CUDA_CALLABLE stim::vec3<T> operator()(T a, T b)
141 140 {
142 141 return p(a,b);
143 142 }
... ... @@ -145,11 +144,11 @@ public:
145 144 ///returns a vector with the points on the initialized circle.
146 145 ///connecting the points results in a circle.
147 146 ///@param n: integer for the number of points representing the circle.
148   - std::vector<stim::vec<T> >
  147 + std::vector<stim::vec3<T> >
149 148 getPoints(int n)
150 149 {
151   - std::vector<stim::vec<T> > result;
152   - stim::vec<T> point;
  150 + std::vector<stim::vec3<T> > result;
  151 + stim::vec3<T> point;
153 152 T x,y;
154 153 float step = 360.0/(float) n;
155 154 for(float j = 0; j <= 360.0; j += step)
... ... @@ -164,7 +163,7 @@ public:
164 163 ///returns a vector with the points on the initialized circle.
165 164 ///connecting the points results in a circle.
166 165 ///@param n: integer for the number of points representing the circle.
167   - stim::vec<T>
  166 + stim::vec3<T>
168 167 p(T theta)
169 168 {
170 169 T x,y;
... ...
stim/math/complex.h
1   -/*RTS Complex number class. This class is CUDA compatible,
2   -and can therefore be used in CUDA code and on CUDA devices.
3   -*/
  1 +/// CUDA compatible complex number class
4 2  
5   -#ifndef RTS_COMPLEX
6   -#define RTS_COMPLEX
  3 +#ifndef STIM_COMPLEX
  4 +#define STIM_COMPLEX
7 5  
8   -#include "../cuda/callable.h"
  6 +#include "../cuda/cudatools/callable.h"
9 7 #include <cmath>
10 8 #include <string>
11 9 #include <sstream>
... ... @@ -13,6 +11,7 @@ and can therefore be used in CUDA code and on CUDA devices.
13 11  
14 12 namespace stim
15 13 {
  14 + enum complexComponentType {complexReal, complexImaginary, complexMag};
16 15  
17 16 template <class T>
18 17 struct complex
... ... @@ -230,12 +229,6 @@ struct complex
230 229 return result;
231 230 }
232 231  
233   - /*CUDA_CALLABLE complex<T> pow(int y)
234   - {
235   -
236   - return pow((double)y);
237   - }*/
238   -
239 232 CUDA_CALLABLE complex<T> pow(T y)
240 233 {
241 234 complex<T> result;
... ... @@ -328,8 +321,31 @@ struct complex
328 321 return *this;
329 322 }
330 323  
  324 +
  325 +
331 326 };
332 327  
  328 +/// Cast an array of complex values to an array of real values
  329 +template<typename T>
  330 +static void real(T* r, complex<T>* c, size_t n){
  331 + for(size_t i = 0; i < n; i++)
  332 + r[i] = c[i].real();
  333 +}
  334 +
  335 +/// Cast an array of complex values to an array of real values
  336 +template<typename T>
  337 +static void imag(T* r, complex<T>* c, size_t n){
  338 + for(size_t i = 0; i < n; i++)
  339 + r[i] = c[i].imag();
  340 +}
  341 +
  342 +/// Calculate the magnitude of an array of complex values
  343 +template<typename T>
  344 +static void abs(T* m, complex<T>* c, size_t n){
  345 + for(size_t i = 0; i < n; i++)
  346 + m[i] = c[i].abs();
  347 +}
  348 +
333 349 } //end RTS namespace
334 350  
335 351 //addition
... ... @@ -432,17 +448,6 @@ CUDA_CALLABLE static T imag(stim::complex&lt;T&gt; a)
432 448 return a.i;
433 449 }
434 450  
435   -//trigonometric functions
436   -//template<class A>
437   -/*CUDA_CALLABLE static stim::complex<float> sinf(const stim::complex<float> x)
438   -{
439   - stim::complex<float> result;
440   - result.r = sinf(x.r) * coshf(x.i);
441   - result.i = cosf(x.r) * sinhf(x.i);
442   -
443   - return result;
444   -}*/
445   -
446 451 template<class A>
447 452 CUDA_CALLABLE stim::complex<A> sin(const stim::complex<A> x)
448 453 {
... ... @@ -453,17 +458,6 @@ CUDA_CALLABLE stim::complex&lt;A&gt; sin(const stim::complex&lt;A&gt; x)
453 458 return result;
454 459 }
455 460  
456   -//floating point template
457   -//template<class A>
458   -/*CUDA_CALLABLE static stim::complex<float> cosf(const stim::complex<float> x)
459   -{
460   - stim::complex<float> result;
461   - result.r = cosf(x.r) * coshf(x.i);
462   - result.i = -(sinf(x.r) * sinhf(x.i));
463   -
464   - return result;
465   -}*/
466   -
467 461 template<class A>
468 462 CUDA_CALLABLE stim::complex<A> cos(const stim::complex<A> x)
469 463 {
... ... @@ -496,10 +490,4 @@ std::istream&amp; operator&gt;&gt;(std::istream&amp; is, stim::complex&lt;A&gt;&amp; x)
496 490 return is; //return the stream
497 491 }
498 492  
499   -//#if __GNUC__ > 3 && __GNUC_MINOR__ > 7
500   -//template<class T> using rtsComplex = stim::complex<T>;
501   -//#endif
502   -
503   -
504   -
505 493 #endif
... ...
stim/math/constants.h
1   -#ifndef RTS_CONSTANTS_H
2   -#define RTS_CONSTANTS_H
  1 +#ifndef STIM_CONSTANTS_H
  2 +#define STIM_CONSTANTS_H
3 3  
4   -#define stimPI 3.14159
5   -#define stimTAU 2 * rtsPI
  4 +#include "stim/cuda/cudatools/callable.h"
  5 +namespace stim{
  6 + const double PI = 3.1415926535897932384626433832795028841971693993751058209749445923078164062862;
  7 + const double TAU = 2 * stim::PI;
  8 +}
6 9  
7 10 #endif
... ...
stim/math/fft.h 0 โ†’ 100644
  1 +#ifndef STIM_FFT_H
  2 +#define STIM_FFT_H
  3 +
  4 +namespace stim{
  5 +
  6 + template<class T>
  7 + void circshift(T *out, const T *in, size_t xdim, size_t ydim, size_t xshift, size_t yshift){
  8 + size_t i, j, ii, jj;
  9 + for (i =0; i < xdim; i++) {
  10 + ii = (i + xshift) % xdim;
  11 + for (j = 0; j < ydim; j++) {
  12 + jj = (j + yshift) % ydim;
  13 + out[ii * ydim + jj] = in[i * ydim + j];
  14 + }
  15 + }
  16 + }
  17 +
  18 + template<typename T>
  19 + void cpu_fftshift(T* out, T* in, size_t xdim, size_t ydim){
  20 + circshift(out, in, xdim, ydim, xdim/2, ydim/2);
  21 + }
  22 +
  23 + template<typename T>
  24 + void cpu_ifftshift(T* out, T* in, size_t xdim, size_t ydim){
  25 + circshift(out, in, xdim, ydim, xdim/2, ydim/2);
  26 + }
  27 +
  28 +
  29 +}
  30 +
  31 +#endif
0 32 \ No newline at end of file
... ...
stim/math/legendre.h
1 1 #ifndef RTS_LEGENDRE_H
2 2 #define RTS_LEGENDRE_H
3 3  
4   -#include "rts/cuda/callable.h"
  4 +#include "../cuda/cudatools/callable.h"
5 5  
6 6 namespace stim{
7 7  
... ... @@ -24,9 +24,11 @@ CUDA_CALLABLE void shift_legendre(int n, T x, T&amp; P0, T&amp; P1)
24 24 P1 = Pnew;
25 25 }
26 26  
  27 +/// Iteratively evaluates the Legendre polynomials for orders l = [0 n]
27 28 template <typename T>
28 29 CUDA_CALLABLE void legendre(int n, T x, T* P)
29 30 {
  31 + if(n < 0) return;
30 32 P[0] = 1;
31 33  
32 34 if(n >= 1)
... ...
stim/math/matrix.h
... ... @@ -5,6 +5,7 @@
5 5 #include <string.h>
6 6 #include <iostream>
7 7 #include <stim/math/vector.h>
  8 +#include <stim/math/vec3.h>
8 9 #include <stim/cuda/cudatools/callable.h>
9 10  
10 11 namespace stim{
... ... @@ -50,10 +51,8 @@ struct matrix
50 51 return *this;
51 52 }
52 53  
53   -
54 54 template<typename Y>
55   - CUDA_CALLABLE vec<Y> operator*(vec<Y> rhs)
56   - {
  55 + vec<Y> operator*(vec<Y> rhs){
57 56 unsigned int N = rhs.size();
58 57  
59 58 vec<Y> result;
... ... @@ -66,6 +65,16 @@ struct matrix
66 65 return result;
67 66 }
68 67  
  68 + template<typename Y>
  69 + CUDA_CALLABLE vec3<Y> operator*(vec3<Y> rhs){
  70 + vec3<Y> result = 0;
  71 + for(int r=0; r<3; r++)
  72 + for(int c=0; c<3; c++)
  73 + result[r] += (*this)(r, c) * rhs[c];
  74 +
  75 + return result;
  76 + }
  77 +
69 78 std::string toStr()
70 79 {
71 80 std::stringstream ss;
... ... @@ -82,10 +91,6 @@ struct matrix
82 91  
83 92 return ss.str();
84 93 }
85   -
86   -
87   -
88   -
89 94 };
90 95  
91 96 } //end namespace rts
... ...
stim/math/meshgrid.h 0 โ†’ 100644
  1 +#ifndef STIM_MESHGRID_H
  2 +#define STIM_MESHGRID_H
  3 +
  4 +namespace stim{
  5 +
  6 + /// Create a 2D grid based on a pair of vectors representing the grid spacing (see Matlab)
  7 + /// @param X is an [nx x ny] array that will store the X coordinates for each 2D point
  8 + /// @param Y is an [nx x ny] array that will store the Y coordinates for each 2D point
  9 + /// @param x is an [nx] array that provides the positions of grid points in the x direction
  10 + /// @param nx is the number of grid points in the x direction
  11 + /// @param y is an [ny] array that provides the positions of grid points in the y direction
  12 + /// @param ny is the number of grid points in the y direction
  13 + template<typename T>
  14 + void meshgrid(T* X, T* Y, T* x, size_t nx, T* y, size_t ny){
  15 + size_t xi, yi; //allocate index variables
  16 + for(yi = 0; yi < ny; yi++){ //iterate through each column
  17 + for(xi = 0; xi < nx; xi++){ //iterate through each row
  18 + X[yi * nx + xi] = x[xi];
  19 + Y[yi * nx + xi] = y[yi];
  20 + }
  21 + }
  22 + }
  23 +
  24 + /// Creates an array of n equally spaced values in the range [xmin xmax]
  25 + /// @param X is an array of length n that stores the values
  26 + /// @param xmin is the start point of the array
  27 + /// @param xmax is the end point of the array
  28 + /// @param n is the number of points in the array
  29 + template<typename T>
  30 + void linspace(T* X, T xmin, T xmax, size_t n){
  31 + T alpha;
  32 + for(size_t i = 0; i < n; i++){
  33 + alpha = (T)i / (T)n;
  34 + X[i] = (1 - alpha) * xmin + alpha * xmax;
  35 + }
  36 + }
  37 +
  38 +
  39 +}
  40 +
  41 +
  42 +#endif
0 43 \ No newline at end of file
... ...
stim/math/plane.h
... ... @@ -2,7 +2,7 @@
2 2 #define STIM_PLANE_H
3 3  
4 4 #include <iostream>
5   -#include <stim/math/vector.h>
  5 +#include <stim/math/vec3.h>
6 6 #include <stim/cuda/cudatools/callable.h>
7 7 #include <stim/math/quaternion.h>
8 8  
... ... @@ -22,17 +22,17 @@ template &lt;typename T&gt;
22 22 class plane
23 23 {
24 24 protected:
25   - stim::vec<T> P;
26   - stim::vec<T> N;
27   - stim::vec<T> U;
  25 + stim::vec3<T> P;
  26 + stim::vec3<T> N;
  27 + stim::vec3<T> U;
28 28  
29 29 ///Initializes the plane with standard coordinates.
30 30 ///
31 31 CUDA_CALLABLE void init()
32 32 {
33   - P = stim::vec<T>(0, 0, 0);
34   - N = stim::vec<T>(0, 0, 1);
35   - U = stim::vec<T>(1, 0, 0);
  33 + P = stim::vec3<T>(0, 0, 0);
  34 + N = stim::vec3<T>(0, 0, 1);
  35 + U = stim::vec3<T>(1, 0, 0);
36 36 }
37 37  
38 38 public:
... ... @@ -42,7 +42,7 @@ class plane
42 42 init();
43 43 }
44 44  
45   - CUDA_CALLABLE plane(vec<T> n, vec<T> p = vec<T>(0, 0, 0))
  45 + CUDA_CALLABLE plane(vec3<T> n, vec3<T> p = vec3<T>(0, 0, 0))
46 46 {
47 47 init();
48 48 P = p;
... ... @@ -56,11 +56,11 @@ class plane
56 56 }
57 57  
58 58 //create a plane from three points (a triangle)
59   - CUDA_CALLABLE plane(vec<T> a, vec<T> b, vec<T> c)
  59 + CUDA_CALLABLE plane(vec3<T> a, vec3<T> b, vec3<T> c)
60 60 {
61 61 init();
62 62 P = c;
63   - stim::vec<T> n = (c - a).cross(b - a);
  63 + stim::vec3<T> n = (c - a).cross(b - a);
64 64 try
65 65 {
66 66 if(n.len() != 0)
... ... @@ -84,17 +84,17 @@ class plane
84 84  
85 85 }
86 86  
87   - CUDA_CALLABLE vec<T> n()
  87 + CUDA_CALLABLE vec3<T> n()
88 88 {
89 89 return N;
90 90 }
91 91  
92   - CUDA_CALLABLE vec<T> p()
  92 + CUDA_CALLABLE vec3<T> p()
93 93 {
94 94 return P;
95 95 }
96 96  
97   - CUDA_CALLABLE vec<T> u()
  97 + CUDA_CALLABLE vec3<T> u()
98 98 {
99 99 return U;
100 100 }
... ... @@ -107,7 +107,7 @@ class plane
107 107 }
108 108  
109 109 //determines how a vector v intersects the plane (1 = intersects front, 0 = within plane, -1 = intersects back)
110   - CUDA_CALLABLE int face(vec<T> v){
  110 + CUDA_CALLABLE int face(vec3<T> v){
111 111  
112 112 T dprod = v.dot(N); //get the dot product between v and N
113 113  
... ... @@ -121,46 +121,46 @@ class plane
121 121 }
122 122  
123 123 //determine on which side of the plane a point lies (1 = front, 0 = on the plane, -1 = bac k)
124   - CUDA_CALLABLE int side(vec<T> p){
  124 + CUDA_CALLABLE int side(vec3<T> p){
125 125  
126   - vec<T> v = p - P; //get the vector from P to the query point p
  126 + vec3<T> v = p - P; //get the vector from P to the query point p
127 127  
128 128 return face(v);
129 129 }
130 130  
131 131 //compute the component of v that is perpendicular to the plane
132   - CUDA_CALLABLE vec<T> perpendicular(vec<T> v){
  132 + CUDA_CALLABLE vec3<T> perpendicular(vec3<T> v){
133 133 return N * v.dot(N);
134 134 }
135 135  
136 136 //compute the projection of v in the plane
137   - CUDA_CALLABLE vec<T> parallel(vec<T> v){
  137 + CUDA_CALLABLE vec3<T> parallel(vec3<T> v){
138 138 return v - perpendicular(v);
139 139 }
140 140  
141   - CUDA_CALLABLE void setU(vec<T> v)
  141 + CUDA_CALLABLE void setU(vec3<T> v)
142 142 {
143 143 U = (parallel(v.norm())).norm();
144 144 }
145 145  
146   - CUDA_CALLABLE void decompose(vec<T> v, vec<T>& para, vec<T>& perp){
  146 + CUDA_CALLABLE void decompose(vec3<T> v, vec3<T>& para, vec3<T>& perp){
147 147 perp = N * v.dot(N);
148 148 para = v - perp;
149 149 }
150 150  
151 151 //get both the parallel and perpendicular components of a vector v w.r.t. the plane
152   - CUDA_CALLABLE void project(vec<T> v, vec<T> &v_par, vec<T> &v_perp){
  152 + CUDA_CALLABLE void project(vec3<T> v, vec3<T> &v_par, vec3<T> &v_perp){
153 153  
154 154 v_perp = v.dot(N);
155 155 v_par = v - v_perp;
156 156 }
157 157  
158 158 //compute the reflection of v off of the plane
159   - CUDA_CALLABLE vec<T> reflect(vec<T> v){
  159 + CUDA_CALLABLE vec3<T> reflect(vec3<T> v){
160 160  
161 161 //compute the reflection using N_prime as the plane normal
162   - vec<T> par = parallel(v);
163   - vec<T> r = (-v) + par * 2;
  162 + vec3<T> par = parallel(v);
  163 + vec3<T> r = (-v) + par * 2;
164 164 return r;
165 165  
166 166 }
... ... @@ -184,7 +184,7 @@ class plane
184 184 }
185 185  
186 186  
187   - CUDA_CALLABLE void rotate(vec<T> n)
  187 + CUDA_CALLABLE void rotate(vec3<T> n)
188 188 {
189 189 quaternion<T> q;
190 190 q.CreateRotation(N, n);
... ... @@ -194,7 +194,7 @@ class plane
194 194  
195 195 }
196 196  
197   - CUDA_CALLABLE void rotate(vec<T> n, vec<T> &Y)
  197 + CUDA_CALLABLE void rotate(vec3<T> n, vec3<T> &Y)
198 198 {
199 199 quaternion<T> q;
200 200 q.CreateRotation(N, n);
... ... @@ -205,7 +205,7 @@ class plane
205 205  
206 206 }
207 207  
208   - CUDA_CALLABLE void rotate(vec<T> n, vec<T> &X, vec<T> &Y)
  208 + CUDA_CALLABLE void rotate(vec3<T> n, vec3<T> &X, vec3<T> &Y)
209 209 {
210 210 quaternion<T> q;
211 211 q.CreateRotation(N, n);
... ...
stim/math/plane_old.h deleted
1   -#ifndef RTS_PLANE_H
2   -#define RTS_PLANE_H
3   -
4   -#include <iostream>
5   -#include <stim/math/vector.h>
6   -#include "rts/cuda/callable.h"
7   -
8   -
9   -namespace stim{
10   -template <typename T, int D> class plane;
11   -}
12   -
13   -template <typename T, int D>
14   -CUDA_CALLABLE stim::plane<T, D> operator-(stim::plane<T, D> v);
15   -
16   -namespace stim{
17   -
18   -template <class T, int D = 3>
19   -class plane{
20   -
21   - //a plane is defined by a point and a normal
22   -
23   -private:
24   -
25   - vec<T, D> P; //point on the plane
26   - vec<T, D> N; //plane normal
27   -
28   - CUDA_CALLABLE void init(){
29   - P = vec<T, D>(0, 0, 0);
30   - N = vec<T, D>(0, 0, 1);
31   - }
32   -
33   -
34   -public:
35   -
36   - //default constructor
37   - CUDA_CALLABLE plane(){
38   - init();
39   - }
40   -
41   - CUDA_CALLABLE plane(vec<T, D> n, vec<T, D> p = vec<T, D>(0, 0, 0)){
42   - P = p;
43   - N = n.norm();
44   - }
45   -
46   - CUDA_CALLABLE plane(T z_pos){
47   - init();
48   - P[2] = z_pos;
49   - }
50   -
51   - //create a plane from three points (a triangle)
52   - CUDA_CALLABLE plane(vec<T, D> a, vec<T, D> b, vec<T, D> c){
53   - P = c;
54   - N = (c - a).cross(b - a);
55   - if(N.len() == 0) //handle the degenerate case when two vectors are the same, N = 0
56   - N = 0;
57   - else
58   - N = N.norm();
59   - }
60   -
61   - template< typename U >
62   - CUDA_CALLABLE operator plane<U, D>(){
63   -
64   - plane<U, D> result(N, P);
65   - return result;
66   - }
67   -
68   - CUDA_CALLABLE vec<T, D> norm(){
69   - return N;
70   - }
71   -
72   - CUDA_CALLABLE vec<T, D> p(){
73   - return P;
74   - }
75   -
76   - //flip the plane front-to-back
77   - CUDA_CALLABLE plane<T, D> flip(){
78   - plane<T, D> result = *this;
79   - result.N = -result.N;
80   - return result;
81   - }
82   -
83   - //determines how a vector v intersects the plane (1 = intersects front, 0 = within plane, -1 = intersects back)
84   - CUDA_CALLABLE int face(vec<T, D> v){
85   -
86   - T dprod = v.dot(N); //get the dot product between v and N
87   -
88   - //conditional returns the appropriate value
89   - if(dprod < 0)
90   - return 1;
91   - else if(dprod > 0)
92   - return -1;
93   - else
94   - return 0;
95   - }
96   -
97   - //determine on which side of the plane a point lies (1 = front, 0 = on the plane, -1 = back)
98   - CUDA_CALLABLE int side(vec<T, D> p){
99   -
100   - vec<T, D> v = p - P; //get the vector from P to the query point p
101   -
102   - return face(v);
103   - }
104   -
105   - //compute the component of v that is perpendicular to the plane
106   - CUDA_CALLABLE vec<T, D> perpendicular(vec<T, D> v){
107   - return N * v.dot(N);
108   - }
109   -
110   - //compute the projection of v in the plane
111   - CUDA_CALLABLE vec<T, D> parallel(vec<T, D> v){
112   - return v - perpendicular(v);
113   - }
114   -
115   - CUDA_CALLABLE void decompose(vec<T, D> v, vec<T, D>& para, vec<T, D>& perp){
116   - perp = N * v.dot(N);
117   - para = v - perp;
118   - }
119   -
120   - //get both the parallel and perpendicular components of a vector v w.r.t. the plane
121   - CUDA_CALLABLE void project(vec<T, D> v, vec<T, D> &v_par, vec<T, D> &v_perp){
122   -
123   - v_perp = v.dot(N);
124   - v_par = v - v_perp;
125   - }
126   -
127   - //compute the reflection of v off of the plane
128   - CUDA_CALLABLE vec<T, D> reflect(vec<T, D> v){
129   -
130   - //compute the reflection using N_prime as the plane normal
131   - vec<T, D> par = parallel(v);
132   - vec<T, D> r = (-v) + par * 2;
133   -
134   - /*std::cout<<"----------------REFLECT-----------------------------"<<std::endl;
135   - std::cout<<str()<<std::endl;
136   - std::cout<<"v: "<<v<<std::endl;
137   - std::cout<<"r: "<<r<<std::endl;
138   - std::cout<<"Perpendicular: "<<perpendicular(v)<<std::endl;
139   - std::cout<<"Parallel: "<<par<<std::endl;*/
140   - return r;
141   -
142   - }
143   -
144   - CUDA_CALLABLE rts::plane<T, D> operator-()
145   - {
146   - rts::plane<T, D> p = *this;
147   -
148   - //negate the normal vector
149   - p.N = -p.N;
150   -
151   - return p;
152   - }
153   -
154   - //output a string
155   - std::string str(){
156   - std::stringstream ss;
157   - ss<<"P: "<<P<<std::endl;
158   - ss<<"N: "<<N;
159   - return ss.str();
160   - }
161   -
162   - ///////Friendship
163   - //friend CUDA_CALLABLE rts::plane<T, D> operator- <> (rts::plane<T, D> v);
164   -
165   -
166   -
167   -};
168   -
169   -}
170   -
171   -//arithmetic operators
172   -
173   -//negative operator flips the plane (front to back)
174   -//template <typename T, int D>
175   -
176   -
177   -
178   -
179   -#endif
stim/math/quad.h deleted
1   -#ifndef RTS_QUAD_H
2   -#define RTS_QUAD_H
3   -
4   -//enable CUDA_CALLABLE macro
5   -#include <stim/cuda/callable.h>
6   -#include <stim/math/vector.h>
7   -#include <stim/math/triangle.h>
8   -#include <stim/math/quaternion.h>
9   -#include <iostream>
10   -#include <iomanip>
11   -#include <algorithm>
12   -
13   -namespace stim{
14   -
15   -//template for a quadangle class in ND space
16   -template <class T, int N = 3>
17   -struct quad
18   -{
19   - /*
20   - B------------------>C
21   - ^ ^
22   - | |
23   - Y |
24   - | |
25   - | |
26   - A---------X-------->O
27   - */
28   -
29   - /*T A[N];
30   - T B[N];
31   - T C[N];*/
32   -
33   - rts::vec<T, N> A;
34   - rts::vec<T, N> X;
35   - rts::vec<T, N> Y;
36   -
37   -
38   - CUDA_CALLABLE quad()
39   - {
40   -
41   - }
42   -
43   - CUDA_CALLABLE quad(vec<T, N> a, vec<T, N> b, vec<T, N> c)
44   - {
45   -
46   - A = a;
47   - Y = b - a;
48   - X = c - a - Y;
49   -
50   - }
51   -
52   - /*******************************************************************
53   - Constructor - create a quad from a position, normal, and rotation
54   - *******************************************************************/
55   - CUDA_CALLABLE quad(rts::vec<T, N> c, rts::vec<T, N> normal, T width, T height, T theta)
56   - {
57   -
58   - //compute the X direction - start along world-space X
59   - Y = rts::vec<T, N>(0, 1, 0);
60   - if(Y == normal)
61   - Y = rts::vec<T, N>(0, 0, 1);
62   -
63   - X = Y.cross(normal).norm();
64   -
65   - std::cout<<X<<std::endl;
66   -
67   - //rotate the X axis by theta radians
68   - rts::quaternion<T> q;
69   - q.CreateRotation(theta, normal);
70   - X = q.toMatrix3() * X;
71   - Y = normal.cross(X);
72   -
73   - //normalize everything
74   - X = X.norm();
75   - Y = Y.norm();
76   -
77   - //scale to match the quad width and height
78   - X = X * width;
79   - Y = Y * height;
80   -
81   - //set the corner of the plane
82   - A = c - X * 0.5f - Y * 0.5f;
83   -
84   - std::cout<<X<<std::endl;
85   - }
86   -
87   - //boolean comparison
88   - bool operator==(const quad<T, N> & rhs)
89   - {
90   - if(A == rhs.A && X == rhs.X && Y == rhs.Y)
91   - return true;
92   - else
93   - return false;
94   - }
95   -
96   - /*******************************************
97   - Return the normal for the quad
98   - *******************************************/
99   - CUDA_CALLABLE rts::vec<T, N> n()
100   - {
101   - return (X.cross(Y)).norm();
102   - }
103   -
104   - CUDA_CALLABLE rts::vec<T, N> p(T a, T b)
105   - {
106   - rts::vec<T, N> result;
107   - //given the two parameters a, b = [0 1], returns the position in world space
108   - result = A + X * a + Y * b;
109   -
110   - return result;
111   - }
112   -
113   - CUDA_CALLABLE rts::vec<T, N> operator()(T a, T b)
114   - {
115   - return p(a, b);
116   - }
117   -
118   - std::string str()
119   - {
120   - std::stringstream ss;
121   -
122   - ss<<std::left<<"B="<<setfill('-')<<setw(20)<<A + Y<<">"<<"C="<<A + Y + X<<std::endl;
123   - ss<<setfill(' ')<<setw(23)<<"|"<<"|"<<std::endl<<setw(23)<<"|"<<"|"<<std::endl;
124   - ss<<std::left<<"A="<<setfill('-')<<setw(20)<<A<<">"<<"D="<<A + X;
125   -
126   - return ss.str();
127   -
128   - }
129   -
130   - CUDA_CALLABLE quad<T, N> operator*(T rhs)
131   - {
132   - //scales the plane by a scalar value
133   -
134   - //compute the center point
135   - rts::vec<T, N> c = A + X*0.5f + Y*0.5f;
136   -
137   - //create the new quadangle
138   - quad<T, N> result;
139   - result.X = X * rhs;
140   - result.Y = Y * rhs;
141   - result.A = c - result.X*0.5f - result.Y*0.5f;
142   -
143   - return result;
144   -
145   - }
146   -
147   - CUDA_CALLABLE T dist(vec<T, N> p)
148   - {
149   - //compute the distance between a point and this quad
150   -
151   - //first break the quad up into two triangles
152   - triangle<T, N> T0(A, A+X, A+Y);
153   - triangle<T, N> T1(A+X+Y, A+X, A+Y);
154   -
155   -
156   - T d0 = T0.dist(p);
157   - T d1 = T1.dist(p);
158   -
159   - if(d0 < d1)
160   - return d0;
161   - else
162   - return d1;
163   - }
164   -
165   - CUDA_CALLABLE T dist_max(vec<T, N> p)
166   - {
167   - T da = (A - p).len();
168   - T db = (A+X - p).len();
169   - T dc = (A+Y - p).len();
170   - T dd = (A+X+Y - p).len();
171   -
172   - return std::max( da, std::max(db, std::max(dc, dd) ) );
173   - }
174   -};
175   -
176   -} //end namespace rts
177   -
178   -template <typename T, int N>
179   -std::ostream& operator<<(std::ostream& os, rts::quad<T, N> R)
180   -{
181   - os<<R.str();
182   - return os;
183   -}
184   -
185   -
186   -#endif
stim/math/quaternion.h
... ... @@ -26,13 +26,13 @@ public:
26 26  
27 27 CUDA_CALLABLE void CreateRotation(T theta, T ux, T uy, T uz){
28 28  
29   - vec<T> u(ux, uy, uz);
  29 + vec3<T> u(ux, uy, uz);
30 30 CreateRotation(theta, u);
31 31 }
32 32  
33   - CUDA_CALLABLE void CreateRotation(T theta, vec<T> u){
  33 + CUDA_CALLABLE void CreateRotation(T theta, vec3<T> u){
34 34  
35   - vec<T> u_hat = u.norm();
  35 + vec3<T> u_hat = u.norm();
36 36  
37 37 //assign the given Euler rotation to this quaternion
38 38 w = (T)cos(theta/2);
... ... @@ -41,9 +41,11 @@ public:
41 41 z = u_hat[2]*(T)sin(theta/2);
42 42 }
43 43  
44   - void CreateRotation(vec<T> from, vec<T> to){
  44 + CUDA_CALLABLE void CreateRotation(vec3<T> from, vec3<T> to){
45 45  
46   - vec<T> r = from.cross(to); //compute the rotation vector
  46 + from = from.norm();
  47 + to = to.norm();
  48 + vec3<T> r = from.cross(to); //compute the rotation vector
47 49 T theta = asin(r.len()); //compute the angle of the rotation about r
48 50 //deal with a zero vector (both k and kn point in the same direction)
49 51 if(theta == (T)0){
... ...
stim/math/rect.h
... ... @@ -28,13 +28,10 @@ class rect : plane &lt;T&gt;
28 28 O---------X--------->
29 29 */
30 30  
31   -private:
32   -
33   - stim::vec<T> X;
34   - stim::vec<T> Y;
35   -
36   -
  31 +protected:
37 32  
  33 + stim::vec3<T> X;
  34 + stim::vec3<T> Y;
38 35  
39 36 public:
40 37  
... ... @@ -65,7 +62,7 @@ public:
65 62 ///create a rectangle from a center point, normal
66 63 ///@param c: x,y,z location of the center.
67 64 ///@param n: x,y,z direction of the normal.
68   - CUDA_CALLABLE rect(vec<T> c, vec<T> n = vec<T>(0, 0, 1))
  65 + CUDA_CALLABLE rect(vec3<T> c, vec3<T> n = vec3<T>(0, 0, 1))
69 66 : plane<T>()
70 67