<table cellspacing="0" cellpadding="0" border="0" ><tr><td valign="top" style="font: inherit;">I am keeping with my project of translating programs from Clean to Haskell. As far as arrays go, I don't understand well how to use them in Haskell. Therefore, I will appreciate if somebody can find time to check the program below, and make suggestions to improve it. My Haskell program is about 4 times slower than the Clean version. It would be great if one could reduce the execution time by half, approaching to the speed of Clean and Scheme. Here are the constraints:<br><br>1 --- The program must be implemented using arrays.&nbsp; Update must be done in place, in order to minimize use of the garbage collector. I have used Data.Array.IO, but I guess that&nbsp; Data.Array.ST is better. Is it easy to rewrite the program in order to use DataArray.ST?<br><br>2 --&nbsp; I liked very much the forM_ monad. I wonder if there is an accumulating monad that play the role
 of a program like leftSide.<br><br>3 -- Clean program almost double its speed, if one uses strictness annotations. Is it possible to use similar anotations for Haskell?<br><br>Here is how I compiled the program:<br><br>ghc -O2 gel.hs --make<br><br>In order to run the program with 2000 equations,&nbsp; type<br><br>gel.exe 2000 +RTS -sstderr<br><br>The program will create a linear system with 2000 equations so that all elements of the solution is equal to 1. It prints 20 elements of the solution.<br><br>Here is the program:<br><br>{- File: gel.hs<br>Compilation: ghc -O2 gel.hs --make<br>Run: time gel.exe 2000<br>-}<br>import Control.Monad<br>import Data.Array.IO<br>import System.IO<br>import System.Random<br>import System (getArgs)<br><br>prtSol i n1 arr | i &lt; 1= return ()<br>prtSol i n1 arr= do<br>&nbsp;&nbsp;&nbsp; b &lt;- readArray arr (i, n1)<br>&nbsp;&nbsp;&nbsp; putStr ((show b)++" ")<br>&nbsp;&nbsp;&nbsp; prtSol (i-1) n1 arr<br><br>fillArray xs
 s (i, n) (j, m) arr |&nbsp; i &gt; n= return ()<br>fillArray xs s (i,n) (j, m) arr | i==n &amp;&amp; j&gt;m= do<br>&nbsp; writeArray arr (i, j) s<br>&nbsp; return ()<br>fillArray xs s (i, n) (j, m) arr | j &gt; m&nbsp; = do<br>&nbsp;&nbsp; writeArray arr (i, j) s<br>&nbsp;&nbsp; fillArray xs 0.0 (i+1, n) (1, m) arr<br>fillArray (val:xs) s (i, n) (j, m) arr= do<br>&nbsp;&nbsp; writeArray arr (i, j) val<br>&nbsp;&nbsp; fillArray xs (s+val) (i, n) (j+1, m) arr<br><br>sLU arr n= sIJ 2 1 2 n arr<br><br>sIJ i j k n arr | i &gt; n = return ()<br>sIJ i j k n arr | k &gt; n = sIJ (i+1) i (i+1) n arr<br>sIJ i j k n arr = do<br>&nbsp; im &lt;- pmax (j+1) j<br>&nbsp; swap j im 1<br>&nbsp; a &lt;- readArray arr (k, j)<br>&nbsp; forM_ [j..n+1] $&nbsp; \l -&gt; do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ajj &lt;- readArray arr (j, j)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ajl &lt;- readArray arr (j, l)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; akl &lt;- readArray arr (k, l)
 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writeArray arr (k, l) (akl-a*(ajl/ajj))<br>&nbsp; sIJ i j (k+1) n arr where<br>&nbsp;&nbsp;&nbsp;&nbsp; pmax line imax | line &gt; n = return imax<br>&nbsp;&nbsp;&nbsp;&nbsp; pmax line imax = do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alj &lt;- readArray arr (line, j)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; aij &lt;- readArray arr (imax, j)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (abs alj)&gt; (abs aij) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; then pmax (line+1) line<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else pmax (line+1) imax<br>&nbsp;&nbsp;&nbsp;&nbsp; swap r s q | q&gt;n+1 = return ()<br>&nbsp;&nbsp;&nbsp;&nbsp; swap r s q | r==s = return ()<br>&nbsp;&nbsp;&nbsp;&nbsp; swap r s q = do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arq &lt;- readArray arr (r,q)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; asq &lt;- readArray arr
 (s,q)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writeArray arr (s,q) arq<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writeArray arr (r,q) asq<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; swap r s (q+1)<br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; <br>leftSide acc i j n arr | j&gt;n= return acc<br>leftSide acc i j n arr = do<br>&nbsp;&nbsp; v &lt;- readArray arr (j, n+1)<br>&nbsp;&nbsp; a &lt;- readArray arr (i, j)<br>&nbsp;&nbsp; leftSide (acc-v*a) i (j+1) n arr<br><br>solvit i n arr | i&lt;1= return ()<br>solvit i n arr= do<br>&nbsp;&nbsp; a &lt;- readArray arr (i, i)<br>&nbsp;&nbsp; acc &lt;- readArray arr (i, n+1)<br>&nbsp;&nbsp; v &lt;- leftSide acc i (i+1) n arr<br>&nbsp;&nbsp; writeArray arr (i, n+1) (v/a)<br>&nbsp;&nbsp; solvit (i-1) n arr<br><br>rnList :: (Double, Double) -&gt; IO [Double]<br>rnList r=getStdGen&gt;&gt;=(\x-&gt;return(randomRs r x))<br><br>dims [input] = (read input, read input)<br>dims _ = (1000, 1000)<br><br>main =
 do<br>&nbsp;&nbsp;&nbsp;&nbsp; xs &lt;- rnList (1.0,1000.0)<br>&nbsp;&nbsp;&nbsp;&nbsp; args &lt;- getArgs<br>&nbsp;&nbsp;&nbsp;&nbsp; let (n, m)= dims args<br>&nbsp;&nbsp;&nbsp;&nbsp; arr &lt;- newArray_ ((1,1),(n,m+1)) :: <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IO (IOUArray (Int, Int) Double)<br>&nbsp;&nbsp;&nbsp;&nbsp; fillArray xs 0.0 (1,n) (1,m) arr<br>&nbsp;&nbsp;&nbsp;&nbsp; sLU arr n<br>&nbsp;&nbsp;&nbsp;&nbsp; solvit n n arr<br>&nbsp;&nbsp;&nbsp;&nbsp; prtSol (min 20 n) (n+1) arr<br>&nbsp;&nbsp;&nbsp;&nbsp; print "Done"<br><br></td></tr></table><br>
      <hr size=1>
Looking for the perfect gift?<a href="http://www.flickr.com/gift/"><b> Give the gift of Flickr!</b></a>