gtool5 Fortran 90/95 ライブラリ 1.0.0-rc5
English
Loading...
Searching...
No Matches
gtvarlimitbinary.f90
Go to the documentation of this file.
1
21
58subroutine gtvarxformbinary(var1, var2, err)
59 use gtdata_types, only: gt_variable
64 implicit none
65 type(gt_variable), intent(inout):: var1, var2
66 logical, intent(out), optional:: err
67 integer:: ndim1, ndim2, ndimo
68 integer, allocatable:: map1(:), map2(:)
69 type(gt_dimmap), pointer:: newmap(:)
70 integer:: i, j, stat
71 character(*), parameter:: subnam = "GTVarXformBinary"
72continue
73 call beginsub(subnam, 'mapid=[%d, %d]', i=(/var1%mapid, var2%mapid/))
74 call gtvar_dump(var1)
75 call gtvar_dump(var2)
76 !
77 ! 二つの変数 var1, var2 から共有次元を調べ、対応表 map1, map2 をつくる。
78 !
79 if (present(err)) err = .false.
80 call inquire(var1, alldims=ndim1)
81 call inquire(var2, alldims=ndim2)
82 ndimo = max(ndim1, ndim2, 0)
83 allocate(map1(1:ndim1), map2(1:ndim2))
84 call getmatch(var1, var2, ndim1, ndim2, map1, map2)
85 call dbgmessage('map1=%*d map2=%*d', i=(/map1(1:ndim1), map2(1:ndim2)/), n=(/ndim1, ndim2/))
86 if (all(map2(1:ndim2) == 0)) then
87 stat = gt_enomatchdim
88 goto 999
89 endif
90 !
91 ! 再配置テーブル作成開始
92 !
93 ndimo = ndim2 + count(map1(1:ndim1) == 0)
94 call map_allocate(newmap, ndimo)
95 !
96 ! 1..ndim2 は map2 によって var2 の次元たちにマップする
97 !
98 newmap(1:ndim2)%dimno = map2(1:ndim2)
99 call inquire(var2, allcount=newmap(1:ndim2)%allcount)
100 call get_slice(var2, count=newmap(1:ndim2)%count)
101 do, j = 1, ndim2
102 if (map2(j) == 0) then
103 newmap(j)%start = 1
104 newmap(j)%stride = 1
105 call inquire(var2, j, url=newmap(j)%url)
106 else
107 ! 位置対応によって var1 側での開始位置を決定する
108 call adjust_slice(var1, var2, map2(j), j, &
109 & newmap(j)%start, newmap(j)%stride)
110 endif
111 enddo
112 !
113 ! ndim2+1.. ndimo は var2 に対応させられない var1 の次元をおく
114 !
115 j = 0
116 loop1: do, i = ndim2 + 1, ndimo
117 do
118 j = j + 1
119 if (j > ndim1) exit loop1
120 if (map1(j) <= 0) exit
121 enddo
122 newmap(i)%dimno = j
123 call inquire(var1, dimord=j, allcount=newmap(i)%allcount)
124 call get_slice(var1, dimord=j, start=newmap(i)%start, &
125 & count=newmap(i)%count, stride=newmap(i)%stride)
126 end do loop1
127 !
128 call map_apply(var1, map=newmap)
129 !
130 stat = dc_noerr
131999 continue
132 call storeerror(stat, subnam, err)
133 call endsub(subnam, 'stat=%d', i=(/stat/))
134 deallocate(map1, map2)
135 return
136contains
137
138 !
139 ! 二つの次元変数を調べ、軸上位置が対応するように
140 ! start シフト数と stride ファクタを決定する
141 !
142 subroutine adjust_slice(var1, var2, idim1, idim2, offset, stepfact)
143 use gtdata_generic, only: get, open, close
144 type(gt_variable), intent(in):: var1, var2
145 integer, intent(in):: idim1, idim2
146 integer, intent(out):: offset, stepfact
147 type(gt_variable):: var_d
148 integer:: n, buf(1)
149 real, allocatable:: val1(:), val2(:)
150 continue
151 call beginsub('adjust_slice')
152 call open(var_d, source_var=var1, dimord=idim1, count_compact=.true.)
153 call inquire(var_d, size=n)
154 allocate(val1(n))
155 call get(var_d, val1, n)
156 call close(var_d)
157 !
158 call open(var_d, source_var=var2, dimord=idim2, count_compact=.true.)
159 call inquire(var_d, size=n)
160 allocate(val2(n))
161 call get(var_d, val2, n)
162 call close(var_d)
163 !
164 buf(1:1) = minloc(abs(val1(:) - val2(1)))
165 offset = buf(1) - 1
166 if (size(val2) < 2 .or. size(val1) < 2) then
167 stepfact = 1
168 else
169 buf(1:1) = minloc(abs(val1(:) - val2(2)))
170 stepfact = buf(1) - (offset + 1)
171 endif
172 !
173 deallocate(val1, val2)
174 call endsub('adjust_slice')
175 end subroutine adjust_slice
176
177 !
178 ! 二つの変数から共有次元を調べ、対応表 map1, map2 を作る。
179 ! すなわち、それぞれの次元番号から相方の次元番号を得る表である。
180 !
181 subroutine getmatch(var1, var2, ndim1, ndim2, map1, map2)
182 use dc_types, only: string
183 use dc_units, only: units, add_okay, assignment(=), clear, deallocate
184 use gtdata_generic, only: get_attr, open, close
185 type(gt_variable), intent(in):: var1, var2
186 integer, intent(in):: ndim1, ndim2
187 integer, intent(out):: map1(:), map2(:)
188 type(gt_variable):: var_d
189 integer, allocatable:: map(:, :)
190 integer:: i, j
191 character(STRING):: su1, su2
192 type(units), allocatable:: u1(:), u2(:)
193 continue
194 call beginsub('getmatch')
195 ! 返却値はデフォルト 0
196 map1(:) = 0
197 map2(:) = 0
198 ! 表の構築: 初期値は消去法をとることを示す
199 allocate(map(ndim1, ndim2))
200 map(:, :) = 1
201
202 ! 単位による対応 --- 加算可能でなければ対にしない
203 ! 単位の構成
204 allocate(u1(ndim1), u2(ndim2))
205 do, i = 1, ndim1
206 call open(var_d, var1, i, count_compact=.true.)
207 call get_attr(var_d, 'units', su1)
208 call close(var_d)
209 call clear(u1(i))
210 u1(i) = su1
211 enddo
212 do, j = 1, ndim2
213 call open(var_d, var2, j, count_compact=.true.)
214 call get_attr(var_d, 'units', su2)
215 call close(var_d)
216 call clear(u2(j))
217 u2(j) = su2
218 enddo
219 ! 処理
220 do, i = 1, ndim1
221 do, j = 1, ndim2
222 if (.not. add_okay(u1(i), u2(j))) &
223 & map(i, j) = 0
224 enddo
225 enddo
226 ! 単位の廃棄
227 do, i = 1, ndim1
228 call deallocate(u1(i))
229 enddo
230 do, j = 1, ndim2
231 call deallocate(u2(j))
232 enddo
233 deallocate(u1, u2)
234
235 if (map_finished(map)) goto 1000
236
237 ! --- it fails ---
238 call endsub('getmatch', 'fail')
239 return
240
2411000 continue
242 do, i = 1, ndim1
243 call dbgmessage('map(%d, :)=%*d', i=(/i, map(i,:)/), n=(/ndim2/))
244 enddo
245 do, i = 1, ndim1
246 if (all(map(i, :) <= 0)) then
247 map1(i) = 0
248 else
249 map1(i:i) = maxloc(map(i, :))
250 endif
251 enddo
252 do, j = 1, ndim2
253 if (all(map(:, j) <= 0)) then
254 map2(j) = 0
255 else
256 map2(j:j) = maxloc(map(:, j), dim=1)
257 endif
258 enddo
259 call endsub('getmatch', 'okay')
260 end subroutine getmatch
261
262 logical function map_finished(map) result(result)
263 integer:: map(:, :)
264 integer:: i, j, ni
265 continue
266 call beginsub('map_finished')
267 ni = size(map, dim=1)
268 do, i = 1, ni
269 if (count(map(i, :) > 0) > 1) then
270 result = .false.
271 goto 999
272 endif
273 enddo
274 do, j = 1, ni
275 if (count(map(j, :) > 0) > 1) then
276 result = .false.
277 goto 999
278 endif
279 enddo
280 result = .true.
281999 continue
282 call endsub('map_finished')
283 end function map_finished
284
285end subroutine gtvarxformbinary
subroutine gtvarxformbinary(var1, var2, err)
subroutine adjust_slice(var1, var2, idim1, idim2, offset, stepfact)
エラー処理用モジュール
Definition dc_error.f90:454
subroutine, public storeerror(number, where, err, cause_c, cause_i)
Definition dc_error.f90:891
integer, parameter, public gt_enomatchdim
Definition dc_error.f90:516
integer, parameter, public dc_noerr
エラー等を保持
Definition dc_error.f90:468
デバッグ時の追跡用モジュール
Definition dc_trace.f90:150
subroutine, public dbgmessage(fmt, i, r, d, l, n, c1, c2, c3, ca)
Definition dc_trace.f90:661
subroutine, public beginsub(name, fmt, i, r, d, l, n, c1, c2, c3, ca, version)
Definition dc_trace.f90:457
subroutine, public endsub(name, fmt, i, r, d, l, n, c1, c2, c3, ca)
Definition dc_trace.f90:580
種別型パラメタを提供します。
Definition dc_types.f90:55
integer, parameter, public string
文字列を保持する 文字型変数の種別型パラメタ
Definition dc_types.f90:137
単位系処理用モジュール
Definition dc_units.f90:52
logical function, public add_okay(u1, u2)
Definition dc_units.f90:308
subroutine map_apply(var, map)
subroutine map_allocate(map, ndims)