| [787] | 1 | //  Usuall mathematical functions and operations on arrays | 
|---|
|  | 2 | //                     R. Ansari, C.Magneville   03/2000 | 
|---|
|  | 3 |  | 
|---|
|  | 4 | #include "machdefs.h" | 
|---|
| [882] | 5 | #include <math.h> | 
|---|
| [787] | 6 | #include "matharr.h" | 
|---|
|  | 7 |  | 
|---|
|  | 8 | // ---------------------------------------------------- | 
|---|
|  | 9 | //          Application d'une fonction | 
|---|
|  | 10 | // ---------------------------------------------------- | 
|---|
|  | 11 |  | 
|---|
| [926] | 12 | /*! | 
|---|
|  | 13 | \class SOPHYA::MathArray | 
|---|
|  | 14 | \ingroup TArray | 
|---|
|  | 15 | Class for simple mathematical operation on arrays | 
|---|
|  | 16 | \warning Instanciated only for \b real and \b double (r_4, r_8) type arrays | 
|---|
|  | 17 | */ | 
|---|
| [894] | 18 |  | 
|---|
|  | 19 | //! Apply Function In Place (function double version) | 
|---|
|  | 20 | /*! | 
|---|
|  | 21 | \param a : array to be replaced in place | 
|---|
|  | 22 | \param f : function for replacement | 
|---|
|  | 23 | \return Return an array \b a filled with function f(a(i,j)) | 
|---|
|  | 24 | */ | 
|---|
| [787] | 25 | template <class T> | 
|---|
|  | 26 | TArray<T>& MathArray<T>::ApplyFunctionInPlace(TArray<T> & a, Arr_DoubleFunctionOfX f) | 
|---|
|  | 27 | { | 
|---|
| [804] | 28 | if (a.NbDimensions() < 1) | 
|---|
|  | 29 | throw RangeCheckError("MathArray<T>::ApplyFunctionInPlace(TArray<T> & a..) Not Allocated Array a !"); | 
|---|
| [787] | 30 | T * pe; | 
|---|
|  | 31 | uint_8 j,k; | 
|---|
|  | 32 | if (a.AvgStep() > 0)   {  // regularly spaced elements | 
|---|
|  | 33 | uint_8 step = a.AvgStep(); | 
|---|
|  | 34 | uint_8 maxx = a.Size()*step; | 
|---|
|  | 35 | pe = a.Data(); | 
|---|
|  | 36 | for(k=0; k<maxx; k+=step )  pe[k] = (T)(f((double)pe[k])); | 
|---|
|  | 37 | } | 
|---|
|  | 38 | else {    // Non regular data spacing ... | 
|---|
|  | 39 | uint_4 ka = a.MaxSizeKA(); | 
|---|
|  | 40 | uint_8 step = a.Step(ka); | 
|---|
|  | 41 | uint_8 gpas = a.Size(ka)*step; | 
|---|
| [813] | 42 | uint_8 naxa = a.Size()/a.Size(ka); | 
|---|
|  | 43 | for(j=0; j<naxa; j++)  { | 
|---|
|  | 44 | pe = a.DataBlock().Begin()+a.Offset(ka,j); | 
|---|
| [787] | 45 | for(k=0; k<gpas; k+=step)  pe[k] = (T)(f((double)pe[k])); | 
|---|
|  | 46 | } | 
|---|
|  | 47 | } | 
|---|
|  | 48 | return(a); | 
|---|
|  | 49 | } | 
|---|
|  | 50 |  | 
|---|
| [894] | 51 | //! Apply Function In Place (function float version) | 
|---|
|  | 52 | /*! | 
|---|
|  | 53 | \param a : array to be replaced in place | 
|---|
|  | 54 | \param f : function for replacement | 
|---|
|  | 55 | \return Return an array \b a filled with function f(a(i,j)) | 
|---|
|  | 56 | */ | 
|---|
| [787] | 57 | template <class T> | 
|---|
|  | 58 | TArray<T>& MathArray<T>::ApplyFunctionInPlace(TArray<T> & a, Arr_FloatFunctionOfX f) | 
|---|
|  | 59 | { | 
|---|
| [804] | 60 | if (a.NbDimensions() < 1) | 
|---|
|  | 61 | throw RangeCheckError("MathArray<T>::ApplyFunctionInPlace(TArray<T> & a..) Not Allocated Array a !"); | 
|---|
| [787] | 62 | T * pe; | 
|---|
|  | 63 | uint_8 j,k; | 
|---|
|  | 64 | if (a.AvgStep() > 0)   {  // regularly spaced elements | 
|---|
|  | 65 | uint_8 step = a.AvgStep(); | 
|---|
|  | 66 | uint_8 maxx = a.Size()*step; | 
|---|
|  | 67 | pe = a.Data(); | 
|---|
|  | 68 | for(k=0; k<maxx; k+=step )  pe[k] = (T)(f((float)pe[k])); | 
|---|
|  | 69 | } | 
|---|
|  | 70 | else {    // Non regular data spacing ... | 
|---|
|  | 71 | uint_4 ka = a.MaxSizeKA(); | 
|---|
|  | 72 | uint_8 step = a.Step(ka); | 
|---|
|  | 73 | uint_8 gpas = a.Size(ka)*step; | 
|---|
| [813] | 74 | uint_8 naxa = a.Size()/a.Size(ka); | 
|---|
|  | 75 | for(j=0; j<naxa; j++)  { | 
|---|
|  | 76 | pe = a.DataBlock().Begin()+a.Offset(ka,j); | 
|---|
| [787] | 77 | for(k=0; k<gpas; k+=step)  pe[k] = (T)(f((float)pe[k])); | 
|---|
|  | 78 | } | 
|---|
|  | 79 | } | 
|---|
|  | 80 | return(a); | 
|---|
|  | 81 | } | 
|---|
|  | 82 |  | 
|---|
|  | 83 |  | 
|---|
| [894] | 84 | //! Apply Function (function double version) | 
|---|
|  | 85 | /*! | 
|---|
|  | 86 | \param a : argument array of the function | 
|---|
|  | 87 | \param f : function for replacement | 
|---|
|  | 88 | \return Return a new array filled with function f(a(i,j)) | 
|---|
|  | 89 | */ | 
|---|
| [787] | 90 | template <class T> | 
|---|
|  | 91 | TArray<T> MathArray<T>::ApplyFunction(TArray<T> const & a, Arr_DoubleFunctionOfX f) | 
|---|
|  | 92 | { | 
|---|
|  | 93 | TArray<T> ra; | 
|---|
|  | 94 | ra = a; | 
|---|
|  | 95 | ApplyFunctionInPlace(ra, f); | 
|---|
|  | 96 | return(ra); | 
|---|
|  | 97 | } | 
|---|
|  | 98 |  | 
|---|
| [894] | 99 | //! Apply Function (function float version) | 
|---|
|  | 100 | /*! | 
|---|
|  | 101 | \param a : argument array of the function | 
|---|
|  | 102 | \param f : function for replacement | 
|---|
|  | 103 | \return Return a new array filled with function f(a(i,j)) | 
|---|
|  | 104 | */ | 
|---|
| [787] | 105 | template <class T> | 
|---|
|  | 106 | TArray<T> MathArray<T>::ApplyFunction(TArray<T> const & a, Arr_FloatFunctionOfX f) | 
|---|
|  | 107 | { | 
|---|
|  | 108 | TArray<T> ra; | 
|---|
|  | 109 | ra = a; | 
|---|
|  | 110 | ApplyFunctionInPlace(ra, f); | 
|---|
|  | 111 | return(ra); | 
|---|
|  | 112 | } | 
|---|
|  | 113 |  | 
|---|
| [894] | 114 | //! Compute \b mean and \b sigma of elements of array \b a, return \b mean | 
|---|
| [804] | 115 | template <class T> | 
|---|
|  | 116 | double MathArray<T>::MeanSigma(TArray<T> const & a, double & mean, double & sig) | 
|---|
|  | 117 | { | 
|---|
|  | 118 | if (a.NbDimensions() < 1) | 
|---|
|  | 119 | throw RangeCheckError("MathArray<T>::MeanSigma(TArray<T> const & a..) Not Allocated Array a !"); | 
|---|
|  | 120 | const T * pe; | 
|---|
|  | 121 | uint_8 j,k; | 
|---|
|  | 122 | mean=0.; | 
|---|
|  | 123 | sig = 0.; | 
|---|
|  | 124 | double valok; | 
|---|
|  | 125 | if (a.AvgStep() > 0)   {  // regularly spaced elements | 
|---|
|  | 126 | uint_8 step = a.AvgStep(); | 
|---|
|  | 127 | uint_8 maxx = a.Size()*step; | 
|---|
|  | 128 | pe = a.Data(); | 
|---|
|  | 129 | for(k=0; k<maxx; k+=step )  { | 
|---|
|  | 130 | valok = (double) pe[k]; | 
|---|
|  | 131 | mean += valok;  sig += valok*valok; | 
|---|
|  | 132 | } | 
|---|
|  | 133 | } | 
|---|
|  | 134 | else {    // Non regular data spacing ... | 
|---|
|  | 135 | uint_4 ka = a.MaxSizeKA(); | 
|---|
|  | 136 | uint_8 step = a.Step(ka); | 
|---|
|  | 137 | uint_8 gpas = a.Size(ka)*step; | 
|---|
| [813] | 138 | uint_8 naxa = a.Size()/a.Size(ka); | 
|---|
|  | 139 | for(j=0; j<naxa; j++)  { | 
|---|
|  | 140 | pe = a.DataBlock().Begin()+a.Offset(ka,j); | 
|---|
| [804] | 141 | for(k=0; k<gpas; k+=step) { | 
|---|
|  | 142 | valok = (double) pe[k]; | 
|---|
|  | 143 | mean += valok;  sig += valok*valok; | 
|---|
|  | 144 | } | 
|---|
|  | 145 | } | 
|---|
|  | 146 | } | 
|---|
|  | 147 | double dsz = (double)(a.Size()); | 
|---|
|  | 148 | mean /= dsz; | 
|---|
|  | 149 | sig = sig/dsz - mean*mean; | 
|---|
| [942] | 150 | //   #if !defined(OS_LINUX) && !defined (__KCC__) | 
|---|
|  | 151 | #if !defined(__GNUG__) | 
|---|
| [804] | 152 | if (sig >= 0.) sig = sqrt(sig); | 
|---|
| [882] | 153 | #else | 
|---|
| [942] | 154 | // va comprendre pourquoi g++ veut ca pour faire la generation | 
|---|
| [882] | 155 | // de template !!!! | 
|---|
|  | 156 | if (sig >= 0.) sig = _Sqrt_(sig); | 
|---|
|  | 157 | #endif | 
|---|
| [804] | 158 | return(mean); | 
|---|
|  | 159 | } | 
|---|
|  | 160 |  | 
|---|
| [787] | 161 | /////////////////////////////////////////////////////////////// | 
|---|
|  | 162 | #ifdef __CXX_PRAGMA_TEMPLATES__ | 
|---|
|  | 163 | #pragma define_template MathArray<r_4> | 
|---|
|  | 164 | #pragma define_template MathArray<r_8> | 
|---|
|  | 165 | #endif | 
|---|
|  | 166 |  | 
|---|
|  | 167 | #if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES) | 
|---|
|  | 168 | template class MathArray<r_4>; | 
|---|
|  | 169 | template class MathArray<r_8>; | 
|---|
|  | 170 | #endif | 
|---|