19 #include "ObjCryst/Quirks/VFNStreamFormat.h"
21 #include "ObjCryst/RefinableObj/LSQNumObj.h"
24 #include "ObjCryst/wxCryst/wxLSQ.h"
27 #include "newmat/newmatap.h"
28 #include "newmat/newmatio.h"
31 using namespace NEWMAT;
37 #define POSSIBLY_UNUSED(expr) (void)(expr)
42 LSQNumObj::LSQNumObj(
string objName)
48 mSaveReportOnEachCycle=
false;
50 mSaveFileName=
"LSQrefinement.save";
54 mStopAfterCycle=
false;
57 LSQNumObj::~LSQNumObj()
64 void LSQNumObj::SetParIsFixed(
const string& parName,
const bool fix)
66 if(mRefParList.GetNbPar()==0) this->PrepareRefParList();
67 mRefParList.SetParIsFixed(parName,fix);
69 void LSQNumObj::SetParIsFixed(
const RefParType *type,
const bool fix)
71 if(mRefParList.GetNbPar()==0) this->PrepareRefParList();
72 mRefParList.SetParIsFixed(type,fix);
77 if(mRefParList.GetNbPar()==0) this->PrepareRefParList();
78 mRefParList.GetPar(par.
GetPointer()).SetIsFixed(fix);
84 if(mRefParList.GetNbPar()==0) this->PrepareRefParList();
85 for(
unsigned int i=0;i<obj.
GetNbPar();++i)
86 this->SetParIsFixed(obj.
GetPar(i),fix);
89 void LSQNumObj::UnFixAllPar()
91 if(mRefParList.GetNbPar()==0) this->PrepareRefParList();
92 mRefParList.UnFixAllPar();
95 void LSQNumObj::SetParIsUsed(
const string& parName,
const bool use)
97 if(mRefParList.GetNbPar()==0) this->PrepareRefParList();
98 mRefParList.SetParIsUsed(parName,use);
100 void LSQNumObj::SetParIsUsed(
const RefParType *type,
const bool use)
102 if(mRefParList.GetNbPar()==0) this->PrepareRefParList();
103 mRefParList.SetParIsUsed(type,use);
106 void LSQNumObj::Refine (
int nbCycle,
bool useLevenbergMarquardt,
107 const bool silent,
const bool callBeginEndOptimization,
108 const float minChi2var)
110 TAU_PROFILE(
"LSQNumObj::Refine()",
"void ()",TAU_USER);
111 TAU_PROFILE_TIMER(timer1,
"LSQNumObj::Refine() 1 - Init",
"", TAU_FIELD);
112 TAU_PROFILE_TIMER(timer2,
"LSQNumObj::Refine() 2 - LSQ Deriv",
"", TAU_FIELD);
113 TAU_PROFILE_TIMER(timer3,
"LSQNumObj::Refine() 3 - LSQ MB",
"", TAU_FIELD);
114 TAU_PROFILE_TIMER(timer4,
"LSQNumObj::Refine() 4 - LSQ Singular Values",
"", TAU_FIELD);
115 TAU_PROFILE_TIMER(timer5,
"LSQNumObj::Refine() 5 - LSQ Newmat, eigenvalues...",
"", TAU_FIELD);
116 TAU_PROFILE_TIMER(timer6,
"LSQNumObj::Refine() 6 - LSQ Apply",
"", TAU_FIELD);
117 TAU_PROFILE_TIMER(timer7,
"LSQNumObj::Refine() 7 - LSQ Finish",
"", TAU_FIELD);
118 TAU_PROFILE_START(timer1);
119 if(callBeginEndOptimization) this->BeginOptimization();
120 mObs=this->GetLSQObs();
121 mWeight=this->GetLSQWeight();
123 bool terminateOnDeltaChi2=
false;
127 terminateOnDeltaChi2=
true;
130 if(!silent) cout <<
"LSQNumObj::Refine():Beginning "<<endl;
132 if(mRefParList.GetNbPar()==0) this->PrepareRefParList();
133 mRefParList.PrepareForRefinement();
135 if(mRefParList.GetNbPar()==0)
throw ObjCrystException(
"LSQNumObj::Refine():no parameter to refine !");
138 long nbVar=mRefParList.GetNbParNotFixed();
139 const long nbObs=mObs.numElements();
140 CrystVector_REAL calc,calc0,calc1,tmpV1,tmpV2;
141 CrystMatrix_REAL M(nbVar,nbVar);
142 CrystMatrix_REAL N(nbVar,nbVar);
143 CrystVector_REAL B(nbVar);
144 CrystMatrix_REAL designMatrix(nbVar,nbObs);
145 CrystVector_REAL deltaVar(nbVar);
147 REAL R_ini,Rw_ini; POSSIBLY_UNUSED(R_ini);
151 const REAL marquardtMult=4.;
153 this->CalcChiSquare();
155 mIndexValuesSetInitial=mRefParList.CreateParamSet(
"LSQ Refinement-Initial Values");
156 mIndexValuesSetLast=mRefParList.CreateParamSet(
"LSQ Refinement-Last Cycle Values");
157 TAU_PROFILE_STOP(timer1);
159 for(
int cycle=1 ; cycle <=nbCycle;cycle++)
161 TAU_PROFILE_START(timer2);
162 const REAL ChisSqPreviousCycle=mChiSq;
163 mRefParList.SaveParamSet(mIndexValuesSetLast);
164 if(!silent) cout <<
"LSQNumObj::Refine():Cycle#"<< cycle <<endl;
166 calc0=this->GetLSQCalc();
173 R_ini=sqrt(tmpV1.sum()/tmpV2.sum());
177 Rw_ini=sqrt(tmpV1.sum()/tmpV2.sum());
180 pTmp2=designMatrix.data();
190 tmpV1=this->GetLSQDeriv(mRefParList.GetParNotFixed(i));
193 for(j=0;j<nbObs;j++) *pTmp2++ = *pTmp1++;
196 this->GetLSQ_FullDeriv();
199 pTmp1=mLSQ_FullDeriv[&(mRefParList.GetParNotFixed(i))].data();
201 for(j=0;j<nbObs;j++) *pTmp2++ = *pTmp1++;
206 TAU_PROFILE_STOP(timer2);
207 LSQNumObj_Refine_Restart:
208 TAU_PROFILE_START(timer3);
217 const REAL * RESTRICT pD=designMatrix.data()+i*designMatrix.cols();
218 const REAL * RESTRICT pW=mWeight.data();
219 REAL * RESTRICT p=tmpV1.data();
220 for(k=0;k<nbObs;k++) *p++ = *pD++ * *pW++;
222 const REAL * pD=designMatrix.data();
225 const REAL * p1=tmpV1.data();
227 for(k=0;k<nbObs;k++) v2+= *pD++ * *p1++;
231 const REAL * pObs=mObs.data();
232 const REAL * pCalc=calc0.data();
233 const REAL * p1=tmpV1.data();
234 for(k=0;k<nbObs;k++) b+= (*pObs++ - *pCalc++)* *p1++;
237 for(k=0;k<nbObs;k++) tmpV1(k)=designMatrix(i,k);
241 for(k=0;k<nbObs;k++) tmpV2(k)=designMatrix(j,k);
253 TAU_PROFILE_STOP(timer3);
254 bool increaseMarquardt=
false;
255 LSQNumObj_Refine_RestartMarquardt:
256 TAU_PROFILE_START(timer4);
259 if(
true==useLevenbergMarquardt)
261 const REAL marquardtOLD=marquardt;
262 if(increaseMarquardt) marquardt=marquardt*marquardtMult;
263 const REAL lmfact=(1+marquardt)/(1+marquardtOLD);
264 for(i=0;i<nbVar;i++) M(i,i) *= lmfact;
272 if(!silent) cout <<
"LSQNumObj::Refine() Singular parameter !"
273 <<
"(null derivate in all points) : "<<M(i,i)<<
":"
274 << mRefParList.GetParNotFixed(i).GetName() << endl;
285 if(!silent) cout <<
"LSQNumObj::Refine(): Automatically fixing parameter";
286 if(!silent) cout <<
" and re-start cycle..";
287 if(!silent) cout << endl;
288 mRefParList.GetParNotFixed(i).SetIsFixed(
true);
289 mRefParList.PrepareForRefinement();
290 nbVar=mRefParList.GetNbParNotFixed();
293 mRefParList.RestoreParamSet(mIndexValuesSetInitial);
294 if(callBeginEndOptimization) this->EndOptimization();
295 if(!silent) mRefParList.Print();
296 throw ObjCrystException(
"LSQNumObj::Refine(): not enough (1) parameters after fixing one...");
298 N.resize(nbVar,nbVar);
299 deltaVar.resize(nbVar);
302 REAL *p1=designMatrix.data();
303 const REAL *p2=designMatrix.data();
306 for(
long j=i*nbObs+nbObs;j<nbObs*nbVar;j++) *p1++ = *p2++;
307 designMatrix.resizeAndPreserve(nbVar,nbObs);
326 M.resize(nbVar,nbVar);
328 TAU_PROFILE_STOP(timer4);
329 goto LSQNumObj_Refine_Restart;
332 TAU_PROFILE_STOP(timer4);
377 TAU_PROFILE_START(timer5);
381 CrystMatrix_REAL V(nbVar,nbVar);
382 CrystVector_REAL invW(nbVar);
385 SymmetricMatrix newmatA(nbVar);
386 Matrix newmatV(nbVar,nbVar),
387 newmatN(nbVar,nbVar);
388 DiagonalMatrix newmatW(nbVar);
389 ColumnVector newmatB(nbVar);
391 DiagonalMatrix newmatDscale(nbVar);
392 for(
long i=0;i<nbVar;i++)
393 newmatDscale(i+1,i+1) = 1./sqrt(M(i,i));
394 for(
long i=0;i<nbVar;i++)
397 for(
long j=0;j<nbVar;j++)
398 newmatA(i+1,j+1) = M(i,j) * newmatDscale(i+1,i+1) * newmatDscale(j+1,j+1);
408 EigenValues(newmatA,newmatW,newmatV);
414 cout<<
"Caught a Newmat exception :"<<BaseException::what()<<endl;
415 cout<<
"A:"<<endl<<newmatA<<endl<<
"W:"<<endl<<newmatW<<endl<<
"V:"<<endl<<newmatV<<endl<<
"Dscale:"<<newmatDscale*1e6<<endl;
416 cout<<setw(5)<<
"B:"<<endl;
417 for(
unsigned int i=0;i<B.size();i++) cout<<B(i)<<
" ";
418 cout<<endl<<endl<<
"M:"<<endl;
419 for(
unsigned int i=0;i<M.rows();i++)
421 for(
unsigned int j=0;j<M.cols();j++) cout<<M(i,j)<<
" ";
424 cout<<endl<<endl<<
"D("<<designMatrix.rows()<<
"x"<<designMatrix.cols()<<
"):"<<endl;
425 for(
unsigned int i=0;i<designMatrix.rows();i++)
427 for(
unsigned int j=0;j<designMatrix.cols();j++) cout<<designMatrix(i,j)<<
" ";
431 throw ObjCrystException(
"LSQNumObj::Refine():caught a newmat exception during Eigenvalues computing !");
433 ColumnVector newmatDelta(nbVar);
434 DiagonalMatrix newmatInvW(nbVar);
438 REAL max=newmatW.MaximumAbsoluteValue();
439 REAL minAllowedValue=1e-5*max;
440 for(
long i=0;i<nbVar;i++)
441 if(newmatW(i+1,i+1) > minAllowedValue)
442 newmatInvW(i+1,i+1)= 1./newmatW(i+1,i+1);
445 if(!silent) cout <<
"LSQNumObj::Refine():fixing ill-cond EigenValue "<< i <<endl;
446 newmatInvW(i+1,i+1) = 0.;
483 newmatN=newmatV * newmatInvW * newmatV.t();
486 newmatN = newmatDscale * newmatN * newmatDscale;
487 newmatDelta = newmatN * newmatB;
489 for(
long i=0;i<nbVar;i++)
491 invW(i)=newmatInvW(i+1,i+1);
492 deltaVar(i)=newmatDelta(i+1);
493 for(
long j=0;j<nbVar;j++)
495 N(i,j) = newmatN(i+1,j+1);
496 V(i,j) = newmatV(i+1,j+1);
507 TAU_PROFILE_STOP(timer5);
603 TAU_PROFILE_START(timer6);
609 mRefParList.GetParNotFixed(i).Mutate(deltaVar(i));
615 calc=this->GetLSQCalc();
618 REAL oldChiSq=mChiSq;
624 if(
true==useLevenbergMarquardt)
626 if(mChiSq > (oldChiSq*1.0001))
628 mRefParList.RestoreParamSet(mIndexValuesSetLast);
629 increaseMarquardt=
true;
632 cout <<
"LSQNumObj::Refine(Chi^2="<<oldChiSq<<
"->"<<mChiSq
633 <<
")=>Increasing Levenberg-Marquardt factor :"
634 <<
FormatFloat(marquardt*marquardtMult,18,14) <<endl;
640 mRefParList.RestoreParamSet(mIndexValuesSetLast);
641 if(callBeginEndOptimization) this->EndOptimization();
646 TAU_PROFILE_STOP(timer6);
647 goto LSQNumObj_Refine_RestartMarquardt;
651 if(!silent && (marquardt>1e-2))
653 cout <<
"LSQNumObj::Refine(Chi^2="<<oldChiSq<<
"->"<<mChiSq
654 <<
")=>Decreasing Levenberg-Marquardt factor :" <<
FormatFloat(marquardt/marquardtMult,18,14) <<endl;
656 marquardt /= marquardtMult;
657 if(marquardt<1e-2) marquardt=1e-2;
661 TAU_PROFILE_STOP(timer6);
662 TAU_PROFILE_START(timer7);
666 for(i=0;i<nbVar;i++) mRefParList.GetParNotFixed(i).SetSigma(0);
668 for(i=0;i<nbVar;i++) mRefParList.GetParNotFixed(i).SetSigma(sqrt(N(i,i)*mChiSq/(nbObs-nbVar)));
670 mCorrelMatrix.resize(nbVar,nbVar);
679 mCorrelMatrix(i,j)=sqrt(N(i,j)*N(i,j)/N(i,i)/N(j,j));
681 mvVarCovar[make_pair(pi,pj)]=N(i,j)*mChiSq/(nbObs-nbVar);
690 mR=sqrt(tmpV1.sum()/tmpV2.sum());
694 mRw=sqrt(tmpV1.sum()/tmpV2.sum());
696 if(!silent) cout <<
"finished cycle #"<<cycle <<
"/"<<nbCycle <<
". Rw="<<Rw_ini<<
"->"<<mRw<<
", Chi^2="<<ChisSqPreviousCycle<<
"->"<<mChiSq<<endl;
697 if (mSaveReportOnEachCycle) this->WriteReportToFile();
699 if(!silent) this->PrintRefResults();
700 TAU_PROFILE_STOP(timer7);
701 if( terminateOnDeltaChi2 && (minChi2var>( (ChisSqPreviousCycle-mChiSq)/abs(ChisSqPreviousCycle+1e-6) ) ) )
break;
703 if(callBeginEndOptimization) this->EndOptimization();
706 bool LSQNumObj::SafeRefine(std::list<RefinablePar*> vnewpar, std::list<const RefParType*> vnewpartype,
708 int nbCycle,
bool useLevenbergMarquardt,
709 const bool silent,
const bool callBeginEndOptimization,
710 const float minChi2var)
712 if(callBeginEndOptimization) this->BeginOptimization();
714 mObs=this->GetLSQObs();
715 mWeight=this->GetLSQWeight();
718 if(mRefParList.GetNbPar()==0) this->PrepareRefParList();
719 mRefParList.PrepareForRefinement();
720 if(mRefParList.GetNbPar()==0)
throw ObjCrystException(
"LSQNumObj::SafeRefine():no parameter to refine !");
722 this->CalcChiSquare();
723 const REAL chi2_0 = mChiSq;
724 for(std::list<RefinablePar*>::iterator pos=vnewpar.begin(); pos!=vnewpar.end(); pos++)
726 this->SetParIsFixed(**pos,
false);
728 for(std::list<const RefParType*>::iterator pos=vnewpartype.begin(); pos!=vnewpartype.end(); pos++)
730 this->SetParIsFixed(*pos,
false);
732 bool diverged =
false;
735 this->Refine(nbCycle, useLevenbergMarquardt, silent,
false, minChi2var);
740 if(!silent) cout <<
"Refinement did not converge !";
742 const REAL deltachi2 = (mChiSq-chi2_0)/(chi2_0+1e-6);
743 if(callBeginEndOptimization) this->EndOptimization();
744 if(deltachi2>maxChi2factor)
746 if(!silent) cout <<
"Refinement did not converge ! Chi2 increase("<<chi2_0<<
"->"<<mChiSq<<
") by a factor: "<< deltachi2<<endl;
751 mRefParList.RestoreParamSet(mIndexValuesSetInitial);
752 for(std::list<RefinablePar*>::iterator pos=vnewpar.begin(); pos!=vnewpar.end(); pos++)
754 this->SetParIsFixed(**pos,
true);
756 for(std::list<const RefParType*>::iterator pos=vnewpartype.begin(); pos!=vnewpartype.end(); pos++)
758 this->SetParIsFixed(*pos,
true);
761 this->CalcRwFactor();
762 this->CalcChiSquare();
763 if(!silent) cout <<
"=> REVERTING to initial parameters values and fixing new parameters"<<endl;
769 CrystMatrix_REAL LSQNumObj::CorrelMatrix()
const{
return mCorrelMatrix;};
771 void LSQNumObj::CalcRfactor()
const
773 CrystVector_REAL calc, tmpV1, tmpV2;
774 calc=this->GetLSQCalc();
775 tmpV1 = this->GetLSQObs();
778 tmpV2 = this->GetLSQObs();
780 mR=sqrt(tmpV1.sum()/tmpV2.sum());
783 REAL LSQNumObj::Rfactor()
const{
return mR;};
785 void LSQNumObj::CalcRwFactor()
const
787 CrystVector_REAL calc, tmpV1, tmpV2;
788 calc=this->GetLSQCalc();
789 tmpV1 = this->GetLSQObs();
792 tmpV2 = this->GetLSQObs();
796 mRw=sqrt(tmpV1.sum()/tmpV2.sum());
799 REAL LSQNumObj::RwFactor()
const{
return mRw;};
801 void LSQNumObj::CalcChiSquare()
const
803 CrystVector_REAL calc, tmpV1;
804 calc=this->GetLSQCalc();
812 REAL LSQNumObj::ChiSquare()
const{
return mChiSq;};
815 void RecursiveMapFunc(RefinableObj &obj,map<RefinableObj*,unsigned int> &themap,
const unsigned int value)
818 ObjRegistry<RefinableObj> *pObjReg=&(obj.GetSubObjRegistry());
819 for(
int i=0;i<pObjReg->GetNb();i++)
820 RecursiveMapFunc(pObjReg->GetObj(i),themap,value);
824 void LSQNumObj::SetRefinedObj(
RefinableObj &obj,
const unsigned int LSQFuncIndex,
const bool init,
const bool recursive)
829 mvRefinedObjMap.clear();
831 if(recursive) RecursiveMapFunc(obj,mvRefinedObjMap,LSQFuncIndex);
832 else mvRefinedObjMap[&obj]=LSQFuncIndex;
837 const map<RefinableObj*,unsigned int>& LSQNumObj::GetRefinedObjMap()
const
839 return mvRefinedObjMap;
842 map<RefinableObj*,unsigned int>& LSQNumObj::GetRefinedObjMap()
844 return mvRefinedObjMap;
850 const RefinableObj& LSQNumObj::GetCompiledRefinedObj()
const{
return mRefParList;}
852 void LSQNumObj::SetUseSaveFileOnEachCycle(
bool yesOrNo)
854 mSaveReportOnEachCycle=yesOrNo;
857 void LSQNumObj::SetSaveFile(
string fileName)
859 mSaveFileName=fileName;
862 void LSQNumObj::PrintRefResults()
const
866 cout <<
"Results after last refinement :(" ;
868 cout <<
"Variable information : Initial, last cycle , current values and sigma"<<endl;
869 for (
int i=0;i<mRefParList.GetNbPar();i++)
871 if( (
true==mRefParList.GetPar(i).IsFixed())
872 || (
false == mRefParList.GetPar(i).IsUsed()) )
continue;
873 cout <<
FormatString(mRefParList.GetPar(i).GetName(),30) <<
" " ;
874 cout <<
FormatFloat((mRefParList.GetParamSet(mIndexValuesSetInitial))(i)*mRefParList.GetPar(i).GetHumanScale(),15,8) <<
" " ;
875 cout <<
FormatFloat((mRefParList.GetParamSet(mIndexValuesSetLast))(i)*mRefParList.GetPar(i).GetHumanScale(),15,8) <<
" " ;
876 cout <<
FormatFloat(mRefParList.GetPar(i).GetHumanValue(),15,8) <<
" " ;
877 cout <<
FormatFloat(mRefParList.GetPar(i).GetHumanSigma(),15,8) <<
" " ;
883 cout <<
"R-factor : " << mR<<endl;
884 cout <<
"Rw-factor : " << mRw<<endl;
885 cout <<
"Chi-Square: " << mChiSq<<endl;
886 cout <<
"GoF: " << mChiSq/this->GetLSQWeight().numElements()<<endl;
890 void LSQNumObj::SetDampingFactor(
const REAL newDampFact)
892 mDampingFactor=newDampFact;
895 void LSQNumObj::PurgeSaveFile()
900 void LSQNumObj::WriteReportToFile()
const
905 void LSQNumObj::OptimizeDerivativeSteps()
910 const std::map<pair<const RefinablePar*,const RefinablePar*>,REAL > & LSQNumObj::GetVarianceCovarianceMap()
const
911 {
return mvVarCovar;}
913 void LSQNumObj::PrepareRefParList(
const bool copy_param)
915 mRefParList.ResetParList();
916 for(map<RefinableObj*,unsigned int>::iterator pos=mvRefinedObjMap.begin();pos!=mvRefinedObjMap.end();++pos)
918 VFN_DEBUG_MESSAGE(
"LSQNumObj::PrepareRefParList():"<<pos->first->GetName(),4);
920 mRefParList.AddPar(*(pos->first),copy_param);
923 if(copy_param) mRefParList.SetDeleteRefParInDestructor(
true);
924 else mRefParList.SetDeleteRefParInDestructor(
false);
927 const CrystVector_REAL& LSQNumObj::GetLSQCalc()
const
929 const CrystVector_REAL *pV;
931 for(map<RefinableObj*,unsigned int>::const_iterator pos=mvRefinedObjMap.begin();pos!=mvRefinedObjMap.end();++pos)
933 if(pos->first->GetNbLSQFunction()==0)
continue;
934 pV=&(pos->first->GetLSQCalc(pos->second));
935 const long n2 = pV->numElements();
936 if((nb+n2)>mLSQCalc.numElements()) mLSQCalc.resizeAndPreserve(nb+pV->numElements());
937 const REAL *p1=pV->data();
938 REAL *p2=mLSQCalc.data()+nb;
939 for(
long j = 0; j < n2; ++j) *p2++ = *p1++;
942 if(mLSQCalc.numElements()>nb) mLSQCalc.resizeAndPreserve(nb);
946 const CrystVector_REAL& LSQNumObj::GetLSQObs()
const
948 const CrystVector_REAL *pV;
950 for(map<RefinableObj*,unsigned int>::const_iterator pos=mvRefinedObjMap.begin();pos!=mvRefinedObjMap.end();++pos)
952 if(pos->first->GetNbLSQFunction()==0)
continue;
953 pV=&(pos->first->GetLSQObs(pos->second));
954 const long n2 = pV->numElements();
955 mvRefinedObjLSQSize[pos->first]=n2;
956 if((nb+n2)>mLSQObs.numElements()) mLSQObs.resizeAndPreserve(nb+pV->numElements());
957 const REAL *p1=pV->data();
958 REAL *p2=mLSQObs.data()+nb;
959 for(
long j = 0; j < n2; ++j) *p2++ = *p1++;
962 if(mLSQObs.numElements()>nb) mLSQObs.resizeAndPreserve(nb);
966 const CrystVector_REAL& LSQNumObj::GetLSQWeight()
const
968 const CrystVector_REAL *pV;
970 for(map<RefinableObj*,unsigned int>::const_iterator pos=mvRefinedObjMap.begin();pos!=mvRefinedObjMap.end();++pos)
972 if(pos->first->GetNbLSQFunction()==0)
continue;
973 pV=&(pos->first->GetLSQWeight(pos->second));
974 const long n2 = pV->numElements();
975 if((nb+n2)>mLSQWeight.numElements()) mLSQWeight.resizeAndPreserve(nb+pV->numElements());
976 const REAL *p1=pV->data();
977 REAL *p2=mLSQWeight.data()+nb;
978 for(
long j = 0; j < n2; ++j) *p2++ = *p1++;
981 if(mLSQWeight.numElements()>nb) mLSQWeight.resizeAndPreserve(nb);
987 const CrystVector_REAL *pV;
989 for(map<RefinableObj*,unsigned int>::iterator pos=mvRefinedObjMap.begin();pos!=mvRefinedObjMap.end();++pos)
991 if(pos->first->GetNbLSQFunction()==0)
continue;
992 pV=&(pos->first->GetLSQDeriv(pos->second,par));
993 const long n2 = pV->numElements();
994 if((nb+n2)>mLSQDeriv.numElements()) mLSQDeriv.resizeAndPreserve(nb+pV->numElements());
995 const REAL *p1=pV->data();
996 REAL *p2=mLSQDeriv.data()+nb;
997 for(
long j = 0; j < n2; ++j) *p2++ = *p1++;
1000 if(mLSQDeriv.numElements()>nb) mLSQDeriv.resizeAndPreserve(nb);
1004 const std::map<RefinablePar*,CrystVector_REAL>& LSQNumObj::GetLSQ_FullDeriv()
1006 long nbVar=mRefParList.GetNbParNotFixed();
1007 std::set<RefinablePar*> vPar;
1008 for(
unsigned int i=0;i<nbVar;++i)
1009 vPar.insert(&(mRefParList.GetParNotFixed(i)));
1010 mLSQ_FullDeriv.clear();
1012 for(map<RefinableObj*,unsigned int>::iterator pos=mvRefinedObjMap.begin();pos!=mvRefinedObjMap.end();++pos)
1014 if(pos->first->GetNbLSQFunction()==0)
continue;
1015 const unsigned long n2=mvRefinedObjLSQSize[pos->first];
1018 const std::map<RefinablePar*,CrystVector_REAL> *pvV=&(pos->first->GetLSQ_FullDeriv(pos->second,vPar));
1019 for(std::map<RefinablePar*,CrystVector_REAL>::const_iterator d=pvV->begin();d!=pvV->end();d++)
1021 if(mLSQ_FullDeriv[d->first].size()==0) mLSQ_FullDeriv[d->first].resize(mLSQObs.size());
1022 REAL *p2=mLSQ_FullDeriv[d->first].data()+nb;
1023 if(d->second.size()==0)
1026 cout<<__FILE__<<
":"<<__LINE__<<
":"<<pos->first->GetClassName()<<
":"<<pos->first->GetName()<<
":"<<d->first->GetName()<<
" (all deriv=0)"<<endl;
1027 for(
unsigned long j=0;j<n2;++j) *p2++ = 0;
1031 const REAL *p1=d->second.data();
1032 for(
unsigned long j=0;j<n2;++j) *p2++ = *p1++;
1037 return mLSQ_FullDeriv;
1040 void LSQNumObj::BeginOptimization(
const bool allowApproximations,
const bool enableRestraints)
1042 for(map<RefinableObj*,unsigned int>::iterator pos=mvRefinedObjMap.begin();pos!=mvRefinedObjMap.end();++pos)
1043 pos->first->BeginOptimization(allowApproximations, enableRestraints);
1046 void LSQNumObj::EndOptimization()
1048 for(map<RefinableObj*,unsigned int>::iterator pos=mvRefinedObjMap.begin();pos!=mvRefinedObjMap.end();++pos)
1049 pos->first->EndOptimization();
1052 #ifdef __WX__CRYST__
1056 mpWXCrystObj=
new WXLSQ(parent,
this);
1057 return mpWXCrystObj;
1059 WXCrystObjBasic* LSQNumObj::WXGet()
1061 return mpWXCrystObj;
1063 void LSQNumObj::WXDelete()
1067 VFN_DEBUG_MESSAGE(
"LSQNumObj::WXDelete()",5)
1068 delete mpWXCrystObj;
1072 void LSQNumObj::WXNotifyDelete()
1074 VFN_DEBUG_MESSAGE(
"LSQNumObj::WXNotifyDelete():"<<mName,5)
The namespace which includes all objects (crystallographic and algorithmic) in ObjCryst++.
bool ISNAN_OR_INF(REAL r)
Test if the value is a NaN.
Exception class for ObjCryst++ library.
class of refinable parameter types.
Generic class for parameters of refinable objects.
const REAL * GetPointer() const
Access to a const pointer to the refined value.
Generic Refinable Object.
RefinablePar & GetPar(const long i)
Access all parameters in the order they were inputted.
long GetNbPar() const
Total number of refinable parameter in the object.
long GetNbParNotFixed() const
Total number of non-fixed parameters. Is initialized by PrepareForRefinement()
output a number as a formatted float:
output a string with a fixed length (adding necessary space or removing excess characters) :
Abstract base class for all objects in wxCryst.