19 #include "ObjCryst/CrystVector/CrystVector.h" 
   20 #include "ObjCryst/Quirks/VFNStreamFormat.h" 
   21 #include "ObjCryst/ObjCryst/General.h" 
   23 #ifdef __LIBCRYST_VECTOR_USE_BLITZ__ 
   25 #define CrystVector Array<REAL,1> 
   26 #define CrystMatrix Array<REAL,2> 
   28 template<
class T> T MaxDifference(
const Array<T,1> &a,
const Array<T,1> &b)
 
   30    return max(fabs(a-b));
 
   33 template<
class T> T MaxDifference(
const Array<T,2> &a,
const Array<T,2> &b)
 
   35    return max(fabs(a-b));
 
   38 #else  // __LIBCRYST_VECTOR_USE_BLITZ__ 
   42 #define __VFN_GEOM_STRUCT_FACTOR_USE_POINTERS 
   44 #include "ObjCryst/Quirks/VFNDebug.h" 
   45 #include "ObjCryst/Quirks/VFNStreamFormat.h" 
   53 mNumElements(nbElements),mIsAreference(false)
 
   55    mpData=
new T[mNumElements];
 
   59 mNumElements(old.numElements()),mIsAreference(false)
 
   61    mpData=
new T[mNumElements];
 
   63    const T *p2=old.data();
 
   64    for(
long i=0;i<mNumElements;i++) *p1++=*p2++;
 
   76    VFN_DEBUG_MESSAGE(
"CrystVector<T>::operator=()",0)
 
   77    this->resize(old.numElements());
 
   80    const T *p2=old.data();
 
   81    for(
long i=0;i<mNumElements;i++) *p1++=*p2++;
 
   92       mNumElements=imax-imin;
 
   93       mpData=old.data()+imin;
 
   97       mNumElements=old.numElements();
 
  109    register const T *p=this->data();
 
  110    for(
long i=0;i<this->numElements();i++) tmp += *p++ ;
 
  116    register const T *p=this->data();
 
  118    for(
long i=1;i<this->numElements();i++)
 
  128    register const T *p=this->data();
 
  130    for(
long i=1;i<this->numElements();i++)
 
  138 template<
class T> 
unsigned long CrystVector<T>::imin(
const unsigned long start0,
const unsigned long finish0)
const 
  140    unsigned long start=start0,finish=finish0;
 
  144       finish=this->numElements();
 
  147    register const T *p=this->data()+start;
 
  150    for(
unsigned long i=start+1;i<finish;i++)
 
  152       if(tmp>*p) {tmp=*p;im=i;}
 
  155    return (
unsigned long)im;
 
  157 template<
class T> 
unsigned long CrystVector<T>::imax(
const unsigned long start0,
const unsigned long finish0)
const 
  159    unsigned long start=start0,finish=finish0;
 
  163       finish=this->numElements();
 
  166    register const T *p=this->data()+start;
 
  169    for(
unsigned long i=start+1;i<finish;i++)
 
  171       if(tmp<*p) {tmp=*p;im=i;}
 
  174    return (
unsigned long)im;
 
  182    if(mNumElements==newNbElements) 
return;
 
  183    VFN_DEBUG_MESSAGE(
"CrystVector<T>::resize():("<<mNumElements<<
"->" 
  184       <<newNbElements<<
").",0)
 
  185    if((mIsAreference==false) && (mNumElements != 0))
 
  190    mNumElements=newNbElements;
 
  193       mpData=
new T[mNumElements];
 
  201    if(newNbElements == mNumElements) 
return;
 
  202    register T * RESTRICT p=mpData;
 
  203    register T * RESTRICT p2,*p1;
 
  205    mpData=
new T[newNbElements];
 
  208    const long tmp= (newNbElements > mNumElements) ? mNumElements : newNbElements ;
 
  209    for(
long i=tmp;i>0;i--) *p2++ = *p1++ ;
 
  210    if(mIsAreference==
false)
 
  214    mNumElements=newNbElements;
 
  220    register T * RESTRICT p=mpData;
 
  221    for(
int i=mNumElements;i>0;i--) *p++ *= num;
 
  227    if( vect.numElements() != mNumElements)
 
  229       cout<<
"CrystVector::operator*=(&vect)(i): Number of elements differ:"<< mNumElements \
 
  230             << 
"!="<< vect.numElements() <<endl;
 
  234    if(mpData!=vect.data())
 
  236       register T * RESTRICT p=mpData;
 
  237       register const T * RESTRICT rhs=vect.data();
 
  238       for(
int i=mNumElements;i>0;i--) { *p *= *rhs; p++ ; rhs++;}
 
  242       register T *p=mpData;
 
  243       for(
int i=mNumElements;i>0;i--) { *p *= *p; p++ ;}
 
  249    register T * RESTRICT p=mpData;
 
  251    for(
int i=mNumElements;i>0;i--) *p++ *= d;
 
  257    if( vect.numElements() != mNumElements)
 
  259       cout<<
