Re: m.*! not native?

Jefferson Provost <[email protected]>
Newsgroups gmane.lisp.matlisp.user
Message-ID <B8809C66.1CFB%[email protected]>
Tunc,

Thanks for the help and the code.  I'll look at it and see what I can do and
let you all know.  I may post with some questions on optimization, since I
haven't really tried to optimize my code much before.

Re: "covariance normalization":  I don't know if there's an official name
for it, but basically it's an operation on a square matrix A to produce a
new matrix B, where B(x,y) = A(x,y)/sqrt(A(x,x)*A(y,y)).

If A was a covariance matrix, B will be the corresponding correlation
matrix, with 1's on the diagonal and all the other values in the range
[-1,1].  (i.e. B(x,y) is the correlation between variable x and variable y.)

I have implemented it using MATLISP, but it's not optimized at all... I see
how to optimize it now, I think, so hopefully it should speed up a lot.

Thanks!
Jeff


On 2/1/02 4:55 PM, "Tunc Simsek" <[email protected]> wrote:

> Hi Ray, Jefferson;
> 
> I've played with Allegro 6.0 as follows (I asked it to explain
> the compilation of m.*!):
> 
> (defmethod m.*! ((a real-matrix) (b real-matrix))
> (let* ((nxm (number-of-elements b)))
>   (declare (type fixnum nxm)
>     (optimize (speed 3) (safety 0)))
> 
>   (dotimes (k nxm b)
>     (declare (type fixnum k))
>     (let ((a-val (matrix-ref a k))
>    (b-val (matrix-ref b k)))
> (declare (type real-matrix-element-type a-val b-val)
> (:explain :calls :types :boxing))
> (setf (matrix-ref b k) (* a-val b-val))))))
> 
> 
> and here is what I get:
> 
> ;;; Compiling file C:\usr\gigascale\shift\src\matlisp\src\mtimes.lisp
> ;Examining a (possibly unboxed) call to *_2OP with arguments:
> ;  symeval A-VAL type (DOUBLE-FLOAT * *)
> ;  symeval B-VAL type (DOUBLE-FLOAT * *)
> ; which returns a value of type (DOUBLE-FLOAT * *)
> ;Generating a DOUBLE-FLOAT box
> ;Examining a call to FUNCALL with arguments:
> ;  call to CDR type KNOWN-FUNCTION
> ;  symeval G16043 type (DOUBLE-FLOAT * *)
> ;  symeval G16044 type #<STANDARD-CLASS REAL-MATRIX>
> ;  symeval G16045 type (INTEGER -536870912 536870911)
> ; which returns a value of type T
> ;Examining a call to CDR with arguments:
> ;  constant ((EVAL-WHEN-LOADED) SETF-METHOD-LOCATIVE (QUOTE MATRIX-REF)
> ...) type TRUE-LIST
> ; which returns a value of type KNOWN-FUNCTION
> ;;; Writing fasl file C:\usr\gigascale\shift\src\matlisp\bin\mtimes.fasl
> 
> so my conclusion is that the MATRIX-REF used to access the variables is
> waaaaay more expensive than AREF.  Insomuch that it has the overhead of
> a generic function dispatch and also a boxing of the results.
> This will explain the performance figures given by Jefferson, which
> I was able to duplicate (roughly on the same order) on my Windows 2000
> pentium something machine.
> 
> Now I quickly tried the following change and got a performance increase
> of exactly 10 fold (ie. from 1.7 seconds per call to .13 seconds)
> and the compiler is still saying that there is boxing.  I don't know
> the Allegro flags very well, but it seems that the matlisp sources
> can be modified so that this performance problem disappears
> and there is no need to do m.*! in fortran. (disclaimer:  I DIDN'T
> TEST IF THE FOLLOWING MODIFICATIONS GIVE CORRECT COMPUTATIONAL
> RESULTS OR ARE CONSISTENT WITH MATLISP CODING STANDARDS)
> 
> (defmethod m.*! ((a real-matrix) (b real-matrix))
> (let* ((nxm (number-of-elements b))
> (aa (store a))
> (bb (store b)))
>   (declare (type fixnum nxm)
>     (type (real-matrix-store-type (*)) aa bb)
>     (optimize (speed 3) (safety 0)))
> 
>   (dotimes (k nxm b)
>     (declare (type fixnum k))
>     (let ((a-val (aref aa k))
>    (b-val (aref bb k)))
> (declare (type real-matrix-element-type a-val b-val)
> (:explain :calls :types :boxing))
> (setf (aref bb k) (* a-val b-val))))))
> 
> Good luck and keep this list posted on your results,
> I think a tested version of these changes should be checked in
> to the repository.
> 
>  -- Tunc
> 
> ps. I don't know your terminology on covariance normalization.
> But it seems to me that it should be possible using matlisp functions.
> 
> Jefferson Provost wrote:
>> 
>> On 2/1/02 11:34 AM, "Raymond Toy" <[email protected]> wrote:
>> 
>>>>>>>> "Jefferson" == Jefferson Provost <[email protected]> writes:
>>> 
>>> You are right.  A peek at the generated code on Solaris seems to show
>>> that we are calling out to generic functions way too often and could
>>> be vastly optimized.
>>> 
>>> I know with CMUCL, a Lisp version of m+ was almost as fast (< 5%
>>> slower?) than Fortran, so m.* should be as fast, even in Lisp.
>>> 
>>> I'll look in to it soon.
>> 
>> Thanks, though I'd be happy to just write the thing in fortran myself, but
>> I'm totally unfamiliar with the foreign function interfaces for Allegro and
>> CMUCL.
>> 
>> Actually, I have another routine that I use a lot which I was hoping might
>> be in MATLISP, but which I couldn't find.  I've had to write it myself (in
>> lisp) and it's slower than I'd like it to be.  It's basically the
>> "covariance normalization" i.e. the normalization that turns a covariance
>> matrix into a correlation coefficients matrix.
>> 
>> J.
>> 
>> _______________________________________________
>> Matlisp-users mailing list
>> [email protected]
>> https://lists.sourceforge.net/lists/listinfo/matlisp-users
> 
> _______________________________________________
> Matlisp-users mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/matlisp-users
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.