我无法在Fortran程序中实现一种调用牛顿方法的方法。 因此,我想使用牛顿法来求解the link
之后的方程但是,我的程序与上面的示例略有不同。在我的情况下,方程式需要一些其他信息,这些信息是在运行时生成的。
pandas
这意味着f不仅基于x进行计算,还基于其他一些变量(但x是未知数)计算。
我有一个解决方案,该解决方案仅适用于简单情况: 我使用了一个模块来包含牛顿的求解器。我还定义了一个派生数据类型来保存模块内部的所有参数。现在效果很好。
我的问题是:我需要多次调用牛顿方法,并且每次参数都不相同。我应该如何设计模块的结构?还是应该使用其他解决方案?
我在下面提供了一个简单的示例:
subroutine solve(f, fp, x0, x, iters, debug)
调用模块是:
module solver
type argu
integer :: m
end type argu
type(argu):: aArgu_test !should I put here?
contains
subroutine solve(f, fp, x0, x, iters, debug)
...
!m is used inside here
end subroutine solve
subroutine set_parameter(m_in)
aArgu%m = m_in
end subroutine set_parameter()
end module solver
我的理解是,如果将argu对象放在Solver模块中,则所有Solver调用都将使用相同的参数(我仍然可以使用上述方法将所有参数保存在A模块中)。在那种情况下,我必须在每个for循环中更新参数吗?
因为程序使用MPI / OpenMP运行,所以我想确保线程之间没有覆盖。 谢谢。
答案 0 :(得分:3)
现代Fortran中有一个常见的模式可以解决您面临的问题(partial function application)。与其他语言不同,Fortran没有函数闭包,因此为函数建立词法作用域有点“费解”,而且有点局限。
您应该真正考虑重新访问评论中@VladmirF共享的所有链接,其中大多数直接适用于您的案例。我会给你一个解决方案的例子。
这是不使用包装器类型的解决方案。我将使用Fortran 2008标准中包含的功能:传递内部过程作为参数。它与最新的gfortran,Intel等兼容。 如果您无法使用此功能访问编译器,或者您希望使用派生类型的解决方案,则可以参考this答案。
headers.add("Content-Disposition", "attachment; filename=" + "example.pdf");
此代码的原理是:由于df = df1.merge(df2, how='left', left_on='A', right_on = 'A')
def select(row, field):
if row['{}_y'.format(field)] is np.nan:
return row['{}_x'.format(field)]
else:
return row['{}_y'.format(field)]
df['C'] = df[['C_x', 'C_y']].apply(select, field='C', axis=1)
df['B'] = df[['B_x', 'B_y']].apply(select, field='B', axis=1)
和module without_custom_type
use, intrinsic :: iso_fortran_env, only: r8 => real64
use :: solver
contains
subroutine solve_quad(a, b, c, x0, x, iters, debug)
integer, intent(in) :: a, b, c
real(r8), intent(in) :: x0
real(r8), intent(out) :: x
integer, intent(out) :: iters
logical, intent(in) :: debug
call solve(f, fp, x0, x, iters, debug)
contains
real(r8) function f(x)
real(r8),intent(in) :: x
f = a * x * x + b * x + c
end
real(r8) function fp(x)
real(r8),intent(in) :: x
fp = 2 * a * x + b
end
end
end
位于f
过程中,因此他们可以访问参数fp
,solve_quad
和a
(通过主机关联),而无需触摸这些功能的签名。产生的效果就像更改函数的Arity。
使用gfortran 8.0和您共享的链接中的b
实现对其进行测试,我得到了:
c
答案 1 :(得分:1)
与同事讨论后,我对问题2有了解决方案。
如果求解器模块只有一个参数对象,则所有调用将访问相同的参数,因为它们共享相同的内存空间。
为避免这种情况,我们希望将参数对象作为参数传递给求解器。 因此,我们将使用牛顿的方法来重写它,以接受其他参数,而不是使用默认的求解器子例程。
(我之前使用了最简单的Newton子例程,因为我希望保持不变。)
这样,我们将定义一个参数对象数组,并在运行时传递它们。
谢谢您的评论。