num4simdiff 0.0.3 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/ext/num4simdiff/CNum4SimDiff.c +42 -39
- data/ext/num4simdiff/CNum4SimDiff.h +6 -8
- data/lib/num4simdiff.rb +74 -52
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 61244490a74e2b2b27f14967ce4d45cc073cfe2323021a488babcd39f921995b
|
4
|
+
data.tar.gz: 57b1d91fa1b8e7c1e0114eb749722f9a25a5bb60613608a4b5db30f8a375910a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f3f0e6cc7764903302b93212e93b58e46a04703950c229bb9e3775bf4cd28a90e1d8f18010f9007c25b762ce76c005f97bb1e19f45a46c4aa72c14c50819248b
|
7
|
+
data.tar.gz: f60265b9f41b006209937b8cf055ff7043658033dd66fc92c48f9e098fecbd599c8d5c9cd442dd98e002a251be422338bbbb6b20448c99eaa7a6217995b14bd0
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,22 @@
|
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
+
## [0.2.1] - 2023-05-08
|
6
|
+
|
7
|
+
### Fixed
|
8
|
+
- change cnvRbAry2pt to private
|
9
|
+
- change cnvPt2RbAry to private
|
10
|
+
|
11
|
+
## [0.1.1] - 2023-05-02
|
12
|
+
|
13
|
+
### Fixed
|
14
|
+
- Fix support function of multiple
|
15
|
+
|
16
|
+
## [0.0.3] - 2023-05-01
|
17
|
+
|
18
|
+
### Added
|
19
|
+
- add file of .yardopts
|
20
|
+
|
5
21
|
## [0.0.2] - 2023-04-30
|
6
22
|
|
7
23
|
### Added
|
@@ -4,9 +4,9 @@
|
|
4
4
|
#include <stdlib.h>
|
5
5
|
#include "CNum4SimDiff.h"
|
6
6
|
|
7
|
-
static double* CNum4SimDiff_doEulerMethod(
|
8
|
-
static double* CNum4SimDiff_doHeunMethod(
|
9
|
-
static double* CNum4SimDiff_doRungeKuttaMethod(
|
7
|
+
static double* CNum4SimDiff_doEulerMethod(int n, double *yi, double h, double *f);
|
8
|
+
static double* CNum4SimDiff_doHeunMethod(int n, double *yi, double h, double *f);
|
9
|
+
static double* CNum4SimDiff_doRungeKuttaMethod(int n, double *yi, double h, double *f);
|
10
10
|
static CNum4SimDiff _cNum4SiDiff = {
|
11
11
|
.FP_eulerMethod = CNum4SimDiff_doEulerMethod,
|
12
12
|
.FP_heunMethod = CNum4SimDiff_doHeunMethod,
|
@@ -18,26 +18,29 @@ static CNum4SimDiff _cNum4SiDiff = {
|
|
18
18
|
/**************************************/
|
19
19
|
/* Class部 */
|
20
20
|
/**************************************/
|
21
|
-
double* CNum4SimDiff_eulerMethod(
|
21
|
+
double* CNum4SimDiff_eulerMethod(int n, double *yi, double h, double *f)
|
22
22
|
{
|
23
|
-
assert(
|
24
|
-
assert(
|
23
|
+
assert(f != 0);
|
24
|
+
assert(yi != 0);
|
25
|
+
assert( n > 0);
|
25
26
|
|
26
|
-
return _cNum4SiDiff.FP_eulerMethod(
|
27
|
+
return _cNum4SiDiff.FP_eulerMethod(n, yi, h, f);
|
27
28
|
}
|
28
|
-
double* CNum4SimDiff_heunMethod(
|
29
|
+
double* CNum4SimDiff_heunMethod(int n, double *yi, double h, double *f)
|
29
30
|
{
|
30
|
-
assert(
|
31
|
-
assert(
|
31
|
+
assert(f != 0);
|
32
|
+
assert(yi != 0);
|
33
|
+
assert( n > 0);
|
32
34
|
|
33
|
-
return _cNum4SiDiff.FP_heunMethod(
|
35
|
+
return _cNum4SiDiff.FP_heunMethod(n, yi, h, f);
|
34
36
|
}
|
35
|
-
double* CNum4SimDiff_rungeKuttaMethod(
|
37
|
+
double* CNum4SimDiff_rungeKuttaMethod(int n, double *yi, double h, double *f)
|
36
38
|
{
|
37
|
-
assert(
|
38
|
-
assert(
|
39
|
+
assert(f != 0);
|
40
|
+
assert(yi != 0);
|
41
|
+
assert( n > 0);
|
39
42
|
|
40
|
-
return _cNum4SiDiff.FP_rungeKuttaMethod(
|
43
|
+
return _cNum4SiDiff.FP_rungeKuttaMethod(n, yi, h, f);
|
41
44
|
}
|
42
45
|
/**************************************/
|
43
46
|
/* 処理実行部 */
|
@@ -45,16 +48,14 @@ double* CNum4SimDiff_rungeKuttaMethod(double *yi, double xi, double h, Func func
|
|
45
48
|
/*
|
46
49
|
* オイラー法
|
47
50
|
*/
|
48
|
-
static double* CNum4SimDiff_doEulerMethod(
|
51
|
+
static double* CNum4SimDiff_doEulerMethod(int n, double *yi, double h, double *f)
|
49
52
|
{
|
50
53
|
int i;
|
51
|
-
double *
|
52
|
-
double *yi_1 = malloc(sizeof(double) * N);
|
54
|
+
double *yi_1 = malloc(sizeof(double) * n);
|
53
55
|
|
54
|
-
|
55
|
-
f[1] = func2(xi, yi[1]);
|
56
|
+
assert(yi_1 != 0);
|
56
57
|
// yi_1 = yi + h * f(xi, y)
|
57
|
-
for (i = 0; i <
|
58
|
+
for (i = 0; i < n; i++) {
|
58
59
|
yi_1[i] = yi[i] + h * f[i];
|
59
60
|
}
|
60
61
|
return yi_1;
|
@@ -62,43 +63,45 @@ static double* CNum4SimDiff_doEulerMethod(double *yi, double xi, double h, Func
|
|
62
63
|
/*
|
63
64
|
* ホイン法
|
64
65
|
*/
|
65
|
-
static double* CNum4SimDiff_doHeunMethod(
|
66
|
+
static double* CNum4SimDiff_doHeunMethod(int n, double *yi, double h, double *f)
|
66
67
|
{
|
67
68
|
int i;
|
68
|
-
double *
|
69
|
-
double *
|
70
|
-
double *
|
71
|
-
double *k2 = malloc(sizeof(double) * N);
|
69
|
+
double *yi_1 = malloc(sizeof(double) * n);
|
70
|
+
double *k1 = malloc(sizeof(double) * n);
|
71
|
+
double *k2 = malloc(sizeof(double) * n);
|
72
72
|
|
73
|
-
|
74
|
-
|
73
|
+
assert(yi_1 != 0);
|
74
|
+
assert(k1 != 0);
|
75
|
+
assert(k2 != 0);
|
75
76
|
// k1 = h * f(xi, y)
|
76
77
|
// k2 = h * f(xi + h, h * f(xi + h, yi + k1)
|
77
78
|
// yi_1 = yi + (k1 + k2) / 2.0;
|
78
|
-
for (i = 0; i <
|
79
|
+
for (i = 0; i < n; i++) {
|
79
80
|
k1[i] = h * f[i];
|
80
81
|
k2[i] = h * (yi[i] + k1[i]);
|
81
82
|
yi_1[i] = yi[i] + (k1[i] + k2[i]) / 2.0;
|
82
83
|
}
|
83
84
|
return yi_1;
|
84
85
|
}
|
85
|
-
static double* CNum4SimDiff_doRungeKuttaMethod(
|
86
|
+
static double* CNum4SimDiff_doRungeKuttaMethod(int n, double *yi, double h, double *f)
|
86
87
|
{
|
87
88
|
int i;
|
88
|
-
double *
|
89
|
-
double *
|
90
|
-
double *
|
91
|
-
double *
|
92
|
-
double *
|
93
|
-
double *k4 = malloc(sizeof(double) * N);
|
89
|
+
double *yi_1 = malloc(sizeof(double) * n);
|
90
|
+
double *k1 = malloc(sizeof(double) * n);
|
91
|
+
double *k2 = malloc(sizeof(double) * n);
|
92
|
+
double *k3 = malloc(sizeof(double) * n);
|
93
|
+
double *k4 = malloc(sizeof(double) * n);
|
94
94
|
|
95
|
-
|
96
|
-
|
95
|
+
assert(yi_1 != 0);
|
96
|
+
assert(k1 != 0);
|
97
|
+
assert(k2 != 0);
|
98
|
+
assert(k3 != 0);
|
99
|
+
assert(k4 != 0);
|
97
100
|
// k1 = h * f(xi, y)
|
98
101
|
// k2 = h * f(xi + h / 2, yi + k1 / 2)
|
99
102
|
// k3 = h * f(xi + h / 2, y1 + k2 / 2)
|
100
103
|
// k4 = h * f(xi + h, yi + k3)
|
101
|
-
for (i = 0; i <
|
104
|
+
for (i = 0; i < n; i++) {
|
102
105
|
k1[i] = h * f[i];
|
103
106
|
k2[i] = h * (yi[i] + k1[i] / 2.0);
|
104
107
|
k3[i] = h * (yi[i] + k2[i] / 2.0);
|
@@ -5,22 +5,20 @@
|
|
5
5
|
/* 構造体宣言 */
|
6
6
|
/**************************************/
|
7
7
|
typedef struct _CNum4SimDiff CNum4SimDiff;
|
8
|
-
typedef double (*Func)(double x, double dx);
|
9
8
|
|
10
9
|
struct _CNum4SimDiff
|
11
10
|
{
|
12
|
-
double* (*FP_eulerMethod)(
|
13
|
-
double* (*FP_heunMethod)(
|
14
|
-
double* (*FP_rungeKuttaMethod)(
|
11
|
+
double* (*FP_eulerMethod)(int n, double *yi, double h, double *f);
|
12
|
+
double* (*FP_heunMethod)(int n, double *yi, double h, double *f);
|
13
|
+
double* (*FP_rungeKuttaMethod)(int n, double *yi, double h, double *f);
|
15
14
|
};
|
16
15
|
/**************************************/
|
17
16
|
/* define宣言 */
|
18
17
|
/**************************************/
|
19
|
-
#define N 2
|
20
18
|
/**************************************/
|
21
19
|
/* プロトタイプ宣言 */
|
22
20
|
/**************************************/
|
23
|
-
double* CNum4SimDiff_eulerMethod(
|
24
|
-
double* CNum4SimDiff_heunMethod(
|
25
|
-
double* CNum4SimDiff_rungeKuttaMethod(
|
21
|
+
double* CNum4SimDiff_eulerMethod(int n, double *yi, double h, double *f);
|
22
|
+
double* CNum4SimDiff_heunMethod(int n, double *yi, double h, double *f);
|
23
|
+
double* CNum4SimDiff_rungeKuttaMethod(int n, double *yi, double h, double *f);
|
26
24
|
#endif
|
data/lib/num4simdiff.rb
CHANGED
@@ -6,77 +6,100 @@ module Num4SimDiffLib
|
|
6
6
|
extend FFI::Library
|
7
7
|
|
8
8
|
ffi_lib FFI::Compiler::Loader.find('num4simdiff')
|
9
|
-
|
10
|
-
# @overload f(x, dx)
|
11
|
-
# dy = f(x, dx)
|
12
|
-
# @yield [x, dx] dy = f(x, dx)
|
13
|
-
# @yieldparam [double] x xiの値
|
14
|
-
# @yieldparam [double] dx xiの値
|
15
|
-
# @return [double] xiに対するyの値
|
16
|
-
callback :f, [:double, :double], :double
|
17
|
-
|
18
9
|
attach_function :eulerMethodFFI,
|
19
|
-
:CNum4SimDiff_eulerMethod, [:
|
10
|
+
:CNum4SimDiff_eulerMethod, [:int, :buffer_in, :double, :buffer_in], :pointer
|
20
11
|
attach_function :heunMethodFFI,
|
21
|
-
:CNum4SimDiff_heunMethod, [:
|
12
|
+
:CNum4SimDiff_heunMethod, [:int, :buffer_in, :double, :buffer_in], :pointer
|
22
13
|
attach_function :rungeKuttaMethodFFI,
|
23
|
-
:CNum4SimDiff_rungeKuttaMethod, [:
|
14
|
+
:CNum4SimDiff_rungeKuttaMethod, [:int, :buffer_in, :double, :buffer_in], :pointer
|
24
15
|
class << self
|
25
16
|
#
|
26
17
|
# オイラー法による数値計算
|
27
|
-
# @overload eulerMethod(yi,
|
28
|
-
# yi_1 = eulerMethod(yi,
|
29
|
-
# @param [double] yi xiに対するyiの値(配列)
|
30
|
-
# @param [double] xi xiの値
|
18
|
+
# @overload eulerMethod(yi, h, func)
|
19
|
+
# yi_1 = eulerMethod(yi, h, func)
|
20
|
+
# @param [double[]] yi xiに対するyiの値(配列)
|
31
21
|
# @param [double] h 刻み幅
|
32
|
-
# @param [callback]
|
33
|
-
# @
|
34
|
-
#
|
22
|
+
# @param [callback] func xiに対する傾きを計算する関数
|
23
|
+
# @return [double[]] xi+hに対するyi_1の値(配列)
|
24
|
+
# @example
|
25
|
+
# func = Proc.new do | n, yi |
|
26
|
+
# f = []
|
27
|
+
# f[0] = yi[0]
|
28
|
+
# f[1] = yi[1]
|
29
|
+
# next f
|
30
|
+
# end
|
31
|
+
# yi = [1.0, 1.0]
|
32
|
+
# yi_1 = Num4SimDiffLib.eulerMethod(yi, 0.001, func)
|
35
33
|
#
|
36
|
-
def eulerMethod(yi,
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
34
|
+
def eulerMethod(yi, h, func)
|
35
|
+
n = yi.size
|
36
|
+
f = func.call(n, yi)
|
37
|
+
f_ptr = cnvRbAry2pt(n, f)
|
38
|
+
yi_ptr = cnvRbAry2pt(n, yi)
|
39
|
+
yi_1_ptr = eulerMethodFFI(n, yi_ptr, h, f_ptr)
|
40
|
+
yi_1 = cnvPt2RbAry(n, yi_1_ptr)
|
41
|
+
f_ptr.free()
|
42
|
+
return yi_1
|
41
43
|
end
|
42
44
|
#
|
43
45
|
# ホイン法による数値計算
|
44
|
-
# @overload heunMethod(yi,
|
45
|
-
# yi_1 = heunMethod(yi,
|
46
|
-
# @param [double] yi xiに対するyiの値(配列)
|
47
|
-
# @param [double] xi xiの値
|
46
|
+
# @overload heunMethod(yi, h, func)
|
47
|
+
# yi_1 = heunMethod(yi, h, func)
|
48
|
+
# @param [double[]] yi xiに対するyiの値(配列)
|
48
49
|
# @param [double] h 刻み幅
|
49
|
-
# @param [callback]
|
50
|
-
# @
|
51
|
-
#
|
50
|
+
# @param [callback] func xiに対する傾きを計算する関数
|
51
|
+
# @return [double[]] xi+hに対するyi_1の値(配列)
|
52
|
+
# @example
|
53
|
+
# func = Proc.new do | n, yi |
|
54
|
+
# f = []
|
55
|
+
# f[0] = yi[0]
|
56
|
+
# f[1] = yi[1]
|
57
|
+
# next f
|
58
|
+
# end
|
59
|
+
# yi = [1.0, 1.0]
|
60
|
+
# yi_1 = Num4SimDiffLib.heunMethod(yi, 0.001, func)
|
52
61
|
#
|
53
|
-
def heunMethod(yi,
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
62
|
+
def heunMethod(yi, h, func)
|
63
|
+
n = yi.size
|
64
|
+
f = func.call(n, yi)
|
65
|
+
f_ptr = cnvRbAry2pt(n, f)
|
66
|
+
yi_ptr = cnvRbAry2pt(n, yi)
|
67
|
+
yi_1_ptr = heunMethodFFI(n, yi_ptr, h, f_ptr)
|
68
|
+
yi_1 = cnvPt2RbAry(n, yi_1_ptr)
|
69
|
+
f_ptr.free()
|
70
|
+
return yi_1
|
58
71
|
end
|
59
72
|
#
|
60
73
|
# 4次のルンゲ=クッタ法による数値計算
|
61
|
-
# @overload rungeKuttaMethod(yi,
|
62
|
-
# yi_1 = rungeKuttaMethod(yi,
|
63
|
-
# @param [double] yi xiに対するyiの値(配列)
|
64
|
-
# @param [double] xi xiの値
|
74
|
+
# @overload rungeKuttaMethod(yi, h, func)
|
75
|
+
# yi_1 = rungeKuttaMethod(yi, h, func)
|
76
|
+
# @param [double[]] yi xiに対するyiの値(配列)
|
65
77
|
# @param [double] h 刻み幅
|
66
|
-
# @param [callback]
|
67
|
-
# @
|
68
|
-
#
|
78
|
+
# @param [callback] func xiに対する傾きを計算する関数
|
79
|
+
# @return [double[]] xi+hに対するyi_1の値(配列)
|
80
|
+
# @example
|
81
|
+
# func = Proc.new do | n, yi |
|
82
|
+
# f = []
|
83
|
+
# f[0] = yi[0]
|
84
|
+
# f[1] = yi[1]
|
85
|
+
# next f
|
86
|
+
# end
|
87
|
+
# yi = [1.0, 1.0]
|
88
|
+
# yi_1 = Num4SimDiffLib.rungeKuttaMethod(yi, 0.001, func)
|
69
89
|
#
|
70
|
-
def rungeKuttaMethod(yi,
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
90
|
+
def rungeKuttaMethod(yi, h, func)
|
91
|
+
n = yi.size
|
92
|
+
f = func.call(n, yi)
|
93
|
+
f_ptr = cnvRbAry2pt(n, f)
|
94
|
+
yi_ptr = cnvRbAry2pt(n, yi)
|
95
|
+
yi_1_ptr = rungeKuttaMethodFFI(n, yi_ptr, h, f_ptr)
|
96
|
+
yi_1 = cnvPt2RbAry(n, yi_1_ptr)
|
97
|
+
f_ptr.free()
|
98
|
+
return yi_1
|
75
99
|
end
|
76
100
|
|
77
101
|
#
|
78
102
|
# @private
|
79
|
-
#
|
80
103
|
def cnvRbAry2pt(n, ary)
|
81
104
|
yi_ptr = FFI::MemoryPointer.new(:double, n)
|
82
105
|
n.times.map { |i|
|
@@ -86,17 +109,16 @@ module Num4SimDiffLib
|
|
86
109
|
end
|
87
110
|
#
|
88
111
|
# @private
|
89
|
-
#
|
90
112
|
def cnvPt2RbAry(n, pt)
|
91
113
|
rbAry = n.times.map { |i|
|
92
114
|
pt.get_double(i * Fiddle::SIZEOF_DOUBLE)
|
93
115
|
}
|
94
116
|
return rbAry
|
95
117
|
end
|
118
|
+
private :cnvRbAry2pt
|
119
|
+
private :cnvPt2RbAry
|
96
120
|
private :eulerMethodFFI
|
97
121
|
private :heunMethodFFI
|
98
122
|
private :rungeKuttaMethodFFI
|
99
|
-
private :cnvRbAry2pt
|
100
|
-
private :cnvPt2RbAry
|
101
123
|
end
|
102
124
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: num4simdiff
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- siranovel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-05-
|
11
|
+
date: 2023-05-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi-compiler
|
@@ -70,10 +70,12 @@ licenses:
|
|
70
70
|
- MIT
|
71
71
|
metadata:
|
72
72
|
changelog_uri: http://github.com/siranovel/num4simdiffrent/blob/main/CHANGELOG.md
|
73
|
-
documentation_uri: https://rubydoc.info/gems/num4simdiff/0.
|
73
|
+
documentation_uri: https://rubydoc.info/gems/num4simdiff/0.2.1
|
74
74
|
homepage_uri: http://github.com/siranovel/num4simdiffrent
|
75
|
+
wiki_uri: https://github.com/siranovel/mydocs/tree/main/num4simdiff
|
75
76
|
post_install_message:
|
76
|
-
rdoc_options:
|
77
|
+
rdoc_options:
|
78
|
+
- "--no-private"
|
77
79
|
require_paths:
|
78
80
|
- lib
|
79
81
|
required_ruby_version: !ruby/object:Gem::Requirement
|