File: CrystVector.h

package info (click to toggle)
objcryst-fox 2022.1-2
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 7,040 kB
  • sloc: cpp: 70,656; xml: 43,909; ansic: 467; python: 170; makefile: 21; sh: 12
file content (613 lines) | stat: -rw-r--r-- 20,472 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
/*  ObjCryst++ Object-Oriented Crystallographic Library
    (c) 2000-2008 Vincent Favre-Nicolin vincefn@users.sourceforge.net
        2000-2001 University of Geneva (Switzerland)

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
// This header defines which description should be used
// for vectors.

#ifndef __LIBCRYST_VECTOR_H
#define __LIBCRYST_VECTOR_H

#include "ObjCryst/ObjCryst/General.h"

#undef __LIBCRYST_VECTOR_USE_BLITZ__
//#define __LIBCRYST_VECTOR_USE_BLITZ__

#ifdef __LIBCRYST_VECTOR_USE_BLITZ__

#include <blitz/array.h>
using namespace blitz;

//Still use pointers for the Geometrical Structure computation ?
//(due to the complexity of the formulas, a blitz coding requires
//to much memory when compiling)
#define __VFN_GEOM_STRUCT_FACTOR_USE_POINTERS

#define CrystVector_REAL Array<REAL,1>
#define CrystVector_float  Array<float,1>
#define CrystVector_long   Array<long,1>
#define CrystVector_int    Array<int,1>
#define CrystVector_uint   Array<unsigned int,1>
#define CrystVector_bool   Array<bool,1>

#define CrystMatrix_REAL Array<REAL,2>
#define CrystMatrix_float  Array<float,2>
#define CrystMatrix_long   Array<long,2>
#define CrystMatrix_int    Array<int,2>
#define CrystMatrix_uint   Array<unsigned int,2>
#define CrystMatrix_bool   Array<bool,2>

#define CrystVector_T    Array<T,1>
#define CrystMatrix_T    Array<T,2>
#define CrystArray3D_T    Array<T,3>

template<class T> T MaxDifference(const Array<T,1> &a,const Array<T,1> &b);

template<class T> T MaxDifference(const Array<T,2> &a,const Array<T,2> &b);

#else  // __VFN_VECTOR_USE_BLITZ__


#define CrystVector_REAL CrystVector<REAL>
#define CrystVector_double  CrystVector<double>
#define CrystVector_float  CrystVector<float>
#define CrystVector_long   CrystVector<long>
#define CrystVector_int    CrystVector<int>
#define CrystVector_uint   CrystVector<unsigned int>
#define CrystVector_bool   CrystVector<bool>

#define CrystMatrix_REAL CrystMatrix<REAL>
#define CrystMatrix_double CrystMatrix<double>
#define CrystMatrix_float  CrystMatrix<float>
#define CrystMatrix_long   CrystMatrix<long>
#define CrystMatrix_int    CrystMatrix<int>
#define CrystMatrix_uint   CrystMatrix<unsigned int>
#define CrystMatrix_bool   CrystMatrix<bool>

#define CrystArray3D_REAL CrystArray3D<REAL>

#define CrystVector_T    CrystVector<T>
#define CrystMatrix_T    CrystMatrix<T>
#define CrystArray3D_T    CrystMatrix<T>

#define __VFN_GEOM_STRUCT_FACTOR_USE_POINTERS

#include <iostream>
#include <cmath>
using namespace std;

#ifdef _MSC_VER // MS VC++ predefined macros....
#undef min
#undef max
#endif

//######################################################################
//  CrystVector
//######################################################################
/** \brief Vector library (Blitz++ mimic) for ObjCryst++
*
*  The CrystVector library is not a new array computation library, despite
* the appearances. ObjCryst++ should used the
*  <a href="http://www.oonumerics.org/blitz/"> Blitz++ array library</a> , which yields
* excellent performance \e and simple array expressions. Unfortunately, the memory
* required to \e compile the library using gcc is far too high to be reasonable
* when using complex expressions and optimizing code. So until this has changed,
* The CrystVector and CrystMatrix library have been created, and these emulate
* (supposedly exactly) the Blitz++ interface (but not the smart handling of
* mathematical expressions, so pointers must be used). For documentation about these
* two libraries you should read the <a href="http://www.oonumerics.org/blitz/manual/">
* Blitz++ documentation</a>. CrystVector and CrystMatrix use the same kind of storage
* in memory.
*
* You can use CrystVector_REAL, CrystVector_long,etc... to declare 1D vectors. Macros
* ensure (well, should) ensure compatibility with Blitz++. (as of april 2001 support of
* blitz++ is broken).
*
* \todo check again Blitz++ support in newer gcc versions.
*/
template<class T> class CrystVector
{
   public:
   CrystVector();

   CrystVector(const long nbElements);

   CrystVector(const CrystVector &old);

   ~CrystVector();

   void operator=(const CrystVector &old);

   template<class U> void operator=(const CrystVector<U> &old)
   {
      if(mNumElements != old.numElements())
      {
         mNumElements = old.numElements();
         delete[] mpData;
         mpData=new T[mNumElements];
      };
      mIsAreference=false;
      T *p1=mpData;
      const U *p2=old.data();
      for(long i=0;i<mNumElements;i++) *p1++ = (T) *p2++;
   }

   #ifdef __MWERKS__
   operator CrystVector<bool>() const
   {
      CrystVector<bool> vect;
      vect=*this;
      return vect;
   }
   operator CrystVector<int>() const
   {
      CrystVector<int> vect;
      vect=*this;
      return vect;
   }
   operator CrystVector<long>() const
   {
      CrystVector<long> vect;
      vect=*this;
      return vect;
   }
   operator CrystVector<float>() const
   {
      CrystVector<float> vect;
      vect=*this;
      return vect;
   }
   operator CrystVector<double>() const
   {
      CrystVector<double> vect;
      vect=*this;
      return vect;
   }
   #else
   template<class U> operator CrystVector<U>() const
   {
      CrystVector<U> vect;
      vect=*this;
      return vect;
   }
   #endif
   /** Define this vector as a reference to another vector, or part of another vector
   *
   * \param old: the vector this one should point to
   * \param imin,imax: imax>imin, this vector will point to a part of the other
   * vector, from old(i) to old(imax-1)
   */
   void reference(CrystVector &old, const long imin=0, const long imax=0);

   long numElements()const;
   long size()const;
   T sum()const;
   T min()const;
   T max()const;
   /// Find index of minimum, 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 maximum, between start and end (if start==end, use full vector)
   unsigned long imax(const unsigned long start=0,const unsigned long finish=0)const;

   T * data();
   const T * data() const;

   void resize(const long newNbElements);

   void resizeAndPreserve(const long newNbElements);

   void operator*=(const T num);

   void operator*=(const CrystVector &vect);

   void operator/=(const T num);

   void operator/=(const CrystVector &vect);

   void operator+=(const T num);

   void operator+=(const CrystVector &vect);

   void operator-=(const CrystVector &vect);
/* Buggy ? (my version, not Blitz's!)
   // ListInitializer & ListInitializerSwitch are a simplified
   //version borrowed from the blitz++ library (see the blitz/listinit.h file)
   //
   // It allows a very convenient way of initializing arrays like this:
   // CrystVector arr(5); arr = 1,3,6,8,9;
   class ListInitializer
   {
      public:
         ListInitializer(T *pData):mpData(pData){};
         ~ListInitializer(){cout << "toto";};
         ListInitializer operator,(T x)
         {
            *mpData=x;
            return ListInitializer(mpData+1);
         }
      private:
         ListInitializer(){};
         T *mpData;
   };
   class ListInitializerSwitch
   {
      public:
         ListInitializerSwitch(CrystVector &vect, const T value):
            mVectData(vect.data()),mValue(value),
            mNumElements(vect.numElements()),wipeOnDestruct(true)
         {};

         ~ListInitializerSwitch()
         {
            if(wipeOnDestruct)
            {  //only one value given -> set all elements
               for(int i=0;i<mNumElements;i++)*mVectData++ = mValue;
            };
         };

         ListInitializer operator,(T x)
         {
            wipeOnDestruct=false;//operator, is used
            *mVectData=mValue;
            mVectData++;
            *mVectData=x;
            return ListInitializer(mVectData+1);
         }
      private:
         T *mVectData;
         T mValue;
         long mNumElements;
         bool wipeOnDestruct;
   };


   ListInitializerSwitch operator=(const T num)
   {
      return ListInitializerSwitch(*this,num);
   }
*/
   void operator=(const T num);

   T operator()(const long i) const;

   T& operator()(const long i);


   protected:
   private:
   T *mpData;
   long mNumElements;
   bool mIsAreference;//is a reference to another vector ?
   //friend ostream& operator<<(ostream &os,const CrystVector &vect);

};

