Advertisement
Guest User

Untitled

a guest
Oct 19th, 2019
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.71 KB | None | 0 0
  1. #!/bin/bash
  2.  
  3. #######################################
  4. # Developer: Harrison Latimer
  5. #
  6. # Class: CS 344 Fall 2019
  7. #
  8. # Program: Matrix Calculator
  9. #
  10. # Description: Takes in tab seperated
  11. # matrices and can calculate the
  12. # dimensions, transpose and mean
  13. # of a single matric and the sum
  14. # and dot product of two matrices
  15. ########################################
  16.  
  17.  
  18. ##########################################
  19. # Function: dims
  20. #
  21. # Description: reads in a tab and new line
  22. # seperated file and returns the number of
  23. # columns and row seperated by a space
  24. ##########################################
  25. dims() {
  26.  
  27. #set up temp file
  28. TMP1=./tempfile
  29. cat $1 > $TMP1
  30.  
  31. #cut the first column and count the number
  32. #of numbers to get rows
  33. row=$(cat $TMP1 | head -c -1 | cut -f1 | wc -l)
  34. #cut the first row and count the number
  35. #of numbers
  36. col=$(cat $TMP1 | head -1 | wc -w)
  37.  
  38. #print result
  39. echo "$row $col"
  40. }
  41.  
  42. ##########################################
  43. # Function: transpose
  44. #
  45. # Description: reads in a tab and new line
  46. # seperated file and converts \t into \n
  47. # to transform rows into columns
  48. ##########################################
  49. transpose() {
  50.  
  51. #get the column size to transpose matrix
  52. colSize=$(head -1 $1 | wc -w)
  53.  
  54. #iterate through each column, convert tabs
  55. #to new lines to make columns rows
  56. for i in `eval echo {1..$colSize}`
  57. do
  58. #strip the last character since it will be \t\n
  59. line=$(cat $1 | cut -f$i | tr '\n' '\t')
  60. line=${line%?}
  61. echo "$line" >> transpose
  62.  
  63. done
  64.  
  65. #print result and clean up
  66. cat transpose
  67. rm -f trans2
  68. rm -f transpose
  69. rm -f trans
  70. }
  71.  
  72. ###########################################
  73. # Function: mean
  74. #
  75. # Description: reads in a tab and new line
  76. # seperated file and calculates the sum of
  77. # each row then divides by the number count
  78. # of the row to get the mean. Result is
  79. # tab seperated row that is the same column
  80. # size as the matrix supplied.
  81. ###########################################
  82. mean() {
  83.  
  84. #variable set up for column and rows
  85. # and temp files to be used
  86. colSize=$(head -1 $1 | wc -w)
  87. rowSize=$(cut -f1 $1 | wc -l)
  88. sum=0
  89. TMP1=./tempfile
  90.  
  91. #for each column iterate through each number
  92. # in the column and add to the total of the col
  93. for i in `eval echo {1..$colSize}`
  94. do
  95. #over write the column in the
  96. #temp file for each iteration
  97. cat $1 | cut -f$i > row
  98. cat row > $TMP1
  99.  
  100. #get the sum of each column
  101. for num in $(cat row)
  102. do
  103. sum=`expr $sum + $num`
  104. done < $TMP1
  105.  
  106. #divide the sum of the column by the number of items in the
  107. #column and round up
  108. meanResult=$(( ($sum+($rowSize/2)*(($sum>0)*2-1))/$rowSize ))
  109.  
  110. #add a tab between each mean value and a new line at the end of
  111. #the row
  112. if test $i -ne $colSize
  113. then
  114. printf '%.0f' $meanResult >> result && echo -ne "\t" >> result
  115. else
  116. echo -n $meanResult >> result && echo -ne "\n" >> result
  117. fi
  118. sum=0
  119. done
  120.  
  121. #write result and clean up files
  122. cat result
  123. rm -f result
  124. rm -f mean
  125. rm -f tempfile
  126. rm -f row
  127. }
  128.  
  129. ##############################################
  130. # Function: sum
  131. #
  132. # Description: reads in two tab and new line
  133. # seperated files. Each number at the same
  134. # index are added together and the resulting
  135. # matrix is returned. The matrix retunred has
  136. # same dimensions as the matrices supplied
  137. #############################################
  138. sum() {
  139.  
  140. if test $(dims $1 | cut -d ' ' -f1) -ne $(dims $2 | cut -d ' ' -f1)
  141. then
  142. >&2 0
  143. exit 1
  144. else
  145. colSize=$(head -1 $1 | wc -w)
  146. rowSize=$(cut -f1 $1 | wc -l)
  147. sum=0
  148. for i in `eval echo {1..$rowSize}`
  149. do
  150. for j in `eval echo {1..$colSize}`
  151. do
  152. num1=$(cat $1 | cut -f$j | head -$i | tail -1)
  153. num2=$(cat $2 | cut -f$j | head -$i | tail -1)
  154. sum=`expr $num1 + $num2`
  155.  
  156. if test $j -ne $colSize
  157. then
  158. echo -n $sum >> sumResult && echo -ne "\t" >> sumResult
  159. else
  160. echo -n $sum >> sumResult && echo -ne "\n" >> sumResult
  161. fi
  162. sum=0
  163. done
  164. done
  165. cat sumResult
  166. rm -f sumResult
  167. fi
  168. }
  169.  
  170. ##############################################
  171. # Function: multiply
  172. #
  173. # Description: reads in two tab and new line
  174. # seperated files. Takes the dot product of
  175. # two matrices. The dot product multiples
  176. # each value in a row from matrix 1 by each
  177. # column in matrix 2 and takes the sum of
  178. # each row column pair as the value of the
  179. # result
  180. #############################################
  181. multiply() {
  182. TMP1=./tempfile
  183. TMP2=./tempfile2
  184. rowSize1=$(cut -f1 $1 | wc -l)
  185. rowSize2=$(cut -f1 $2 | wc -l)
  186. colSize1=$(head -1 $1 | wc -w)
  187. colSize2=$(head -1 $2 | wc -w)
  188.  
  189. #test to see if the column size of the first matrix equals the
  190. #row size of the second matrix. if not error out
  191. if ! test $colSize1 -eq $rowSize2
  192. then
  193. >&2 0
  194. exit 1
  195. else
  196. #if matrices are switched flip them back to smaller col size
  197. #for matrix 1 and large col matrix as matrix 2
  198.  
  199. cat $1 > $TMP1
  200. cat $2 > $TMP2
  201. smallerCol=$colSize2
  202.  
  203.  
  204. #read in each row of the matrix to multiply by the
  205. #column of the second matrix. This is called the
  206. #dot product
  207. while read row
  208. do
  209. #use row size of m2 for loop limit
  210. #use col size of smaller matrix
  211. for j in `eval echo {1..$smallerCol}`
  212. do
  213. m1Row=1
  214. sum=0
  215. product=1
  216. #multiple row and column values and add together
  217. while read row2
  218. do
  219. m1Num=$(echo -ne "$row" | cut -f$m1Row)
  220. m2Num=$(echo -ne "$row2" | cut -f$j)
  221. product=$(($m1Num * $m2Num))
  222. sum=`expr $product + $sum`
  223. m1Row=`expr $m1Row + 1`
  224. done < $TMP2
  225.  
  226. #use row size of m2 for loop limit
  227. if test $j -ne $smallerCol
  228. then
  229. echo -n "$sum" >> result && echo -ne "\t" >> result
  230. else
  231. echo -n "$sum" >> result && echo -ne "\n" >> result
  232. fi
  233. done
  234. done < $TMP1
  235.  
  236. #print result and clean up
  237. cat result
  238. rm -f result
  239. fi
  240. }
  241.  
  242. ##################################
  243. # Operation Request Handler Logic
  244. #################################
  245.  
  246. # Operation Requsted
  247. op=$1
  248.  
  249. # Case Statement to Handle Request
  250. case $op in
  251. dims)
  252. # args is great one, throw error
  253. if test "$#" -ge 3
  254. then
  255. >&2 "error: too many args"
  256. exit 1
  257. else
  258. # args are present but not readable throw an error
  259. [ $# -ge 1 -a -f "$2" ] && input="$2" || input="-"
  260. if test -z $input
  261. then
  262. >&2 "error: file is not readable"
  263. exit 1
  264. elif ! test -f $2
  265. then
  266. >&2 "error: file is not readable"
  267. exit 1
  268. else
  269. dims $input
  270. fi
  271. fi
  272. ;;
  273. transpose)
  274. #test that there are only 2 args and that the
  275. #file can be opened
  276. if ! test -r $2
  277. then
  278. >&2 "error: file not readable"
  279. exit 1
  280. elif test "$#" -ge 3
  281. then
  282. >&2 "error: too many args"
  283. exit 1
  284. else
  285. transpose $2
  286. fi
  287. ;;
  288. mean)
  289. #test that there are only 2 args and that that
  290. #files can be opened
  291. if test "$#" -ge 3
  292. then
  293. >&2 "error: too many args"
  294. exit 1
  295. elif ! test -r $2
  296. then
  297. >&2 "error: file not readable"
  298. exit 1
  299. else
  300. mean $2
  301. fi
  302. ;;
  303. add)
  304. #test that there are only 3 args and that both
  305. #files and be opened
  306. if test "$#" -le 2 || test "$#" -ge 4
  307. then
  308. >&2 "error: supply 3 args only"
  309. exit 1
  310. elif ! test -r $2 || ! test -r $3
  311. then
  312. >&2 "error: file not readable"
  313. exit 1
  314. else
  315. sum $2 $3
  316. fi
  317. ;;
  318. multiply)
  319. #test that there are only 3 args an that both
  320. #file can be opened
  321. if test "$#" -le 2 || test "$#" -ge 4
  322. then
  323. >&2 "error: supply 3 args only"
  324. exit 1
  325. elif ! test -r $2 || ! test -r $3
  326. then
  327. >&2 "error: file not readable"
  328. exit 1
  329. else
  330. multiply $2 $3
  331. fi
  332. ;;
  333. *)
  334. #catch misspelled commands
  335. >&2 "error: not an operator"
  336. exit 1
  337. ;;
  338. esac
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement