Matrix transform

2011-02-04 Thread Nick
I've got a matrix transformation that I'm doing which is really slow.
I'm looking for ways to speed it up.

source is a NxD matrix (seqs of seqs of values).  I will set and read
this matrix.
dest is a NxN transformation of f in which indices are mapped to
specific indices of f.  I will only read this matrix, not set it.

If I place a value in one cell of source, it may show up in 30 other
places in dest due to a mapping function.  I then use dest for some
simple matrix operations.  The mapping that I use is generated once,
however it has to be applied to the source very frequently.

Is there any way I could define dest with memory locations that
correspond to the mapped locations of source?  This would allow me to
define the mapping once.  Subsequently I could simply set source and
read dest with the changes already propagated.

I've thought about using seqs of seqs of refs in source, then
assigning those same refs to the mapped locations of dest, but I'm not
sure if there is some other overhead hit I would take from setting and
reading the refs.

What is the right solution?

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Matrix transform

2011-02-04 Thread Robert McIntyre
Could you possibly put up a minimal example of code that shows the
problem?  I'm having a hard time following exactly what you're doing
but would like to help.   :)

sincerely,
--Robert McIntyre

On Fri, Feb 4, 2011 at 10:20 AM, Nick npatric...@gmail.com wrote:
 I've got a matrix transformation that I'm doing which is really slow.
 I'm looking for ways to speed it up.

 source is a NxD matrix (seqs of seqs of values).  I will set and read
 this matrix.
 dest is a NxN transformation of f in which indices are mapped to
 specific indices of f.  I will only read this matrix, not set it.

 If I place a value in one cell of source, it may show up in 30 other
 places in dest due to a mapping function.  I then use dest for some
 simple matrix operations.  The mapping that I use is generated once,
 however it has to be applied to the source very frequently.

 Is there any way I could define dest with memory locations that
 correspond to the mapped locations of source?  This would allow me to
 define the mapping once.  Subsequently I could simply set source and
 read dest with the changes already propagated.

 I've thought about using seqs of seqs of refs in source, then
 assigning those same refs to the mapped locations of dest, but I'm not
 sure if there is some other overhead hit I would take from setting and
 reading the refs.

 What is the right solution?

 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with your 
 first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Matrix transform

2011-02-04 Thread Ken Wesson
If you need efficient numeric matrix operations, your best bet is to
move away from higher level abstractions like seqs and (especially)
refs and just use a one-dimensional Java array of primitives of size
(* m n), and indexed as (+ (* i m) j) or (+ (* j n) i) using primitive
arithmetic for speed. You can, of course, use macros or even
definlines to create an abstraction over this implementation while
still retaining the speed (and the use of primitive math). If you're
using 1.3 alpha, you can also pass primitives through normal function
calls, which may help (but you'll have to use long instead of int,
which may hinder, since Java array indices must be int forcing a
coercion and since long arithmetic may be slower on some 32-bit
hardware than int arithmetic).

In particular, using a 1D array of primitives keeps the entire matrix
in one contiguous block of RAM, versus a 2D array (which may have your
rows (or columns) scattered randomly about the heap) or an array of
boxed values (which may have the values themselves scattered randomly
about the heap). The memory access pattern with the 1D array of
primitives will improve cache performance, and especially should
improve performance if there's any paging by the OS.

Of course, using a mutable array carries all the peril and pitfalls of
unsynchronized mutable values, as well as the speed potential. Your
abstraction layer should do fairly high level jobs (such as row
reduction) with mutable temp matrices while avoiding mutating their
arguments, and should shield user-visible matrices (and vectors) from
being mutated, so that to the caller of the library the objects seem
immutable. You'll probably want three components: low level macros for
the basic operations like indexing into the matrix and getting and
setting cells; macro analogues of common functional operations like
map and reduce (built off areduce perhaps; with code bodies instead of
function arguments); and higher level functions that provide the real
API and use these lower level components to perform tasks like
multiplication, row reduction, and whatever other operations you need
to perform.

Then make your application a caller of this library.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en