Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 将VBA代码转换为Fortran_Algorithm_Vba_Fortran - Fatal编程技术网

Algorithm 将VBA代码转换为Fortran

Algorithm 将VBA代码转换为Fortran,algorithm,vba,fortran,Algorithm,Vba,Fortran,我试图用高斯消去法和部分旋转法来解这个方程 x-2y-z=2 5x+2y+2z=9 -3x+5y-z=1 所以我把 1 2 -1 5 2 2 -3 5 -1 输入1.DAT 及 输入2.DAT 这是运行良好的VBA代码 Option Explicit Sub GaussElim() Dim n As Integer, er As Integer, i As Integer Dim a(10, 10) As Double, b(10) As Do

我试图用高斯消去法和部分旋转法来解这个方程

x-2y-z=2
5x+2y+2z=9
-3x+5y-z=1
所以我把

 1    2   -1

 5    2    2

-3    5   -1
输入1.DAT 及

输入2.DAT

这是运行良好的VBA代码

   Option Explicit

Sub GaussElim()
Dim n As Integer, er As Integer, i As Integer
Dim a(10, 10) As Double, b(10) As Double, x(10) As Double
n = 3
a(1, 1) = 1: a(1, 2) = 2: a(1, 3) = -1
a(2, 1) = 5: a(2, 2) = 2: a(2, 3) = 2
a(3, 1) = -3: a(3, 2) = 5: a(3, 3) = -1
b(1) = 2: b(2) = 9: b(3) = 1
Call Gauss(a, b, n, x, er)
If er = 0 Then
  For i = 1 To n
    MsgBox "x(" & i & ") = " & x(i)
  Next i
Else
  MsgBox "ill-conditioned system"
End If
End Sub

Sub Gauss(a, b, n, x, er)
Dim i As Integer, j As Integer
Dim s(10) As Double
Const tol As Double = 0.000001
er = 0
For i = 1 To n
  s(i) = Abs(a(i, 1))
  For j = 2 To n
    If Abs(a(i, j)) > s(i) Then s(i) = Abs(a(i, j))
  Next j
Next i
Call Eliminate(a, s, n, b, tol, er)
If er <> -1 Then
  Call Substitute(a, n, b, x)
End If
End Sub

Sub Pivot(a, b, s, n, k)
Dim p As Integer, ii As Integer, jj As Integer
Dim factor As Double, big As Double, dummy As Double
p = k
big = Abs(a(k, k) / s(k))
For ii = k + 1 To n
  dummy = Abs(a(ii, k) / s(ii))
  If dummy > big Then
    big = dummy
    p = ii
  End If
Next ii
If p <> k Then
  For jj = k To n
    dummy = a(p, jj)
    a(p, jj) = a(k, jj)
    a(k, jj) = dummy
  Next jj
  dummy = b(p)
  b(p) = b(k)
  b(k) = dummy
  dummy = s(p)
  s(p) = s(k)
  s(k) = dummy
End If
End Sub

Sub Substitute(a, n, b, x)
Dim i As Integer, j As Integer
Dim sum As Double
x(n) = b(n) / a(n, n)
For i = n - 1 To 1 Step -1
  sum = 0
  For j = i + 1 To n
    sum = sum + a(i, j) * x(j)
  Next j
  x(i) = (b(i) - sum) / a(i, i)
Next i
End Sub

Sub Eliminate(a, s, n, b, tol, er)
Dim i As Integer, j As Integer, k As Integer
Dim factor As Double
For k = 1 To n - 1
  Call Pivot(a, b, s, n, k)
  If Abs(a(k, k) / s(k)) < tol Then
    er = -1
    Exit For
  End If
  For i = k + 1 To n
    factor = a(i, k) / a(k, k)
    For j = k + 1 To n
      a(i, j) = a(i, j) - factor * a(k, j)
    Next j
    b(i) = b(i) - factor * b(k)
  Next i
Next k
If Abs(a(k, k) / s(k)) < tol Then er = -1
End Sub
这个代码我没有错误

但问题是我 '0.0000000 E+00 0.0000000 E+00 -7.1424372E-02' 结果,

它应该是‘x(1)=1,x(2)=1,x(3)=1’


有谁能帮我找出我算法中的错误吗???

首先,你应该确保把所有这些子程序都放在一个模块中。这样,您就不需要在每个子例程中声明
外部GaussElim
,因为编译器将知道模块中的所有子例程以及它们期望的参数。要做到这一点,只需将所有这些子例程放在一个文件中,并将它们放在中间:

module gauss_mod

implicit none

contains

! your code here

end module gauss_mod
然后在主程序中,只需将
use gauss_mod
放在顶部,就可以访问模块中的所有子程序。
implicit none
告诉编译器您将声明所有变量,并且它不应该猜测您没有告诉它的任何变量的类型。例如,这将捕获许多由打字错误引起的错误

其次,您需要向子例程声明参数。这就是造成大多数错误的原因。除了
GaussElim
,其他子程序都不知道像
A
这样的变量是什么。因此,当编译器看到

s(i) = ABS(A(i,1))
它认为
A(i,1)
是一个函数,并给出与此相关的错误。只需在子程序中添加以下行即可修复此问题:

