Tuesday, January 23, 2018

#1 2014-08-19 02:02:58 pm

McUsrII
Member
Registered: 2012-11-21
Posts: 3046
Website

Handlers for calculating with Matrixes

Basic operations on matrixes.

Applescript:

(*
       Version 1: 2014-8-19 created by McUsr
        Version 2: 2014-8-2014 Changed mat_equalDimensions to mat_isSameSize, added mat_isSquare,
               mat_isEqual, and added some comments.
       Version3: 2014-8-20 Added some handlers for "boolean" matrices (zeroOne matrices)
       

*)


on mat_create(r, c)
   # creates a matrix with r rows and c cols
   script o
       property m : {}
   end script
   repeat with i from 1 to r
       set end of o's m to {}
       # row major matrix, which means that a 5X1 matrix (5 rows 1 col )looks like
       # {{1},{2},{3},{4},{5}} and a 1X5 matrix ( 1 row 5 cols) looks like:
       # {{1,2,3,4,5}}
       repeat with j from 1 to c
           set end of item -1 of o's m to {}
       end repeat
   end repeat
   return o's m
end mat_create
(* ============================ *)
# Differences between a 1 col and a 1 row matrix
# set d to {{1}, {2}, {3}, {4}, {5}}
# set d to {{1, 2, 3, 4, 5}}
# mat_print(d)
(* ============================ *)

on mat_print(m)
   # Prints out a matrix into the log pane of Applescript Editor
   repeat with i from 1 to (count m)
       set this_row to {}
       repeat with j from 1 to (count item 1 of m)
           if (class of item j of item i of m) is number or (class of item j of item i of m) is integer then
               set end of this_row to item j of item i of m
           else
               set end of this_row to 0
           end if
       end repeat
       log this_row
   end repeat
end mat_print


(* Two convenience handlers to make the code more readable *)

on mat_insval(m, r, c, v)
   # inserts a value into a matrix
   set item c of item r of m to v
end mat_insval

on mat_getval(m, r, c)
   # returns a value from a matrix
   return item c of item r of m
end mat_getval

on mat_rows(m)
   # returns number of rows in a matrix.
   return (count m)
end mat_rows

on mat_cols(m)
   # returns number of columns in a matrix.
   return count (item 1 of m)
end mat_cols

on mat_isCompat(a, b)
   # Returns true if the matrixes are compatible.
   # -they must be ordered like passed as arguments
   # for this test to be meaningful.
   if (mat_rows(b) = mat_cols(a)) then return true
   return false
end mat_isCompat


on mat_isSquare(Matrix_a)
   # returns true if the matrix has equal number of rows and cols
   if (mat_rows(Matrix_a) = mat_cols(Matrix_a)) then return true
   return false
end mat_isSquare

on mat_isSameSize(Matrix_a, Matrix_B)
   # returns true if the matrixes has equal number of rows and cols
   if (mat_rows(Matrix_a) = mat_rows(Matrix_B)) and (mat_cols(Matrix_a) = mat_cols(Matrix_B)) then return true
   return false
end mat_isSameSize
(*
set a to {{1, 2, 3}, ¬
   {1, 2, 3}, ¬
   {1, 2, 3}}

set b to {{1, 2, 3}, ¬
   {1, 2, 3}, ¬
   {1, 2, 2}}
log mat_isSquare(a)
*)

on mat_isEqual(Matrix_a, Matrix_B)
   set m to mat_rows(Matrix_a)
   if not (m is mat_rows(Matrix_B)) then return false
   set n to mat_cols(Matrix_a)
   if not (n is mat_cols(Matrix_B)) then return false
   repeat with i from 1 to m
       repeat with j from 1 to n
           if mat_getval(Matrix_a, i, j) ≠ mat_getval(Matrix_B, i, j) then return false
       end repeat
   end repeat
   return true
end mat_isEqual

on mat_isSymmetric(Matrix_a)
   set m to mat_rows(Matrix_a)
   set n to mat_cols(Matrix_a)
   if m ≠ n then return false
   repeat with i from 1 to m
       repeat with i from 1 to n
           if mat_getval(Matrix_a, i, j) ≠ mat_getval(Matrix_a, j, i) then return false
       end repeat
   end repeat
   return true
