Handlers for calculating with Matrixes

Basic operations on matrixes.

(*
		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

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. :slight_smile: