tel / clatrix Goto Github PK
View Code? Open in Web Editor NEWA stupid name for a smart matrix library, because who doesn't love smart matrices?
License: MIT License
A stupid name for a smart matrix library, because who doesn't love smart matrices?
License: MIT License
trying to unroll an [n x m] matrix into a vector [1 x (m*n)]
the (dotom A p q) statement is blowing up. it looks like it's trying to cast the matrix as a function.
also, most of the other calls to dotom include a function
java.lang.ClassCastException: clatrix.core.Matrix cannot be cast to clojure.lang.IFn
at clatrix.core$reshape.invoke (core.clj:388)
clatrix.core$eval7977.invoke (NO_SOURCE_FILE:1)
clojure.lang.Compiler.eval (Compiler.java:6511)
clojure.lang.Compiler.eval (Compiler.java:6477)
clojure.core$eval.invoke (core.clj:2797)
clojure.main$repl$read_eval_print__6405.invoke (main.clj:245)
clojure.main$repl$fn__6410.invoke (main.clj:266)
clojure.main$repl.doInvoke (main.clj:266)
clojure.lang.RestFn.invoke (RestFn.java:1096)
clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__548.invoke (interruptible_eval.clj:5$
clojure.lang.AFn.applyToHelper (AFn.java:159)
clojure.lang.AFn.applyTo (AFn.java:151)
clojure.core$apply.invoke (core.clj:601)
clojure.core$with_bindings_STAR_.doInvoke (core.clj:1771)
clojure.lang.RestFn.invoke (RestFn.java:425)
clojure.tools.nrepl.middleware.interruptible_eval$evaluate.invoke (interruptible_eval.clj:41)
clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__589$fn__591.invoke (interr$
clojure.core$comp$fn__4034.invoke (core.clj:2278)
clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__582.invoke (interruptible_eval.clj:1$
clojure.lang.AFn.run (AFn.java:24)
java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:615)
java.lang.Thread.run (Thread.java:722)
Hey there,
Incanter is depending on clatrix for both QR decomposition and the determinant function,
and since there is no recent non-SNAPSHOT version of clatrix yet, the latest Incanter version has no QR decomposition or determinant functions.
What would it take to make a stable release? More SVD tests?
SVD gives incorrect V and U* when I used it on a 434 x 32 matrix. When I compare (V * S * U^T) with original matrix, the result is way off. Comparing with matlab result, lots of entries of V appears to have the wrong sign, although abs values of those entries seems to be correct. Also singluar values appears to be OK.
I reported this on Jblas, but I thought people who are using clatrix should know.
The clojure.core + operation generates a 0 for 0 arguments being passed to it, and operates as the identity for 1 argument being passed to it. This makes operations on lists, such as '(apply + (...)) work much more cleanly. It would be good if the matrix + operator acted more like the standard clojure.core + operator, since we would not need to check the number of arguments explicitly before applying it.
core.matrix API specifics that V* should be the transpose of the V matrix in the SVD decomposition. Clatrix is currently returning the non-transposed V.
@tel thanks for adding us. do you mind adding us to the clatrix clojars group too please?
We should probably have a compliance testing suite that verifies adherence to core.matrix APIs for an arbitrary implementation.
Advantages:
Initial stub (needs more tests!)
Vectorz's svd
returns a full singular-value decomposition, while the Clatrix core.matrix svd
returns reduced singular-value decomposition. The raw Clatrix interface allows you to get the full SVD with optional keyword arguments (:type :full
). mikera suggested changing the core.matrix version of Clatrix's svd
to return the full version. Would it be OK to add :type :full
at line 1756?
Example:
user=> (run! pm (vals (svd (matrix :vectorz [[1 2 3][4 5 6]]))))
[[0.386 0.922]
[0.922 -0.386]]
[9.508 0.773]
[[ 0.429 0.566 0.704]
[-0.806 -0.112 0.581]
[ 0.408 -0.816 0.408]]
nil
user=> (run! pm (vals (svd (matrix :clatrix [[1 2 3][4 5 6]]))))
[[-0.386 -0.922]
[-0.922 0.386]]
[9.508 0.773]
[[-0.429 -0.566 -0.704]
[ 0.806 0.112 -0.581]]
nil
;; Notice that the V* matrices differ above.
user=> (require '[clatrix.core :as cx])
nil
user=> (cx/svd (matrix :clatrix [[1 2 3][4 5 6]]))
{:left A 2x2 matrix
-------------
-3.86e-01 -9.22e-01
-9.22e-01 3.86e-01
, :right A 3x2 matrix
-------------
-4.29e-01 8.06e-01
-5.66e-01 1.12e-01
-7.04e-01 -5.81e-01
, :values (9.508032000695724 0.7728696356734847), :rank 2}
user=> (cx/svd (matrix :clatrix [[1 2 3][4 5 6]]) :type :full)
{:left A 2x2 matrix
-------------
-3.86e-01 -9.22e-01
-9.22e-01 3.86e-01
, :right A 3x3 matrix
-------------
-4.29e-01 8.06e-01 4.08e-01
-5.66e-01 1.12e-01 -8.16e-01
-7.04e-01 -5.81e-01 4.08e-01
, :values (9.508032000695724 0.7728696356734847), :rank 2}
user=> (run! pm (vals (cx/svd (matrix :clatrix [[1 2 3][4 5 6]]) :type :full)))
[[-0.386 -0.922]
[-0.922 0.386]]
[[-0.429 0.806 0.408]
[-0.566 0.112 -0.816]
[-0.704 -0.581 0.408]]
[9.508 0.773]
I gather that it's OK for the U and V* matrices to be negated--i.e. the vectorz versions are -1 times the clatrix versions.
(Just noticed a typo in the docstring at line 1204. :values
is missing the final "s".)
There are no tests for slicing, these should be added.
As part of investigation for incanter's bug #149 I've found that comparison of 2 empty matrices causes NPE in the jBlas:
user> (= (matrix []) (matrix []))
NullPointerException org.jblas.JavaBlas.rcopy (JavaBlas.java:80)
Following change in Matrix
deftype in clatrix fixes comparison of matrices, but it still fails for comparison of empty vector and empty matrix, etc.
(matrix? that) (if (and (= (count this) 0) (= (count that) 0))
true
(.equals (.me this) (.me that)))
I'm not sure - this is jBlas's issue or clatrix's
There is no function for dispatch value :matrix in the matrix multimethod. So (matrix (matrix ...)) fails. This should be added.
This is more of a general roadmap question really than an issue, but: clatrix is the closest thing I've found to python's awesome numpy library (http://docs.scipy.org/doc/ ) in the clojure world. Do you have any interest / plans / thoughts on feasibility for taking clatrix more in that direction?
This might mean, for example, support for higher-dimensional arrays, strides, broadcasting of fast vectorised operations over arrays of compatible shapes (e.g. Nx1 vector plus NxM matrix does the right thing), support for sparse matrices etc.
I suspect this may be quite a tall order because of the limitations of JBLAS, which seems more narrowly focused on dense matrix/vector linear algebra. But perhaps I'm wrong or perhaps there are other java HPC libraries or bindings could be added into the mix to help with this stuff?
May be interested in helping out if anyone thinks this sounds worth attempting, especially if I end up doing more ML/stats stuff on the JVM.
Example:
(rank (matrix [[1 2 3] [1 2 3]]))
Real rank is 1 (rows are linearly dependant). Function returns 2.
I think the problem with svd
function. It's documentation says:
(svd A) computes the sparse singular value decomposition of A
returning a map with keys {:values L :left U :right V} such that
A = U (diag L) V. If (size A) is [n m] and the rank of A is
k, we have the size of U as [n k], (diag L) as [k k],
and (t V) as [k m].
But it's not true. In jblas size of L calculated as min(n, m)
, not as rank of a matrix. Check this: https://github.com/mikiobraun/jblas/blob/master/src/main/java/org/jblas/Singular.java#L26
I think correct solution is to calculate number of non zero elements of L.
Thanks to Kevin for bug: https://groups.google.com/forum/#!topic/incanter/eINeIuV2Ktw
I saw someone else post the following error resulting from an attempt to reshape a matrix:
ClassCastException clatrix.core.Matrix cannot be cast to clojure.lang.IFn clatrix.core/reshape (core.clj:388)
The bug report says it was fixed, but I am still having the problem.
Example:
(det (matrix [[0 1]
[1 0]]))
; returns 1 but answer is -1
Current implementation of det
doesn't use permutation matrix P though it should. Check Computing the determinant
Currently the as-vec
function behaves inconsistently:
The Clatrix behaviour is similar to that displayed by R, but this is widely regarded as a design flaw, see e.g.: http://radfordneal.wordpress.com/2008/08/20/design-flaws-in-r-2-%E2%80%94-dropped-dimensions/
This auto-flattening behaviour causes problems when writing any code that is designed to deal with arbitrary sized matrix, as it requires significant amounts of special-case code to be written. I believe it is also a root cause of some of the problems with recent builds of Incanter.
I propose that this should be fixed in the next major release of Clatrix, and the behaviour (1) adopted throughout. It may be a breaking change for some users.
Hey @tel, (and perhaps, @mikera, who appears to have the latest up-to-date fork).
The link to the "Marginalia Documentation" in the README appears to be broken. I also understand @tel isn't maintaining this anymore, and was wondering if the project is still alive. Is this now under clojure-numerics (that fork hasn't seen a commit since 2013, last I checked), mikera/clatrix, or somewhere else?
I'm interested in potentially using the library but am unsure what the state of clatrix is at the moment. I'm sure there's others who are similarly looking for clarification on this.
Any info is appreciated!
Incanter is dependent on 0.3.0-SNAPSHOT. Can we release 0.3.0 before api breaking changes are applied please?
Applying emap
to a clatrix.core.Matrix
returns a LazySeq, rather than returning something that preserves the matrix's shape.
(def M (matrix [[1 2][3 4]]))
#'user/M
M
A 2x2 matrix
-------------
1.00e+00 2.00e+00
3.00e+00 4.00e+00
(def Mi (emap inc M))
#'user/Mi
Mi
(2.0 3.0 4.0 5.0)
(type Mi)
clojure.lang.LazySeq
Maybe this is related to issue 36?
(Feel free to let me know if I'm not doing something correctly here. First issue not for my own project.)
Running the following code on a clean project throws this error (Mac OSX 10.6.8):
(require '[clatrix.core :as m])
(m/pp (m/* (m/rand 2 5) (m/rand 5 2)))
Could not initialize class org.jblas.NativeBlas
[Thrown class java.lang.NoClassDefFoundError]
Backtrace:
0: SimpleBlas.java:245 org.jblas.SimpleBlas.gemm
1: DoubleMatrix.java:1674 org.jblas.DoubleMatrix.mmuli
2: DoubleMatrix.java:3005 org.jblas.DoubleMatrix.mmul
3: core.clj:630 clatrix.core/*
Any ideas?
Hi there, this is somewhat of a general roadmap question for matrix maths libraries in Clojure.
I have my own matrix wrapper for the vectorz vector / matrix library (which is pure Java, i.e. no native dependencies):
I need the vectorz library for some specific features which aren't in BLAS. However, I'd like to avoid reinventing wheels if possible, so is it likely to be feasible to create a common interface for clojure matrix libraries, supporting multiple matrix implementations?
If so, could clatrix take on that role?
Right now, the Clatrix has inconsistency in how it represent rows when executing seq
/map
/filter
& other related operations. Clatrix uses the 1x2 matrices to represent rows, while other implementations (like, vectorz-clj) use the separate types to represent them. This lead to problem when trying to create matrix from the result of the map
or filter
- the dimensionality
returns 3 instead of correct 2, like in other implementations, and this lead to exception when trying to construct matrix (in functions clatrix
& construct-clatrix
).
incanter.core> (set-current-implementation :clatrix)
:clatrix
incanter.core> (def m (matrix [[1 0] [2 1]]))
#'incanter.core/m
incanter.core> (m/dimensionality (map identity m))
3
incanter.core> (map identity m)
( A 1x2 matrix
-------------
1.00e+00 0.00e+00
A 1x2 matrix
-------------
2.00e+00 1.00e+00
)
incanter.core> (set-current-implementation :vectorz)
:vectorz
incanter.core> (def m (matrix [[1 0] [2 1]]))
#'incanter.core/m
incanter.core> (m/dimensionality (map identity m))
2
incanter.core> (map identity m)
(#<ArraySubVector [1.0,0.0]> #<ArraySubVector [2.0,1.0]>)
I have a small workaround for clatrix
& construct-clatrix
that checks if the every element is 1xN matrix, and the use the join
to merge results together, but the correct solution will be the use of separate type (existing Vector
type) to represent rows when calling seq
.
Looking at the source, I was unable to find an implementation of the PMatrixProducts protocol for inner/outer products. The results of the default implementation for outer-product are incorrect:
(def vv (m/matrix :clatrix [1 2 3 4]))
=> #'user/vv
(m/outer-product vv vv)
=> (1.0 2.0 3.0 4.0 2.0 4.0 6.0 8.0 3.0 6.0 9.0 12.0 4.0 8.0 12.0 16.0)
(type (m/outer-product vv vv))
=> clatrix.core.Vector
while for :persistent-vector
it works as expected (i.e. outer-product produces a matrix):
(def vv (m/matrix :persistent-vector [1 2 3 4]))
=> #'user/vv
(m/outer-product vv vv)
=> [[1 2 3 4] [2 4 6 8] [3 6 9 12] [4 8 12 16]]
if I have 2 matrices - row matrix & col matrix, then the seq
, first
, map
, and other functions behaves the same for them, although this is incorrect (imho):
(def m2 (matrix [[1 2 3]]))
m2
A 1x3 matrix
-------------
1.00e+00 2.00e+00 3.00e+00(def m3 (matrix [1 2 3]))
m3
A 3x1 matrix
-------------
1.00e+00
2.00e+00
3.00e+00(first m2)
1.0
(first m3)
1.0
(matrix (seq m2))
A 3x1 matrix
-------------
1.00e+00
2.00e+00
3.00e+00
(matrix (seq m3))
A 3x1 matrix
-------------
1.00e+00
2.00e+00
3.00e+00
This breaks some functions in incanter that process matrices on per-row basis. I think, that this relates to issue #30
I implemented matrix-api. Release this working version so that we can put the matrix-api stuff into 0.3.0?
The identity matrix is created via the id function. A common alias is eye, should we add this ?
There appears to be a race condition when loading Clatrix as a core.matrix implementation.
See this report: mikera/core.matrix#80
I have been able to reproduce with Clatrix, but not with other implementations, so it appears to be a Clatrix-only issue.
Hey Joseph,
To be honest I have not (yet) used clatrix but I am fully aware of its potential.
This is not an issue per se, but rather just to let you know something.
There has been some rather interesting developing going on regarding Clojure numeric computations. I want to raise your attention to two open source libraries: ClojureCL and neanderthal. They are based on ATLAS implementation as well but seem to be very optimized.
According to neanderthal's website, its matrix computation can be as much as 5x faster than JBlas, and from his statements, it seems that with the support of GPUs (next release), it can be even faster (see comment)
Hope it helps,
PS: I am in no way affiliated to them. I just wanted to share the knowledge ;)
The new pull from Paul introduces some new things that need documention.
Paul, can you add descriptions, please ?
Some Criterium benchmark checks revealed a significant performance potential for the core API function 'get'. Based on this, a new macro 'submatrix' could be introduced, which gives a significantly better performance than the current implementation via 'matrix'.
You may check the proposal prototypes here, lines 49 and 85.
You find the performance results here. Please note that the warnings relate to a variant the I do not advocate here.
I could imagine to intoduce the get variant as 'get-2D' (and 'get-1D' resp.).
WARNING: abs already refers to: #'clojure.core/abs in namespace: clatrix.core, being replaced by: #'clatrix.core/abs
clojure.core/abs
should be excluded, similar to here: clojure/tools.analyzer@5992741
Currently the as-vec
function behaves inconsistently:
The Clatrix behaviour is similar to that displayed by R, but this is widely regarded as a design flaw, see e.g.: http://radfordneal.wordpress.com/2008/08/20/design-flaws-in-r-2-%E2%80%94-dropped-dimensions/
This auto-flattening behaviour causes problems when writing any code that is designed to deal with arbitrary sized matrix, as it requires significant amounts of special-case code to be written.
I propose that this should be fixed in the next major release of Clatrix, and the behaviour (1) adopted throughout. It may be a breaking change for some users.
@mikera has created a GitHub org to collect the clojure numerics libraries. I propose that we move Clatrix there. Thoughts ?
Perhaps we think of a new name at the same time ?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.