Hello

I've been playing around with math in clojure lately and have run up
against a few hurdles that I'm not sure how to overcome, any help
would be appreciated!  Mostly I've been trying to use the apache
commons math library (http://commons.apache.org/math/), but have been
hitting similar problems with other libraries too.  I suppose I'm
hitting a composablilty and Static typing problem?



Say I have a fairly complete matrix/vector library, such as
FieldVector or FieldMatrix, that already implement a whole heap of
useful things like cross products and that can be decomposed and find
the determinant, also has a heap of solvers, root finders and other
useful things. etc. etc.  Looks like a good starting point.

Now rather than using BigReal, which implements a FieldElement, I want
to use BigDecimal.  (big real seems to not honour precision settings
very well? a side issue...)


My first thoughts were to try wrap BigDecimal in a (proxy [BigDecimal
FieldElement] [x] ...) and this works to a point, but all the
functions such as .add still return BigDecimals rather than the new
proxy type.

So the wrapping continues as
(defn nbd [x] (proxy [BigDecimal FieldElement] [x] (nbd (.toString
(add [y] (.add this y)))) which works out to be a whole lot of
inefficient and boring wrapper code when all I really want to do it
insert a getField method into BigDecimal.

Of course I could wrap backward, so that every time I actually want to
use a BigDecimal i call .toBigDecimal on the BigReal object first, but
again it seems clunky and forces the user to deal with types that are
essentially identical.


A similar but different problem comes up when trying to use the apache
Complex type, which only works based on double precision - I need to
reimplement the entire class using BigDecimal (or something else) as
the storage mechanism, even though the majority of the logic is
already there, and even the method names are practically the same?
The only fix I see here is writing a new Complex class that implements
the FieldElement interface, since using a Complex class from somewhere
else will hit similar problems to the above.


Another issue is inserting the data.  Using maths from the repl, being
able to get the syntax [0 1 2] return a maths capable object would be
much nicer than (create-math-vector 0 1 2).  similarly with complex
numbers, writing (complex x y) is very long compared to xiy, or x +
iy.  Would it be possible to modify the reader so that, eg. 3i5 would
return a complex type?  What about something like 3.0b to return
BigDecimals?  or even (set-maths-type BigDecimals) then 3.0?

similarly with matrix access (get m ri ci) is long in an equation
compared with m[ri,ci], (map to-big-decimal (range 0 0.1 1)) is long
compared to something like (set-vector type BigDecimal) ...  [0:0.1:1]


Another issue comes up with performing operations on items.  Rather
than being able to call (+ (apache vector) 3) i need to call
(.mapAddToSelf (apache vector) (to-type (determine-vector-type v))
3)).  Now I can use (:refer-clojure :exclude [+]) and then define a
multimethod such as
(defmulti + #(vec (map class %)))
(defmethod + [Number] [x] x)
(defmethod + [Number Number] [x y] (clojure.core/+ x y))
(defmethod + :default [& args] (reduce + args))
(defmethod + [FieldVector FieldVector] [x y] (.add x y))
(defmethod + [FieldVector Number] [x y] (.mapAddToSelf x (to-type
(determine-vector-type v)) y)
(defmethod + [Number FieldVector] [x y] (.mapAddToSelf y (to-type
(determine-vector-type v)) x))

this gets tiresome pretty quick (try adding a few more types), seems
fairly error prone and is slow.


So basically I'm stuck - short of writing a maths library from scratch
with pluggable types and dispatch by operation name, anyone got any
ideas?  Cheers for your help

- Lachlan

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

Reply via email to