Commit 35a7195f62dc2428df5f4b6024956ebdb8713e1b

Authored by David Mayerich
1 parent 1b2858a2

added median spectra to ENVI files, updated mean spectra in interleave formats

matlab/enviLoadRaw.m
1 %loads an ENVI file without any manipulation (changing orientation) 1 %loads an ENVI file without any manipulation (changing orientation)
  2 +% enviLoadRaw(filename, headername)
2 function M = enviLoadRaw(filename, headername) 3 function M = enviLoadRaw(filename, headername)
3 4
4 %if a header isn't provided, assume it's just the filename 5 %if a header isn't provided, assume it's just the filename
matlab/enviSaveRaw.m
1 %saves an ENVI file without any manipulation, assumes (X, Y, S) 1 %saves an ENVI file without any manipulation, assumes (X, Y, S)
  2 +% enviSaveRaw(M, filename, headername)
2 function enviSaveRaw(M, filename, headername) 3 function enviSaveRaw(M, filename, headername)
3 4
4 %if a header isn't provided, assume it's just the filename 5 %if a header isn't provided, assume it's just the filename
stim/cuda/cudatools/error.h
@@ -11,12 +11,7 @@ using namespace std; @@ -11,12 +11,7 @@ using namespace std;
11 //handle error macro 11 //handle error macro
12 static void HandleError( cudaError_t err, const char *file, int line ) { 12 static void HandleError( cudaError_t err, const char *file, int line ) {
13 if (err != cudaSuccess) { 13 if (err != cudaSuccess) {
14 - //FILE* outfile = fopen("cudaErrorLog.txt", "w");  
15 - //fprintf(outfile, "%s in %s at line %d\n", cudaGetErrorString( err ), file, line );  
16 - //fclose(outfile);  
17 printf("%s in %s at line %d\n", cudaGetErrorString( err ), file, line ); 14 printf("%s in %s at line %d\n", cudaGetErrorString( err ), file, line );
18 - //exit( EXIT_FAILURE );  
19 -  
20 } 15 }
21 } 16 }
22 #define HANDLE_ERROR( err ) (HandleError( err, __FILE__, __LINE__ )) 17 #define HANDLE_ERROR( err ) (HandleError( err, __FILE__, __LINE__ ))
@@ -992,32 +992,35 @@ public: @@ -992,32 +992,35 @@ public:
992 992
993 /// @param p is a pointer to pre-allocated memory of size [B * sizeof(T)] that stores the mean spectrum 993 /// @param p is a pointer to pre-allocated memory of size [B * sizeof(T)] that stores the mean spectrum
994 /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location 994 /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location
995 - bool avg_band(double* p, unsigned char* mask = NULL, bool PROGRESS = false){ 995 + bool mean_spectrum(double* m, double* std, unsigned char* mask = NULL, bool PROGRESS = false){
996 unsigned long long XZ = X() * Z(); 996 unsigned long long XZ = X() * Z();
997 unsigned long long XY = X() * Y(); 997 unsigned long long XY = X() * Y();
998 T* temp = (T*)malloc(sizeof(T) * XZ); 998 T* temp = (T*)malloc(sizeof(T) * XZ);
999 - for (unsigned long long j = 0; j < Z(); j++){  
1000 - p[j] = 0;  
1001 - } 999 + memset(m, 0, Z() * sizeof(double)); //initialize the mean to zero
  1000 + double* e_x2 = (double*)malloc(Z() * sizeof(double)); //allocate space for E[x^2]
  1001 + memset(e_x2, 0, Z() * sizeof(double)); //initialize E[x^2] to zero
1002 //calculate vaild number in a band 1002 //calculate vaild number in a band
1003 - unsigned long long count = 0;  
1004 - for (unsigned long long j = 0; j < XY; j++){  
1005 - if (mask == NULL || mask[j] != 0){  
1006 - count++;  
1007 - }  
1008 - } 1003 + size_t count = nnz(mask); //count the number of pixels in the mask
  1004 +
  1005 + double x; //create a register to store the pixel value
1009 for (unsigned long long k = 0; k < Y(); k++){ 1006 for (unsigned long long k = 0; k < Y(); k++){
1010 read_plane_y(temp, k); 1007 read_plane_y(temp, k);
1011 unsigned long long kx = k * X(); 1008 unsigned long long kx = k * X();
1012 for (unsigned long long i = 0; i < X(); i++){ 1009 for (unsigned long long i = 0; i < X(); i++){
1013 if (mask == NULL || mask[kx + i] != 0){ 1010 if (mask == NULL || mask[kx + i] != 0){
1014 for (unsigned long long j = 0; j < Z(); j++){ 1011 for (unsigned long long j = 0; j < Z(); j++){
1015 - p[j] += temp[j * X() + i] / (double)count; 1012 + x = temp[j * X() + i];
  1013 + m[j] += x / (double)count;
  1014 + e_x2[j] += x*x / (double)count;
1016 } 1015 }
1017 } 1016 }
1018 } 1017 }
1019 if(PROGRESS) progress = (double)(k+1) / Y() * 100; 1018 if(PROGRESS) progress = (double)(k+1) / Y() * 100;
1020 } 1019 }
  1020 +
  1021 + for(size_t i = 0; i < Z(); i++) //calculate the standard deviation
  1022 + std[i] = sqrt(e_x2[i] - m[i] * m[i]);
  1023 +
1021 free(temp); 1024 free(temp);
1022 return true; 1025 return true;
1023 } 1026 }
@@ -954,26 +954,31 @@ public: @@ -954,26 +954,31 @@ public:
954 954
955 /// @param p is a pointer to pre-allocated memory of size [B * sizeof(T)] that stores the mean spectrum 955 /// @param p is a pointer to pre-allocated memory of size [B * sizeof(T)] that stores the mean spectrum
956 /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location 956 /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location
957 - bool avg_band(double* p, unsigned char* mask = NULL, bool PROGRESS = false){ 957 + bool mean_spectrum(double* m, double* std, unsigned char* mask = NULL, bool PROGRESS = false){
958 unsigned long long XY = X() * Y(); //calculate the total number of pixels in the HSI 958 unsigned long long XY = X() * Y(); //calculate the total number of pixels in the HSI
959 T* temp = (T*)malloc(sizeof(T) * Z()); //allocate space for the current spectrum to be read 959 T* temp = (T*)malloc(sizeof(T) * Z()); //allocate space for the current spectrum to be read
960 - memset(p, 0, sizeof(double) * Z()); //initialize the average spectrum to zero (0)  
961 - //for (unsigned j = 0; j < Z(); j++){  
962 - // p[j] = 0;  
963 - //} 960 + memset(m, 0, Z() * sizeof(double)); //set the mean spectrum to zero
  961 + double* e_x2 = (double*)malloc(Z() * sizeof(double)); //allocate space for E[x^2]
  962 + memset(e_x2, 0, Z() * sizeof(double)); //set all values for E[x^2] to zero
964 963
965 unsigned long long count = nnz(mask); //calculate the number of masked pixels 964 unsigned long long count = nnz(mask); //calculate the number of masked pixels
966 - 965 + double x;
967 for (unsigned long long i = 0; i < XY; i++){ //for each pixel in the HSI 966 for (unsigned long long i = 0; i < XY; i++){ //for each pixel in the HSI
968 if (mask == NULL || mask[i] != 0){ //if the pixel is masked 967 if (mask == NULL || mask[i] != 0){ //if the pixel is masked
969 pixel(temp, i); //get the spectrum 968 pixel(temp, i); //get the spectrum
970 for (unsigned long long j = 0; j < Z(); j++){ //for each spectral component 969 for (unsigned long long j = 0; j < Z(); j++){ //for each spectral component
971 - p[j] += (double)temp[j] / (double)count; //add the weighted value to the average 970 + x = temp[j];
  971 + m[j] += x / (double)count; //add the weighted value to the average
  972 + e_x2[j] += x*x / (double)count;
972 } 973 }
973 } 974 }
974 if(PROGRESS) progress = (double)(i+1) / XY * 100; //increment the progress 975 if(PROGRESS) progress = (double)(i+1) / XY * 100; //increment the progress
975 } 976 }
976 977
  978 + //calculate the standard deviation
  979 + for(size_t i = 0; i < Z(); i++)
  980 + std[i] = sqrt(e_x2[i] - m[i] * m[i]);
  981 +
