Advertisement
Guest User

Untitled

a guest
May 29th, 2015
287
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.09 KB | None | 0 0
  1. # Linear Equations Solver using Guassian-Jordan elimination
  2. # Syed Usama Jamil CS-037
  3. # Muhammad Yaseen CS-050
  4. # Project ID CA-03
  5. #===========================================================================
  6.  
  7. .data
  8.  
  9. dimension : .byte 4
  10.  
  11. #matrix : .float 1.0, 1.0, 2.0, 9.0, 2.0, 4.0, -3.0, 1.0, 3.0, 6.0, -5.0, 0.0 #pg 7 x=1,y=2,z=3
  12.  
  13. matrix : .float 1.0, 2.0, 3.0, 4.0, 5.0, 2.0, 7.0, 8.0, 9.0, 10.0, 1.0, 12.0, 2.0, 14.0, 5.0, 5.0, 17.0, 18.0, 19.0, 2.0 #pg 7 x=1,y=2,z=3
  14.  
  15. #matrix : .float 2.0, 1.0, 3.0, 1.0, 2.0, 6.0, 8.0, 3.0, 6.0, 8.0, 18.0, 5.0 #pg 7 x=3/10,y=2/5,z=0
  16.  
  17. #matrix : .float 1.0, -2.0, 3.0, 7.0, 2.0, 1.0, 1.0, 4.0, -3.0, 2.0, -2.0, -10.0 #pg 7 x=2,y=-1,z=1
  18.  
  19. results : .space 1000 #reserve 1000 bytes
  20.  
  21. result : .asciiz "Solution is : "
  22.  
  23. newline : .asciiz "\n"
  24.  
  25. zero : .float 0.0
  26.  
  27. .text
  28.  
  29. main:
  30.  
  31. #get the address of input matrix system
  32. la $t0, matrix
  33.  
  34. #get the dimension ( NxN ) of matrix
  35. lw $t1, dimension
  36.  
  37. addi $s6,$t1,1 #for offset calc
  38.  
  39. #Loop control variable, goes from 1 to n, named 'j' in c code
  40. li $t3, 0
  41.  
  42. #loop for generation of triangular matrix
  43.  
  44. gen_tri_mat:
  45.  
  46. addi $t3, $t3, 1 #increment control var
  47.  
  48. bgt $t3, $t1, end_gen_tri_mat #if current_dim > dim, then we end loop
  49.  
  50. li $t2, 0 #control var for inner_Loop1,, named 'i' in c code
  51.  
  52. inner_Loop1: #goes from 1 to n
  53.  
  54. addi $t2, $t2, 1 #increment control var
  55.  
  56. bgt $t2, $t1, end_inner_Loop1
  57.  
  58. sgt $t4, $t2, $t3 #Set $t5 if i > j i.e if $t3 > $t2
  59.  
  60. beq $t4,$0, inner_Loop1 # we want $t4 to be 1, i.e. NOT equal to zero.. designated ' if (i>j)' in c code
  61.  
  62. #if we reach here , it means that if condition was true i.e i>j is true
  63.  
  64. # c = A[i][j] / A[j][j] or A[t2][t3] / A[t3][t3]
  65.  
  66. # load A[i][j], i = $t2; j = $t3
  67.  
  68. #now we load the Matrix element A[row][col]
  69.  
  70. #===============================================================================
  71. #generic formula (for NxN matrix) for offset value is : N*s*(row-1) + s*(col-1)
  72. # where
  73. # N is the matrix dimension
  74. # s is the size of ONE element of matrix e.g 4 bytes for int, 1 byte for char
  75. #===============================================================================
  76.  
  77. # in code we have row = $t2, col = $t3
  78.  
  79. #calc (row - 1)
  80. addi $t4, $t2, -1
  81.  
  82. #calc (col - 1)
  83. addi $t5, $t3, -1
  84.  
  85. # s = 4 bytes for IEEE 754 Single Precision Floating Point
  86. # calc s*(col-1)
  87. li $t6, 4
  88.  
  89. mul $t5, $t5, $t6
  90.  
  91. #calc s*(row-1)
  92. mul $t4, $t4,$t6
  93.  
  94. #calc N*s*(row-1)
  95.  
  96. mul $t4, $t4,$s6
  97.  
  98. #add the two products
  99. add $t7, $t5,$t4
  100.  
  101. #now $t7 has final offset value to be added to the array starting
  102. #Let add the value to start address
  103.  
  104. add $t7,$t7,$t0
  105.  
  106. #now t7 has correct mem address of element A[r][c], Let's laod it -- A[i][j] loaded
  107. l.s $f0, 0($t7)
  108.  
  109.  
  110. ## reset all used intermediate registers so that the next address could be calculated.
  111.  
  112. li $t4, 0
  113. li $t5, 0
  114. li $t7, 0
  115.  
  116. #===========================================================================
  117. # load A[j][j] ; Here j = t3 #
  118. #===========================================================================
  119.  
  120. #calc (row - 1)
  121. addi $t4, $t3, -1
  122.  
  123. #calc (col - 1)
  124. addi $t5, $t3, -1
  125.  
  126. # s = 4 bytes for IEEE 754 Single Precision Floating Point
  127. # calc s*(col-1)
  128. li $t6, 4
  129.  
  130. mul $t5, $t5, $t6
  131.  
  132. #calc s*(row-1)
  133. mul $t4, $t4,$t6
  134.  
  135. #calc N*s*(row-1)
  136. mul $t4, $t4,$s6
  137.  
  138. #add the two products
  139. add $t7, $t5,$t4
  140.  
  141. #now $t7 has final offset value to be added to the array starting
  142. #Let add the value to start address
  143.  
  144. add $t7,$t7,$t0
  145.  
  146. #now t7 has correct mem address of element A[r][c], Let's laod it -- A[j][j] loaded
  147. l.s $f1, 0($t7)
  148.  
  149. ## reset all used intermediate registers so that the next address could be calculated.
  150.  
  151. li $t4, 0
  152. li $t5, 0
  153. li $t7, 0
  154.  
  155. #==============================================================
  156. # Now $f0 = A[i][j] AND $f1 = A[j][j] , we need to divide now
  157. #==============================================================
  158.  
  159. div.s $f3, $f0, $f1 #this is our 'C' !!! Causing NaN
  160.  
  161. # second inner loop , goes from k=1 to n+1
  162.  
  163. addi $s0,$t1, 1 #set s0 to n+1
  164.  
  165. li $s1, 0 #loop control var
  166. inner_Loop2:
  167.  
  168. addi $s1, $s1, 1
  169.  
  170. bgt $s1,$s0, end_inner_Loop2 #compare with n+1
  171.  
  172. # A[i][k]=A[i][k]-c*A[j][k];
  173. #tast breakdown
  174. # 1. Load A[i][k] and A[j][k]
  175. # 2. calc C*A[j][k]
  176. # 3. calc x = A[i][k]-c*A[j][k]
  177. # 4. store x on A[i][k] ... for this we need Address of A[i][k]th element
  178.  
  179. # task 1 : Load A[i][k] ; i = t2 k = s1
  180.  
  181. #calc (row - 1)
  182. addi $t4, $t2, -1
  183.  
  184. #calc (col - 1)
  185. addi $t5, $s1, -1
  186.  
  187. # s = 4 bytes for IEEE 754 Single Precision Floating Point
  188. # calc s*(col-1)
  189. li $t6, 4
  190.  
  191. mul $t5, $t5, $t6
  192.  
  193. #calc s*(row-1)
  194. mul $t4, $t4,$t6
  195.  
  196. #calc N*s*(row-1)
  197. mul $t4, $t4,$s6
  198.  
  199. #add the two products
  200. add $t7, $t5,$t4
  201.  
  202. #now $t7 has final offset value to be added to the array starting
  203. #Let add the value to start address
  204.  
  205. add $t7,$t7,$t0
  206.  
  207. #now t7 has correct mem address of element A[r][c], Let's laod it
  208. l.s $f4, 0($t7)
  209.  
  210. #save address of A[i][k], bcz we have to store it back
  211. move $s7, $t7
  212.  
  213. ## reset all used intermediate registers so that the next address could be calculated.
  214.  
  215. li $t4, 0
  216. li $t5, 0
  217. li $t7, 0
  218.  
  219. #==== loaded A[i][k] ===
  220.  
  221. # load A[j][k]
  222.  
  223. #calc (row - 1)
  224. addi $t4, $t3, -1
  225.  
  226. #calc (col - 1)
  227. addi $t5, $s1, -1
  228.  
  229. # s = 4 bytes for IEEE 754 Single Precision Floating Point
  230. # calc s*(col-1)
  231. li $t6, 4
  232.  
  233. mul $t5, $t5, $t6
  234.  
  235. #calc s*(row-1)
  236. mul $t4, $t4,$t6
  237.  
  238. #calc N*s*(row-1)
  239. mul $t4, $t4,$s6
  240.  
  241. #add the two products
  242. add $t7, $t5,$t4
  243.  
  244. #now $t7 has final offset value to be added to the array starting
  245. #Let add the value to start address
  246.  
  247. add $t7,$t7,$t0
  248.  
  249. #now t7 has correct mem address of element A[r][c], Let's laod it
  250. l.s $f5, 0($t7)
  251.  
  252. ## reset all used intermediate registers so that the next address could be calculated.
  253.  
  254. li $t4, 0
  255. li $t5, 0
  256. li $t7, 0
  257.  
  258.  
  259. # now $f4 = A[i][k] and $f5 = A[j][k]
  260.  
  261. # 2. calc C*A[j][k]
  262.  
  263. #mul.s $f6, $f4, $f5 #possible error : $f4 shoud be $f3
  264. mul.s $f6, $f3, $f5 #attempt at rectifying error
  265.  
  266. # 3. calc x = A[i][k]-c*A[j][k]
  267.  
  268. sub.s $f7, $f4,$f6
  269.  
  270. # 4. store x on A[i][k] ... for this we need Address of A[i][k]th element. s7 has addr of A[i][k]
  271.  
  272. s.s $f7, 0($s7)
  273.  
  274. b inner_Loop2
  275.  
  276. end_inner_Loop2:
  277.  
  278. b inner_Loop1
  279.  
  280. end_inner_Loop1:
  281.  
  282. b gen_tri_mat
  283.  
  284. end_gen_tri_mat:
  285.  
  286. ## reset all used intermediate registers so that the next address could be calculated.
  287. ## (added this as precaution, following 3 lines were NOT present in initial attempt
  288. li $t4, 0
  289. li $t5, 0
  290. li $t7, 0
  291.  
  292. # Now we're done with generation of Upper triangular matrix, it's time to substitute back in!
  293. # Back substitution code
  294.  
  295. # === START code for caclulating X[n] =====
  296.  
  297. # calc x[n]=A[n][n+1]/A[n][n], where n is the dimension
  298.  
  299. # load A[n][n] ... n is in t1
  300.  
  301. #calc (row - 1)
  302. addi $t4, $t1, -1
  303.  
  304. #calc (col - 1)
  305. addi $t5, $t1, -1
  306.  
  307. # s = 4 bytes for IEEE 754 Single Precision Floating Point
  308. # calc s*(col-1)
  309. li $t6, 4
  310.  
  311. mul $t5, $t5, $t6
  312.  
  313. #calc s*(row-1)
  314. mul $t4, $t4,$t6
  315.  
  316. #calc N*s*(row-1)
  317. mul $t4, $t4,$s6
  318.  
  319. #add the two products
  320. add $t7, $t5,$t4
  321.  
  322. #now $t7 has final offset value to be added to the array starting
  323. #Let add the value to start address
  324.  
  325. add $t7,$t7,$t0
  326.  
  327. #now t7 has correct mem address of element A[r][c], Let's laod it
  328. l.s $f9, 0($t7)
  329.  
  330. ## reset all used intermediate registers so that the next address could be calculated.
  331.  
  332. li $t4, 0
  333. li $t5, 0
  334. li $t7, 0
  335.  
  336. #========================
  337. # load A[n][n+1]
  338. #========================
  339.  
  340. addi $s2, $t1, 1 #set s2 to n+1
  341.  
  342. #calc (row - 1)
  343. addi $t4, $t1, -1
  344.  
  345. #calc (col - 1)
  346. addi $t5, $s2, -1
  347.  
  348. # s = 4 bytes for IEEE 754 Single Precision Floating Point
  349. # calc s*(col-1)
  350. li $t6, 4
  351.  
  352. mul $t5, $t5, $t6
  353.  
  354. #calc s*(row-1)
  355. mul $t4, $t4,$t6
  356.  
  357. #calc N*s*(row-1)
  358. mul $t4, $t4,$s6
  359.  
  360. #add the two products
  361. add $t7, $t5,$t4
  362.  
  363. #now $t7 has final offset value to be added to the array starting
  364. #Let add the value to start address
  365.  
  366. add $t7,$t7,$t0
  367.  
  368. #now t7 has correct mem address of element A[r][c], Let's laod it
  369. l.s $f10, 0($t7)
  370.  
  371. ## reset all used intermediate registers so that the next address could be calculated.
  372.  
  373. li $t4, 0
  374. li $t5, 0
  375. li $t7, 0
  376.  
  377. #perform division (this ONLY performs the division op, but DOESNOT store result back in x[n]
  378. div.s $f11, $f10, $f9
  379.  
  380. # Let $t9 be the starting addr of result vector
  381. la $t9, results
  382.  
  383. #offset = s*(i-1)
  384. #for this step i = n = dimension = $t1
  385. add $t8, $0, $t1
  386. addi $t8, $t8, -1
  387. mul $t8, $t8, 4
  388.  
  389. #add offset to starting addr of results vector
  390. add $t8, $t8, $t9
  391.  
  392. #store X[n]
  393. s.s $f11,0($t8)
  394.  
  395. #reset t8
  396. li $t8, 0
  397.  
  398.  
  399. # === END code for caclulating X[n] =====
  400.  
  401. ## Usama Work Start
  402.  
  403. # backward substitution
  404.  
  405.  
  406. #reset two control vars , this clears values which COULD be present
  407.  
  408. li $t2, 0
  409. li $t3, 0
  410.  
  411. #Loop control variable, goes from n-1 to 1, named 'i' in c code
  412. addi $t2,$t1,0
  413.  
  414. #loop for backward substitution
  415.  
  416. back_sub:
  417.  
  418. addi $t2, $t2, -1 #decrement control var
  419.  
  420. blt $t2, 1, end_back_sub #if loop control variable is less than 1, then we end loop
  421.  
  422. # j = i + 1, $t3 = $t2 + 1
  423. li $t3, 0
  424.  
  425. addi $t3, $t2, 0 #control var for inner_Loop1,, named 'j' in c code
  426.  
  427. #li $f15,0 #will contain sum of sum <-- sum+A[i][j]*x[j]
  428. #add.s $f15,$0,$0
  429. #commented above two lines, assume $f15 has 0 already
  430.  
  431. #sum = 0
  432. l.s $f15, zero
  433.  
  434. inner_Loop_Us: #goes from i+1 to n
  435.  
  436. addi $t3, $t3, 1 #increment control var
  437.  
  438. bgt $t3, $t1, end_inner_Loop_Us
  439.  
  440.  
  441. # sum=sum+A[i][j]*x[j] or A[t2][t3]*x[t3]
  442.  
  443. # load A[i][j], i = $t2; j = $t3
  444.  
  445. #now we load the Matrix element A[row][col]
  446.  
  447. #===============================================================================
  448. #generic formula (for NxN matrix) for offset value is : N*s*(row-1) + s*(col-1)
  449. # where
  450. # N is the matrix dimension
  451. # s is the size of ONE element of matrix e.g 4 bytes for int, 1 byte for char
  452. #===============================================================================
  453.  
  454. # in code we have row = $t2, col = $t3
  455.  
  456. #calc (row - 1)
  457. addi $t4, $t2, -1
  458.  
  459. #calc (col - 1)
  460. addi $t5, $t3, -1
  461.  
  462. # s = 4 bytes for IEEE 754 Single Precision Floating Point
  463. # calc s*(col-1)
  464. li $t6, 4
  465.  
  466. mul $t5, $t5, $t6
  467.  
  468. #calc s*(row-1)
  469. mul $t4, $t4,$t6
  470.  
  471. #calc N*s*(row-1)
  472. mul $t4, $t4,$s6
  473.  
  474. #add the two products
  475. add $t7, $t5,$t4
  476.  
  477. #now $t7 has final offset value to be added to the array starting
  478. #Let add the value to start address
  479.  
  480. add $t7,$t7,$t0
  481.  
  482. #now t7 has correct mem address of element A[r][c], Let's laod it -- A[i][j] loaded
  483. l.s $f20, 0($t7)
  484.  
  485.  
  486. ## reset all used intermediate registers so that the next address could be calculated.
  487.  
  488. li $t4, 0
  489. li $t5, 0
  490. li $t7, 0
  491.  
  492. #===========================================================================
  493. # multiply A[i][j]*x[j] ; Here j = t3 #
  494. #===========================================================================
  495.  
  496. #load x[j]
  497.  
  498. # Let $t9 be the starting addr of result vector
  499. la $t9, results
  500.  
  501. #4 bytes = 1 SP FP num
  502. li $t8, 4
  503.  
  504. #offset = size*number
  505. mul $t8, $t8, $s6
  506.  
  507. #add offset to starting addr of results vector
  508. add $t8, $t8, $t9
  509.  
  510. l.s $f13,0($t8) # load address of $t3 in $f13
  511.  
  512. # ======================= TEST CODE FOR x[j] loading =========================
  513.  
  514. # Let $t9 be the starting addr of result vector
  515. la $t9, results
  516.  
  517. #offset = s*(j-1)
  518. #for this step j = $t3
  519. add $t8, $0, $t3
  520. addi $t8, $t8, -1
  521. mul $t8, $t8, 4
  522.  
  523. #add offset to starting addr of results vector
  524. add $t8, $t8, $t9
  525.  
  526. #load X[n]
  527. l.s $f13,0($t8)
  528.  
  529. #reset t8
  530. li $t8, 0
  531. # ======================== end test code =====================================
  532.  
  533. mul.s $f14,$f20,$f13 # $s2 stores the product of two
  534.  
  535. # now performing 'sum=sum+A[i][j]*x[j]' where sum is represented by $s0
  536.  
  537. add.s $f15,$f15,$f14
  538.  
  539. #reset t8
  540. li $t8, 0
  541.  
  542. b inner_Loop_Us
  543.  
  544. end_inner_Loop_Us: #inner_loop ends
  545.  
  546.  
  547. # TODO: x[i]=(A[i][n+1]-sum)/A[i][i],
  548. # where n is the dimension
  549. # i = t2
  550. # sum = $s2
  551.  
  552. #x[i]=(A[i][n+1]-sum)/A[i][i];
  553. #tast breakdown
  554. # 1. Load A[i][i] and A[i][n+1]
  555. # 2. calc (A[i][n+1]-sum)
  556. # 3. calc x[i] = (A[i][n+1]-sum)/A[i][i]
  557.  
  558.  
  559. # task 1 : Load A[i][i] and A[i][n+1] ; i = t2
  560.  
  561. #========================
  562. # load A[i][i]
  563. #========================
  564.  
  565.  
  566. #calc (row - 1)
  567. addi $t4, $t2, -1
  568.  
  569. #calc (col - 1)
  570. addi $t5, $t2, -1
  571.  
  572. # s = 4 bytes for IEEE 754 Single Precision Floating Point
  573. # calc s*(col-1)
  574. li $t6, 4
  575.  
  576. mul $t5, $t5, $t6
  577.  
  578. #calc s*(row-1)
  579. mul $t4, $t4,$t6
  580.  
  581. #calc N*s*(row-1)
  582. mul $t4, $t4,$s6
  583.  
  584. #add the two products
  585. add $t7, $t5,$t4
  586.  
  587. #now $t7 has final offset value to be added to the array starting
  588. #Let add the value to start address
  589.  
  590. add $t7,$t7,$t0
  591.  
  592. #now t7 has correct mem address of element A[r][c], Let's laod it
  593. l.s $f16, 0($t7)
  594.  
  595. ## reset all used intermediate registers so that the next address could be calculated.
  596.  
  597. li $t4, 0
  598. li $t5, 0
  599. li $t7, 0
  600.  
  601. #========================
  602. # load A[i][n+1]
  603. #========================
  604.  
  605. addi $s2, $t1, 1 #set s2 to n+1
  606.  
  607. #calc (row - 1)
  608. addi $t4, $t2, -1
  609.  
  610. #calc (col - 1)
  611. addi $t5, $s2, -1
  612.  
  613. # s = 4 bytes for IEEE 754 Single Precision Floating Point
  614. # calc s*(col-1)
  615. li $t6, 4
  616.  
  617. mul $t5, $t5, $t6
  618.  
  619. #calc s*(row-1)
  620. mul $t4, $t4,$t6
  621.  
  622. #calc N*s*(row-1)
  623. mul $t4, $t4,$s6
  624.  
  625. #add the two products
  626. add $t7, $t5,$t4
  627.  
  628. #now $t7 has final offset value to be added to the array starting
  629. #Let add the value to start address
  630.  
  631. add $t7,$t7,$t0
  632.  
  633. #now t7 has correct mem address of element A[r][c], Let's laod it
  634. l.s $f17, 0($t7)
  635.  
  636. ## reset all used intermediate registers so that the next address could be calculated.
  637.  
  638. li $t4, 0
  639. li $t5, 0
  640. li $t7, 0
  641.  
  642. # task 2 : calc (A[i][n+1]-sum)
  643.  
  644. # sum = f15
  645.  
  646. sub.s $f18,$f17,$f15
  647.  
  648.  
  649. # task 3 : calc x[i] = (A[i][n+1]-sum)/A[i][i]
  650.  
  651. #perform division, f19 has x[i]
  652. div.s $f19, $f18, $f16
  653.  
  654. # ======================= TEST CODE FOR x[i] SAVING =========================
  655.  
  656. # Let $t9 be the starting addr of result vector
  657. la $t9, results
  658.  
  659. #offset = s*(i-1)
  660. #for this step i = $t2
  661. add $t8, $0, $t2
  662. addi $t8, $t8, -1
  663. mul $t8, $t8, 4
  664.  
  665. #add offset to starting addr of results vector
  666. add $t8, $t8, $t9
  667.  
  668. #store X[n]
  669. s.s $f19,0($t8)
  670.  
  671. #reset t8
  672. li $t8, 0
  673. # ======================== end test code =====================================
  674.  
  675. #prints out statement
  676. #li $v0, 4
  677. #la $a0, result
  678. #syscall
  679.  
  680. ##MY added lines
  681. #li $v0, 2
  682.  
  683. # print
  684. #mov.s $f12,$f19
  685. #syscall
  686.  
  687. ##MY added lines end
  688.  
  689. b back_sub
  690.  
  691. end_back_sub:
  692.  
  693. # Now finally printing the results
  694.  
  695. # output prompt
  696.  
  697. li $v0, 4
  698. la $a0, result #prints out statement
  699. syscall
  700.  
  701. #print new line
  702.  
  703. li $v0, 4
  704. la $a0, newline
  705. syscall
  706.  
  707. #printing results loop
  708.  
  709. li $t2, 0 #control var for inner_Loop1,, named 'i' in c code
  710.  
  711. Output_Loop: #goes from 1 to n
  712.  
  713. addi $t2, $t2, 1 #increment control var
  714.  
  715. bgt $t2, $t1, End_Output_Loop
  716.  
  717. # print result
  718. # ======================= TEST CODE FOR x[j] loading =========================
  719.  
  720. # Let $t9 be the starting addr of result vector
  721. la $t9, results
  722.  
  723. #offset = s*(j-1)
  724. #for this step j = $t2
  725. add $t8, $0, $t2
  726. addi $t8, $t8, -1
  727. mul $t8, $t8, 4
  728.  
  729. #add offset to starting addr of results vector
  730. add $t8, $t8, $t9
  731.  
  732. #load X[n]
  733. l.s $f22,0($t8)
  734.  
  735. li $v0, 2
  736. mov.s $f12, $f22
  737. syscall
  738.  
  739. #reset t8
  740. li $t8, 0
  741. # ======================== end test code =====================================
  742.  
  743. #print new line
  744.  
  745. li $v0, 4
  746. la $a0, newline
  747. syscall
  748.  
  749. b Output_Loop
  750.  
  751. End_Output_Loop:
  752.  
  753. jr $ra
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement