On 6 Jul 2011, at 06:35, jlk wrote:
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?
Right. The problem is that OO (more precisely Java's way of doing OO)
imposes some limitations that quickly get in the way when you want to
implement mathematical concept hierarchies in terms of a class
hierarchy. So ultimately the root of your problem is that you want to
use Java math libraries, not that you are using Clojure. Yes, I know,
one of the good points of Clojure is access to all those Java
libraries...
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.
It might be worth investigating if all that wrapper code could be
generated by a few Clojure macros.
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.
I'd say this is worse because it means converting between data
representations all the time. Better keep one data representation and
make it fit into your framework.
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.
Right, that's the most flexible solution, but also likely to be the
least efficient one.
For a Clojure approach to this specific problem, see
http://clojure.github.com/clojure-contrib/complex-numbers-api.html
which is based on the generic arithmetic from
http://clojure.github.com/clojure-contrib/generic.arithmetic-api.html
and thus ultimately on multimethods. There is a performance penalty to
such approaches, but it lets you formulate mathematical hierarchies
much better than Java's OO style. Note that this approach is not based
on types or on mathematical concepts such as fields, but only on
operations: the real and imaginary parts of a complex number can be
any value that supports arithemetic. This permits complex numbers with
nonsensical elements, but I have not found this to be a problem in
real life.
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).
Generic arithmetic can take care of that.
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?
Yes, but I doubt you'd have much success lobbying for such a change.
The tradeoff between cost (increased complexity of the reader) and
utility (limited to a small number of users) doesn't look very
promising. Moreover, my personal experience doing REPL math in Python
shows that complex constants are pretty rare.
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
One idea (but not a simple one to implement) is to define a domain-
specific language for maths (standard Clojure syntax but with
different semantics) and compile it into standard Clojure using a set
of macros.
Konrad.
--
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