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.