template<class T> ostream& operator<<(ostream &os, CrystVector<T> &vect);

//Return the sorted subscripts of the array
template<class T> CrystVector<long> SortSubs(const CrystVector<T> &vect);
//Sort the array in place and also return the sorted subscripts
template<class T> long QuickSortSubs(CrystVector<T> &vect,
                                     CrystVector<long> &subscript,
                                     long last,long first=0, int depth=0);

///Cosinus (slow routine, not memory-savy..)
template<class T> CrystVector<T> cos(const CrystVector<T> &vect);
///Sinus (slow routine, not memory-savy...)
template<class T> CrystVector<T> sin(const CrystVector<T> &vect);
///Tangent (slow routine, not memory-savy...)
template<class T> CrystVector<T> tan(const CrystVector<T> &vect);
///Square root (slow routine, not memory-savy...)
template<class T> CrystVector<T> sqrt(const CrystVector<T> &vect);

//######################################################################
//  CrystMatrix
//######################################################################
/** \brief 2D Vector library (Blitz++ mimic) for ObjCryst++
*
*  The CrystVector library is not a new array computation library, despite
* the appearances. ObjCryst++ should used the
*  <a href="http://www.oonumerics.org/blitz/"> Blitz++ array library</a> , which yields
* excellent performance \e and simple array expressions. Unfortunately, the memory
* required to \e compile the library using gcc is far too high to be reasonable
* when using complex expressions and optimizing code. So until this has changed,
* The CrystVector and CrystMatrix library have been created, and these emulate
* (supposedly exactly) the Blitz++ interface (but not the smart handling of
* mathematical expressions, so pointers must be used). For documentation about these
* two libraries you should read the <a href="http://www.oonumerics.org/blitz/manual/">
* Blitz++ documentation</a>. CrystVector and CrystMatrix use the same kind of storage
* in memory.
*
* You can use CrystMatrix_REAL, CrystMatrix_long,etc... to declare 2D vectors. Macros
* ensure (well, should) ensure compatibility with Blitz++. (as of april 2001 support of
* blitz++ is broken).
*/
template<class T> class CrystMatrix
{
   public:
   CrystMatrix();
   //ySize : number of rows, xSize : number of columns
   CrystMatrix(const long ySize,const long xSize);

   CrystMatrix(const CrystMatrix &old);

   ~CrystMatrix();

   void operator=(const CrystMatrix &old);

   void reference(CrystMatrix &old);
   long numElements()const;
   long size()const;
   T sum()const;
   T min()const;
   T max()const;
   long rows()const;
   long cols()const;

   T * data();
   const T * data() const;

   void resize(const long ySize,const long xSize);

   void resizeAndPreserve(const long ySize,const long xSize);

   //void operator=(const T num);
   /// Element-by element multiplication (array-like)
   void operator*=(const T num);
   /// Element-by element multiplication (array-like)
   void operator*=(const CrystMatrix &vect);
   /// Element-by element division (array-like)
   void operator/=(const T num);
   /// Element-by element addition (array-like)
   void operator+=(const T num);
   /// Element-by element substraction (array-like)
   void operator-=(const T num);

   /// matrix multiplication (linear algebra)
   CrystMatrix Mult(const CrystMatrix &rhs);
   //:TODO: Check the following...

   // ListInitializer & ListInitializerSwitch are a simplified
   //version borrowed from the blitz++ library (see the blitz/listinit.h file)
   //
   // It allows a very convenient way of initializing arrays like this:
   // CrystVector arr(5); arr = 1,3,6,8,9;
   class ListInitializer
   {
      public:
         ListInitializer(T *pData):mpData(pData){};
         ~ListInitializer(){};
         ListInitializer operator,(T x)
         {
            *mpData=x;
            return ListInitializer(mpData+1);
         }
      private:
         ListInitializer(){};
         T *mpData;
   };
   class ListInitializerSwitch
   {
      public:
         ListInitializerSwitch(CrystMatrix &vect, const T value):
            mVectData(vect.data()),mValue(value),
            mNumElements(vect.numElements()),wipeOnDestruct(true)
         {};

         ~ListInitializerSwitch()
         {
            if(wipeOnDestruct)
            {  //only one value given -> set all elements
               for(int i=0;i<mNumElements;i++)*mVectData++ = mValue;
            };
         };

         ListInitializer operator,(T x)
         {
            wipeOnDestruct=false;//operator, is used
            *mVectData=mValue;
            mVectData++;
            *mVectData=x;
            return ListInitializer(mVectData+1);
         }
      private:
         T *mVectData;
         T mValue;
         long mNumElements;
         bool wipeOnDestruct;
   };


   ListInitializerSwitch operator=(const T num)
   {
      return ListInitializerSwitch(*this,num);
   }


   T operator()(const long i) const;

   T operator()(const long row,const long col) const;

   T& operator()(const long i);

   T& operator()(const long i,const long j);

   CrystMatrix transpose()const;

   protected:
   private:
   T *mpData;
   long mNumElements;
   long mXSize,mYSize;
   bool mIsAreference;//is a reference to another vector ?

   //friend ostream& operator<<(ostream &os,const CrystMatrix &vect);

};