end mat_isSymmetric

on mat_isZeroOne(Marix_a)
   # returns true if the matrix consists of just 1's and 0's
   set m to mat_rows(Matrix_a)
   set n to mat_cols(Matrix_a)
   repeat with i from 1 to m
       repeat with i from 1 to n
           set tmpval to mat_getval(Matrix_a, i, j)
           if tmpval is not 0 and tmpval is not 1 then return false
       end repeat
   end repeat
   return true
end mat_isZeroOne


on mat_zero(Matrix_z)
   repeat with i from 1 to mat_rows(Matrix_z)
       repeat with j from 1 to mat_cols(Matrix_z)
           mat_insval(Matrix_z, i, j, 0)
       end repeat
   end repeat
end mat_zero


on mat_join(Matrix_a, Matrix_B)
   # ors two matrixes that better be zero one matrixes.
   set m to mat_rows(Matrix_a)
   set n to mat_cols(Matrix_a)
   
   if mat_isSameSize(Matrix_a, Matrix_B) then
       copy Matrix_a to Matrix_c
       # mat_zero(Matrix_c)
       repeat with i from 1 to mat_rows(Matrix_c)
           repeat with j from 1 to mat_cols(Matrix_c)
               if mat_getval(Matrix_a, i, j) is 1 or mat_getval(Matrix_B, i, j) is 1 then
                   mat_insval(Matrix_c, i, j, 1)
               else
                   mat_insval(Matrix_c, i, j, 0)
               end if
           end repeat
       end repeat
       return Matrix_c
   end if
end mat_join

on mat_meet(Matrix_a, Matrix_B)
   # ands two matrixes that better be zero one matrixes.
   set m to mat_rows(Matrix_a)
   set n to mat_cols(Matrix_a)
   
   if mat_isSameSize(Matrix_a, Matrix_B) then
       copy Matrix_a to Matrix_c
       # mat_zero(Matrix_c)
       repeat with i from 1 to mat_rows(Matrix_c)
           repeat with j from 1 to mat_cols(Matrix_c)
               if mat_getval(Matrix_a, i, j) is 1 and mat_getval(Matrix_B, i, j) is 1 then
                   mat_insval(Matrix_c, i, j, 1)
               else
                   mat_insval(Matrix_c, i, j, 0)
               end if
           end repeat
       end repeat
       return Matrix_c
   end if
end mat_meet

(*
set matA to {¬
   {1, 0}, ¬
   {0, 1}, ¬
   {1, 0}}

set matB to {¬
   {1, 1, 0}, ¬
   {0, 1, 1}}


set m to mat_rows(matA)
set n to mat_cols(matB)

set matC to mat_create(m, n)

mat_boolProduct(matA, matB, matC, m, n)

mat_print(matC)
*)


on mat_boolProduct(Matrix_a, Matrix_B, Matrix_c, m, n)
   (*
       Returns the boolean product of to zeroOne matrices as a zeroOne matrix.
   
       Matrix a is first factor, matrix b the second factor, the boolean product is
       stored in matrix c. m is number of rows in matrix a, n is number of cols in matrix b
       
       The computation of the boolean product is value = ( valueaA1 and valueBN1) or (valueA2 and valueB2) or . . .
       Otherwise it is just like regular matrix multiplication.
       *)

   
   if mat_isCompat(Matrix_a, Matrix_B) and mat_rows(Matrix_c) = mat_rows(Matrix_a) and mat_cols(Matrix_c) = mat_cols(Matrix_B) then
       
       set colsA to mat_cols(Matrix_a)
       repeat with curRowA from 1 to m
           -- every row of Matrix_a
           repeat with curColB from 1 to n
               -- every col of b
               set tempval to 0
               repeat with k from 1 to colsA
                   -- multiply and store result
                   set tempval to ((tempval as boolean) or ((mat_getval(Matrix_a, curRowA, k) as boolean) and ((mat_getval(Matrix_B, k, curColB) as boolean)))) as integer
               end repeat
               mat_insval(Matrix_c, curRowA, curColB, tempval)
           end repeat
       end repeat
   else
       error "mat_boolProduct cols of a not equal to rows in b or other error maybe in mat. c" number 3335
   end if