"CrystVector::operator/=(&vect)(i): Number of elements differ:"<< mNumElements \
 
  260             << 
"!="<< vect.numElements() <<endl;
 
  264    if(mpData!=vect.data())
 
  266       register T * RESTRICT p=mpData;
 
  267       register const T * RESTRICT rhs=vect.data();
 
  268       for(
int i=mNumElements;i>0;i--) { *p /= *rhs; p++ ; rhs++;}
 
  275    register T * RESTRICT p=mpData;
 
  276    for(
int i=mNumElements;i>0;i--) *p++ += num;
 
  282    if( vect.numElements() != mNumElements)
 
  284       cout<<
"CrystVector::operator+=(&vect)(i): Number of elements differ:"<< mNumElements \
 
  285             << 
"!="<< vect.numElements() <<endl;
 
  289    if(mpData!=vect.data())
 
  291       register T * RESTRICT p=mpData;
 
  292       const T * RESTRICT rhs=vect.data();
 
  293       for(
int i=mNumElements;i>0;i--) *p++ += *rhs++;
 
  297       register T *p=mpData;
 
  298       for(
int i=mNumElements;i>0;i--) {*p += *p; p++;}
 
  305    if( vect.numElements() != mNumElements)
 
  307       cout<<
"CrystVector::operator-=(&vect)(i): Number of elements differ:"<< mNumElements \
 
  308             << 
"!="<< vect.numElements() <<endl;
 
  312    if(mpData!=vect.data())
 
  314       register T * RESTRICT p=mpData;
 
  315       const T * RESTRICT rhs=vect.data();
 
  316       for(
int i=mNumElements;i>0;i--) *p++ -= *rhs++;
 
  323    register T *p=mpData;
 
  324    for(
int i=mNumElements;i>0;i--) *p++ = num;
 
  330    if( (i<0) || (i>=mNumElements))
 
  332       cout<<
"CrystVector::operator()(i): Tried to access an element out of bounds :"<<i<<endl;
 
  342    if( (i<0) || (i>=mNumElements))
 
  344       cout<<
"CrystVector::operator()(i): Tried to access an element out of bounds !"<<i<<endl;
 
  354 template<
class T> ostream& operator<<(ostream &os, CrystVector<T> &vect)
 
  357    for(
long i=0;i<vect.numElements();i++) os << vect(i) <<endl;
 
  365       long *pLong=subscript.data();
 
  366       for(
long i=0;i<subscript.numElements();i++) *pLong++ = i;
 
  370    QuickSortSubs(v,subscript,v.numElements()-1,0,0);
 
  376                                      long last,
long first, 
int depth)
 
  385    sepValeur = vect( (first + last) / 2 );
 
  388       while( vect(low) < sepValeur ) low++;
 
  389       while( vect(high) > sepValeur ) high--;
 
  394          vect(low) = vect(high);
 
  396          tmpSubs = subscript(low);
 
  397          subscript(low++) = subscript(high);
 
  398          subscript(high--) = tmpSubs;
 
  400    } 
while( low <= high);
 
  401    if( first < high ) QuickSortSubs(vect,subscript, high, first,depth);
 
  402    if( low < last ) QuickSortSubs(vect,subscript, last, low,depth);
 
  409    for(
long i=0;i<vect.numElements();i++) cosVect(i) = (T) cos(vect(i));
 
  416    for(
long i=0;i<vect.numElements();i++) sinVect(i) = (T) sin(vect(i));
 
  423    for(
long i=0;i<vect.numElements();i++) tanVect(i) = (T) tan(vect(i));
 
  430    for(
long i=0;i<vect.numElements();i++) tanVect(i) = (T) sqrt(vect(i));
 
  438 mpData(0),mNumElements(0),mXSize(0),mYSize(0),mIsAreference(false){}
 
  441 mNumElements(xSize*ySize),mXSize(xSize),mYSize(ySize),mIsAreference(false)
 
  443    mpData=
new T[mNumElements];
 
  447 mNumElements(old.numElements()),mXSize(old.cols()),mYSize(old.rows()),mIsAreference(false)
 
  449    mpData=
new T[mNumElements];
 
  450    register T *p1=mpData;
 
  451    register const T *p2=old.data();
 
  452    for(
long i=0;i<mNumElements;i++) *p1++=*p2++;
 
  468    if(mNumElements!=old.numElements())
 
  470       if(mIsAreference==
false)
 
  474       mNumElements=old.numElements();
 
  475       mpData=
new T[mNumElements];
 
  477    register T *p1=mpData;
 
  478    register const T *p2=old.data();
 
  479    for(
long i=0;i<mNumElements;i++) *p1++=*p2++;
 
  484    if(mIsAreference==
false)
 
  489    mNumElements=old.numElements();
 
  499    register const T *p=this->data();
 
  500    for(
long i=0;i<this->numElements();i++) tmp += *p++ ;
 
  507    register const T *p=this->data();
 
  509    for(
long i=1;i<this->numElements();i++)
 
  520    register const T *p=this->data();
 
  522    for(
long i=1;i<this->numElements();i++)
 
  541    if(xSize*ySize == mNumElements) 
