ode 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Gem Version](https://badge.fury.io/rb/ode.svg)](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
|