annotate src/expm.cc @ 453:393e95f46b51

[project @ 1994-06-06 00:05:20 by jwe]
author jwe
date Mon, 06 Jun 1994 00:14:55 +0000
parents a99f28f5e351
children 88614b380d6e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
1 // tc-expm.cc -*- C++ -*-
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
2 /*
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
3
453
393e95f46b51 [project @ 1994-06-06 00:05:20 by jwe]
jwe
parents: 240
diff changeset
4 Copyright (C) 1993, 1994 John W. Eaton
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
5
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
6 This file is part of Octave.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
7
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
8 Octave is free software; you can redistribute it and/or modify it
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
9 under the terms of the GNU General Public License as published by the
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
10 Free Software Foundation; either version 2, or (at your option) any
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
11 later version.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
12
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
13 Octave is distributed in the hope that it will be useful, but WITHOUT
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
16 for more details.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
17
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
18 You should have received a copy of the GNU General Public License
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
19 along with Octave; see the file COPYING. If not, write to the Free
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
20 Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
21
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
22 */
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
23
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
24 // Written by A. S. Hodel <scotte@eng.auburn.edu>
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
25
240
a99f28f5e351 [project @ 1993-11-30 20:24:36 by jwe]
jwe
parents: 234
diff changeset
26 #ifdef HAVE_CONFIG_H
a99f28f5e351 [project @ 1993-11-30 20:24:36 by jwe]
jwe
parents: 234
diff changeset
27 #include "config.h"
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
28 #endif
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
29
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
30 #include <math.h>
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
31
453
393e95f46b51 [project @ 1994-06-06 00:05:20 by jwe]
jwe
parents: 240
diff changeset
32 #include "dMatrix.h"
393e95f46b51 [project @ 1994-06-06 00:05:20 by jwe]
jwe
parents: 240
diff changeset
33 #include "CMatrix.h"
393e95f46b51 [project @ 1994-06-06 00:05:20 by jwe]
jwe
parents: 240
diff changeset
34 #include "CColVector.h"
393e95f46b51 [project @ 1994-06-06 00:05:20 by jwe]
jwe
parents: 240
diff changeset
35 #include "dbleAEPBAL.h"
393e95f46b51 [project @ 1994-06-06 00:05:20 by jwe]
jwe
parents: 240
diff changeset
36 #include "CmplxAEPBAL.h"
234
a366eb563bf2 [project @ 1993-11-16 11:10:08 by jwe]
jwe
parents: 162
diff changeset
37 #include "f77-uscore.h"
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
38
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
39 #include "tree-const.h"
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
40 #include "user-prefs.h"
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
41 #include "gripes.h"
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
42 #include "error.h"
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
43 #include "f-expm.h"
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
44
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
45 #ifdef WITH_DLD
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
46 tree_constant *
162
d1c5e5edbf1e [project @ 1993-10-18 19:26:01 by jwe]
jwe
parents: 90
diff changeset
47 builtin_matrix_exp_2 (const tree_constant *args, int nargin, int nargout)
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
48 {
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
49 tree_constant *retval = new tree_constant [2];
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
50 retval[0] = matrix_exp (args[1]);
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
51 return retval;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
52 }
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
53 #endif
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
54
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
55 extern "C"
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
56 {
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
57 double F77_FCN (dlange) (const char*, const int*, const int*,
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
58 const double*, const int*, double*);
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
59
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
60 double F77_FCN (zlange) (const char*, const int*, const int*,
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
61 const Complex*, const int*, double*);
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
62 }
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
63
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
64 tree_constant
162
d1c5e5edbf1e [project @ 1993-10-18 19:26:01 by jwe]
jwe
parents: 90
diff changeset
65 matrix_exp (const tree_constant& a)
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
66 {
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
67 tree_constant retval;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
68 tree_constant tmp = a.make_numeric ();
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
69
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
70 // Constants for matrix exponential calculation.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
71
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
72 static double padec[] =
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
73 {
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
74 5.0000000000000000e-1,
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
75 1.1666666666666667e-1,
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
76 1.6666666666666667e-2,
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
77 1.6025641025641026e-3,
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
78 1.0683760683760684e-4,
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
79 4.8562548562548563e-6,
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
80 1.3875013875013875e-7,
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
81 1.9270852604185938e-9,
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
82 };
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
83
90
cd4df7ad58fa [project @ 1993-09-13 02:28:11 by jwe]
jwe
parents: 52
diff changeset
84 if (tmp.is_empty ())
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
85 {
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
86 int flag = user_pref.propagate_empty_matrices;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
87 if (flag != 0)
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
88 {
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
89 if (flag < 0)
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
90 gripe_empty_arg ("expm", 0);
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
91 Matrix m;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
92 retval = tree_constant (m);
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
93 }
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
94 else gripe_empty_arg ("expm", 1);
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
95 }
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
96 else if (tmp.rows () != tmp.columns ())
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
97 gripe_square_matrix_required ("expm");
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
98 else
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
99 {
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
100 int i, j;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
101 int n_cols = tmp.columns ();
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
102
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
103 char* balance_job = "B"; // variables for balancing
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
104
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
105 int sqpow; // power for scaling and squaring
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
106 double inf_norm; // norm of preconditioned matrix
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
107 int minus_one_j; // used in computing pade approx
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
108
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
109 switch (tmp.const_type ())
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
110 {
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
111 case tree_constant_rep::complex_matrix_constant:
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
112 {
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
113 ComplexMatrix m = tmp.complex_matrix_value ();
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
114 Complex trshift = 0.0; // trace shift value
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
115
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
116 // Preconditioning step 1: trace normalization.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
117
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
118 for (i = 0; i < n_cols; i++)
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
119 trshift += m.elem (i, i);
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
120 trshift /= n_cols;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
121 for (i = 0; i < n_cols; i++)
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
122 m.elem (i, i) -= trshift;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
123
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
124 // Preconditioning step 2: eigenvalue balancing.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
125
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
126 ComplexAEPBALANCE mbal (m, balance_job);
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
127 m = mbal.balanced_matrix ();
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
128 ComplexMatrix d = mbal.balancing_matrix ();
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
129
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
130 // Preconditioning step 3: scaling.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
131
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
132 ColumnVector work (n_cols);
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
133 inf_norm = F77_FCN (zlange) ("I", &n_cols, &n_cols, m.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
134 fortran_vec (), &n_cols,
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
135 work.fortran_vec ());
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
136
52
9eda1009cf95 [project @ 1993-08-11 21:05:59 by jwe]
jwe
parents: 50
diff changeset
137 sqpow = (int) (1.0 + log (inf_norm) / log (2.0));
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
138
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
139 // Check whether we need to square at all.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
140
52
9eda1009cf95 [project @ 1993-08-11 21:05:59 by jwe]
jwe
parents: 50
diff changeset
141 if (sqpow < 0)
9eda1009cf95 [project @ 1993-08-11 21:05:59 by jwe]
jwe
parents: 50
diff changeset
142 sqpow = 0;
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
143 else
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
144 {
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
145 for (inf_norm = 1.0, i = 0; i < sqpow; i++)
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
146 inf_norm *= 2.0;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
147
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
148 m = m / inf_norm;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
149 }
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
150
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
151 // npp, dpp: pade' approx polynomial matrices.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
152
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
153 ComplexMatrix npp (n_cols, n_cols, 0.0);
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
154 ComplexMatrix dpp = npp;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
155
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
156 // Now powers a^8 ... a^1.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
157
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
158 minus_one_j = -1;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
159 for (j = 7; j >= 0; j--)
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
160 {
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
161 npp = m * npp + m * padec[j];
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
162 dpp = m * dpp + m * (minus_one_j * padec[j]);
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
163 minus_one_j *= -1;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
164 }
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
165
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
166 // Zero power.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
167
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
168 dpp = -dpp;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
169 for (j = 0; j < n_cols; j++)
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
170 {
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
171 npp.elem (j, j) += 1.0;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
172 dpp.elem (j, j) += 1.0;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
173 }
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
174
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
175 // Compute pade approximation = inverse (dpp) * npp.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
176
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
177 ComplexMatrix result = dpp.solve (npp);
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
178
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
179 // Reverse preconditioning step 3: repeated squaring.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
180
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
181 while (sqpow)
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
182 {
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
183 result = result * result;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
184 sqpow--;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
185 }
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
186
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
187 // reverse preconditioning step 2: inverse balancing XXX FIXME XXX:
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
188 // should probably do this with lapack calls instead of a complete
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
189 // matrix inversion.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
190
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
191 result = result.transpose ();
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
192 d = d.transpose ();
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
193 result = result * d;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
194 result = d.solve (result);
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
195 result = result.transpose ();
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
196
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
197 // Reverse preconditioning step 1: fix trace normalization.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
198
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
199 result = result * exp (trshift);
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
200
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
201 retval = tree_constant (result);
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
202 }
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
203 break;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
204 case tree_constant_rep::complex_scalar_constant:
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
205 {
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
206 Complex c = tmp.complex_value ();
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
207 retval = tree_constant (exp (c));
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
208 }
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
209 break;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
210 case tree_constant_rep::matrix_constant:
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
211 {
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
212
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
213 // Compute the exponential.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
214
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
215 Matrix m = tmp.matrix_value ();
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
216
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
217 double trshift = 0; // trace shift value
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
218
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
219 // Preconditioning step 1: trace normalization.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
220
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
221 for (i = 0; i < n_cols; i++)
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
222 trshift += m.elem (i, i);
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
223 trshift /= n_cols;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
224 for (i = 0; i < n_cols; i++)
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
225 m.elem (i, i) -= trshift;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
226
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
227 // Preconditioning step 2: balancing.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
228
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
229 AEPBALANCE mbal (m, balance_job);
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
230 m = mbal.balanced_matrix ();
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
231 Matrix d = mbal.balancing_matrix ();
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
232
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
233 // Preconditioning step 3: scaling.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
234
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
235 ColumnVector work(n_cols);
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
236 inf_norm = F77_FCN (dlange) ("I", &n_cols, &n_cols,
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
237 m.fortran_vec (), &n_cols,
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
238 work.fortran_vec ());
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
239
52
9eda1009cf95 [project @ 1993-08-11 21:05:59 by jwe]
jwe
parents: 50
diff changeset
240 sqpow = (int) (1.0 + log (inf_norm) / log (2.0));
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
241
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
242 // Check whether we need to square at all.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
243
52
9eda1009cf95 [project @ 1993-08-11 21:05:59 by jwe]
jwe
parents: 50
diff changeset
244 if (sqpow < 0)
9eda1009cf95 [project @ 1993-08-11 21:05:59 by jwe]
jwe
parents: 50
diff changeset
245 sqpow = 0;
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
246 else
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
247 {
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
248 for (inf_norm = 1.0, i = 0; i < sqpow; i++)
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
249 inf_norm *= 2.0;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
250
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
251 m = m / inf_norm;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
252 }
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
253
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
254 // npp, dpp: pade' approx polynomial matrices.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
255
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
256 Matrix npp (n_cols, n_cols, 0.0);
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
257 Matrix dpp = npp;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
258
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
259 // now powers a^8 ... a^1.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
260
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
261 minus_one_j = -1;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
262 for (j = 7; j >= 0; j--)
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
263 {
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
264 npp = m * npp + m * padec[j];
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
265 dpp = m * dpp + m * (minus_one_j * padec[j]);
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
266 minus_one_j *= -1;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
267 }
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
268 // Zero power.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
269
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
270 dpp = -dpp;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
271 for(j = 0; j < n_cols; j++)
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
272 {
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
273 npp.elem (j, j) += 1.0;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
274 dpp.elem (j, j) += 1.0;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
275 }
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
276
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
277 // Compute pade approximation = inverse (dpp) * npp.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
278
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
279 Matrix result = dpp.solve (npp);
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
280
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
281 // Reverse preconditioning step 3: repeated squaring.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
282
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
283 while(sqpow)
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
284 {
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
285 result = result * result;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
286 sqpow--;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
287 }
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
288
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
289 // Reverse preconditioning step 2: inverse balancing.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
290
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
291 result = result.transpose();
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
292 d = d.transpose ();
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
293 result = result * d;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
294 result = d.solve (result);
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
295 result = result.transpose ();
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
296
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
297 // Reverse preconditioning step 1: fix trace normalization.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
298
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
299 result = result * exp (trshift);
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
300
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
301 retval = tree_constant (result);
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
302 }
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
303 break;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
304 case tree_constant_rep::scalar_constant:
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
305 {
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
306 double d = tmp.double_value ();
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
307 retval = tree_constant (exp (d));
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
308 }
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
309 break;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
310 default:
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
311 panic_impossible();
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
312 break;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
313 }
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
314 }
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
315 return retval;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
316 }
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
317
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
318 /*
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
319 ;;; Local Variables: ***
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
320 ;;; mode: C++ ***
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
321 ;;; page-delimiter: "^/\\*" ***
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
322 ;;; End: ***
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
323 */