<div dir="ltr">Recall that last. Always measure at the command line <sigh>. I'm seeing FlVector at 30% faster. <div><br></div><div style><div>#lang typed/racket</div><div><br></div><div>(provide main)</div><div>
<br></div><div>(require racket/unsafe/ops</div><div><span class="" style="white-space:pre">        </span> racket/fixnum</div><div> racket/flonum)</div><div><br></div><div>(define-type NF Nonnegative-Fixnum)</div><div><br>
</div><div>(: matrix* :</div><div> FlVector FlVector Index Index Index</div><div> -> FlVector)</div><div>(define (matrix* A B m p n)</div><div> (define size (* m n))</div><div> (define: v : FlVector (make-flvector size 0.0))</div>
<div> (define index 0)</div><div> (: loop-i : NF -> FlVector)</div><div> (define (loop-i i)</div><div> (cond [(< i m)</div><div> (loop-j i 0)</div><div> (loop-i (+ i 1))]</div><div> [else v]))</div>
<div> (: loop-j : NF NF -> Void)</div><div> (define (loop-j i j)</div><div> (when (< j n)</div><div> (loop-k i j 0 0.0)</div><div> (set! index (+ index 1))</div><div> (loop-j i (+ j 1))))</div><div>
(: loop-k : NF NF NF Flonum -> Void)</div><div> (define (loop-k i j k sum)</div><div> (define i*p (* i p))</div><div> (define k*n (* k n))</div><div> (cond</div><div> [(< k p)</div><div> (loop-k i j (+ k 1)</div>
<div><span class="" style="white-space:pre">        </span> (+ sum</div><div><span class="" style="white-space:pre">                </span> (* (unsafe-flvector-ref A (+ i*p k))</div><div><span class="" style="white-space:pre">                        </span>(unsafe-flvector-ref B (+ k*n j)))))]</div>
<div> [else</div><div> (unsafe-flvector-set! v index sum)]))</div><div> (loop-i 0))</div><div><br></div><div>(: mkFlVector (Fixnum (-> Flonum) -> FlVector))</div><div>(define (mkFlVector sz init)</div><div>
(let ((v (make-flvector sz)))</div><div> (do ((i #{0 : Fixnum} (+ i 1)))</div><div><span class="" style="white-space:pre">        </span>((>= i sz) v)</div><div> (unsafe-flvector-set! v i (init)))))</div><div><br></div>
<div>(define: dim : Index 300)</div><div>(define: A : FlVector (mkFlVector (fx* dim dim) random))</div><div>(define: B : FlVector (mkFlVector (fx* dim dim) random))</div><div><br></div><div>(define (main)</div><div> (collect-garbage)</div>
<div> (collect-garbage)</div><div> (let ((m (time (matrix* A B dim dim dim))))</div><div> (void)))</div><div><br></div></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Sun, Jan 20, 2013 at 4:25 PM, Ray Racine <span dir="ltr"><<a href="mailto:ray.racine@gmail.com" target="_blank">ray.racine@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Modification of the above to use FlVector did not show a difference.</div><div class="HOEnZb"><div class="h5">
<div class="gmail_extra"><br><br><div class="gmail_quote">On Sun, Jan 20, 2013 at 2:35 PM, Jens Axel Søgaard <span dir="ltr"><<a href="mailto:jensaxel@soegaard.net" target="_blank">jensaxel@soegaard.net</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">2013/1/20 Berthold Bäuml <<a href="mailto:berthold.baeuml@dlr.de" target="_blank">berthold.baeuml@dlr.de</a>>:<br>
<div>>> Ah! The Numpy example uses floats and not doubles.<br>
><br>
> On my machine Numpy says it is using float64, hence, double.<br>
> <a href="http://big1.dtype.name" target="_blank">big1.dtype.name</a> -> float64<br>
<br>
</div>Sorry for the confusion. I am used to the Racket documentation<br>
were float means single precision, so I misinterpreted the Numpy<br>
documentation.<br>
<br>
Also<br>
<br>
> numpy.random.random((5,5))<br>
array([[ 0.04748764, 0.15242073, 0.2366255 , 0.86926654, 0.16586114],<br>
[ 0.33117124, 0.7504899 , 0.43179013, 0.1992083 , 0.83266119],<br>
[ 0.25741902, 0.36912007, 0.38273193, 0.29622522, 0.75817261],<br>
[ 0.49313726, 0.20514653, 0.45329344, 0.964105 , 0.77459153],<br>
[ 0.5267172 , 0.87269101, 0.34530438, 0.38218051, 0.05107181]])<br>
<br>
suggested, that the numbers were single precision. It turns out<br>
that random only produces 53 bit random floats.<br>
<br>
Anyways, here is a standard matrix multiplication algorithm in<br>
Typed Racket.<br>
<br>
#lang typed/racket<br>
(require racket/unsafe/ops<br>
racket/flonum)<br>
<br>
(define-type NF Nonnegative-Fixnum)<br>
<br>
(: matrix* :<br>
(Vectorof Flonum) (Vectorof Flonum) Index Index Index<br>
-> (Vectorof Flonum))<br>
(define (matrix* A B m p n)<br>
(define size (* m n))<br>
(define: v : (Vectorof Flonum) (make-vector size 0.0))<br>
(define index 0)<br>
(: loop-i : NF -> (Vectorof Flonum))<br>
(define (loop-i i)<br>
(cond [(< i m)<br>
(loop-j i 0)<br>
(loop-i (+ i 1))]<br>
[else v]))<br>
(: loop-j : NF NF -> Void)<br>
(define (loop-j i j)<br>
(when (< j n)<br>
(loop-k i j 0 0.0)<br>
(set! index (+ index 1))<br>
(loop-j i (+ j 1))))<br>
(: loop-k : NF NF NF Flonum -> Void)<br>
(define (loop-k i j k sum)<br>
(define i*p (* i p))<br>
(define k*n (* k n))<br>
(cond<br>
[(< k p)<br>
(loop-k i j (+ k 1)<br>
(+ sum<br>
(* (unsafe-vector-ref A (+ i*p k))<br>
(unsafe-vector-ref B (+ k*n j)))))]<br>
[else<br>
(vector-set! v index sum)]))<br>
(loop-i 0))<br>
<br>
(define dim 200)<br>
(define A (build-vector (* dim dim) (λ (_) (random))))<br>
(define B (build-vector (* dim dim) (λ (_) (random))))<br>
(collect-garbage)<br>
(collect-garbage)<br>
(define A*B (time (matrix* A B dim dim dim)))<br>
<span><font color="#888888"><br>
/Jens Axel<br>
</font></span><div><div><br>
____________________<br>
Racket Users list:<br>
<a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>