如何在Fortran中排列向量的元素?
我有两个 p*n 数组,y 和 ymiss。 y 包含实数和 NA。 ymiss 包含 1 和 0,因此如果 y(i,j)==NA,则 ymiss(i,j)==0,否则为 1。我还有 1*n 数组 ydim ,它告诉 y(1:p,n) 有多少个实数,因此 ydim 的值为 0 到 p
在 R 编程语言中,我可以执行以下操作:
if(ydim!=p && ydim!=0)
y(1:ydim(t), t) = y(ymiss(,t), t)
该代码排列了所有实数y(,t)
首先像 这样 y(,t) = (3,1,NA,6,2,NA) 代码之后是 y(,t) = (3,1,6,2,2,NA)
现在我只需要前一个 1:ydim(t),所以其余的是什么并不重要。
问题是,我怎样才能在 Fortran 中做类似的事情呢?
谢谢,
朱尼
I have two p*n arrays, y and ymiss. y contains real numbers and NA's. ymiss contains 1's and 0's, so that if y(i,j)==NA, ymiss(i,j)==0, and 1 otherwise. I also have 1*n array ydim which tells how many real numbers there is at y(1:p,n), so ydim has values 0 to p
In R programming language, I can do following:
if(ydim!=p && ydim!=0)
y(1:ydim(t), t) = y(ymiss(,t), t)
That code arranges all real numbers of y(,t) in like this
first there's for example
y(,t) = (3,1,NA,6,2,NA)
after the code it's
y(,t) = (3,1,6,2,2,NA)
Now I will only need those first 1:ydim(t), so it doesn't matter what those rest are.
The question is, how can I do something like that in Fortran?
Thanks,
Jouni
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
“where 语句”和“merge”内部函数功能强大,可在数组中的选定位置上进行操作,但它们不会将项目移动到数组的前面。使用具有显式索引的老式代码(可以打包到函数中),例如:
您想要的可以使用“pack”内在函数通过数组内在函数来完成。将 ymiss 转换为逻辑数组:0 --> .false., 1 --> .true.. 然后使用如下代码(在没有第二个索引的情况下进行测试):
y(1:ydim(t), t) = pack (y (:,t), ymiss (:,t))
编辑以添加示例代码,显示 Fortran 内在函数“where”、“count”和“pack”的使用。仅“where”无法解决问题,但“pack”可以。在本例中,我使用“< -90”作为 NaN。 OP 不需要步骤“y (ydim+1:LEN) = -99.0”,因为他们不需要使用这些元素。
输出为:
输入数组:
3.0 1.0 -99.0 6.0 2.0 -99.0
使用 where 进行掩码,不重新排列:
3.0 1.0 -99.0 6.0 2.0 -99.0
使用 pack 后,并“擦除”末尾:
3.0 1.0 6.0 2.0 -99.0 -99.0
The "where statement" and the "merge" intrinsic function are powerful, operating on selected positions in arrays, but they don't move items to the front of an array. With old-fashioned code with explicit indexing (could be packaged into a function) e.g.:
What you want could be done with array intrinsics using the "pack" intrinsic. Convert ymiss into a logical array: 0 --> .false., 1 --> .true.. Then use code like (tested without the second index):
y(1:ydim(t), t) = pack (y (:,t), ymiss (:,t))
Edit to add example code, showing use of Fortran intrinsics "where", "count" and "pack". "where" alone can't solve the problem, but "pack" can. I used "< -90" as NaN for this example. The step "y (ydim+1:LEN) = -99.0" isn't required by the OP, who doesn't need to use these elements.
Output is:
The input array:
3.0 1.0 -99.0 6.0 2.0 -99.0
Masking with where does not rearrange:
3.0 1.0 -99.0 6.0 2.0 -99.0
After using pack, and "erasing" the end:
3.0 1.0 6.0 2.0 -99.0 -99.0
在 Fortran 中,你不能将 na 存储在实数数组中,只能存储实数。因此,您可能希望将 na 替换为数据中不太可能出现的某个值:huge() 可能合适。 2D 数组对于 Fortan 来说完全没有问题。您可能想要使用逻辑的 2D 数组来替换 ymiss,而不是 1 和 0 的 2D 数组。
没有简单的、内在的来实现你想要的,你需要编写一个函数。然而,更适合 Fortran 的处理方式是使用逻辑数组作为要执行的操作的掩码。
因此,这里有一些未经测试的 Fortran 代码片段:
In Fortran you can't store na in an array of real numbers, you can only store real numbers. So you'll probably want to replace na's with some value not likely to be present in your data: huge() might be suitable. 2D arrays are no problem at all for Fortan. You might want to use a 2D array of logicals to replace ymiss rather than a 2D array of 1s and 0s.
There is no simple, intrinsic to achieve what you want, you'd need to write a function. However, a more Fortran way of doing things would be to use the array of logicals as a mask for the operations you want to carry out.
So, here's some fragmentary Fortran code, not tested: