Commit 8ffb8373b71fd5d6e8327b372b67c50fb8df43f9

Authored by dmayerich
1 parent 4198e3be

Improved materials and the Kramers-Kronig solver.

@@ -25,6 +25,9 @@ find_package(GLUT REQUIRED) @@ -25,6 +25,9 @@ find_package(GLUT REQUIRED)
25 #find GLEW 25 #find GLEW
26 find_package(GLEW REQUIRED) 26 find_package(GLEW REQUIRED)
27 27
  28 +#find Qwt
  29 +find_package(Qwt REQUIRED)
  30 +
28 #add Qt OpenGL stuff 31 #add Qt OpenGL stuff
29 set(QT_USE_QTOPENGL TRUE) 32 set(QT_USE_QTOPENGL TRUE)
30 33
@@ -53,9 +56,10 @@ file(GLOB SRC_CU "*.cu") @@ -53,9 +56,10 @@ file(GLOB SRC_CU "*.cu")
53 #set up copying data files 56 #set up copying data files
54 configure_file(kPMMA.txt ${CMAKE_CURRENT_BINARY_DIR}/kPMMA.txt @ONLY) 57 configure_file(kPMMA.txt ${CMAKE_CURRENT_BINARY_DIR}/kPMMA.txt @ONLY)
55 configure_file(eta_polystyreneK.txt ${CMAKE_CURRENT_BINARY_DIR}/eta_polystyreneK.txt @ONLY) 58 configure_file(eta_polystyreneK.txt ${CMAKE_CURRENT_BINARY_DIR}/eta_polystyreneK.txt @ONLY)
56 -configure_file(eta_TolueneK.txt ${CMAKE_CURRENT_BINARY_DIR}/eta_TolueneK.txt @ONLY)  
57 -configure_file(eta_TolueneN.txt ${CMAKE_CURRENT_BINARY_DIR}/eta_TolueneN.txt @ONLY) 59 +configure_file(etaToluene.txt ${CMAKE_CURRENT_BINARY_DIR}/etaToluene.txt @ONLY)
58 configure_file(source_midIR.txt ${CMAKE_CURRENT_BINARY_DIR}/source_midIR.txt @ONLY) 60 configure_file(source_midIR.txt ${CMAKE_CURRENT_BINARY_DIR}/source_midIR.txt @ONLY)
  61 +configure_file(kPolyethylene.txt ${CMAKE_CURRENT_BINARY_DIR}/kPolyethylene.txt @ONLY)
  62 +configure_file(kPTFE.txt ${CMAKE_CURRENT_BINARY_DIR}/kPTFE.txt @ONLY)