return;
 
  549    mNumElements=xSize*ySize;
 
  552       mpData=
new T[mNumElements];
 
  560    if(xSize*ySize == mNumElements) 
return;
 
  561    register T *p=mpData;
 
  564    mpData=
new T[xSize*ySize];
 
  567    long tmp= ( (xSize*ySize) > mNumElements) ? mNumElements : xSize*ySize;
 
  568    for(
long i=0;i<tmp;i++) *p2++ = *p1++ ;
 
  573    mNumElements=xSize*ySize;
 
  585    register T *p=mpData;
 
  586    for(
int i=0;i<mNumElements;i++) *p++ *= num;
 
  592    if( this->numElements() != vect.numElements())
 
  594       cout<<
"CrystMatrix::operator*=(): Number of elements differ !"<<endl;
 
  598    register T *p=mpData;
 
  599    register const T *rhs=vect.data();
 
  600    for(
int i=0;i<mNumElements;i++) *p++ *= *rhs++;
 
  605    register T *p=mpData;
 
  606    for(
int i=0;i<mNumElements;i++) *p++ /= num;
 
  611    register T *p=mpData;
 
  612    for(
int i=0;i<mNumElements;i++) *p++ += num;
 
  617    register T *p=mpData;
 
  618    for(
int i=0;i<mNumElements;i++) *p++ -= num;
 
  623    if((this->cols()!=rhs.rows())||(this->rows()!=rhs.cols()))
 
  628    for(
unsigned int r=0;r<this->rows();r++)
 
  629      for(
unsigned int c=0;r<rhs.cols();c++)
 
  632        for(
unsigned int i=0;i<this->cols();i++)
 
  633          tmp+=(*
this)(r,i)*rhs(i,c);
 
  642    if( (i<0) || (i>=mNumElements))
 
  644       cout<<
"CrystMatrix::operator()(i): element out of bounds !"<<i<<endl;
 
  654    if( (i<0) || (j<0) || (i>=mYSize) || (j>=mXSize) )
 
  656       cout<<
"CrystMatrix::operator()(i,j): element out of bounds:"<<i<<
","<<j<<endl;
 
  657       cout<<
"dimensions:"<<mYSize<<
","<<mXSize<<endl;
 
  661    return mpData[i*mXSize+j];
 
  667    if( (i<0) || (i>=mNumElements))
 
  669       cout<<
"CrystMatrix::operator()(i): element out of bounds !"<<i<<endl;
 
  679    if( (i<0) || (j<0) || (i>=mYSize) || (j>=mXSize) )
 
  681       cout<<
"CrystMatrix::operator()(i,j): element out of bounds:"<<i<<
","<<j<<endl;
 
  685    return mpData[i*mXSize+j];
 
  691    for(
long i=0;i<this->cols();i++)
 
  692       for(
long j=0;j<this->rows();j++) newM(i,j)=(*this)(j,i);
 
  700 mpData(0),mNumElements(0),mXSize(0),mYSize(0),mZSize(0),mIsAreference(false){}
 
  705 mNumElements(xSize*ySize*zSize),mXSize(xSize),mYSize(ySize),mZSize(zSize),
 
  708    mpData=
new T[mNumElements];
 
  712 mNumElements(old.numElements()),
 
  713 mXSize(old.cols()),mYSize(old.rows()),mZSize(old.depth()),
 
  716    mpData=
new T[mNumElements];
 
  717    register T *p1=mpData;
 
  718    register const T *p2=old.data();
 
  719    for(
long i=0;i<mNumElements;i++) *p1++=*p2++;
 
  723 { 
if(!mIsAreference)
delete[] mpData;}
 
  731    if(mNumElements!=old.numElements())
 
  733       mNumElements=old.numElements();
 
  734       if(mIsAreference==
false)
delete[] mpData ;
 
  735       mpData=
new T[mNumElements];
 
  737    register T *p1=mpData;
 
  738    register const T *p2=old.data();
 
  739    for(
long i=0;i<mNumElements;i++) *p1++=*p2++;
 
  744    if(mIsAreference==
false) 
delete[] mpData ;
 
  746    mNumElements=old.numElements();
 
  756    register const T *p=this->data();
 
  757    for(
long i=0;i<this->numElements();i++) tmp += *p++ ;
 
  764    register const T *p=this->data();
 
  766    for(
long i=1;i<this->numElements();i++)
 
  777    register const T *p=this->data();
 
  779    for(
long i=1;i<this->numElements();i++)
 
  803    if(xSize*ySize*zSize == mNumElements) 
return;
 
  804    if(!mIsAreference)
