00001
00002
00004
00005 #include "SingleNetworkMinimizable.h"
00006
00008
00010
00011 SingleNetworkMinimizable::SingleNetworkMinimizable()
00012 {
00013
00014 }
00015
00016 SingleNetworkMinimizable::SingleNetworkMinimizable(Experiment *experiment,CReactionMover *reactionMover, bool rateConstantsOptimizable, bool initialChemConcOptimizable, bool logsInObjectiveFunction, double timeSeriesWeight, double rateConstantsWeight, double initialChemConcWeight, int nCells)
00017 {
00018 Initialize(experiment,reactionMover,nCells,rateConstantsOptimizable,initialChemConcOptimizable,logsInObjectiveFunction,timeSeriesWeight,rateConstantsWeight,initialChemConcWeight);
00019 }
00020
00021 SingleNetworkMinimizable::~SingleNetworkMinimizable()
00022 {
00023 delete [] initialNetworkData;
00024 delete [] currentNetworkData;
00025 this->reactionMover->Detach(cellObserver);
00026 delete cellObserver;
00027 for(int i = 0; i < m_pConversionFactors.size(); i++)
00028 {
00029 delete m_pConversionFactors[i];
00030 }
00031 }
00032
00033 void SingleNetworkMinimizable::Initialize(Experiment *experiment, CReactionMover *reactionMover, int nCells, bool rateConstantsOptimizable, bool initialChemConcOptimizable, bool logsInObjectiveFunction, double timeSeriesWeight, double rateConstantsWeight, double initialChemConcWeight)
00034 {
00035 this->experiment = experiment;
00036 this->reactionMover = reactionMover;
00037 this->nCells = nCells;
00038 this->rateConstantsOptimizable = rateConstantsOptimizable;
00039 this->initialChemConcOptimizable = initialChemConcOptimizable;
00040 this->logsInObjectiveFunction = logsInObjectiveFunction;
00041
00042 this->SetTimeSeriesWeight(timeSeriesWeight);
00043 this->SetRateConstantsWeight(rateConstantsWeight);
00044 this->SetInitialChemConcWeight(initialChemConcWeight);
00045
00046
00047 this->experiment->ReadData();
00048
00049 this->experiment->ReadForcingData();
00050
00051 int nChem = this->experiment->GetReactionNetwork()->GetNumberOfChemicals();
00052 int nRateConstants = this->experiment->GetReactionNetwork()->GetNumberOfRateConstants();
00053 int intTime = ((int) this->experiment->GetChemicalTimeSeriesData()->GetLatestDataTime()) + 2;
00054 cellObserver = new CellAverageObserver(nChem,intTime,nCells);
00055
00056
00057 this->reactionMover->Attach(cellObserver);
00058
00059 initialNetworkData = new double[nRateConstants + nChem];
00060 currentNetworkData = new double[nRateConstants + nChem];
00061
00062
00063
00064
00065 for(int l = 0; l < nChem; l++)
00066 {
00067 if((experiment->GetChemicalTimeSeriesData()->GetTimeSeries(l)).size() > 0 )
00068 {
00069 m_pConversionFactors.push_back(new CConversionFactor(true,false,1.0));
00070 }
00071 else
00072 {
00073 m_pConversionFactors.push_back(new CConversionFactor(false));
00074 }
00075 }
00076
00077 m_iNBFactors = 0;
00078
00079
00080
00081 for(int i = 0; i < nRateConstants; i++)
00082 {
00083 initialNetworkData[i] = this->experiment->GetReactionNetwork()->GetRateConstant(i)->GetInitialValue();
00084 currentNetworkData[i] = initialNetworkData[i];
00085 }
00086 for(int i = nRateConstants; i < nRateConstants + nChem; i++)
00087 {
00088 initialNetworkData[i] = this->experiment->GetReactionNetwork()->GetChemical(i-nRateConstants)->GetInitialAmount();
00089 currentNetworkData[i] = initialNetworkData[i];
00090 }
00091
00092 int localResidualsSize = 0;
00093 if(this->timeSeriesWeight > 0.0) {localResidualsSize += this->experiment->GetChemicalTimeSeriesData()->GetNDataPoints();}
00094 if(this->rateConstantsWeight > 0.0) {localResidualsSize += nRateConstants;}
00095 if(this->initialChemConcWeight > 0.0) {localResidualsSize += nChem;}
00096
00097 Allocate(localResidualsSize);
00098
00099 }
00100
00101 double SingleNetworkMinimizable::ComputeES(double *parameters, double T)
00102 {
00103 m_dEnergyLastComputed = this->ComputeResiduals(parameters);
00104 double S = this->EntropyShift(T) - 0.5*m_dEntropyLastComputed;
00105 m_dEntropyLastComputed = S;
00106 return m_dEnergyLastComputed;
00107 }
00108
00109 double SingleNetworkMinimizable::EntropyShift(double T)
00110 {
00111 return 0.5*m_iNBFactors*log(2*3.14159265358979323846*T);
00112 }
00113
00114 double SingleNetworkMinimizable::F(double *parameters, double T)
00115 {
00116 m_dEnergyLastComputed = this->ComputeResiduals(parameters);
00117 double S = -0.5*m_dEntropyLastComputed;
00118 m_dEntropyLastComputed = S;
00119 return (m_dEnergyLastComputed - T*m_dEntropyLastComputed);
00120 }
00121
00122 double SingleNetworkMinimizable::F0(double *parameters, double T)
00123 {
00124 m_dEnergyLastComputed = this->ComputeResiduals(parameters);
00125 double S = this->EntropyShift(T) - 0.5*m_dEntropyLastComputed;
00126 m_dEntropyLastComputed = S;
00127 return (m_dEnergyLastComputed - T*m_dEntropyLastComputed);
00128 }
00129
00130 double SingleNetworkMinimizable::ComputeResiduals(double *parameters)
00131 {
00132 m_iNBFactors = 0;
00133 m_dEntropyLastComputed = 0.0;
00134 double partialEntropy = 0.0;
00135
00136 double objFuncVal = 0.0;
00137 int nRateConstants = experiment->GetReactionNetwork()->GetNumberOfRateConstants();
00138 int nChem = experiment->GetReactionNetwork()->GetNumberOfChemicals();
00139
00140
00141
00142 if(rateConstantsOptimizable && initialChemConcOptimizable)
00143 {
00144 for(int i = 0; i < nRateConstants; i++)
00145 {
00146 experiment->GetReactionNetwork()->GetRateConstant(i)->SetRateConstant(parameters[i]);
00147 currentNetworkData[i] = parameters[i];
00148 }
00149 for(int i = nRateConstants; i < nRateConstants + nChem; i++)
00150 {
00151 experiment->GetReactionNetwork()->GetChemical(i - nRateConstants)->SetAmount(parameters[i]);
00152 currentNetworkData[i] = parameters[i];
00153 }
00154 }
00155 else if(rateConstantsOptimizable)
00156 {
00157 for(int i = 0; i < nRateConstants; i++)
00158 {
00159 experiment->GetReactionNetwork()->GetRateConstant(i)->SetRateConstant(parameters[i]);
00160 currentNetworkData[i] = parameters[i];
00161 }
00162 experiment->GetReactionNetwork()->ChemicalReset();
00163 }
00164 else if(initialChemConcOptimizable)
00165 {
00166 for(int i = 0; i < nChem; i++)
00167 {
00168 experiment->GetReactionNetwork()->GetChemical(i)->SetAmount(parameters[i]);
00169 currentNetworkData[i+nRateConstants] = parameters[i];
00170 }
00171 experiment->GetReactionNetwork()->RateConstantReset();
00172 }
00173 else
00174 {
00175
00176
00177
00178
00179
00180 experiment->GetReactionNetwork()->RateConstantReset();
00181 experiment->GetReactionNetwork()->ChemicalReset();
00182 }
00183
00184
00185 cellObserver->ZeroConcentrations();
00186
00187 for(int cellCounter = 1; cellCounter <= nCells; cellCounter++)
00188 {
00189
00190
00191
00192
00193 if(initialChemConcOptimizable)
00194 {
00195 for(int i = nRateConstants; i < nRateConstants + nChem; i++)
00196 {
00197 experiment->GetReactionNetwork()->GetChemical(i - nRateConstants)->SetAmount(parameters[i]);
00198 }
00199 }
00200 else
00201 {
00202 experiment->GetReactionNetwork()->ChemicalReset();
00203 }
00204
00205
00206
00207
00208
00209 reactionMover->ResetStepStatistics(experiment->GetChemicalTimeSeriesData()->GetLatestDataTime());
00210
00211
00212 if(experiment->GetForcingData()->GetForcingVector().size() == 0)
00213 {
00214
00215 reactionMover->Move(0.0,0.0,experiment->GetReactionNetwork());
00216 reactionMover->Move(0.0,experiment->GetChemicalTimeSeriesData()->GetLatestDataTime(),experiment->GetReactionNetwork());
00217 }
00218 else
00219 {
00220 int forceCount = 0;
00221 double time = 0.0;
00222 int lastForce = experiment->GetForcingData()->GetForcingVector().size();
00223 double finaltime = experiment->GetChemicalTimeSeriesData()->GetLatestDataTime();
00224 double finalForceTime = experiment->GetForcingData()->GetLatestForcingTime();
00225 int index;
00226 int start,stop;
00227 double t1,t2,value;
00228 while(time < finalForceTime)
00229 {
00230 start = forceCount;
00231 stop = forceCount;
00232 t1 = experiment->GetForcingData()->GetForcingVector()[start]->GetTime();
00233
00234
00235 for(int i = start; i < lastForce; i++)
00236 {
00237 t2 = experiment->GetForcingData()->GetForcingVector()[i]->GetTime();
00238 if(t1 == t2)
00239 {
00240 }
00241 else
00242 {
00243 stop = i-1;
00244 for(int j = start; j <= stop; j++)
00245 {
00246 index = experiment->GetForcingData()->GetForcingVector()[j]->GetChemNumber();
00247 value = experiment->GetForcingData()->GetForcingVector()[j]->GetValue();
00248 experiment->GetReactionNetwork()->GetChemical(index)->SetAmount(value);
00249 }
00250 break;
00251 }
00252 }
00253 forceCount = stop+1;
00254
00255 reactionMover->Move(time,t1,experiment->GetReactionNetwork());
00256 time = t1;
00257 }
00258
00259
00260 t2 = finalForceTime;
00261 stop = lastForce-1;
00262 for(int i = lastForce-1; i > 0; i--)
00263 {
00264 t1 = experiment->GetForcingData()->GetForcingVector()[i]->GetTime();
00265 if(t1 == t2)
00266 {
00267 }
00268 else
00269 {
00270 start = i+1;
00271 for(int j = start; j <= stop; j++)
00272 {
00273 index = experiment->GetForcingData()->GetForcingVector()[j]->GetChemNumber();
00274 value = experiment->GetForcingData()->GetForcingVector()[j]->GetValue();
00275 experiment->GetReactionNetwork()->GetChemical(index)->SetAmount(value);
00276 }
00277 break;
00278 }
00279 }
00280
00281
00282 if(finaltime > time)
00283 {
00284 reactionMover->Move(time,finaltime,experiment->GetReactionNetwork());
00285 }
00286 time = finaltime;
00287 }
00288 }
00289
00290
00291
00292
00293 for(int chemCount = 0; chemCount < nChem; chemCount++)
00294 {
00295 double num = 0.0;
00296 double den = 0.0;
00297
00298
00299 if(m_pConversionFactors[chemCount]->IsFactorNeeded())
00300 {
00301 if(m_pConversionFactors[chemCount]->IsFactorFixed())
00302 {
00303 num = m_pConversionFactors[chemCount]->GetFactorValue();
00304 den = 1.0;
00305 }
00306 else
00307 {
00308 m_iNBFactors++;
00309 int dataSize = (experiment->GetChemicalTimeSeriesData()->GetTimeSeries(chemCount)).size();
00310
00311 for(int nData = 0; nData < dataSize; nData++)
00312 {
00313 double time = experiment->GetChemicalTimeSeriesData()->GetTimeSeries(chemCount)[nData]->GetTime();
00314 double data = experiment->GetChemicalTimeSeriesData()->GetTimeSeries(chemCount)[nData]->GetDatum();
00315 double error = experiment->GetChemicalTimeSeriesData()->GetTimeSeries(chemCount)[nData]->GetError();
00316 double sim = (cellObserver->GetAverageConcentration())[chemCount][int(time)];
00317 num += ((2*sim)/(error*error))*data;
00318 den += ((2*sim)/(error*error))*sim;
00319
00320 partialEntropy += ((sim*sim)/(error*error));
00321 }
00322 m_dEntropyLastComputed += log(partialEntropy);
00323 }
00324 }
00325 else
00326 {
00327 num = 1.0;
00328 den = 1.0;
00329 }
00330
00331 double factor = num/den;
00332 m_pConversionFactors[chemCount]->SetFactorValue(factor);
00333
00334 }
00335
00336
00337 int nextAvailableIndex = 0;
00338 if(timeSeriesWeight > 0.0)
00339 {
00340
00341 for(int chemIt = 0; chemIt < (experiment->GetChemicalTimeSeriesData()->GetTimeVector()).size(); chemIt++)
00342 {
00343
00344 double targetTime = (experiment->GetChemicalTimeSeriesData()->GetTimeVector())[chemIt]->GetTime();
00345 int targetChem = (experiment->GetChemicalTimeSeriesData()->GetTimeVector())[chemIt]->GetChemNumber();
00346 int vectorIndex = (experiment->GetChemicalTimeSeriesData()->GetTimeVector())[chemIt]->GetVectorIndex();
00347
00348 double data = (experiment->GetChemicalTimeSeriesData()->GetTimeSeries(targetChem))[vectorIndex]->GetDatum();
00349 double sigma = (experiment->GetChemicalTimeSeriesData()->GetTimeSeries(targetChem))[vectorIndex]->GetError();
00350 double sim = (cellObserver->GetAverageConcentration())[targetChem][int(targetTime)];
00351
00352 if(m_pConversionFactors[targetChem]->IsFactorNeeded())
00353 {
00354 sim = sim*(m_pConversionFactors[targetChem]->GetFactorValue());
00355 }
00356
00357 residuals[nextAvailableIndex] = (sqrt(timeSeriesWeight/2.0))*((data - sim)/sigma);
00358 objFuncVal += residuals[nextAvailableIndex]*residuals[nextAvailableIndex];
00359 nextAvailableIndex++;
00360 }
00361 }
00362 if(rateConstantsWeight > 0.0)
00363 {
00364
00365 if(logsInObjectiveFunction)
00366 {
00367 for(int i = 0; i < nRateConstants; i++)
00368 {
00369 double sigma = experiment->GetReactionNetwork()->GetRateConstant(i)->GetErrorInInitialValue();
00370 double sigmalog = sigma/initialNetworkData[i];
00371 residuals[nextAvailableIndex] = (sqrt(rateConstantsWeight/2.0))*(log(initialNetworkData[i]/currentNetworkData[i])/sigmalog);
00372 objFuncVal += residuals[nextAvailableIndex]*residuals[nextAvailableIndex];
00373 nextAvailableIndex++;
00374 }
00375 }
00376 else
00377 {
00378 for(int i = 0; i < nRateConstants; i++)
00379 {
00380 double sigma = experiment->GetReactionNetwork()->GetRateConstant(i)->GetErrorInInitialValue();
00381 residuals[nextAvailableIndex] = (sqrt(rateConstantsWeight/2.0))*((initialNetworkData[i] - currentNetworkData[i])/sigma);
00382 objFuncVal += residuals[nextAvailableIndex]*residuals[nextAvailableIndex];
00383 nextAvailableIndex++;
00384 }
00385 }
00386 }
00387 if(initialChemConcWeight > 0.0)
00388 {
00389
00390 for(int i = 0; i < nChem; i++)
00391 {
00392 double sigma = experiment->GetReactionNetwork()->GetChemical(i)->GetErrorInInitialAmount();
00393 residuals[nextAvailableIndex] = (sqrt(initialChemConcWeight/2.0))*((initialNetworkData[i+nRateConstants] - currentNetworkData[i+nRateConstants])/sigma);
00394 objFuncVal += residuals[nextAvailableIndex]*residuals[nextAvailableIndex];
00395 nextAvailableIndex++;
00396 }
00397 }
00398
00399
00400 Notify();
00401
00402 return objFuncVal;
00403 }
00404
00405 int SingleNetworkMinimizable::GetNParameters()
00406 {
00407 int nRateConstants = experiment->GetReactionNetwork()->GetNumberOfRateConstants();
00408 int nChem = experiment->GetReactionNetwork()->GetNumberOfChemicals();
00409 int nParameters;
00410
00411 if(rateConstantsOptimizable && initialChemConcOptimizable)
00412 {
00413 nParameters = nRateConstants + nChem;
00414 }
00415 else if(rateConstantsOptimizable)
00416 {
00417 nParameters = nRateConstants;
00418 }
00419 else if(initialChemConcOptimizable)
00420 {
00421 nParameters = nChem;
00422 }
00423 else
00424 {
00425 nParameters = 0;
00426 }
00427
00428 return nParameters;
00429 }
00430
00431 double SingleNetworkMinimizable::GetParameter(int parIndex)
00432 {
00433 int nP = GetNParameters();
00434
00435 if(parIndex > nP)
00436 {
00437 throw std::runtime_error("Parameter index is off parameter list.");
00438 }
00439 else
00440 {
00441 return currentNetworkData[parIndex];
00442 }
00443
00444 return 0.0;
00445 }