ode 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +37 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +17 -0
- data/MIT-License.txt +22 -0
- data/README.md +32 -0
- data/Rakefile +12 -0
- data/SciPy-License.txt +30 -0
- data/ext/ode/extconf.rb +25 -0
- data/ext/ode/ode.c +124 -0
- data/ext/ode/odepack.h +6 -0
- data/ext/ode/odepack/blkdta000.f +26 -0
- data/ext/ode/odepack/bnorm.f +30 -0
- data/ext/ode/odepack/cfode.f +112 -0
- data/ext/ode/odepack/ewset.f +32 -0
- data/ext/ode/odepack/fnorm.f +22 -0
- data/ext/ode/odepack/intdy.f +84 -0
- data/ext/ode/odepack/lsoda.f +1654 -0
- data/ext/ode/odepack/prja.f +177 -0
- data/ext/ode/odepack/readme +84 -0
- data/ext/ode/odepack/solsy.f +72 -0
- data/ext/ode/odepack/srcma.f +55 -0
- data/ext/ode/odepack/stoda.f +637 -0
- data/ext/ode/odepack/vmnorm.f +18 -0
- data/ext/ode/odepack/vode.f +3667 -0
- data/ext/ode/odepack/xerrwv.f +114 -0
- data/ext/ode/odepack/zvode.f +3658 -0
- data/lib/ode.rb +9 -0
- data/lib/ode/methods.rb +15 -0
- data/lib/ode/solver.rb +42 -0
- data/lib/ode/version.rb +3 -0
- data/ode.gemspec +23 -0
- metadata +105 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 268ad106e9a7617020dd7ee6d9cf540b694d2cfe
|
4
|
+
data.tar.gz: 5e8c6e7fc50b16cf2eee39142e8f72d5cc6998d2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 713a2c92a16b3e9200eab1ed5d2c19f16cd4d0983200ac9a2d754aacca88b2af05315d6277e3e7a0245108b21b809755b6e7fb12d45d5cd2f117fe9263ded02d
|
7
|
+
data.tar.gz: 6e9a85ea3afbd29063e43e25e01d3ac3d7f6becda3ee6ad0e5643d862f37151680947fc79042e90f09eb95ed4c28e0202cf4b66a2ec3fab90f0692e435481bdb
|
data/.gitignore
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
*.o
|
4
|
+
*~
|
5
|
+
*.so
|
6
|
+
/.config
|
7
|
+
/coverage/
|
8
|
+
/InstalledFiles
|
9
|
+
/pkg/
|
10
|
+
/spec/reports/
|
11
|
+
/test/tmp/
|
12
|
+
/test/version_tmp/
|
13
|
+
/tmp/
|
14
|
+
|
15
|
+
## Specific to RubyMotion:
|
16
|
+
.dat*
|
17
|
+
.repl_history
|
18
|
+
build/
|
19
|
+
|
20
|
+
## Documentation cache and generated files:
|
21
|
+
/.yardoc/
|
22
|
+
/_yardoc/
|
23
|
+
/doc/
|
24
|
+
/rdoc/
|
25
|
+
|
26
|
+
## Environment normalisation:
|
27
|
+
/.bundle/
|
28
|
+
/lib/bundler/man/
|
29
|
+
|
30
|
+
# for a library or gem, you might want to ignore these files since the code is
|
31
|
+
# intended to run in multiple environments; otherwise, check them in:
|
32
|
+
# Gemfile.lock
|
33
|
+
# .ruby-version
|
34
|
+
# .ruby-gemset
|
35
|
+
|
36
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
37
|
+
.rvmrc
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
data/MIT-License.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Naoki Nishida
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# Ode
|
2
|
+
|
3
|
+
[](http://badge.fury.io/rb/ode)
|
4
|
+
|
5
|
+
An ODE solver package for Ruby users.
|
6
|
+
Ode is a the wrapper for [ODEPACK](https://computation.llnl.gov/casc/odepack/) and may perform as well as scipy.integrate.odeint and other wrappers.
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
```
|
10
|
+
gem install ode
|
11
|
+
```
|
12
|
+
|
13
|
+
## Examples
|
14
|
+
```
|
15
|
+
require 'ode'
|
16
|
+
|
17
|
+
f = Proc.new{|t, y, fargs|
|
18
|
+
p, r, b = fargs[:p], fargs[:r], fargs[:b]
|
19
|
+
[ -p*y[0] + p*y[1],
|
20
|
+
-y[0]*y[2] + r*y[0] - y[1],
|
21
|
+
y[0]*y[1] - b*y[2]
|
22
|
+
]
|
23
|
+
}
|
24
|
+
|
25
|
+
solver = Ode::Solver.new(f).init(0, [0, 0, 0]).f_args({p: 10, r: 28, b: 8/3}).
|
26
|
+
solver.integrate(3.0) #integrate f from t=0 to t=3.0
|
27
|
+
```
|
28
|
+
|
29
|
+
## License
|
30
|
+
|
31
|
+
All files under ext/ode/odepack are from scipy.integrate (originally from ODEPACK), and distributed under [SciPy License](https://github.com/domitry/ode/blob/master/SciPy-License.txt).
|
32
|
+
All the other files are distributed under [the MIT License](https://github.com/domitry/ode/blob/master/MIT-License.txt).
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
require 'rake/extensiontask'
|
3
|
+
|
4
|
+
Bundler::GemHelper.install_tasks
|
5
|
+
Bundler.setup(:default, :development)
|
6
|
+
|
7
|
+
Rake::ExtensionTask.new do |ext|
|
8
|
+
ext.name = 'ode'
|
9
|
+
ext.ext_dir = 'ext/ode'
|
10
|
+
ext.lib_dir = 'lib'
|
11
|
+
ext.source_pattern = "**/*.{f, c, h}"
|
12
|
+
end
|
data/SciPy-License.txt
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
Copyright (c) 2001, 2002 Enthought, Inc.
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Copyright (c) 2003-2012 SciPy Developers.
|
5
|
+
All rights reserved.
|
6
|
+
|
7
|
+
Redistribution and use in source and binary forms, with or without
|
8
|
+
modification, are permitted provided that the following conditions are met:
|
9
|
+
|
10
|
+
a. Redistributions of source code must retain the above copyright notice,
|
11
|
+
this list of conditions and the following disclaimer.
|
12
|
+
b. Redistributions in binary form must reproduce the above copyright
|
13
|
+
notice, this list of conditions and the following disclaimer in the
|
14
|
+
documentation and/or other materials provided with the distribution.
|
15
|
+
c. Neither the name of Enthought nor the names of the SciPy Developers
|
16
|
+
may be used to endorse or promote products derived from this software
|
17
|
+
without specific prior written permission.
|
18
|
+
|
19
|
+
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
23
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
|
24
|
+
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
25
|
+
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
26
|
+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
27
|
+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
28
|
+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
29
|
+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
30
|
+
THE POSSIBILITY OF SUCH DAMAGE.
|
data/ext/ode/extconf.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'mkmf'
|
2
|
+
|
3
|
+
$DEBUG = true
|
4
|
+
$libs += " -llapack -lcblas -latlas"
|
5
|
+
|
6
|
+
$INSTALLFILES = [['odepack.h', '$(archdir)'], ['ode.so', '$(archdir)']]
|
7
|
+
|
8
|
+
path = File.expand_path("../odepack", __FILE__)
|
9
|
+
odepack_c = Dir::entries(path).select {|str| str =~ /(.+)\.f/}.map{|str| "odepack/"+str}
|
10
|
+
odepack_obj = odepack_c.map{|str| str.gsub(".f", ".o")}
|
11
|
+
other_c = %w{ode.c}
|
12
|
+
other_obj = other_c.map{|str| str.gsub(".c", ".o")}
|
13
|
+
|
14
|
+
$objs = odepack_obj + other_obj
|
15
|
+
$srcs = odepack_c + other_c
|
16
|
+
|
17
|
+
create_makefile("ode")
|
18
|
+
|
19
|
+
Dir.mkdir("odepack") unless Dir.exists?("odepack")
|
20
|
+
|
21
|
+
if $makefile_created
|
22
|
+
text = File.read("Makefile")
|
23
|
+
text.gsub!(".mm", ".f")
|
24
|
+
File.write("Makefile", text)
|
25
|
+
end
|
data/ext/ode/ode.c
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
#include "odepack.h"
|
2
|
+
#include <stdlib.h>
|
3
|
+
#include <ruby.h>
|
4
|
+
#include <stdio.h>
|
5
|
+
|
6
|
+
static int number_of_params;
|
7
|
+
static VALUE func_proc, jac_proc, f_args;
|
8
|
+
|
9
|
+
#define RESTORE_NEQ(neq) number_of_params=neq;
|
10
|
+
#define RESTORE_FUNC(func) func_proc=func;
|
11
|
+
#define RESTORE_JAC(func) jac_proc=func;
|
12
|
+
#define RESTORE_FARGS(args) f_args=args;
|
13
|
+
#define max(v1, v2) (v1 < v2 ? v2 : v1)
|
14
|
+
#define min(v1, v2) (v1 < v2 ? v1 : v2)
|
15
|
+
|
16
|
+
int ode_jacobian_function(int *n, double *t, double *y, int *ml, int *mu, double *pd, int *nrowpd){
|
17
|
+
return -1;
|
18
|
+
}
|
19
|
+
|
20
|
+
void ode_function(int *n, double *t, double *y, double *ydot){
|
21
|
+
VALUE y_arr = rb_ary_new2(number_of_params), ret;
|
22
|
+
int i;
|
23
|
+
|
24
|
+
for(i=0; i<number_of_params; i++)
|
25
|
+
rb_ary_store(y_arr, i, DBL2NUM(y[i]));
|
26
|
+
|
27
|
+
ret = rb_funcall(func_proc, rb_intern("call"), 3, DBL2NUM(*t), y_arr, f_args);
|
28
|
+
|
29
|
+
for(i=0; i<number_of_params; i++){
|
30
|
+
VALUE num = rb_ary_entry(ret, i);
|
31
|
+
ydot[i] = NUM2DBL(num);
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
VALUE excute_lsoda(VALUE self, VALUE t_out, VALUE func, VALUE jac, VALUE init_t, VALUE init_y, VALUE fargs, VALUE opts){
|
36
|
+
int itol; double rtol, atol;
|
37
|
+
int *iwork; double *rwork;
|
38
|
+
int lrw, liw;
|
39
|
+
int neq = RARRAY_LEN(init_y);
|
40
|
+
|
41
|
+
double *y = (double *)ALLOC_N(double, neq);
|
42
|
+
double t = NUM2DBL(init_t);
|
43
|
+
double tout = NUM2DBL(t_out);
|
44
|
+
|
45
|
+
int itask = 1; // run solver untill t == tout
|
46
|
+
int istate = 1; // this is the first call of the problem
|
47
|
+
int iopt = 0; // no optional inputs
|
48
|
+
|
49
|
+
int jt = 2; // jacobian type indicator. 1: user provides full jacobian. 2: interanally generated jacobian.
|
50
|
+
VALUE ret_arr = rb_ary_new2(neq);
|
51
|
+
double h0 = 0, hmax =0, hmin = 0;
|
52
|
+
int ixpr=0, max_step=0, max_hnil=0, max_ordn=12, max_ords=5;
|
53
|
+
int i;
|
54
|
+
|
55
|
+
RESTORE_NEQ(neq)
|
56
|
+
RESTORE_FUNC(func)
|
57
|
+
RESTORE_FARGS(fargs)
|
58
|
+
|
59
|
+
for(i=0; i<neq; i++){
|
60
|
+
y[i] = NUM2DBL(rb_ary_entry(init_y, i));
|
61
|
+
}
|
62
|
+
|
63
|
+
// parse options (TODO: accept array)
|
64
|
+
itol = NUM2INT(rb_hash_lookup(opts, ID2SYM(rb_intern("itol"))));
|
65
|
+
|
66
|
+
rtol = NUM2DBL(rb_hash_aref(opts, ID2SYM(rb_intern("rtol"))));
|
67
|
+
atol = NUM2DBL(rb_hash_aref(opts, ID2SYM(rb_intern("atol"))));
|
68
|
+
|
69
|
+
// decide lrw, liw
|
70
|
+
liw = 20 + neq;
|
71
|
+
iwork = (int *)ALLOC_N(int, liw);
|
72
|
+
|
73
|
+
if(jac != Qnil){
|
74
|
+
jt = 1;
|
75
|
+
RESTORE_JAC(jac);
|
76
|
+
lrw = max(20+16*neq, 22+9*neq+neq*neq);
|
77
|
+
}
|
78
|
+
else{
|
79
|
+
int ml=0, mu=0; VALUE val;
|
80
|
+
if(val = rb_hash_aref(opts, ID2SYM(rb_intern("ml"))) != Qnil)ml = NUM2INT(val);
|
81
|
+
if(val = rb_hash_aref(opts, ID2SYM(rb_intern("mu"))) != Qnil)mu = NUM2INT(val);
|
82
|
+
|
83
|
+
iwork[0] = mu;
|
84
|
+
iwork[1] = ml;
|
85
|
+
lrw = max(20+16*neq, 22+10*neq+(2*ml+mu)*neq);
|
86
|
+
}
|
87
|
+
|
88
|
+
rwork = (double *)ALLOC_N(double, lrw);
|
89
|
+
rwork[4] = h0;
|
90
|
+
rwork[5] = hmax;
|
91
|
+
rwork[6] = hmin;
|
92
|
+
|
93
|
+
iwork[4] = ixpr;
|
94
|
+
iwork[5] = max_step;
|
95
|
+
iwork[6] = max_hnil;
|
96
|
+
iwork[7] = max_ordn;
|
97
|
+
iwork[8] = max_ords;
|
98
|
+
|
99
|
+
// run lsoda
|
100
|
+
lsoda_(ode_function, &neq, y, &t, &tout, &itol, &rtol, &atol, &itask, &istate, &iopt, rwork, &lrw, iwork, &liw, ode_jacobian_function, &jt);
|
101
|
+
|
102
|
+
// check error
|
103
|
+
if(istate<0){
|
104
|
+
rb_raise(rb_eTypeError, "Something went wrong.");
|
105
|
+
}
|
106
|
+
|
107
|
+
for(i=0; i<neq; i++){
|
108
|
+
VALUE num = DBL2NUM(y[i]);
|
109
|
+
rb_ary_store(ret_arr, i, num);
|
110
|
+
}
|
111
|
+
|
112
|
+
xfree(y);
|
113
|
+
xfree(iwork);
|
114
|
+
xfree(rwork);
|
115
|
+
return ret_arr;
|
116
|
+
}
|
117
|
+
|
118
|
+
|
119
|
+
void Init_ode(){
|
120
|
+
VALUE ode = rb_define_module("Ode");
|
121
|
+
VALUE methods = rb_define_module_under(ode, "Methods");
|
122
|
+
|
123
|
+
rb_define_singleton_method(methods, "lsoda", excute_lsoda, 7);
|
124
|
+
}
|
data/ext/ode/odepack.h
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
void lsoda_(void (*f)(int*, double*, double*, double*), int *neq, double *y, double *t, double *tout, int *itol, double *rtol, double *atol, int *itask, int *istate, int *iopt, double *rwork, int *lrw, int *iwork, int *liw, int (*jac)(int*, double*, double*, int*, int*, double*, int*), int *jt);
|
2
|
+
|
3
|
+
/*int itol = 2; // indicator for error control
|
4
|
+
double rtol = 1e-4; // relative error tolerance parameter (scalar or array)
|
5
|
+
double atol[3] = {1e-6, 1e-10, 1e-6}; // absolute error tolerance parameter (scalar or array)
|
6
|
+
*/
|
@@ -0,0 +1,26 @@
|
|
1
|
+
block data
|
2
|
+
c-----------------------------------------------------------------------
|
3
|
+
c this data subprogram loads variables into the internal common
|
4
|
+
c blocks used by the odepack solvers. the variables are
|
5
|
+
c defined as follows..
|
6
|
+
c illin = counter for the number of consecutive times the package
|
7
|
+
c was called with illegal input. the run is stopped when
|
8
|
+
c illin reaches 5.
|
9
|
+
c ntrep = counter for the number of consecutive times the package
|
10
|
+
c was called with istate = 1 and tout = t. the run is
|
11
|
+
c stopped when ntrep reaches 5.
|
12
|
+
c mesflg = flag to control printing of error messages. 1 means print,
|
13
|
+
c 0 means no printing.
|
14
|
+
c lunit = default value of logical unit number for printing of error
|
15
|
+
c messages.
|
16
|
+
c-----------------------------------------------------------------------
|
17
|
+
integer illin, iduma, ntrep, idumb, iowns, icomm, mesflg, lunit
|
18
|
+
double precision rowns, rcomm
|
19
|
+
common /ls0001/ rowns(209), rcomm(9),
|
20
|
+
1 illin, iduma(10), ntrep, idumb(2), iowns(6), icomm(19)
|
21
|
+
common /eh0001/ mesflg, lunit
|
22
|
+
data illin/0/, ntrep/0/
|
23
|
+
data mesflg/1/, lunit/6/
|
24
|
+
c
|
25
|
+
c----------------------- end of block data -----------------------------
|
26
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
double precision function bnorm (n, a, nra, ml, mu, w)
|
2
|
+
clll. optimize
|
3
|
+
c-----------------------------------------------------------------------
|
4
|
+
c this function computes the norm of a banded n by n matrix,
|
5
|
+
c stored in the array a, that is consistent with the weighted max-norm
|
6
|
+
c on vectors, with weights stored in the array w.
|
7
|
+
c ml and mu are the lower and upper half-bandwidths of the matrix.
|
8
|
+
c nra is the first dimension of the a array, nra .ge. ml+mu+1.
|
9
|
+
c in terms of the matrix elements a(i,j), the norm is given by..
|
10
|
+
c bnorm = max(i=1,...,n) ( w(i) * sum(j=1,...,n) abs(a(i,j))/w(j) )
|
11
|
+
c-----------------------------------------------------------------------
|
12
|
+
integer n, nra, ml, mu
|
13
|
+
integer i, i1, jlo, jhi, j
|
14
|
+
double precision a, w
|
15
|
+
double precision an, sum
|
16
|
+
dimension a(nra,n), w(n)
|
17
|
+
an = 0.0d0
|
18
|
+
do 20 i = 1,n
|
19
|
+
sum = 0.0d0
|
20
|
+
i1 = i + mu + 1
|
21
|
+
jlo = max0(i-ml,1)
|
22
|
+
jhi = min0(i+mu,n)
|
23
|
+
do 10 j = jlo,jhi
|
24
|
+
10 sum = sum + dabs(a(i1-j,j))/w(j)
|
25
|
+
an = dmax1(an,sum*w(i))
|
26
|
+
20 continue
|
27
|
+
bnorm = an
|
28
|
+
return
|
29
|
+
c----------------------- end of function bnorm -------------------------
|
30
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
subroutine cfode (meth, elco, tesco)
|
2
|
+
clll. optimize
|
3
|
+
integer meth
|
4
|
+
integer i, ib, nq, nqm1, nqp1
|
5
|
+
double precision elco, tesco
|
6
|
+
double precision agamq, fnq, fnqm1, pc, pint, ragq,
|
7
|
+
1 rqfac, rq1fac, tsign, xpin
|
8
|
+
dimension elco(13,12), tesco(3,12)
|
9
|
+
c-----------------------------------------------------------------------
|
10
|
+
c cfode is called by the integrator routine to set coefficients
|
11
|
+
c needed there. the coefficients for the current method, as
|
12
|
+
c given by the value of meth, are set for all orders and saved.
|
13
|
+
c the maximum order assumed here is 12 if meth = 1 and 5 if meth = 2.
|
14
|
+
c (a smaller value of the maximum order is also allowed.)
|
15
|
+
c cfode is called once at the beginning of the problem,
|
16
|
+
c and is not called again unless and until meth is changed.
|
17
|
+
c
|
18
|
+
c the elco array contains the basic method coefficients.
|
19
|
+
c the coefficients el(i), 1 .le. i .le. nq+1, for the method of
|
20
|
+
c order nq are stored in elco(i,nq). they are given by a genetrating
|
21
|
+
c polynomial, i.e.,
|
22
|
+
c l(x) = el(1) + el(2)*x + ... + el(nq+1)*x**nq.
|
23
|
+
c for the implicit adams methods, l(x) is given by
|
24
|
+
c dl/dx = (x+1)*(x+2)*...*(x+nq-1)/factorial(nq-1), l(-1) = 0.
|
25
|
+
c for the bdf methods, l(x) is given by
|
26
|
+
c l(x) = (x+1)*(x+2)* ... *(x+nq)/k,
|
27
|
+
c where k = factorial(nq)*(1 + 1/2 + ... + 1/nq).
|
28
|
+
c
|
29
|
+
c the tesco array contains test constants used for the
|
30
|
+
c local error test and the selection of step size and/or order.
|
31
|
+
c at order nq, tesco(k,nq) is used for the selection of step
|
32
|
+
c size at order nq - 1 if k = 1, at order nq if k = 2, and at order
|
33
|
+
c nq + 1 if k = 3.
|
34
|
+
c-----------------------------------------------------------------------
|
35
|
+
dimension pc(12)
|
36
|
+
c
|
37
|
+
go to (100, 200), meth
|
38
|
+
c
|
39
|
+
100 elco(1,1) = 1.0d0
|
40
|
+
elco(2,1) = 1.0d0
|
41
|
+
tesco(1,1) = 0.0d0
|
42
|
+
tesco(2,1) = 2.0d0
|
43
|
+
tesco(1,2) = 1.0d0
|
44
|
+
tesco(3,12) = 0.0d0
|
45
|
+
pc(1) = 1.0d0
|
46
|
+
rqfac = 1.0d0
|
47
|
+
do 140 nq = 2,12
|
48
|
+
c-----------------------------------------------------------------------
|
49
|
+
c the pc array will contain the coefficients of the polynomial
|
50
|
+
c p(x) = (x+1)*(x+2)*...*(x+nq-1).
|
51
|
+
c initially, p(x) = 1.
|
52
|
+
c-----------------------------------------------------------------------
|
53
|
+
rq1fac = rqfac
|
54
|
+
rqfac = rqfac/dfloat(nq)
|
55
|
+
nqm1 = nq - 1
|
56
|
+
fnqm1 = dfloat(nqm1)
|
57
|
+
nqp1 = nq + 1
|
58
|
+
c form coefficients of p(x)*(x+nq-1). ----------------------------------
|
59
|
+
pc(nq) = 0.0d0
|
60
|
+
do 110 ib = 1,nqm1
|
61
|
+
i = nqp1 - ib
|
62
|
+
110 pc(i) = pc(i-1) + fnqm1*pc(i)
|
63
|
+
pc(1) = fnqm1*pc(1)
|
64
|
+
c compute integral, -1 to 0, of p(x) and x*p(x). -----------------------
|
65
|
+
pint = pc(1)
|
66
|
+
xpin = pc(1)/2.0d0
|
67
|
+
tsign = 1.0d0
|
68
|
+
do 120 i = 2,nq
|
69
|
+
tsign = -tsign
|
70
|
+
pint = pint + tsign*pc(i)/dfloat(i)
|
71
|
+
120 xpin = xpin + tsign*pc(i)/dfloat(i+1)
|
72
|
+
c store coefficients in elco and tesco. --------------------------------
|
73
|
+
elco(1,nq) = pint*rq1fac
|
74
|
+
elco(2,nq) = 1.0d0
|
75
|
+
do 130 i = 2,nq
|
76
|
+
130 elco(i+1,nq) = rq1fac*pc(i)/dfloat(i)
|
77
|
+
agamq = rqfac*xpin
|
78
|
+
ragq = 1.0d0/agamq
|
79
|
+
tesco(2,nq) = ragq
|
80
|
+
if (nq .lt. 12) tesco(1,nqp1) = ragq*rqfac/dfloat(nqp1)
|
81
|
+
tesco(3,nqm1) = ragq
|
82
|
+
140 continue
|
83
|
+
return
|
84
|
+
c
|
85
|
+
200 pc(1) = 1.0d0
|
86
|
+
rq1fac = 1.0d0
|
87
|
+
do 230 nq = 1,5
|
88
|
+
c-----------------------------------------------------------------------
|
89
|
+
c the pc array will contain the coefficients of the polynomial
|
90
|
+
c p(x) = (x+1)*(x+2)*...*(x+nq).
|
91
|
+
c initially, p(x) = 1.
|
92
|
+
c-----------------------------------------------------------------------
|
93
|
+
fnq = dfloat(nq)
|
94
|
+
nqp1 = nq + 1
|
95
|
+
c form coefficients of p(x)*(x+nq). ------------------------------------
|
96
|
+
pc(nqp1) = 0.0d0
|
97
|
+
do 210 ib = 1,nq
|
98
|
+
i = nq + 2 - ib
|
99
|
+
210 pc(i) = pc(i-1) + fnq*pc(i)
|
100
|
+
pc(1) = fnq*pc(1)
|
101
|
+
c store coefficients in elco and tesco. --------------------------------
|
102
|
+
do 220 i = 1,nqp1
|
103
|
+
220 elco(i,nq) = pc(i)/pc(2)
|
104
|
+
elco(2,nq) = 1.0d0
|
105
|
+
tesco(1,nq) = rq1fac
|
106
|
+
tesco(2,nq) = dfloat(nqp1)/elco(1,nq)
|
107
|
+
tesco(3,nq) = dfloat(nq+2)/elco(1,nq)
|
108
|
+
rq1fac = rq1fac/fnq
|
109
|
+
230 continue
|
110
|
+
return
|
111
|
+
c----------------------- end of subroutine cfode -----------------------
|
112
|
+
end
|