annotate src/expm.cc @ 1352:19c10b8657d5

[project @ 1995-09-05 08:11:57 by jwe]
author jwe
date Tue, 05 Sep 1995 08:33:58 +0000
parents 61bb2bdee11e
children 749071f48336
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
519
b9284136189a [project @ 1994-07-19 14:40:20 by jwe]
jwe
parents: 516
diff changeset
1 // f-expm.cc -*- C++ -*-
50
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
1009
dfe01093f657 [project @ 1995-01-04 04:05:12 by jwe]
jwe
parents: 718
diff changeset
4 Copyright (C) 1993, 1994, 1995 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
1315
611d403c7f3d [project @ 1995-06-25 19:56:32 by jwe]
jwe
parents: 1255
diff changeset
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
50
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
1192
b6360f2d4fa6 [project @ 1995-03-30 21:38:35 by jwe]
jwe
parents: 1009
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
1342
61bb2bdee11e [project @ 1995-09-04 00:19:22 by jwe]
jwe
parents: 1315
diff changeset
30 #include <cmath>
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
31
1352
19c10b8657d5 [project @ 1995-09-05 08:11:57 by jwe]
jwe
parents: 1342
diff changeset
32 #include "CColVector.h"
453
393e95f46b51 [project @ 1994-06-06 00:05:20 by jwe]
jwe
parents: 240
diff changeset
33 #include "CMatrix.h"
1352
19c10b8657d5 [project @ 1995-09-05 08:11:57 by jwe]
jwe
parents: 1342
diff changeset
34 #include "CmplxAEPBAL.h"
19c10b8657d5 [project @ 1995-09-05 08:11:57 by jwe]
jwe
parents: 1342
diff changeset
35 #include "dMatrix.h"
453
393e95f46b51 [project @ 1994-06-06 00:05:20 by jwe]
jwe
parents: 240
diff changeset
36 #include "dbleAEPBAL.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
1352
19c10b8657d5 [project @ 1995-09-05 08:11:57 by jwe]
jwe
parents: 1342
diff changeset
39 #include "defun-dld.h"
19c10b8657d5 [project @ 1995-09-05 08:11:57 by jwe]
jwe
parents: 1342
diff changeset
40 #include "error.h"
19c10b8657d5 [project @ 1995-09-05 08:11:57 by jwe]
jwe
parents: 1342
diff changeset
41 #include "gripes.h"
19c10b8657d5 [project @ 1995-09-05 08:11:57 by jwe]
jwe
parents: 1342
diff changeset
42 #include "help.h"
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
43 #include "tree-const.h"
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
44 #include "user-prefs.h"
636
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
45 #include "utils.h"
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
46
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
47 extern "C"
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
48 {
1255
fa24599e3d2c [project @ 1995-04-11 17:49:27 by jwe]
jwe
parents: 1246
diff changeset
49 double F77_FCN (dlange, DLANGE) (const char*, const int&,
fa24599e3d2c [project @ 1995-04-11 17:49:27 by jwe]
jwe
parents: 1246
diff changeset
50 const int&, const double*,
fa24599e3d2c [project @ 1995-04-11 17:49:27 by jwe]
jwe
parents: 1246
diff changeset
51 const int&, double*);
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
52
1255
fa24599e3d2c [project @ 1995-04-11 17:49:27 by jwe]
jwe
parents: 1246
diff changeset
53 double F77_FCN (zlange, ZLANGE) (const char*, const int&,
fa24599e3d2c [project @ 1995-04-11 17:49:27 by jwe]
jwe
parents: 1246
diff changeset
54 const int&, const Complex*,
fa24599e3d2c [project @ 1995-04-11 17:49:27 by jwe]
jwe
parents: 1246
diff changeset
55 const int&, double*);
50
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
701
0a81458ef677 [project @ 1994-09-15 02:23:24 by jwe]
jwe
parents: 636
diff changeset
58 DEFUN_DLD_BUILTIN ("expm", Fexpm, Sexpm, 2, 1,
519
b9284136189a [project @ 1994-07-19 14:40:20 by jwe]
jwe
parents: 516
diff changeset
59 "expm (X): matrix exponential, e^A")
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
60 {
519
b9284136189a [project @ 1994-07-19 14:40:20 by jwe]
jwe
parents: 516
diff changeset
61 Octave_object retval;
b9284136189a [project @ 1994-07-19 14:40:20 by jwe]
jwe
parents: 516
diff changeset
62
b9284136189a [project @ 1994-07-19 14:40:20 by jwe]
jwe
parents: 516
diff changeset
63 int nargin = args.length ();
b9284136189a [project @ 1994-07-19 14:40:20 by jwe]
jwe
parents: 516
diff changeset
64
712
36ba0576bd1b [project @ 1994-09-19 14:18:15 by jwe]
jwe
parents: 701
diff changeset
65 if (nargin != 1)
519
b9284136189a [project @ 1994-07-19 14:40:20 by jwe]
jwe
parents: 516
diff changeset
66 {
b9284136189a [project @ 1994-07-19 14:40:20 by jwe]
jwe
parents: 516
diff changeset
67 print_usage ("expm");
b9284136189a [project @ 1994-07-19 14:40:20 by jwe]
jwe
parents: 516
diff changeset
68 return retval;
b9284136189a [project @ 1994-07-19 14:40:20 by jwe]
jwe
parents: 516
diff changeset
69 }
b9284136189a [project @ 1994-07-19 14:40:20 by jwe]
jwe
parents: 516
diff changeset
70
712
36ba0576bd1b [project @ 1994-09-19 14:18:15 by jwe]
jwe
parents: 701
diff changeset
71 tree_constant arg = args(0);
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
72
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
73 // Constants for matrix exponential calculation.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
74
497
88614b380d6e [project @ 1994-07-08 02:00:57 by jwe]
jwe
parents: 453
diff changeset
75 static double padec [] =
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
76 {
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
77 5.0000000000000000e-1,
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
78 1.1666666666666667e-1,
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
79 1.6666666666666667e-2,
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
80 1.6025641025641026e-3,
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
81 1.0683760683760684e-4,
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
82 4.8562548562548563e-6,
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
83 1.3875013875013875e-7,
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
84 1.9270852604185938e-9,
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
636
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
87 int nr = arg.rows ();
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
88 int nc = arg.columns ();
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
89
718
e81d3a66725e [project @ 1994-09-21 14:58:18 by jwe]
jwe
parents: 712
diff changeset
90 int arg_is_empty = empty_arg ("expm", nr, nc);
e81d3a66725e [project @ 1994-09-21 14:58:18 by jwe]
jwe
parents: 712
diff changeset
91
e81d3a66725e [project @ 1994-09-21 14:58:18 by jwe]
jwe
parents: 712
diff changeset
92 if (arg_is_empty < 0)
636
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
93 return retval;
718
e81d3a66725e [project @ 1994-09-21 14:58:18 by jwe]
jwe
parents: 712
diff changeset
94 if (arg_is_empty > 0)
e81d3a66725e [project @ 1994-09-21 14:58:18 by jwe]
jwe
parents: 712
diff changeset
95 return Matrix ();
636
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
96
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
97 if (nr != nc)
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
98 {
636
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
99 gripe_square_matrix_required ("expm");
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
100 return retval;
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
101 }
636
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
102
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
103 int i, j;
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
104
636
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
105 char* balance_job = "B"; // variables for balancing
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
106
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
107 int sqpow; // power for scaling and squaring
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
108 double inf_norm; // norm of preconditioned matrix
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
109 int minus_one_j; // used in computing pade approx
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
110
636
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
111 if (arg.is_real_type ())
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
112 {
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
113
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
114 // Compute the exponential.
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
115
636
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
116 Matrix m = arg.matrix_value ();
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
117
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
118 if (error_state)
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
119 return retval;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
120
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
121 double trshift = 0; // trace shift value
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
122
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
123 // Preconditioning step 1: trace normalization.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
124
636
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
125 for (i = 0; i < nc; i++)
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
126 trshift += m.elem (i, i);
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
127 trshift /= nc;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
128 for (i = 0; i < nc; i++)
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
129 m.elem (i, i) -= trshift;
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
130
636
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
131 // Preconditioning step 2: balancing.
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
132
636
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
133 AEPBALANCE mbal (m, balance_job);
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
134 m = mbal.balanced_matrix ();
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
135 Matrix d = mbal.balancing_matrix ();
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
136
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
137 // Preconditioning step 3: scaling.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
138
636
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
139 ColumnVector work(nc);
1255
fa24599e3d2c [project @ 1995-04-11 17:49:27 by jwe]
jwe
parents: 1246
diff changeset
140 inf_norm = F77_FCN (dlange, DLANGE) ("I", nc, nc,
fa24599e3d2c [project @ 1995-04-11 17:49:27 by jwe]
jwe
parents: 1246
diff changeset
141 m.fortran_vec (), nc,
fa24599e3d2c [project @ 1995-04-11 17:49:27 by jwe]
jwe
parents: 1246
diff changeset
142 work.fortran_vec ());
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
143
636
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
144 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
145
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
146 // Check whether we need to square at all.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
147
636
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
148 if (sqpow < 0)
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
149 sqpow = 0;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
150 else
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
151 {
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
152 for (inf_norm = 1.0, i = 0; i < sqpow; i++)
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
153 inf_norm *= 2.0;
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
154
636
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
155 m = m / inf_norm;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
156 }
50
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 // npp, dpp: pade' approx polynomial matrices.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
159
636
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
160 Matrix npp (nc, nc, 0.0);
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
161 Matrix dpp = npp;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
162
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
163 // now powers a^8 ... a^1.
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
164
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
165 minus_one_j = -1;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
166 for (j = 7; j >= 0; j--)
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
167 {
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
168 npp = m * npp + m * padec[j];
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
169 dpp = m * dpp + m * (minus_one_j * padec[j]);
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
170 minus_one_j *= -1;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
171 }
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
172 // Zero power.
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
173
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
174 dpp = -dpp;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
175 for(j = 0; j < nc; j++)
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
176 {
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
177 npp.elem (j, j) += 1.0;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
178 dpp.elem (j, j) += 1.0;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
179 }
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
180
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
181 // Compute pade approximation = inverse (dpp) * npp.
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
182
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
183 Matrix result = dpp.solve (npp);
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
184
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
185 // Reverse preconditioning step 3: repeated squaring.
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
186
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
187 while (sqpow)
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
188 {
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
189 result = result * result;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
190 sqpow--;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
191 }
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
192
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
193 // Reverse preconditioning step 2: inverse balancing.
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
194
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
195 result = result.transpose();
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
196 d = d.transpose ();
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
197 result = result * d;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
198 result = d.solve (result);
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
199 result = result.transpose ();
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
200
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
201 // Reverse preconditioning step 1: fix trace normalization.
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
202
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
203 result = result * exp (trshift);
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
204
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
205 retval = result;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
206 }
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
207 else if (arg.is_complex_type ())
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
208 {
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
209 ComplexMatrix m = arg.complex_matrix_value ();
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
210
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
211 if (error_state)
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
212 return retval;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
213
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
214 Complex trshift = 0.0; // trace shift value
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
215
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
216 // Preconditioning step 1: trace normalization.
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
217
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
218 for (i = 0; i < nc; i++)
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
219 trshift += m.elem (i, i);
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
220 trshift /= nc;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
221 for (i = 0; i < nc; i++)
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
222 m.elem (i, i) -= trshift;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
223
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
224 // Preconditioning step 2: eigenvalue balancing.
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
225
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
226 ComplexAEPBALANCE mbal (m, balance_job);
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
227 m = mbal.balanced_matrix ();
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
228 ComplexMatrix d = mbal.balancing_matrix ();
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
229
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
230 // Preconditioning step 3: scaling.
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
231
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
232 ColumnVector work (nc);
1255
fa24599e3d2c [project @ 1995-04-11 17:49:27 by jwe]
jwe
parents: 1246
diff changeset
233 inf_norm = F77_FCN (zlange, ZLANGE) ("I", nc, nc,
fa24599e3d2c [project @ 1995-04-11 17:49:27 by jwe]
jwe
parents: 1246
diff changeset
234 m.fortran_vec (), nc,
fa24599e3d2c [project @ 1995-04-11 17:49:27 by jwe]
jwe
parents: 1246
diff changeset
235 work.fortran_vec ());
636
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
236
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
237 sqpow = (int) (1.0 + log (inf_norm) / log (2.0));
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
238
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
239 // Check whether we need to square at all.
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
240
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
241 if (sqpow < 0)
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
242 sqpow = 0;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
243 else
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
244 {
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
245 for (inf_norm = 1.0, i = 0; i < sqpow; i++)
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
246 inf_norm *= 2.0;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
247
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
248 m = m / inf_norm;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
249 }
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
250
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
251 // npp, dpp: pade' approx polynomial matrices.
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
252
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
253 ComplexMatrix npp (nc, nc, 0.0);
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
254 ComplexMatrix dpp = npp;
50
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 // Now powers a^8 ... a^1.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
257
636
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
258 minus_one_j = -1;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
259 for (j = 7; j >= 0; j--)
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
260 {
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
261 npp = m * npp + m * padec[j];
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
262 dpp = m * dpp + m * (minus_one_j * padec[j]);
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
263 minus_one_j *= -1;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
264 }
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
265
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
266 // Zero power.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
267
636
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
268 dpp = -dpp;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
269 for (j = 0; j < nc; j++)
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
270 {
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
271 npp.elem (j, j) += 1.0;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
272 dpp.elem (j, j) += 1.0;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
273 }
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
274
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
275 // Compute pade approximation = inverse (dpp) * npp.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
276
636
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
277 ComplexMatrix result = dpp.solve (npp);
50
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 // Reverse preconditioning step 3: repeated squaring.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
280
636
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
281 while (sqpow)
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
282 {
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
283 result = result * result;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
284 sqpow--;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
285 }
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
286
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
287 // reverse preconditioning step 2: inverse balancing XXX FIXME XXX:
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
288 // 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
289 // matrix inversion.
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
290
636
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
291 result = result.transpose ();
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
292 d = d.transpose ();
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
293 result = result * d;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
294 result = d.solve (result);
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
295 result = result.transpose ();
50
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
636
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
299 result = result * exp (trshift);
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
300
636
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
301 retval = result;
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
302 }
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
303 else
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
304 {
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
305 gripe_wrong_type_arg ("expm", arg);
fae2bd91c027 [project @ 1994-08-23 18:39:50 by jwe]
jwe
parents: 620
diff changeset
306 }
50
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
307
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
308 return retval;
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
309 }
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
310
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
311 /*
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
312 ;;; Local Variables: ***
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
313 ;;; mode: C++ ***
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
314 ;;; page-delimiter: "^/\\*" ***
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
315 ;;; End: ***
6028dcac27ef [project @ 1993-08-11 20:48:00 by jwe]
jwe
parents:
diff changeset
316 */