64 #if _MSC_VER < 1300 // Microsoft
65 #ifndef GUARD_minmax_H
66 #define GUARD_minmax_H
69 template <
class T>
inline T max(
const T& a,
const T& b)
71 return (a > b) ? a : b;
73 template <
class T>
inline T min(
const T& a,
const T& b)
75 return (a < b) ? a : b;
83 using namespace NEWMAT;
90 Matrix S(3,3); S = 0.0;
91 S(1,2) = -x(3); S(1,3) = x(2);
92 S(2,1) = x(3); S(2,3) = -x(1);
93 S(3,1) = -x(2); S(3,2) = x(1);
95 S.Release();
return (S);
98 ReturnMatrix
pinv(
const Matrix & M)
122 const Real eps = numeric_limits<Real>::epsilon();
129 Matrix X =
pinv(M.t()).t();
141 Real tol = max(m,n)*Q(1)*eps;
145 for(
int i = 1; i <= Q.size(); i++)
152 for(
int i = 1; i <= r; i++)
157 X = V.SubMatrix(1,V.nrows(),1,r)*D*U.SubMatrix(1,U.nrows(),1,r).t();
164 ReturnMatrix
Integ_Trap(
const ColumnVector & present, ColumnVector & past,
168 ColumnVector integration(present.Nrows());
169 integration = (past+present)*0.5*dt;
172 integration.Release();
173 return ( integration );
178 bool & exit,
bool & init),
179 const Matrix & xo, Real to, Real tf,
int nsteps)
182 static Real h, h2, t;
183 static Matrix k1, k2, k3, k4, x;
184 static bool first_pass =
true, init =
false, exit =
false;
186 if(first_pass || init)
194 k1 = (*xdot)(t, x, exit, init) * h;
196 k2 = (*xdot)(t+h2, x+k1*0.5, exit, init)*h;
198 k3 = (*xdot)(t+h2, x+k2*0.5, exit, init)*h;
200 k4 = (*xdot)(t+h, x+k3, exit, init)*h;
202 x = x + (k1*0.5+ k2 + k3 + k4*0.5)*(1.0/3.0);
207 const Matrix & xo,
const Real to,
const Real tf,
const int nsteps)
209 static Real h, h2, t;
210 static Matrix k1, k2, k3, k4, x;
211 static bool first_pass =
true;
221 k1 = (*xdot)(t, x) * h;
223 k2 = (*xdot)(t, x+k1*0.5)*h;
224 k3 = (*xdot)(t, x+k2*0.5)*h;
226 k4 = (*xdot)(t, x+k3)*h;
227 x = x + (k1*0.5+ k2 + k3 + k4*0.5)*(1.0/3.0);
232 const Matrix & xo, Real to, Real tf,
int nsteps,
233 RowVector & tout, Matrix & xout)
237 Matrix k1, k2, k3, k4, x;
243 xout = Matrix(xo.Nrows(),(nsteps+1)*xo.Ncols());
244 xout.SubMatrix(1,xo.Nrows(),1,xo.Ncols()) = x;
245 tout = RowVector(nsteps+1);
247 for (
int i = 1; i <= nsteps; i++) {
248 k1 = (*xdot)(t, x) * h;
249 k2 = (*xdot)(t+h2, x+k1*0.5)*h;
250 k3 = (*xdot)(t+h2, x+k2*0.5)*h;
251 k4 = (*xdot)(t+h, x+k3)*h;
252 x = x + (k1*0.5+ k2 + k3 + k4*0.5)*(1.0/3.0);
255 xout.SubMatrix(1,xo.Nrows(),i*xo.Ncols()+1,(i+1)*xo.Ncols()) = x;
259 ReturnMatrix
rk4(
const Matrix & x,
const Matrix & dxdt, Real t, Real h,
260 ReturnMatrix (*xdot)(Real time,
const Matrix & xin))
270 Matrix xt, xout, dxm, dxt;
277 dxt = (*xdot)(th,xt);
279 dxm = (*xdot)(th,xt);
282 dxt = (*xdot)(t+h,xt);
283 xout = x+h6*(dxdt+dxt+2.0*dxm);
285 xout.Release();
return xout;
290 #define FCOR 0.06666666
292 #define ERRCON 6.0E-4
294 void rkqc(Matrix & x, Matrix & dxdt, Real & t, Real htry,
295 Real eps, Matrix & xscal, Real & hdid, Real & hnext,
296 ReturnMatrix (*xdot)(Real time,
const Matrix & xin))
306 Real tsav, hh, h, temp, errmax;
307 Matrix dxsav, xsav, xtemp;
315 xtemp =
rk4(xsav,dxsav,tsav,hh,xdot);
317 dxdt = (*xdot)(t,xtemp);
318 x =
rk4(xtemp,dxdt,t,hh,xdot);
321 cerr <<
"Step size too small in routine RKQC\n";
324 xtemp =
rk4(xsav,dxsav,tsav,h,xdot);
327 for(
int i = 1; i <= x.Nrows(); i++) {
328 temp = fabs(xtemp(i,1)/xscal(i,1));
329 if(errmax < temp) errmax = temp;
334 hnext = (errmax > ERRCON ?
335 SAFETY*h*exp(PGROW*log(errmax)) : 4.0*h);
338 h = SAFETY*h*exp(PSHRNK*log(errmax));
346 void odeint(ReturnMatrix (*xdot)(Real time,
const Matrix & xin),
347 Matrix & xo, Real to, Real tf, Real eps, Real h1, Real hmin,
348 int & nok,
int & nbad,
349 RowVector & tout, Matrix & xout, Real dtsav)
360 Real tsav, t, hnext, hdid, h;
363 Matrix xscal, x, dxdt;
370 h = (tf > to) ? fabs(h1) : -fabs(h1);
374 for(
int nstp = 1; nstp <= MAXSTP; nstp++){
376 for(
int i = 1; i <= x.Nrows(); i++)
377 xscal(i,1) = fabs(x(i,1))+fabs(dxdt(i,1)*h)+TINY;
378 if((t+h-tf)*(t+h-to) > 0.0) h = tf-t;
379 rkqc(x,dxdt,t,h,eps,xscal,hdid,hnext,xdot);
380 if(hdid == h) ++(nok);
else ++(nbad);
381 if((t-tf)*(tf-to) >= 0.0) {
388 if(fabs(t-tsav) > fabs(dtsav)) {
394 if(fabs(hnext) <= hmin) {
395 cerr <<
"Step size too small in ODEINT\n";
396 cerr << setw(7) << setprecision(3) << (tout & xout).t();
401 cerr <<
"Too many step in routine ODEINT\n";
405 ReturnMatrix
sign(
const Matrix & x)
410 for(
int i = 1; i <= out.Ncols(); i++) {
411 for(
int j = 1; j <= out.Nrows(); j++) {
414 }
else if(out(j,i) < 0.0) {
420 out.Release();
return out;