delete[] mpData ;
 
  806    mNumElements=xSize*ySize*zSize;
 
  807    if(mNumElements>0) mpData=
new T[mNumElements];
 
  817    if(xSize*ySize*zSize == mNumElements) 
return;
 
  818    register T *p=mpData;
 
  820    mpData=
new T[xSize*ySize*zSize];
 
  823    long tmp= ( (xSize*ySize*zSize) > mNumElements) ? mNumElements : xSize*ySize*zSize;
 
  824    for(
long i=0;i<tmp;i++) *p2++ = *p1++ ;
 
  825    mNumElements=xSize*ySize*zSize;
 
  826    if(!mIsAreference)
delete[] p ;
 
  832    VFN_DEBUG_MESSAGE(
"CrystArray3D<T>::operator=():"<<num,1)
 
  833    register T *p=mpData;
 
  834    for(
int i=0;i<mNumElements;i++) *p++ = num;
 
  836 template<class T> 
void CrystArray3D<T>::operator*=(const T num)
 
  838    register T *p=mpData;
 
  839    for(
int i=0;i<mNumElements;i++) *p++ *= num;
 
  845    if( this->numElements() != vect.numElements())
 
  847       cout<<
"CrystArray3D::operator*=(): Number of elements differ !"<<endl;
 
  851    register T *p=mpData;
 
  852    register const T *rhs=vect.data();
 
  853    for(
int i=0;i<mNumElements;i++) *p++ *= *rhs++;
 
  858    register T *p=mpData;
 
  859    for(
int i=0;i<mNumElements;i++) *p++ /= num;
 
  864    register T *p=mpData;
 
  865    for(
int i=0;i<mNumElements;i++) *p++ += num;
 
  870    register T *p=mpData;
 
  871    for(
int i=0;i<mNumElements;i++) *p++ -= num;
 
  877    if( (i<0) || (i>=mNumElements))
 
  879       cout<<
"CrystArray3D::operator()(i): element out of bounds !"<<i<<endl;
 
  889    if( (i<0) || (j<0) || (k<0) || (i>=mZSize) || (j>=mYSize) || (k>=mXSize))
 
  891       cout<<
"CrystArray3D::operator()(i,j,k): element out of bounds:"<<i<<
","<<j<<
","<<k<<endl;
 
  892       cout<<
"dimensions:"<<mZSize<<
","<<mYSize<<
","<<mXSize<<endl;
 
  896    return mpData[i*mYSize*mXSize+j*mXSize+k];
 
  902    if( (i<0) || (i>=mNumElements))
 
  904       cout<<
"CrystArray3D::operator()(i): element out of bounds !"<<i<<endl;
 
  914    if( (i<0) || (j<0) || (k<0) || (i>=mZSize) || (j>=mYSize) || (k>=mXSize))
 
  916       cout<<
"CrystArray3D::operator()(i,j,k): element out of bounds:"<<i<<
","<<j<<
","<<k<<endl;
 
  917       cout<<
"dimensions:"<<mZSize<<
","<<mYSize<<
","<<mXSize<<endl;
 
  921    return mpData[i*mYSize*mXSize+j*mXSize+k];
 
  928 template<
class T> ostream& operator<<(ostream &os, const CrystMatrix<T> &vect)
 
  931    for(
long i=0;i<vect.rows();i++)
 
  933       for(
long j=0;j<vect.cols();j++) os << 
FormatFloat(vect(i,j)) ;
 
  939 template<
class T> ostream& operator<<(ostream &os, const CrystArray3D<T> &vect)
 
  941    for(
long i=0;i<vect.depth();i++)
 
  943       for(
long j=0;j<vect.rows();j++)
 
  945        for(
long k=0;k<vect.cols();k++) os << 
FormatFloat(vect(i,j,k)) ;
 
  955    const T *p1=a.data();
 
  956    const T *p2=b.data();
 
  959    for(
long i=0;i<a.numElements();i++)
 
  961       tmp=(T)fabs((REAL) (*p1++ - *p2++));
 
  969    const T *p1=a.data();
 
  970    const T *p2=b.data();
 
  973    for(
long i=0;i<a.numElements();i++)
 
  975       tmp=(T)fabs((REAL)(*p1++ - *p2++));
 
  983    VFN_DEBUG_ENTRY(
"CrystMatrix<T> product()",2)
 
  986    for(
long i=0;i<ab.rows();i++)
 
  988       for(
long j=0;j<ab.cols();j++)
 
  991          for(
long k=0;k<b.rows();k++) ab(i,j) += a(i,k)*b(k,j);
 
  994    VFN_DEBUG_EXIT(
"CrystMatrix<T> product()",2)
 
 1004 template ostream& operator<<(ostream &os, 
CrystVector<REAL> &vect);
 
 1007                             long last,
