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)