template<class T> ostream& operator<<(ostream &os, const CrystMatrix<T> &vect);

template<class T> T MaxDifference(const CrystVector<T> &a,const CrystVector<T> &b);

template<class T> T MaxDifference(const CrystMatrix<T> &a,const CrystMatrix<T> &b);

template<class T> CrystMatrix<T> product(const CrystMatrix<T> &a,const CrystMatrix<T> &b);

//######################################################################
//  CrystArray3D
//######################################################################
/** \brief 3D Vector (Blitz++ mimic) for ObjCryst++
*
*  The CrystVector library is not a new array computation library, despite
* the appearances. ObjCryst++ should used the
*  <a href="http://www.oonumerics.org/blitz/"> Blitz++ array library</a> , which yields
* excellent performance \e and simple array expressions. Unfortunately, the memory
* required to \e compile the library using gcc is far too high to be reasonable
* when using complex expressions and optimizing code. So until this has changed,
* The CrystVector and CrystMatrix library have been created, and these emulate
* (supposedly exactly) the Blitz++ interface (but not the smart handling of
* mathematical expressions, so pointers must be used). For documentation about these
* two libraries you should read the <a href="http://www.oonumerics.org/blitz/manual/">
* Blitz++ documentation</a>. CrystVector and CrystMatrix use the same kind of storage
* in memory.
*
* You can use CrystArray3D_REAL, CrystArray3D_long,etc... to declare 3D vectors. Macros
* ensure (well, should) ensure compatibility with Blitz++. (as of april 2001 support of
* blitz++ is broken).
*/
template<class T> class CrystArray3D
{
   public:
   CrystArray3D();
   //ySize : number of rows, xSize : number of columns
   CrystArray3D(const long zSize,const long ySize,const long xSize);

   CrystArray3D(const CrystArray3D &old);

   ~CrystArray3D();

   void operator=(const CrystArray3D &old);

   void reference(CrystArray3D &old);
   long numElements()const;
   long size()const;
   T sum()const;
   T min()const;
   T max()const;
   long rows()const;
   long cols()const;
   long depth()const;

   T * data();
   const T * data() const;

   void resize(const long zSize,const long ySize,const long xSize);

   void resizeAndPreserve(const long zSize,const long ySize,const long xSize);

   void operator=(const T num);
   void operator*=(const T num);
   void operator*=(const CrystArray3D &vect);
   void operator/=(const T num);
   void operator+=(const T num);
   void operator-=(const T num);

   //void operator=(const T num);

   T operator()(const long i) const;

   T operator()(const long depth,const long row,const long col) const;

   T& operator()(const long i);

   T& operator()(const long depth,const long row,const long col);

   protected:
   private:
   T *mpData;
   long mNumElements;
   long mXSize,mYSize,mZSize;
   bool mIsAreference;//is a reference to another vector ?
};
template<class T> ostream& operator<<(ostream &os, const CrystArray3D<T> &vect);

