Changeset 1517 in Sophya for trunk/SophyaLib/TArray/matharr.cc


Ignore:
Timestamp:
Jun 12, 2001, 6:21:13 PM (24 years ago)
Author:
ansari
Message:

Rajout classe ComplexMathArray pour operations sur tableaux complexes (real(), imag() ,...) - Ajout fonctions TArray::ReadASCII() (pas encore implementee) et TArray::WriteASCII() - Reza 12/6/2001

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/SophyaLib/TArray/matharr.cc

    r1226 r1517  
    152152}
    153153
     154
     155//-------------------------------------------------------------------------------
     156//      Definition utilitaire d'application de fonction
     157inline complex<r_8> ApplyComplexDoubleFunction(complex<r_8> z,
     158                                               Arr_ComplexDoubleFunctionOfX f)
     159{
     160  return(f(z));
     161}
     162
     163inline complex<r_4> ApplyComplexDoubleFunction(complex<r_4> z,
     164                                               Arr_ComplexDoubleFunctionOfX f)
     165{
     166  complex<r_8> zd((r_8)z.real(), (r_8)z.imag());
     167  zd = f(zd);
     168  complex<r_8> zr((r_4)zd.real(), (r_4)zd.imag());
     169  return(zr);
     170}
     171
     172//-------------------------------------------------------------------------------
     173
     174/*!
     175  \class SOPHYA::ComplexMathArray
     176  \ingroup TArray
     177  Class for simple mathematical operation on arrays
     178  \warning Instanciated only for \b real and \b double (r_4, r_8) complex arrays
     179*/
     180
     181//! Apply Function In Place (complex arrays)
     182/*!
     183  \param a : complex array to be replaced in place
     184  \param f : function for replacement
     185  \return Return an array \b a filled with function f(a(i,j))
     186*/
     187template <class T>
     188TArray< complex<T> >& ComplexMathArray<T>::ApplyFunctionInPlace(TArray< complex<T> > & a, Arr_ComplexDoubleFunctionOfX f)
     189{
     190  if (a.NbDimensions() < 1)
     191    throw RangeCheckError("ComplexMathArray< complex<T> >::ApplyFunctionInPlace(TArray< complex<T> > & a..) Not Allocated Array a !");
     192  complex<T> * pe;
     193  sa_size_t j,k;
     194  if (a.AvgStep() > 0)   {  // regularly spaced elements
     195    sa_size_t step = a.AvgStep();
     196    sa_size_t maxx = a.Size()*step;
     197    pe = a.Data();
     198    for(k=0; k<maxx; k+=step )  pe[k] = ApplyComplexDoubleFunction(pe[k],f);
     199  }
     200  else {    // Non regular data spacing ...
     201    int_4 ka = a.MaxSizeKA();
     202    sa_size_t step = a.Step(ka);
     203    sa_size_t gpas = a.Size(ka)*step;
     204    sa_size_t naxa = a.Size()/a.Size(ka);
     205    for(j=0; j<naxa; j++)  {
     206      pe = a.DataBlock().Begin()+a.Offset(ka,j);
     207      for(k=0; k<gpas; k+=step)  pe[k] = ApplyComplexDoubleFunction(pe[k],f);
     208    }
     209  }
     210  return(a);
     211}
     212
     213
     214
     215//! Apply Function (complex arrays)
     216/*!
     217  \param a : argument array of the function
     218  \param f : function for replacement
     219  \return Return a new array filled with function f(a(i,j))
     220*/
     221template <class T>
     222TArray< complex<T> > ComplexMathArray<T>::ApplyFunction(TArray< complex<T> > const & a, Arr_ComplexDoubleFunctionOfX f)
     223{
     224  TArray< complex<T> > ra;
     225  ra = a;
     226  ApplyFunctionInPlace(ra, f);
     227  return(ra);
     228}
     229
     230//! Create a complex array, from a real and an imaginary arrays
     231/*!
     232  \param p_real : array containing the real part of the complex output array
     233  \param p_imag : array containing the imaginary part of the complex output array
     234  \return Return a new complex array build from \b p_real and \b p_imag
     235*/
     236template <class T>
     237TArray< complex<T> > ComplexMathArray<T>::FillFrom(TArray<T> const & p_real,
     238                                                   TArray<T> const & p_imag)
     239{
     240  if (p_real.NbDimensions() < 1)
     241    throw RangeCheckError("ComplexMathArray<T>::FillFrom() - Not Allocated Array ! ");
     242  bool smo;
     243  if (!p_real.CompareSizes(p_imag, smo))
     244    throw(SzMismatchError("ComplexMathArray<T>::FillFrom() SizeMismatch")) ;
     245
     246  TArray< complex<T> > ra;
     247  ra.ReSize(p_real);
     248
     249  complex<T> * pe;
     250  const T * per;
     251  const T * pei;
     252  sa_size_t j,k,ka;
     253  if (smo && (p_real.AvgStep() > 0) && (p_imag.AvgStep() > 0))   {  // regularly spaced elements
     254    sa_size_t step = p_real.AvgStep();
     255    sa_size_t stepa = p_imag.AvgStep();
     256    sa_size_t maxx = p_real.Size()*step;
     257    per = p_real.Data();
     258    pei = p_imag.Data();
     259    pe = ra.Data();
     260    for(k=0, ka=0;  k<maxx;  k+=step, ka+=stepa ) 
     261      pe[k] = complex<T>(per[k], pei[ka]) ;
     262  }
     263  else {    // Non regular data spacing ...
     264    int_4 ax,axa;
     265    sa_size_t step, stepa;
     266    sa_size_t gpas, naxa;
     267    p_real.GetOpeParams(p_imag, smo, ax, axa, step, stepa, gpas, naxa);
     268    for(j=0; j<naxa; j++)  {
     269      per = p_real.Data()+p_real.Offset(ax,j);
     270      pei = p_imag.Data()+p_imag.Offset(axa,j);
     271      pe = ra.Data()+ra.Offset(ax,j);
     272      for(k=0, ka=0;  k<gpas;  k+=step, ka+=stepa) 
     273        pe[k] = complex<T>(per[k], pei[ka]) ;
     274    }
     275  }
     276  return(ra);
     277}
     278
     279
     280//! Returns the real part of the complex input array.
     281/*!
     282  \param a : input complex array
     283  \return Return a new array filled with the real part of the input complex array elements
     284*/
     285
     286template <class T>
     287TArray<T> ComplexMathArray<T>::real(TArray< complex<T> > const & a)
     288{
     289  if (a.NbDimensions() < 1)
     290    throw RangeCheckError("ComplexMathArray< complex<T> >::real(TArray< complex<T> >& a) Not Allocated Array a !");
     291  TArray<T> ra;
     292  ra.ReSize(a);
     293
     294  const complex<T> * pe;
     295  T * po;
     296  sa_size_t j,k;
     297  if (a.AvgStep() > 0)   {  // regularly spaced elements
     298    sa_size_t step = a.AvgStep();
     299    sa_size_t maxx = a.Size()*step;
     300    pe = a.Data();
     301    po = ra.Data();
     302    for(k=0; k<maxx; k+=step )  po[k] = pe[k].real();
     303  }
     304  else {    // Non regular data spacing ...
     305    int_4 ka = a.MaxSizeKA();
     306    sa_size_t step = a.Step(ka);
     307    sa_size_t gpas = a.Size(ka)*step;
     308    sa_size_t naxa = a.Size()/a.Size(ka);
     309    for(j=0; j<naxa; j++)  {
     310      pe = a.DataBlock().Begin()+a.Offset(ka,j);
     311      po = ra.DataBlock().Begin()+ra.Offset(ka,j);
     312      for(k=0; k<gpas; k+=step)  po[k] = pe[k].real();
     313    }
     314  }
     315  return(ra);
     316}
     317
     318//! Returns the imaginary part of the complex input array.
     319/*!
     320  \param a : input complex array
     321  \return Return a new array filled with the imaginary part of the input complex array elements
     322*/
     323
     324template <class T>
     325TArray<T> ComplexMathArray<T>::imag(TArray< complex<T> > const & a)
     326{
     327  if (a.NbDimensions() < 1)
     328    throw RangeCheckError("ComplexMathArray< complex<T> >::imag(TArray< complex<T> >& a) Not Allocated Array a !");
     329  TArray<T> ra;
     330  ra.ReSize(a);
     331
     332  const complex<T> * pe;
     333  T * po;
     334  sa_size_t j,k;
     335  if (a.AvgStep() > 0)   {  // regularly spaced elements
     336    sa_size_t step = a.AvgStep();
     337    sa_size_t maxx = a.Size()*step;
     338    pe = a.Data();
     339    po = ra.Data();
     340    for(k=0; k<maxx; k+=step )  po[k] = pe[k].imag();
     341  }
     342  else {    // Non regular data spacing ...
     343    int_4 ka = a.MaxSizeKA();
     344    sa_size_t step = a.Step(ka);
     345    sa_size_t gpas = a.Size(ka)*step;
     346    sa_size_t naxa = a.Size()/a.Size(ka);
     347    for(j=0; j<naxa; j++)  {
     348      pe = a.DataBlock().Begin()+a.Offset(ka,j);
     349      po = ra.DataBlock().Begin()+ra.Offset(ka,j);
     350      for(k=0; k<gpas; k+=step)  po[k] = pe[k].imag();
     351    }
     352  }
     353  return(ra);
     354}
     355
     356//! Returns the module squared of the complex input array.
     357/*!
     358  \param a : input complex array
     359  \return Return a new array filled with the module squared of the input complex array elements
     360*/
     361
     362template <class T>
     363TArray<T> ComplexMathArray<T>::module2(TArray< complex<T> > const & a)
     364{
     365  if (a.NbDimensions() < 1)
     366    throw RangeCheckError("ComplexMathArray< complex<T> >::module2(TArray< complex<T> >& a) Not Allocated Array a !");
     367  TArray<T> ra;
     368  ra.ReSize(a);
     369
     370  const complex<T> * pe;
     371  T * po;
     372  sa_size_t j,k;
     373  if (a.AvgStep() > 0)   {  // regularly spaced elements
     374    sa_size_t step = a.AvgStep();
     375    sa_size_t maxx = a.Size()*step;
     376    pe = a.Data();
     377    po = ra.Data();
     378    for(k=0; k<maxx; k+=step ) 
     379      po[k] = (pe[k].real()*pe[k].real()+pe[k].imag()*pe[k].imag());
     380  }
     381  else {    // Non regular data spacing ...
     382    int_4 ka = a.MaxSizeKA();
     383    sa_size_t step = a.Step(ka);
     384    sa_size_t gpas = a.Size(ka)*step;
     385    sa_size_t naxa = a.Size()/a.Size(ka);
     386    for(j=0; j<naxa; j++)  {
     387      pe = a.DataBlock().Begin()+a.Offset(ka,j);
     388      po = ra.DataBlock().Begin()+ra.Offset(ka,j);
     389      for(k=0; k<gpas; k+=step) 
     390        po[k] = (pe[k].real()*pe[k].real()+pe[k].imag()*pe[k].imag());
     391    }
     392  }
     393  return(ra);
     394}
     395
     396//! Returns the module of the complex input array.
     397/*!
     398  \param a : input complex array
     399  \return Return a new array filled with the module of the input complex array elements
     400*/
     401
     402template <class T>
     403TArray<T> ComplexMathArray<T>::module(TArray< complex<T> > const & a)
     404{
     405  if (a.NbDimensions() < 1)
     406    throw RangeCheckError("ComplexMathArray< complex<T> >::module(TArray< complex<T> >& a) Not Allocated Array a !");
     407  TArray<T> ra;
     408  ra.ReSize(a);
     409
     410  const complex<T> * pe;
     411  T * po;
     412  sa_size_t j,k;
     413  if (a.AvgStep() > 0)   {  // regularly spaced elements
     414    sa_size_t step = a.AvgStep();
     415    sa_size_t maxx = a.Size()*step;
     416    pe = a.Data();
     417    po = ra.Data();
     418    for(k=0; k<maxx; k+=step ) 
     419      po[k] = sqrt((double)(pe[k].real()*pe[k].real()+pe[k].imag()*pe[k].imag()));
     420  }
     421  else {    // Non regular data spacing ...
     422    int_4 ka = a.MaxSizeKA();
     423    sa_size_t step = a.Step(ka);
     424    sa_size_t gpas = a.Size(ka)*step;
     425    sa_size_t naxa = a.Size()/a.Size(ka);
     426    for(j=0; j<naxa; j++)  {
     427      pe = a.DataBlock().Begin()+a.Offset(ka,j);
     428      po = ra.DataBlock().Begin()+ra.Offset(ka,j);
     429      for(k=0; k<gpas; k+=step) 
     430        po[k] = sqrt((double)(pe[k].real()*pe[k].real()+pe[k].imag()*pe[k].imag()));
     431    }
     432  }
     433  return(ra);
     434}
     435
     436
     437//! Returns the phase of the complex input array.
     438/*!
     439  \param a : input complex array
     440  \return Return a new array filled with the phase of the input complex array elements
     441*/
     442
     443template <class T>
     444TArray<T> ComplexMathArray<T>::phase(TArray< complex<T> > const & a)
     445{
     446  if (a.NbDimensions() < 1)
     447    throw RangeCheckError("ComplexMathArray< complex<T> >::phase(TArray< complex<T> >& a) Not Allocated Array a !");
     448  TArray<T> ra;
     449  ra.ReSize(a);
     450
     451  const complex<T> * pe;
     452  T * po;
     453  sa_size_t j,k;
     454  if (a.AvgStep() > 0)   {  // regularly spaced elements
     455    sa_size_t step = a.AvgStep();
     456    sa_size_t maxx = a.Size()*step;
     457    pe = a.Data();
     458    po = ra.Data();
     459    for(k=0; k<maxx; k+=step ) 
     460      po[k] = atan2((double)pe[k].imag(), (double)pe[k].real());
     461  }
     462  else {    // Non regular data spacing ...
     463    int_4 ka = a.MaxSizeKA();
     464    sa_size_t step = a.Step(ka);
     465    sa_size_t gpas = a.Size(ka)*step;
     466    sa_size_t naxa = a.Size()/a.Size(ka);
     467    for(j=0; j<naxa; j++)  {
     468      pe = a.DataBlock().Begin()+a.Offset(ka,j);
     469      po = ra.DataBlock().Begin()+ra.Offset(ka,j);
     470      for(k=0; k<gpas; k+=step) 
     471        po[k] = atan2((double)pe[k].imag(), (double)pe[k].real());
     472    }
     473  }
     474  return(ra);
     475}
     476
     477
    154478///////////////////////////////////////////////////////////////
    155479#ifdef __CXX_PRAGMA_TEMPLATES__
    156480#pragma define_template MathArray<r_4>
    157481#pragma define_template MathArray<r_8>
     482#pragma define_template ComplexMathArray<r_4>
     483#pragma define_template ComplexMathArray<r_8>
    158484#endif
    159485
     
    161487template class MathArray<r_4>;
    162488template class MathArray<r_8>;
     489template class ComplexMathArray<r_4>;
     490template class ComplexMathArray<r_8>;
    163491#endif
Note: See TracChangeset for help on using the changeset viewer.