有谁知道无穷多解矩阵的算法?

解决方案 »

  1.   

    多项式及其导数之值 
    欲求 f(x)=anxn+an-1xn-1+....+a1x+a0 的多项式及其一阶导数在 x=x0 之值,我们可以很直觉地把 x0代入 f(x) 及 f'(x) 多项式之中来求解,程式码如下:
    '求多项式之值
    Public Function f(a() As Single, x As Single) As Single
         Dim i As Long
         For i = 0 To UBound(a)
              f = f + a(i) * x ^ i
         Next
    End Function'求一阶导数之值
    Public Function Df(a() As Single, x As Single) As Single
         Dim i As Long, b() As Single
         ReDim b(0 To UBound(a) - 1)
         For i = 1 To UBound(a)
              b(i - 1) = i * a(i)
         Next
         Df = f(b, x)
    End Function
    其中参数 a() 是多项式之系数,a(0)=a0、a(1)=a1 依此类推,参数 x 即为 x0,这样的程式虽然简单,但是执行起来比较没有效率,因为 f(x) 在 x=x0 之值可以化简成 f(x)=(x-x0)*g(x)+b0,这样可以减少乘法和加法的计算次数,所以我们只要把 b0 解出即可,同样的道理可应用于 f'(x),例如以下的程式码使用 Horner method 来解出多项式及其一阶导数之值。
    副程式:
    '求多项式之值
    Public Function fx(a() As Single, x As Single) As Single
         Dim i As Long
         fx = a(UBound(a))
         For i = UBound(a) - 1 To LBound(a) Step -1
              fx = a(i) + fx * x
         Next
    End Function'求一阶导数之值
    Public Function Dfx(a() As Single, x As Single) As Single
         Dim i As Long, fx As Single
         If (UBound(a) - LBound(a) = 0) Then Dfx = 0: Exit Function 
         fx = a(UBound(a)): Dfx = fx
         For i = UBound(a) - 1 To LBound(a) + 1 Step -1
              fx = a(i) + x * fx
              Dfx = fx + x * Dfx
         Next
    End Function
    参数说明:
    a():多项式之系数 a(0)=a0、a(1)=a1 依此类推。
    x:即为x0。
    范例:
    Private Sub Command1_Click()
         Dim Keyin As String, a() As Single, x As Single
         Keyin = InputBox("请输入多项式的系数,低阶项的系数先输入," & _
                      "再输入高阶项的系数,以空白来区隔。" & _
                      vbNewLine & "例如:f(x)=10x^3-5x+3,则依序输入 3  -5  0  10")
         If Not SepStrToNumArray(Keyin, " ", 0, a) Then MsgBox "输入了非数值": Exit Sub
         x = Val(InputBox("请输入x值"))
         Debug.Print "此多项式在x=" & x & "的值为 " & fx(a, x)
         Debug.Print "此多项式在x=" & x & "的一阶导数为 " & Dfx(a, x)
    End Sub
    例如 f(x)=10x3-5x+3 在 x=2.3 之值为113.17,一阶导数为153.7。
    其中 SepStrToNumArray 这个函数,请参阅本站的 将字串拆解成阵列 Lagrange Interpolation.  
    严格说来,Lagrange Interpolation 也算是一种 Curve fitting,它可以保证 fit 出来的多项式一定通过每一个已知的 f(x),但是由于它所 fit 出来的可能是高阶多项式 (如果有 n 个 f(x),fit 出来的多项式为 n-1 阶),所以 Lagrange Interpolation 比较适合 noise free 的系统,否则就必须使用其它方法,例如:Least Square 或 Cubic Spline Interpolation。Lagrange 多项式有一个比较重要的应用,就是用来导出数值微分和积分的方法,以及其误差范围。
    副程式:
    Public Function LagrangeInterpolation(x() As Single, f() As Single, dx As Single) As Single
         Dim i As Long, j As Long, n As Single, m As Single
         For i = 1 To UBound(x)
              m = x(i): n = 1
              For j = 1 To UBound(x)
                   If i <> j Then n = n * (dx - x(j)) / (m - x(j))
              Next
              LagrangeInterpolation = LagrangeInterpolation + n * f(i)
         Next
    End Function
    参数说明:
    x:x值的阵列,阵列基底为 1。
    f:f(x)值的阵列,阵列基底为 1。
    dx:欲内插的x值。
    范例:
    Private Sub Command1_Click()
         Dim Keyin As String, x() As Single, f() As Single, dx As Single
         Keyin = InputBox("请输入x值,以空白来区隔。")
         If Not SepStrToNumArray(Keyin, " ", 1, x) Then MsgBox "输入了非数值": Exit Sub
         Keyin = InputBox("请输入f(x)值,以空白来区隔。")
         If Not SepStrToNumArray(Keyin, " ", 1, f) Then MsgBox "输入了非数值": Exit Sub
         dx = Val(InputBox("请输入欲内插的x值"))
         Debug.Print "f(x)在x=" & dx & "的内插值为 " & LagrangeInterpolation(x, f, dx)
    End Sub
    其中 SepStrToNumArray 这个函数,请参阅本站的 将字串拆解成阵列。
    例如以下的数据以 Lagrange Interpolation 求 f(4.3) 之值:
    x 0 1.0 2.0 3.8 5
    f(x) 0 0.569 0.791 0.224 -0.185
    执行 Command1 并在提示输入 x 值时输入 0 1 2 3.8 5,提示输入 f(x) 值时输入 0 0.569 0.791 0.224 -0.185,则在 VB 的即时运算视窗可得 f(4.3)= -0.007