Professional Documents
Culture Documents
He visto que muchas personas que programan con Visual Basic preguntan sobre la
matriz inversa, me doy cuenta que es un poco difícil encontrarla en Internet. En este
documento me gustaría colocar como se hace.
Figura 1
AutoRedraw = True
Figura 2
The University of Tennessee Modified by Nilson
Figura 3
Figura 4
The University of Tennessee Modified by Nilson
Doble click
Figura 5.
Figura 6
Copie el siguiente código y péguelo dentro de esta ventana (el tamaño de la letra
fue reducido para ahorrar espacio en este documento, NO NECESITA LEERLO):
The University of Tennessee Modified by Nilson
Result.X = X
Result.Y = 0
C_Complex = Result
End Function
XABS = Abs(Z.X)
YABS = Abs(Z.Y)
W = MaxReal(XABS, YABS)
V = MinReal(XABS, YABS)
If V = 0 Then
Result = W
Else
Result = W * Sqr(1 + Square(V / W))
End If
AbsComplex = Result
End Function
The University of Tennessee Modified by Nilson
Result.X = -Z.X
Result.Y = -Z.Y
C_Opposite = Result
End Function
Result.X = Z.X
Result.Y = -Z.Y
Conj = Result
End Function
CSqr = Result
End Function
C_Add = Result
End Function
C_Mul = Result
End Function
Result.X = Z1.X + R
Result.Y = Z1.Y
C_AddR = Result
End Function
Result.X = Z1.X * R
Result.Y = Z1.Y * R
C_MulR = Result
End Function
C_Sub = Result
End Function
Result.X = Z1.X - R
Result.Y = Z1.Y
C_SubR = Result
End Function
Result.X = R - Z1.X
Result.Y = -Z1.Y
C_RSub = Result
End Function
A = Z1.X
B = Z1.Y
C = Z2.X
D = Z2.Y
If Abs(D) < Abs(C) Then
E=D/C
F=C+D*E
Result.X = (A + B * E) / F
Result.Y = (B - A * E) / F
Else
E=C/D
F=D+C*E
Result.X = (B + A * E) / F
Result.Y = (-A + B * E) / F
End If
C_Div = Result
End Function
Result.X = Z1.X / R
Result.Y = Z1.Y / R
C_DivR = Result
End Function
A=R
C = Z2.X
D = Z2.Y
The University of Tennessee Modified by Nilson
C_RDiv = Result
End Function
C_Equal = Result
End Function
C_NotEqual = Result
End Function
C_EqualR = Result
End Function
C_NotEqualR = Result
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Copyright (c) 1992-2007 The University of Tennessee. All rights reserved.
'
'Contributors:
' * Sergey Bochkanov (ALGLIB project). Translation from FORTRAN to
' pseudocode.
'
'See subroutines comments for additional copyrights.
'
'Redistribution and use in source and binary forms, with or without
'modification, are permitted provided that the following conditions are
'met:
'
'- Redistributions of source code must retain the above copyright
' notice, this list of conditions and the following disclaimer.
'
'- Redistributions in binary form must reproduce the above copyright
' notice, this list of conditions and the following disclaimer listed
' in this license in the documentation and/or other materials
' provided with the distribution.
'
'- Neither the name of the copyright holders nor the names of its
' contributors may be used to endorse or promote products derived from
' this software without specific prior written permission.
'
'THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
'"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
'LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
'A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
'OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
'SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
'LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
'DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
'THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
'(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
'OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Routines
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Inversion of a matrix given by its LU decomposition.
'
'Input parameters:
' A - LU decomposition of the matrix (output of RMatrixLU subroutine).
' Pivots - table of permutations which were made during the LU decomposition
' (the output of RMatrixLU subroutine).
' N - size of matrix A.
'
'Output parameters:
' A - inverse of matrix A.
' Array whose indexes range within [0..N-1, 0..N-1].
'
'Result:
' True, if the matrix is not singular.
' False, if the matrix is singular.
'
' -- LAPACK routine (version 3.0) --
' Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
' Courant Institute, Argonne National Lab, and Rice University
' February 29, 1992
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Function RMatrixLUInverse(ByRef A() As Double, _
ByRef Pivots() As Long, _
ByVal N As Long) As Boolean
Dim Result As Boolean
Dim WORK() As Double
Dim I As Long
Dim IWS As Long
Dim J As Long
Dim JB As Long
Dim JJ As Long
Dim JP As Long
Dim V As Double
Dim i_ As Long
Result = True
'
' Quick return if possible
'
If N = 0# Then
RMatrixLUInverse = Result
Exit Function
End If
ReDim WORK(0# To N - 1#)
'
' Form inv(U)
'
If Not RMatrixTRInverse(A, N, True, False) Then
Result = False
RMatrixLUInverse = Result
Exit Function
End If
'
' Solve the equation inv(A)*L = inv(U) for inv(A).
'
The University of Tennessee Modified by Nilson
For J = N - 1# To 0# Step -1
'
' Copy current column of L to WORK and replace with zeros.
'
For I = J + 1# To N - 1# Step 1
WORK(I) = A(I, J)
A(I, J) = 0#
Next I
'
' Compute current column of inv(A).
'
If J < N - 1# Then
For I = 0# To N - 1# Step 1
V = 0#
For i_ = J + 1# To N - 1# Step 1
V = V + A(I, i_) * WORK(i_)
Next i_
A(I, J) = A(I, J) - V
Next I
End If
Next J
'
' Apply column interchanges.
'
For J = N - 2# To 0# Step -1
JP = Pivots(J)
If JP <> J Then
For i_ = 0# To N - 1# Step 1
WORK(i_) = A(i_, J)
Next i_
For i_ = 0# To N - 1# Step 1
A(i_, J) = A(i_, JP)
Next i_
For i_ = 0# To N - 1# Step 1
A(i_, JP) = WORK(i_)
Next i_
End If
Next J
RMatrixLUInverse = Result
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Inversion of a general matrix.
'
'Input parameters:
' A - matrix. Array whose indexes range within [0..N-1, 0..N-1].
' N - size of matrix A.
'
'Output parameters:
' A - inverse of matrix A.
' Array whose indexes range within [0..N-1, 0..N-1].
'
'Result:
' True, if the matrix is not singular.
' False, if the matrix is singular.
'
' -- ALGLIB --
' Copyright 2005 by Bochkanov Sergey
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Function RMatrixInverse(ByRef A() As Double, ByVal N As Long) As Boolean
Dim Result As Boolean
Dim Pivots() As Long
RMatrixInverse = Result
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Obsolete 1-based subroutine.
'
'See RMatrixLUInverse for 0-based replacement.
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Function InverseLU(ByRef A() As Double, _
ByRef Pivots() As Long, _
ByVal N As Long) As Boolean
Dim Result As Boolean
Dim WORK() As Double
Dim I As Long
Dim IWS As Long
Dim J As Long
Dim JB As Long
Dim JJ As Long
Dim JP As Long
Dim JP1 As Long
Dim V As Double
Dim i_ As Long
Result = True
'
' Quick return if possible
'
If N = 0# Then
InverseLU = Result
Exit Function
End If
ReDim WORK(1# To N)
'
' Form inv(U)
'
If Not InvTriangular(A, N, True, False) Then
Result = False
InverseLU = Result
Exit Function
End If
'
' Solve the equation inv(A)*L = inv(U) for inv(A).
'
For J = N To 1# Step -1
'
' Copy current column of L to WORK and replace with zeros.
'
For I = J + 1# To N Step 1
WORK(I) = A(I, J)
A(I, J) = 0#
Next I
'
' Compute current column of inv(A).
'
If J < N Then
JP1 = J + 1#
For I = 1# To N Step 1
V = 0#
For i_ = JP1 To N Step 1
V = V + A(I, i_) * WORK(i_)
Next i_
A(I, J) = A(I, J) - V
Next I
End If
Next J
'
' Apply column interchanges.
'
For J = N - 1# To 1# Step -1
JP = Pivots(J)
The University of Tennessee Modified by Nilson
If JP <> J Then
For i_ = 1# To N Step 1
WORK(i_) = A(i_, J)
Next i_
For i_ = 1# To N Step 1
A(i_, J) = A(i_, JP)
Next i_
For i_ = 1# To N Step 1
A(i_, JP) = WORK(i_)
Next i_
End If
Next J
InverseLU = Result
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Obsolete 1-based subroutine.
'
'See RMatrixInverse for 0-based replacement.
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Function Inverse(ByRef A() As Double, ByVal N As Long) As Boolean
Dim Result As Boolean
Dim Pivots() As Long
Inverse = Result
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Copyright (c) 1992-2007 The University of Tennessee. All rights reserved.
'
'Contributors:
' * Sergey Bochkanov (ALGLIB project). Translation from FORTRAN to
' pseudocode.
'
'See subroutines comments for additional copyrights.
'
'Redistribution and use in source and binary forms, with or without
'modification, are permitted provided that the following conditions are
'met:
'
'- Redistributions of source code must retain the above copyright
' notice, this list of conditions and the following disclaimer.
'
'- Redistributions in binary form must reproduce the above copyright
' notice, this list of conditions and the following disclaimer listed
' in this license in the documentation and/or other materials
' provided with the distribution.
'
'- Neither the name of the copyright holders nor the names of its
' contributors may be used to endorse or promote products derived from
' this software without specific prior written permission.
'
'THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
'"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
'LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
'A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
'OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
'SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
'LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
'DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
'THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
'(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
'OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Global constants
'Routines
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'LU decomposition of a general matrix of size MxN
'
'The subroutine calculates the LU decomposition of a rectangular general
'matrix with partial pivoting (with row permutations).
'
'Input parameters:
' A - matrix A whose indexes range within [0..M-1, 0..N-1].
' M - number of rows in matrix A.
' N - number of columns in matrix A.
'
'Output parameters:
' A - matrices L and U in compact form (see below).
' Array whose indexes range within [0..M-1, 0..N-1].
' Pivots - permutation matrix in compact form (see below).
' Array whose index ranges within [0..Min(M-1,N-1)].
'
'Matrix A is represented as A = P * L * U, where P is a permutation matrix,
'matrix L - lower triangular (or lower trapezoid, if M>N) matrix,
'U - upper triangular (or upper trapezoid, if M<N) matrix.
'
'Let M be equal to 4 and N be equal to 3:
'
' ( 1 ) ( U11 U12 U13 )
'A = P1 * P2 * P3 * ( L21 1 ) *( U22 U23 )
' ( L31 L32 1 ) ( U33 )
' ( L41 L42 L43 )
'
'Matrix L has size MxMin(M,N), matrix U has size Min(M,N)xN, matrix P(i) is
'a permutation of the identity matrix of size MxM with numbers I and Pivots[I].
'
'The algorithm returns array Pivots and the following matrix which replaces
'matrix A and contains matrices L and U in compact form (the example applies
'to M=4, N=3).
'
' ( U11 U12 U13 )
' ( L21 U22 U23 )
' ( L31 L32 U33 )
' ( L41 L42 L43 )
'
'As we can see, the unit diagonal isn't stored.
'
' -- LAPACK routine (version 3.0) --
' Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
' Courant Institute, Argonne National Lab, and Rice University
' June 30, 1992
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Sub RMatrixLU(ByRef A() As Double, _
ByVal M As Long, _
ByVal N As Long, _
ByRef Pivots() As Long)
Dim B() As Double
Dim T() As Double
Dim BP() As Long
Dim MinMN As Long
Dim I As Long
Dim IP As Long
Dim J As Long
Dim J1 As Long
Dim J2 As Long
Dim CB As Long
Dim NB As Long
Dim V As Double
Dim i_ As Long
Dim i1_ As Long
NB = LUNB
'
' Decide what to use - blocked or unblocked code
'
If N <= 1# Or MinInt(M, N) <= NB Or NB = 1# Then
The University of Tennessee Modified by Nilson
'
' Unblocked code
'
Call RMatrixLU2(A, M, N, Pivots)
Else
'
' Blocked code.
' First, prepare temporary matrix and indices
'
ReDim B(0# To M - 1#, 0# To NB - 1#)
ReDim T(0# To N - 1#)
ReDim Pivots(0# To MinInt(M, N) - 1#)
MinMN = MinInt(M, N)
J1 = 0#
J2 = MinInt(MinMN, NB) - 1#
'
' Main cycle
'
Do While J1 < MinMN
CB = J2 - J1 + 1#
'
' LU factorization of diagonal and subdiagonal blocks:
' 1. Copy columns J1..J2 of A to B
' 2. LU(B)
' 3. Copy result back to A
' 4. Copy pivots, apply pivots
'
For I = J1 To M - 1# Step 1
i1_ = (J1) - (0#)
For i_ = 0# To CB - 1# Step 1
B(I - J1, i_) = A(I, i_ + i1_)
Next i_
Next I
Call RMatrixLU2(B, M - J1, CB, BP)
For I = J1 To M - 1# Step 1
i1_ = (0#) - (J1)
For i_ = J1 To J2 Step 1
A(I, i_) = B(I - J1, i_ + i1_)
Next i_
Next I
For I = 0# To CB - 1# Step 1
IP = BP(I)
Pivots(J1 + I) = J1 + IP
If BP(I) <> I Then
If J1 <> 0# Then
'
' Interchange columns 0:J1-1
'
For i_ = 0# To J1 - 1# Step 1
T(i_) = A(J1 + I, i_)
Next i_
For i_ = 0# To J1 - 1# Step 1
A(J1 + I, i_) = A(J1 + IP, i_)
Next i_
For i_ = 0# To J1 - 1# Step 1
A(J1 + IP, i_) = T(i_)
Next i_
End If
If J2 < N - 1# Then
'
' Interchange the rest of the matrix, if needed
'
For i_ = J2 + 1# To N - 1# Step 1
T(i_) = A(J1 + I, i_)
Next i_
For i_ = J2 + 1# To N - 1# Step 1
A(J1 + I, i_) = A(J1 + IP, i_)
Next i_
For i_ = J2 + 1# To N - 1# Step 1
A(J1 + IP, i_) = T(i_)
Next i_
End If
End If
Next I
'
' Compute block row of U
'
If J2 < N - 1# Then
For I = J1 + 1# To J2 Step 1
For J = J1 To I - 1# Step 1
V = A(I, J)
For i_ = J2 + 1# To N - 1# Step 1
A(I, i_) = A(I, i_) - V * A(J, i_)
Next i_
Next J
Next I
End If
'
' Update trailing submatrix
'
If J2 < N - 1# Then
For I = J2 + 1# To M - 1# Step 1
For J = J1 To J2 Step 1
V = A(I, J)
For i_ = J2 + 1# To N - 1# Step 1
A(I, i_) = A(I, i_) - V * A(J, i_)
Next i_
Next J
Next I
End If
'
' Next step
'
J1 = J2 + 1#
J2 = MinInt(MinMN, J1 + NB) - 1#
Loop
End If
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Obsolete 1-based subroutine. Left for backward compatibility.
'See RMatrixLU for 0-based replacement.
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Sub LUDecomposition(ByRef A() As Double, _
ByVal M As Long, _
ByVal N As Long, _
ByRef Pivots() As Long)
Dim I As Long
Dim J As Long
Dim JP As Long
Dim T1() As Double
Dim s As Double
Dim i_ As Long
'
' Quick return if possible
'
If M = 0# Or N = 0# Then
Exit Sub
End If
For J = 1# To MinInt(M, N) Step 1
'
' Find pivot and test for singularity.
'
JP = J
For I = J + 1# To M Step 1
The University of Tennessee Modified by Nilson
'
'Apply the interchange to rows
'
If JP <> J Then
For i_ = 1# To N Step 1
T1(i_) = A(J, i_)
Next i_
For i_ = 1# To N Step 1
A(J, i_) = A(JP, i_)
Next i_
For i_ = 1# To N Step 1
A(JP, i_) = T1(i_)
Next i_
End If
'
'Compute elements J+1:M of J-th column.
'
If J < M Then
'
' CALL DSCAL( M-J, ONE / A( J, J ), A( J+1, J ), 1 )
'
JP = J + 1#
s = 1# / A(J, J)
For i_ = JP To M Step 1
A(i_, J) = s * A(i_, J)
Next i_
End If
End If
If J < MinInt(M, N) Then
'
'Update trailing submatrix.
'CALL DGER( M-J, N-J, -ONE, A( J+1, J ), 1, A( J, J+1 ), LDA,A( J+1, J+1 ), LDA )
'
JP = J + 1#
For I = J + 1# To M Step 1
s = A(I, J)
For i_ = JP To N Step 1
A(I, i_) = A(I, i_) - s * A(J, i_)
Next i_
Next I
End If
Next J
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Obsolete 1-based subroutine. Left for backward compatibility.
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Sub LUDecompositionUnpacked(ByRef A_() As Double, _
ByVal M As Long, _
ByVal N As Long, _
ByRef L() As Double, _
ByRef U() As Double, _
ByRef Pivots() As Long)
Dim A() As Double
Dim I As Long
Dim J As Long
Dim MinMN As Long
A = A_
If M = 0# Or N = 0# Then
Exit Sub
End If
MinMN = MinInt(M, N)
ReDim L(1# To M, 1# To MinMN)
ReDim U(1# To MinMN, 1# To N)
Call LUDecomposition(A, M, N, Pivots)
For I = 1# To M Step 1
For J = 1# To MinMN Step 1
If J > I Then
L(I, J) = 0#
End If
If J = I Then
L(I, J) = 1#
End If
If J < I Then
L(I, J) = A(I, J)
End If
Next J
Next I
For I = 1# To MinMN Step 1
For J = 1# To N Step 1
If J < I Then
U(I, J) = 0#
End If
If J >= I Then
U(I, J) = A(I, J)
End If
Next J
Next I
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Level 2 BLAS version of RMatrixLU
'
' -- LAPACK routine (version 3.0) --
' Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
' Courant Institute, Argonne National Lab, and Rice University
' June 30, 1992
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Sub RMatrixLU2(ByRef A() As Double, _
ByVal M As Long, _
ByVal N As Long, _
ByRef Pivots() As Long)
Dim I As Long
Dim J As Long
Dim JP As Long
Dim T1() As Double
Dim s As Double
Dim i_ As Long
'
' Quick return if possible
'
If M = 0# Or N = 0# Then
Exit Sub
End If
For J = 0# To MinInt(M - 1#, N - 1#) Step 1
'
' Find pivot and test for singularity.
'
JP = J
For I = J + 1# To M - 1# Step 1
If Abs(A(I, J)) > Abs(A(JP, J)) Then
JP = I
End If
Next I
Pivots(J) = JP
If A(JP, J) <> 0# Then
'
'Apply the interchange to rows
'
The University of Tennessee Modified by Nilson
If JP <> J Then
For i_ = 0# To N - 1# Step 1
T1(i_) = A(J, i_)
Next i_
For i_ = 0# To N - 1# Step 1
A(J, i_) = A(JP, i_)
Next i_
For i_ = 0# To N - 1# Step 1
A(JP, i_) = T1(i_)
Next i_
End If
'
'Compute elements J+1:M of J-th column.
'
If J < M Then
JP = J + 1#
s = 1# / A(J, J)
For i_ = JP To M - 1# Step 1
A(i_, J) = s * A(i_, J)
Next i_
End If
End If
If J < MinInt(M, N) - 1# Then
'
'Update trailing submatrix.
'
JP = J + 1#
For I = J + 1# To M - 1# Step 1
s = A(I, J)
For i_ = JP To N - 1# Step 1
A(I, i_) = A(I, i_) - s * A(J, i_)
Next i_
Next I
End If
Next J
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Copyright (c) 1992-2007 The University of Tennessee. All rights reserved.
'
'Contributors:
' * Sergey Bochkanov (ALGLIB project). Translation from FORTRAN to
' pseudocode.
'
'See subroutines comments for additional copyrights.
'
'Redistribution and use in source and binary forms, with or without
'modification, are permitted provided that the following conditions are
'met:
'
'- Redistributions of source code must retain the above copyright
' notice, this list of conditions and the following disclaimer.
'
'- Redistributions in binary form must reproduce the above copyright
' notice, this list of conditions and the following disclaimer listed
' in this license in the documentation and/or other materials
' provided with the distribution.
'
'- Neither the name of the copyright holders nor the names of its
' contributors may be used to endorse or promote products derived from
' this software without specific prior written permission.
'
'THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
'"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
'LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
'A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
'OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
'SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
'LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
'DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
'THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
'(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
'OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Routines
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Triangular matrix inversion
'
'The subroutine inverts the following types of matrices:
' * upper triangular
' * upper triangular with unit diagonal
' * lower triangular
' * lower triangular with unit diagonal
'
'In case of an upper (lower) triangular matrix, the inverse matrix will
'also be upper (lower) triangular, and after the end of the algorithm, the
'inverse matrix replaces the source matrix. The elements below (above) the
'main diagonal are not changed by the algorithm.
'
'If the matrix has a unit diagonal, the inverse matrix also has a unit
'diagonal, and the diagonal elements are not passed to the algorithm.
'
'Input parameters:
' A - matrix.
' Array whose indexes range within [0..N-1, 0..N-1].
' N - size of matrix A.
' IsUpper - True, if the matrix is upper triangular.
' IsUnitTriangular
' - True, if the matrix has a unit diagonal.
'
'Output parameters:
' A - inverse matrix (if the problem is not degenerate).
'
'Result:
' True, if the matrix is not singular.
' False, if the matrix is singular.
'
' -- LAPACK routine (version 3.0) --
' Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
' Courant Institute, Argonne National Lab, and Rice University
' February 29, 1992
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Result = True
ReDim T(0# To N - 1#)
'
' Test the input parameters.
'
NOUNIT = Not IsUnitTriangular
If IsUpper Then
The University of Tennessee Modified by Nilson
'
' Compute inverse of upper triangular matrix.
'
For J = 0# To N - 1# Step 1
If NOUNIT Then
If A(J, J) = 0# Then
Result = False
RMatrixTRInverse = Result
Exit Function
End If
A(J, J) = 1# / A(J, J)
AJJ = -A(J, J)
Else
AJJ = -1#
End If
'
' Compute elements 1:j-1 of j-th column.
'
If J > 0# Then
For i_ = 0# To J - 1# Step 1
T(i_) = A(i_, J)
Next i_
For I = 0# To J - 1# Step 1
If I < J - 1# Then
V = 0#
For i_ = I + 1# To J - 1# Step 1
V = V + A(I, i_) * T(i_)
Next i_
Else
V = 0#
End If
If NOUNIT Then
A(I, J) = V + A(I, I) * T(I)
Else
A(I, J) = V + T(I)
End If
Next I
For i_ = 0# To J - 1# Step 1
A(i_, J) = AJJ * A(i_, J)
Next i_
End If
Next J
Else
'
' Compute inverse of lower triangular matrix.
'
For J = N - 1# To 0# Step -1
If NOUNIT Then
If A(J, J) = 0# Then
Result = False
RMatrixTRInverse = Result
Exit Function
End If
A(J, J) = 1# / A(J, J)
AJJ = -A(J, J)
Else
AJJ = -1#
End If
If J < N - 1# Then
'
' Compute elements j+1:n of j-th column.
'
For i_ = J + 1# To N - 1# Step 1
T(i_) = A(i_, J)
Next i_
For I = J + 1# To N - 1# Step 1
If I > J + 1# Then
V = 0#
For i_ = J + 1# To I - 1# Step 1
V = V + A(I, i_) * T(i_)
Next i_
Else
V = 0#
End If
If NOUNIT Then
A(I, J) = V + A(I, I) * T(I)
Else
A(I, J) = V + T(I)
End If
Next I
For i_ = J + 1# To N - 1# Step 1
A(i_, J) = AJJ * A(i_, J)
Next i_
End If
Next J
End If
RMatrixTRInverse = Result
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Obsolete 1-based subroutine.
'See RMatrixTRInverse for 0-based replacement.
'
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Function InvTriangular(ByRef A() As Double, _
ByVal N As Long, _
ByVal IsUpper As Boolean, _
ByVal IsUnitTriangular As Boolean) As Boolean
Dim Result As Boolean
Dim NOUNIT As Boolean
Dim I As Long
Dim J As Long
Dim NMJ As Long
Dim JM1 As Long
Dim JP1 As Long
Dim V As Double
Dim AJJ As Double
Dim T() As Double
Dim i_ As Long
Result = True
ReDim T(1# To N)
'
' Test the input parameters.
'
NOUNIT = Not IsUnitTriangular
If IsUpper Then
'
' Compute inverse of upper triangular matrix.
'
For J = 1# To N Step 1
If NOUNIT Then
If A(J, J) = 0# Then
Result = False
InvTriangular = Result
Exit Function
End If
A(J, J) = 1# / A(J, J)
AJJ = -A(J, J)
Else
AJJ = -1#
End If
'
' Compute elements 1:j-1 of j-th column.
'
If J > 1# Then
JM1 = J - 1#
For i_ = 1# To JM1 Step 1
T(i_) = A(i_, J)
Next i_
For I = 1# To J - 1# Step 1
If I < J - 1# Then
The University of Tennessee Modified by Nilson
V = 0#
For i_ = I + 1# To JM1 Step 1
V = V + A(I, i_) * T(i_)
Next i_
Else
V = 0#
End If
If NOUNIT Then
A(I, J) = V + A(I, I) * T(I)
Else
A(I, J) = V + T(I)
End If
Next I
For i_ = 1# To JM1 Step 1
A(i_, J) = AJJ * A(i_, J)
Next i_
End If
Next J
Else
'
' Compute inverse of lower triangular matrix.
'
For J = N To 1# Step -1
If NOUNIT Then
If A(J, J) = 0# Then
Result = False
InvTriangular = Result
Exit Function
End If
A(J, J) = 1# / A(J, J)
AJJ = -A(J, J)
Else
AJJ = -1#
End If
If J < N Then
'
' Compute elements j+1:n of j-th column.
'
NMJ = N - J
JP1 = J + 1#
For i_ = JP1 To N Step 1
T(i_) = A(i_, J)
Next i_
For I = J + 1# To N Step 1
If I > J + 1# Then
V = 0#
For i_ = JP1 To I - 1# Step 1
V = V + A(I, i_) * T(i_)
Next i_
Else
V = 0#
End If
If NOUNIT Then
A(I, J) = V + A(I, I) * T(I)
Else
A(I, J) = V + T(I)
End If
Next I
For i_ = JP1 To N Step 1
A(i_, J) = AJJ * A(i_, J)
Next i_
End If
Next J
End If
InvTriangular = Result
End Function
Figura 7
End Sub
The University of Tennessee Modified by Nilson
Figura 8
*Ahora Copie el siguiente código y péguelo dentro de esta ventana (NO NECESITA
LEERLO):
For II = 1 To UBound(Matriz())
For JJ = 1 To UBound(Matriz())
If SCI = True Then
EscribirMat = EscribirMat & Let27(Str(Format(Matriz(II, JJ), "0.0000000"))) & vbTab
ElseIf SCI = False Then
EscribirMat = EscribirMat & Let27(Str(Matriz(II, JJ))) & vbTab
End If
Next JJ
EscribirMat = EscribirMat & vbCrLf
Next II
Print EscribirMat
End Sub
nn = Val(InputBox("Tamaño de matriz"))
If nn = 0 Then Exit Sub
For II = 1 To nn
For JJ = 1 To nn
Matr(II, JJ) = InputBox("Elemento ( " & II & " , " & JJ & " ) = ")
Next JJ
Next II
Me.Cls
Print "Matriz a invertir"
Call MostrarMatriz(Matr(), False)
Print vbCrLf
End Sub
End Sub
The University of Tennessee Modified by Nilson
7) Ejecución de la aplicación Matriz Inversa en Visual Basic. Pulse este botón para ejecutar la aplicación
Figura 9.
Figura 10.
* De nuevo aparecerá un cuadro de texto por cada elemento de la matriz, esto es para
introducir cada elemento de la matriz cuadrada.
* Una vez introducidos todos los elementos de la matriz, el resultado se imprimirá en el
formulario.
Figura 11.