Matrix transform
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
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
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