long first, 
int depth);
 
 1011 template ostream& operator<<(ostream &os, const 
CrystMatrix<REAL> &vect);
 
 1017 template ostream& operator<<(ostream &os, const 
CrystArray3D<REAL> &vect);
 
 1021 template ostream& operator<<(ostream &os, 
CrystVector<
long> &vect);
 
 1024                             long last,
long first, 
int depth);
 
 1028 template ostream& operator<<(ostream &os, const 
CrystMatrix<
long> &vect);
 
 1033 template ostream& operator<<(ostream &os, 
CrystVector<
int> &vect);
 
 1036                             long last,
long first, 
int depth);
 
 1040 template ostream& operator<<(ostream &os, const 
CrystMatrix<
int> &vect);
 
 1044 template ostream& operator<<(ostream &os, 
CrystVector<
unsigned int> &vect);
 
 1047                             long last,
long first, 
int depth);
 
 1051 template ostream& operator<<(ostream &os, const 
CrystMatrix<
unsigned int> &vect);
 
 1055 template ostream& operator<<(ostream &os, 
CrystVector<
bool> &vect);
 
 1058 template ostream& operator<<(ostream &os, const 
CrystMatrix<
bool> &vect);
 
 1062 #endif // __LIBCRYST_VECTOR_USE_BLITZ__ 
 1069 CrystMatrix_REAL InvertMatrix(
const CrystMatrix_REAL &m)
 
 1071    VFN_DEBUG_ENTRY(
"InvertMatrix()",2)
 
 1072    VFN_DEBUG_MESSAGE("->Matrix to invert :"<<endl<<m,1)
 
 1075       if( (m.rows() != m.cols()) || (m.rows() <2))
 
 1077          cout << 
"Matrix inversion: Cannot invert matrix !" <<endl;
 
 1082       CrystMatrix_REAL im(size,size),cm(size,size);
 
 1085       for(
long i=0;i<size;i++) im(i,i)=1.;
 
 1086       CrystMatrix_long rowIndex(size,1);
 
 1087       for(
long i=0;i<size;i++) rowIndex(i)=i;
 
 1089       for(
long i=0;i<size;i++)
 
 1094                REAL max=fabs(m(i,i));
 
 1095                for(
long j=i+1;j<m.rows();j++)
 
 1096                   if(fabs(m(j,i)) > max)
 
 1114                MatrixExchangeRows(cm,i,(
long)rowMax);
 
 1115                MatrixExchangeRows(im,i,(
long)rowMax);
 
 1116                MatrixExchangeRows(rowIndex,i,(
long)rowMax);
 
 1122             for(
long j=i+1;j<size;j++)
 
 1124                const REAL a=cm(j,i)/cm(i,i);
 
 1125                for(
long k=0;k<size;k++) im(j,k) -= im(i,k)*a;
 
 1126                for(
long k=0;k<size;k++) cm(j,k) -= cm(i,k)*a;
 
 1131    VFN_DEBUG_MESSAGE(
"Finish solving from the upper triangular matrix...",1);
 
 1132       for(
long i=0;i<size;i++)
 
 1135          for(
long j=i-1;j>=0;j--)
 
 1138             for(
long k=0;k<size;k++) im(j,k) -= im(i,k)*a;
 
 1139             for(
long k=0;k<size;k++) cm(j,k) -= cm(i,k)*a;
 
 1142          for(
long k=0;k<size;k++) im(i,k) /= a;
 
 1143          for(
long k=0;k<size;k++) cm(i,k) /= a;
 
 1160    VFN_DEBUG_MESSAGE(
"->Inverted Matrix :"<<endl<<im,1)
 
 1161    VFN_DEBUG_EXIT("InvertMatrix()",2)
 
 1165 template<class T> 
void MatrixExchangeRows(CrystMatrix_T &m, const 
long row1, const 
long row2)
 
 1168    if(row1 == row2) 
return;
 
 1169    long rowSize=m.cols();
 
 1171    for(
long i=0;i<rowSize;i++)
 
 1174       m(row1,i)=m(row2,i);
 
 1180 template void MatrixExchangeRows(CrystMatrix_REAL &m, 
const long row1, 
const long row2);
 
 1184 template<
class T> T MaxAbs(
const CrystVector_T &vector)
 
 1186    const T* pData=vector.data();
 
 1187    T max =(T) fabs((REAL) *pData++);
 
 1188    for(
long i=1;i<vector.numElements();i++)
 
 1190       if ( fabs((REAL) *pData) > max) max=(T) fabs((REAL) *pData);
 
 1197 template REAL  MaxAbs(
const CrystVector_REAL &vector);
 
 1198 template int    MaxAbs(
const CrystVector_int &vector);
 
 1199 template unsigned int    MaxAbs(
const CrystVector_uint &vector);
 
 1200 template long   MaxAbs(
const CrystVector_long &vector);
 
 1203 template<
