Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@frgomes
Last active May 3, 2021 01:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save frgomes/6ecf066af7fbdfb438893be68fbbd4d0 to your computer and use it in GitHub Desktop.
Save frgomes/6ecf066af7fbdfb438893be68fbbd4d0 to your computer and use it in GitHub Desktop.
Bash - Matrix multiplication, passing associative arrays to functions, returning associative arrays from functions
#!/bin/bash -eu
function linalg_matrix_dump {
local -n M=${1}
local -a data=(${M[data]})
typeset -i rows=${M[rows]}
typeset -i cols=${M[cols]}
typeset -i i j
printf "%s:\n" ${1}
for ((i=0;i<rows;i++)) ; do
printf ' | '
for ((j=0;j<cols;j++)) ; do
idx=$((i*cols+j))
printf "%s " ${data[$((i*cols+j))]}
done
printf '\n';
done
printf '\n';
}
function linalg_matrix_multiply {
local -n A=${1}
local -n B=${2}
local -a dataA=(${A[data]})
local -a dataB=(${B[data]})
typeset -i rowsA=${A[rows]}
typeset -i colsA=${A[cols]}
typeset -i rowsB=${B[rows]}
typeset -i colsB=${B[cols]}
[[ $((rowsA*colsA)) -eq ${#dataA[@]} ]] || return 1
[[ $((rowsB*colsB)) -eq ${#dataB[@]} ]] || return 1
[[ ${colsA} -eq ${rowsB} ]] || return 1
typeset -i i j k a b c
local -a dataC
for ((i=0;i<rowsA;i++)) ;do
for ((j=0;j<colsB;j++)) ;do
local sum=0
for ((k=0;k<rowsB;k++)) ;do
local a=$((i*colsA+k))
local b=$((j+colsB*k))
local cellA=${dataA[a]}
local cellB=${dataB[b]}
sum=$(echo "${sum} + ${cellA} * ${cellB}" | bc -ls)
done
local c=$((i*colsB+j))
dataC[$c]=${sum}
done
done
declare -A result=([rows]=${rowsA} [cols]=${colsB} [data]=${dataC[@]})
declare -p result
}
declare -A m1=([rows]=2 [cols]=2 [data]="1 2 3 4")
linalg_matrix_dump m1
declare -A m2=([rows]=2 [cols]=3 [data]="0 1 2 1 2 3")
linalg_matrix_dump m2
m=$(linalg_matrix_multiply m1 m2)
eval "${m/result=/m=}"
linalg_matrix_dump m
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment