1 #ifndef CNTR_ELEMENTS_H 2 #define CNTR_ELEMENTS_H 11 #define LARGESIZE (-1) // Fall back to dynamic size 12 #define BLAS_SIZE 4 // use blas for larger matrices 19 #define CPLX std::complex<T> 21 template<
typename T,
int DIM1,
int DIM2>
23 inline void element_set_zero(
int size1,
int size2,CPLX * z){
24 memset(z,0,
sizeof(CPLX)*size1*size2);
27 template<
typename T,
int DIM1,
int DIM2>
28 inline void element_set(
int size1,
int size2,CPLX *z,CPLX *z1) {
29 memcpy(z,z1,
sizeof(CPLX)*size1*size2);
32 template<
typename T,
int DIM1,
int DIM2>
33 inline void element_swap(
int size1,
int size2,CPLX *z,CPLX *z1) {
36 for(i=0;i<nm;i++){x=z[i];z[i]=z1[i];z1[i]=x;}
40 template<
typename T,
int DIM1,
int DIM2>
41 inline void element_conj(
int size1,
int size2,CPLX * z,CPLX *z1){
48 z[l*size2 + m ] = CPLX(temp.real(),-temp.imag());
53 template<
typename T,
int DIM1,
int DIM2>
54 inline void element_conj(
int size1,
int size2,CPLX * z){
55 CPLX *z1 =
new CPLX [size1*size2];
56 element_set<T,DIM2,DIM1>(size2,size1,z1,z);
57 element_conj<T,DIM1,DIM2>(size1,size2,z,z1);
61 template<
typename T,
int DIM1,
int DIM2>
62 inline void element_minusconj(
int size1,
int size2,CPLX * z,CPLX *z1){
69 z[l*size2 + m ] = CPLX(-temp.real(),temp.imag());
74 template<
typename T,
int DIM1,
int DIM2>
75 inline void element_minusconj(
int size1,
int size2,CPLX * z){
76 CPLX *z1 =
new CPLX [size1*size2];
77 element_set<T,DIM2,DIM1>(size2,size1,z1,z);
78 element_minusconj<T,DIM1,DIM2>(size1,size2,z,z1);
82 template<
typename T,
int DIM1,
int DIM2>
83 inline T element_norm2(
int size1,
int size2,CPLX * z){
86 for(i=0;i<nm;i++) r += z[i].real()*z[i].real()+z[i].imag()*z[i].imag();
91 template<
typename T,
int DIM1,
int DIM2>
92 inline void element_smul(
int size1,
int size2,CPLX *z,T z0) {
94 for(i=0;i<nm;i++) z[i] *= z0;
97 template<
typename T,
int DIM1,
int DIM2>
98 inline void element_smul(
int size1,
int size2,CPLX *z,CPLX z0) {
100 for(i=0;i<nm;i++) z[i] *= z0;
104 template<
typename T,
int DIM1,
int DIM2,
int DIM3>
105 inline void element_mult(
int size1,
int size2,
int size3,CPLX *z,CPLX *z1,CPLX *z2){
106 element_map<DIM1, DIM2>(size1, size2, z) =
107 element_map<DIM1, DIM3>(size1, size3, z1) *
108 element_map<DIM3, DIM2>(size3, size2, z2);
112 template<
typename T,
int DIM1,
int DIM2>
113 inline void element_incr(
int size1,
int size2,CPLX *z,CPLX *z1) {
115 element_map<DIM1, DIM2>(size1, size2, z).noalias() +=
116 element_map<DIM1, DIM2>(size1, size2, z1);
118 element_map<DIM1, DIM2>(size1, size2, z) +=
119 element_map<DIM1, DIM2>(size1, size2, z1);
123 template<
typename T,
int DIM1,
int DIM2>
124 inline void element_incr(
int size1,
int size2,CPLX *z,CPLX alpha,CPLX *z1) {
126 element_map<DIM1, DIM2>(size1, size2, z).noalias() +=
127 alpha * element_map<DIM1, DIM2>(size1, size2, z1);
129 element_map<DIM1, DIM2>(size1, size2, z) +=
130 alpha * element_map<DIM1, DIM2>(size1, size2, z1);
134 template<
typename T,
int DIM1,
int DIM2,
int DIM3>
135 inline void element_incr(
int size1,
int size2,
int size3,CPLX *z,CPLX *z1,CPLX *z2){
136 if (z != z1 && z != z2) {
137 element_map<DIM1, DIM2>(size1, size2, z).noalias() +=
138 element_map<DIM1, DIM3>(size1, size3, z1) *
139 element_map<DIM3, DIM2>(size3, size2, z2);
141 element_map<DIM1, DIM2>(size1, size2, z) +=
142 element_map<DIM1, DIM3>(size1, size3, z1) *
143 element_map<DIM3, DIM2>(size3, size2, z2);
147 template<
typename T,
int DIM1,
int DIM2,
int DIM3>
148 inline void element_incr(
int size1,
int size2,
int size3,CPLX *z,CPLX alpha,CPLX *z1,CPLX *z2){
149 if (z != z1 && z != z2) {
150 element_map<DIM1, DIM2>(size1, size2, z).noalias() +=
151 alpha * (element_map<DIM1, DIM3>(size1, size3, z1) *
152 element_map<DIM3, DIM2>(size3, size2, z2));
154 element_map<DIM1, DIM2>(size1, size2, z) +=
155 alpha * (element_map<DIM1, DIM3>(size1, size3, z1) *
156 element_map<DIM3, DIM2>(size3, size2, z2));
161 #define CPLX std::complex<double> 163 #define VALUE_TYPE double 164 template<>
inline void element_set_zero<VALUE_TYPE,1,1>(
int size1,
int size2,CPLX * z){
169 template<>
inline void element_set<VALUE_TYPE,1,1>(
int size1,
int size2,CPLX *z,CPLX *z1) {
173 template<>
inline void element_swap<VALUE_TYPE,1,1>(
int size1,
int size2,CPLX *z,CPLX *z1) {
178 template<>
inline void element_conj<VALUE_TYPE,1,1>(
int size1,
int size2,CPLX * z,CPLX *z1){
181 temp = std::conj( temp );
185 template<>
inline void element_conj<VALUE_TYPE,1,1>(
int size1,
int size2,CPLX * z){
188 temp = std::conj( temp );
192 template<>
inline void element_minusconj<VALUE_TYPE,1,1>(
int size1,
int size2,CPLX * z,CPLX *z1){
195 temp = -std::conj( temp );
199 template<>
inline void element_minusconj<VALUE_TYPE,1,1>(
int size1,
int size2,CPLX * z){
202 temp = -std::conj( temp );
206 template<>
inline VALUE_TYPE element_norm2<VALUE_TYPE,1,1>(
int size1,
int size2,CPLX * z){
208 return sqrt(x.real()*x.real()+x.imag()*x.imag());
211 template<>
inline void element_smul<VALUE_TYPE,1,1>(
int size1,
int size2,CPLX *z,VALUE_TYPE alpha) {
215 template<>
inline void element_smul<VALUE_TYPE,1,1>(
int size1,
int size2,CPLX *z,CPLX alpha){
219 template<>
inline void element_mult<VALUE_TYPE,1,1,1>(
int size1,
int size2,
int size3,CPLX *z,CPLX *z1,CPLX *z2){
223 template<>
inline void element_incr<VALUE_TYPE,1,1>(
int size1,
int size2,CPLX *z,CPLX *z1) {
227 template<>
inline void element_incr<VALUE_TYPE,1,1>(
int size1,
int size2,CPLX *z,CPLX alpha,CPLX *z1) {
231 template<>
inline void element_incr<VALUE_TYPE,1,1,1>(
int size1,
int size2,
int size3,CPLX *z,CPLX *z1,CPLX *z2){
235 template<>
inline void element_incr<VALUE_TYPE,1,1,1>(
int size1,
int size2,
int size3,CPLX *z,CPLX alpha,CPLX *z1,CPLX *z2){
236 *z=*z+alpha*(*z1)*(*z2);
240 #define CPLX std::complex<float> 242 #define VALUE_TYPE float 243 template<>
inline void element_set_zero<VALUE_TYPE,1,1>(
int size1,
int size2,CPLX * z){
248 template<>
inline void element_set<VALUE_TYPE,1,1>(
int size1,
int size2,CPLX *z,CPLX *z1) {
252 template<>
inline void element_swap<VALUE_TYPE,1,1>(
int size1,
int size2,CPLX *z,CPLX *z1) {
257 template<>
inline void element_conj<VALUE_TYPE,1,1>(
int size1,
int size2,CPLX * z,CPLX *z1){
260 temp = std::conj( temp );
264 template<>
inline void element_conj<VALUE_TYPE,1,1>(
int size1,
int size2,CPLX * z){
267 temp = std::conj( temp );
271 template<>
inline void element_minusconj<VALUE_TYPE,1,1>(
int size1,
int size2,CPLX * z,CPLX *z1){
274 temp = -std::conj( temp );
278 template<>
inline void element_minusconj<VALUE_TYPE,1,1>(
int size1,
int size2,CPLX * z){
281 temp = -std::conj( temp );
285 template<>
inline VALUE_TYPE element_norm2<VALUE_TYPE,1,1>(
int size1,
int size2,CPLX * z){
287 return sqrt(x.real()*x.real()+x.imag()*x.imag());
290 template<>
inline void element_smul<VALUE_TYPE,1,1>(
int size1,
int size2,CPLX *z,VALUE_TYPE alpha) {
294 template<>
inline void element_smul<VALUE_TYPE,1,1>(
int size1,
int size2,CPLX *z,CPLX alpha) {
298 template<>
inline void element_mult<VALUE_TYPE,1,1,1>(
int size1,
int size2,
int size3,CPLX *z,CPLX *z1,CPLX *z2){
302 template<>
inline void element_incr<VALUE_TYPE,1,1>(
int size1,
int size2,CPLX *z,CPLX *z1) {
306 template<>
inline void element_incr<VALUE_TYPE,1,1>(
int size1,
int size2,CPLX *z,CPLX alpha,CPLX *z1) {
310 template<>
inline void element_incr<VALUE_TYPE,1,1,1>(
int size1,
int size2,
int size3,CPLX *z,CPLX *z1,CPLX *z2){
314 template<>
inline void element_incr<VALUE_TYPE,1,1,1>(
int size1,
int size2,
int size3,CPLX *z,CPLX alpha,CPLX *z1,CPLX *z2){
315 *z=*z+alpha*(*z1)*(*z2);
325 #define CPLX std::complex<T> 328 template<
typename T,
int DIM>
330 inline void element_set_zero(
int size1,CPLX * z){
331 element_set_zero<T,DIM,DIM>(size1,size1,z);
334 template<
typename T,
int DIM>
335 inline void element_set(
int size1,CPLX *z,CPLX z0) {
336 element_set_zero<T,DIM>(size1,z);
337 for(
int i=0;i<size1;i++) z[i*size1+i]=z0;
340 template<
typename T,
int DIM>
341 inline void element_set(
int size1,CPLX *z,CPLX *z1) {
342 element_set<T,DIM,DIM>(size1,size1,z,z1);
345 template<
typename T,
int DIM>
346 inline void element_swap(
int size1,CPLX *z,CPLX *z1) {
347 element_swap<T,DIM,DIM>(size1,size1,z,z1);
350 template<
typename T,
int DIM>
351 inline CPLX element_trace(
int size1,CPLX * z){
353 for(
int i=0;i<size1;i++) result += z[i*size1+i];
358 template<
typename T,
int DIM>
359 inline void element_conj(
int size1,CPLX * z,CPLX *z1){
360 element_conj<T,DIM,DIM>(size1,size1,z,z1);
363 template<
typename T,
int DIM>
364 inline void element_conj(
int size1,CPLX * z){
365 element_conj<T,DIM,DIM>(size1,size1,z);
368 template<
typename T,
int DIM>
369 inline void element_minusconj(
int size1,CPLX * z,CPLX *z1){
370 element_minusconj<T,DIM,DIM>(size1,size1,z,z1);
373 template<
typename T,
int DIM>
374 inline void element_minusconj(
int size1,CPLX * z){
375 element_minusconj<T,DIM,DIM>(size1,size1,z);
378 template<
typename T,
int DIM>
379 inline T element_norm2(
int size1,CPLX * z){
380 return element_norm2<T,DIM,DIM>(size1,size1,z);
384 template<
typename T,
int DIM>
385 inline void element_smul(
int size1,CPLX *z,T z0) {
386 element_smul<T,DIM,DIM>(size1,size1,z,z0);
389 template<
typename T,
int DIM>
390 inline void element_smul(
int size1,CPLX *z,CPLX z0) {
391 element_smul<T,DIM,DIM>(size1,size1,z,z0);
395 template<
typename T,
int DIM>
396 inline void element_mult(
int size1,CPLX *z,CPLX *z1,CPLX *z2){
397 element_mult<T,DIM,DIM,DIM>(size1,size1,size1,z,z1,z2);
401 template<
typename T,
int DIM>
402 inline void element_incr(
int size1,CPLX *z,CPLX z0) {
403 for(
int i=0;i<size1;i++) z[i*size1+i]+=z0;
406 template<
typename T,
int DIM>
407 inline void element_incr(
int size1,CPLX *z,CPLX *z1) {
408 element_incr<T,DIM,DIM>(size1,size1,z,z1);
411 template<
typename T,
int DIM>
412 inline void element_incr(
int size1,CPLX *z,CPLX alpha,CPLX *z1) {
413 element_incr<T,DIM,DIM>(size1,size1,z,alpha,z1);
416 template<
typename T,
int DIM>
417 inline void element_incr(
int size1,CPLX *z,CPLX *z1,CPLX *z2){
418 element_incr<T,DIM,DIM,DIM>(size1,size1,size1,z,z1,z2);
421 template<
typename T,
int DIM>
422 inline void element_incr(
int size1,CPLX *z,CPLX alpha,CPLX *z1,CPLX *z2){
423 element_incr<T,DIM,DIM,DIM>(size1,size1,size1,z,alpha,z1,z2);
428 template<
typename T,
int DIM>
429 inline void element_inverse(
int size1,CPLX *z,CPLX *z1) {
430 int i,nm=size1*size1;
431 std::complex<double> *zd =
new std::complex<double> [size1*size1];
432 std::complex<double> *z1d =
new std::complex<double> [size1*size1];
433 for(i=0;i<nm;i++) z1d[i]= (std::complex<double>) z1[i];
435 for(i=0;i<nm;i++) z[i]= (CPLX)zd[i];
442 template<
typename T,
int DIM>
443 inline void element_linsolve_right(
int size1,
int n,CPLX *X,CPLX *M,CPLX *Q){
445 int size=size1,llen=size*n,l,s2=size*size;
447 std::complex<double> *mtemp =
new std::complex<double> [llen*llen];
448 std::complex<double> *qtemp =
new std::complex<double> [n*s2];
449 std::complex<double> *xtemp =
new std::complex<double> [n*s2];
455 mtemp[ (l*size + p)*llen + m*size+q] = (std::complex<double>) M[ (l*n+m)*s2+p*size+q];
463 qtemp[ q*n*size + l*size+p] = (std::complex<double>) Q[ l*s2+p*size+q];
471 X[ l*s2+p*size+q]= (CPLX) xtemp[ q*n*size + l*size+p];
480 template<
typename T,
int DIM>
481 inline void element_linsolve_right(
int size1,CPLX *X,CPLX *M,CPLX *Q){
482 element_linsolve_right<T,DIM>(size1,1,X,M,Q);
485 template<
typename T,
int DIM>
486 inline void element_linsolve_left(
int size1,
int n,CPLX *X,CPLX *M,CPLX *Q){
487 int l,m,element_size=size1*size1;
489 for(l=0;l<n;l++) for(m=0;m<n;m++) element_conj<T,DIM>(size1, M + (l*n+m)*element_size);
490 for(l=0;l<n;l++) element_conj<T,DIM>(size1, Q + l*element_size);
491 element_linsolve_right<T,DIM>(size1,n,X,M,Q);
492 for(l=0;l<n;l++) element_conj<T,DIM>(size1, X + l*element_size);
495 template<
typename T,
int DIM>
496 inline void element_linsolve_left(
int size1,CPLX *X,CPLX *M,CPLX *Q){
497 element_linsolve_left<T,DIM>(size1,1,X,M,Q);
503 #define CPLX std::complex<double> 505 #define VALUE_TYPE double 506 template<>
inline void element_set<VALUE_TYPE,1>(
int size1,CPLX *z,CPLX z0) {
511 template<>
inline CPLX element_trace<VALUE_TYPE,1>(
int size1,CPLX * z){
515 template<>
inline void element_incr<VALUE_TYPE,1>(
int size1,CPLX *z,CPLX z0) {
519 template<>
inline void element_linsolve_right<VALUE_TYPE,1>(
int size1,CPLX *X,CPLX *M,CPLX *Q) {
523 template<>
inline void element_linsolve_left<VALUE_TYPE,1>(
int size1,CPLX *X,CPLX *M,CPLX *Q) {
527 template<>
inline void element_inverse<VALUE_TYPE,1>(
int size1,CPLX *z,CPLX *z1) {
533 #define CPLX std::complex<float> 535 #define VALUE_TYPE float 536 template<>
inline void element_set<VALUE_TYPE,1>(
int size1,CPLX *z,CPLX z0) {
541 template<>
inline CPLX element_trace<VALUE_TYPE,1>(
int size1,CPLX * z){
545 template<>
inline void element_incr<VALUE_TYPE,1>(
int size1,CPLX *z,CPLX z0) {
549 template<>
inline void element_linsolve_right<VALUE_TYPE,1>(
int size1,CPLX *X,CPLX *M,CPLX *Q) {
553 template<>
inline void element_linsolve_left<VALUE_TYPE,1>(
int size1,CPLX *X,CPLX *M,CPLX *Q) {
557 template<>
inline void element_inverse<VALUE_TYPE,1>(
int size1,CPLX *z,CPLX *z1) {
558 *z= CPLX(1.0,0.0)/(*z1);
567 #endif // CNTR_ELEMENTS_H void cplx_matrix_inverse(void *a, void *x, int n)
Evaluate the inverse matrix of a complex matrix .
void cplx_sq_solve_many(void *a, void *b, void *x, int dim, int d)
Solve a linear equation .