Changeset 1517 in Sophya for trunk/SophyaLib/TArray/matharr.cc
- Timestamp:
- Jun 12, 2001, 6:21:13 PM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/SophyaLib/TArray/matharr.cc
r1226 r1517 152 152 } 153 153 154 155 //------------------------------------------------------------------------------- 156 // Definition utilitaire d'application de fonction 157 inline complex<r_8> ApplyComplexDoubleFunction(complex<r_8> z, 158 Arr_ComplexDoubleFunctionOfX f) 159 { 160 return(f(z)); 161 } 162 163 inline 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 */ 187 template <class T> 188 TArray< 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 */ 221 template <class T> 222 TArray< 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 */ 236 template <class T> 237 TArray< 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 286 template <class T> 287 TArray<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 324 template <class T> 325 TArray<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 362 template <class T> 363 TArray<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 402 template <class T> 403 TArray<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 443 template <class T> 444 TArray<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 154 478 /////////////////////////////////////////////////////////////// 155 479 #ifdef __CXX_PRAGMA_TEMPLATES__ 156 480 #pragma define_template MathArray<r_4> 157 481 #pragma define_template MathArray<r_8> 482 #pragma define_template ComplexMathArray<r_4> 483 #pragma define_template ComplexMathArray<r_8> 158 484 #endif 159 485 … … 161 487 template class MathArray<r_4>; 162 488 template class MathArray<r_8>; 489 template class ComplexMathArray<r_4>; 490 template class ComplexMathArray<r_8>; 163 491 #endif
Note:
See TracChangeset
for help on using the changeset viewer.