class T> T MinAbs(
const CrystVector_T &vector)
 
 1205    const T* pData=vector.data();
 
 1206    T min =(T)  fabs((REAL) *pData++);
 
 1207    for(
long i=1;i<vector.numElements();i++)
 
 1209       if ( fabs((REAL) *pData) < min) min=(T) fabs((REAL) *pData);
 
 1216 template REAL  MinAbs(
const CrystVector_REAL &vector);
 
 1217 template int    MinAbs(
const CrystVector_int &vector);
 
 1218 template unsigned int    MinAbs(
const CrystVector_uint &vector);
 
 1219 template long   MinAbs(
const CrystVector_long &vector);
 
 1225 mX(0),mY(0),mYsecond(0)
 
 1229                          const REAL yp0, 
const REAL ypn)
 
 1231    this->
Init(x,y,yp0,ypn);
 
 1235                          const REAL yp0, 
const REAL ypn)
 
 1237    this->
Init(px,py,nbPoints,yp0,ypn);
 
 1247    this->
Init(px,py,nbPoints);
 
 1251                        const REAL yp0, 
const REAL ypn)
 
 1253    VFN_DEBUG_ENTRY(
"CubicSpline::Init(x,y,yp0,ypn)",5)
 
 1256    mYsecond.resize(x.numElements());
 
 1257    this->InitSpline(yp0,ypn);
 
 1258    VFN_DEBUG_EXIT(
"CubicSpline::Init(x,y,yp0,ypn)",5)
 
 1261                        const REAL yp0, 
const REAL ypn)
 
 1263    VFN_DEBUG_ENTRY(
"CubicSpline::Init(px,py,yp0,ypn)",5)
 
 1264    mX.resize(nbPoints);
 
 1265    mY.resize(nbPoints);
 
 1266    mYsecond.resize(nbPoints);
 
 1267    for(
unsigned long i=0;i<nbPoints;i++)
 
 1272    this->InitSpline(yp0,ypn);
 
 1273    VFN_DEBUG_EXIT(
"CubicSpline::Init(x,y,yp0,ypn)",5)
 
 1278    VFN_DEBUG_ENTRY(
"CubicSpline::Init(x,y)",5)
 
 1281    mYsecond.resize(x.numElements());
 
 1282    this->InitNaturalSpline();
 
 1283    VFN_DEBUG_EXIT(
"CubicSpline::Init(x,y)",5)
 
 1288    VFN_DEBUG_ENTRY(
"CubicSpline::Init(px,py,n)",5)
 
 1289    mX.resize(nbPoints);
 
 1290    mY.resize(nbPoints);
 
 1291    mYsecond.resize(nbPoints);
 
 1292    for(
unsigned long i=0;i<nbPoints;i++)
 
 1297    this->InitNaturalSpline();
 
 1298    VFN_DEBUG_EXIT(
"CubicSpline::Init(x,y,n)",5)
 
 1301 CubicSpline::~CubicSpline()
 
 1310    if(x<mX(0)) 