#endif // __LIBCRYST_VECTOR_USE_BLITZ__

//Basic Gauss-Jordan elimination with partial pivot (rows only, using max pivot)
//Definitly *not* optimized !
CrystMatrix_REAL InvertMatrix(const CrystMatrix_REAL &m);
template<class T> void MatrixExchangeRows(CrystMatrix_T &m, const long row1, const long row2);

///Maximum absolute value of vector
template<class T> T MaxAbs(const CrystVector_T &vector);
///Minimum absolute value of vector
template<class T> T MinAbs(const CrystVector_T &vector);

//######################################################################
//  CubicSpline
//######################################################################
/// Cubic spline interpolation.
class CubicSpline
{
   public:
      /// Default constructor - CubicSpline::Init() should be called afterwards
      CubicSpline();
      /// Spline with given extremum derivatives
      CubicSpline(const CrystVector_REAL &x, const CrystVector_REAL &y,
                  const REAL yp1, const REAL ypn);
      /// Spline with given extremum derivatives
      CubicSpline(const REAL *px, const REAL *py, const unsigned long nbPoints,
                  const REAL yp1, const REAL ypn);
      /// Natural cubic spline
      CubicSpline(const CrystVector_REAL &x, const CrystVector_REAL &y);
      /// Natural cubic spline
      CubicSpline(const REAL *px, const REAL *py, const unsigned long nbPoints);
      ~CubicSpline();

