我知道,并使用f2py2e来包装一些旧的Fortran 77代码,但我的理解是它不适用于较新的Fortran 95代码.我已经研究了我应该使用的东西,并且遇到了fwrap 和G3 f2py,它们似乎都没有给出它们当前状态的任何解释,或者如何使用它们.我已经看到f2py的版本可以选择使用第三代f2py,但它被评为不起作用.鉴于此,我不知道应该使用哪个项目.我应该使用哪一个?
这个问题现已交叉发布到Computational Science堆栈交换站点(并在其中回答),我应该使用哪个包来用Python包装Modern Fortran Code?
假设我有一个Fortran派生类型
type :: atype
integer :: n
integer :: a(10)
integer, allocatable :: b(:)
end type
Run Code Online (Sandbox Code Playgroud)
我有两个这种类型的实例
type(atype) :: t1, t2
Run Code Online (Sandbox Code Playgroud)
当我做以下任务时到底发生了什么?
t2 = t1
Run Code Online (Sandbox Code Playgroud)
我对此感兴趣,因为我想正确地创建派生类型变量的副本意味着,标量组件应该相等,数组组件的每个元素应该相等,并且可分配的数组应该具有相同的分配大小,并且元素应该相等.目前我只想写一个子程序,它正确地复制和分配组件.
subroutine copy_atype(from, to)
type(atype) :: from, to
to%n = from%n
to%a = from%a
if (allocated(to%b)) deallocate(to%b)
if (allocated(from%b) then
allocate(to%b(size(from%b)))
to%b = from%b
end if
end subroutine
Run Code Online (Sandbox Code Playgroud)
我希望指导标准中的相应部分.
我正在使用gfortran 4.7.
我想(超)优化Heaviside函数的实现.
我正在研究一种速度特别重要的数值算法(在Fortran中).它多次使用Heaviside函数,目前由signum内部函数实现如下:
heaviside = 0.5*sign(1,x)+1
Run Code Online (Sandbox Code Playgroud)
我主要感兴趣的是x是intel处理器上的双精度实数.
是否有可能开发更高效的Heaviside功能实现?也许使用汇编语言,超优化代码或调用现有的外部库?
我被告知我的博士学位,我必须学习fortran 2003语言.我以前从未使用过OOP程序,也没有使用过fortran程序.我试图了解类型和类之间的区别.我知道类是使用'TYPE'关键字声明的,但我也看到了使用关键字'CLASS'的例子,所以我感到困惑.希望有道理.
有没有使用Fortran 2003标准的内部模块从C库头自动生成Fortan 绑定的工具iso_c_bindings?
我对将 C 转换为Fortran 不感兴趣,但只生成绑定.
假设您创建了一个 Fortran array(:),其中包含指向在 C 中分配的内存的指针malloc(如最佳答案所示,下面重复了代码)。有没有办法使用 Fortran 数组(即 iso_c_bindings)将整数值写入这个分配的内存中?或者我必须在 C 中做到这一点?
#include "stdlib.h"
int *create_storage()
{
/* Array of four integers. */
return malloc(sizeof(int) * 4);
}
void destroy_storage(int *ptr)
{
free(ptr);
}
PROGRAM fortran_side
USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR, C_F_POINTER, C_INT
IMPLICIT NONE
INTERFACE
FUNCTION create_storage() BIND(C, NAME='create_storage')
USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR
IMPLICIT NONE
TYPE(C_PTR) :: create_storage
END FUNCTION create_storage
SUBROUTINE destroy_storage(p) BIND(C, NAME='destroy_storage')
USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR
IMPLICIT NONE …Run Code Online (Sandbox Code Playgroud) 我有一个wrapper包含其他派生类型(over)的派生类型().对于后者,赋值运算符已经过载.由于派生类型的赋值按默认的组件方式发生,我希望分配两个实例wrapper会over在某个时刻调用重载的赋值.但是,使用下面的程序似乎并非如此.仅当我还重载用于在实例之间wrapper包含显式赋值的赋值时over(通过取消注释注释的代码行),才会调用重载的赋值.为什么?我发现它有点违反直觉.有没有办法避免包装类型的过载?
module test_module
implicit none
type :: over
integer :: ii = 0
end type over
type :: wrapper
type(over) :: myover
end type wrapper
interface assignment(=)
module procedure over_assign
!module procedure wrapper_assign
end interface assignment(=)
contains
subroutine over_assign(other, self)
type(over), intent(out) :: other
type(over), intent(in) :: self
print *, "Assignment of over called"
other%ii = -1
end subroutine over_assign
!subroutine wrapper_assign(other, self)
! type(wrapper), intent(out) …Run Code Online (Sandbox Code Playgroud) 现代 Fortran 包含各种面向对象的思想,包括通过FINAL关键字“析构函数”的概念。
MODULE mobject
TYPE :: tobject
! Data declarations
CONTAINS
FINAL :: finalize
END TYPE
CONTAINS
SUBROUTINE finalize(object)
TYPE(tobject) object
...
END SUBROUTINE
END MODULE
Run Code Online (Sandbox Code Playgroud)
然而,这个功能可靠吗?值得注意的是,我注意到有关何时以及是否会调用它的不一致,英特尔 Fortran 19 和 GFortan 7、8 之间存在主要差异:
我注意到 gfortran-7.4.0 和 gfortran-8.2.1.2 之间没有区别。
这些不一致给我带来了一些关于析构函数的实际可用性的问题。是否有任何一种行为完全符合标准?这个标准不清楚吗?标准是否可能包含导致不直观行为的条款?
程序块。Gfortran 不会为在 PROGRAM 块中声明的实例调用析构函数,而 Ifort 会(参见run1示例)。
标量对象。对于声明为标量的实例,如果变量已经看到任何形式的初始化,Gfortran 和 IFort 都会调用析构函数。然而,英特尔 Fortran 在分配函数返回值时,也会调用它
newObject函数的末尾。然而,这可以通过在执行任何清理之前显式检查对象是否已初始化来防止。
这意味着,程序员必须明确检查实例是否已初始化。
数组中的对象。如果对象包含在数组中,并且数组超出范围,
allocatable …对于一个新项目,我正在考虑使用 Fortran2003 的面向对象特性。我尝试过的一件事涉及一个过程指针,它指向一个函数(不是子例程),该函数返回一个指向多态类型的指针。我想知道这样的构造是否合法,因为我从不同的编译器得到了混合的结果(见下文)。
作为一个具体的例子,考虑以下函数接口:
abstract interface
function if_new_test(lbls) result(t)
import :: test_t
class(test_t),pointer :: t
character(len=*),intent(in) :: lbls(:)
end function if_new_test
end interface
Run Code Online (Sandbox Code Playgroud)
并且使用代码应该有一个过程指针,可以指向具有这个接口的函数:
procedure(if_new_test),pointer :: nt
Run Code Online (Sandbox Code Playgroud)
我在问这是否合法,因为 gfortran (4.7.2) 用消息抱怨这个过程指针声明:
错误:(1) 处的 CLASS 变量“nt”必须是虚拟的、可分配的或指针
我不明白这个错误信息,因为nt它本身是一个指针,它指向的函数返回的也是一个指针。
作为参考,示例的完整源代码如下。第一,包含我的派生类型、接口和函数/子例程的模块:
module test_m
implicit none
type :: test_t
character(len=10) :: label
contains
procedure :: print => print_test
end type test_t
type,extends(test_t) :: test2_t
character(len=10) :: label2
contains
procedure :: print => print_test2
end type test2_t
abstract interface
function if_new_test(lbls) result(t)
import :: …Run Code Online (Sandbox Code Playgroud) 是否有可能直接在函数的返回值上使用索引?像这样的东西:
readStr()(2:5)
Run Code Online (Sandbox Code Playgroud)
wherereadStr()是一个返回字符串或数组的函数。在许多其他语言中,这是很有可能的,但是 Fortran 呢?我的示例中的语法当然无法编译。有没有其他语法可以使用?
fortran ×10
fortran2003 ×10
c ×2
fortran95 ×2
gfortran ×2
assembly ×1
binding ×1
fortran90 ×1
intel ×1
numpy ×1
optimization ×1
pointers ×1
polymorphism ×1
python ×1