00001 // ReplicaMinimizableDirector.cpp: implementation of the CReplicaMinimizableDirector class. 00002 // 00004 00005 #include "ReplicaMinimizableDirector.h" 00006 00008 // Construction/Destruction 00010 00011 CReplicaMinimizableDirector::CReplicaMinimizableDirector(double epsSq, double deltaSq) 00012 { 00013 m_dEpsSquared = epsSq; 00014 m_dDeltaSquared = deltaSq; 00015 } 00016 00017 CReplicaMinimizableDirector::~CReplicaMinimizableDirector() 00018 { 00019 00020 } 00021 00022 int CReplicaMinimizableDirector::GetNParameters() 00023 { 00024 int summedNP = 0; 00025 for(int i = 0; i < _minimizableList.size(); i++) 00026 { 00027 summedNP += _minimizableList[i]->GetNParameters(); 00028 } 00029 return summedNP; 00030 } 00031 00032 double CReplicaMinimizableDirector::GetParameter(int parIndex) 00033 { 00034 // it's in the first list 00035 int firstNP = _minimizableList[0]->GetNParameters(); 00036 if(parIndex < firstNP) 00037 { 00038 return _minimizableList[0]->GetParameter(parIndex); 00039 } 00040 else // it's in the second list 00041 { 00042 return _minimizableList[1]->GetParameter(parIndex - firstNP); 00043 } 00044 } 00045 00046 void CReplicaMinimizableDirector::SetIntersectionLists() 00047 { 00048 // look at all the parameters in the first minimizable/replica and determine 00049 // if they have counterparts in the second network. When they are found, push 00050 // them onto the intersection lists 00051 for(int i = 0; i < _networkList[0]->GetNumberOfRateConstants(); i++) 00052 { 00053 std::string firstName = _networkList[0]->GetRateConstant(i)->GetName(); 00054 for(int j = 0; j < _networkList[1]->GetNumberOfRateConstants(); j++) 00055 { 00056 if(firstName == _networkList[1]->GetRateConstant(j)->GetName()) 00057 { 00058 // put i on the first intersection list and j on the second 00059 // intersection list 00060 m_viIntersectOne.push_back(i); 00061 m_viIntersectTwo.push_back(j); 00062 } 00063 } 00064 } 00065 } 00066 00067 double CReplicaMinimizableDirector::ComputeResiduals(double *parameters) 00068 { 00069 int i; 00070 // divide the residuals by 1/sqrt(N_i) and the summed cost by 1/N_i, where 00071 // N_i is the number of residuals in each replica (replicas are separated in 00072 // this calculation in a way that sub-experiments in minimizables are not) 00073 double summedCost = 0.0; 00074 double psiSquared = 0.0; 00075 double psiFourth = 0.0; 00076 double Pcost = 0.0; 00077 double gammaCost = 0.0; 00078 int subResSize = 0; 00079 if(m_dGammaSquared > 0.0) 00080 { 00081 subResSize = this->nResiduals - 1; 00082 } 00083 else 00084 { 00085 subResSize = this->nResiduals; 00086 } 00087 // compute the residuals/cost from each replica 00088 for(i = 0; i < _minimizableList.size(); i++) 00089 { 00090 int startingIndex = 0; 00091 for(int j = 0; j < i; j++) 00092 { 00093 startingIndex += _minimizableList[j]->GetNParameters(); 00094 } 00095 double tempCost = _minimizableList[i]->ObjectiveFunction(¶meters[startingIndex]); 00096 summedCost += tempCost/(_minimizableList[i]->GetNResiduals()); 00097 } 00098 00099 // load up the master list with each set of residuals 00100 int nextResidual = 0; 00101 for(i = 0; i < _minimizableList.size(); i++) 00102 { 00103 int nRes = _minimizableList[i]->GetNResiduals(); 00104 for(int j = 0; j < nRes; j++) 00105 { 00106 residuals[nextResidual+j] = ((_minimizableList[i]->GetResiduals())[j])/sqrt((double)nRes); 00107 } 00108 nextResidual += nRes; 00109 } 00110 // the intersection list is the same size for both replicas, so it doesn't matter 00111 // which one you ask for the size 00112 double rcCost = 0.0; 00113 int intersectionSize = m_viIntersectOne.size(); 00114 int n1 = _minimizableList[0]->GetNParameters(); 00115 for(int j = 0; j < intersectionSize; j++) 00116 { 00117 double psi = log(parameters[m_viIntersectOne[j]]) - log(parameters[n1 + m_viIntersectTwo[j]]); 00118 psiSquared += psi*psi; 00119 psiFourth += psi*psi*psi*psi; 00120 residuals[nextResidual+j] = sqrt(m_dEpsSquared/intersectionSize)*psi; 00121 rcCost += residuals[nextResidual+j]*residuals[nextResidual+j]; 00122 } 00123 // if the integration penalty is present, the P ratio is the next-to-last 00124 // residual. Otherwise it's the last one 00125 if(m_dGammaSquared > 0.0) 00126 { 00127 // take care of P ratio 00128 residuals[this->nResiduals - 2] = sqrt(m_dDeltaSquared)*(2.0*log(psiSquared) - log(psiFourth)); 00129 Pcost = residuals[this->nResiduals-2]*residuals[this->nResiduals-2]; 00130 // now the time cost 00131 double totalSteps = 0.0; 00132 for(int l = 0; l < _moverList.size(); l++) 00133 { 00134 totalSteps += _moverList[l]->GetTotalStepsTaken(); 00135 } 00136 residuals[this->nResiduals - 1] = sqrt(m_dGammaSquared)*(totalSteps/_moverList.size()); 00137 gammaCost = residuals[this->nResiduals - 1]*residuals[this->nResiduals - 1]; 00138 } 00139 else 00140 { 00141 // fill in the next to last residual, which is the participation ratio 00142 residuals[this->nResiduals - 1] = sqrt(m_dDeltaSquared)*(2.0*log(psiSquared) - log(psiFourth)); 00143 Pcost = residuals[this->nResiduals - 1]*residuals[this->nResiduals - 1]; 00144 // no time cost 00145 gammaCost = 0.0; 00146 } 00147 // XXX debug 00148 cout << "Summed cost = " << summedCost << ", RC cost = " << rcCost << endl; 00149 return summedCost + rcCost + Pcost + gammaCost; 00150 }