LB Booster
« Matrix multiplication (dot product) »

Welcome Guest. Please Login or Register.
Apr 1st, 2018, 03:50am



ATTENTION MEMBERS: Conforums will be closing it doors and discontinuing its service on April 15, 2018.
We apologize Conforums does not have any export functions to migrate data.
Ad-Free has been deactivated. Outstanding Ad-Free credits will be reimbursed to respective payment methods.

Thank you Conforums members.
Speed up Liberty BASIC programs by up to ten times!
Compile Liberty BASIC programs to compact, standalone executables!
Overcome many of Liberty BASIC's bugs and limitations!
LB Booster Resources
LB Booster documentation
LB Booster Home Page
LB Booster technical Wiki
Just BASIC forum
BBC BASIC Home Page
Liberty BASIC forum (the original)

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: Matrix multiplication (dot product)  (Read 1080 times)
Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 1348
xx Matrix multiplication (dot product)
« Thread started on: Nov 11th, 2016, 11:47am »

Neither LB 4 nor LBB supports matrix multiplication (dot product) as a native operator, but BBC BASIC does so that makes it easy to incorporate it in an LBB program. This is exactly what I did as one of my speed-up modifications to Bluatigro's CG animation demo.

His original code used a multiply routine similar to this:

Code:
' matrix( c ) = matrix( a ) . matrix( b )
  for i = 0 to 3
    for j = 0 to 3
      c(i,j) = 0
      for k = 0 to 3
        c(i,j) = c(i,j) + a(i,k) * b(k,j)
      next k
    next j
  next i 

In my LBB version I used this as a (very) much faster replacement:

Code:
  !c() = a() . b() 

You might be surprised to discover how often matrix multiplication is useful. 3D manipulations (rotation, translation, scaling) as used by Bluatigro are probably some of the most common applications, but there are many others.

Richard.
User IP Logged

CryptoMan
New Member
Image


member is offline

Avatar




PM

Gender: Male
Posts: 46
xx Re: Matrix multiplication (dot product)
« Reply #1 on: Nov 18th, 2016, 10:43pm »

How about Inverse of a square matrıx?
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 1348
xx Re: Matrix multiplication (dot product)
« Reply #2 on: Nov 19th, 2016, 09:59am »

on Nov 18th, 2016, 10:43pm, CryptoMan wrote:
How about Inverse of a square matrıx?

There's no built-in matrix inversion, but it's not that difficult to code in BASIC (the complexity depends on whether you need to choose the pivots carefully to maximize accuracy and avoid division-by-zero errors). Of course it won't be as fast as a native function would be.

I've got a matrix inversion routine in BBC BASIC but not in Liberty BASIC. Rather surprisingly, Rosetta Code doesn't seem to have a matrix inversion task either.

If I were to create a Programming Challenge to write a fast, accurate and stable matrix inversion in LB, do you think anybody other than me would submit an entry? wink

Richard.
User IP Logged

CryptoMan
New Member
Image


member is offline

Avatar




PM

Gender: Male
Posts: 46
xx Re: Matrix multiplication (dot product)
« Reply #3 on: Nov 19th, 2016, 10:41pm »

I would. In my past iife I used to work a lot on that. In those days memory was limited and we were spending more effort in storşng the matrices in smaller spacesdue to the nature of our matrices which were symetric around the diagonal. Today, there is obscene amount of memory is available.

Ofcourse, I know it can be done in Basic but wondering if there is a native version maybe even by accessing libraries on graphics processor cards which can do it lightning fast.

Probably, there are some 3rd party DLLs available for full set of matrix arithmetic. Just asked as a matter of curiosity if more native matrix functions
Available. I don't even remember the theory of Finite Elements now to make any use of it. Need to open the texr books and remember from 35 years ago.

I used to write it on TI59 and HP41CV programmable calculators and solving some of the problems in exams very quickly during the days when they did not expect such things from calculators and not forbidding them from exams. Later when IBM PC came in 1981 it was so simple and huge so we translated lots of code from IBM mainframe FORTRAN to BASIC, Pascal and C. So, it is always interesting for me to see what can be now done with all this additional power we have today. Some amazing things should be possible.


User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 1348
xx Re: Matrix multiplication (dot product)
« Reply #4 on: Nov 20th, 2016, 11:48am »

on Nov 19th, 2016, 10:41pm, CryptoMan wrote:
the nature of our matrices which were symetric around the diagonal.