59 63
60 #determine which source files have to be moc'd 64 #determine which source files have to be moc'd
61 Qt4_wrap_cpp(UI_MOC ${SRC_H}) 65 Qt4_wrap_cpp(UI_MOC ${SRC_H})
@@ -72,7 +76,4 @@ source_group(QtUI FILES ${SRC_UI}) @@ -72,7 +76,4 @@ source_group(QtUI FILES ${SRC_UI})
72 cuda_add_executable(IMie ${SRC_CPP} ${SRC_H} ${UI_H} ${UI_MOC} ${ALL_RCC} ${SRC_CU}) 76 cuda_add_executable(IMie ${SRC_CPP} ${SRC_H} ${UI_H} ${UI_MOC} ${ALL_RCC} ${SRC_CU})
73 77
74 #set the link libraries 78 #set the link libraries
75 -target_link_libraries(IMie ${QT_LIBRARIES} ${QT_QTOPENGL_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${GLEW_LIBRARY})  
76 -  
77 -  
78 - 79 +target_link_libraries(IMie ${QT_LIBRARIES} ${QT_QTOPENGL_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${GLEW_LIBRARY} ${QWT_LIBRARY})
79 \ No newline at end of file 80 \ No newline at end of file
EstimateMaterial.cpp
1 -#include "globals.h"  
2 -#include <stdlib.h>  
3 -#define PI 3.14159  
4 -  
5 -double CalculateError(double* E)  
6 -{  
7 - //Calculate the error between the Reference Spectrum and the Simulated Spectrum  
8 - double sumE = 0.0;  
9 - int nVals = RefSpectrum[currentSpec].size();  
10 - double nu;  
11 - for(int i=0; i<nVals; i++)  
12 - {  
13 - nu = RefSpectrum[currentSpec][i].nu;  
14 - E[i] = RefSpectrum[currentSpec][i].A + nu * refSlope - SimSpectrum[i].A;  
15 - sumE += E[i]*E[i];  
16 - }  
17 -  
18 - return sumE/nVals;  
19 -}  
20 -  
21 -void EstimateK(double* E)  
22 -{  
23 - int nVals = RefSpectrum[currentSpec].size();  
24 - double nuStart = RefSpectrum[currentSpec].front().nu;  
25 - double nuEnd = RefSpectrum[currentSpec].back().nu;  
26 -  
27 - double r = radius/10000.0;  
28 - double nu;  
29 - double dNu = (nuEnd - nuStart)/(nVals-1);  
30 - double eScale;  
31 - for(int i=0; i<nVals; i++)  
32 - {  
33 - nu = nuStart + i*2;  
34 -  
35 - eScale = 1/(8*PI*r*nu);  
36 - EtaK[i].A = EtaK[i].A + eScale * E[i];  
37 - if(EtaK[i].A < 0.0) EtaK[i].A = 0.0;  
38 - }  
39 -}  
40 -  
41 -void EstimateMaterial()  
42 -{  
43 - /*This function estimates the material properties of a sphere based on the  
44 - input spectrum RefSpectrum and the optical properties of the system.  
45 - 1) The material properties are stored in EtaK and EtaN  
46 - 2) The best fit is stored in SimSpectrum*/  
47 -  
48 - //initialize the material index of refraction  
49 - EtaN.clear();  
50 - EtaK.clear();  
51 -  
52 - //insert the default material properties  
53 - SpecPair temp;  
54 - for(int s=0; s<(int)RefSpectrum[currentSpec].size(); s++)  
55 - {  
56 - //the real part of the IR is the user-specified baseline IR  
57 - temp.nu = RefSpectrum[currentSpec][s].nu;  
58 - temp.A = baseIR;  
59 - EtaN.push_back(temp);  
60 - //the imaginary part of the IR is zero absorbance  
61 - temp.A = 0.0f;  
62 - EtaK.push_back(temp);  
63 - }  
64 -  
65 -  
66 - //allocate space to store the list of error values  
67 - double* E = (double*)malloc(sizeof(double) * RefSpectrum[currentSpec].size());  
68 - //copy the absorbance values into a linear array  
69 - double* k = (double*)malloc(sizeof(double) * EtaK.size());  
70 - double* n = (double*)malloc(sizeof(double) * EtaN.size());  
71 -  
72 - //iterate to solve for both n and k  
73 - double sumE = 99999.9;  
74 - int j=0;  
75 - //clear the console  
76 - system("cls");  
77 - while(sumE > minMSE && j < maxFitIter)  
78 - {  
79 - //simulate a spectrum based on the current IR  
80 - SimulateSpectrum();  
81 -  
82 - //calculate the error term  
83 - sumE = CalculateError(E);  
84 -  
85 - //estimate the new absorbance  
86 - EstimateK(E);  
87 -  
88 - //use Kramers-Kronig to compute n  
89 -  
90 - for(unsigned int i=0; i<EtaK.size(); i++)  
91 - k[i] = EtaK[i].A;  
92 - cudaKramersKronig(n, k, EtaK.size(), EtaK.front().nu, EtaK.back().nu, baseIR);  
93 -  
94 - //copy the real part of the index of refraction into the vector  
95 - EtaN.clear();  
96 - for(int i=0; i<(int)EtaK.size(); i++)  
97 - {  
98 - temp.nu = EtaK[i].nu;  
99 - temp.A = n[i];  
100 - EtaN.push_back(temp);  
101 - }  
102 -  
103 - cout<<" E = "<<sumE<<endl;  
104 - j++;  
105 - //SaveSpectrum(n, nVals, "simNj.txt");  
106 - //SaveSpectrum(k, nVals, "simKj.txt");  
107 - //SaveSpectrum(simSpec, nVals, "simSpec.txt");  
108 - //exit(1);  
109 -  
110 - }  
111 -  
112 - free(E);  
113 - free(k);  
114 - free(n);  
115 -  
116 -  
117 -  
118 -  
119 -}  
120 \ No newline at end of file 1 \ No newline at end of file
  2 +#include "globals.h"
  3 +#include <stdlib.h>
  4 +#define PI 3.14159
  5 +
  6 +double CalculateError(double* E)
  7 +{
  8 + //Calculate the error between the Reference Spectrum and the Simulated Spectrum
  9 + double sumE = 0.0;
  10 + int nVals = RefSpectrum[currentSpec].size();
  11 + double nu;
  12 + for(int i=0; i<nVals; i++)
  13 + {
  14 + nu = RefSpectrum[currentSpec][i].nu;
  15 + E[i] = RefSpectrum[currentSpec][i].A + nu * refSlope - SimSpectrum[i].A;
  16 + sumE += E[i]*E[i];
  17 + }
  18 +
  19 + return sumE/nVals;
  20 +}
  21 +
  22 +void EstimateK(double* E)
  23 +{
  24 + int nVals = RefSpectrum[currentSpec].size();
  25 + double nuStart = RefSpectrum[currentSpec].front().nu;
  26 + double nuEnd = RefSpectrum[currentSpec].back().nu;
  27 +
  28 + double r = radius/10000.0;
  29 + double nu;
  30 + double dNu = (nuEnd - nuStart)/(nVals-1);
  31 + double eScale;
  32 + for(int i=0; i<nVals; i++)
  33 + {
  34 + nu = nuStart + i*2;
  35 +
  36 + eScale = 1/(8*PI*r*nu);
  37 + EtaK[i].A = EtaK[i].A + eScale * E[i];
  38 + if(EtaK[i].A < 0.0) EtaK[i].A = 0.0;
  39 + }
  40 +}
  41 +
  42 +void EstimateMaterial()
  43 +{
  44 + /*This function estimates the material properties of a sphere based on the
  45 + input spectrum RefSpectrum and the optical properties of the system.
  46 + 1) The material properties are stored in EtaK and EtaN
  47 + 2) The best fit is stored in SimSpectrum*/
  48 +
  49 + //initialize the material index of refraction
  50 + EtaN.clear();
  51 + EtaK.clear();
  52 +
  53 + //insert the default material properties
  54 + SpecPair temp;
  55 + for(int s=0; s<(int)RefSpectrum[currentSpec].size(); s++)
  56 + {
  57 + //the real part of the IR is the user-specified baseline IR
  58 + temp.nu = RefSpectrum[currentSpec][s].nu;
  59 + temp.A = baseIR;
  60 + EtaN.push_back(temp);
  61 + //the imaginary part of the IR is zero absorbance
  62 + temp.A = 0.0f;
  63 + EtaK.push_back(temp);
  64 + }
  65 +
  66 +
  67 + //allocate space to store the list of error values
  68 + double* E = (double*)malloc(sizeof(double) * RefSpectrum[currentSpec].size());
  69 + //copy the absorbance values into a linear array
  70 + double* k = (double*)malloc(sizeof(double) * EtaK.size());
  71 + double* n = (double*)malloc(sizeof(double) * EtaN.size());
  72 +
  73 + //iterate to solve for both n and k
  74 + double sumE = 99999.9;
  75 + int j=0;
  76 + //clear the console
  77 + system("cls");
  78 + while(sumE > minMSE && j < maxFitIter)
  79 + {
  80 + //simulate a spectrum based on the current IR
  81 + SimulateSpectrum();
  82 +
  83 + //calculate the error term
  84 + sumE = CalculateError(E);
  85 +
  86 + //estimate the new absorbance
  87 + EstimateK(E);
  88 +
  89 + //use Kramers-Kronig to compute n
  90 +
  91 + for(unsigned int i=0; i<EtaK.size(); i++)
  92 + k[i] = EtaK[i].A;
  93 + cudaKramersKronig(n, k, EtaK.size(), EtaK.front().nu, EtaK.back().nu, baseIR);
  94 +
  95 + //copy the real part of the index of refraction into the vector
  96 + EtaN.clear();
  97 + for(int i=0; i<(int)EtaK.size(); i++)
  98 + {
  99 + temp.nu = EtaK[i].nu;
  100 + temp.A = n[i];
  101 + EtaN.push_back(temp);
  102 + }
  103 +
  104 + cout<<" E = "<<sumE<<endl;
  105 + j++;
  106 + //SaveSpectrum(n, nVals, "simNj.txt");
  107 + //SaveSpectrum(k, nVals, "simKj.txt");
  108 + //SaveSpectrum(simSpec, nVals, "simSpec.txt");
  109 + //exit(1);
  110 +
  111 + }
  112 +
  113 + free(E);
  114 + free(k);
  115 + free(n);
  116 +
  117 +
  118 +
  119 +
  120 +}
@@ -6,191 +6,198 @@ using namespace std; @@ -6,191 +6,198 @@ using namespace std;
6 6
7 vector<SpecPair> LoadSpectrum(string filename) 7 vector<SpecPair> LoadSpectrum(string filename)
8 { 8 {
9 - //load a spectrum from a file and resample to 2wn intervals  
10 -  
11 - //create the spectrum  
12 - vector<SpecPair> S;  
13 -  
14 - //open the file  
15 - ifstream inFile(filename.c_str());  
16 -  
17 - //read all elements of the file  
18 - SpecPair temp;  
19 - while(!inFile.eof()){  
20 - inFile>>temp.nu;  
21 - inFile>>temp.A;  
22 - S.push_back(temp);  
23 - }  
24 -  
25 - //compute the minimum and maximum input wavenumbers  
26 - double inMin = S.front().nu;  
27 - double inMax = S.back().nu;  
28 -  
29 - int nuMin = (int)ceil(inMin);  
30 - int nuMax = (int)floor(inMax);  
31 -  
32 - //make sure both are either even or odd  
33 - if(nuMin % 2 != nuMax % 2)  
34 - nuMax--;  
35 -  
36 - //compute the number of values in the resampled spectrum  
37 - int nVals = (nuMax - nuMin)/2 + 1;  
38 -  
39 - //allocate space for the spectrum  
40 - vector<SpecPair> outSpec;  
41 -  
42 - double nu, highVal, lowVal, a;  
43 - int j=1;  
44 - for(int i=0; i<nVals; i++)  
45 - {  
46 - nu = nuMin + i * 2;  
47 - temp.nu = nu;  
48 -  
49 - //handle the boundary cases  
50 - if(nu < inMin || nu > inMax)  
51 - temp.A = 0.0;  
52 - else  
53 - {  
54 - //move to the correct position in the input array  
55 - while(j < (int)S.size()-1 && S[j].nu <= nu)  
56 - j++;  
57 -  
58 -  
59 - lowVal = S[j-1].nu;  
60 - highVal = S[j].nu;  
61 - a = (nu - lowVal)/(highVal - lowVal);  
62 - temp.A = S[j-1].A * (1.0 - a) + S[j].A * a;  
63 - }  
64 - outSpec.push_back(temp);  
65 - }  
66 -  
67 -  
68 -  
69 - return outSpec; 9 + //load a spectrum from a file and resample to 2wn intervals
  10 +
  11 + //create the spectrum
  12 + vector<SpecPair> S;
  13 +
  14 + //open the file
  15 + ifstream inFile(filename.c_str());
  16 + if(!inFile)
  17 + {
  18 + cout<<"Error loading spectrum: "<<inFile<<endl;
  19 + return S;
  20 + }
  21 +
  22 + //read all elements of the file
  23 + SpecPair temp;
  24 + while(!inFile.eof()) {
  25 + inFile>>temp.nu;
  26 + inFile>>temp.A;
  27 + S.push_back(temp);
  28 + }
  29 +
  30 + //compute the minimum and maximum input wavenumbers
  31 + double inMin = S.front().nu;
  32 + double inMax = S.back().nu;
  33 +
  34 + int nuMin = (int)ceil(inMin);
  35 + int nuMax = (int)floor(inMax);
  36 +
  37 + //make sure both are either even or odd
  38 + if(nuMin % 2 != nuMax % 2)
  39 + nuMax--;
  40 +
  41 + //compute the number of values in the resampled spectrum
  42 + int nVals = (nuMax - nuMin)/2 + 1;
  43 +
  44 + //allocate space for the spectrum
  45 + vector<SpecPair> outSpec;
  46 +
  47 + double nu, highVal, lowVal, a;
  48 + int j=1;
  49 + for(int i=0; i<nVals; i++)
  50 + {
  51 + nu = nuMin + i * 2;
  52 + temp.nu = nu;
  53 +
  54 + //handle the boundary cases
  55 + if(nu < inMin || nu > inMax)
  56 + temp.A = 0.0;
  57 + else
  58 + {
  59 + //move to the correct position in the input array
  60 + while(j < (int)S.size()-1 && S[j].nu <= nu)
  61 + j++;
  62 +
  63 +
  64 + lowVal = S[j-1].nu;
  65 + highVal = S[j].nu;
  66 + a = (nu - lowVal)/(highVal - lowVal);
  67 + temp.A = S[j-1].A * (1.0 - a) + S[j].A * a;
  68 + }
  69 + outSpec.push_back(temp);
  70 + }
  71 +
  72 +
  73 +
  74 + return outSpec;
70 } 75 }
71 76
72 vector<SpecPair> SetReferenceSpectrum(char* text) 77 vector<SpecPair> SetReferenceSpectrum(char* text)
73 { 78 {
74 - stringstream inString(text); 79 + stringstream inString(text);
75 80
76 - //create the spectrum  
77 - vector<SpecPair> S; 81 + //create the spectrum
  82 + vector<SpecPair> S;
78 83
79 - SpecPair temp;  
80 - while(!inString.eof()){  
81 - inString>>temp.nu;  
82 - inString>>temp.A;  
83 - S.push_back(temp);  
84 - } 84 + SpecPair temp;
  85 + while(!inString.eof()) {
  86 + inString>>temp.nu;
  87 + inString>>temp.A;
  88 + S.push_back(temp);
  89 + }
85 90
86 - return S; 91 + return S;
87 } 92 }
88 93
89 -void SaveK(string fileName) 94 +/*void SaveK(string fileName)
90 { 95 {
91 - ofstream outFile(fileName.c_str());  
92 - for(unsigned int i=0; i<EtaK.size(); i++)  
93 - {  
94 - outFile<<EtaK[i].nu<<" ";  
95 - outFile<<EtaK[i].A<<endl;  
96 - }  
97 - outFile.close();  
98 -}  
99 -  
100 -void SaveN(string fileName) 96 + ofstream outFile(fileName.c_str());
  97 + for(unsigned int i=0; i<EtaK.size(); i++)
  98 + {
  99 + outFile<<EtaK[i].nu<<" ";
  100 + outFile<<EtaK[i].A<<endl;
  101 + }
  102 + outFile.close();
  103 +}*/
  104 +
  105 +void SaveMaterial(string fileName)
101 { 106 {
102 - ofstream outFile(fileName.c_str());  
103 - for(unsigned int i=0; i<EtaN.size(); i++)  
104 - {  
105 - outFile<<EtaN[i].nu<<" ";  
106 - outFile<<EtaN[i].A<<endl;  
107 - }  
108 - outFile.close(); 107 + ofstream outFile(fileName.c_str());
  108 + outFile<<"nu"<<'\t'<<"n"<<'\t'<<"k"<<endl;
  109 + for(unsigned int i=0; i<EtaN.size(); i++)
  110 + {
  111 + outFile<<EtaN[i].nu<<'\t';
  112 + outFile<<EtaN[i].A<<'\t';
  113 + outFile<<EtaK[i].A<<endl;
  114 + }
  115 + outFile.close();
109 } 116 }
110 117
111 void SaveSimulation(string fileName) 118 void SaveSimulation(string fileName)
112 { 119 {
113 - ofstream outFile(fileName.c_str());  
114 - outFile.precision(10);  
115 - for(unsigned int i=0; i<SimSpectrum.size(); i++)  
116 - {  
117 - outFile<<SimSpectrum[i].nu<<" ";  
118 - outFile<<SimSpectrum[i].A<<endl;  
119 - }  
120 - outFile.close(); 120 + ofstream outFile(fileName.c_str());
  121 + outFile.precision(10);
  122 + for(unsigned int i=0; i<SimSpectrum.size(); i++)
  123 + {
  124 + outFile<<SimSpectrum[i].nu<<" ";
  125 + outFile<<SimSpectrum[i].A<<endl;
  126 + }
  127 + outFile.close();
121 } 128 }
122 129
123 void SaveState() 130 void SaveState()
124 { 131 {
125 - ofstream outFile("main.prj");  
126 - //Window Parameters  
127 - outFile<<nuMin<<endl;  
128 - outFile<<nuMax<<endl;  
129 - outFile<<aMin<<endl;  
130 - outFile<<aMax<<endl;  
131 - outFile<<dNu<<endl;  
132 -  
133 - //material parameters  
134 - outFile<<radius<<endl;  
135 - outFile<<baseIR<<endl;  
136 - outFile<<cA<<endl;  
137 -  
138 - //optical parameters  
139 - outFile<<cNAi<<endl;  
140 - outFile<<cNAo<<endl;  
141 - outFile<<oNAi<<endl;  
142 - outFile<<oNAo<<endl;  
143 -  
144 - outFile.close(); 132 + ofstream outFile("main.prj");
  133 + //Window Parameters
  134 + outFile<<nuMin<<endl;
  135 + outFile<<nuMax<<endl;
  136 + outFile<<aMin<<endl;
  137 + outFile<<aMax<<endl;
  138 + outFile<<dNu<<endl;
  139 +
  140 + //material parameters
  141 + outFile<<radius<<endl;
  142 + outFile<<baseIR<<endl;
  143 + outFile<<cA<<endl;
  144 +
  145 + //optical parameters
  146 + outFile<<cNAi<<endl;
  147 + outFile<<cNAo<<endl;
  148 + outFile<<oNAi<<endl;
  149 + outFile<<oNAo<<endl;
  150 +
  151 + outFile.close();
145 152
146 } 153 }
147 154
148 void LoadState() 155 void LoadState()
149 { 156 {
150 - ifstream inFile("main.prj");  
151 - //Window Parameters  
152 - inFile>>nuMin;  
153 - inFile>>nuMax;  
154 - inFile>>aMin;  
155 - inFile>>aMax;  
156 - inFile>>dNu;  
157 -  
158 - //material parameters  
159 - inFile>>radius;  
160 - inFile>>baseIR;  
161 - inFile>>cA;  
162 -  
163 - //optical parameters  
164 - inFile>>cNAi;  
165 - inFile>>cNAo;  
166 - inFile>>oNAi;  
167 - inFile>>oNAo;  
168 -  
169 - inFile.close(); 157 + ifstream inFile("main.prj");
  158 + //Window Parameters
  159 + inFile>>nuMin;
  160 + inFile>>nuMax;
  161 + inFile>>aMin;
  162 + inFile>>aMax;
  163 + inFile>>dNu;
  164 +
  165 + //material parameters
  166 + inFile>>radius;
  167 + inFile>>baseIR;
  168 + inFile>>cA;
  169 +
  170 + //optical parameters
  171 + inFile>>cNAi;
  172 + inFile>>cNAo;
  173 + inFile>>oNAi;
  174 + inFile>>oNAo;
  175 +
  176 + inFile.close();
170 177
171 } 178 }
172 179
173 void SetDefaults() 180 void SetDefaults()
174 { 181 {
175 182
176 - nuMin = 800;  
177 - nuMax = 4000;  
178 - dNu = 2; 183 + nuMin = 800;
  184 + nuMax = 4000;
  185 + dNu = 2;
179 186
180 - aMin = 0;  
181 - aMax = 1; 187 + aMin = 0;
  188 + aMax = 1;
182 189
183 190
184 - //material parameters  
185 - radius = 4.0f;  
186 - baseIR = 1.49f;  
187 - cA = 1.0;  
188 - vector<SpecPair> KMaterial;  
189 - vector<SpecPair> NMaterial; 191 + //material parameters
  192 + radius = 4.0f;
  193 + baseIR = 1.49f;
  194 + cA = 1.0;
  195 + vector<SpecPair> KMaterial;
  196 + vector<SpecPair> NMaterial;
190 197
191 - //optical parameters  
192 - cNAi = 0.0;  
193 - cNAo = 0.6;  
194 - oNAi = 0.0;  
195 - oNAo = 0.6;  
196 -}  
197 \ No newline at end of file 198 \ No newline at end of file
  199 + //optical parameters
  200 + cNAi = 0.0;
  201 + cNAo = 0.6;
  202 + oNAi = 0.0;
  203 + oNAo = 0.6;
  204 +}
1 -// gamma.cpp -- computation of gamma function.  
2 -// Algorithms and coefficient values from "Computation of Special  
3 -// Functions", Zhang and Jin, John Wiley and Sons, 1996.  
4 -//  
5 -// (C) 2003, C. Bond. All rights reserved.  
6 -//  
7 -// Returns gamma function of argument 'x'.  
8 -//  
9 -// NOTE: Returns 1e308 if argument is a negative integer or 0,  
10 -// or if argument exceeds 171.  
11 -//  
12 -#define _USE_MATH_DEFINES  
13 -#include <math.h>  
14 -double gamma(double x)  
15 -{  
16 - int i,k,m;  
17 - double ga,gr,r,z;  
18 -  
19 - static double g[] = {  
20 - 1.0,  
21 - 0.5772156649015329,  
22 - -0.6558780715202538,  
23 - -0.420026350340952e-1,  
24 - 0.1665386113822915,  
25 - -0.421977345555443e-1,  
26 - -0.9621971527877e-2,  
27 - 0.7218943246663e-2,  
28 - -0.11651675918591e-2,  
29 - -0.2152416741149e-3,  
30 - 0.1280502823882e-3,  
31 - -0.201348547807e-4,  
32 - -0.12504934821e-5,  
33 - 0.1133027232e-5,  
34 - -0.2056338417e-6,  
35 - 0.6116095e-8,  
36 - 0.50020075e-8,  
37 - -0.11812746e-8,  
38 - 0.1043427e-9,  
39 - 0.77823e-11,  
40 - -0.36968e-11,  
41 - 0.51e-12,  
42 - -0.206e-13,  
43 - -0.54e-14,  
44 - 0.14e-14};  
45 -  
46 - if (x > 171.0) return 1e308; // This value is an overflow flag.  
47 - if (x == (int)x) {  
48 - if (x > 0.0) {  
49 - ga = 1.0; // use factorial  
50 - for (i=2;i<x;i++) {  
51 - ga *= i;  
52 - }  
53 - }  
54 - else  
55 - ga = 1e308;  
56 - }  
57 - else {  
58 - if (fabs(x) > 1.0) {  
59 - z = fabs(x);  
60 - m = (int)z;  
61 - r = 1.0;  
62 - for (k=1;k<=m;k++) {  
63 - r *= (z-k);  
64 - }  
65 - z -= m;  
66 - }  
67 - else  
68 - z = x;  
69 - gr = g[24];  
70 - for (k=23;k>=0;k--) {  
71 - gr = gr*z+g[k];  
72 - }  
73 - ga = 1.0/(gr*z);  
74 - if (fabs(x) > 1.0) {  
75 - ga *= r;  
76 - if (x < 0.0) {  
77 - ga = -M_PI/(x*ga*sin(M_PI*x));  
78 - }  
79 - }  
80 - }  
81 - return ga;  
82 -} 1 +// gamma.cpp -- computation of gamma function.
  2 +// Algorithms and coefficient values from "Computation of Special
  3 +// Functions", Zhang and Jin, John Wiley and Sons, 1996.
  4 +//
  5 +// (C) 2003, C. Bond. All rights reserved.
  6 +//
  7 +// Returns gamma function of argument 'x'.
  8 +//
  9 +// NOTE: Returns 1e308 if argument is a negative integer or 0,
  10 +// or if argument exceeds 171.
  11 +//
  12 +#define _USE_MATH_DEFINES
  13 +#include <math.h>
  14 +double gamma(double x)
  15 +{
  16 + int i,k,m;
  17 + double ga,gr,r,z;
  18 +
  19 + static double g[] = {
  20 + 1.0,
  21 + 0.5772156649015329,
  22 + -0.6558780715202538,
  23 + -0.420026350340952e-1,
  24 + 0.1665386113822915,
  25 + -0.421977345555443e-1,
  26 + -0.9621971527877e-2,
  27 + 0.7218943246663e-2,
  28 + -0.11651675918591e-2,
  29 + -0.2152416741149e-3,
  30 + 0.1280502823882e-3,
  31 + -0.201348547807e-4,
  32 + -0.12504934821e-5,
  33 + 0.1133027232e-5,
  34 + -0.2056338417e-6,
  35 + 0.6116095e-8,
  36 + 0.50020075e-8,
  37 + -0.11812746e-8,
  38 + 0.1043427e-9,
  39 + 0.77823e-11,
  40 + -0.36968e-11,
  41 + 0.51e-12,
  42 + -0.206e-13,
  43 + -0.54e-14,
  44 + 0.14e-14
  45 + };
  46 +
  47 + if (x > 171.0) return 1e308; // This value is an overflow flag.
  48 + if (x == (int)x) {
  49 + if (x > 0.0) {
  50 + ga = 1.0; // use factorial
  51 + for (i=2; i<x; i++) {
  52 + ga *= i;
  53 + }
  54 + }
  55 + else
  56 + ga = 1e308;
  57 + }
  58 + else {
  59 + if (fabs(x) > 1.0) {
  60 + z = fabs(x);
  61 + m = (int)z;
  62 + r = 1.0;
  63 + for (k=1; k<=m; k++) {
  64 + r *= (z-k);
  65 + }
  66 + z -= m;
  67 + }
  68 + else
  69 + z = x;
  70 + gr = g[24];
  71 + for (k=23; k>=0; k--) {
  72 + gr = gr*z+g[k];
  73 + }
  74 + ga = 1.0/(gr*z);
  75 + if (fabs(x) > 1.0) {
  76 + ga *= r;
  77 + if (x < 0.0) {
  78 + ga = -M_PI/(x*ga*sin(M_PI*x));
  79 + }
  80 + }
  81 + }
  82 + return ga;
  83 +}
1 -// add the following to a cpp file:  
2 -// PerformanceData PD;  
3 -  
4 -  
5 -#pragma once  
6 -#include <ostream>  
7 -using namespace std;  
8 -  
9 -enum PerformanceDataType  
10 -{  
11 - PD_DISPLAY=0,  
12 - PD_SPS,  
13 - PD_UNUSED0,  
14 -  
15 - //my stuff  
16 - SIMULATE_SPECTRUM,  
17 - SIMULATE_GPU,  
18 - KRAMERS_KRONIG,  
19 -  
20 -  
21 -  
22 - //end my stuff  
23 - PERFORMANCE_DATA_TYPE_COUNT  
24 -};  
25 -  
26 -static char PDTypeNames[][255] = {  
27 - "Display ",  
28 - "Simulation Total ",  
29 - " ----------------- ",  
30 - //my stuff  
31 - "Simulate Spectrum ",  
32 - " GPU Portion ",  
33 - "Kramers-Kronig ",  
34 -  
35 - //end my stuff  
36 -  
37 -};  
38 -#ifdef WIN32  
39 -#include <stdio.h>  
40 -#include <windows.h>  
41 -#include <float.h>  
42 -  
43 -#include <iostream>  
44 -#include <iomanip>  
45 -  
46 -//-------------------------------------------------------------------------------  
47 -  
48 -class PerformanceData  
49 -{  
50 -public:  
51 - PerformanceData() { ClearAll(); QueryPerformanceFrequency(&cps); }  
52 - ~PerformanceData(){}  
53 -  
54 - void ClearAll()  
55 - {  
56 - for ( int i=0; i<PERFORMANCE_DATA_TYPE_COUNT; i++ ) {  
57 - for ( int j=0; j<256; j++ ) times[i][j] = 0;  
58 - pos[i] = 0;  
59 - minTime[i] = 0xFFFFFFFF;  
60 - maxTime[i] = 0;  
61 - totalTime[i] = 0;  
62 - dataReady[i] = false;  
63 - }  
64 - }  
65 -  
66 - void StartTimer( int type ) { QueryPerformanceCounter( &startTime[type] );}  
67 - void EndTimer( int type ) {  
68 - LARGE_INTEGER endTime;  
69 - QueryPerformanceCounter( &endTime );  
70 - double t = (double)(endTime.QuadPart - startTime[type].QuadPart);  
71 - //unsigned int t = GetTickCount() - startTime[type];  
72 - if ( t < minTime[type] ) minTime[type] = t;  
73 - if ( t > maxTime[type] ) maxTime[type] = t;  
74 - totalTime[type] -= times[type][ pos[type] ];  
75 - times[type][ pos[type] ] = t;  
76 - totalTime[type] += t;  
77 - pos[type]++;  
78 - if ( pos[type] == 0 ) dataReady[type] = true;  
79 - }  
80 -  
81 - void PrintResult( ostream &os,int i=PERFORMANCE_DATA_TYPE_COUNT)  
82 - {  
83 - os.setf(ios::fixed);  
84 - if ((i<PERFORMANCE_DATA_TYPE_COUNT)&&(i>=0)){  
85 - double a = GetAvrgTime(i);  
86 - if ( a )  
87 - os<< PDTypeNames[i]<<" : avrg="<<setw(8)<<setprecision(3)<<a<<"\tmin="<<setw(8)<<setprecision(3)<< GetMinTime(i) <<"\tmax="<<setw(8)<<setprecision(3)<< GetMaxTime(i) <<endl ;  
88 - else  
89 - os<< PDTypeNames[i]<<" : avrg= -----\tmin= -----\tmax= -----"<<endl;  
90 - }  
91 - }  
92 -  
93 - void PrintResults( ostream &os)  
94 - {  
95 - for ( int i=0; i<PERFORMANCE_DATA_TYPE_COUNT; i++ )  
96 - PrintResult(os,i);  
97 - }  
98 -  
99 - double GetLastTime( int type ) { return times[type][pos[type]]; }  
100 - double GetAvrgTime( int type ) { double a = 1000.0 * totalTime[type] / (float)cps.QuadPart / ( (dataReady[type]) ? 256.0 : (double)pos[type] ); return (_finite(a))? a:0; }  
101 - double GetMinTime( int type ) { return 1000.0 * minTime[type] / (float)cps.LowPart; }  
102 - double GetMaxTime( int type ) { return 1000.0 * maxTime[type] / (float)cps.LowPart; }  
103 -  
104 -private:  
105 - double times[PERFORMANCE_DATA_TYPE_COUNT][256];  
106 - unsigned char pos[PERFORMANCE_DATA_TYPE_COUNT];  
107 - LARGE_INTEGER startTime[PERFORMANCE_DATA_TYPE_COUNT];  
108 - double minTime[ PERFORMANCE_DATA_TYPE_COUNT ];  
109 - double maxTime[ PERFORMANCE_DATA_TYPE_COUNT ];  
110 - double totalTime[ PERFORMANCE_DATA_TYPE_COUNT ];  
111 - bool dataReady[ PERFORMANCE_DATA_TYPE_COUNT ];  
112 - LARGE_INTEGER cps;  
113 -};  
114 -  
115 -//-------------------------------------------------------------------------------  
116 -#else  
117 -  
118 -class PerformanceData{  
119 -public:  
120 - PerformanceData() {;};  
121 - ~PerformanceData(){;};  
122 - void ClearAll(){;};  
123 - void StartTimer( int type ) {;};  
124 - void EndTimer( int type ) {;};  
125 - void PrintResults( ostream &os){;};  
126 - void PrintResult( ostream &os, int i=PERFORMANCE_DATA_TYPE_COUNT){;};  
127 - double GetLastTime( int type ) { return 0.0; };  
128 - double GetAvrgTime( int type ) { return 0.0; };  
129 - double GetMinTime( int type ) { return 0.0; };  
130 - double GetMaxTime( int type ) { return 0.0; };  
131 -};  
132 -  
133 -#endif  
134 -//-------------------------------------------------------------------------------  
135 -  
136 -extern PerformanceData PD;  
137 -  
138 -//------------------------------------------------------------------------------- 1 +// add the following to a cpp file:
  2 +// PerformanceData PD;
  3 +
  4 +
  5 +#pragma once
  6 +#include <ostream>
  7 +using namespace std;
  8 +
  9 +enum PerformanceDataType
  10 +{
  11 + PD_DISPLAY=0,
  12 + PD_SPS,
  13 + PD_UNUSED0,
  14 +
  15 + //my stuff
  16 + SIMULATE_SPECTRUM,
  17 + SIMULATE_GPU,
  18 + KRAMERS_KRONIG,
  19 +
  20 +
  21 +
  22 + //end my stuff
  23 + PERFORMANCE_DATA_TYPE_COUNT
  24 +};
  25 +
  26 +static char PDTypeNames[][255] = {
  27 + "Display ",
  28 + "Simulation Total ",
  29 + " ----------------- ",
  30 + //my stuff
  31 + "Simulate Spectrum ",
  32 + " GPU Portion ",
  33 + "Kramers-Kronig ",
  34 +
  35 + //end my stuff
  36 +
  37 +};
  38 +#ifdef WIN32
  39 +#include <stdio.h>
  40 +#include <windows.h>
  41 +#include <float.h>
  42 +
  43 +#include <iostream>
  44 +#include <iomanip>
  45 +
  46 +//-------------------------------------------------------------------------------
  47 +
  48 +class PerformanceData
  49 +{
  50 +public:
  51 + PerformanceData() {
  52 + ClearAll();
  53 + QueryPerformanceFrequency(&cps);
  54 + }
  55 + ~PerformanceData() {}
  56 +
  57 + void ClearAll()
  58 + {
  59 + for ( int i=0; i<PERFORMANCE_DATA_TYPE_COUNT; i++ ) {
  60 + for ( int j=0; j<256; j++ ) times[i][j] = 0;
  61 + pos[i] = 0;
  62 + minTime[i] = 0xFFFFFFFF;
  63 + maxTime[i] = 0;
  64 + totalTime[i] = 0;
  65 + dataReady[i] = false;
  66 + }
  67 + }
  68 +
  69 + void StartTimer( int type ) {
  70 + QueryPerformanceCounter( &startTime[type] );
  71 + }
  72 + void EndTimer( int type ) {
  73 + LARGE_INTEGER endTime;
  74 + QueryPerformanceCounter( &endTime );
  75 + double t = (double)(endTime.QuadPart - startTime[type].QuadPart);
  76 + //unsigned int t = GetTickCount() - startTime[type];
  77 + if ( t < minTime[type] ) minTime[type] = t;
  78 + if ( t > maxTime[type] ) maxTime[type] = t;
  79 + totalTime[type] -= times[type][ pos[type] ];
  80 + times[type][ pos[type] ] = t;
  81 + totalTime[type] += t;
  82 + pos[type]++;
  83 + if ( pos[type] == 0 ) dataReady[type] = true;
  84 + }
  85 +
  86 + void PrintResult( ostream &os,int i=PERFORMANCE_DATA_TYPE_COUNT)
  87 + {
  88 + os.setf(ios::fixed);
  89 + if ((i<PERFORMANCE_DATA_TYPE_COUNT)&&(i>=0)) {
  90 + double a = GetAvrgTime(i);
  91 + if ( a )
  92 + os<< PDTypeNames[i]<<" : avrg="<<setw(8)<<setprecision(3)<<a<<"\tmin="<<setw(8)<<setprecision(3)<< GetMinTime(i) <<"\tmax="<<setw(8)<<setprecision(3)<< GetMaxTime(i) <<endl ;
  93 + else
  94 + os<< PDTypeNames[i]<<" : avrg= -----\tmin= -----\tmax= -----"<<endl;
  95 + }
  96 + }
  97 +
  98 + void PrintResults( ostream &os)
  99 + {
  100 + for ( int i=0; i<PERFORMANCE_DATA_TYPE_COUNT; i++ )
  101 + PrintResult(os,i);
  102 + }
  103 +
  104 + double GetLastTime( int type ) {
  105 + return times[type][pos[type]];
  106 + }
  107 + double GetAvrgTime( int type ) {
  108 + double a = 1000.0 * totalTime[type] / (float)cps.QuadPart / ( (dataReady[type]) ? 256.0 : (double)pos[type] );
  109 + return (_finite(a))? a:0;
  110 + }
  111 + double GetMinTime( int type ) {
  112 + return 1000.0 * minTime[type] / (float)cps.LowPart;
  113 + }
  114 + double GetMaxTime( int type ) {
  115 + return 1000.0 * maxTime[type] / (float)cps.LowPart;
  116 + }
  117 +
  118 +private:
  119 + double times[PERFORMANCE_DATA_TYPE_COUNT][256];
  120 + unsigned char pos[PERFORMANCE_DATA_TYPE_COUNT];
  121 + LARGE_INTEGER startTime[PERFORMANCE_DATA_TYPE_COUNT];
  122 + double minTime[ PERFORMANCE_DATA_TYPE_COUNT ];
  123 + double maxTime[ PERFORMANCE_DATA_TYPE_COUNT ];
  124 + double totalTime[ PERFORMANCE_DATA_TYPE_COUNT ];
  125 + bool dataReady[ PERFORMANCE_DATA_TYPE_COUNT ];
  126 + LARGE_INTEGER cps;
  127 +};
  128 +
  129 +//-------------------------------------------------------------------------------
  130 +#else
  131 +
  132 +class PerformanceData {
  133 +public:
  134 + PerformanceData() {
  135 + ;
  136 + };
  137 + ~PerformanceData() {
  138 + ;
  139 + };
  140 + void ClearAll() {
  141 + ;
  142 + };
  143 + void StartTimer( int type ) {
  144 + ;
  145 + };
  146 + void EndTimer( int type ) {
  147 + ;
  148 + };
  149 + void PrintResults( ostream &os) {
  150 + ;
  151 + };
  152 + void PrintResult( ostream &os, int i=PERFORMANCE_DATA_TYPE_COUNT) {
  153 + ;
  154 + };
  155 + double GetLastTime( int type ) {
  156 + return 0.0;
  157 + };
  158 + double GetAvrgTime( int type ) {
  159 + return 0.0;
  160 + };
  161 + double GetMinTime( int type ) {
  162 + return 0.0;
  163 + };
  164 + double GetMaxTime( int type ) {
  165 + return 0.0;
  166 + };
  167 +};
  168 +
  169 +#endif
  170 +//-------------------------------------------------------------------------------
  171 +
  172 +extern PerformanceData PD;
  173 +
  174 +//-------------------------------------------------------------------------------
SimulateSpectrum.cpp
1 -#include <math.h>  
2 -#include <complex>  
3 -#include <iostream>  
4 -#include <fstream>  
5 -#include "globals.h"  
6 -#include <QProgressDialog>  
7 -#include <stdlib.h>  
8 -//#include "cufft.h"  
9 -using namespace std;  
10 -  
11 -#define pi 3.14159  
12 -  
13 -typedef complex<double> scComplex;  
14 -  
15 -extern int cbessjyva(double v,complex<double> z,double &vm,complex<double>*cjv,  
16 - complex<double>*cyv,complex<double>*cjvp,complex<double>*cyvp);  
17 -extern int bessjyv(double v,double x,double &vm,double *jv,double *yv,  
18 - double *djv,double *dyv);  
19 -  
20 -complex<double> Jl_neg(complex<double> x)  
21 -{  
22 - //this function computes the bessel function of the first kind Jl(x) for l = -0.5  
23 - return ( sqrt(2.0/pi) * cos(x) )/sqrt(x);  
24 -}  
25 -  
26 -double Jl_neg(double x)  
27 -{  
28 - //this function computes the bessel function of the first kind Jl(x) for l = -0.5  
29 - return ( sqrt(2.0/pi) * cos(x) )/sqrt(x);  
30 -}  
31 -  
32 -double Yl_neg(double x)  
33 -{  
34 - //this function computes the bessel function of the second kind Yl(x) for l = -0.5;  
35 - return ( sqrt(2.0/pi) * sin(x) )/sqrt(x);  
36 -}  
37 -  
38 -void computeB(complex<double>* B, double radius, complex<double> refIndex, double lambda, int Nl)  
39 -{  
40 - double k = (2*pi)/lambda;  
41 - int b = 2;  
42 -  
43 - //allocate space for the real bessel functions  
44 - double* jv = (double*)malloc(sizeof(double)*(Nl+b));  
45 - double* yv = (double*)malloc(sizeof(double)*(Nl+b));  
46 - double* jvp = (double*)malloc(sizeof(double)*(Nl+b));  
47 - double* yvp = (double*)malloc(sizeof(double)*(Nl+b));  
48 -  
49 - //allocate space for the complex bessel functions  
50 - complex<double>* cjv = (complex<double>*)malloc(sizeof(complex<double>)*(Nl+b));  
51 - complex<double>* cyv = (complex<double>*)malloc(sizeof(complex<double>)*(Nl+b));  
52 - complex<double>* cjvp = (complex<double>*)malloc(sizeof(complex<double>)*(Nl+b));  
53 - complex<double>* cyvp = (complex<double>*)malloc(sizeof(complex<double>)*(Nl+b));  
54 -  
55 - double kr = k*radius;  
56 - complex<double> knr = k*refIndex*(double)radius;  
57 - complex<double> n = refIndex;  
58 -  
59 - //compute the bessel functions for k*r  
60 - double vm;// = Nl - 1;  
61 - bessjyv((Nl)+0.5, kr, vm, jv, yv, jvp, yvp);  
62 - //cout<<"Nl: "<<Nl<<" vm: "<<vm<<endl;  
63 - //printf("Nl: %f, vm: %f\n", (float)Nl, (float)vm);  
64 -  
65 - //compute the bessel functions for k*n*r  
66 - cbessjyva((Nl)+0.5, knr, vm, cjv, cyv, cjvp, cyvp);  
67 -  
68 - //scale factor for spherical bessel functions  
69 - double scale_kr = sqrt(pi/(2.0*kr));  
70 - complex<double> scale_knr = sqrt(pi/(2.0*knr));  
71 -  
72 - complex<double> numer, denom;  
73 - double j_kr;  
74 - double y_kr;  
75 - complex<double> j_knr;  
76 - complex<double> j_d_knr;  
77 - double j_d_kr;  
78 - complex<double> h_kr;  
79 - complex<double> h_d_kr;  
80 - complex<double> h_neg;  
81 - complex<double> h_pos;  
82 -  
83 - //cout<<"B coefficients:"<<endl;  
84 - for(int l=0; l<Nl; l++)  
85 - {  
86 - //compute the spherical bessel functions  
87 - j_kr = jv[l] * scale_kr;  
88 - y_kr = yv[l] * scale_kr;  
89 - j_knr = cjv[l] * scale_knr;  
90 -  
91 - //compute the Hankel function  
92 - h_kr = complex<double>(j_kr, y_kr);  
93 -  
94 - //compute the derivatives  
95 - if(l == 0)  
96 - {  
97 - //spherical bessel functions for l=0  
98 - j_d_kr = scale_kr * (Jl_neg(kr) - (jv[l] + kr*jv[l+1])/kr )/2.0;  
99 - j_d_knr = scale_knr * ( Jl_neg(knr) - (cjv[l] + knr*cjv[l+1])/knr )/2.0;  
100 - h_neg = complex<double>(scale_kr*Jl_neg(kr), scale_kr*Yl_neg(kr));  
101 - h_pos = complex<double>(scale_kr*jv[l+1], scale_kr*yv[l+1]);  
102 - h_d_kr = (h_neg - (h_kr + kr*h_pos)/kr)/2.0;  
103 - }  
104 - else  
105 - {  
106 - //spherical bessel functions  
107 - j_d_kr = scale_kr * (jv[l-1] - (jv[l] + kr*jv[l+1])/kr )/2.0;  
108 - j_d_knr = scale_knr * ( cjv[l-1] - (cjv[l] + knr*cjv[l+1])/knr )/2.0;  
109 - h_neg = complex<double>(scale_kr*jv[l-1], scale_kr*yv[l-1]);  
110 - h_pos = complex<double>(scale_kr*jv[l+1], scale_kr*yv[l+1]);  
111 - h_d_kr = (h_neg - (h_kr + kr*h_pos)/kr)/2.0;  
112 - }  
113 -  
114 - numer = j_kr*j_d_knr*n - j_knr*j_d_kr;  
115 - denom = j_knr*h_d_kr - h_kr*j_d_knr*n;  
116 - B[l] = numer/denom;  
117 -  
118 - //B[l] = scComplex(temp.real(), temp.imag());  
119 - //cout<<B[l]<<endl;  
120 - }  
121 -  
122 - free(jv);  
123 - free(yv);  
124 - free(jvp);  
125 - free(yvp);  
126 - free(cjv);  
127 - free(cyv);  
128 - free(cjvp);  
129 - free(cyvp);  
130 -}  
131 -  
132 -void Legendre(double* P, double x, int Nl)  
133 -{  
134 - //computes the legendre polynomials from orders 0 to Nl-1  
135 - P[0] = 1;  
136 - if(Nl == 1) return;  
137 - P[1] = x;  
138 - for(int l = 2; l < Nl; l++)  
139 - {  
140 - P[l] = ((2*l - 1)*x*P[l-1] - (l - 1)*P[l-2])/l;  
141 - }  
142 -  
143 -}  
144 -  
145 -complex<double> integrateUi(double cAngleI, double cAngleO, double oAngleI, double oAngleO, double M = 2*pi)  
146 -{  
147 - /*This function integrates the incident field of magnitude M in the far zone  
148 - in order to evaluate the field at the central pixel of a detector.  
149 - cNAi = condenser inner angle  
150 - cNAo = condenser outer angle  
151 - oNAi = objective inner angle  
152 - oNAo = objective outer angle  
153 - M = field magnitude*/  
154 -  
155 - double alphaIn = max(cAngleI, oAngleI);  
156 - double alphaOut = min(cAngleO,oAngleO);  
157 -  
158 - complex<double> Ui;  
159 - if(alphaIn > alphaOut)  
160 - Ui = complex<double>(0.0, 0.0);  
161 - else  
162 - Ui = complex<double>(M * 2 * pi * (cos(alphaIn) - cos(alphaOut)), 0.0f);  
163 -  
164 - return Ui;  
165 -  
166 -}  
167 -  
168 -void computeCondenserAlpha(double* alpha, int Nl, double cAngleI, double cAngleO)  
169 -{  
170 - /*This function computes the condenser integral in order to build the field of incident light  
171 - alpha = list of Nl floating point values representing the condenser alpha as a function of l  
172 - Nl = number of orders in the incident field  
173 - cAngleI, cAngleO = inner and outer condenser angles (inner and outer NA)*/  
174 -  
175 - //compute the Legendre polynomials for the condenser aperature  
176 - double* PcNAo = (double*)malloc(sizeof(double)*(Nl+1));  
177 - Legendre(PcNAo, cos(cAngleO), Nl+1);  
178 - double* PcNAi = (double*)malloc(sizeof(double)*(Nl+1));  
179 - Legendre(PcNAi, cos(cAngleI), Nl+1);  
180 -  
181 - for(int l=0; l<Nl; l++)  
182 - {  
183 - //integration term  
184 - if(l == 0)  
185 - alpha[l] = -PcNAo[l+1] + PcNAo[0] + PcNAi[l+1] - PcNAi[0];  
186 - else  
187 - alpha[l] = -PcNAo[l+1] + PcNAo[l-1] + PcNAi[l+1] - PcNAi[l-1];  
188 -  
189 - alpha[l] *= 2 * pi;  
190 - }  
191 -  
192 -}  
193 -  
194 -complex<double> integrateUs(double r, double lambda, complex<double> eta,  
195 - double cAngleI, double cAngleO, double oAngleI, double oAngleO, double M = 2*pi)  
196 -{  
197 - /*This function integrates the incident field of magnitude M in the far zone  
198 - in order to evaluate the field at the central pixel of a detector.  
199 - r = sphere radius  
200 - lambda = wavelength  
2