977 free(temp); 982 free(temp);
978 return true; 983 return true;
979 } 984 }
@@ -561,12 +561,12 @@ public: @@ -561,12 +561,12 @@ public:
561 free(src[1]); 561 free(src[1]);
562 free(dst[0]); 562 free(dst[0]);
563 free(dst[1]); 563 free(dst[1]);
564 - //if(VERBOSE){ 564 + if(VERBOSE){
565 std::cout<<"total time to execute bsq::bip(): "<<t_total<<" ms"<<std::endl; 565 std::cout<<"total time to execute bsq::bip(): "<<t_total<<" ms"<<std::endl;
566 std::cout<<" total time spent processing: "<<pt_total<<" ms"<<std::endl; 566 std::cout<<" total time spent processing: "<<pt_total<<" ms"<<std::endl;
567 std::cout<<" total time spent reading: "<<rt_total<<" ms"<<std::endl; 567 std::cout<<" total time spent reading: "<<rt_total<<" ms"<<std::endl;
568 std::cout<<" total time spent writing: "<<wt_total<<" ms"<<std::endl; 568 std::cout<<" total time spent writing: "<<wt_total<<" ms"<<std::endl;
569 - //} 569 + }
570 return true; //return true 570 return true; //return true
571 } 571 }
572 572
@@ -1120,27 +1120,61 @@ public: @@ -1120,27 +1120,61 @@ public:
1120 1120
1121 /// @param p is a pointer to pre-allocated memory of size [B * sizeof(T)] that stores the mean spectrum 1121 /// @param p is a pointer to pre-allocated memory of size [B * sizeof(T)] that stores the mean spectrum
1122 /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location 1122 /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location
1123 - bool avg_band(double* p, unsigned char* mask = NULL, bool PROGRESS = false){ 1123 + bool mean_spectrum(double* m, double* std, unsigned char* mask = NULL, bool PROGRESS = false){
1124 unsigned long long XY = X() * Y(); 1124 unsigned long long XY = X() * Y();
1125 - unsigned long long count = 0; //count will store the number of masked pixels 1125 + unsigned long long count = nnz(mask); //count will store the number of masked pixels
1126 T* temp = (T*)malloc(sizeof(T) * XY); 1126 T* temp = (T*)malloc(sizeof(T) * XY);
1127 - //calculate this loop counts the number of true pixels in the mask  
1128 - for (unsigned j = 0; j < XY; j++){  
1129 - if (mask == NULL || mask[j] != 0){  
1130 - count++;  
1131 - }  
1132 - } 1127 +
1133 //this loops goes through each band in B (Z()) 1128 //this loops goes through each band in B (Z())
1134 // masked (or valid) pixels from that band are averaged and the average is stored in p 1129 // masked (or valid) pixels from that band are averaged and the average is stored in p
  1130 + double e_x; //stores E[x]^2
  1131 + double e_x2; //stores E[x^2]
  1132 + double x;
1135 for (unsigned long long i = 0; i < Z(); i++){ 1133 for (unsigned long long i = 0; i < Z(); i++){
1136 - p[i] = 0; 1134 + e_x = 0;
  1135 + e_x2 = 0;
1137 band_index(temp, i); //get the band image and store it in temp 1136 band_index(temp, i); //get the band image and store it in temp
1138 for (unsigned long long j = 0; j < XY; j++){ //loop through temp, averaging valid pixels 1137 for (unsigned long long j = 0; j < XY; j++){ //loop through temp, averaging valid pixels
1139 if (mask == NULL || mask[j] != 0){ 1138 if (mask == NULL || mask[j] != 0){
1140 - p[i] += (double)temp[j] / (double)count; 1139 + x = (double)temp[j];
  1140 + e_x += x / (double)count; //sum the expected value of x
  1141 + e_x2 += (x * x) / (double)count; //sum the expected value of x^2
  1142 + }
  1143 + }
  1144 + m[i] = e_x; //store the mean
  1145 + std[i] = sqrt(e_x2 - e_x * e_x); //calculate the standard deviation
  1146 + if(PROGRESS) progress = (double)(i+1) / Z() * 100; //update the progress counter
  1147 + }
  1148 + free(temp);
  1149 + return true;
  1150 + }
  1151 +
  1152 + /// Calculate the median value for all masked (or valid) pixels in a band and returns the median spectrum
  1153 +
  1154 + /// @param p is a pointer to pre-allocated memory of size [B * sizeof(T)] that stores the mean spectrum
  1155 + /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location
  1156 + bool median_spectrum(double* m, unsigned char* mask = NULL, bool PROGRESS = false){
  1157 + size_t XY = X() * Y();
  1158 + size_t count = nnz(mask); //count will store the number of masked pixels
  1159 + T* temp = (T*)malloc(sizeof(T) * XY);
  1160 +
  1161 + std::vector<T> band_values(count); //create an STD vector of band values
  1162 +
  1163 + //this loops goes through each band in B (Z())
  1164 + // masked (or valid) pixels from that band are averaged and the average is stored in p
  1165 + size_t k;
  1166 + for (size_t i = 0; i < Z(); i++){ //for each band
  1167 + band_index(temp, i); //get the band image and store it in temp
  1168 + k = 0; //initialize the band_value index to zero
  1169 + for (size_t j = 0; j < XY; j++){ //loop through temp, averaging valid pixels
  1170 + if (mask == NULL || mask[j] != 0){
  1171 + band_values[k] = temp[j]; //store the value in the band_values array
  1172 + k++; //increment the band_values index
1141 } 1173 }
1142 } 1174 }
1143 - if(PROGRESS) progress = (double)(i+1) / Z() * 100; 1175 + std::sort(band_values.begin(), band_values.end()); //sort all of the values in the band
  1176 + m[i] = band_values[ count/2 ]; //store the center value in the array
  1177 + if(PROGRESS) progress = (double)(i+1) / Z() * 100; //update the progress counter
1144 } 1178 }
1145 free(temp); 1179 free(temp);
1146 return true; 1180 return true;
@@ -1380,12 +1380,12 @@ public: @@ -1380,12 +1380,12 @@ public:
1380 1380
1381 /// @param p is a pointer to pre-allocated memory of size [B * sizeof(T)] that stores the mean spectrum 1381 /// @param p is a pointer to pre-allocated memory of size [B * sizeof(T)] that stores the mean spectrum
1382 /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location 1382 /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location
1383 - bool avg_band(double * p, unsigned char* mask, bool PROGRESS = false){ 1383 + bool mean_spectrum(double * p, double* std, unsigned char* mask, bool PROGRESS = false){
1384 if (header.interleave == envi_header::BSQ){ 1384 if (header.interleave == envi_header::BSQ){
1385 if (header.data_type == envi_header::float32) 1385 if (header.data_type == envi_header::float32)
1386 - return ((bsq<float>*)file)->avg_band(p, mask, PROGRESS); 1386 + return ((bsq<float>*)file)->mean_spectrum(p, std, mask, PROGRESS);
1387 else if (header.data_type == envi_header::float64) 1387 else if (header.data_type == envi_header::float64)
1388 - return ((bsq<double>*)file)->avg_band(p, mask, PROGRESS); 1388 + return ((bsq<double>*)file)->mean_spectrum(p, std, mask, PROGRESS);
1389 else{ 1389 else{
1390 std::cout << "ERROR: unidentified data type" << std::endl; 1390 std::cout << "ERROR: unidentified data type" << std::endl;
1391 exit(1); 1391 exit(1);
@@ -1393,9 +1393,9 @@ public: @@ -1393,9 +1393,9 @@ public:
1393 } 1393 }
1394 else if (header.interleave == envi_header::BIL){ 1394 else if (header.interleave == envi_header::BIL){
1395 if (header.data_type == envi_header::float32) 1395 if (header.data_type == envi_header::float32)
1396 - return ((bil<float>*)file)->avg_band(p, mask, PROGRESS); 1396 + return ((bil<float>*)file)->mean_spectrum(p, std, mask, PROGRESS);
1397 else if (header.data_type == envi_header::float64) 1397 else if (header.data_type == envi_header::float64)
1398 - return ((bil<double>*)file)->avg_band(p, mask, PROGRESS); 1398 + return ((bil<double>*)file)->mean_spectrum(p, std, mask, PROGRESS);
1399 else{ 1399 else{
1400 std::cout << "ERROR: unidentified data type" << std::endl; 1400 std::cout << "ERROR: unidentified data type" << std::endl;
1401 exit(1); 1401 exit(1);
@@ -1403,9 +1403,9 @@ public: @@ -1403,9 +1403,9 @@ public:
1403 } 1403 }
1404 else if (header.interleave == envi_header::BIP){ 1404 else if (header.interleave == envi_header::BIP){
1405 if (header.data_type == envi_header::float32) 1405 if (header.data_type == envi_header::float32)
1406 - return ((bip<float>*)file)->avg_band(p, mask, PROGRESS); 1406 + return ((bip<float>*)file)->mean_spectrum(p, std, mask, PROGRESS);
1407 else if (header.data_type == envi_header::float64) 1407 else if (header.data_type == envi_header::float64)
1408 - return ((bip<double>*)file)->avg_band(p, mask, PROGRESS); 1408 + return ((bip<double>*)file)->mean_spectrum(p, std, mask, PROGRESS);
1409 else{ 1409 else{
1410 std::cout << "ERROR: unidentified data type" << std::endl; 1410 std::cout << "ERROR: unidentified data type" << std::endl;
1411 exit(1); 1411 exit(1);
@@ -1414,6 +1414,28 @@ public: @@ -1414,6 +1414,28 @@ public:
1414 return false; 1414 return false;
1415 } 1415 }
1416 1416
  1417 + /// Calculate the mean value for all masked (or valid) pixels in a band and returns the average spectrum
  1418 +
  1419 + /// @param p is a pointer to pre-allocated memory of size [B * sizeof(T)] that stores the mean spectrum
  1420 + /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location
  1421 + bool median_spectrum(double* m, unsigned char* mask, bool PROGRESS = false){
  1422 + if (header.interleave == envi_header::BSQ){
  1423 + if (header.data_type == envi_header::float32)
  1424 + return ((bsq<float>*)file)->median_spectrum(m, mask, PROGRESS);
  1425 + else if (header.data_type == envi_header::float64)
  1426 + return ((bsq<double>*)file)->median_spectrum(m, mask, PROGRESS);
  1427 + else{
  1428 + std::cout << "ERROR: unidentified data type" << std::endl;
  1429 + exit(1);
  1430 + }
  1431 + }
  1432 + else{
  1433 + std::cout<<"ERROR: median calculation is only supported for BSQ interleave types. Convert to process."<<std::endl;
  1434 + exit(1);
  1435 + }
  1436 + return false;
  1437 + }
  1438 +
1417 /// Calculate the covariance matrix for all masked pixels in the image. 1439 /// Calculate the covariance matrix for all masked pixels in the image.
1418 1440
1419 /// @param co is a pointer to pre-allocated memory of size [B * B] that stores the resulting covariance matrix 1441 /// @param co is a pointer to pre-allocated memory of size [B * B] that stores the resulting covariance matrix
stim/gl/gl_spider.h
@@ -473,7 +473,7 @@ class gl_spider // : public virtual gl_texture&lt;T&gt; @@ -473,7 +473,7 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
473 glEndList(); ///finilize the display list. 473 glEndList(); ///finilize the display list.
474 #ifdef DEBUG 474 #ifdef DEBUG
475 for(int i = 0; i < numSamplesPos; i++) 475 for(int i = 0; i < numSamplesPos; i++)
476 - std::cout << pV[i] << std::endl; 476 + std::cout << pV[i].str() << std::endl;
477 #endif 477 #endif
478 } 478 }
479 479
@@ -1145,8 +1145,8 @@ class gl_spider // : public virtual gl_texture&lt;T&gt; @@ -1145,8 +1145,8 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
1145 out[3] = temp[2]; 1145 out[3] = temp[2];
1146 } 1146 }
1147 #ifdef DEBUG 1147 #ifdef DEBUG
1148 - std::cout << "out is " << out << std::endl;  
1149 - std::cout << "when rotating from " << from << " to " << dir << std::endl; 1148 + std::cout << "out is " << out.str() << std::endl;
  1149 + std::cout << "when rotating from " << from.str() << " to " << dir.str() << std::endl;
1150 #endif 1150 #endif
1151 return out; 1151 return out;
1152 } 1152 }
@@ -1531,7 +1531,7 @@ class gl_spider // : public virtual gl_texture&lt;T&gt; @@ -1531,7 +1531,7 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
1531 setMagnitude(curSeedMag); 1531 setMagnitude(curSeedMag);
1532 1532
1533 #ifdef DEBUG 1533 #ifdef DEBUG
1534 - std::cout << "The new seed " << curSeed << curSeedVec << curSeedMag << std::endl; 1534 + std::cout << "The new seed " << curSeed.str() << curSeedVec.str() << curSeedMag << std::endl;
1535 #endif 1535 #endif
1536 1536
1537 // Bind(direction_texID, direction_buffID, numSamples, n_pixels); 1537 // Bind(direction_texID, direction_buffID, numSamples, n_pixels);
stim/math/vector.h
@@ -74,11 +74,11 @@ struct vec : public std::vector&lt;T&gt; @@ -74,11 +74,11 @@ struct vec : public std::vector&lt;T&gt;
74 at(i) = other[i]; 74 at(i) = other[i];
75 } 75 }
76 } 76 }
77 - 77 +
78 // vec( vec3<T>& other){ 78 // vec( vec3<T>& other){
79 // resize(3); //resize the current vector to match the copy 79 // resize(3); //resize the current vector to match the copy
80 // for(size_t i=0; i<3; i++){ //copy each element 80 // for(size_t i=0; i<3; i++){ //copy each element
81 -// at(i) = other[i]; 81 +// at(i) = other[i];
82 // } 82 // }
83 // } 83 // }
84 84
@@ -139,16 +139,16 @@ struct vec : public std::vector&lt;T&gt; @@ -139,16 +139,16 @@ struct vec : public std::vector&lt;T&gt;
139 139
140 } 140 }
141 141
142 -  
143 - vec<T> cyl2cart() const  
144 - {  
145 - vec<T> cyl;  
146 - cyl.push_back(at(0)*std::sin(at(1)));  
147 - cyl.push_back(at(0)*std::cos(at(1)));  
148 - cyl.push_back(at(2));  
149 - return(cyl);  
150 -  
151 - } 142 +
  143 + vec<T> cyl2cart() const
  144 + {
  145 + vec<T> cyl;
  146 + cyl.push_back(at(0)*std::sin(at(1)));
  147 + cyl.push_back(at(0)*std::cos(at(1)));
  148 + cyl.push_back(at(2));
  149 + return(cyl);
  150 +
  151 + }
