4 Adapted from iDMC, Copyright (C) 2004-2006 Marji Lines and Alfredo Medio
5 Copyright (C) 2006,2007 Marji Lines and Alfredo Medio.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or any
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
21 #include <gsl/gsl_block.h>
22 #include <gsl/gsl_vector.h>
23 #include <gsl/gsl_matrix.h>
24 #include <gsl/gsl_blas.h>
25 #include <gsl/gsl_linalg.h>
26 #include <gsl/gsl_odeiv.h>
41 typedef struct combined Combined
;
43 int func(double t
,const double y
[],double f
[],void* params
){
45 Combined
* c
=(Combined
*) params
;
46 status
=idmc_model_f((*c
).model
,(*c
).pars
,y
,f
);
53 inline int func_jac(double t
,double* y
,double* f
,Combined
* params
){
55 Combined
* par
=(Combined
*) params
;
56 status
=idmc_model_Jf((*par
).model
,(*par
).pars
,y
,f
);
63 //(*c).draft should hold dim*dim
64 inline int interpolated_jac(Combined
* c
, double t0
, double* y0
, double t1
, double* y1
, double t
, double f
[])
68 double* draft
=(*c
).draft1
;//(double*) malloc(dim*dim*sizeof(double));
69 //assumes that y0 y1 hold dim elements each
76 status1
=func_jac(t0
,y0
,f
,c
);
77 status2
=func_jac(t1
,y1
,draft
,c
);
79 gsl_matrix_view m1v
= gsl_matrix_view_array(draft
,dim
,dim
);
80 gsl_matrix_view m0v
= gsl_matrix_view_array(f
,dim
,dim
);
81 gsl_matrix_scale(&m1v
.matrix
,a
);
82 gsl_matrix_scale(&m0v
.matrix
,1-a
);
83 gsl_matrix_add(&m0v
.matrix
,&m1v
.matrix
);
84 if (status1
==GSL_SUCCESS
&& status2
==GSL_SUCCESS
)
90 // (*c).data is 2dim+2, (*c).draft should hold 5*dim*dim (sizeof(double))
91 int Qsystem (double t
, const double Q
[], double RHS
[], void *params
)
94 Combined
* c
=(Combined
*) params
;
98 double* ptr
=(*c
).data
;
101 double tt1
=*(ptr
+dim
+1);
102 double* yy1
=ptr
+(dim
+2);
105 double* draft
=(*c
).draft2
;//(double*) malloc(4*dim*dim*sizeof(double));
108 status
=interpolated_jac(c
,tt0
, yy0
, tt1
, yy1
, t
, Jac
);
111 transpose(Q
,Qt
,dim
,dim
);
114 mmproduct(Jac
,Q
,tmp1
,dim
,dim
,dim
);
115 double* tmp2
=tmp1
+dd
;
116 mmproduct(Qt
,tmp1
,tmp2
,dim
,dim
,dim
);
118 mmproduct(Q
,tmp2
,RHS
,dim
,dim
,dim
);
120 if (status
==GSL_SUCCESS
)
123 return GSL_SUCCESS
-1;
126 inline int elementary_step(Combined
* c
, double step
, gsl_odeiv_step
* ode_step
, gsl_odeiv_step
* Q_step
, gsl_odeiv_system
* sys
,
127 double* t
, double* y
, double* Q
, double* l
, double* y_err
, double* Q_err
){
128 int status1
,status2
,status3
;
141 memcpy((*c
).data
+1,y
,dim
*sizeof(double));
144 status1
= gsl_odeiv_step_apply (ode_step
, *t
, step
, y
, y_err
, NULL
, NULL
, sys
);
146 *((*c
).data
+dim
+1)=*t
+step
;
147 memcpy((*c
).data
+dim
+2,y
,dim
*sizeof(double));
149 gsl_odeiv_system Q_sys
={Qsystem
, NULL
,dim
*dim
, c
};
151 status2
= gsl_odeiv_step_apply (Q_step
, *t
, step
, Q
, Q_err
, NULL
, NULL
, &Q_sys
);
154 double* draft
=(*c
).draft3
;//(double*) malloc((6*dd+dim)*sizeof(double));
163 memcpy(Qcopy
,Q
,dd
*sizeof(double));
164 qr_coded( Qcopy
, tmp1
, dim
,dim
);
165 qr_decomp(Qcopy
, tmp1
, Q
, R
,dim
,dim
);
167 status3
=idmc_model_Jf((*c
).model
,(*c
).pars
,y
,Jac
);
168 transpose(Q
,Qt
,dim
,dim
);
169 mmproduct(Qt
,Jac
,QtJ
,dim
,dim
,dim
);
170 mmproduct(QtJ
,Q
,QtJQ
,dim
,dim
,dim
);
171 gsl_vector_view lv
=gsl_vector_view_array(l
,dim
);
172 gsl_matrix_view QtJQv
=gsl_matrix_view_array(QtJQ
,dim
,dim
);
173 gsl_vector_view diagv
=gsl_matrix_diagonal(&QtJQv
.matrix
);
174 gsl_vector_scale(&diagv
.vector
,step
);
175 gsl_vector_add(&lv
.vector
,&diagv
.vector
);
177 if (status1
==GSL_SUCCESS
&& status2
==GSL_SUCCESS
&& status3
==IDMC_OK
)
180 return GSL_SUCCESS
-1;
184 inline int time_plot_step(idmc_model
* model
, int dim
, double step
, double* t
, double* pars
,
185 double* y
, double* Q
, double* l
, double* alloc_memory
){
191 const gsl_odeiv_step_type
* step_type
= gsl_odeiv_step_rk2
;
193 gsl_odeiv_step
* ode_step
=gsl_odeiv_step_alloc (step_type
, dim
);
194 gsl_odeiv_step
* Q_step
=gsl_odeiv_step_alloc (step_type
, dim
*dim
);
196 gsl_vector_view lv
=gsl_vector_view_array(l
,dim
);
198 gsl_vector_set_zero(&lv
.vector
);
200 double* work_space
=alloc_memory
;
201 double* y_err
=work_space
;
203 double* Q_err
=y_err
+dim
;
204 double* point_pair
=Q_err
+dd
;
206 double* draft1
=alloc_memory
+3*dim
+2+2*dd
;
207 double* draft2
=draft1
+dd
;
208 double* draft3
=draft2
+4*dd
;
209 gsl_matrix_view Qv
=gsl_matrix_view_array(Q
,dim
,dim
);
211 gsl_matrix_set_identity(&Qv
.matrix
);
221 gsl_odeiv_system sys
= {func
, NULL
, dim
, &c
};
223 s
=elementary_step(&c
, step
, ode_step
, Q_step
, &sys
, t
, y
, Q
, l
, y_err
, Q_err
);
228 gsl_odeiv_step_free(ode_step
);
229 gsl_odeiv_step_free(Q_step
);
233 //y0=y, t0=0, t1 is the final time, l is the array containing the Lyap.exps.
234 inline int compute_lexp(idmc_model
* model
, double* par
, int dim
,
235 double step
, double* y
, double t1
, double* l
, double* alloc_memory
){
241 const gsl_odeiv_step_type
* step_type
= gsl_odeiv_step_rk2
;
243 gsl_odeiv_step
* ode_step
=gsl_odeiv_step_alloc (step_type
, dim
);
244 gsl_odeiv_step
* Q_step
=gsl_odeiv_step_alloc (step_type
, dim
*dim
);
248 gsl_vector_view lv
=gsl_vector_view_array(l
,dim
);
249 gsl_vector_set_zero(&lv
.vector
);
251 double* work_space
=alloc_memory
;
252 double* y_err
=work_space
;
256 double* point_pair
=Q_err
+dd
;
258 double* draft1
=alloc_memory
+3*dim
+2+2*dd
;
259 double* draft2
=draft1
+dd
;
260 double* draft3
=draft2
+4*dd
;
262 gsl_matrix_view Qv
=gsl_matrix_view_array(Q
,dim
,dim
);
263 gsl_matrix_set_identity(&Qv
.matrix
);
273 gsl_odeiv_system sys
= {func
, NULL
, dim
, &c
};
276 s
= elementary_step(&c
, step
, ode_step
, Q_step
, &sys
, &t
,
277 y
, Q
, l
, y_err
, Q_err
);
282 gsl_vector_scale(&lv
.vector
,1/(t1
+step
));//if t1 is set to zero, does not give an error
283 gsl_odeiv_step_free (ode_step
);
284 gsl_odeiv_step_free (Q_step
);