Mine usually are too, I suspect it follows when they are used for least-squares regression. Inverting such a symmetrical matrix is less demanding, I think, and that supports my feeling that there isn't a 'one size fits all' inversion routine. That may be one reason why inversion wasn't incorporated as a native operation in BBC BASIC 30 years ago (I was there at the time, but I don't think the BBC expressed a view either way).

Nevertheless embedded BBC BASIC code for array arithmetic can be very useful; one neat thing you can do is to normalise a vector to unit length in one fast operation:

Code:
    !array() /= MOD(array()) 

That can be valuable in some 3D graphics applications.

Quote:
I know it can be done in Basic but wondering if there is a native version maybe even by accessing libraries

In my experience matrix inversion hasn't been time-critical. Even in a real-time application like free-d2 (see the BBC BASIC Birthday page) it was acceptable to do the inversion in interpreted BASIC.

You may be interested in this example of using array arithmetic to fit a polynomial function to a large set of data points.

Richard.
User IP Logged

Optimax
New Member
Image


member is offline

Avatar




PM


Posts: 11
xx Re: Matrix multiplication (dot product)
« Reply #5 on: Nov 21st, 2016, 07:07am »

A long time ago, I wrote an "inverse matrix" in Rapidq, that I later ported to LB. It uses the method of "minors" elaborated by Gauss and Jordan. There is an other method called "the simplex" that I never could find back.
Strangely there appears at the end a "-0.00" which is anyway equal to zero; could maybe come from rounding ?

Code:
'GAUSS-JORDAN MATRICE INVERSE
'=============================

'A original matrix, InvA inverse of A, B extended matrix, P = A * InvA

'let's have a square matrix A (3x3)         '2,        1,    -2
                                            '3         2      2
                                            '5         4      3

'--- creating the extended matrix B = A + unit matrix

DATA         2,     1,   -2,      1,     0,     0
DATA         3,     2,    2,      0,     1,     0
DATA         5,     4,    3,      0,     0,     1

n = 3

DIM A(n+1, n+1)
DIM B(n+1, n*2)

PRINT "EXTENDED MATRIX B :": PRINT
FOR i = 1 TO n
FOR j = 1 TO 2*n
    READ m
    B(i,j) = m
    PRINT "", B(i,j);    'and displaying it
NEXT j
    PRINT: PRINT
NEXT i
PRINT

'--- A is the left part of B, extraction

PRINT "ORIGINAL MATRIX A, extracted from B :"
PRINT
FOR i = 1 TO n
FOR j = 1 TO n
    A(i,j) = B(i,j)
    PRINT "", A(i,j);    'and displaying it
NEXT j
    PRINT: PRINT
NEXT i
PRINT

'--- calculation begins here 

'i = row index        'k = other row index (not-i)      'j = column index
'intermediary variables p, q, r to avoid divisions like A(i,j)/A(m,n) e.g., giving unpredictable results

FOR i = 1 TO n

'reducing each diagonal term B(i,i)  to 1 by dividing the hole row by B(i,i)
    p = B(i, i)
    FOR j = 1 TO 2*n
    q = B(i, j)
    B(i, j) = q / p
    NEXT j

'multiply row i by B(k,i)
'substract row i from row k

        FOR k = 1 TO n
        p = B(k, i)
        IF k <> i THEN
                  FOR j = 1 TO 2*n
                  q = B(k, j)
                   r = B(i, j)
                  B(k, j) = q - p * r
                  NEXT j
        END IF
    NEXT k

NEXT i

'--- end of calculation, let's see matrix B  now

PRINT "INTERMEDIAIRY MATRIX B :": PRINT
FOR i = 1 TO n
  FOR j= 1 TO 2*n
      m = B(i, j)
      PRINT "", USING("###.###", m);
  NEXT j
      PRINT: PRINT
NEXT i
PRINT

'---INVERSE of a, i.e. InvA, is the *right* part of B

PRINT "INVERSE of A (rounded) :": PRINT
DIM InvA(n+1,n+1)

FOR i = 1 TO n
FOR j = n+1 TO 2*n                            'copying the right part of B
          InvA(i, j-n) = B(i,j)
          m = InvA(i, j-n)
          PRINT "", USING("###.###", m);      'rounding
NEXT j
          PRINT: PRINT
NEXT i
PRINT

'--- Checking the result: A * InvA must guve P = the unit matrix

PRINT "CHECKING for InvA:  A * Inv must give the unit matrix P"
PRINT

DIM P(n+1, n+1)                  'empty

FOR i = 1 TO n                    'for each row i o f A and P
  FOR j = 1 TO n                  'for each horizontal term j of row i of P
    FOR k = 1 TO n                'for each vertical term k of column j of InvA
        x = A(k,i): y = InvA(j,k)
        P(i, j) = P(i, j) + x*y
     NEXT k
     m = P(i, j)
     PRINT "", USING("###.###", m);
  NEXT j
  PRINT: PRINT
NEXT i

END
 
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 1348
xx Re: Matrix multiplication (dot product)
« Reply #6 on: Nov 21st, 2016, 09:43am »

on Nov 21st, 2016, 07:07am, Optimax wrote:
A long time ago, I wrote an "inverse matrix" in Rapidq, that I later ported to LB. It uses the method of "minors" elaborated by Gauss and Jordan.

The problem with that method is that there's no 'pivot selection': you simply work down the diagonal from top-left to bottom-right. This can result in inaccuracy, or worse, if you are unlucky with your input matrix.

That can easily be demonstrated by changing your test matrix so that the top-left element is 0 rather than 2:

Code:
DATA         0,     1,   -2,      1,     0,     0
DATA         3,     2,    2,      0,     1,     0
DATA         5,     4,    3,      0,     0,     1 

Now when I run your program it reports a Division by zero error! It's not that the matrix is non-invertable, in fact the inverse matrix is this:

Code:
      -0.4         1      -0.4
       0.2        -2       1.2
       0.4         1      -0.6 

The BBC BASIC code I referred to does attempt to be more 'intelligent' in its pivot selection, and it is successful in this case, but I make no claims for it in other respects.

Quote:
Strangely there appears at the end a "-0.00"

I don't see that here, but it's a perfectly reasonable thing to output (representing a negative number which is zero when rounded to two decimal places)

Richard.
User IP Logged

Optimax
New Member
Image


member is offline

Avatar




PM


Posts: 11
xx Re: Matrix multiplication (dot product)
« Reply #7 on: Nov 25th, 2016, 12:30pm »

You are right.
Thanks for advice.
I should have a look at that pivot thing.
User IP Logged

Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

| |

This forum powered for FREE by Conforums ©
Terms of Service | Privacy Policy | Conforums Support | Parental Controls