152 /// Convert the vector from cartesian to spherical coordinates (x, y, z -> r, theta, phi where theta = [0, 2*pi]) 152 /// Convert the vector from cartesian to spherical coordinates (x, y, z -> r, theta, phi where theta = [0, 2*pi])
153 vec<T> cart2sph() const 153 vec<T> cart2sph() const
154 { 154 {
@@ -335,16 +335,16 @@ struct vec : public std::vector&lt;T&gt; @@ -335,16 +335,16 @@ struct vec : public std::vector&lt;T&gt;
335 return *this; 335 return *this;
336 } 336 }
337 337
338 - /// Cast to a vec3  
339 - operator stim::vec3<T>(){  
340 - stim::vec3<T> r;  
341 - size_t N = std::min<size_t>(size(), 3);  
342 - for(size_t i = 0; i < N; i++)  
343 - r[i] = at(i);  
344 - return r;  
345 - }  
346 -  
347 - 338 + /// Cast to a vec3
  339 + operator stim::vec3<T>(){
  340 + stim::vec3<T> r;
  341 + size_t N = min(size(), (size_t)3);
  342 + for(size_t i = 0; i < N; i++)
  343 + r[i] = at(i);
  344 + return r;
  345 + }
  346 +
  347 +
348 /// Casting and assignment 348 /// Casting and assignment
349 template<typename Y> 349 template<typename Y>
350 vec<T> & operator=(vec<Y> rhs){ 350 vec<T> & operator=(vec<Y> rhs){
@@ -355,16 +355,16 @@ struct vec : public std::vector&lt;T&gt; @@ -355,16 +355,16 @@ struct vec : public std::vector&lt;T&gt;
355 at(i) = rhs[i]; 355 at(i) = rhs[i];
356 return *this; 356 return *this;
357 } 357 }
358 -  
359 - /// Assign a vec = vec3  
360 - template<typename Y>  
361 - vec<T> & operator=(vec3<Y> rhs)  
362 - {  
363 - resize(3);  
364 - for(size_t i=0; i<3; i++)  
365 - at(i) = rhs[i];  
366 - return *this;  
367 - } 358 +
  359 + /// Assign a vec = vec3
  360 + template<typename Y>
  361 + vec<T> & operator=(vec3<Y> rhs)
  362 + {
  363 + resize(3);
  364 + for(size_t i=0; i<3; i++)
  365 + at(i) = rhs[i];
  366 + return *this;
  367 + }
368 368
369 /// Unary minus (returns the negative of the vector) 369 /// Unary minus (returns the negative of the vector)
370 vec<T> operator-() const{ 370 vec<T> operator-() const{