News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Reduced Row-Echelon Form of a Matrix Help

Started by brettc431, April 18, 2013, 12:35:02 AM

Previous topic - Next topic

dedndave

i haven't done much of this type stuff, but it doesn't look too difficult

http://en.wikipedia.org/wiki/Gauss%E2%80%93Jordan_elimination

QuoteThere are three types of elementary row operations: 1) Swapping two rows, 2) Multiplying a row by a
non-zero number, 3) Adding a multiple of one row to another row. Using these operations a matrix can
always be transformed into an upper triangular matrix, and in fact one that is in row echelon form.

FORTRANS

Hi,

   Since the matrix elements are floating point numbers, you
will need to use the FPU or SSE instructions.  And your
instructor should have routines to print the numbers out.

Cheers,

Steve N.

dedndave

Steve,
the assignment is merely to re-order the matrix
they are using MATLAB to generate the original matrix - and to display the results

FORTRANS

Hi Dave,

   He's going to do the stuff in Reply #9 without adding, subtracting,
and comparing floats?

Cheers,

Steve N.

dedndave

no - but he doesn't have to convert them to decimal   :P

the hard part will be the compares

QuoteAnd your instructor should have routines to print the numbers out.
MATLAB

brettc431

#20
Worked on the code a bit this morning so here's another look:

.MODEL SMALL ;Defines memory model as small which uses seperate segments for code and data
.386 ;Microprocessor number
.STACK ;Stack segment defined as 1024 by default
.DATA ;Begins definition of the data type used in this project

row DB ?
col DB ?
e DW ?
ep1 DW ?
D DB ?
d DW ?
ROW DB ?
COLUMN DB ?
M DW 65025 DUP(?)
RREF DB "matrix", 0


.CODE
MAIN PROC FAR
.STARTUP
;Program:

MOV BP, 0
MOV SI, 0

MOV AX, 3D02h ;Open file
MOV DX, OFFSET RREF
INT 21H
MOV BX, AX

MOV     CX,1    ;Read two bytes.
MOV     DX, OFFSET ROW
MOV     AH, 3FH ;Read
INT     21H
JC      QUIT
    CMP      AX, 1
        JNE     QUIT
       
        MOV     CX,8    ;Read eight bytes.
MOV     DX, OFFSET M
MOV     AH, 3FH ;Read
INT     21H
JC      QUIT
    CMP      AX, 8
JNE     QUIT

        IF (ROW LT COLUMN)
        MOV D, ROW
   
        ELSEIF (ROW GT COLUMN)
        MOV D, COLUMN
        ENDIF
       
        MOV row, D
        MOV col, D
       
           
       
       
        MOV AX, d
        MOV BX, 8
        MUL BX
        ADD AX, 2 ;M[d] = d*8+2
       
       
        MOV EAX, 0
       
       
       
        ;d=(col-1)*ROW+(row-1)
        MOV AL, col ;Determine number of diagonals
        SUB AL, 1
        MOV BL, row
        MOV DL, BL
        SUB BL, 1
        MUL DL
        ADD AX, BL
        MOV d, AX
       
        ;e=M(I,I)
        ;ep1=M(I+1,I)
       
       
        MOV SI, LENGTHOF M
        MOV EAX, M[SI]
        MOV EBX, M[SI+1] ;Now I'm Stuck
       
       
       
       
       
       
       
QUIT:  .EXIT
MAIN    ENDP
      END


I created an array with a length of 65025 dup (?) to account for a max value of 255x255.  The code is in no particular order but I'm following the algorithm the instructor gave us from a few posts up.  Am I completely lost or am I least on the right track?  I know it has a lot left to be a working code but I'm struggling with the language and how to put the algorithm into code.

brettc431

I haven't made any progress since my last post and the code has to be working by tomorrow evening.  We are beginning to feel like it won't get done on time since we are having so much trouble with the language itself.

dedndave

you seem to understand the concept of what the program needs to do

what you don't understand is the FPU code
i suggest you read Ray's FPU tutorial
http://www.ray.masmcode.com/fpu.html

you don't need to use all the FPU instructions - so you won't need to understand the entire tutorial
but, you do need to understand how to use the FPU registers (aka stack)
you need to know how to get numbers into and out of the FPU
you need to know how to add, subtract, multiply, and compare

so, chapters 1-4 and 7-8 should get you going

jj2007

Given that you have little time, study in the attachment:
fld
fst
fadd, fsub, fmul, fdiv (whatever you need)

On the net, read about fcomi (compare)

Dave's advice is valid, too, of course - maybe you can split the work. What I attach is the barebones of FPU work, what Dave suggests is more thorough.

Good luck :icon14:

FORTRANS

Hi,

MOV     CX,1    ;Read two bytes.

   Your comment says to read two bytes.  You are only reading one.
Either make another read section to read in one byte into the column
variable.  Or actually read two bytes to fill both row and columns.
This affects all further reads from the file and they will all be off one
byte.  And thus a bit wrong.