double precision, dimension(:,:) :: A
这告诉子程序A必须有两个维度,但可以是任意大小。 您还应该为输入参数添加
intent(in)
,为输出参数添加
intent(out)
,为子程序更改的参数添加
intent(inout)

此外,使用
real
并设置
种类
参数,而不是使用
双精度

module gauss_mod

implicit none

integer, parameter :: dp = selected_real_kind(15)

contains

! your code here

  ! As an example:
  subroutine gauss(a, b, n, x, er)
    ! dummy arguments
    real(kind=dp), dimension(:,:), intent(in) :: a, b
    integer, intent(in) :: n
    real(kind=dp), dimension(:), intent(out) :: x
    real(kind=dp), intent(out) :: er

    real(kind=dp), dimension(10) :: S(10)
    real(kind=dp), parameter :: tol = 0.000001

    ! rest of subroutine
  end subroutine gauss

end module gauss_mod

做这些事情会消除很多错误。如果仍有错误,则应发布准确的错误消息,并指出它们所指的代码行。

首先,应确保将所有这些子例程放在一个模块中。这样,您就不需要在每个子例程中声明
外部GaussElim
,因为编译器将知道模块中的所有子例程以及它们期望的参数。要做到这一点,只需将所有这些子例程放在一个文件中,并将它们放在中间:

module gauss_mod

implicit none

contains

! your code here

end module gauss_mod
然后在主程序中,只需将
use gauss_mod
放在顶部,就可以访问模块中的所有子程序。
implicit none
告诉编译器您将声明所有变量,并且它不应该猜测您没有告诉它的任何变量的类型。例如,这将捕获许多由打字错误引起的错误

其次,您需要向子例程声明参数。这就是造成大多数错误的原因。除了
GaussElim
,其他子程序都不知道像
A
这样的变量是什么。因此,当编译器看到

s(i) = ABS(A(i,1))
它认为
A(i,1)
是一个函数,并给出与此相关的错误。只需在子程序中添加以下行即可修复此问题:

double precision, dimension(:,:) :: A
这告诉子程序A必须有两个维度,但可以是任意大小。 您还应该为输入参数添加
intent(in)
,为输出参数添加
intent(out)
,为子程序更改的参数添加
intent(inout)

此外,使用
real
并设置
种类
参数,而不是使用
双精度

module gauss_mod

implicit none

integer, parameter :: dp = selected_real_kind(15)

contains

! your code here

  ! As an example:
  subroutine gauss(a, b, n, x, er)
    ! dummy arguments
    real(kind=dp), dimension(:,:), intent(in) :: a, b
    integer, intent(in) :: n
    real(kind=dp), dimension(:), intent(out) :: x
    real(kind=dp), intent(out) :: er

    real(kind=dp), dimension(10) :: S(10)
    real(kind=dp), parameter :: tol = 0.000001

    ! rest of subroutine
  end subroutine gauss

end module gauss_mod

做这些事情会消除很多错误。如果仍有错误,则应发布准确的错误消息,并指出它们所指的代码行。

首先,应确保将所有这些子例程放在一个模块中。这样,您就不需要在每个子例程中声明
外部GaussElim
,因为编译器将知道模块中的所有子例程以及它们期望的参数。要做到这一点,只需将所有这些子例程放在一个文件中,并将它们放在中间:

module gauss_mod

implicit none

contains

! your code here

end module gauss_mod
然后在主程序中,只需将
use gauss_mod
放在顶部,就可以访问模块中的所有子程序。
implicit none
告诉编译器您将声明所有变量,并且它不应该猜测您没有告诉它的任何变量的类型。例如,这将捕获许多由打字错误引起的错误

其次,您需要向子例程声明参数。这就是造成大多数错误的原因。除了
GaussElim
,其他子程序都不知道像
A
这样的变量是什么。因此,当编译器看到

s(i) = ABS(A(i,1))
它认为
A(i,1)
是一个函数,并给出与此相关的错误。只需在子程序中添加以下行即可修复此问题:

double precision, dimension(:,:) :: A
这告诉子程序A必须有两个维度,但可以是任意大小。 您还应该为输入参数添加
intent(in)
,为输出参数添加
intent(out)
,为子程序更改的参数添加
intent(inout)

此外,使用
real
并设置
种类
参数,而不是使用
双精度

module gauss_mod

implicit none

integer, parameter :: dp = selected_real_kind(15)

contains

! your code here

  ! As an example:
  subroutine gauss(a, b, n, x, er)
    ! dummy arguments
    real(kind=dp), dimension(:,:), intent(in) :: a, b
    integer, intent(in) :: n
    real(kind=dp), dimension(:), intent(out) :: x
    real(kind=dp), intent(out) :: er

    real(kind=dp), dimension(10) :: S(10)
    real(kind=dp), parameter :: tol = 0.000001

    ! rest of subroutine
  end subroutine gauss

end module gauss_mod

做这些事情会消除很多错误。如果仍有错误,则应发布准确的错误消息,并指出它们所指的代码行。

首先,应确保将所有这些子例程放在一个模块中。这样,您就不需要在每个子例程中声明
外部GaussElim
,因为编译器将知道模块中的所有子例程,并且