00001 #ifndef vm_vmath_h_INCLUDED
00002 #define vm_vmath_h_INCLUDED
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <cstring>
00040 #include <cmath>
00041 #include <iostream>
00042 #include <cstdio>
00043
00044
00045
00046
00047
00048
00077 template <class T_fp, int N_len>
00078 class vm_VMath
00079 {
00080 private:
00081
00082 enum ENelts_ { ENelts = N_len };
00083
00084 public:
00085
00091 typedef T_fp value_type;
00092
00097
00107 inline static void copy( T_fp v[], T_fp const cv[] );
00120 inline static void set( T_fp v[], T_fp r );
00133 inline static void add_eq( T_fp v[], T_fp const cv[] );
00134
00141 inline static void sub_eq( T_fp v[], T_fp const cv[] );
00142
00149 inline static void mul_eq( T_fp v[], T_fp const cv[] );
00150
00157 inline static void div_eq( T_fp v[], T_fp const cv[] );
00158
00165 inline static void add_eq( T_fp v[], T_fp r );
00166
00173 inline static void sub_eq( T_fp v[], T_fp r );
00174
00181 inline static void mul_eq( T_fp v[], T_fp r );
00182
00189 inline static void div_eq( T_fp v[], T_fp r );
00190
00196 inline static void negate( T_fp v[] );
00210 inline static void add( T_fp v[], T_fp const cv1[], T_fp const cv2[] );
00211
00219 inline static void sub( T_fp v[], T_fp const cv1[], T_fp const cv2[] );
00220
00228 inline static void mul( T_fp v[], T_fp const cv1[], T_fp const cv2[] );
00229
00237 inline static void div( T_fp v[], T_fp const cv1[], T_fp const cv2[] );
00238
00246 inline static void add( T_fp v[], T_fp const cv[], T_fp r );
00247
00255 inline static void sub( T_fp v[], T_fp const cv[], T_fp r );
00256
00264 inline static void mul( T_fp v[], T_fp const cv[], T_fp r );
00265
00273 inline static void div( T_fp v[], T_fp const cv[], T_fp r );
00274
00282 inline static void add( T_fp v[], T_fp r, T_fp const cv[] );
00283
00291 inline static void sub( T_fp v[], T_fp r, T_fp const cv[] );
00292
00300 inline static void mul( T_fp v[], T_fp r, T_fp const cv[] );
00301
00309 inline static void div( T_fp v[], T_fp r, T_fp const cv[] );
00312
00329 inline static void lincomb( T_fp res[],
00330 T_fp c1, T_fp const v1[],
00331 T_fp c2, T_fp const v2[] );
00334
00348 inline static std::ostream&
00349 print_on( std::ostream& os, T_fp const v[], int by,
00350 char const prefix[] = "", char const postfix[] = "" );
00351
00361 inline static void
00362 cprint_on( FILE* of, T_fp const v[], int by,
00363 char const prefix[] = "", char const postfix[] = "" );
00365 };
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383 template <class T_fp, int N_len>
00384 inline void vm_VMath<T_fp,N_len>::
00385 copy( T_fp v[], T_fp const cv[] )
00386 { memcpy( v, cv, N_len * sizeof(T_fp) ); }
00387
00388
00389
00390
00391 template <class T_fp, int N_len>
00392 inline void vm_VMath<T_fp,N_len>::
00393 set( T_fp v[], T_fp r )
00394 { int n = N_len+1; while ( --n ) { *v++ = r; } }
00395
00396
00397
00398
00399 #define _tpl_Op_EQ_(_OPNAM_,_OPEQ_) \
00400 template <class T_fp, int N_len> \
00401 inline void vm_VMath<T_fp,N_len>::_OPNAM_( T_fp v[], T_fp const cv[] ) \
00402 { int n = N_len+1; while ( --n ) { *v++ _OPEQ_ *cv++; } } \
00403 template <class T_fp, int N_len> \
00404 inline void vm_VMath<T_fp,N_len>::_OPNAM_( T_fp v[], T_fp r ) \
00405 { int n = N_len+1; while ( --n ) { *v++ _OPEQ_ r; } }
00406 _tpl_Op_EQ_(add_eq,+=)
00407 _tpl_Op_EQ_(sub_eq,-=)
00408 _tpl_Op_EQ_(mul_eq,*=)
00409 _tpl_Op_EQ_(div_eq,/=)
00410 #undef _tpl_Op_EQ_
00411
00412 template <class T_fp, int N_len>
00413 inline void vm_VMath<T_fp,N_len>::
00414 negate( T_fp v[] )
00415 { int n = N_len+1; while ( --n ) { *v = - *v; ++v; } }
00416
00417
00418
00419 #define _tpl_BinOp_(_OPNAM_,_OP_) \
00420 template <class T_fp, int N_len> \
00421 inline void vm_VMath<T_fp,N_len>::_OPNAM_( T_fp v[], \
00422 T_fp const cv1[], T_fp const cv2[] ) \
00423 { int n = N_len+1; while ( --n ) { *v++ = *cv1++ _OP_ *cv2++; } } \
00424 template <class T_fp, int N_len> \
00425 inline void vm_VMath<T_fp,N_len>::_OPNAM_( T_fp v[], T_fp const cv[], T_fp r ) \
00426 { int n = N_len+1; while ( --n ) { *v++ = *cv++ _OP_ r; } } \
00427 template <class T_fp, int N_len> \
00428 inline void vm_VMath<T_fp,N_len>::_OPNAM_( T_fp v[], T_fp r, T_fp const cv[] ) \
00429 { int n = N_len+1; while ( --n ) { *v++ = r _OP_ *cv++; } }
00430 _tpl_BinOp_(add,+)
00431 _tpl_BinOp_(sub,-)
00432 _tpl_BinOp_(mul,*)
00433 _tpl_BinOp_(div,/)
00434 #undef _tpl_BinOp_
00435
00436
00437
00438
00439 template <class T_fp, int N_len>
00440 inline void vm_VMath<T_fp,N_len>::
00441 lincomb( T_fp res[],
00442 T_fp c1, T_fp const v1[],
00443 T_fp c2, T_fp const v2[] )
00444 { int n = N_len+1; while ( --n ) { *res++ = c1 * *v1++ + c2 * *v2++; } }
00445
00446
00447
00448
00449 template <class T_fp, int N_len>
00450 inline std::ostream& vm_VMath<T_fp,N_len>::
00451 print_on( std::ostream& os, T_fp const v[], int by,
00452 char const prefix[], char const postfix[] )
00453 {
00454 if ( std::strlen(prefix) ) { os << prefix; }
00455 int i = N_len / by;
00456 while ( i-- )
00457 {
00458 int j = by;
00459 while ( --j )
00460 {
00461 os << *v++ << " ";
00462 }
00463 os << *v++ << "\n";
00464 }
00465 if ( std::strlen(postfix) ) { os << postfix; }
00466 return os;
00467 }
00468
00469 template <class T_fp, int N_len>
00470 inline void vm_VMath<T_fp,N_len>::
00471 cprint_on( FILE* of, T_fp const v[], int by,
00472 char const prefix[], char const postfix[] )
00473 {
00474 if ( std::strlen(prefix) ) { std::fprintf(of, "%s", prefix); }
00475 int i = N_len / by;
00476 while ( i-- )
00477 {
00478 int j = by;
00479 while ( --j )
00480 {
00481 fprintf(of, "%.18e ", *v++);
00482 }
00483 fprintf(of, "%.18e\n", *v++);
00484 }
00485 if ( std::strlen(postfix) ) { std::fprintf(of, "%s", postfix); }
00486 }
00487
00488 #endif