comparison liboctave/NLEqn.cc @ 3:9a4c07481e61

[project @ 1993-08-08 01:20:23 by jwe] Initial revision
author jwe
date Sun, 08 Aug 1993 01:21:46 +0000
parents
children edfb6cafe85d
comparison
equal deleted inserted replaced
2:c0190df9885d 3:9a4c07481e61
1 // NLEqn.cc -*- C++ -*-
2 /*
3
4 Copyright (C) 1992, 1993 John W. Eaton
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
10 Free Software Foundation; either version 2, or (at your option) any
11 later version.
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
19 along with Octave; see the file COPYING. If not, write to the Free
20 Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21
22 */
23
24 #ifdef __GNUG__
25 #pragma implementation
26 #endif
27
28 #include <iostream.h>
29 #include <float.h>
30 #include "NLEqn.h"
31 #include "f77-uscore.h"
32
33 extern "C"
34 {
35 int F77_FCN (hybrd1) (int (*)(), const int*, double*, double*,
36 const double*, int*, double*, const int*);
37
38 int F77_FCN (hybrj1) (int (*)(), const int*, double*, double*,
39 double*, const int*, const double*, int*,
40 double*, const int*);
41 }
42
43 static nonlinear_fcn user_fun;
44 static jacobian_fcn user_jac;
45
46 // error handling
47
48 void
49 NLEqn::error (const char* msg)
50 {
51 cerr << "Fatal NLEqn error. " << msg << "\n";
52 exit(1);
53 }
54
55 // Constructors
56
57 NLEqn::NLEqn (void) : NLFunc (), x (), n (0) {}
58
59 NLEqn::NLEqn (const Vector& xvec, const NLFunc f)
60 : NLFunc (f), x (xvec), n (x.capacity ()) {}
61
62 NLEqn::NLEqn (const NLEqn& a) : NLFunc (a.fun, a.jac), x (a.x), n (a.n) {}
63
64 void
65 NLEqn::resize (int nn)
66 {
67 if (n != nn)
68 {
69 n = nn;
70 x.resize (n);
71 }
72 }
73
74 int
75 NLEqn::size (void) const
76 {
77 return n;
78 }
79
80 // Assignment
81
82 NLEqn&
83 NLEqn::operator = (const NLEqn& a)
84 {
85 fun = a.fun;
86 jac = a.jac;
87 x = a.n;
88
89 return *this;
90 }
91
92 Vector
93 NLEqn::states (void) const
94 {
95 return x;
96 }
97
98 void
99 NLEqn::set_states (const Vector& xvec)
100 {
101 if (xvec.capacity () != n)
102 error ("dimension error");
103
104 x = xvec;
105 }
106
107 // Other operations
108
109 Vector
110 NLEqn::solve (const Vector& xvec)
111 {
112 set_states (xvec);
113 int info;
114 return solve (info);
115 }
116
117 Vector
118 NLEqn::solve (const Vector& xvec, int& info)
119 {
120 set_states (xvec);
121 return solve (info);
122 }
123
124 Vector
125 NLEqn::solve (void)
126 {
127 int info;
128 return solve (info);
129 }
130
131 int
132 hybrd1_fcn (int *n, double *x, double *fvec, int *iflag)
133 {
134 int nn = *n;
135 Vector tmp_f (nn);
136 Vector tmp_x (nn);
137
138 for (int i = 0; i < nn; i++)
139 tmp_x.elem (i) = x[i];
140
141 tmp_f = (*user_fun) (tmp_x);
142
143 for (i = 0; i < nn; i++)
144 fvec[i] = tmp_f.elem (i);
145
146 return 0;
147 }
148
149 int
150 hybrj1_fcn (int *n, double *x, double *fvec, double *fjac,
151 int *ldfjac, int *iflag)
152 {
153 int nn = *n;
154 Vector tmp_x (nn);
155
156 for (int i = 0; i < nn; i++)
157 tmp_x.elem (i) = x[i];
158
159 int flag = *iflag;
160 if (flag == 1)
161 {
162 Vector tmp_f (nn);
163
164 tmp_f = (*user_fun) (tmp_x);
165
166 for (i = 0; i < nn; i++)
167 fvec[i] = tmp_f.elem (i);
168 }
169 else
170 {
171 Matrix tmp_fj (nn, nn);
172
173 tmp_fj = (*user_jac) (tmp_x);
174
175 int ld = *ldfjac;
176 for (int j = 0; j < nn; j++)
177 for (i = 0; i < nn; i++)
178 fjac[j*ld+i] = tmp_fj.elem (i, j);
179 }
180
181 return 0;
182 }
183
184 Vector
185 NLEqn::solve (int& info)
186 {
187 int tmp_info = 0;
188
189 if (n == 0)
190 error ("Equation set not initialized");
191
192 double tol = sqrt (DBL_EPSILON);
193
194 double *fvec = new double [n];
195 double *px = new double [n];
196 for (int i = 0; i < n; i++)
197 px[i] = x.elem (i);
198
199 user_fun = fun;
200 user_jac = jac;
201
202 if (jac == NULL)
203 {
204 int lwa = (n*(3*n+13))/2;
205 double *wa = new double [lwa];
206
207 F77_FCN (hybrd1) (hybrd1_fcn, &n, px, fvec, &tol, &tmp_info, wa, &lwa);
208
209 delete [] wa;
210 }
211 else
212 {
213 int lwa = (n*(n+13))/2;
214 double *wa = new double [lwa];
215 double *fjac = new double [n*n];
216
217 F77_FCN (hybrj1) (hybrj1_fcn, &n, px, fvec, fjac, &n, &tol,
218 &tmp_info, wa, &lwa);
219
220 delete [] wa;
221 delete [] fjac;
222 }
223
224 info = tmp_info;
225
226 Vector retval (n);
227
228 for (i = 0; i < n; i++)
229 retval.elem (i) = px[i];
230
231 return retval;
232 }
233
234 /*
235 ;;; Local Variables: ***
236 ;;; mode: C++ ***
237 ;;; page-delimiter: "^/\\*" ***
238 ;;; End: ***
239 */