Mercurial > hg > octave-nkf
annotate liboctave/CollocWt.cc @ 10822:23d2378512a0
implement rsf2csf
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Tue, 27 Jul 2010 11:26:43 +0200 |
parents | d909c4c14b63 |
children | fd0a3ac60b0e |
rev | line source |
---|---|
3 | 1 /* |
2 | |
7017 | 3 Copyright (C) 1993, 1994, 1995, 1996, 1997, 2000, 2002, 2003, 2004, |
4 2005, 2007 John W. Eaton | |
3 | 5 |
6 This file is part of Octave. | |
7 | |
8 Octave is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
7016 | 10 Free Software Foundation; either version 3 of the License, or (at your |
11 option) any later version. | |
3 | 12 |
13 Octave is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
7016 | 19 along with Octave; see the file COPYING. If not, see |
20 <http://www.gnu.org/licenses/>. | |
3 | 21 |
22 */ | |
23 | |
238 | 24 #ifdef HAVE_CONFIG_H |
1192 | 25 #include <config.h> |
3 | 26 #endif |
27 | |
3503 | 28 #include <iostream> |
238 | 29 |
10603
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
30 #include <cfloat> |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
31 |
3 | 32 #include "CollocWt.h" |
1847 | 33 #include "f77-fcn.h" |
227 | 34 #include "lo-error.h" |
3 | 35 |
10603
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
36 // The following routines jcobi, dif, and dfopr are based on the code |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
37 // found in Villadsen, J. and M. L. Michelsen, Solution of Differential |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
38 // Equation Models by Polynomial Approximation, Prentice-Hall (1978) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
39 // pages 418-420. |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
40 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
41 // Translated to C++ by jwe. |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
42 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
43 // Compute the first three derivatives of the node polynomial. |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
44 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
45 // n0 (alpha,beta) n1 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
46 // p (x) = (x) * p (x) * (1 - x) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
47 // nt n |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
48 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
49 // at the interpolation points. Each of the parameters n0 and n1 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
50 // may be given the value 0 or 1. The total number of points |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
51 // nt = n + n0 + n1 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
52 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
53 // The values of root must be known before a call to dif is possible. |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
54 // They may be computed using jcobi. |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
55 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
56 static void |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
57 dif (octave_idx_type nt, double *root, double *dif1, double *dif2, |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
58 double *dif3) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
59 { |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
60 // Evaluate derivatives of node polynomial using recursion formulas. |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
61 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
62 for (octave_idx_type i = 0; i < nt; i++) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
63 { |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
64 double x = root[i]; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
65 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
66 dif1[i] = 1.0; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
67 dif2[i] = 0.0; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
68 dif3[i] = 0.0; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
69 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
70 for (octave_idx_type j = 0; j < nt; j++) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
71 { |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
72 if (j != i) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
73 { |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
74 double y = x - root[j]; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
75 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
76 dif3[i] = y * dif3[i] + 3.0 * dif2[i]; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
77 dif2[i] = y * dif2[i] + 2.0 * dif1[i]; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
78 dif1[i] = y * dif1[i]; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
79 } |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
80 } |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
81 } |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
82 } |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
83 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
84 // Compute the zeros of the Jacobi polynomial. |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
85 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
86 // (alpha,beta) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
87 // p (x) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
88 // n |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
89 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
90 // Use dif to compute the derivatives of the node |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
91 // polynomial |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
92 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
93 // n0 (alpha,beta) n1 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
94 // p (x) = (x) * p (x) * (1 - x) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
95 // nt n |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
96 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
97 // at the interpolation points. |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
98 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
99 // See Villadsen and Michelsen, pages 131-132 and 418. |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
100 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
101 // Input parameters: |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
102 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
103 // nd : the dimension of the vectors dif1, dif2, dif3, and root |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
104 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
105 // n : the degree of the jacobi polynomial, (i.e. the number |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
106 // of interior interpolation points) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
107 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
108 // n0 : determines whether x = 0 is included as an |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
109 // interpolation point |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
110 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
111 // n0 = 0 ==> x = 0 is not included |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
112 // n0 = 1 ==> x = 0 is included |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
113 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
114 // n1 : determines whether x = 1 is included as an |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
115 // interpolation point |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
116 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
117 // n1 = 0 ==> x = 1 is not included |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
118 // n1 = 1 ==> x = 1 is included |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
119 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
120 // alpha : the value of alpha in the description of the jacobi |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
121 // polynomial |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
122 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
123 // beta : the value of beta in the description of the jacobi |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
124 // polynomial |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
125 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
126 // For a more complete explanation of alpha an beta, see Villadsen |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
127 // and Michelsen, pages 57 to 59. |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
128 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
129 // Output parameters: |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
130 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
131 // root : one dimensional vector containing on exit the |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
132 // n + n0 + n1 zeros of the node polynomial used in the |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
133 // interpolation routine |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
134 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
135 // dif1 : one dimensional vector containing the first derivative |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
136 // of the node polynomial at the zeros |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
137 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
138 // dif2 : one dimensional vector containing the second derivative |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
139 // of the node polynomial at the zeros |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
140 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
141 // dif3 : one dimensional vector containing the third derivative |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
142 // of the node polynomial at the zeros |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
143 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
144 static bool |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
145 jcobi (octave_idx_type n, octave_idx_type n0, octave_idx_type n1, |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
146 double alpha, double beta, double *dif1, double *dif2, |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
147 double *dif3, double *root) |
3 | 148 { |
10603
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
149 assert (n0 == 0 || n0 == 1); |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
150 assert (n1 == 0 || n1 == 1); |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
151 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
152 octave_idx_type nt = n + n0 + n1; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
153 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
154 assert (nt > 1); |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
155 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
156 // -- first evaluation of coefficients in recursion formulas. |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
157 // -- recursion coefficients are stored in dif1 and dif2. |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
158 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
159 double ab = alpha + beta; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
160 double ad = beta - alpha; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
161 double ap = beta * alpha; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
162 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
163 dif1[0] = (ad / (ab + 2.0) + 1.0) / 2.0; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
164 dif2[0] = 0.0; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
165 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
166 if (n >= 2) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
167 { |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
168 for (octave_idx_type i = 1; i < n; i++) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
169 { |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
170 double z1 = i; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
171 double z = ab + 2 * z1; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
172 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
173 dif1[i] = (ab * ad / z / (z + 2.0) + 1.0) / 2.0; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
174 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
175 if (i == 1) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
176 dif2[i] = (ab + ap + z1) / z / z / (z + 1.0); |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
177 else |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
178 { |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
179 z = z * z; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
180 double y = z1 * (ab + z1); |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
181 y = y * (ap + y); |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
182 dif2[i] = y / z / (z - 1.0); |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
183 } |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
184 } |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
185 } |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
186 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
187 // Root determination by Newton method with suppression of previously |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
188 // determined roots. |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
189 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
190 double x = 0.0; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
191 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
192 for (octave_idx_type i = 0; i < n; i++) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
193 { |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
194 bool done = false; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
195 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
196 int k = 0; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
197 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
198 while (! done) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
199 { |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
200 double xd = 0.0; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
201 double xn = 1.0; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
202 double xd1 = 0.0; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
203 double xn1 = 0.0; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
204 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
205 for (octave_idx_type j = 0; j < n; j++) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
206 { |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
207 double xp = (dif1[j] - x) * xn - dif2[j] * xd; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
208 double xp1 = (dif1[j] - x) * xn1 - dif2[j] * xd1 - xn; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
209 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
210 xd = xn; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
211 xd1 = xn1; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
212 xn = xp; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
213 xn1 = xp1; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
214 } |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
215 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
216 double zc = 1.0; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
217 double z = xn / xn1; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
218 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
219 if (i != 0) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
220 { |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
221 for (octave_idx_type j = 1; j <= i; j++) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
222 zc = zc - z / (x - root[j-1]); |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
223 } |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
224 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
225 z = z / zc; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
226 x = x - z; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
227 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
228 // Famous last words: 100 iterations should be more than |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
229 // enough in all cases. |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
230 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
231 if (++k > 100 || xisnan (z)) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
232 return false; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
233 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
234 if (std::abs (z) <= 100 * DBL_EPSILON) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
235 done = true; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
236 } |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
237 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
238 root[i] = x; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
239 x = x + sqrt (DBL_EPSILON); |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
240 } |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
241 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
242 // Add interpolation points at x = 0 and/or x = 1. |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
243 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
244 if (n0 != 0) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
245 { |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
246 for (octave_idx_type i = n; i > 0; i--) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
247 root[i] = root[i-1]; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
248 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
249 root[0] = 0.0; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
250 } |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
251 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
252 if (n1 != 0) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
253 root[nt-1] = 1.0; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
254 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
255 dif (nt, root, dif1, dif2, dif3); |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
256 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
257 return true; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
258 } |
3 | 259 |
10603
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
260 // Compute derivative weights for orthogonal collocation. |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
261 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
262 // See Villadsen and Michelsen, pages 133-134, 419. |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
263 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
264 // Input parameters: |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
265 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
266 // nd : the dimension of the vectors dif1, dif2, dif3, and root |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
267 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
268 // n : the degree of the jacobi polynomial, (i.e. the number |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
269 // of interior interpolation points) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
270 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
271 // n0 : determines whether x = 0 is included as an |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
272 // interpolation point |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
273 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
274 // n0 = 0 ==> x = 0 is not included |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
275 // n0 = 1 ==> x = 0 is included |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
276 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
277 // n1 : determines whether x = 1 is included as an |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
278 // interpolation point |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
279 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
280 // n1 = 0 ==> x = 1 is not included |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
281 // n1 = 1 ==> x = 1 is included |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
282 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
283 // i : the index of the node for which the weights are to be |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
284 // calculated |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
285 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
286 // id : indicator |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
287 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
288 // id = 1 ==> first derivative weights are computed |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
289 // id = 2 ==> second derivative weights are computed |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
290 // id = 3 ==> gaussian weights are computed (in this |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
291 // case, the value of i is irrelevant) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
292 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
293 // Output parameters: |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
294 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
295 // dif1 : one dimensional vector containing the first derivative |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
296 // of the node polynomial at the zeros |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
297 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
298 // dif2 : one dimensional vector containing the second derivative |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
299 // of the node polynomial at the zeros |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
300 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
301 // dif3 : one dimensional vector containing the third derivative |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
302 // of the node polynomial at the zeros |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
303 // |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
304 // vect : one dimensional vector of computed weights |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
305 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
306 static void |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
307 dfopr (octave_idx_type n, octave_idx_type n0, octave_idx_type n1, |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
308 octave_idx_type i, octave_idx_type id, double *dif1, |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
309 double *dif2, double *dif3, double *root, double *vect) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
310 { |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
311 assert (n0 == 0 || n0 == 1); |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
312 assert (n1 == 0 || n1 == 1); |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
313 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
314 octave_idx_type nt = n + n0 + n1; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
315 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
316 assert (nt > 1); |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
317 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
318 assert (id == 1 || id == 2 || id == 3); |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
319 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
320 if (id != 3) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
321 assert (i >= 0 && i < nt); |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
322 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
323 // Evaluate discretization matrices and Gaussian quadrature weights. |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
324 // Quadrature weights are normalized to sum to one. |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
325 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
326 if (id != 3) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
327 { |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
328 for (octave_idx_type j = 0; j < nt; j++) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
329 { |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
330 if (j == i) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
331 { |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
332 if (id == 1) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
333 vect[i] = dif2[i] / dif1[i] / 2.0; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
334 else |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
335 vect[i] = dif3[i] / dif1[i] / 3.0; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
336 } |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
337 else |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
338 { |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
339 double y = root[i] - root[j]; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
340 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
341 vect[j] = dif1[i] / dif1[j] / y; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
342 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
343 if (id == 2) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
344 vect[j] = vect[j] * (dif2[i] / dif1[i] - 2.0 / y); |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
345 } |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
346 } |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
347 } |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
348 else |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
349 { |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
350 double y = 0.0; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
351 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
352 for (octave_idx_type j = 0; j < nt; j++) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
353 { |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
354 double x = root[j]; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
355 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
356 double ax = x * (1.0 - x); |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
357 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
358 if (n0 == 0) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
359 ax = ax / x / x; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
360 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
361 if (n1 == 0) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
362 ax = ax / (1.0 - x) / (1.0 - x); |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
363 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
364 vect[j] = ax / (dif1[j] * dif1[j]); |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
365 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
366 y = y + vect[j]; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
367 } |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
368 |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
369 for (octave_idx_type j = 0; j < nt; j++) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
370 vect[j] = vect[j] / y; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
371 } |
3 | 372 } |
373 | |
374 // Error handling. | |
375 | |
376 void | |
377 CollocWt::error (const char* msg) | |
378 { | |
227 | 379 (*current_liboctave_error_handler) ("fatal CollocWt error: %s", msg); |
3 | 380 } |
381 | |
382 CollocWt& | |
383 CollocWt::set_left (double val) | |
384 { | |
385 if (val >= rb) | |
227 | 386 { |
387 error ("left bound greater than right bound"); | |
388 return *this; | |
389 } | |
3 | 390 |
391 lb = val; | |
392 initialized = 0; | |
393 return *this; | |
394 } | |
395 | |
396 CollocWt& | |
397 CollocWt::set_right (double val) | |
398 { | |
399 if (val <= lb) | |
227 | 400 { |
401 error ("right bound less than left bound"); | |
402 return *this; | |
403 } | |
3 | 404 |
405 rb = val; | |
406 initialized = 0; | |
407 return *this; | |
408 } | |
409 | |
410 void | |
411 CollocWt::init (void) | |
412 { | |
1360 | 413 // Check for possible errors. |
3 | 414 |
415 double wid = rb - lb; | |
416 if (wid <= 0.0) | |
227 | 417 { |
418 error ("width less than or equal to zero"); | |
419 return; | |
420 } | |
3 | 421 |
5275 | 422 octave_idx_type nt = n + inc_left + inc_right; |
1870 | 423 |
3 | 424 if (nt < 0) |
227 | 425 { |
426 error ("total number of collocation points less than zero"); | |
427 return; | |
428 } | |
3 | 429 else if (nt == 0) |
430 return; | |
431 | |
10350
12884915a8e4
merge MArray classes & improve Array interface
Jaroslav Hajek <highegg@gmail.com>
parents:
10314
diff
changeset
|
432 Array<double> dif1 (nt, 1); |
1938 | 433 double *pdif1 = dif1.fortran_vec (); |
434 | |
10350
12884915a8e4
merge MArray classes & improve Array interface
Jaroslav Hajek <highegg@gmail.com>
parents:
10314
diff
changeset
|
435 Array<double> dif2 (nt, 1); |
1938 | 436 double *pdif2 = dif2.fortran_vec (); |
437 | |
10350
12884915a8e4
merge MArray classes & improve Array interface
Jaroslav Hajek <highegg@gmail.com>
parents:
10314
diff
changeset
|
438 Array<double> dif3 (nt, 1); |
1938 | 439 double *pdif3 = dif3.fortran_vec (); |
440 | |
10350
12884915a8e4
merge MArray classes & improve Array interface
Jaroslav Hajek <highegg@gmail.com>
parents:
10314
diff
changeset
|
441 Array<double> vect (nt, 1); |
1938 | 442 double *pvect = vect.fortran_vec (); |
3 | 443 |
10350
12884915a8e4
merge MArray classes & improve Array interface
Jaroslav Hajek <highegg@gmail.com>
parents:
10314
diff
changeset
|
444 r.resize (nt, 1); |
12884915a8e4
merge MArray classes & improve Array interface
Jaroslav Hajek <highegg@gmail.com>
parents:
10314
diff
changeset
|
445 q.resize (nt, 1); |
3 | 446 A.resize (nt, nt); |
447 B.resize (nt, nt); | |
448 | |
449 double *pr = r.fortran_vec (); | |
450 | |
1360 | 451 // Compute roots. |
3 | 452 |
10603
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
453 if (! jcobi (n, inc_left, inc_right, Alpha, Beta, pdif1, pdif2, pdif3, pr)) |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
454 { |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
455 error ("jcobi: newton iteration failed"); |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
456 return; |
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
457 } |
3 | 458 |
5275 | 459 octave_idx_type id; |
3 | 460 |
1360 | 461 // First derivative weights. |
3 | 462 |
463 id = 1; | |
10603
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
464 for (octave_idx_type i = 0; i < nt; i++) |
3 | 465 { |
10603
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
466 dfopr (n, inc_left, inc_right, i, id, pdif1, pdif2, pdif3, pr, pvect); |
3 | 467 |
5275 | 468 for (octave_idx_type j = 0; j < nt; j++) |
10603
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
469 A(i,j) = vect(j); |
3 | 470 } |
471 | |
1360 | 472 // Second derivative weights. |
3 | 473 |
474 id = 2; | |
10603
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
475 for (octave_idx_type i = 0; i < nt; i++) |
3 | 476 { |
10603
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
477 dfopr (n, inc_left, inc_right, i, id, pdif1, pdif2, pdif3, pr, pvect); |
3 | 478 |
5275 | 479 for (octave_idx_type j = 0; j < nt; j++) |
10603
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
480 B(i,j) = vect(j); |
3 | 481 } |
482 | |
1360 | 483 // Gaussian quadrature weights. |
3 | 484 |
485 id = 3; | |
486 double *pq = q.fortran_vec (); | |
10603
d909c4c14b63
convert villad functions to C++
John W. Eaton <jwe@octave.org>
parents:
10350
diff
changeset
|
487 dfopr (n, inc_left, inc_right, id, id, pdif1, pdif2, pdif3, pr, pq); |
3 | 488 |
489 initialized = 1; | |
490 } | |
491 | |
3504 | 492 std::ostream& |
493 operator << (std::ostream& os, const CollocWt& a) | |
3 | 494 { |
495 if (a.left_included ()) | |
496 os << "left boundary is included\n"; | |
497 else | |
498 os << "left boundary is not included\n"; | |
499 | |
500 if (a.right_included ()) | |
501 os << "right boundary is included\n"; | |
502 else | |
503 os << "right boundary is not included\n"; | |
504 | |
505 os << "\n"; | |
506 | |
507 os << a.Alpha << " " << a.Beta << "\n\n" | |
508 << a.r << "\n\n" | |
509 << a.q << "\n\n" | |
510 << a.A << "\n" | |
511 << a.B << "\n"; | |
512 | |
513 return os; | |
514 } |