end mat_boolProduct

on mat_transpose(Matrix_a)
   # transpose a matrix by interchanging the rows and columns of the original matrix
   set m_rows to mat_rows(Matrix_a)
   set m_cols to mat_cols(Matrix_a)
   set Matrix_t to mat_create(m_cols, m_rows)
   # we create a matrix with transposed dimensions cols = rows, and rows = cols
   
   repeat with i from 1 to m_cols
       repeat with j from 1 to m_rows
           mat_insval(Matrix_t, j, i, mat_getval(Matrix_a, i, j))
       end repeat
   end repeat
   return Matrix_t
end mat_transpose

on mat_multiply(Matrix_a, Matrix_B, Matrix_c, m, n)
   (* Matrix a is first factor, matrix b the second factor, the product is
       stored in matrix c. m is number of rows in matrix a, n is number of cols in matrix b *)

   
   if mat_isCompat(Matrix_a, Matrix_B) and mat_rows(Matrix_c) = mat_rows(Matrix_a) and mat_cols(Matrix_c) = mat_cols(Matrix_B) then
       
       set colsA to mat_cols(Matrix_a)
       repeat with curRowA from 1 to m
           -- every row of Matrix_a
           repeat with curColB from 1 to n
               -- every col of b
               set tempval to 0
               repeat with k from 1 to colsA
                   -- multiply and store result
                   set tempval to tempval + (mat_getval(Matrix_a, curRowA, k) * (mat_getval(Matrix_B, k, curColB)))
               end repeat
               mat_insval(Matrix_c, curRowA, curColB, tempval)
           end repeat
       end repeat
   else
       error "mat_multiply cols of a not equal to rows in b or other error maybe in mat. c" number 3333
   end if
end mat_multiply

on mat_sum(Matrix_a, Matrix_B, Matrix_c)
   # Sums two matrices. returned in Matrix_c.
   if mat_isSameSize(Matrix_a, Matrix_B) and mat_isSameSize(Matrix_B, Matrix_c) then
       
       repeat with i from 1 to mat_rows(Matrix_a)
           repeat with j from 1 to mat_cols(Matrix_a)
               mat_insval(Matrix_c, i, j, (mat_getval(Matrix_a, i, j) + mat_getval(Matrix_B, i, j)))
           end repeat
       end repeat
       
   else
       error "mat_sum cols of a not equal to cols in b or cols in c or vice versa for rows." number 3334
       
   end if
   
end mat_sum

on mat_diff(Matrix_a, Matrix_B, Matrix_c)
   # Difference of two matrices. returned in Matrix_c.
   if mat_isSameSize(Matrix_a, Matrix_B) and mat_isSameSize(Matrix_B, Matrix_c) then
       
       repeat with i from 1 to mat_rows(Matrix_a)
           repeat with j from 1 to mat_cols(Matrix_a)
               mat_insval(Matrix_c, i, j, (mat_getval(Matrix_a, i, j) - mat_getval(Matrix_B, i, j)))
           end repeat
       end repeat
       
   else
       error "mat_diff cols of a not equal to cols in b or cols in c or vice versa for rows." number 3334
       
   end if
   
end mat_diff

Last edited by McUsrII (2014-08-20 07:05:22 am)


Filed under: Matrix

Offline

 

#2 2014-08-20 07:04:14 am

McUsrII
Member
Registered: 2012-11-21
Posts: 3046
Website

Re: Handlers for calculating with Matrixes

Hello.

Changed mat_equalDimensions to mat_isSameSize, added mat_isSquare,  mat_isEqual, and added some comments.

Added some handlers for "boolean" matrices: (zeroOne matrices) meet, join and boolean product.

There is still more to come, as I need tools for solving matrix equations on the form Ax=B. smile


Filed under: Matrix

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)