-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest.py
More file actions
executable file
·109 lines (80 loc) · 3.07 KB
/
test.py
File metadata and controls
executable file
·109 lines (80 loc) · 3.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/usr/bin/env python3
# -* coding: utf-8 -*-
#f2pyはnumpyの付属プログラムなので、numpy.ndarrayの使用を推奨する。
import numpy
#実装は下記関数名に対応する.F90ファイルを読むこと、
from f2py_example import\
hello_world, print_integer, print_string, print_iarray, \
range_iarray, doubleme_iarray, struct_vec_rotate
# hello_world
hello_world()
# integer引数の値渡し
# 引数に対して、int[Python]への変換を行うので注意
print_integer(0)
print_integer(0.0)
print_integer("0")
# character引数の値渡し
# integerの場合と同じく、str[Python]への変換を行う。
# 実際に渡されているのはbytesなのかもしれない?
print_string(0)
print_string(0.0)
print_string( "hello, world!")
print_string(b"HELLO, WORLD!")
print_string( "こんにちは、世界".encode("utf-8")) #Linuxで正しく表示されるはず
print_string( "こんにちは、世界".encode("cp932")) #Windowsで正しく表示されるはず
# 配列の値渡し
# 値渡しについては、結局f2pyでコピーが作成されるので、
# int[Python]に変換できるiterableなら、自由に渡せる。
print("配列の値渡し")
print_iarray([0, 1, 2])
print_iarray(100) #numpyではスカラーも0次元のarrayとみなす
print_iarray(numpy.arange(10))
print_iarray(range(5)) #特定の組み込みiteratorもいけるらしい
# 配列の参照渡し
# 参照渡しの場合、配列要素がメモリ上に連続していなければならない。
# そういった制約のために、numpy.ndarrayのみ利用できる。
# 型のサイズkind[Fortran]については、PythonとFortranで合わせる必要がある。
# integer(4) <=> numpy.int16
# integer(8) <=> numpy.int32
# などと自力で対応付けてもよいが、Cの型に合わせるのがよいように思える。
# Fortran| use iso_c_binding, only : c_int
# Fortran| integer(c_int)
# v.s.
# Python | numpy.intc
print("配列の参照渡し")
arr0 = numpy.zeros(10, dtype=numpy.intc)
range_iarray(arr0)
print_iarray(arr0)
# 配列を返す関数
# numpy.ndarrayで値を返す。
print(
doubleme_iarray(range(5))
)
# 構造体の参照渡し
# f2pyでは構造体に直接は対応していないので、
# ctypesで作成したC互換なVec[Python]のアドレスを
# long[C]型で取りだしてFortanに渡す。
# Fortranでアドレスからvec_t[Fortran]に変換して利用する。
import ctypes
# Pythonで作成したC互換なデータ型
class Vec(ctypes.Structure):
_fields_ = [
("x", ctypes.c_double),
("y", ctypes.c_double),
("z", ctypes.c_double),
]
def __repr__(self):
className = self.__class__.__name__
valueList = ", ".join(
"{}={}".format(attr, getattr(self, attr))
for attr, _ in self._fields_
)
return "{className}({valueList})".format(**vars())
# 下記データ型と対応する。
# C | struct _vec_t {
# C | double x, y, z;
# C | };
vec = Vec(10, 20, 30)
print(vec)
struct_vec_rotate(ctypes.addressof(vec))
print(vec)