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