return mY(0);
 
 1311    for(i=0;i<(mX.numElements()-1);i++)
 
 1314          VFN_DEBUG_MESSAGE(
"CubicSpline::operator()(x):"<<x<<
":"<<mX(i+1)<<
":"<<i,0)
 
 1315          const REAL e=mX(i+1)-mX(i);
 
 1316          const REAL a=(mX(i+1)-x)/e;
 
 1318          const REAL c=1./6.*(a*a*a-a)*e*e;
 
 1319          const REAL d=1./6.*(b*b*b-b)*e*e;
 
 1320          return a*mY(i)+b*mY(i+1)+c*mYsecond(i)+d*mYsecond(i+1);
 
 1322    return mY(mY.numElements()-1);
 
 1327    const long nb=x.numElements();
 
 1328    CrystVector_REAL y(nb);
 
 1331    const REAL *px=x.data();
 
 1334    const REAL *pX=mX.data();
 
 1335    const REAL *pY=mY.data();
 
 1336    const REAL *pY2=mYsecond.data();
 
 1337    while((*px<*pX)&&(i<nb))
 
 1342    for(
long j=0;j<(mX.numElements()-1);j++)
 
 1344       while((*px<*(pX+1))&&(i<nb))
 
 1346          const REAL e= *(pX+1) - *pX;
 
 1347          const REAL a= (*(pX+1)- *px)/e;
 
 1349          const REAL c=0.16666666666666666*(a*a*a-a)*e*e;
 
 1350          const REAL d=0.16666666666666666*(b*b*b-b)*e*e;
 
 1351          *py++ = a* *pY +b* *(pY+1) +c* *pY2 +d* *(pY2+1);
 
 1357    for(;i<nb;++i) *py++ = *pY;
 
 1363    CrystVector_REAL y(nb);
 
 1367    const REAL *pX=mX.data();
 
 1368    const REAL *pY=mY.data();
 
 1369    const REAL *pY2=mYsecond.data();
 
 1370    while((x<*pX)&&(i<nb))
 
 1372       *py++=*pY;x += xstep;i++;
 
 1375    for(
long j=0;j<(mX.numElements()-1);j++)
 
 1377       while((x<*(pX+1))&&(i<nb))
 
 1379          const REAL e= *(pX+1) - *pX;
 
 1380          const REAL a= (*(pX+1)- x)/e;
 
 1382          const REAL c=0.16666666666666666*(a*a*a-a)*e*e;
 
 1383          const REAL d=0.16666666666666666*(b*b*b-b)*e*e;
 
 1384          *py++ = a* *pY +b* *(pY+1) +c* *pY2 +d* *(pY2+1);
 
 1390    for(;i<nb;++i) *py++ = *pY;
 
 1394 void CubicSpline::InitSpline(
const REAL yp0, 
const REAL ypn)
 
 1396    const long n=mX.numElements();
 
 1397    CrystVector_REAL u(mX.numElements());
 
 1399    u(0)=(3/(mX(1)-mX(0)))*((mY(1)-mY(0))/(mX(1)-mX(0))-yp0);
 
 1401    for(
long i=1;i<(n-1);i++)
 
 1403       a=(mX(i)-mX(i-1))/(mX(i+1)-mX(i-1));
 
 1404       b=a*mYsecond(i-1)+2;
 
 1405       mYsecond(i)=(a-1.)/b;
 
 1406       u(i)=(6*((mY(i+1)-mY(i))/(mX(i+1)-mX(i))-(mY(i)-mY(i-1))/(mX(i)-mX(i-1)))
 
 1407            /(mX(i+1)-mX(i-1))-a*u(i-1))/b;
 
 1409    const REAL c=(3./(mX(n-1)-mX(n-2)))*(ypn-(mY(n-1)-mY(n-2))/(mX(n-1)-mX(n-2)));
 
 1410    mYsecond(n-1)=(c-.5*u(n-2))/(0.5*mYsecond(n-2)+1);
 
 1411    for(
long i=(n-2);i>=0;i--) mYsecond(i)=mYsecond(i)*mYsecond(i+1)+u(i);
 
 1414 void CubicSpline::InitNaturalSpline()
 
 1416    const long n=mX.numElements();
 
 1417    CrystVector_REAL u(mX.numElements());
 
 1421    for(
long i=1;i<=(n-2);i++)
 
 1423       a=(mX(i)-mX(i-1))/(mX(i+1)-mX(i-1));
 
 1424       b=a*mYsecond(i-1)+2;
 
 1425       mYsecond(i)=(a-1)/b;
 
 1426       u(i)=(6*((mY(i+1)-mY(i))/(mX(i+1)-mX(i))-(mY(i)-mY(i-1))/(mX(i)-mX(i-1)))
 
 1427            /(mX(i+1)-mX(i-1))-a*u(i-1))/b;
 
 1430    for(
long i=(n-2);i>=0;i--) mYsecond(i)=mYsecond(i)*mYsecond(i+1)+u(i);
 
 1437 REAL sgcoeffs_0_5[]={-0.08571429,  0.34285714,  0.48571429,  0.34285714, -0.08571429};
 
 1438 REAL sgcoeffs_0_7[]={-0.0952381 ,  0.14285714,  0.28571429,  0.33333333,  0.28571429,
 
 1439                        0.14285714,  -0.0952381};
 
 1440 REAL sgcoeffs_0_9[]={-0.09090909,  0.06060606,  0.16883117,  0.23376623,  0.25541126,
 
 1441                       0.23376623,   0.16883117,  0.06060606, -0.09090909};
 
 1442 REAL sgcoeffs_0_11[]={-0.08391608,  0.02097902,  0.1025641 ,  0.16083916,  0.1958042 ,  0.20745921,
 
 1443                        0.1958042 ,  0.16083916,  0.1025641 ,  0.02097902, -0.08391608};
 
 1444 REAL sgcoeffs_0_13[]={-7.69230769e-02,   1.73472348e-18,   6.29370629e-02,   1.11888112e-01,
 
 1445                        1.46853147e-01,   1.67832168e-01,   1.74825175e-01,   1.67832168e-01,
 
 1446                        1.46853147e-01,   1.11888112e-01,   6.29370629e-02,   1.73472348e-18,
 
 1448 REAL sgcoeffs_0_15[]={-0.07058824, -0.01176471,  0.03800905,  0.07873303,  0.11040724,  0.13303167,
 
 1449                        0.14660633,  0.15113122,  0.14660633,  0.13303167,  0.11040724,
 
 1450                        0.07873303,  0.03800905, -0.01176471, -0.07058824};
 
 1451 REAL sgcoeffs_0_17[]={-0.06501548, -0.01857585,  0.02167183,  0.05572755,  0.08359133,  0.10526316,
 
 1452                        0.12074303,  0.13003096,  0.13312693,  0.13003096,  0.12074303,
 
 1453                        0.10526316,  0.08359133,  0.05572755,  0.02167183, -0.01857585,
 
 1455 REAL sgcoeffs_0_19[]={-0.06015038, -0.02255639,  0.01061477,  0.03936311,  0.06368863,  0.08359133,
 
 1456                        0.09907121,  0.11012826,  0.11676249,  0.11897391,  0.11676249,
 
 1457                        0.11012826,  0.09907121,  0.08359133,  0.06368863,  0.03936311,
 
 1458                        0.01061477, -0.02255639, -0.06015038};
 
 1459 REAL sgcoeffs_0_21[]={-0.05590062, -0.02484472,  0.00294214,  0.02745995,  0.04870873,  0.06668846,
 
 1460                        0.08139915,  0.0928408 ,  0.1010134 ,  0.10591697,  0.10755149,
 
 1461                        0.10591697,  0.1010134 ,  0.0928408 ,  0.08139915,  0.06668846,
 
 1462                        0.04870873,  0.02745995,  0.00294214, -0.02484472, -0.05590062};
 
 1463 REAL sgcoeffs_0_23[]={-0.05217391, -0.02608696, -0.00248447,  0.01863354,  0.03726708,  0.05341615,
 
 1464                        0.06708075,  0.07826087,  0.08695652,  0.0931677 ,  0.09689441,
 
 1465                        0.09813665,  0.09689441,  0.0931677 ,  0.08695652,  0.07826087,
 
 1466                        0.06708075,  0.05341615,  0.03726708,  0.01863354, -0.00248447,
 
 1467                       -0.02608696, -0.05217391};
 
 1468 CrystVector_REAL SavitzkyGolay(
const CrystVector_REAL &v, 
const unsigned int um, 
const unsigned int deriv)
 
 1470    const int m=(int)um;
 
 1474       if(m==2)sgcoeffs=sgcoeffs_0_5;
 
 1475       if(m==3)sgcoeffs=sgcoeffs_0_7;
 
 1476       if(m==4)sgcoeffs=sgcoeffs_0_9;
 
 1477       if(m==5)sgcoeffs=sgcoeffs_0_11;
 
 1478       if(m==6)sgcoeffs=sgcoeffs_0_13;
 
 1479       if(m==7)sgcoeffs=sgcoeffs_0_15;
 
 1480       if(m==8)sgcoeffs=sgcoeffs_0_17;
 
 1481       if(m==9)sgcoeffs=sgcoeffs_0_19;
 
 1482       if(m==10)sgcoeffs=sgcoeffs_0_21;
 
 1483       if(m==11)sgcoeffs=sgcoeffs_0_23;
 
 1487       sgcoeffs=
new REAL[2*m+1];
 
 1489       const REAL f=3/(REAL) (m*(m+1)*(2*m+1));
 
 1490       for(
int j=-m;j<=m;++j) *p++ = f*j;
 
 1494       sgcoeffs=
new REAL[2*m+1];
 
 1496       const REAL f1=45/(REAL) (m*(m+1)*(2*m+1)*(4*m*(m+1)-3));
 
 1497       const REAL f2=-15/(REAL) ((2*m+1)*(4*m*(m+1)-3));
 
 1498       for(
int j=-m;j<=m;++j) *p++ = f1*j*j + f2;
 
 1503    const unsigned int n=v.numElements();
 
 1504    CrystVector_REAL d(n);
 
 1506    const unsigned int nm=n-m;
 
 1507    REAL *pd=d.data()+m;
 
 1508    for(
unsigned int i=m;i<nm;++i)
 
 1510       const REAL *c=sgcoeffs,*p=v.data()+i-m;
 
 1511       for(
int j=-m;j<=m;++j) *pd += *c++ * *p++;
 
 1514    if(deriv!=0) 
delete[]sgcoeffs;
 
3D Vector (Blitz++ mimic) for ObjCryst++ 
void operator/=(const T num)
Element-by element division (array-like) 
CrystVector_REAL operator()(const CrystVector_REAL &x) const 
Get spline value at a series of point - x is assumed to be sorted by increasing values. 
void operator-=(const T num)
Element-by element substraction (array-like) 
void operator+=(const T num)
Element-by element addition (array-like) 
CubicSpline()
Default constructor - CubicSpline::Init() should be called afterwards. 
Vector library (Blitz++ mimic) for ObjCryst++. 
void Init(const CrystVector_REAL &x, const CrystVector_REAL &y, const REAL yp1, const REAL ypn)
Spline with given extremum derivatives. 
output a number as a formatted float: 
CrystMatrix Mult(const CrystMatrix &rhs)
matrix multiplication (linear algebra) 
2D Vector library (Blitz++ mimic) for ObjCryst++ 
unsigned long imax(const unsigned long start=0, const unsigned long finish=0) const 
Find index of maximum, between start and end (if start==end, use full vector) 
unsigned long imin(const unsigned long start=0, const unsigned long finish=0) const 
Find index of minimum, between start and end (if start==end, use full vector) 
void operator*=(const T num)
Element-by element multiplication (array-like)