// Usuall mathematical functions and operations on arrays // R. Ansari, C.Magneville 03/2000 #include "machdefs.h" #include #include "matharr.h" // ---------------------------------------------------- // Application d'une fonction // ---------------------------------------------------- /*! \class SOPHYA::MathArray \ingroup TArray Class for simple mathematical operation on arrays \warning Instanciated only for \b real and \b double (r_4, r_8) type arrays */ //! Apply Function In Place (function double version) /*! \param a : array to be replaced in place \param f : function for replacement \return Return an array \b a filled with function f(a(i,j)) */ template TArray& MathArray::ApplyFunctionInPlace(TArray & a, Arr_DoubleFunctionOfX f) { if (a.NbDimensions() < 1) throw RangeCheckError("MathArray::ApplyFunctionInPlace(TArray & a..) Not Allocated Array a !"); T * pe; sa_size_t j,k; if (a.AvgStep() > 0) { // regularly spaced elements sa_size_t step = a.AvgStep(); sa_size_t maxx = a.Size()*step; pe = a.Data(); for(k=0; k TArray& MathArray::ApplyFunctionInPlaceF(TArray & a, Arr_FloatFunctionOfX f) { if (a.NbDimensions() < 1) throw RangeCheckError("MathArray::ApplyFunctionInPlaceF(TArray & a..) Not Allocated Array a !"); T * pe; sa_size_t j,k; if (a.AvgStep() > 0) { // regularly spaced elements sa_size_t step = a.AvgStep(); sa_size_t maxx = a.Size()*step; pe = a.Data(); for(k=0; k TArray MathArray::ApplyFunction(TArray const & a, Arr_DoubleFunctionOfX f) { TArray ra; ra = a; ApplyFunctionInPlace(ra, f); return(ra); } //! Apply Function (function float version) /*! \param a : argument array of the function \param f : function for replacement \return Return a new array filled with function f(a(i,j)) */ template TArray MathArray::ApplyFunctionF(TArray const & a, Arr_FloatFunctionOfX f) { TArray ra; ra = a; ApplyFunctionInPlaceF(ra, f); return(ra); } //! Compute \b mean and \b sigma of elements of array \b a, return \b mean template double MathArray::MeanSigma(TArray const & a, double & mean, double & sig) { if (a.NbDimensions() < 1) throw RangeCheckError("MathArray::MeanSigma(TArray const & a..) Not Allocated Array a !"); const T * pe; sa_size_t j,k; mean=0.; sig = 0.; double valok; if (a.AvgStep() > 0) { // regularly spaced elements sa_size_t step = a.AvgStep(); sa_size_t maxx = a.Size()*step; pe = a.Data(); for(k=0; k= 0.) sig = sqrt(sig); return(mean); } //------------------------------------------------------------------------------- // Definition utilitaire d'application de fonction inline complex ApplyComplexDoubleFunction(complex z, Arr_ComplexDoubleFunctionOfX f) { return(f(z)); } inline complex ApplyComplexDoubleFunction(complex z, Arr_ComplexDoubleFunctionOfX f) { complex zd((r_8)z.real(), (r_8)z.imag()); zd = f(zd); complex zr((r_4)zd.real(), (r_4)zd.imag()); return(zr); } //------------------------------------------------------------------------------- /*! \class SOPHYA::ComplexMathArray \ingroup TArray Class for simple mathematical operation on arrays \warning Instanciated only for \b real and \b double (r_4, r_8) complex arrays */ //! Apply Function In Place (complex arrays) /*! \param a : complex array to be replaced in place \param f : function for replacement \return Return an array \b a filled with function f(a(i,j)) */ template TArray< complex >& ComplexMathArray::ApplyFunctionInPlace(TArray< complex > & a, Arr_ComplexDoubleFunctionOfX f) { if (a.NbDimensions() < 1) throw RangeCheckError("ComplexMathArray< complex >::ApplyFunctionInPlace(TArray< complex > & a..) Not Allocated Array a !"); complex * pe; sa_size_t j,k; if (a.AvgStep() > 0) { // regularly spaced elements sa_size_t step = a.AvgStep(); sa_size_t maxx = a.Size()*step; pe = a.Data(); for(k=0; k TArray< complex > ComplexMathArray::ApplyFunction(TArray< complex > const & a, Arr_ComplexDoubleFunctionOfX f) { TArray< complex > ra; ra = a; ApplyFunctionInPlace(ra, f); return(ra); } //! Create a complex array, from a real and an imaginary arrays /*! \param p_real : array containing the real part of the complex output array \param p_imag : array containing the imaginary part of the complex output array \return Return a new complex array build from \b p_real and \b p_imag */ template TArray< complex > ComplexMathArray::FillFrom(TArray const & p_real, TArray const & p_imag) { if (p_real.NbDimensions() < 1) throw RangeCheckError("ComplexMathArray::FillFrom() - Not Allocated Array ! "); bool smo; if (!p_real.CompareSizes(p_imag, smo)) throw(SzMismatchError("ComplexMathArray::FillFrom() SizeMismatch")) ; TArray< complex > ra; ra.ReSize(p_real); complex * pe; const T * per; const T * pei; sa_size_t j,k,ka; if (smo && (p_real.AvgStep() > 0) && (p_imag.AvgStep() > 0)) { // regularly spaced elements sa_size_t step = p_real.AvgStep(); sa_size_t stepa = p_imag.AvgStep(); sa_size_t maxx = p_real.Size()*step; per = p_real.Data(); pei = p_imag.Data(); pe = ra.Data(); for(k=0, ka=0; k(per[k], pei[ka]) ; } else { // Non regular data spacing ... int_4 ax,axa; sa_size_t step, stepa; sa_size_t gpas, naxa; p_real.GetOpeParams(p_imag, smo, ax, axa, step, stepa, gpas, naxa); for(j=0; j(per[k], pei[ka]) ; } } return(ra); } //! Returns the real part of the complex input array. /*! \param a : input complex array \return Return a new array filled with the real part of the input complex array elements */ template TArray ComplexMathArray::real(TArray< complex > const & a) { if (a.NbDimensions() < 1) throw RangeCheckError("ComplexMathArray< complex >::real(TArray< complex >& a) Not Allocated Array a !"); TArray ra; ra.ReSize(a); const complex * pe; T * po; sa_size_t j,k; if (a.AvgStep() > 0) { // regularly spaced elements sa_size_t step = a.AvgStep(); sa_size_t maxx = a.Size()*step; pe = a.Data(); po = ra.Data(); for(k=0; k TArray ComplexMathArray::imag(TArray< complex > const & a) { if (a.NbDimensions() < 1) throw RangeCheckError("ComplexMathArray< complex >::imag(TArray< complex >& a) Not Allocated Array a !"); TArray ra; ra.ReSize(a); const complex * pe; T * po; sa_size_t j,k; if (a.AvgStep() > 0) { // regularly spaced elements sa_size_t step = a.AvgStep(); sa_size_t maxx = a.Size()*step; pe = a.Data(); po = ra.Data(); for(k=0; k TArray ComplexMathArray::module2(TArray< complex > const & a) { if (a.NbDimensions() < 1) throw RangeCheckError("ComplexMathArray< complex >::module2(TArray< complex >& a) Not Allocated Array a !"); TArray ra; ra.ReSize(a); const complex * pe; T * po; sa_size_t j,k; if (a.AvgStep() > 0) { // regularly spaced elements sa_size_t step = a.AvgStep(); sa_size_t maxx = a.Size()*step; pe = a.Data(); po = ra.Data(); for(k=0; k TArray ComplexMathArray::module(TArray< complex > const & a) { if (a.NbDimensions() < 1) throw RangeCheckError("ComplexMathArray< complex >::module(TArray< complex >& a) Not Allocated Array a !"); TArray ra; ra.ReSize(a); const complex * pe; T * po; sa_size_t j,k; if (a.AvgStep() > 0) { // regularly spaced elements sa_size_t step = a.AvgStep(); sa_size_t maxx = a.Size()*step; pe = a.Data(); po = ra.Data(); for(k=0; k TArray ComplexMathArray::phase(TArray< complex > const & a) { if (a.NbDimensions() < 1) throw RangeCheckError("ComplexMathArray< complex >::phase(TArray< complex >& a) Not Allocated Array a !"); TArray ra; ra.ReSize(a); const complex * pe; T * po; sa_size_t j,k; if (a.AvgStep() > 0) { // regularly spaced elements sa_size_t step = a.AvgStep(); sa_size_t maxx = a.Size()*step; pe = a.Data(); po = ra.Data(); for(k=0; k #pragma define_template MathArray #pragma define_template ComplexMathArray #pragma define_template ComplexMathArray #endif #if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES) template class MathArray; template class MathArray; template class ComplexMathArray; template class ComplexMathArray; #endif