complex number library

97 views
Skip to first unread message

Alan Forrester

unread,
May 31, 2015, 6:55:46 PM5/31/15
to clo...@googlegroups.com, numerica...@googlegroups.com
https://clojars.org/complex

https://github.com/alanforr/complex

Complex is a Clojure library for doing complex number calculations
that wraps the Java commons-math3 Complex library.

complex

A Clojure library for doing calculations with complex numbers. Wraps
the Java commons-math3 Complex library.

Usage

A complex number can be created by invoking the complex number
function. With one argument the function produces a complex number in
which only the real component is non-zero. With two arguments, the
first argument is the real part, the second argument is the imaginary
part:

=> (complex-number 1)

Complex (1.0, 0.0)

=> (complex-number 1 2)

Complex (1.0, 2.0).

The library can be used to do complex arithmetic. The + function can
have any number of real or complex arguments but always produces a
complex result.

=> (+ 1 (complex-number 3 4))

Complex (4.0, 4.0).

The same is true of the other arithmetical operations *,-,/. The
arithmetical functions are fastest on a per number basis when used on
only two arguments. They are also faster when their arguments are
complex.

The library also provides other functions, such as (pow a b), which
raises a to the power b, (sin a) which calculates the sine of a, and
several other functions. For details, see the docs.

Alan

Christopher Small

unread,
Jun 1, 2015, 3:49:22 AM6/1/15
to numerica...@googlegroups.com, clo...@googlegroups.com
Are these operations (*, +, etc) interoperable with core.matrix operations? That may end up being pretty key for a lot of numerical users.

Chris

Alan Forrester

unread,
Jun 1, 2015, 4:32:20 AM6/1/15
to numerica...@googlegroups.com
On 1 June 2015 at 08:49, Christopher Small <metas...@gmail.com> wrote:

> Are these operations (*, +, etc) interoperable with core.matrix operations?
> That may end up being pretty key for a lot of numerical users.

I have looked through the protocols here

https://github.com/mikera/core.matrix/blob/31bd8f93a4967acbb08fcf106139dcac7965c899/src/main/clojure/clojure/core/matrix/protocols.clj#L646

and I know of no specific reason why it should be impossible to write
a matrix library that would comply with those protocols using this
library to the extent that one would expect. For example, operations
like larger or smaller won't make sense for complex numbers and so the
non-mandatory parts of the protocols dealing with those operations
would have to either not be implemented or throw an error, e.g.
PElementMinMax.

If you can see some potential problem then I would be interested in
hearing about it.

Alan

Christopher Small

unread,
Jun 1, 2015, 1:57:44 PM6/1/15
to numerica...@googlegroups.com

I think you're right; you'd probably have to have a specialized matrix implementation. While that's a fine solution, it's unfortunate, since there are so many nice implementations to choose from based on user needs. It would be ideal if the complex operations could be "injected" into JVM implementations such as Vectorz or the default Clojure implementations. I'm not sure if that's possible though. Clearly it wouldn't work for Clatrix and other native implementations.

In any case, it's agreed there should be a path here which is great.

Best


Mike Anderson

unread,
Jun 2, 2015, 11:20:49 AM6/2/15
to numerica...@googlegroups.com, metas...@gmail.com, clo...@googlegroups.com
I think the right strategy is to make a separate complex array implementation library ("core.matrix.complex"?). In terms of dependencies, it would only need to depend depend upon "core.matrix" and "complex".

The array representation could simply be a deftype which uses two underlying arrays for the real and complex parts of the array respectively.

This world:
- use Complex values for array elements (mget etc.)
- allow the use of arbitrary underlying implementations (vectorz-clj, Clatrix etc.)
- implement all the relevant core.matrix protocols for Complex scalar values
- implement all the relevant core.matrix protocols for Complex arrays
- maybe add some special functions for complex-specific tasks
- as an added bonus, act as a proof point that the core.matrix protocols work for non-real valued arrays (which I think they do, but would be nice to confirm...)

The implementation should be fairly straightforward, but if anyone wants I can create a repo and bang out a bare-bones implementation in an hour or so that people can build upon.

Christopher Small

unread,
Jun 2, 2015, 11:35:25 AM6/2/15
to numerica...@googlegroups.com, clo...@googlegroups.com
> The array representation could simply be a deftype which uses two underlying arrays for the real and complex parts of the array respectively.

Oh man; that is flipping brilliant. And simple...


> The implementation should be fairly straightforward, but if anyone wants I can create a repo and bang out a bare-bones implementation in an hour or so that people can build upon.

Please!


Chris



Mike Anderson

unread,
Jun 2, 2015, 1:41:34 PM6/2/15
to numerica...@googlegroups.com, metas...@gmail.com, clo...@googlegroups.com
OK, here's a basic version that I think has most of the key elements in place.

A lot more protocols still need implementing, but it should be a reasonable basis to build upon:

Christopher Small

unread,
Jun 2, 2015, 2:20:14 PM6/2/15
to numerica...@googlegroups.com, clo...@googlegroups.com
You sir, rock.

--
You received this message because you are subscribed to a topic in the Google Groups "Numerical Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/numerical-clojure/gocQu7XTaNo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to numerical-cloj...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Christopher Graham

unread,
Jun 2, 2015, 8:17:49 PM6/2/15
to numerica...@googlegroups.com, clo...@googlegroups.com
How about changing the name of the complex-number function to, ideally, complex    ?
complex-number seems irritating to (have to) read. Further, calling this function is a form of type coercion. (float ...), (int ...), etc., are idiomatic Clojure, whereas (float-number ...), (int-number ...), etc., were not included in the language.

Christopher Small

unread,
Jun 2, 2015, 8:45:08 PM6/2/15
to numerica...@googlegroups.com

I agree; I’d personally prefer complex over complex-number for that function. When I was tinkering around with it, that’s actually intuitively what I tried first and was expecting.


--

Mike Anderson

unread,
Jun 2, 2015, 8:53:22 PM6/2/15
to numerica...@googlegroups.com, chgrah...@gmail.com, clo...@googlegroups.com
I agree that complex would be a better name.

It would be also be nice if it the 1-arg version could be idempotent (i.e. returns an existing complex number unchanged). The downside is that this would mean a slight performance hit because it would prevent the use of primitive arguments. Maybe we should do this but still use primitive type hints for the 2-arg version?

Christopher Small

unread,
Jun 2, 2015, 11:49:43 PM6/2/15
to numerica...@googlegroups.com, chgrah...@gmail.com, clo...@googlegroups.com
That sounds pretty solid imo.

--

Alan Forrester

unread,
Jun 3, 2015, 4:16:02 AM6/3/15
to numerica...@googlegroups.com
I have changed complex-number to complex.

Alan
> --
> You received this message because you are subscribed to the Google Groups
> "Numerical Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an

Alan Forrester

unread,
Jun 3, 2015, 5:12:59 AM6/3/15
to numerica...@googlegroups.com
I have made this change. It does not appear to change the performance
very much according to tests I ran with criterium compared to the
previous version.

Alan
Reply all
Reply to author
Forward
0 new messages