I'm working on implementing a solution for extracting slices of
multidimensional vectors, in the sense of vectors of vectors. I'm
taking the recursive route. I'm almost there, just have to work out a
few things. But I was wondering, this being a rather straightforward
need, perhaps it's already been done by someone, or maybe it's even in
the colujure.contrib libraries somewhere, so I thought I'd come here
and ask to see if anybody knows something I don't! I wouldn't want to
reinvent the wheel so to speak :)
Anyway, I'm trying to follow the MATLAB path. For instance, suppose
this is a 5x5 matrix:
(def a [[2 3 5 7 11] [13 17 19 23 29] [31 37 41 43 47] [53 59 61
67 71] [73 79 83 89 97]])
This:
(submvec a [[0 2 4] [0 2 4]])
would yield:
[[2 5 11] [13 19 29] [31 41 47] [53 61 71] [73 83 97]] (actually a
sequence)
In other words, [0 2 4] is to be interpreted as [START STRIDE END].
STRIDE should be optional.
What do you think? And, above all, has it already been done (or
something similar)?
Thank you.
Rock
> I'm working on implementing a solution for extracting slices of
> multidimensional vectors, in the sense of vectors of vectors. I'm
> taking the recursive route.
I have some code for working with nested vectors here:
http://code.google.com/p/clj-multiarray/source/browse/src/clj_multiarray/nested_vectors.clj
It's work in progress, but it may give you some ideas.
> Anyway, I'm trying to follow the MATLAB path. For instance, suppose
> this is a 5x5 matrix:
>
> (def a [[2 3 5 7 11] [13 17 19 23 29] [31 37 41 43 47] [53 59 61
> 67 71] [73 79 83 89 97]])
>
> This:
>
> (submvec a [[0 2 4] [0 2 4]])
>
> would yield:
>
> [[2 5 11] [13 19 29] [31 41 47] [53 61 71] [73 83 97]] (actually a
> sequence)
>
> In other words, [0 2 4] is to be interpreted as [START STRIDE END].
> STRIDE should be optional.
That's my "sample" function:
(defn nv-sample
[x dim start end step]
(assert (vector? x))
(if (zero? dim)
(vec (take-nth step (subvec x start end)))
(vec (map #(nv-sample % (dec dim) start end step) x))))
Just call it once for each dimension (0 and 1).
Konrad.
Rock
On Jan 10, 10:01 am, Konrad Hinsen <konrad.hin...@fastmail.net> wrote:
> On 09.01.2010, at 21:22, Rock wrote:
>
> > I'm working on implementing a solution for extracting slices of
> > multidimensional vectors, in the sense of vectors of vectors. I'm
> > taking the recursive route.
>
> I have some code for working with nested vectors here:
>
> http://code.google.com/p/clj-multiarray/source/browse/src/clj_multiar...
> I hadn't thought about. I'm so happy that you are working on this as
> well. I think Clojure has immense potential for scientific and
> mathematical computing, but this aspect has been somewhat neglected
> until now for some reason. Let's hope for a big change in this respect
> as soon as possible.
I agree! I believe that a good array library is essential for
scientific applications, so that's what I started to work on. There
are already a couple of array libraries in the Java world, but they
all "suffer" from being designed for Java rather than for a dynamical
language such as Clojure.
My project clj-multiarray is in fact quite ambitious: I want to design
an array library not only for Clojure, but for other dynamic libraries
on the JVM as well. I am thinking in particular of Jython, which still
lacks an equivalent of the NumPy library for C-Python. My goal thus is
to have both a nice Clojure interface and a Java-level interface on
which other JVM languages can build. And I also want to facilitate
interfacing with the existing Java array libraries, in particular for
using I/O libraries (netCDF) and matrix-related code (linear algebra
etc.) that already exists in the Java world.
All this to explain why this is a slowly progressing project and still
likely to undergo important changes. It's definitely not ready for use
yet, but I welcome comments on its design.
Konrad.
As for the Java libraries, have you had a look at JScience? From what
I've seen, it's not at all bad. However, I do believe that, as far as
Clojure is concerned, it should have its own scientific libraries and
infrastructure. So I'm really glad that you've started this project. I
hope I will be able to contribute and help in any possible way.
Thanks again.
> As for the Java libraries, have you had a look at JScience? From what
> I've seen, it's not at all bad.
It's an interesting library, but it lives clearly in the Java universe
of strict typing. Moreover, it doesn't really have arrays, just
vectors and matrices. Those are very well thought out and implemented,
but it's still a more limited approach than providing general N-
dimensional arrays.
A problem with all Java libraries is their orientation towards static
typing. In Clojure (like in Python), it is natural to have nested data
structures, and in particular nested vectors (in Python nested lists)
as a conceptual representation of multidimensional arrays. This
implies that array indexing operations can return either another array
or an element, meaning that the return type must be Object. This can
be done in Java but it is not a natural approach. Therefore the Java
libraries typically have separate operations for accessing elements
and for extracting subarrays, which makes many algorithms
unnecessarily cumbersome.
Konrad.
In particular, maybe this is useful:
http://liebke.github.com/incanter/core-api.html#incanter.core/sel
Carson
> Have you looked into Incanter project? I just found out about it
> recently. "Incanter is a Clojure-based, R-like platform for
> statistical computing and graphics." http://incanter.org/
Incanter uses ParallelColt as its underlying matrix library. While
this is a fine library for working with matrices, it is not a
multidimensional array library. Colt arrays exist only in 1, 2, and 3
dimensions and there are no generic (dimension-independent) operations
on array structure.
As the huge success of Matlab has shown, a lot can be done with just
matrices and vectors, but anyone who has used an array language (such
as APL) or an equivalent library (such as Python's NumPy) will feel
constrained by such an approach.
Konrad.
I'm using Konrad Hinsen's multi-array library (keep up the great work
Konrad!). Here's the code (I'm sure it can be greatly improved and
optimized):
(defn nv-subvec [x & ind]
(loop [v x
dim 0
i ind]
(let [[start end step] (first i)
other (rest i)]
(if (empty? other)
(nv-sample v dim start end step)
(recur (nv-sample v dim start end step) (inc dim) other)))))
It works like this:
(nv-subvec VECTOR SLICE+)
where each SLICE is [STAR END STEP].
Here's a 3 x 3 matrix:
(def a [[[1 2 3] [4 5 6] [7 8 9]] [[10 11 12] [13 14 15] [16 17 18]]
[[19 20 21] [22 23 24] [25 26 27]]])
user=> (nv-subvec a [0 3 2] [0 2 1] [1 3 1])
[[[2 3] [5 6]] [[20 21] [23 24]]]
user=> (nv-subvec a [0 3 2] [0 2 1])
[[[1 2 3] [4 5 6]] [[19 20 21] [22 23 24]]]
The result is correct in both cases. Seems to work fine. Of course a
lot of space for improvement.
Let me know what you think.