      /// Spline with given extremum derivatives
      void Init(const CrystVector_REAL &x, const CrystVector_REAL &y,
                const REAL yp1, const REAL ypn);
      /// Spline with given extremum derivatives
      void Init(const REAL *px, const REAL *py, const unsigned long nbPoints,
                const REAL yp1, const REAL ypn);
      /// Natural cubic spline
      void Init(const CrystVector_REAL &x, const CrystVector_REAL &y);
      /// Natural cubic spline
      void Init(const REAL *px, const REAL *py, const unsigned long nbPoints);

      /// Get spline value at a series of point - x is assumed to be sorted by increasing values
      CrystVector_REAL operator()(const CrystVector_REAL &x) const;
      /// Get spline value on a range of values with a fixed step
      CrystVector_REAL operator()(const REAL min,const REAL step, const long nbpoint) const;
      /// Get spline value at one point
      REAL operator()(const REAL x) const;
   private:
      void InitSpline(const REAL yp1, const REAL ypn);
      void InitNaturalSpline();
      CrystVector_REAL mX;
      CrystVector_REAL mY;
      CrystVector_REAL mYsecond;
};
//######################################################################
//  Savitzky-Golay interpolation
//######################################################################
/** Savitzky-Golay computing of smoothed data, using 2nd order polynomial coefficients
*
*/
CrystVector_REAL SavitzkyGolay(const CrystVector_REAL &v, const unsigned int m, const unsigned int deriv);

#endif   // __LIBCRYST_VECTOR_H