Steve

brettc431

FORTRANS, that was an error on my partner's part, it should have the number 2.

Thanks everyone for the help with FPU.  I'm reviewing it now and should hopefully have some more code in the thread in a little while.

dedndave

the FPU registers will hold 8 values, and are typically addressed as a last-in-first-out stack
the stack top is refered to as ST(0), or just ST
the others are refered to as ST(1) to ST(7)
some operations allow you to perform an arithmetic function and "pop" the stack into memory, in a single instruction (FADDP for example)

if all the registers are full, and you try to load a new value, an exception will occur
not only will the results of the next operation be incorrect, but the code will execute very slowly
this is one thing that catches many beginners   :P
half the trick of writing FPU code is to keep track of what is where in the register stack

i like to think of the register stack as an 8-shot revolver cylinder



a few instructions are intended for managing the stack

FFREE marks a register as empty, so that it may be loaded with a new value
notice that you can FFREE ST(7) to make room for a new value in ST(0)
the old ST(0) value becomes ST(1), the old ST(1) value becomes ST(2), and so on

FDECSTP and FINCSTP allow you to rotate the "cylinder" to select which value will be on the stack top
very handy

FFREE, FDECSTP, and FINCSTP are discussed in chapter 3 of Ray's tutorial

brettc431

Here's some more code.  No real progress:

.MODEL SMALL ;Defines memory model as small which uses seperate segments for code and data
.386 ;Microprocessor number
.STACK ;Stack segment defined as 1024 by default
.DATA ;Begins definition of the data type used in this project

row DB ?
col DB ?
e DW ?
ep1 DW ?
D DB ?
d DW ?
ROW DB ?
COLUMN DB ?
M DW 65025 DUP(?)
RREF DB "matrix", 0


.CODE
MAIN PROC FAR
.STARTUP
;Program:

MOV BP, 0
MOV SI, 0

MOV AX, 3D02h ;Open file
MOV DX, OFFSET RREF
INT 21H
MOV BX, AX

MOV     CX,2    ;Want to read two bytes.
MOV     DX, OFFSET ROW
MOV     AH, 3FH ;Read
INT     21H
JC      QUIT
    CMP      AX, 2
        JNE     QUIT
       
        MOV     CX,8    ;Want to read eight bytes.
MOV     DX, OFFSET M
MOV     AH, 3FH ;Read
INT     21H
JC      QUIT
    CMP      AX, 8
JNE     QUIT

        IF (ROW LT COLUMN)
        MOV D, ROW
   
        ELSEIF (ROW GT COLUMN)
        MOV D, COLUMN
        ENDIF
       
        MOV row, D
        MOV col, D
       
           
       
       
        ;MOV AX, d
        ;MOV BX, 8
        ;MUL BX
        ;ADD AX, 2 ;M[d] = d*8+2
       
       
        MOV EAX, 0
       
       
       
        MOV SI, D ;d=(col-1)*ROW+(row-1)
    L1:    MOV AL, col ;Determine number of diagonals
        SUB AL, 1
        MOV BL, row
        MOV DL, BL
        SUB BL, 1
        MUL DL
        ADD AX, BL
        MOV d, AX
       
        ;e=M(I,I)
        ;ep1=M(I+1,I)
       
        MOV EAX, M[d*8+2]
        MOV e, EAX
       
       
        MOV AL, col
SUB AL, 1
MOV BL, row
ADD BL, 1
MOV DL, BL
SUB BL, 1
MUL DL
ADD AX, BL
        MOV d, AX
       
        MOV EBX, M[d*8+2]
        MOV ep1, EBX
       
        ADD row, 1
        MOV col, 1
       
               
        FINIT
        FLD1
        FLD1
        FADD ST(1), ST(1)
        CMP ST(1), ep1
        JE SKIP
L2:        FADD ST(1), ST
        CMP ST(1), ep1
        JNE L2
SKIP: FCHS
FDIVR
       
       
       
       
       
QUIT:  .EXIT
MAIN    ENDP
      END

FORTRANS

Hi,

   To compare registers in the FPU to something, use FCMP rather
than CMP, which is for the CPU registers or memory.


        CMP ST(1), ep1
test43.asm(108) : error A2152: coprocessor register cannot be first operand


   You also have some symbols defined more than once.  Make a
listing to check for errors.


ROW DB ?
test43.asm(12) : error A2005: symbol redefinition : row


HTH,

Steve N.

jj2007

Quote from: FORTRANS on April 22, 2013, 11:16:33 PM
To compare registers in the FPU to something, use FCMP rather
than CMP, which is for the CPU registers or memory.

Quote from: jj2007 on April 22, 2013, 06:02:25 AM
On the net, read about fcomi (compare)

AFAIK there is no FCMP (there is a MasmBasic Fcmp, though). FCOM works but it is difficult to handle, as it does not set the EFLAGS as we are expect them. Therefore FCOMI seems the easiest solution - if it works in 16-bit code and on the group's CPU, of course.