(Is that correct? mset copies the rest of the matrix?)
--
You received this message because you are subscribed to the Google Groups "Numerical Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to numerical-cloj...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
I'd like to modify an arbitrary number of elements in a core.matrix matrix (in vectorz-clj) at one time. I can go through and make the changes individually with 'mset', but changing, say, 30 elements in a 300x300 matrix using 'mset' seems like it's going to do a lot of unnecessary copying. (Is that correct? mset copies the rest of the matrix?) Or I can use 'mset!', which would be efficient, but I thought I would try to do it functionally, and then benchmark the functional version against a mutating version.
It looks like 'set-indices' does what I want:
-------------------------
clojure.core.matrix/set-indices
([a indices values])
like select-indices but sets the elements at the specified indices to values.
Leaves a unchanged and returns a modified array
clojure.core.matrix/select-indices
([a indices])
returns a one-dimensional array of the elements which are at the specified
indices. An index is a one-dimensional array which element-count matches the
dimensionality of a. Examples:
(select-indices [[1 2] [3 4]] [[0 0][1 1]]) ;=> [1 4]
This seems to work on small matrices with ndarray, but not vectorz-clj at the moment:
(set-indices (matrix :ndarray [[1 2][3 4]]) [[0 1][1 0]] [10 20])
#<NDArray [[1 10] [20 4]]>
(set-indices (matrix :vectorz [[1 2][3 4]]) [[0 1][1 0]] [10 20])
RuntimeException Can't do 2D set on nil clojure.core.matrix.impl.default/eval5591/fn--5594 (default.clj:204)
Although set-indices! works on vectorz-clj:
(set-indices! (matrix :vectorz [[1 2][3 4]]) [[0 1][1 0]] [10 20])
#<Matrix22 [[1.0,10.0],[20.0,4.0]]>
But my real question is about the syntax of set-indices and set-indices! for larger matrices. Maybe there's a bug, but I suspect that I just don't understand.
(set-indices (matrix :ndarray [[1 2][3 4][5 6]]) [[0 1][1 0][2 1]] [10 20 30])
RuntimeException Incompatible shapes, cannot broadcast [3] to [3 2] clojure.core.matrix.impl.persistent-vector/eval4676/fn--4677 (persistent_vector.clj:156)
popco.core.popco=> (set-indices (matrix :ndarray [[1 2][3 4][5 6]]) [[0 1][1 0][2 1]] [[10 20] [30 40] [50 60]])
#<NDArray [[1 10] [20 4] [5 30]]>
Is set-indices part of the recent selector functionality, and is in flux?
Thanks.
Okay, I pushed a PR to fix this issueOn Fri, Apr 25, 2014 at 3:38 AM, Mars0i <mars...@logical.net> wrote:
I'd like to modify an arbitrary number of elements in a core.matrix matrix (in vectorz-clj) at one time. I can go through and make the changes individually with 'mset', but changing, say, 30 elements in a 300x300 matrix using 'mset' seems like it's going to do a lot of unnecessary copying. (Is that correct? mset copies the rest of the matrix?) Or I can use 'mset!', which would be efficient, but I thought I would try to do it functionally, and then benchmark the functional version against a mutating version.
It looks like 'set-indices' does what I want:
-------------------------
clojure.core.matrix/set-indices
([a indices values])
like select-indices but sets the elements at the specified indices to values.
Leaves a unchanged and returns a modified array
clojure.core.matrix/select-indices
([a indices])
returns a one-dimensional array of the elements which are at the specified
indices. An index is a one-dimensional array which element-count matches the
dimensionality of a. Examples:
(select-indices [[1 2] [3 4]] [[0 0][1 1]]) ;=> [1 4]
This seems to work on small matrices with ndarray, but not vectorz-clj at the moment:
(set-indices (matrix :ndarray [[1 2][3 4]]) [[0 1][1 0]] [10 20])
#<NDArray [[1 10] [20 4]]>
(set-indices (matrix :vectorz [[1 2][3 4]]) [[0 1][1 0]] [10 20])
RuntimeException Can't do 2D set on nil clojure.core.matrix.impl.default/eval5591/fn--5594 (default.clj:204)
This fails because vectorz returns nil on mp/set-nd and doesn't fall back to set-2d here.What is the contract for the set-nd implementation if the underlying implementation does only support 1 and 2 dimensional matrices?Should if fall back to set-1d and set-2d where possible or should the default implementation make sure only to call mp/set-nd in the case for more than two dimensions?
Although set-indices! works on vectorz-clj:
(set-indices! (matrix :vectorz [[1 2][3 4]]) [[0 1][1 0]] [10 20])
#<Matrix22 [[1.0,10.0],[20.0,4.0]]>
But my real question is about the syntax of set-indices and set-indices! for larger matrices. Maybe there's a bug, but I suspect that I just don't understand.
(set-indices (matrix :ndarray [[1 2][3 4][5 6]]) [[0 1][1 0][2 1]] [10 20 30])
RuntimeException Incompatible shapes, cannot broadcast [3] to [3 2] clojure.core.matrix.impl.persistent-vector/eval4676/fn--4677 (persistent_vector.clj:156)
That works now.
popco.core.popco=> (set-indices (matrix :ndarray [[1 2][3 4][5 6]]) [[0 1][1 0][2 1]] [[10 20] [30 40] [50 60]])
#<NDArray [[1 10] [20 4] [5 30]]>
Is set-indices part of the recent selector functionality, and is in flux?
Thanks.
--
You received this message because you are subscribed to the Google Groups "Numerical Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to numerical-clojure+unsubscribe@googlegroups.com.
Thanks Mike, Maik.
After thinking about the fact that many of the functional update functions in core.matrix are in effect mutating update functions applied to a clone of the original matrix, it became obvious that I can just clone and then call mset! as many times as I want, if I want a functional multi-element update. Sometimes it takes time to see the obvious. (And benchmarking the number of times I'd have to clone a matrix showed that the cost is small.)
--
You received this message because you are subscribed to the Google Groups "Numerical Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to numerical-cloj...@googlegroups.com.
Hi,On Fri, Apr 25, 2014 at 4:41 PM, Mars0i <mars...@logical.net> wrote:
Thanks Mike, Maik.
After thinking about the fact that many of the functional update functions in core.matrix are in effect mutating update functions applied to a clone of the original matrix, it became obvious that I can just clone and then call mset! as many times as I want, if I want a functional multi-element update. Sometimes it takes time to see the obvious. (And benchmarking the number of times I'd have to clone a matrix showed that the cost is small.)
I think that we should review the default implementations and see what implementations uses loop or recur with functional updates functions instead of cloning and using the destructive operations. And rewrite them to the second approach.
I'll also update the default implementation of set-selection to use the second approach calling set-indices is the same as cloning and mset! ing for the default implementation and optimally faster for certain implementations.
--
You received this message because you are subscribed to the Google Groups "Numerical Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to numerical-clojure+unsubscribe@googlegroups.com.