Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash
- #######################################
- # Developer: Harrison Latimer
- #
- # Class: CS 344 Fall 2019
- #
- # Program: Matrix Calculator
- #
- # Description: Takes in tab seperated
- # matrices and can calculate the
- # dimensions, transpose and mean
- # of a single matric and the sum
- # and dot product of two matrices
- ########################################
- ##########################################
- # Function: dims
- #
- # Description: reads in a tab and new line
- # seperated file and returns the number of
- # columns and row seperated by a space
- ##########################################
- dims() {
- #set up temp file
- TMP1=./tempfile
- cat $1 > $TMP1
- #cut the first column and count the number
- #of numbers to get rows
- row=$(cat $TMP1 | head -c -1 | cut -f1 | wc -l)
- #cut the first row and count the number
- #of numbers
- col=$(cat $TMP1 | head -1 | wc -w)
- #print result
- echo "$row $col"
- }
- ##########################################
- # Function: transpose
- #
- # Description: reads in a tab and new line
- # seperated file and converts \t into \n
- # to transform rows into columns
- ##########################################
- transpose() {
- #get the column size to transpose matrix
- colSize=$(head -1 $1 | wc -w)
- #iterate through each column, convert tabs
- #to new lines to make columns rows
- for i in `eval echo {1..$colSize}`
- do
- #strip the last character since it will be \t\n
- line=$(cat $1 | cut -f$i | tr '\n' '\t')
- line=${line%?}
- echo "$line" >> transpose
- done
- #print result and clean up
- cat transpose
- rm -f trans2
- rm -f transpose
- rm -f trans
- }
- ###########################################
- # Function: mean
- #
- # Description: reads in a tab and new line
- # seperated file and calculates the sum of
- # each row then divides by the number count
- # of the row to get the mean. Result is
- # tab seperated row that is the same column
- # size as the matrix supplied.
- ###########################################
- mean() {
- #variable set up for column and rows
- # and temp files to be used
- colSize=$(head -1 $1 | wc -w)
- rowSize=$(cut -f1 $1 | wc -l)
- sum=0
- TMP1=./tempfile
- #for each column iterate through each number
- # in the column and add to the total of the col
- for i in `eval echo {1..$colSize}`
- do
- #over write the column in the
- #temp file for each iteration
- cat $1 | cut -f$i > row
- cat row > $TMP1
- #get the sum of each column
- for num in $(cat row)
- do
- sum=`expr $sum + $num`
- done < $TMP1
- #divide the sum of the column by the number of items in the
- #column and round up
- meanResult=$(( ($sum+($rowSize/2)*(($sum>0)*2-1))/$rowSize ))
- #add a tab between each mean value and a new line at the end of
- #the row
- if test $i -ne $colSize
- then
- printf '%.0f' $meanResult >> result && echo -ne "\t" >> result
- else
- echo -n $meanResult >> result && echo -ne "\n" >> result
- fi
- sum=0
- done
- #write result and clean up files
- cat result
- rm -f result
- rm -f mean
- rm -f tempfile
- rm -f row
- }
- ##############################################
- # Function: sum
- #
- # Description: reads in two tab and new line
- # seperated files. Each number at the same
- # index are added together and the resulting
- # matrix is returned. The matrix retunred has
- # same dimensions as the matrices supplied
- #############################################
- sum() {
- if test $(dims $1 | cut -d ' ' -f1) -ne $(dims $2 | cut -d ' ' -f1)
- then
- >&2 0
- exit 1
- else
- colSize=$(head -1 $1 | wc -w)
- rowSize=$(cut -f1 $1 | wc -l)
- sum=0
- for i in `eval echo {1..$rowSize}`
- do
- for j in `eval echo {1..$colSize}`
- do
- num1=$(cat $1 | cut -f$j | head -$i | tail -1)
- num2=$(cat $2 | cut -f$j | head -$i | tail -1)
- sum=`expr $num1 + $num2`
- if test $j -ne $colSize
- then
- echo -n $sum >> sumResult && echo -ne "\t" >> sumResult
- else
- echo -n $sum >> sumResult && echo -ne "\n" >> sumResult
- fi
- sum=0
- done
- done
- cat sumResult
- rm -f sumResult
- fi
- }
- ##############################################
- # Function: multiply
- #
- # Description: reads in two tab and new line
- # seperated files. Takes the dot product of
- # two matrices. The dot product multiples
- # each value in a row from matrix 1 by each
- # column in matrix 2 and takes the sum of
- # each row column pair as the value of the
- # result
- #############################################
- multiply() {
- TMP1=./tempfile
- TMP2=./tempfile2
- rowSize1=$(cut -f1 $1 | wc -l)
- rowSize2=$(cut -f1 $2 | wc -l)
- colSize1=$(head -1 $1 | wc -w)
- colSize2=$(head -1 $2 | wc -w)
- #test to see if the column size of the first matrix equals the
- #row size of the second matrix. if not error out
- if ! test $colSize1 -eq $rowSize2
- then
- >&2 0
- exit 1
- else
- #if matrices are switched flip them back to smaller col size
- #for matrix 1 and large col matrix as matrix 2
- cat $1 > $TMP1
- cat $2 > $TMP2
- smallerCol=$colSize2
- #read in each row of the matrix to multiply by the
- #column of the second matrix. This is called the
- #dot product
- while read row
- do
- #use row size of m2 for loop limit
- #use col size of smaller matrix
- for j in `eval echo {1..$smallerCol}`
- do
- m1Row=1
- sum=0
- product=1
- #multiple row and column values and add together
- while read row2
- do
- m1Num=$(echo -ne "$row" | cut -f$m1Row)
- m2Num=$(echo -ne "$row2" | cut -f$j)
- product=$(($m1Num * $m2Num))
- sum=`expr $product + $sum`
- m1Row=`expr $m1Row + 1`
- done < $TMP2
- #use row size of m2 for loop limit
- if test $j -ne $smallerCol
- then
- echo -n "$sum" >> result && echo -ne "\t" >> result
- else
- echo -n "$sum" >> result && echo -ne "\n" >> result
- fi
- done
- done < $TMP1
- #print result and clean up
- cat result
- rm -f result
- fi
- }
- ##################################
- # Operation Request Handler Logic
- #################################
- # Operation Requsted
- op=$1
- # Case Statement to Handle Request
- case $op in
- dims)
- # args is great one, throw error
- if test "$#" -ge 3
- then
- >&2 "error: too many args"
- exit 1
- else
- # args are present but not readable throw an error
- [ $# -ge 1 -a -f "$2" ] && input="$2" || input="-"
- if test -z $input
- then
- >&2 "error: file is not readable"
- exit 1
- elif ! test -f $2
- then
- >&2 "error: file is not readable"
- exit 1
- else
- dims $input
- fi
- fi
- ;;
- transpose)
- #test that there are only 2 args and that the
- #file can be opened
- if ! test -r $2
- then
- >&2 "error: file not readable"
- exit 1
- elif test "$#" -ge 3
- then
- >&2 "error: too many args"
- exit 1
- else
- transpose $2
- fi
- ;;
- mean)
- #test that there are only 2 args and that that
- #files can be opened
- if test "$#" -ge 3
- then
- >&2 "error: too many args"
- exit 1
- elif ! test -r $2
- then
- >&2 "error: file not readable"
- exit 1
- else
- mean $2
- fi
- ;;
- add)
- #test that there are only 3 args and that both
- #files and be opened
- if test "$#" -le 2 || test "$#" -ge 4
- then
- >&2 "error: supply 3 args only"
- exit 1
- elif ! test -r $2 || ! test -r $3
- then
- >&2 "error: file not readable"
- exit 1
- else
- sum $2 $3
- fi
- ;;
- multiply)
- #test that there are only 3 args an that both
- #file can be opened
- if test "$#" -le 2 || test "$#" -ge 4
- then
- >&2 "error: supply 3 args only"
- exit 1
- elif ! test -r $2 || ! test -r $3
- then
- >&2 "error: file not readable"
- exit 1
- else
- multiply $2 $3
- fi
- ;;
- *)
- #catch misspelled commands
- >&2 "error: not an operator"
- exit 1
- ;;
- esac
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement