Results 1 to 6 of 6

Thread: PureBasic --> Timing Matrix Inversions

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #1
    thinBasic MVPs danbaron's Avatar
    Join Date
    Jan 2010
    Location
    California
    Posts
    1,378
    Rep Power
    152

    PureBasic --> Timing Matrix Inversions

    [font=courier new][size=8pt]Here is a PureBasic program which times matrix inversions.

    It was made with PureBasic, version 4.5.

    The program fills an N x N matrix with random doubles in the range of [0, 2147483647], and inverts it using the same
    algorithm that was used for the corresponding C, Java, and PowerBASIC programs.

    The program runs in a console window, and indicates its progress in the window.

    It times the inversion, and then writes the elapsed time, and a check vector to the file, "MATINV.TXT". If every value
    of the N-dimensional check vector is very close to 1, then the inversion is correct.

    From within the PureBasic IDE, there are three ways you can compile a program; "Compile with Debugger", "Compile without
    Debugger", and, "Create Executable...". I used, "Create Executable...", for the times listed below. In other words, I
    made the ".exe" file, and double clicked on it to time the inversions.

    I ran the program three times for a 1000 x 1000 matrix.

    I'll compare it to my results for PowerBASIC.

    A = PowerBASIC, using the internal function, "MAT INV()".
    B = PowerBASIC, using my coding of the algorithm (a subroutine).
    C = PureBasic, using my coding of the algorithm (a procedure).

    The times on my machine were (seconds),

    A B C
    105.881 54.896 37.627
    104.301 54.863 37.784
    104.918 55.051 37.643

    I attached the program file below. I called it, "MATINV.PB.TXT".

    I also attached the ".exe" file, in case someone wants to try it who doesn't have PureBasic. I called it,
    "MATINV.EXE.TXT". (The ".exe" file, is only 16 KB.)

    If you download the files, then, remove the ".TXT" extensions.


    Dan

    ;************************************************************************************************************
    
    ; FILE = "MATINV.PB"
    
    ; Made with the PureBasic, version 4.5.
    
    ; The program runs in a console window, and indicates its progress in the window.
    
    ; It fills an N x N matrix with random doubles in the range of [0, 2147483647],
    ; and inverts it using the procedure, "INV()", below.
    ; It times the inversion, and then writes the elapsed time, and a check vector to the file, "MATINV.TXT".
    ; If every value of the N-dimensional check vector is very close to 1, then the inversion is correct.
    
    ; 2010 - 08 - 09:
    ; The program uses the same inversion algorithm that was used in the corresponding, C, Java, and PowerBASIC programs.
    
    ;************************************************************************************************************
    
    EnableExplicit
    
    ;Set the size of the N x N matrix to invert, on the next line.
    #N = 1000
    
    #NMO = #N - 1
    
    #FN = "MATINV.TXT"
    
    ;************************************************************************************************************
    ;************************************************************************************************************
    ;************************************************************************************************************
    
    Global DATE.S
    Global TIME.S
    Global T1.D
    Global T2.D
    Global TT.D
    Global Dim A0.D(#NMO, #NMO)
    Global Dim AI.D(#NMO, #NMO)
    Global Dim ID.D(#NMO, #NMO)
    Global Dim VA.D(#NMO)
    Global Dim VB.D(#NMO)
    
    ;---------------------------------------------
    
    Declare INITIALIZEARRAYS(Array A1.D(2), Array A2.D(2), Array V.D(1))
    Declare CONSOLEOUTPUT(WHICHTIME.I, T.D)
    Declare WRITEFILE(Array V.D(1), T.D)
    Declare INV(Array A.D(2))
    Declare MATMATMULT(Array M1.D(2), Array M2.D(2), Array M3.D(2))
    Declare MATVECMULT(Array M1.D(2), Array V1.D(1), Array V2.D(1))
    
    ;---------------------------------------------
    
    DATE = FormatDate("%yyyy-%mm-%dd", Date())
    TIME = FormatDate("%hh:%ii:%ss", Date())
    
    ;---------------------------------------------
    
    Define DUMB.S
    
    ;---------------------------------------------
    
    OpenConsole()
    
    INITIALIZEARRAYS(A0(), AI(), VA())
    
    CONSOLEOUTPUT(1, TT)
    
    T1 = ElapsedMilliseconds()
    INV(AI())
    T2 = ElapsedMilliseconds()
    TT = (T2 - T1) / 1000
    
    CONSOLEOUTPUT(2, TT)
    
    MATMATMULT(A0(), AI(), ID())
    MATVECMULT(ID(), VA(), VB())
    
    WRITEFILE(VB(), TT)
    
    CONSOLEOUTPUT(3, TT)
    DUMB = Input()
    
    ;************************************************************************************************************
    ;************************************************************************************************************
    ;************************************************************************************************************
    
    Procedure INITIALIZEARRAYS(Array A1.D(2), Array A2.D(2), Array V.D(1))
    Define FIRST.I, LAST.I, I.I, J.I, D.D
    
    FIRST = 0
    LAST = ArraySize(V())
    
    For I = FIRST To LAST
    V(I) = 1
    For J = FIRST To LAST
    D = Random(2147483647)
    A1(I, J) = D
    A2(I, J) = D
    Next
    Next
    EndProcedure
    
    ;************************************************************************************************************
    ;************************************************************************************************************
    ;************************************************************************************************************
    
    Procedure CONSOLEOUTPUT(WHICHTIME.I, T.D)
    Define SO.S, SN.S, ST.S
    
    SN = Str(#N)
    ST = StrD(T, 3)
    
    Select WHICHTIME
    
    Case 1
    SO = "Inverting a " + SN + " by " + SN + " matrix.."
    PrintN("")
    PrintN(SO)
    PrintN("")
    
    Case 2
    PrintN("Done.")
    PrintN("")
    SO = "elapsed time = " + ST + " seconds"
    PrintN(SO)
    PrintN("")
    PrintN("Calculating and writing the check vector..")
    PrintN("")
    
    Case 3
    PrintN("Done.")
    PrintN("")
    PrintN("Press 'Enter' to quit.")
    PrintN("")
    
    Default
    PrintN("Something wrong.")
    PrintN("")
    
    EndSelect
    
    EndProcedure
    
    ;************************************************************************************************************
    ;************************************************************************************************************
    ;************************************************************************************************************
    
    Procedure WRITEFILE(Array V.D(1), T.D)
    Define FIRST.I, LAST.I, I.I
    Define S1.S, S2.S, SN.S, SO.S, ST.S
    
    FIRST = 0
    LAST = ArraySize(V())
    
    SN = Str(#N)
    ST = StrD(T, 3)
    
    CreateFile(0, #FN)
    
    S1 = "; FILE = " + "'" + #FN + "'"
    WriteStringN(0, S1)
    S1 = "; " + DATE + ", " + TIME + "."
    WriteStringN(0, S1)
    WriteStringN(0, "")
    S1 = "; Inversion of a " + SN + " by " + SN + " matrix,"
    WriteStringN(0, S1)
    WriteStringN(0, "; filled with uniformly distributed random doubles,")
    WriteStringN(0, "; in the range of [0, 2147483647].")
    WriteStringN(0, "")
    S1 = "; elapsed time = " + ST + " seconds"
    WriteStringN(0, S1)
    WriteStringN(0, "")
    WriteStringN(0, "; If the inversion was calculated correctly, then every")
    WriteStringN(0, "; value shown below should be very close to 1.")
    WriteStringN(0, "")
    WriteStringN(0, "Index      Value")
    
    For I = FIRST To LAST
    S1 = RSet(Str(I + 1), 4, "0")
    S1 = S1 + "  "
    S2 = StrD(V(I), 20)
    S1 = S1 + S2
    WriteStringN(0, S1)
    Next
    
    CloseFile(0)
    
    EndProcedure
    
    ;************************************************************************************************************
    ;************************************************************************************************************
    ;************************************************************************************************************
    
    Procedure INV(Array A.D(2))
    ;Uses the Gauss-Jordan Method.
    ;Inverts matrix, A(), "in-place".
    
    Define PIVOT.I, ROW.I, COL.I, MAXROW.I, ROWSWITCH.I, SWITCHCOUNT.I, FIRST.I, LAST.I
    Define TEST.D, TEMP.D, COLMAX.D, DIVISOR.D, FACTOR.D, TEMP.D
    
    ;---------------------------------------------
    
    FIRST = 0
    LAST = ArraySize(A(), 1)
    
    Dim ROWSWITCHES.I(#NMO, 1)
    
    SWITCHCOUNT = -1
    
    For PIVOT = FIRST To LAST
    
    COLMAX = 0
    MAXROW = PIVOT
    
    ;---------------------------------------------
    
    For ROW = PIVOT To LAST
    TEST = Abs(A(ROW, PIVOT))
    If( TEST > COLMAX)
    COLMAX = TEST
    MAXROW = ROW
    EndIf
    Next
    
    ;---------------------------------------------
    
    If(MAXROW <> PIVOT)
    For COL = FIRST To LAST
    TEMP = A(PIVOT, COL)
    A(PIVOT, COL) = A(MAXROW, COL)
    A(MAXROW, COL) = TEMP
    Next
    
    SWITCHCOUNT = SWITCHCOUNT + 1
    ROWSWITCHES(SWITCHCOUNT, 0) = PIVOT
    ROWSWITCHES(SWITCHCOUNT, 1) = MAXROW
    EndIf
    
    ;---------------------------------------------
    
    DIVISOR = A(PIVOT, PIVOT)
    A(PIVOT, PIVOT) = 1
    
    For COL = FIRST To LAST
    A(PIVOT, COL) = A(PIVOT, COL) / DIVISOR
    Next
    
    ;---------------------------------------------
    
    For ROW = FIRST To LAST
    
    If(ROW <> PIVOT)
    
    FACTOR = -A(ROW, PIVOT)
    A(ROW, PIVOT) = 0
    
    For COL = FIRST To LAST
    A(ROW, COL) = A(ROW, COL) + A(PIVOT, COL) * FACTOR
    Next
    
    EndIf
    Next
    
    Next
    
    ;---------------------------------------------
    
    For ROWSWITCH = SWITCHCOUNT To 1 Step -1
    For ROW = FIRST To LAST
    TEMP = A(ROW, ROWSWITCHES(ROWSWITCH, 0))
    A(ROW, ROWSWITCHES(ROWSWITCH, 0)) = A(ROW, ROWSWITCHES(ROWSWITCH, 1))
    A(ROW, ROWSWITCHES(ROWSWITCH, 1)) = TEMP
    Next
    Next
    
    EndProcedure
    
    ;************************************************************************************************************
    ;************************************************************************************************************
    ;************************************************************************************************************
    ;************************************************************************************************
    
    Procedure MATMATMULT(Array M1.D(2), Array M2.D(2), Array M3.D(2))
    Define I.I, J.I, K.I, FIRST.I, LAST.I
    
    FIRST = 0
    LAST = ArraySize(M1(), 1)
    
    For I = FIRST To LAST
    For J = FIRST To LAST
    M3(I, J) = 0; 
    For K = FIRST To LAST
     M3(I, J) = M3(I, J) + M1(I, K) * M2(K, J);
    Next
    Next
    Next
    EndProcedure
    
    ;************************************************************************************************
    ;************************************************************************************************
    ;************************************************************************************************
    
    Procedure MATVECMULT(Array M1.D(2), Array V1.D(1), Array V2.D(1))
    Define I.I, J.I, K.I, FIRST.I, LAST.I
    
    FIRST = 0;
    LAST = ArraySize(M1(), 1)
    
    For I = FIRST To LAST
    V2(I) = 0;
    For J = FIRST To LAST
    V2(I) = V2(I) + M1(I, J) * V1(J) 
    Next
    Next
    EndProcedure
    
    ;************************************************************************************************
    ;************************************************************************************************
    ;************************************************************************************************
    
    Attached Files Attached Files
    "You can't cheat an honest man. Never give a sucker an even break, or smarten up a chump." - W.C.Fields

Members who have read this thread: 0

There are no members to list at the moment.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •