Team:Cambridge/ProjectBioluminescence/LightLevel/SourceCode
From 2010.igem.org
- include <iostream>
- include <vector>
- include <fstream>
- include <math.h>
- ifndef __mjdmatrix_h
- define __mjdmatrix_h
- include <iostream>
using namespace std; // generic object (class) definition of matrix: template <class D> class matrix{
// NOTE: maxsize determines available memory storage, but // actualsize determines the actual size of the stored matrix in use // at a particular time. int maxsize; // max number of rows (same as max number of columns) int actualsize; // actual size (rows, or columns) of the stored matrix D* data; // where the data contents of the matrix are stored void allocate() { delete[] data; data = new D [maxsize*maxsize]; }; matrix() {}; // private ctor's matrix(int newmaxsize) {matrix(newmaxsize,newmaxsize);};
public:
void print() { for(int i=0; i<maxsize; i++){ for(int j=0; j<maxsize; j++){
cout << getvalue(i,j) << " "; } cout << endl; }
};
D getvalue(int row, int column){return data[ row * maxsize + column ];};
matrix(int newmaxsize, int newactualsize) { // the only public ctor if (newmaxsize <= 0) newmaxsize = 5; maxsize = newmaxsize; if ((newactualsize <= newmaxsize)&&(newactualsize>0)) actualsize = newactualsize; else actualsize = newmaxsize; // since allocate() will first call delete[] on data: data = 0; allocate(); }; ~matrix() { delete[] data; };
void comparetoidentity() { int worstdiagonal = 0; D maxunitydeviation = 0.0; D currentunitydeviation; for ( int i = 0; i < actualsize; i++ ) { currentunitydeviation = data[i*maxsize+i] - 1.; if ( currentunitydeviation < 0.0) currentunitydeviation *= -1.; if ( currentunitydeviation > maxunitydeviation ) { maxunitydeviation = currentunitydeviation; worstdiagonal = i; } } int worstoffdiagonalrow = 0; int worstoffdiagonalcolumn = 0; D maxzerodeviation = 0.0; D currentzerodeviation ; for ( int i = 0; i < actualsize; i++ ) { for ( int j = 0; j < actualsize; j++ ) { if ( i == j ) continue; // we look only at non-diagonal terms currentzerodeviation = data[i*maxsize+j]; if ( currentzerodeviation < 0.0) currentzerodeviation *= -1.0; if ( currentzerodeviation > maxzerodeviation ) { maxzerodeviation = currentzerodeviation; worstoffdiagonalrow = i; worstoffdiagonalcolumn = j; }
} } cout << "Worst diagonal value deviation from unity: " << maxunitydeviation << " at row/column " << worstdiagonal << endl; cout << "Worst off-diagonal value deviation from zero: " << maxzerodeviation << " at row = " << worstoffdiagonalrow << ", column = " << worstoffdiagonalcolumn << endl; }
void settoproduct(matrix& left, matrix& right) { actualsize = left.getactualsize(); if ( maxsize < left.getactualsize() ) { maxsize = left.getactualsize(); allocate(); } for ( int i = 0; i < actualsize; i++ ) for ( int j = 0; j < actualsize; j++ ) { D sum = 0.0; D leftvalue, rightvalue; bool success; for (int c = 0; c < actualsize; c++) { left.getvalue(i,c,leftvalue,success); right.getvalue(c,j,rightvalue,success); sum += leftvalue * rightvalue; } setvalue(i,j,sum); } }
void copymatrix(matrix& source) { actualsize = source.getactualsize(); if ( maxsize < source.getactualsize() ) { maxsize = source.getactualsize(); allocate(); } for ( int i = 0; i < actualsize; i++ ) for ( int j = 0; j < actualsize; j++ ) { D value; bool success; source.getvalue(i,j,value,success); data[i*maxsize+j] = value; } };
void setactualsize(int newactualsize) { if ( newactualsize > maxsize ) { maxsize = newactualsize ; // * 2; // wastes memory but saves // time otherwise required for // operation new[] allocate(); } if (newactualsize >= 0) actualsize = newactualsize; };
int getactualsize() { return actualsize; };
void getvalue(int row, int column, D& returnvalue, bool& success) { if ( (row>=maxsize) || (column>=maxsize) || (row<0) || (column<0) ) { success = false; return; } returnvalue = data[ row * maxsize + column ]; success = true; };
bool setvalue(int row, int column, D newvalue) { if ( (row >= maxsize) || (column >= maxsize) || (row<0) || (column<0) ) return false; data[ row * maxsize + column ] = newvalue; return true; };
void invert() { if (actualsize <= 0) return; // sanity check if (actualsize == 1) return; // must be of dimension >= 2 for (int i=1; i < actualsize; i++) data[i] /= data[0]; // normalize row 0 for (int i=1; i < actualsize; i++) { for (int j=i; j < actualsize; j++) { // do a column of L D sum = 0.0; for (int k = 0; k < i; k++) sum += data[j*maxsize+k] * data[k*maxsize+i]; data[j*maxsize+i] -= sum; } if (i == actualsize-1) continue; for (int j=i+1; j < actualsize; j++) { // do a row of U D sum = 0.0; for (int k = 0; k < i; k++) sum += data[i*maxsize+k]*data[k*maxsize+j]; data[i*maxsize+j] = (data[i*maxsize+j]-sum) / data[i*maxsize+i]; } } for ( int i = 0; i < actualsize; i++ ) // invert L for ( int j = i; j < actualsize; j++ ) { D x = 1.0; if ( i != j ) { x = 0.0; for ( int k = i; k < j; k++ ) x -= data[j*maxsize+k]*data[k*maxsize+i]; } data[j*maxsize+i] = x / data[j*maxsize+j]; } for ( int i = 0; i < actualsize; i++ ) // invert U for ( int j = i; j < actualsize; j++ ) { if ( i == j ) continue; D sum = 0.0; for ( int k = i; k < j; k++ ) sum += data[k*maxsize+j]*( (i==k) ? 1.0 : data[i*maxsize+k] ); data[i*maxsize+j] = -sum; } for ( int i = 0; i < actualsize; i++ ) // final inversion for ( int j = 0; j < actualsize; j++ ) { D sum = 0.0; for ( int k = ((i>j)?i:j); k < actualsize; k++ ) sum += ((j==k)?1.0:data[j*maxsize+k])*data[k*maxsize+i]; data[j*maxsize+i] = sum; } };
};
- endif
using namespace std;
class Function { private: vector <double> wavelength; vector <double> function; vector <double> lambda;
double RBF(double, double); double sigma; double width; int SIZE;
public: void getData(const char*); void findLambda(double);
void fix();
double lat(int i){return lambda.at(i);} double wat(int i){return wavelength.at(i);} double fat(int i){return function.at(i);} void wequals(int i, double value){wavelength.at(i)=value;} void fequals(int i, double value){function.at(i)=value;}
void eraseBeginning(int);
void print(); void print(double,double,double); void printStore();
double size(){return wavelength.size();}
double value(double);
void erase(int);
};
double X(double j, double a, double h) {return a+j*h;} double H(double a,double b,double n) {return (b-a)/n;}
double integral (double a, double b, double (*)(double)); double integral (double a, double b, Function); double integralLength(double, double, Function);
double luminousFlux(Function, Function,double,double);
void testData(char* data,double, char* output);
void runProgram(char*,char*,double,double);
void sortData(char*, char*);
void brightness(double lux);
- define MINI 200
- define MAXI 800
- define HCON 6.63e-34
- define CCON 2.99e8
- define TURNOVER 0.125*2000
- define CDEN 8e12
- ifndef FILE
#define FILE "foo.dat"
- endif
- define N 1000
int main()
{
//sortData("workingdata.dat","spectra.dat");
//testData("photopic.dat",0.7,"output3.dat");
runProgram("scotopic.dat","spectra.dat",CDEN,TURNOVER);
return 0;
}
void brightness(double lux)
{
if(lux<10e-5) cout << "invisible" << endl;
else if(lux<10e-4) cout << "the light from Sirius, the brightest star in the night sky" << endl;
else if(lux<0.002) cout << "total starlight with an overcast sky" << endl;
else if(lux<0.01) cout << "a moonless clear night sky with airglow" << endl;
else if(lux<0.27) cout << "a night sky with a quarter moon" << endl;
else if(lux<1) cout << "a full moon on a clear night" << endl;
else if(lux<3.4) cout << "a full moon overhead at tropical latitude" << endl;
else if(lux<50) cout << "the dark limit of civil twilight under a clear sky" << endl;
else if(lux<80) cout << "a family living room" << endl;
else if(lux<100) cout << "a hallway/toilet" << endl;
else if(lux<320) cout << "a very dark overcast day" << endl;
else if(lux<1e3) cout << "office lighting or a sunrise/sunset" << endl;
else if(lux<1e4) cout << "an overcast day" << endl;
else if(lux<32e3) cout << "full daylight (not direct sun)" << endl;
else cout << "Direct sunlight " << endl;
}
void sortData(char* input, char* output) { Function a; a.getData(input); double wMIN=a.wat(0), wMAX=a.fat(0), fMIN=a.wat(1), fMAX=a.fat(1); a.eraseBeginning(4); double xorigin=(a.wat(0)+a.wat(2))/2, yorigin=(a.fat(0)+a.fat(1))/2; double xMAX=a.wat(1), yMAX=a.fat(2); a.eraseBeginning(6);
double yratio= (fMAX-fMIN)/(yMAX-yorigin); double xratio= (wMAX-wMIN)/(xMAX-xorigin);
for(int i=0; i<a.size(); i++){ a.wequals(i, wMIN+(a.wat(i)-xorigin)*xratio); a.fequals(i, fMIN+(a.fat(i)-yorigin)*yratio); }
int i; a.fix();
ofstream fout(output);
if(!fout) {cout << "Could not open file " << output << " program terminated." << endl; fout.close(); return;}
for(double i=0; i<a.size() ; i++) fout << a.wat(i) << endl << a.fat(i) << endl;
fout.close();
}
void Function::eraseBeginning(int i) { i/=2; function.erase(function.begin(), function.begin()+i); wavelength.erase(wavelength.begin(),wavelength.begin()+i); }
void runProgram(char* lumFile, char* specFile,double cden, double turnover ) { Function luminosity, spectra;
cout << "Getting luminosity data..." << endl; luminosity.getData(lumFile); cout << "Calculating luminosity function..." << endl; luminosity.findLambda(0.7);
cout << "Getting spectral data..." << endl; spectra.getData(specFile); cout << "Calculating spectral function..." << endl; spectra.findLambda(0.7);
cout << "Calculating luminous flux..." << endl;
double x=luminousFlux(luminosity,spectra,cden,turnover) ;
cout << "Luminous Flux is: " << x << endl << "This would be as bright as white paper under light conditions similar to "; brightness(x);
cout << endl << endl << endl; }
void testData(char* data,double CONST, char* output)
{
Function a;
a.getData(data);
a.findLambda(CONST);
ofstream fout(output);
if(!fout) {cout << "Could not open file " << output << " program terminated." << endl; fout.close(); return;}
for(double i=MINI; i<=MAXI ; i+=0.1) fout << i << "\t" << a.value(i) << endl;
// for(double i=0; i<a.size() ; i++) // cout << a.wat(i) << "\t" << a.fat(i)<<"\t" << a.lat(i)<< endl;
fout.close();
}
double luminousFlux(Function x, Function y, double cden, double turnover)
{
double sum1=0, sum2=0;
int a=350,b=750;
double h=H(a,b,N);
for(double j=1; j<=(N/2)-1;j++)
{sum1+=x.value(X(2*j,a,h))*y.value(X(2*j,a,h))/X(2*j,a,h);}
for(double j=1; j<=N/2; j++) {sum2+=x.value(X(2*j-1,a,h))*y.value(X(2*j-1,a,h))/X(2*j-1,a,h);}
return 683.002/(4*3.141)*HCON*CCON*turnover*cden*1e9*((h/3)* ( x.value(a)*y.value(a)/a+ 2*sum1 + 4*sum2 + x.value(b)*y.value(b)/b ))/integral(a,b,y);
}
double integral (double a, double b, Function func) { double sum1=0, sum2=0; double h=H(a,b,N);
for(double j=1; j<=(N/2)-1;j++)
{sum1+=func.value( X( 2*j , a , h ) );}
for(double j=1; j<=N/2; j++)
{sum2+=func.value( X( (2*j)-1 , a , h ) );}
return (h/3)* ( func.value(a)+ 2*sum1 + 4*sum2 + func.value(b) ); }
//.............................................................................................................
void Function::getData(const char* a) { double num;
SIZE=200;
ifstream fin(a); if(!fin) {cout << "Could not open file " << a << " program terminated." << endl; fin.close(); return;}
fin >> num; for (int i=0; !fin.eof(); i++ ) { if(!(i%2)){ wavelength.push_back(num); fin >> num;} else { function.push_back(num); fin >> num;} }
fin.close();
int total=wavelength.size(); vector <double> tempwavelength; vector <double> tempfunction;
if(total>SIZE){
for(int i=0; i<wavelength.size(); i++) {
if(i%(total/SIZE)==0){
tempwavelength.push_back(wavelength.at(i));
tempfunction.push_back(function.at(i));
}}
wavelength.clear(); function.clear();
for(int i=0; i<tempwavelength.size(); i++) {
wavelength.push_back(tempwavelength.at(i));
function.push_back(tempfunction.at(i));
}
}
width=(wavelength.back()-wavelength.front())/wavelength.size();
}
void Function::print(double min, double max, double increment) { for(double i=min; i<=max ; i+=increment) cout << i << "\t" << value(i) << endl; }
void Function::printStore() { for(double i=0; i<wavelength.size() ; i++) cout << wavelength.at(i) << "\t" << function.at(i) << endl;
}
void Function::print() { for(int i=0; i<wavelength.size(); i++) { cout << wavelength.at(i) << "\t" << function.at(i) << endl; }
}
double Function::RBF(double a, double b) { return exp(-(a-b)*(a-b)/(2*sigma*sigma)); //return fabs(a-b); //return 1/sqrt(1+sigma*(a-b)*(a-b)); }
void Function::findLambda(double CONST)
{
sigma=width*CONST;
int M=wavelength.size();
matrix <double> PHI(M,M); // for test we create & invert this matrix matrix <double> lamb(M,1); // this will be a copy of original M1 matrix <double> func(M,1);
for (int i=0; i<M; i++) { func.setvalue(i,1,function.at(i)); for (int j=0; j<M; j++) { PHI.setvalue(i,j,RBF(wavelength.at(i),wavelength.at(j)));
}}
//cout << "matrix before inversion:" << endl << endl; //PHI.print();
PHI.invert(); lamb.settoproduct(PHI,func);
//cout << "matrix after inversion:" << endl << endl; //PHI.print();
double value;bool success;
for(int i=0; i<M; i++){lambda.push_back(lamb.getvalue(i,1));} }
double Function::value(double x) { double sum=0; for(int i=0; i<wavelength.size(); i++) sum+=lambda.at(i)*RBF(x,wavelength.at(i));
return sum; }
void Function::fix() { for(int i=0; i<wavelength.size(); i++){ for(int j=0;j<i; j++){ if(wavelength.at(i)==wavelength.at(j)) {wavelength.erase(wavelength.begin()+j); function.erase(function.begin()+j); j=j-1;} }}
}