1 /*
2 $Id$
3 */
4
5 #include <math.h>
6 #include <stdio.h>
7 #ifndef WIN32
8 #include <strings.h>
9 #endif
10 #include <stdlib.h>
11 #include "ga.h"
12
13 extern int fortchar_to_string();
14
15 /* Maximum number of open shells and corresponding maximum number
16 of spin functions for any possible multiplicity */
17 #define nsmax 14
18 #define nfmax 1001
19
20 /* #define nsmax 15 */
21 /* #define nfmax 2002 */
22
Error(char * string,int integer)23 static void Error(char *string, int integer)
24 {
25 /*
26 (void) fflush(stdout);
27 (void) fprintf(stderr,"\n\nError was called.\n");
28 (void) fprintf(stderr,string);
29 (void) fprintf(stderr," %d (%#x).\n",integer,integer);
30 exit(1); */
31 GA_Error(string, (long) integer);
32 }
33
34
Dscal(int n,double s,double * u,int iu)35 static void Dscal(int n, double s, double *u, int iu)
36 /*
37 Scale double precision vector u by s
38 */
39 {
40 while (n--) {
41 *u = *u * s;
42 u += iu;
43 }
44 }
45
Dfill(int n,double s,double * u,int iu)46 static void Dfill(int n, double s, double *u, int iu)
47 /*
48 Fill double precision vector u with s
49 */
50 {
51 while (n--) {
52 *u = s;
53 u += iu;
54 }
55 }
56
Screen(int n,double s,double * u,int iu)57 static void Screen(int n, double s, double *u, int iu)
58 /*
59 zero elements of double precision vector u if they are less
60 in absolute magnitude than the threshold s
61 */
62 {
63 s = fabs(s);
64 while (n--) {
65 if (fabs(*u) < s)
66 *u = 0.0;
67 u += iu;
68 }
69 }
70
Sparsity(int n,double * u,int iu)71 static double Sparsity(int n, double *u, int iu)
72 /*
73 Return (no. zero elements)/(total no. elements)
74 */
75 {
76 int zero=0, nn;
77
78 nn = n;
79 while (nn--) {
80 if (*u == 0.0)
81 ++zero;
82 u += iu;
83 }
84
85 return (double) zero / (double) n;
86 }
87
Identity(double * u,int n)88 static void Identity(double *u, int n)
89 /*
90 Form the n*n double precision identity matrix
91 */
92 {
93 Dfill(n*n, 0.0, u, 1);
94
95 Dfill(n, 1.0, u, n+1);
96 }
97
PrintMatrix(const double * u,int mcol,int mrow,int ncol,int nrow)98 static void PrintMatrix(const double *u, int mcol, int mrow,
99 int ncol, int nrow)
100 /*
101 Print a double precision matrix.
102 mcol = skip between elements down a column
103 mrow = skip between elements across a column
104 ncol = no. of columns
105 nrow = no. of rows
106 */
107 {
108 double *uu, *uuu;
109 int todo, nnrow, nncol, ttodo, i;
110
111 (void) printf("\n\n");
112 nncol = ncol;
113 while(nncol) {
114
115 if (nncol < 6)
116 todo = nncol;
117 else
118 todo = 6;
119
120 (void) printf(" ");
121 for (i=1; i<=todo; i++)
122 (void) printf("%12d",ncol-nncol+i);
123 (void) printf("\n\n");
124
125
126 uu = (double *)u;
127 nnrow = nrow;
128 while(nnrow--) {
129
130 (void) printf("%3d ",nrow-nnrow);
131 uuu = uu;
132 ttodo = todo;
133 while(ttodo--) {
134 (void) printf("%12.6f",*uuu);
135 uuu += mrow;
136 }
137 (void) printf("\n");
138 uu += mcol;
139 }
140
141 (void) printf("\n\n");
142 u += todo*mrow;
143 nncol -= todo;
144 }
145 }
146
MakeBranchingDiagram(int bd[nsmax+3][nsmax+3],int ns,int multi,int order,int info)147 static void MakeBranchingDiagram(int bd[nsmax+3][nsmax+3],
148 int ns, int multi, int order, int info)
149 /*
150 Form the branching diagram weights
151 bd[m][n] = weight of node with multiplicty m and n electrons
152 ns = maximum no. of open shells or unpaired electrons
153 multi = state multiplicity
154 order = 0 -> normal branching diagram
155 1 -> reversed diagram (for use with dictionary order functions)
156 */
157 {
158 int i, j, wrote;
159
160 for (i=0; i<ns+3; i++)
161 for (j=0; j<ns+3; j++)
162 bd[i][j] = 0;
163
164 if (order == 0) {
165 bd[1][0] = 1;
166
167 for (i=1; i<=ns; i++) {
168 for (j=i%2+1; j<=ns+1; j+=2) {
169 if (abs(multi-j) > (ns-i))
170 continue;
171 bd[j][i] = bd[j-1][i-1] + bd[j+1][i-1];
172 }
173 }
174 }
175 else {
176 bd[multi][ns] = 1;
177
178 for (i=ns-1; i>=0; i--) {
179 for (j=i%2+1; j<=ns+1; j+=2) {
180 if (j > i+1)
181 continue;
182 bd[j][i] = bd[j-1][i+1] + bd[j+1][i+1];
183 }
184 }
185 }
186
187 #ifndef DEBUG
188 if (order == 1)
189 return;
190 #endif
191
192 if (info) {
193 if (order == 0)
194 (void) printf("\nBranching diagram weights.\n\n");
195 else
196 (void) printf("\nReversed branching diagram weights.\n\n");
197
198
199 for (j=ns+1; j>=1; j--) {
200 wrote = 0;
201 for (i=0; i<=ns; i++)
202 if (bd[j][i])
203 wrote=1;
204 if (wrote) {
205 for (i=0; i<=ns; i++) {
206 if (bd[j][i])
207 (void) printf("%4d",bd[j][i]);
208 else
209 (void) printf(" ");
210 }
211 (void) printf("\n");
212 }
213 }
214 (void) printf("\n");
215 }
216 }
217
MakeSpinFunctions(int bd[nsmax+3][nsmax+3],int ns,int multi,int f[nsmax+1][nfmax+1],int nf,int order,int info)218 static void MakeSpinFunctions(int bd[nsmax+3][nsmax+3],
219 int ns, int multi, int f[nsmax+1][nfmax+1],
220 int nf, int order, int info)
221 /*
222 Form the ordered spin functions as an array of 1s and 2s.
223 bd = branching diagram (reversed if want dictionary ordered functions)
224 ns = required no. of unpaired electrons
225 multi = state multiplicity
226 f[j][i] = occupation (1 or 2) of orbital j in function i
227 nf = no. of functions
228 order = 0 -> reversed dictionary, 1 -> dictionary
229
230 if (reversed dictionary)
231 weight of arc (m,k)->(m+1,k+1) = weight of node (m+2,k)
232 and the graph has to be traversed right to left
233 else
234 weight of arc (m,k)->(m+1,k+1) = weight of node (m-1,k+1)
235 and the graph has to be traversed left to right
236 */
237 {
238 int i, test, j, m;
239
240 if (order ==0) {
241 for (i=1; i<=nf; i++) {
242 test = i-1;
243 m = multi;
244 for (j=ns; j>0; j--){
245
246 if (bd[m-1][j-1] && (test-bd[m+1][j-1]) >= 0) {
247 test -= bd[m+1][j-1];
248 f[j][i] = 1;
249 m--;
250 }
251 else if (bd[m+1][j-1]){
252 f[j][i] = 2;
253 m++;
254 }
255 else
256 Error("mis-match walking spin-graph",j);
257 }
258 if (test != 0 || m != 1) {
259 (void) printf("test=%d, m=%d\n",test,m);
260 Error("invalid tail on spin graph",i);
261 }
262 }
263 }
264 else {
265 for (i=1; i<=nf; i++) {
266 test = i-1;
267 m = 1;
268 for (j=0; j<ns; j++){
269
270 if (bd[m+1][j+1] && (test-bd[m-1][j+1]) >= 0) {
271 test -= bd[m-1][j+1];
272 f[j+1][i] = 1;
273 m++;
274 }
275 else if (bd[m-1][j+1]){
276 f[j+1][i] = 2;
277 m--;
278 }
279 else
280 Error("mis-match walking reversed spin-graph",j);
281 }
282 if (test != 0 || m != multi) {
283 (void) printf("test=%d, m=%d\n",test,m);
284 Error("invalid tail on reversed spin graph",i);
285 }
286 }
287 }
288
289 if (info) {
290 (void) printf("\nSpin functions\n\n");
291
292 test = 0;
293 for (i=1; i<=nf; i++) {
294 test += printf("%4d [",i);
295 for (j=1; j<=ns; j++)
296 test += printf("%1d",f[j][i]);
297 if (test > (71-ns)) {
298 test = 0;
299 (void) printf("]\n");
300 }
301 else
302 test += printf("] ");
303 }
304 if (test)
305 (void) printf("\n");
306 }
307 }
308
309
MakeAxialDistances(int ns,int f[nsmax+1][nfmax+1],int nf,int d[nsmax][nfmax+1],double p[nsmax][nfmax+1],double g[nsmax][nfmax+1])310 static void MakeAxialDistances(int ns, int f[nsmax+1][nfmax+1],
311 int nf, int d[nsmax][nfmax+1],
312 double p[nsmax][nfmax+1], double g[nsmax][nfmax+1])
313 /*
314 Compute the axial distances for transpostions (j, j+1) for
315 the Standard Young Tableaux represented by the branching diagram
316 paths in f. (See Paunz, "Spin Eigenfunctions", p106.)
317 ns = no. of electrons
318 f[j][i] = 1 or 2, step j in the ith function
319 d[j][i] = axial distance for (j,j+1) in tableau i
320 p[j][i] = -1.0/d[j][i]
321 g[j][i] = sqrt(1-p[j][i]^2)
322 */
323 {
324 int i, j, k, jb;
325
326 #ifdef DEBUG
327 int test;
328 #endif
329
330 for (i=1; i<=nf; i++) {
331 for (j=1; j<ns; j++) {
332
333 if (f[j][i] == f[j+1][i])
334 d[j][i] = -1;
335 else {
336 jb=0;
337 for (k=1; k<j; k++) {
338 jb += (f[k][i] == f[j][i]);
339 jb -= (f[k][i] == f[j+1][i]);
340 }
341 if (f[j][i] == 1)
342 d[j][i] = jb + 1;
343 else
344 d[j][i] = jb - 1;
345 }
346 }
347 }
348
349 for (j=1; j<ns; j++) {
350 for (i=1; i<=nf; i++) {
351 p[j][i] = -1.0 / d[j][i];
352 g[j][i] = sqrt(1.0 - p[j][i]*p[j][i]);
353 }
354 }
355
356 #ifdef DEBUG
357 (void) printf("\nAxial distances for (j,j+1)\n\n");
358
359 test = 0;
360 for (i=1; i<=nf; i++) {
361 test += printf("%4d [",i);
362 for (j=1; j<ns; j++)
363 test += printf("%4d",d[j][i]);
364 if (test > (71-4*ns)) {
365 test = 0;
366 (void) printf("]\n");
367 }
368 else
369 test += printf("] ");
370 }
371 if (test)
372 (void) printf("\n");
373 #endif
374 }
375
376
MakePerm(int bd[nsmax+3][nsmax+3],int ns,int f[nsmax+1][nfmax+1],int nf,int perm[nsmax][nfmax+1],int order)377 static void MakePerm(int bd[nsmax+3][nsmax+3], int ns, int f[nsmax+1][nfmax+1],
378 int nf, int perm[nsmax][nfmax+1], int order)
379 /*
380 Compute the effect of the transpositions (j j+1) on the spin functions
381 bd = branching diagram (reversed if dictionary order)
382 ns = no. of electrons
383 f[j][i] = 1 or 2, step j in ith function
384 nf = no. of functions
385 perm[j][i] = result of permutation (j j+1) on the ith tableau.
386 is the no. of another standard tableau or zero
387 order = 0 -> reversed dictionary order, 1 -> dictionary order
388 See comments in MakeBranchingDiagram
389 */
390 {
391 int i, j, k, m, test, step;
392
393 for (i=1; i<=nf; i++) {
394
395 for (j=1; j<ns; j++) {
396
397 test = 1;
398 m = 1;
399 for (k=1; k<=ns; k++) {
400
401 if ( k == j )
402 step = f[j+1][i];
403 else if ( k == j+1 )
404 step = f[j][i];
405 else
406 step = f[k][i];
407
408 if (step == 1) {
409 if (order == 0)
410 test = test + bd[m+2][k-1];
411 else
412 test = test + bd[m-1][k];
413 m++;
414 }
415 else
416 m--;
417
418 if ( m<=0 || bd[m][k] == 0) {
419 test = 0;
420 break;
421 }
422 }
423 perm[j][i] = test;
424 }
425 }
426
427 #ifdef DEBUG
428 (void) printf("\nResults of permutations for (j,j+1)\n\n");
429
430 test = 0;
431 for (i=1; i<=nf; i++) {
432 test += printf("%4d [",i);
433 for (j=1; j<ns; j++)
434 test += printf("%4d",perm[j][i]);
435 if (test > (71-4*ns)) {
436 test = 0;
437 (void) printf("]\n");
438 }
439 else
440 test += printf("] ");
441 }
442 if (test)
443 (void) printf("\n");
444 #endif
445 }
446
447
RightMultiply(int i,double * u,double * uu,int nf,double pp[nsmax][nfmax+1],double g[nsmax][nfmax+1],int perm[nsmax][nfmax+1])448 static void RightMultiply(int i, double *u, double *uu, int nf,
449 double pp[nsmax][nfmax+1], double g[nsmax][nfmax+1],
450 int perm[nsmax][nfmax+1])
451 /*
452 uu = (-1) * u * U(i i+1), where u and uu are pointers to
453 other represenation matrices.
454 i = index of required permutation (i i+1)
455 u = pointer to input matrix
456 uu = pointer to result matrix
457 nf = no. of functions = dimension of representation
458 pp[i][j] = negative reciprocal axial distance of (i i+1) in tableau j
459 gg[i][j] = sqrt(1-pp[i][j]^2)
460 perm[i][j] = action of (i i+1) on tableau j
461 */
462 {
463 int p, q, m;
464
465 for (p=0; p<nf; p++) {
466 for (q=0; q<nf; q++) {
467
468 *(uu+p+q*nf) = -(*(u+p+q*nf) * pp[i][q+1]);
469 m = perm[i][q+1];
470 if (m)
471 *(uu+p+q*nf) -= *(u+p+(m-1)*nf)*g[i][q+1];
472 }
473 }
474 }
LeftMultiply(int i,double * u,double * uu,int nf,double pp[nsmax][nfmax+1],double g[nsmax][nfmax+1],int perm[nsmax][nfmax+1])475 static void LeftMultiply(int i, double *u, double *uu, int nf,
476 double pp[nsmax][nfmax+1], double g[nsmax][nfmax+1],
477 int perm[nsmax][nfmax+1])
478 /*
479 uu = (-1) * U(i i+1) * u, where u and uu are pointers to
480 other represenation matrices.
481 i = index of required permutation (i i+1)
482 u = pointer to input matrix
483 uu = pointer to result matrix
484 nf = no. of functions = dimension of representation
485 pp[i][j] = negative reciprocal axial distance of (i i+1) in tableau j
486 gg[i][j] = sqrt(1-pp[i][j]^2)
487 perm[i][j] = action of (i i+1) on tableau j
488 */
489 {
490 int p, q, m;
491
492 for (p=0; p<nf; p++) {
493 for (q=0; q<nf; q++) {
494
495 *(uu+p+q*nf) = -(*(u+p+q*nf) * pp[i][p+1]);
496 m = perm[i][p+1];
497 if (m)
498 *(uu+p+q*nf) -= *(u+m-1+q*nf)*g[i][p+1];
499 }
500 }
501 }
502
503
504 #ifdef OLDCODE
ReadArguments(argc,argv,ns,multi,print)505 static void ReadArguments(argc, argv, ns, multi, print)
506 int argc, *ns, *multi, *print;
507 char **argv;
508 /*
509 The syntax is
510
511 command [-p] multiplicity [ nsmax ]
512
513 If no arguments are specified the command syntax is returned.
514 If only the multiplicity is specified then a sensible default
515 for nsmax is used (this may be too small for large calculations).
516 The -p option, which must precede the other arguments will cause
517 more printout to be generated.
518 */
519 {
520 *print = 0;
521
522 if (argc==1 || (argc==2 && !strcmp(*(argv+1),"-p"))) {
523 (void) fprintf(stderr,"Usage: %s [-p] multiplicity [ nsmax ]\n",*argv);
524 exit(1);
525 }
526
527 argv++;
528 argc--;
529
530 if (!strcmp(*argv,"-p")) {
531 *print = 1;
532 argv++;
533 argc--;
534 }
535
536 *multi = atoi(*(argv++));
537 if (argc == 1)
538 *ns = 8 + (*multi-1)%2;
539 else
540 *ns = atoi(*argv);
541 }
542
543 /*int main(argc, argv)
544 int argc;
545 char **argv;
546 */
547 #endif
548
549 #if (defined(CRAY) ||defined(WIN32))&& !defined(__crayx1) && !defined(__MINGW32__)
SELCI_COUPLE(Integer * pmulti,Integer * pns,Integer * pprint,char * pfilename,int flen)550 void FATR SELCI_COUPLE(Integer *pmulti, Integer *pns, Integer *pprint, char *pfilename, int flen)
551 #else
552 void FATR selci_couple_(Integer *pmulti, Integer *pns, Integer *pprint, char *pfilename, int flen)
553 #endif
554 /*
555 Generate the one particle coupling coefficients between two orbital
556 occupancies including all spin couplings. The spin functions are
557 the standard genealogical functions in the order specified by the
558 variable order. If dictionary order is used (order=1) then the matrices
559 for smaller no.s of open shells are just submatrices of the largest
560 dimension matrix. Thus order is hardwired to 1 just below, but
561 order = 0 (reverse dictionary) does work.
562
563 n(i)=1
564 W1(u,v,i) = <Iu|Eia|Jv> = (-1)^p U(P)uv , P=(i...ns)
565
566 n(i)=2
567 W2(u,v,i) = <Iu|Eia|Jv> = sqrt(2) (-1)^p U(P)uv , P=(1...ns)(1...i)
568
569 i is the position of the orbital i in the open shell orbitals.
570 ns is the no. of open shells, p is the parity of P, and a is an
571 orbital higher in index (so coupled last) than any in |I>, which
572 represents an orbital occupation of the form
573
574 |I> = d1(1)d1(2)d2(3)d2(4) ... dn(2n-1)dn(2n)dn+1(2n+1)...dn+ns(2n+ns)
575
576 That is the ordered doubly occupied orbitals are put first and the
577 the singly occupied are ordered on the end.
578
579 The matrices U(P) are the representation matrices for the permutation
580 P in the genealogical basis.
581
582 The input is just the two command arguments multiplicity and ns.
583
584 The output file 'wmatrix' is a binary stream containing the following
585
586 multi
587 nsmax
588 (nf(i),i=multi-1,nsmax,2)
589 (((w1(u,v,i),u=1,nf(nsmax)),v=1,nf(nsmax)),i=nsmax,1)
590 (((w2(u,v,i),u=1,nf(nsmax-2)),v=1,nf(nsmax)),i=1,nsmax-1)
591
592 multi = multiplicity
593 nf(ns) = no. of spin functions for ns open shells
594 w1,w2 are the desired matrices. note the odd i order for w1.
595
596 Note that in dictionary order w*(*,*,i) for ns=nsmax-m is just
597 w*(*,*,i+m).
598
599 */
600 {
601 int order = 1;
602 static int bd[nsmax+3][nsmax+3], rbd[nsmax+3][nsmax+3];
603 static int d[nsmax][nfmax+1], f[nsmax+1][nfmax+1];
604 int ns, multi, nf, nf2, print, info;
605 static int perm[nsmax][nfmax+1], i, j, k, kk;
606 static double p[nsmax][nfmax+1], g[nsmax][nfmax+1], *u, *uu, *temp, *ttemp;
607 FILE *wmatrix;
608 char filename[255];
609
610 /*ReadArguments(argc, argv, &ns, &multi, &print);*/
611
612 ns = *pns;
613 multi = *pmulti;
614 if (!fortchar_to_string(pfilename, flen, filename, sizeof filename))
615 Error("couple: failed to convert fortran filename", 0);
616 info = *pprint; /* Information output */
617 print = 0; /* Debug output */
618
619 if (info) {
620 (void) printf("\n");
621 (void) printf(" Symmetric Group Coupling Coefficient Generation Program (8/9/89)\n");
622 (void) printf(" ----------------------------------------------------------------\n\n");
623
624 (void) printf("Maximum dimension of open shell %2d\n",ns);
625 }
626
627 if (ns < 0 || ns > nsmax)
628 Error("ns is invalid",ns);
629
630 if (info) {
631 (void) printf("Multiplicity of electronic state %2d\n",multi);
632
633 if (order == 0)
634 (void) printf("Spin functions will be in reverse dictionary order\n");
635 else
636 (void) printf("Spin functions will be in dictionary order\n");
637 }
638
639 if (print)
640 (void) printf("High level print requested\n");
641
642 if ( (multi<1) || (multi>ns+1) || (((multi+ns)%2) != 1) )
643 Error("multiplicity invalid or not consistent with ns",multi);
644
645 MakeBranchingDiagram(bd, ns, multi, 0, info);
646
647
648 nf = bd[multi][ns];
649 if (nf > nfmax)
650 Error("number of spin functions exceeds maximum",nf);
651 nf = nf*nf*sizeof(double);
652 if ( (u = (double *) malloc((unsigned) nf)) == (double *) NULL )
653 Error("failed to allocate memory for u",nf);
654 if ( (uu = (double *) malloc((unsigned) nf)) == (double *) NULL )
655 Error("failed to allocate memory for uu",nf);
656
657 /* open the file for coupling coefficients and write header info */
658
659 if ( (wmatrix = fopen(filename, "w")) == (FILE *) NULL)
660 Error("failed to open file wmatrix for write",0);
661
662 (void) fprintf(wmatrix,"%d\n%d\n",multi,ns);
663 for (i=ns%2; i<=ns; i+=2)
664 (void) fprintf(wmatrix,"%d ",bd[multi][i]);
665 (void) fprintf(wmatrix,"\n");
666
667 /* with dictionary order can get matrices for smaller values of ns
668 from the largest value, so only make that. Using the
669 commented for loop computes the matrices for all values of ns.
670 for (i=ns%2; i<=ns; i+=2) {
671 */
672 for (i=ns; i<=ns; i+=2) {
673
674 nf = bd[multi][i];
675 if (nf == 0)
676 continue;
677
678 if (print) {
679 (void) printf("\n\n---------------------\n");
680 (void) printf("No. of open shells %d\n",i);
681 (void) printf("No. of functions %d\n",nf);
682 (void) printf("---------------------\n\n");
683 }
684
685 if (order == 0)
686 MakeSpinFunctions(bd, i, multi, f, nf, 0, info);
687 else {
688 MakeBranchingDiagram(rbd, i, multi, 1, info);
689 MakeSpinFunctions(rbd, i, multi, f, nf, 1, info);
690 }
691
692 MakeAxialDistances(i, f, nf, d, p, g);
693
694 if (order==0)
695 MakePerm(bd, i, f, nf, perm,0);
696 else
697 MakePerm(rbd, i, f, nf, perm,1);
698
699 /* Make the matrices (-1)^p U(P), P=(j...m) */
700
701 Identity(u, nf);
702 if (print) {
703 (void) printf("\n(-1)^p U(P), P=(%d...%d)\n",i,i);
704 PrintMatrix(u, 1, nf, nf, nf);
705 }
706
707 /* Write matrix out to disk */
708 temp = u;
709 for (k=0; k<nf*nf; k++)
710 (void) fprintf(wmatrix,"%.14g\n",*temp++);
711
712 for (j=i-1; j>=1; j--) {
713 LeftMultiply(j, u, uu, nf, p, g, perm);
714 temp = uu;
715 uu = u;
716 u = temp;
717
718 Screen(nf*nf, 1.0e-8, u, 1);
719 if (print) {
720 (void) printf("\n(-1)^p U(P), P=(%d...%d)\n",j,i);
721 (void) printf("Sparsity of the matrix is %4.2f\n",Sparsity(nf*nf,u,1));
722 PrintMatrix(u,1,nf,nf,nf);
723 }
724
725 /* Write matrix out to disk */
726 temp = u;
727 for (k=0; k<nf*nf; k++)
728 (void) fprintf(wmatrix,"%.14g\n",*temp++);
729
730 }
731
732 if (i >= 2 && (nf2 = bd[multi][i-2]) ) {
733
734 /* Make the matrices (-1)^p sqrt(2) U(P), P=(1...m)(1...j)
735 Note that in u we already have (-1)^m U(1...m) */
736
737 Dscal(nf*nf, sqrt(2.0), u, 1);
738
739 if (print) {
740 (void) printf("\n(-1)^p sqrt(2) U(P), P=(1...%d)(1...%d)\n",i,1);
741 (void) printf("Sparsity of the matrix is %4.2f\n",Sparsity(nf*nf,u,1));
742 PrintMatrix(u, 1, nf, nf, nf2);
743 }
744
745 /* Write matrix out to disk */
746 temp = u;
747 for (k=0; k<nf; k++) {
748 ttemp = temp;
749 for (kk=0; kk<nf2; kk++)
750 (void) fprintf(wmatrix,"%.14g\n",*ttemp++);
751 temp += nf;
752 }
753
754 for (j=1; j<i-1; j++) {
755 RightMultiply(j, u, uu, nf, p, g, perm);
756 temp = uu;
757 uu = u;
758 u = temp;
759
760 Screen(nf*nf, 1.0e-8, u, 1);
761 if (print) {
762 (void) printf("\n(-1)^p sqrt(2) U(P), P=(1...%d)(1...%d)\n",i,j+1);
763 (void) printf("Sparsity of the matrix is %4.2f\n",
764 Sparsity(nf*nf,u,1));
765 PrintMatrix(u,1,nf,nf,nf2);
766 }
767 /* Write matrix out to disk */
768 temp = u;
769 for (k=0; k<nf; k++) {
770 ttemp = temp;
771 for (kk=0; kk<nf2; kk++)
772 (void) fprintf(wmatrix,"%.14g\n",*ttemp++);
773 temp += nf;
774 }
775
776 }
777 }
778
779 }
780
781 (void) free((char *) u);
782 (void) free((char *) uu);
783 (void) fclose(wmatrix);
784 }
785
786
787
788