num4simdiff 0.0.2 → 0.1.1
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 +4 -4
- data/.yardopts +1 -0
- data/CHANGELOG.md +10 -0
- data/ext/num4simdiff/CNum4SimDiff.c +42 -39
- data/ext/num4simdiff/CNum4SimDiff.h +9 -8
- data/lib/num4simdiff.rb +62 -52
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bbcf09943d885f3b0cbf0a59397859d39fbb8b74073952b3886e5103da0764d5
|
4
|
+
data.tar.gz: 5332e037a491ffcf970aa863eb5310d57db35c9e29fdbf3795f9585bab67e086
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6fbc94177cb48dbb77ce6d173309f132647f70ee42ca03d79ade6033d8e034cbad53288a869e4afacd2db56133425870f55e578a67b44bcc16b6cd0f8dfb43b6
|
7
|
+
data.tar.gz: 50688bd54df072e060cf2e503de3d9016e8743ca8d9e39c63c1c5c792f060e40c18d9607cb78c11515e9514b3dce303187c75c20507a292cdcfd0391b59d153b
|
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--no-private
|
data/CHANGELOG.md
CHANGED
@@ -4,10 +4,12 @@
|
|
4
4
|
#include <stdlib.h>
|
5
5
|
#include "CNum4SimDiff.h"
|
6
6
|
|
7
|
-
static double*
|
8
|
-
static double*
|
9
|
-
static double*
|
7
|
+
static double* CNum4SimDiff_doDmy(int n, double *yi, double h, Func func);
|
8
|
+
static double* CNum4SimDiff_doEulerMethod(int n, double *yi, double h, Func func);
|
9
|
+
static double* CNum4SimDiff_doHeunMethod(int n, double *yi, double h, Func func);
|
10
|
+
static double* CNum4SimDiff_doRungeKuttaMethod(int n, double *yi, double h, Func func);
|
10
11
|
static CNum4SimDiff _cNum4SiDiff = {
|
12
|
+
.FP_dmy = CNum4SimDiff_doDmy,
|
11
13
|
.FP_eulerMethod = CNum4SimDiff_doEulerMethod,
|
12
14
|
.FP_heunMethod = CNum4SimDiff_doHeunMethod,
|
13
15
|
.FP_rungeKuttaMethod = CNum4SimDiff_doRungeKuttaMethod,
|
@@ -18,43 +20,48 @@ static CNum4SimDiff _cNum4SiDiff = {
|
|
18
20
|
/**************************************/
|
19
21
|
/* Class部 */
|
20
22
|
/**************************************/
|
21
|
-
double*
|
23
|
+
double* CNum4SimDiff_dmy(int n, double *yi, double h, Func func)
|
22
24
|
{
|
23
|
-
assert(
|
24
|
-
assert(func2 != 0);
|
25
|
+
assert(func != 0);
|
25
26
|
|
26
|
-
return _cNum4SiDiff.
|
27
|
+
return _cNum4SiDiff.FP_dmy(n, yi, h, func);
|
27
28
|
}
|
28
|
-
double*
|
29
|
+
double* CNum4SimDiff_eulerMethod(int n, double *yi, double h, Func func)
|
29
30
|
{
|
30
|
-
assert(
|
31
|
-
assert(func2 != 0);
|
31
|
+
assert(func != 0);
|
32
32
|
|
33
|
-
return _cNum4SiDiff.
|
33
|
+
return _cNum4SiDiff.FP_eulerMethod(n, yi, h, func);
|
34
34
|
}
|
35
|
-
double*
|
35
|
+
double* CNum4SimDiff_heunMethod(int n, double *yi, double h, Func func)
|
36
36
|
{
|
37
|
-
assert(
|
38
|
-
assert(func2 != 0);
|
37
|
+
assert(func != 0);
|
39
38
|
|
40
|
-
return _cNum4SiDiff.
|
39
|
+
return _cNum4SiDiff.FP_heunMethod(n, yi, h, func);
|
40
|
+
}
|
41
|
+
double* CNum4SimDiff_rungeKuttaMethod(int n, double *yi, double h, Func func)
|
42
|
+
{
|
43
|
+
assert(func != 0);
|
44
|
+
|
45
|
+
return _cNum4SiDiff.FP_rungeKuttaMethod(n, yi, h, func);
|
41
46
|
}
|
42
47
|
/**************************************/
|
43
48
|
/* 処理実行部 */
|
44
49
|
/**************************************/
|
50
|
+
static double* CNum4SimDiff_doDmy(int n, double *yi, double h, Func func)
|
51
|
+
{
|
52
|
+
return func(2, yi);
|
53
|
+
}
|
45
54
|
/*
|
46
55
|
* オイラー法
|
47
56
|
*/
|
48
|
-
static double* CNum4SimDiff_doEulerMethod(
|
57
|
+
static double* CNum4SimDiff_doEulerMethod(int n, double *yi, double h, Func func)
|
49
58
|
{
|
50
59
|
int i;
|
51
|
-
double *f =
|
52
|
-
double *yi_1 = malloc(sizeof(double) *
|
60
|
+
double *f = func(n, yi);
|
61
|
+
double *yi_1 = malloc(sizeof(double) * n);
|
53
62
|
|
54
|
-
f[0] = func1(xi, yi[1]);
|
55
|
-
f[1] = func2(xi, yi[1]);
|
56
63
|
// yi_1 = yi + h * f(xi, y)
|
57
|
-
for (i = 0; i <
|
64
|
+
for (i = 0; i < n; i++) {
|
58
65
|
yi_1[i] = yi[i] + h * f[i];
|
59
66
|
}
|
60
67
|
return yi_1;
|
@@ -62,43 +69,39 @@ static double* CNum4SimDiff_doEulerMethod(double *yi, double xi, double h, Func
|
|
62
69
|
/*
|
63
70
|
* ホイン法
|
64
71
|
*/
|
65
|
-
static double* CNum4SimDiff_doHeunMethod(
|
72
|
+
static double* CNum4SimDiff_doHeunMethod(int n, double *yi, double h, Func func)
|
66
73
|
{
|
67
74
|
int i;
|
68
|
-
double *f =
|
69
|
-
double *yi_1 = malloc(sizeof(double) *
|
70
|
-
double *k1 = malloc(sizeof(double) *
|
71
|
-
double *k2 = malloc(sizeof(double) *
|
75
|
+
double *f = func(n, yi);
|
76
|
+
double *yi_1 = malloc(sizeof(double) * n);
|
77
|
+
double *k1 = malloc(sizeof(double) * n);
|
78
|
+
double *k2 = malloc(sizeof(double) * n);
|
72
79
|
|
73
|
-
f[0] = func1(xi, yi[1]);
|
74
|
-
f[1] = func2(xi, yi[1]);
|
75
80
|
// k1 = h * f(xi, y)
|
76
81
|
// k2 = h * f(xi + h, h * f(xi + h, yi + k1)
|
77
82
|
// yi_1 = yi + (k1 + k2) / 2.0;
|
78
|
-
for (i = 0; i <
|
83
|
+
for (i = 0; i < n; i++) {
|
79
84
|
k1[i] = h * f[i];
|
80
85
|
k2[i] = h * (yi[i] + k1[i]);
|
81
86
|
yi_1[i] = yi[i] + (k1[i] + k2[i]) / 2.0;
|
82
87
|
}
|
83
88
|
return yi_1;
|
84
89
|
}
|
85
|
-
static double* CNum4SimDiff_doRungeKuttaMethod(
|
90
|
+
static double* CNum4SimDiff_doRungeKuttaMethod(int n, double *yi, double h, Func func)
|
86
91
|
{
|
87
92
|
int i;
|
88
|
-
double *f =
|
89
|
-
double *yi_1 = malloc(sizeof(double) *
|
90
|
-
double *k1 = malloc(sizeof(double) *
|
91
|
-
double *k2 = malloc(sizeof(double) *
|
92
|
-
double *k3 = malloc(sizeof(double) *
|
93
|
-
double *k4 = malloc(sizeof(double) *
|
93
|
+
double *f = func(n, yi);
|
94
|
+
double *yi_1 = malloc(sizeof(double) * n);
|
95
|
+
double *k1 = malloc(sizeof(double) * n);
|
96
|
+
double *k2 = malloc(sizeof(double) * n);
|
97
|
+
double *k3 = malloc(sizeof(double) * n);
|
98
|
+
double *k4 = malloc(sizeof(double) * n);
|
94
99
|
|
95
|
-
f[0] = func1(xi, yi[1]);
|
96
|
-
f[1] = func2(xi, yi[1]);
|
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,23 @@
|
|
5
5
|
/* 構造体宣言 */
|
6
6
|
/**************************************/
|
7
7
|
typedef struct _CNum4SimDiff CNum4SimDiff;
|
8
|
-
typedef double (*Func)(
|
8
|
+
typedef double* (*Func)(int n, double* yi);
|
9
9
|
|
10
10
|
struct _CNum4SimDiff
|
11
11
|
{
|
12
|
-
double* (*
|
13
|
-
double* (*
|
14
|
-
double* (*
|
12
|
+
double* (*FP_dmy)(int n, double *yi, double h, Func func);
|
13
|
+
double* (*FP_eulerMethod)(int n, double *yi, double h, Func func);
|
14
|
+
double* (*FP_heunMethod)(int n, double *yi, double h, Func func);
|
15
|
+
double* (*FP_rungeKuttaMethod)(int n, double *yi, double h, Func func);
|
15
16
|
};
|
16
17
|
/**************************************/
|
17
18
|
/* define宣言 */
|
18
19
|
/**************************************/
|
19
|
-
#define N 2
|
20
20
|
/**************************************/
|
21
21
|
/* プロトタイプ宣言 */
|
22
22
|
/**************************************/
|
23
|
-
double*
|
24
|
-
double*
|
25
|
-
double*
|
23
|
+
double* CNum4SimDiff_dmy(int n, double *yi, double h, Func func);
|
24
|
+
double* CNum4SimDiff_eulerMethod(int n, double *yi, double h, Func func);
|
25
|
+
double* CNum4SimDiff_heunMethod(int n, double *yi, double h, Func func);
|
26
|
+
double* CNum4SimDiff_rungeKuttaMethod(int n, double *yi, double h, Func func);
|
26
27
|
#endif
|
data/lib/num4simdiff.rb
CHANGED
@@ -7,76 +7,85 @@ module Num4SimDiffLib
|
|
7
7
|
|
8
8
|
ffi_lib FFI::Compiler::Loader.find('num4simdiff')
|
9
9
|
|
10
|
-
# @overload f(
|
11
|
-
# dy = f(
|
12
|
-
# @yield [
|
13
|
-
# @yieldparam [
|
14
|
-
# @yieldparam [
|
15
|
-
# @return [
|
16
|
-
callback :f, [:
|
10
|
+
# @overload f(n, yn)
|
11
|
+
# dy = f(n, yn)
|
12
|
+
# @yield [n, yn] dy = f(n, yn)
|
13
|
+
# @yieldparam [int] n ynの個数
|
14
|
+
# @yieldparam [pointer] yn FFI::Pointer
|
15
|
+
# @return [pointer] xiに対するyの値(FFI::Pointer)
|
16
|
+
callback :f, [:int, :pointer], :pointer
|
17
17
|
|
18
|
+
attach_function :dmyFFI,
|
19
|
+
:CNum4SimDiff_dmy, [:int, :buffer_in, :double, :f], :pointer
|
18
20
|
attach_function :eulerMethodFFI,
|
19
|
-
:CNum4SimDiff_eulerMethod, [:
|
21
|
+
:CNum4SimDiff_eulerMethod, [:int, :buffer_in, :double, :f], :pointer
|
20
22
|
attach_function :heunMethodFFI,
|
21
|
-
:CNum4SimDiff_heunMethod, [:
|
23
|
+
:CNum4SimDiff_heunMethod, [:int, :buffer_in, :double, :f], :pointer
|
22
24
|
attach_function :rungeKuttaMethodFFI,
|
23
|
-
:CNum4SimDiff_rungeKuttaMethod, [:
|
25
|
+
:CNum4SimDiff_rungeKuttaMethod, [:int, :buffer_in, :double, :f], :pointer
|
24
26
|
class << self
|
27
|
+
# @private
|
28
|
+
def dmy(yi, h, func)
|
29
|
+
n = yi.size
|
30
|
+
yi_ptr = cnvRbAry2pt(n, yi)
|
31
|
+
yi_1_ptr = dmyFFI(n, yi_ptr, h, func)
|
32
|
+
yi_1 = cnvPt2RbAry(n, yi_1_ptr)
|
33
|
+
end
|
25
34
|
#
|
26
35
|
# オイラー法による数値計算
|
27
|
-
# @overload eulerMethod(yi,
|
28
|
-
# yi_1 = eulerMethod(yi,
|
29
|
-
# @param [double] yi xiに対するyiの値(配列)
|
30
|
-
# @param [double] xi xiの値
|
36
|
+
# @overload eulerMethod(yi, h, func)
|
37
|
+
# yi_1 = eulerMethod(yi, h, func)
|
38
|
+
# @param [double[]] yi xiに対するyiの値(配列)
|
31
39
|
# @param [double] h 刻み幅
|
32
|
-
# @param [callback]
|
33
|
-
# @
|
34
|
-
# @return [double] xi+hに対するyi_1の値(配列)
|
40
|
+
# @param [callback] func xiに対する傾きを計算する関数
|
41
|
+
# @return [double[]] xi+hに対するyi_1の値(配列)
|
35
42
|
#
|
36
|
-
def eulerMethod(yi,
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
43
|
+
def eulerMethod(yi, h, func)
|
44
|
+
n = yi.size
|
45
|
+
yi_ptr = cnvRbAry2pt(n, yi)
|
46
|
+
yi_1_ptr = eulerMethodFFI(n, yi_ptr, h, func)
|
47
|
+
yi_1 = cnvPt2RbAry(n, yi_1_ptr)
|
48
|
+
return yi_1
|
41
49
|
end
|
42
50
|
#
|
43
51
|
# ホイン法による数値計算
|
44
|
-
# @overload heunMethod(yi,
|
45
|
-
# yi_1 = heunMethod(yi,
|
46
|
-
# @param [double] yi xiに対するyiの値(配列)
|
47
|
-
# @param [double] xi xiの値
|
52
|
+
# @overload heunMethod(yi, h, func)
|
53
|
+
# yi_1 = heunMethod(yi, h, func)
|
54
|
+
# @param [double[]] yi xiに対するyiの値(配列)
|
48
55
|
# @param [double] h 刻み幅
|
49
|
-
# @param [callback]
|
50
|
-
# @
|
51
|
-
# @return [double] xi+hに対するyi_1の値(配列)
|
56
|
+
# @param [callback] func xiに対する傾きを計算する関数
|
57
|
+
# @return [double[]] xi+hに対するyi_1の値(配列)
|
52
58
|
#
|
53
|
-
def heunMethod(yi,
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
59
|
+
def heunMethod(yi, h, func)
|
60
|
+
n = yi.size
|
61
|
+
yi_ptr = cnvRbAry2pt(n, yi)
|
62
|
+
yi_1_ptr = heunMethodFFI(n, yi_ptr, h, func)
|
63
|
+
yi_1 = cnvPt2RbAry(n, yi_1_ptr)
|
64
|
+
return yi_1
|
58
65
|
end
|
59
66
|
#
|
60
67
|
# 4次のルンゲ=クッタ法による数値計算
|
61
|
-
# @overload rungeKuttaMethod(yi,
|
62
|
-
# yi_1 = rungeKuttaMethod(yi,
|
63
|
-
# @param [double] yi xiに対するyiの値(配列)
|
64
|
-
# @param [double] xi xiの値
|
68
|
+
# @overload rungeKuttaMethod(yi, h, func)
|
69
|
+
# yi_1 = rungeKuttaMethod(yi, h, func)
|
70
|
+
# @param [double[]] yi xiに対するyiの値(配列)
|
65
71
|
# @param [double] h 刻み幅
|
66
|
-
# @param [callback]
|
67
|
-
# @
|
68
|
-
# @return [double] xi+hに対するyi_1の値(配列)
|
72
|
+
# @param [callback] func xiに対する傾きを計算する関数
|
73
|
+
# @return [double[]] xi+hに対するyi_1の値(配列)
|
69
74
|
#
|
70
|
-
def rungeKuttaMethod(yi,
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
+
def rungeKuttaMethod(yi, h, func)
|
76
|
+
n = yi.size
|
77
|
+
yi_ptr = cnvRbAry2pt(n, yi)
|
78
|
+
yi_1_ptr = rungeKuttaMethodFFI(n, yi_ptr, h, func)
|
79
|
+
yi_1 = cnvPt2RbAry(n, yi_1_ptr)
|
80
|
+
return yi_1
|
75
81
|
end
|
76
82
|
|
77
83
|
#
|
78
|
-
#
|
79
|
-
#
|
84
|
+
# ruby配列からFFI::Pointer型に変換
|
85
|
+
# @overload cnvRbAry2pt(n, ary)
|
86
|
+
# @param [int] n 配列の個数
|
87
|
+
# @param [double[]] ary yiの値(配列)
|
88
|
+
# @return [pointer] FFI::Pointer
|
80
89
|
def cnvRbAry2pt(n, ary)
|
81
90
|
yi_ptr = FFI::MemoryPointer.new(:double, n)
|
82
91
|
n.times.map { |i|
|
@@ -85,8 +94,11 @@ module Num4SimDiffLib
|
|
85
94
|
return yi_ptr
|
86
95
|
end
|
87
96
|
#
|
88
|
-
#
|
89
|
-
#
|
97
|
+
# FFI::Pointer型からruby配列に変換
|
98
|
+
# @overload cnvPt2RbAry(n, pt)
|
99
|
+
# @param [int] n 配列の個数
|
100
|
+
# @param [pointer] pt FFI::Pointer
|
101
|
+
# @return [double[]] yiの値(配列)
|
90
102
|
def cnvPt2RbAry(n, pt)
|
91
103
|
rbAry = n.times.map { |i|
|
92
104
|
pt.get_double(i * Fiddle::SIZEOF_DOUBLE)
|
@@ -96,7 +108,5 @@ module Num4SimDiffLib
|
|
96
108
|
private :eulerMethodFFI
|
97
109
|
private :heunMethodFFI
|
98
110
|
private :rungeKuttaMethodFFI
|
99
|
-
private :cnvRbAry2pt
|
100
|
-
private :cnvPt2RbAry
|
101
111
|
end
|
102
112
|
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.1.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-
|
11
|
+
date: 2023-05-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi-compiler
|
@@ -57,6 +57,7 @@ extensions:
|
|
57
57
|
- ext/num4simdiff/Rakefile
|
58
58
|
extra_rdoc_files: []
|
59
59
|
files:
|
60
|
+
- ".yardopts"
|
60
61
|
- CHANGELOG.md
|
61
62
|
- Gemfile
|
62
63
|
- LICENSE
|
@@ -69,7 +70,7 @@ licenses:
|
|
69
70
|
- MIT
|
70
71
|
metadata:
|
71
72
|
changelog_uri: http://github.com/siranovel/num4simdiffrent/blob/main/CHANGELOG.md
|
72
|
-
documentation_uri: https://rubydoc.info/gems/num4simdiff/0.
|
73
|
+
documentation_uri: https://rubydoc.info/gems/num4simdiff/0.1.1
|
73
74
|
homepage_uri: http://github.com/siranovel/num4simdiffrent
|
74
75
|
post_install_message:
|
75
76
|
rdoc_options:
|