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;
40 LSQNumObj::LSQNumObj(
string objName)
46 mSaveReportOnEachCycle=
false;
48 mSaveFileName=
"LSQrefinement.save";
52 mStopAfterCycle=
false;
55 LSQNumObj::~LSQNumObj()
62 void LSQNumObj::SetParIsFixed(
const string& parName,
const bool fix)
64 if(mRefParList.GetNbPar()==0) this->PrepareRefParList();
65 mRefParList.SetParIsFixed(parName,fix);
67 void LSQNumObj::SetParIsFixed(
const RefParType *type,
const bool fix)
69 if(mRefParList.GetNbPar()==0) this->PrepareRefParList();
70 mRefParList.SetParIsFixed(type,fix);
75 if(mRefParList.GetNbPar()==0) this->PrepareRefParList();
76 mRefParList.GetPar(par.
GetPointer()).SetIsFixed(fix);
82 if(mRefParList.GetNbPar()==0) this->PrepareRefParList();
83 for(
unsigned int i=0;i<obj.
GetNbPar();++i)
84 this->SetParIsFixed(obj.
GetPar(i),fix);
87 void LSQNumObj::UnFixAllPar()
89 if(mRefParList.GetNbPar()==0) this->PrepareRefParList();
90 mRefParList.UnFixAllPar();
93 void LSQNumObj::SetParIsUsed(
const string& parName,
const bool use)
95 if(mRefParList.GetNbPar()==0) this->PrepareRefParList();
96 mRefParList.SetParIsUsed(parName,use);
98 void LSQNumObj::SetParIsUsed(
const RefParType *type,
const bool use)
100 if(mRefParList.GetNbPar()==0) this->PrepareRefParList();
101 mRefParList.SetParIsUsed(type,use);
104 void LSQNumObj::Refine (
int nbCycle,
bool useLevenbergMarquardt,
105 const bool silent,
const bool callBeginEndOptimization,
106 const float minChi2var)
108 TAU_PROFILE(
"LSQNumObj::Refine()",
"void ()",TAU_USER);
109 TAU_PROFILE_TIMER(timer1,
"LSQNumObj::Refine() 1 - Init",
"", TAU_FIELD);
110 TAU_PROFILE_TIMER(timer2,
"LSQNumObj::Refine() 2 - LSQ Deriv",
"", TAU_FIELD);
111 TAU_PROFILE_TIMER(timer3,
"LSQNumObj::Refine() 3 - LSQ MB",
"", TAU_FIELD);
112 TAU_PROFILE_TIMER(timer4,
"LSQNumObj::Refine() 4 - LSQ Singular Values",
"", TAU_FIELD);
113 TAU_PROFILE_TIMER(timer5,
"LSQNumObj::Refine() 5 - LSQ Newmat, eigenvalues...",
"", TAU_FIELD);
114 TAU_PROFILE_TIMER(timer6,
"LSQNumObj::Refine() 6 - LSQ Apply",
"", TAU_FIELD);
115 TAU_PROFILE_TIMER(timer7,
"LSQNumObj::Refine() 7 - LSQ Finish",
"", TAU_FIELD);
116 TAU_PROFILE_START(timer1);
117 if(callBeginEndOptimization) this->BeginOptimization();
118 mObs=this->GetLSQObs();
119 mWeight=this->GetLSQWeight();
121 bool terminateOnDeltaChi2=
false;
125 terminateOnDeltaChi2=
true;
128 if(!silent) cout <<
"LSQNumObj::Refine():Beginning "<<endl;
130 if(mRefParList.GetNbPar()==0) this->PrepareRefParList();
131 mRefParList.PrepareForRefinement();
133 if(mRefParList.GetNbPar()==0)
throw ObjCrystException(
"LSQNumObj::Refine():no parameter to refine !");
136 long nbVar=mRefParList.GetNbParNotFixed();
137 const long nbObs=mObs.numElements();
138 CrystVector_REAL calc,calc0,calc1,tmpV1,tmpV2;
139 CrystMatrix_REAL M(nbVar,nbVar);
140 CrystMatrix_REAL N(nbVar,nbVar);
141 CrystVector_REAL B(nbVar);
142 CrystMatrix_REAL designMatrix(nbVar,nbObs);
143 CrystVector_REAL deltaVar(nbVar);
149 const REAL marquardtMult=4.;
152 calc=this->GetLSQCalc();
160 mIndexValuesSetInitial=mRefParList.CreateParamSet(
"LSQ Refinement-Initial Values");
161 mIndexValuesSetLast=mRefParList.CreateParamSet(
"LSQ Refinement-Last Cycle Values");
162 TAU_PROFILE_STOP(timer1);
164 for(
int cycle=1 ; cycle <=nbCycle;cycle++)
166 TAU_PROFILE_START(timer2);
167 const REAL ChisSqPreviousCycle=mChiSq;
168 mRefParList.SaveParamSet(mIndexValuesSetLast);
169 if(!silent) cout <<
"LSQNumObj::Refine():Cycle#"<< cycle <<endl;
171 calc0=this->GetLSQCalc();
178 R_ini=sqrt(tmpV1.sum()/tmpV2.sum());
182 Rw_ini=sqrt(tmpV1.sum()/tmpV2.sum());
185 pTmp2=designMatrix.data();
195 tmpV1=this->GetLSQDeriv(mRefParList.GetParNotFixed(i));
198 for(j=0;j<nbObs;j++) *pTmp2++ = *pTmp1++;
201 this->GetLSQ_FullDeriv();
204 pTmp1=mLSQ_FullDeriv[&(mRefParList.GetParNotFixed(i))].data();
206 for(j=0;j<nbObs;j++) *pTmp2++ = *pTmp1++;
211 TAU_PROFILE_STOP(timer2);
212 LSQNumObj_Refine_Restart:
213 TAU_PROFILE_START(timer3);
222 const register REAL * RESTRICT pD=designMatrix.data()+i*designMatrix.cols();
223 const register REAL * RESTRICT pW=mWeight.data();
224 REAL * RESTRICT p=tmpV1.data();
225 for(k=0;k<nbObs;k++) *p++ = *pD++ * *pW++;
227 const register REAL * pD=designMatrix.data();
230 const register REAL * p1=tmpV1.data();
232 for(k=0;k<nbObs;k++) v2+= *pD++ * *p1++;
236 const register REAL * pObs=mObs.data();
237 const register REAL * pCalc=calc0.data();
238 const register REAL * p1=tmpV1.data();
239 for(k=0;k<nbObs;k++) b+= (*pObs++ - *pCalc++)* *p1++;
242 for(k=0;k<nbObs;k++) tmpV1(k)=designMatrix(i,k);
246 for(k=0;k<nbObs;k++) tmpV2(k)=designMatrix(j,k);
258 TAU_PROFILE_STOP(timer3);
259 bool increaseMarquardt=
false;
260 LSQNumObj_Refine_RestartMarquardt:
261 TAU_PROFILE_START(timer4);
264 if(
true==useLevenbergMarquardt)
266 const REAL marquardtOLD=marquardt;
267 if(increaseMarquardt) marquardt=marquardt*marquardtMult;
268 const REAL lmfact=(1+marquardt)/(1+marquardtOLD);
269 for(i=0;i<nbVar;i++) M(i,i) *= lmfact;
277 if(!silent) cout <<
"LSQNumObj::Refine() Singular parameter !"
278 <<
"(null derivate in all points) : "<<M(i,i)<<
":"
279 << mRefParList.GetParNotFixed(i).GetName() << endl;
290 if(!silent) cout <<
"LSQNumObj::Refine(): Automatically fixing parameter";
291 if(!silent) cout <<
" and re-start cycle..";
292 if(!silent) cout << endl;
293 mRefParList.GetParNotFixed(i).SetIsFixed(
true);
294 mRefParList.PrepareForRefinement();
295 nbVar=mRefParList.GetNbParNotFixed();
298 mRefParList.RestoreParamSet(mIndexValuesSetInitial);
299 if(callBeginEndOptimization) this->EndOptimization();
300 if(!silent) mRefParList.Print();
301 throw ObjCrystException(
"LSQNumObj::Refine(): not enough (1) parameters after fixing one...");
303 N.resize(nbVar,nbVar);
304 deltaVar.resize(nbVar);
307 REAL *p1=designMatrix.data();
308 const REAL *p2=designMatrix.data();
311 for(
long j=i*nbObs+nbObs;j<nbObs*nbVar;j++) *p1++ = *p2++;
312 designMatrix.resizeAndPreserve(nbVar,nbObs);
331 M.resize(nbVar,nbVar);
333 TAU_PROFILE_STOP(timer4);
334 goto LSQNumObj_Refine_Restart;
337 TAU_PROFILE_STOP(timer4);
382 TAU_PROFILE_START(timer5);
386 CrystMatrix_REAL V(nbVar,nbVar);
387 CrystVector_REAL invW(nbVar);
390 SymmetricMatrix newmatA(nbVar);
391 Matrix newmatV(nbVar,nbVar),
392 newmatN(nbVar,nbVar);
393 DiagonalMatrix newmatW(nbVar);
394 ColumnVector newmatB(nbVar);
396 DiagonalMatrix newmatDscale(nbVar);
397 for(
long i=0;i<nbVar;i++)
398 newmatDscale(i+1,i+1) = 1./sqrt(M(i,i));
399 for(
long i=0;i<nbVar;i++)
402 for(
long j=0;j<nbVar;j++)
403 newmatA(i+1,j+1) = M(i,j) * newmatDscale(i+1,i+1) * newmatDscale(j+1,j+1);
413 EigenValues(newmatA,newmatW,newmatV);
417 cout<<
"Caught a Newmat exception :"<<BaseException::what()<<endl;
418 cout<<
"A:"<<endl<<newmatA<<endl<<
"W:"<<endl<<newmatW<<endl<<
"V:"<<endl<<newmatV<<endl<<
"Dscale:"<<newmatDscale*1e6<<endl;
419 cout<<setw(5)<<
"B:"<<endl;
420 for(
unsigned int i=0;i<B.size();i++) cout<<B(i)<<
" ";
421 cout<<endl<<endl<<
"M:"<<endl;
422 for(
unsigned int i=0;i<M.rows();i++)
424 for(
unsigned int j=0;j<M.cols();j++) cout<<M(i,j)<<
" ";
427 cout<<endl<<endl<<
"D:"<<endl;
428 for(
unsigned int i=0;i<designMatrix.rows();i++)
430 for(
unsigned int j=0;j<designMatrix.cols();j++) cout<<designMatrix(i,j)<<
" ";
436 ColumnVector newmatDelta(nbVar);
437 DiagonalMatrix newmatInvW(nbVar);
441 REAL max=newmatW.MaximumAbsoluteValue();
442 REAL minAllowedValue=1e-5*max;
443 for(
long i=0;i<nbVar;i++)
444 if(newmatW(i+1,i+1) > minAllowedValue)
445 newmatInvW(i+1,i+1)= 1./newmatW(i+1,i+1);
448 if(!silent) cout <<
"LSQNumObj::Refine():fixing ill-cond EigenValue "<< i <<endl;
449 newmatInvW(i+1,i+1) = 0.;
486 newmatN=newmatV * newmatInvW * newmatV.t();
489 newmatN = newmatDscale * newmatN * newmatDscale;
490 newmatDelta = newmatN * newmatB;
492 for(
long i=0;i<nbVar;i++)
494 invW(i)=newmatInvW(i+1,i+1);
495 deltaVar(i)=newmatDelta(i+1);
496 for(
long j=0;j<nbVar;j++)
498 N(i,j) = newmatN(i+1,j+1);
499 V(i,j) = newmatV(i+1,j+1);
510 TAU_PROFILE_STOP(timer5);
606 TAU_PROFILE_START(timer6);
612 mRefParList.GetParNotFixed(i).Mutate(deltaVar(i));
618 calc=this->GetLSQCalc();
621 REAL oldChiSq=mChiSq;
627 if(
true==useLevenbergMarquardt)
629 if(mChiSq > (oldChiSq*1.0001))
631 mRefParList.RestoreParamSet(mIndexValuesSetLast);
632 increaseMarquardt=
true;
635 cout <<
"LSQNumObj::Refine(Chi^2="<<oldChiSq<<
"->"<<mChiSq
636 <<
")=>Increasing Levenberg-Marquardt factor :"
637 <<
FormatFloat(marquardt*marquardtMult,18,14) <<endl;
643 mRefParList.RestoreParamSet(mIndexValuesSetLast);
644 if(callBeginEndOptimization) this->EndOptimization();
649 TAU_PROFILE_STOP(timer6);
650 goto LSQNumObj_Refine_RestartMarquardt;
654 if(!silent && (marquardt>1e-2))
656 cout <<
"LSQNumObj::Refine(Chi^2="<<oldChiSq<<
"->"<<mChiSq
657 <<
")=>Decreasing Levenberg-Marquardt factor :" <<
FormatFloat(marquardt/marquardtMult,18,14) <<endl;
659 marquardt /= marquardtMult;
660 if(marquardt<1e-2) marquardt=1e-2;
664 TAU_PROFILE_STOP(timer6);
665 TAU_PROFILE_START(timer7);
669 for(i=0;i<nbVar;i++) mRefParList.GetParNotFixed(i).SetSigma(0);
671 for(i=0;i<nbVar;i++) mRefParList.GetParNotFixed(i).SetSigma(sqrt(N(i,i)*mChiSq/(nbObs-nbVar)));
673 mCorrelMatrix.resize(nbVar,nbVar);
682 mCorrelMatrix(i,j)=sqrt(N(i,j)*N(i,j)/N(i,i)/N(j,j));
684 mvVarCovar[make_pair(pi,pj)]=N(i,j)*mChiSq/(nbObs-nbVar);
693 mR=sqrt(tmpV1.sum()/tmpV2.sum());
697 mRw=sqrt(tmpV1.sum()/tmpV2.sum());
699 if(!silent) cout <<
"finished cycle #"<<cycle <<
"/"<<nbCycle <<
". Rw="<<Rw_ini<<
"->"<<mRw<<
", Chi^2="<<ChisSqPreviousCycle<<
"->"<<mChiSq<<endl;
700 if (mSaveReportOnEachCycle) this->WriteReportToFile();
702 if(!silent) this->PrintRefResults();
703 TAU_PROFILE_STOP(timer7);
704 if( terminateOnDeltaChi2 && (minChi2var>( (ChisSqPreviousCycle-mChiSq)/abs(ChisSqPreviousCycle+1e-6) ) ) )
break;
706 if(callBeginEndOptimization) this->EndOptimization();
709 CrystMatrix_REAL LSQNumObj::CorrelMatrix()
const{
return mCorrelMatrix;};
711 REAL LSQNumObj::Rfactor()
const{
return mR;};
713 REAL LSQNumObj::RwFactor()
const{
return mRw;};
715 REAL LSQNumObj::ChiSquare()
const{
return mChiSq;};
718 void RecursiveMapFunc(RefinableObj &obj,map<RefinableObj*,unsigned int> &themap,
const unsigned int value)
721 ObjRegistry<RefinableObj> *pObjReg=&(obj.GetSubObjRegistry());
722 for(
int i=0;i<pObjReg->GetNb();i++)
723 RecursiveMapFunc(pObjReg->GetObj(i),themap,value);
727 void LSQNumObj::SetRefinedObj(
RefinableObj &obj,
const unsigned int LSQFuncIndex,
const bool init,
const bool recursive)
732 mvRefinedObjMap.clear();
734 if(recursive) RecursiveMapFunc(obj,mvRefinedObjMap,LSQFuncIndex);
735 else mvRefinedObjMap[&obj]=LSQFuncIndex;
740 const map<RefinableObj*,unsigned int>& LSQNumObj::GetRefinedObjMap()
const
742 return mvRefinedObjMap;
745 map<RefinableObj*,unsigned int>& LSQNumObj::GetRefinedObjMap()
747 return mvRefinedObjMap;
753 const RefinableObj& LSQNumObj::GetCompiledRefinedObj()
const{
return mRefParList;}
755 void LSQNumObj::SetUseSaveFileOnEachCycle(
bool yesOrNo)
757 mSaveReportOnEachCycle=yesOrNo;
760 void LSQNumObj::SetSaveFile(
string fileName)
762 mSaveFileName=fileName;
765 void LSQNumObj::PrintRefResults()
const
769 cout <<
"Results after last refinement :(" ;
771 cout <<
"Variable information : Initial, last cycle , current values and sigma"<<endl;
772 for (
int i=0;i<mRefParList.GetNbPar();i++)
774 if( (
true==mRefParList.GetPar(i).IsFixed())
775 || (
false == mRefParList.GetPar(i).IsUsed()) )
continue;
776 cout <<
FormatString(mRefParList.GetPar(i).GetName(),30) <<
" " ;
777 cout <<
FormatFloat((mRefParList.GetParamSet(mIndexValuesSetInitial))(i)*mRefParList.GetPar(i).GetHumanScale(),15,8) <<
" " ;
778 cout <<
FormatFloat((mRefParList.GetParamSet(mIndexValuesSetLast))(i)*mRefParList.GetPar(i).GetHumanScale(),15,8) <<
" " ;
779 cout <<
FormatFloat(mRefParList.GetPar(i).GetHumanValue(),15,8) <<
" " ;
780 cout <<
FormatFloat(mRefParList.GetPar(i).GetHumanSigma(),15,8) <<
" " ;
786 cout <<
"R-factor : " << mR<<endl;
787 cout <<
"Rw-factor : " << mRw<<endl;
788 cout <<
"Chi-Square: " << mChiSq<<endl;
789 cout <<
"GoF: " << mChiSq/this->GetLSQWeight().numElements()<<endl;
793 void LSQNumObj::SetDampingFactor(
const REAL newDampFact)
795 mDampingFactor=newDampFact;
798 void LSQNumObj::PurgeSaveFile()
803 void LSQNumObj::WriteReportToFile()
const
808 void LSQNumObj::OptimizeDerivativeSteps()
813 const std::map<pair<const RefinablePar*,const RefinablePar*>,REAL > & LSQNumObj::GetVarianceCovarianceMap()
const
814 {
return mvVarCovar;}
816 void LSQNumObj::PrepareRefParList(
const bool copy_param)
818 mRefParList.ResetParList();
819 for(map<RefinableObj*,unsigned int>::iterator pos=mvRefinedObjMap.begin();pos!=mvRefinedObjMap.end();++pos)
821 VFN_DEBUG_MESSAGE(
"LSQNumObj::PrepareRefParList():"<<pos->first->GetName(),4);
823 mRefParList.AddPar(*(pos->first),copy_param);
826 if(copy_param) mRefParList.SetDeleteRefParInDestructor(
true);
827 else mRefParList.SetDeleteRefParInDestructor(
false);
830 const CrystVector_REAL& LSQNumObj::GetLSQCalc()
const
832 const CrystVector_REAL *pV;
834 for(map<RefinableObj*,unsigned int>::const_iterator pos=mvRefinedObjMap.begin();pos!=mvRefinedObjMap.end();++pos)
836 if(pos->first->GetNbLSQFunction()==0)
continue;
837 pV=&(pos->first->GetLSQCalc(pos->second));
838 const long n2 = pV->numElements();
839 if((nb+n2)>mLSQCalc.numElements()) mLSQCalc.resizeAndPreserve(nb+pV->numElements());
840 const REAL *p1=pV->data();
841 REAL *p2=mLSQCalc.data()+nb;
842 for(
long j = 0; j < n2; ++j) *p2++ = *p1++;
845 if(mLSQCalc.numElements()>nb) mLSQCalc.resizeAndPreserve(nb);
849 const CrystVector_REAL& LSQNumObj::GetLSQObs()
const
851 const CrystVector_REAL *pV;
853 for(map<RefinableObj*,unsigned int>::const_iterator pos=mvRefinedObjMap.begin();pos!=mvRefinedObjMap.end();++pos)
855 if(pos->first->GetNbLSQFunction()==0)
continue;
856 pV=&(pos->first->GetLSQObs(pos->second));
857 const long n2 = pV->numElements();
858 mvRefinedObjLSQSize[pos->first]=n2;
859 if((nb+n2)>mLSQObs.numElements()) mLSQObs.resizeAndPreserve(nb+pV->numElements());
860 const REAL *p1=pV->data();
861 REAL *p2=mLSQObs.data()+nb;
862 for(
long j = 0; j < n2; ++j) *p2++ = *p1++;
865 if(mLSQObs.numElements()>nb) mLSQObs.resizeAndPreserve(nb);
869 const CrystVector_REAL& LSQNumObj::GetLSQWeight()
const
871 const CrystVector_REAL *pV;
873 for(map<RefinableObj*,unsigned int>::const_iterator pos=mvRefinedObjMap.begin();pos!=mvRefinedObjMap.end();++pos)
875 if(pos->first->GetNbLSQFunction()==0)
continue;
876 pV=&(pos->first->GetLSQWeight(pos->second));
877 const long n2 = pV->numElements();
878 if((nb+n2)>mLSQWeight.numElements()) mLSQWeight.resizeAndPreserve(nb+pV->numElements());
879 const REAL *p1=pV->data();
880 REAL *p2=mLSQWeight.data()+nb;
881 for(
long j = 0; j < n2; ++j) *p2++ = *p1++;
884 if(mLSQWeight.numElements()>nb) mLSQWeight.resizeAndPreserve(nb);
890 const CrystVector_REAL *pV;
892 for(map<RefinableObj*,unsigned int>::iterator pos=mvRefinedObjMap.begin();pos!=mvRefinedObjMap.end();++pos)
894 if(pos->first->GetNbLSQFunction()==0)
continue;
895 pV=&(pos->first->GetLSQDeriv(pos->second,par));
896 const long n2 = pV->numElements();
897 if((nb+n2)>mLSQDeriv.numElements()) mLSQDeriv.resizeAndPreserve(nb+pV->numElements());
898 const REAL *p1=pV->data();
899 REAL *p2=mLSQDeriv.data()+nb;
900 for(
long j = 0; j < n2; ++j) *p2++ = *p1++;
903 if(mLSQDeriv.numElements()>nb) mLSQDeriv.resizeAndPreserve(nb);
907 const std::map<RefinablePar*,CrystVector_REAL>& LSQNumObj::GetLSQ_FullDeriv()
909 long nbVar=mRefParList.GetNbParNotFixed();
910 std::set<RefinablePar*> vPar;
911 for(
unsigned int i=0;i<nbVar;++i)
912 vPar.insert(&(mRefParList.GetParNotFixed(i)));
913 mLSQ_FullDeriv.clear();
915 for(map<RefinableObj*,unsigned int>::iterator pos=mvRefinedObjMap.begin();pos!=mvRefinedObjMap.end();++pos)
917 if(pos->first->GetNbLSQFunction()==0)
continue;
918 const unsigned long n2=mvRefinedObjLSQSize[pos->first];
921 const std::map<RefinablePar*,CrystVector_REAL> *pvV=&(pos->first->GetLSQ_FullDeriv(pos->second,vPar));
922 for(std::map<RefinablePar*,CrystVector_REAL>::const_iterator d=pvV->begin();d!=pvV->end();d++)
924 if(mLSQ_FullDeriv[d->first].size()==0) mLSQ_FullDeriv[d->first].resize(mLSQObs.size());
925 REAL *p2=mLSQ_FullDeriv[d->first].data()+nb;
926 if(d->second.size()==0)
929 cout<<__FILE__<<
":"<<__LINE__<<
":"<<pos->first->GetClassName()<<
":"<<pos->first->GetName()<<
":"<<d->first->GetName()<<
" (all deriv=0)"<<endl;
930 for(
unsigned long j=0;j<n2;++j) *p2++ = 0;
934 const REAL *p1=d->second.data();
935 for(
unsigned long j=0;j<n2;++j) *p2++ = *p1++;
940 return mLSQ_FullDeriv;
943 void LSQNumObj::BeginOptimization(
const bool allowApproximations,
const bool enableRestraints)
945 for(map<RefinableObj*,unsigned int>::iterator pos=mvRefinedObjMap.begin();pos!=mvRefinedObjMap.end();++pos)
946 pos->first->BeginOptimization(allowApproximations, enableRestraints);
949 void LSQNumObj::EndOptimization()
951 for(map<RefinableObj*,unsigned int>::iterator pos=mvRefinedObjMap.begin();pos!=mvRefinedObjMap.end();++pos)
952 pos->first->EndOptimization();
959 mpWXCrystObj=
new WXLSQ(parent,
this);
962 WXCrystObjBasic* LSQNumObj::WXGet()
966 void LSQNumObj::WXDelete()
970 VFN_DEBUG_MESSAGE(
"LSQNumObj::WXDelete()",5)
975 void LSQNumObj::WXNotifyDelete()
977 VFN_DEBUG_MESSAGE(
"LSQNumObj::WXNotifyDelete():"<<mName,5)
const REAL * GetPointer() const
Access to a const pointer to the refined value.
bool ISNAN_OR_INF(REAL r)
Test if the value is a NaN.
long GetNbPar() const
Total number of refinable parameter in the object.
long GetNbParNotFixed() const
Total number of non-fixed parameters. Is initialized by PrepareForRefinement()
RefinablePar & GetPar(const long i)
Access all parameters in the order they were inputted.
Generic Refinable Object.
Abstract base class for all objects in wxCryst.
output a number as a formatted float:
output a string with a fixed length (adding necessary space or removing excess characters) : ...
Exception class for ObjCryst++ library.
The namespace which includes all objects (crystallographic and algorithmic) in ObjCryst++.
Generic class for parameters of refinable objects.
class of refinable parameter types.