00001 // CoupledReplicasMinimizableDirector.cpp: implementation of the CCoupledReplicasMinimizableDirector class. 00002 // 00004 00005 #include "CoupledReplicasMinimizableDirector.h" 00006 00008 // Construction/Destruction 00010 00011 CCoupledReplicasMinimizableDirector::CCoupledReplicasMinimizableDirector(double epsSq, double deltaSq) 00012 { 00013 m_dEpsSquared = epsSq; 00014 m_dDeltaSquared = deltaSq; 00015 } 00016 00017 CCoupledReplicasMinimizableDirector::~CCoupledReplicasMinimizableDirector() 00018 { 00019 delete m_pReplicaOne; 00020 delete m_pReplicaTwo; 00021 } 00022 00023 int CCoupledReplicasMinimizableDirector::GetNParameters() 00024 { 00025 return (m_pReplicaOne->GetNParameters() + m_pReplicaTwo->GetNParameters()); 00026 } 00027 00028 double CCoupledReplicasMinimizableDirector::GetParameter(int parIndex) 00029 { 00030 // it's in the first list 00031 int firstNP = m_pReplicaOne->GetNParameters(); 00032 if(parIndex < firstNP) 00033 { 00034 return m_pReplicaOne->GetParameter(parIndex); 00035 } 00036 else // it's in the second list 00037 { 00038 return m_pReplicaTwo->GetParameter(parIndex - firstNP); 00039 } 00040 00041 } 00042 00043 void CCoupledReplicasMinimizableDirector::SetIntersectionLists() 00044 { 00045 // look at all the parameters in the first minimizable/replica and determine 00046 // if they have counterparts in the second network. When they are found, push 00047 // them onto the intersection lists 00048 for(int i = 0; i < m_pReplicaOne->GetReactionNetwork(0)->GetNumberOfRateConstants(); i++) 00049 { 00050 std::string firstName = m_pReplicaOne->GetReactionNetwork(0)->GetRateConstant(i)->GetName(); 00051 for(int j = 0; j < m_pReplicaTwo->GetReactionNetwork(0)->GetNumberOfRateConstants(); j++) 00052 { 00053 if(firstName == m_pReplicaTwo->GetReactionNetwork(0)->GetRateConstant(j)->GetName()) 00054 { 00055 // put i on the first intersection list and j on the second 00056 // intersection list 00057 m_viIntersectOne.push_back(i); 00058 m_viIntersectTwo.push_back(j); 00059 } 00060 } 00061 } 00062 00063 // before returning, if the intersection list is null print a warning 00064 if(m_viIntersectOne.size() == 0) 00065 { 00066 cout << "WARNING : Coupled models have no shared parameters." << endl; 00067 } 00068 } 00069 00070 double CCoupledReplicasMinimizableDirector::ComputeResiduals(double *parameters) 00071 { 00072 int j; 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 00080 // compute the residuals/cost from each replica 00081 int startingIndex = m_pReplicaOne->GetNParameters(); 00082 summedCost = m_pReplicaOne->ObjectiveFunction(¶meters[0]) + m_pReplicaTwo->ObjectiveFunction(¶meters[startingIndex]); 00083 00084 int ResOne = m_pReplicaOne->GetNResiduals(); 00085 int ResTwo = m_pReplicaTwo->GetNResiduals(); 00086 00087 for(j = 0; j < ResOne; j++) 00088 { 00089 residuals[j] = (m_pReplicaOne->GetResiduals())[j]; 00090 } 00091 for(j = ResOne; j < ResOne + ResTwo; j++) 00092 { 00093 residuals[j] = (m_pReplicaTwo->GetResiduals())[j-ResOne]; 00094 } 00095 int nextResidual = ResOne + ResTwo; 00096 00097 double rcCost = 0.0; 00098 int intersectionSize = m_viIntersectOne.size(); 00099 int n1 = m_pReplicaOne->GetNParameters(); 00100 for(j = 0; j < intersectionSize; j++) 00101 { 00102 double psi = log(parameters[m_viIntersectOne[j]]) - log(parameters[n1 + m_viIntersectTwo[j]]); 00103 psiSquared += psi*psi; 00104 psiFourth += psi*psi*psi*psi; 00105 residuals[nextResidual+j] = sqrt(m_dEpsSquared/2.0)*psi; 00106 rcCost += residuals[nextResidual+j]*residuals[nextResidual+j]; 00107 } 00108 // last residual is the participation ratio 00109 residuals[nResiduals-1] = sqrt(m_dDeltaSquared/2.0)*(2*log(psiSquared) - log(psiFourth)); 00110 PCost = residuals[nResiduals-1]*residuals[nResiduals-1]; 00111 00112 return summedCost + rcCost + PCost; 00113 }