complex numbers in clojure

1,468 views
Skip to first unread message

Maik Schünemann

unread,
Aug 15, 2014, 11:24:24 AM8/15/14
to clo...@googlegroups.com
Hi, 
is there a recommended way to do complex arithmetic in clojure ? 
I am interested to see clojure going forward for scientific computing purposes. 
There is already considerable effort going on with core.matrix, incanter, expresso etc.
But something thad is oddly lacking is support for complex numbers. For some areas, this is
a show stopper and it is very basic stuff in other languages and systems: 
- common-lisp, python etc all have a standard complex type as part of the language/standard library

In Java, there are multiple incompatible complex number classes and I don't want that incompatibilities 
in clojure libraries that provide complex number manipulation. 

In my opinion we should strive as a community for a standard complex number datatype, that is agreed on by clojure libraries, 
and plays nicely with clojures other numeric types.
Ideally, this would be provided as part of clojure.contrib or even clojure itself - like rationals are!




Reid McKenzie

unread,
Aug 15, 2014, 1:08:01 PM8/15/14
to clo...@googlegroups.com

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

The best way to build a complex arithmetic package is probably to work atop `clojure.algo.generic`. I've done a pair of libraries (https://github.com/arrdem/imprecise, https://github.com/arrdem/meajure) based around extending algo.generic with custom datatypes and they've both worked out well.

Clojure in general seems pretty loath to package "traditional" numerics facilities... note that we don't even have a built in square root operator and the common practice is to use java.lang.Math through interop so I wouldn't go holding your breath over adding irrational numbers to the language core. Also clojure.contrib is abandoned and deprecated in favor of "real" community maintained standalone libraries. The most likely place for an irrational type is probably either a user library like both of the above or possibly algo.generic itself.

Reid
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@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+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com <mailto:clojure+u...@googlegroups.com>.
> For more options, visit https://groups.google.com/d/optout.


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQIcBAEBAgAGBQJT7jysAAoJELjHpJOzPfTlUqoP/3UGoIusWhK+/0yzYvqCHsPK
QzU7criJGsNCfP8h0H7kClwJh7gIZHJlnBDMVHh7eP6VDPlnunTv7nYbFCPMYUys
SiM0dhW94EqEKUtl0gcIUoFfhDBeAPhgoi02/Lm0w51CcarhEnstVFVnUOLJPbsB
sTJuEC1ZigBtJz8pwBzGQnBYIRDaSONSxAEoV8aDmXinKBh+mPZKDRkE2emHsxDi
kSkMmDYicmc/2chFnjdbhSvJQajqoKKZvxuHAVboKKkWqowgHbHaB3ybsoZs/GT9
NYZEBVfEJWrgvQvgQsZNnuc2esd4f86JJp/QAyCvIzofsoNQbGBtPzbXBLkq7JYF
Me3JBwI1F9N221ZfTyRIXjRzc2P6cZdRcMAetsRgw2tSl94HVuHp2VGzaeqGlsR/
b7tsv06o2jTlNbaH+o1lisAQcs7pTJ1SZO1FZmCBoY1/b7f3MVa//hAK5pHa/tMH
+bAVZaAtAe+K3JjCokHwN7MX1gfVUNyIxD9kj/jlnrq+Xmvg8U7EA16wH+NDEI0j
jDXUkcTYfdM/dR7NV5Jvzwgd9A7Gm+2If6xN4Kx1ZviJk+XP3tYWx3FoCLungjaz
FujqwSChdDQ3Qw9k9uJ8zUR+e+9EsOsB86CmX/BmQCifcEpp1KlTUzFaR1XR3Gbg
VS5qG9H32gMMXpXSU02M
=cssb
-----END PGP SIGNATURE-----

Maik Schünemann

unread,
Aug 15, 2014, 1:54:53 PM8/15/14
to clo...@googlegroups.com
Hi,

On Fri, Aug 15, 2014 at 7:00 PM, Reid McKenzie <rmcke...@gmail.com> wrote:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

The best way to build a complex arithmetic package is probably to work atop `clojure.algo.generic`. I've done a pair of libraries (https://github.com/arrdem/imprecise, https://github.com/arrdem/meajure) based around extending algo.generic with custom datatypes and they've both worked out well
I'll look at these. 
Building complex arithmetic atop algo.generic wouldn't bring the desired unification, because for example core.matrix doesn't use algo.generic ... 
Clojure in general seems pretty loath to package "traditional" numerics facilities... note that we don't even have a built in square root operator and the common practice is to use java.lang.Math through interop so I wouldn't go holding your breath over adding irrational numbers to the language core. Also clojure.contrib is abandoned and deprecated in favor of "real" community maintained standalone libraries. The most likely place for an irrational type is probably either a user library like both of the above or possibly algo.generic itself.
Yeah, I meant 'as a contrib library' when I wrote clojure.contrib. Sorry for the confusion. 
As for the other part, let me elaborate a bit:
As it is true that clojure doesn't have much numeric functions in core (like the square root example), it doesn't eschew numeric /types/ like BigInt and Rationals, and you obviously can't pass  to java.lang.Math via interop already. 

Take rationals as example. I really like them and use them often in my clojure code because they give you exact arithmetic basically for free because they are part of the core language and you can use them anywhere (in pure clojure). They even have a convenient literal syntax (but that is not that inportant). 

We had a discussion a while ago on the clojure-numerics mailing list on how we could open core.matrix for arbitrary scalar types, like complex numbers or symbolic expressions. I'll link this here as it could be of interest: https://groups.google.com/forum/#!topic/numerical-clojure/Ze7lNjXJeQc/discussion
I think a reason that held the discussion back was missing standard types to experiment with. 

I don't argue that clojure should provide complex types as part of clojure.core and can understand the reasons not to (while I think it would be the same reason as including rationals in clojure.core) but as a clojure contrib library that other clojure math libraries build ontop of (including core.matrix and algo.generic).
The tricky part would then be figuring out how to nicely interop with the other clojure types without incuring too much overhead to be used in serious scientific computing (I think algo.generic uses multimethods for dispatch, which is definitly too slow in highly stressed inner loops of heavy matrix manipulations for example).

greetings
Maik

To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.

Mikera

unread,
Aug 16, 2014, 7:08:04 AM8/16/14
to clo...@googlegroups.com
There is really no "perfect" numerical type:
- primitive doubles are best if you care about performance and reasonably good precision (but no complex numbers!)
- boxed Doubles are needed in some circumtances, e g. storage in collections, passing to dynamic code
- something like org.apache.commons.math3.complex.Complex is a good general purpose complex number
- you might also want "rational doubles" where both the real and imaginary part are rationals
- sometimes libraries might use a length 2 vector as a complex number (many libraries do this, including vectorz-clj)
- quaternions would be nice too!

With all this in mind, I'd love to see a way to get a numerical stack that abstracts away from the concrete number type, in roughly the same way that core.matrix abstracts away from the underlying array type. That way, mathematical functions could defined to work intelligently on arbitrary numerical types.

Performance would be the main concern.... if this is going to be the "standard solution" for Clojure then we want it to work for all use cases, including the performance-sensitive ones. Multimethods (the approach used by algo.generic) are flexible but way too slow. Even protocols are probably too expensive for performance-oriented numerical code if you are paying the dispatch overhead for every single operation. Note that protocols are fine for core.matrix, since you only pay the protocol once per whole-array operation which might execute millions of individual element operations.

Basically... I think making this work both elegantly and efficiently is going to need compiler enhancements. Ideally there would be a mechanism to allow type hints / type inference or something similar that would optimise away the dynamic type-based dispatch checks in the case where the compiler knows or can infer the exact concrete type. 

Jan-Paul Bultmann

unread,
Aug 16, 2014, 8:29:18 AM8/16/14
to clo...@googlegroups.com
I agree that Clojure could really use an imaginary number type.

The best place to start with this might be `clojure.math.numeric-tower` because it already provides a
`MathFunctions` protocol that defines a square root operation.

Cheers Jan

Maik Schünemann

unread,
Aug 16, 2014, 5:56:30 PM8/16/14
to clo...@googlegroups.com
I agree with mikera on this, the standard numeric abstraction have to be able to fulfill all performance needs.
This definitly excludes multimethods (algo.generic) and protocols/interface-calls (numeric-tower). 
(Imagine multiplying two 5000x5000 matrices and having to go through a protocol for each scalar operation).

Ultimately wee would need numeric code like that from clojure's numeric primitives. Here is some relevant code snippet from

Basically... I think making this work both elegantly and efficiently is going to need compiler enhancements. Ideally there would be a mechanism to allow type hints / type inference or something similar that would optimise away the dynamic type-based dispatch checks in the case where the compiler knows or can infer the exact concrete type. 
Maybe we could do something similar here to what was done for the ndarray implementation of core.matrix using macros. 
(from maps {[Type-left Type-right] operation} generate class with static methods (using gen-class) that are overloaded in the right way like in the snippet from the clojure compiler. This would make it simple to add new numeric types, but the code would have to be recompiled.


On Friday, 15 August 2014 23:24:24 UTC+8, Maik Schünemann wrote:
Hi, 
is there a recommended way to do complex arithmetic in clojure ? 
I am interested to see clojure going forward for scientific computing purposes. 
There is already considerable effort going on with core.matrix, incanter, expresso etc.
But something thad is oddly lacking is support for complex numbers. For some areas, this is
a show stopper and it is very basic stuff in other languages and systems: 
- common-lisp, python etc all have a standard complex type as part of the language/standard library

In Java, there are multiple incompatible complex number classes and I don't want that incompatibilities 
in clojure libraries that provide complex number manipulation. 

In my opinion we should strive as a community for a standard complex number datatype, that is agreed on by clojure libraries, 
and plays nicely with clojures other numeric types.
Ideally, this would be provided as part of clojure.contrib or even clojure itself - like rationals are!




endbegin

unread,
Apr 27, 2015, 11:39:34 AM4/27/15
to clo...@googlegroups.com
I have been thinking along the lines of mikera and Maik - and it seems like there is no further progress here? I would like to take a crack at creating a complex number type, but implemented as a library to Clojure. I am not sure where to start, and if anyone here has suggestions, I'd be happy to hear them. 

A complex number could simply be a vector of two elements, or a map with :real and :imag keys (or something lightweight) - and I am not sure what it would require to make this type work happily with code arithmetic functions in Clojure and Java Math. 

It would also have to work with seq operations in Clojure - for instance: 
If I have a complex number c = {:real 3 :imag 4}, and a vector v = [1 -2 c], it would be nice to have the call 'map #(Math/abs %) v' produce (1 2 5). 

I am having trouble figuring out all the pieces that need to be implemented. Is it even possible to implement this as a library, or does this need to be a part of clojure.core?

Gary Verhaegen

unread,
Apr 27, 2015, 12:45:32 PM4/27/15
to clo...@googlegroups.com
As far as I understand, your example with Math/abs would need to be part of Java.

You cannot extend the arithmetic operators in Java, and you will not be able to extend static Java methods like Math/abs.

What you may be able to do is make your custom type play nice with Clojure operators, like Clojure's rationals and bignums.

I'd suggest looking at the code for these, and considering a Java class with two primitive attributes rather than a Clojure vector or map (which have a big overhead compared to a simple number). Depending on what you want to do, you may also want to consider implementing a "vector of complex" type, which could be a single object with two primitive arrays.

If you're targeting a performant implementation, you should probably cross post to numerical-clojure; people over there have a lot of experience about numerical optimizations in Clojure.
--

Andy Fingerhut

unread,
Apr 27, 2015, 12:45:46 PM4/27/15
to clo...@googlegroups.com
Unless the Java Math library handles complex types already, I don't know of any way to extend it in a way that would let you get the answer you want from (Math/abs my-complex-number) in Clojure.

If you want code that gives the correct answers, a library using vectors or maps for complex numbers can get you there.  Memory footprint and performance should be better with Clojure records or a new class written directly in Java.  With a library, I don't know of any way to be able to mix Clojure's arithmetic operations like + - * / etc. with its existing numeric types, and your new library-implemented complex types.

Support of Clojure's arithmetic operations on complex numbers might only be achievable by modifying Clojure itself.  Depending upon your goals, the down side of that approach is that it will not become part of the normal Clojure distribution unless the Clojure core team wants that addition, which I would guess would be very low on their priority list (just a guess -- I have no inside knowledge there).

Andy

--

endbegin

unread,
Apr 27, 2015, 1:36:06 PM4/27/15
to clo...@googlegroups.com
This is what I suspected. Of course, this is not just for abs, but really for any mathematical operation. Sqrt, Trig operations etc.

I will study the Ratio type more closely, but note that something like (Math/abs (/ 22 7)) does not work. 


On Monday, April 27, 2015 at 12:45:32 PM UTC-4, Gary Verhaegen wrote:
As far as I understand, your example with Math/abs would need to be part of Java.

You cannot extend the arithmetic operators in Java, and you will not be able to extend static Java methods like Math/abs.

What you may be able to do is make your custom type play nice with Clojure operators, like Clojure's rationals and bignums.

I'd suggest looking at the code for these, and considering a Java class with two primitive attributes rather than a Clojure vector or map (which have a big overhead compared to a simple number). Depending on what you want to do, you may also want to consider implementing a "vector of complex" type, which could be a single object with two primitive arrays.

If you're targeting a performant implementation, you should probably cross post to numerical-clojure; people over there have a lot of experience about numerical optimizations in Clojure.

On Monday, 27 April 2015, endbegin <nkri...@gmail.com> wrote:
I have been thinking along the lines of mikera and Maik - and it seems like there is no further progress here? I would like to take a crack at creating a complex number type, but implemented as a library to Clojure. I am not sure where to start, and if anyone here has suggestions, I'd be happy to hear them. 

A complex number could simply be a vector of two elements, or a map with :real and :imag keys (or something lightweight) - and I am not sure what it would require to make this type work happily with code arithmetic functions in Clojure and Java Math. 

It would also have to work with seq operations in Clojure - for instance: 
If I have a complex number c = {:real 3 :imag 4}, and a vector v = [1 -2 c], it would be nice to have the call 'map #(Math/abs %) v' produce (1 2 5). 

I am having trouble figuring out all the pieces that need to be implemented. Is it even possible to implement this as a library, or does this need to be a part of clojure.core?

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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

For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscribe@googlegroups.com.

endbegin

unread,
Apr 27, 2015, 1:46:14 PM4/27/15
to clo...@googlegroups.com
As far as I know, Java Math does not have a complex number type. Some implementations of a complex number exist (such as Apache Commons Math), but they create a Complex class that implements Serializeable and a Commons specific interface.  

Modifying clojure.core itself is a bit daunting, and like you said, it would need to be a priority for the core team.

Andy Fingerhut

unread,
Apr 27, 2015, 1:52:57 PM4/27/15
to clo...@googlegroups.com
People frequently make their own modified versions of Clojure without having their changes made part of the core Clojure distribution.  That is why I said "depending upon your goals".  If your goal is to try it out and learn from it, and you don't care whether it becomes part of the standard Clojure distribution, then it does not matter what the Clojure core team's priorities are, because they are not involved.

Andy

Lee Spector

unread,
Apr 27, 2015, 2:46:48 PM4/27/15
to clo...@googlegroups.com
Just cheerleading: I, for one, would love for Clojure to have complex number support, however it can be arranged (built-in or through a library). 

I sometimes do quantum computing work and this issue has prevented progress on a couple of projects. I haven't tried to solve the problem myself, and I'm not sure exactly what the difficulties are in detail, but a couple of strong students have worked on this for me and been stymied.

I started my quantum computing work in Common Lisp, where complex numbers are free and easy... and it's frustrating that this (and only this) has prevented us from continuing that work now that we've switched to Clojure for almost everything else.

 -Lee

--
Lee Spector, Professor of Computer Science
Director, Institute for Computational Intelligence
Cognitive Science, Hampshire College
893 West Street, Amherst, MA 01002-3359
lspe...@hampshire.eduhttp://hampshire.edu/lspector/
Phone: 413-559-5352, Fax: 413-559-5438

Alex Miller

unread,
Apr 27, 2015, 3:43:13 PM4/27/15
to clo...@googlegroups.com
I think it's unlikely that Clojure would add a complex number type. However, it might be possible to open up the system enough that new types could be created and integrated by others. I think this discussion and implementation from clojure-dev (about unsigned numbers) is pertinent:


In my last posts on that thread, I suggested some of the design and testing work that I would expect Rich to ask about. I did not get the impression that anyone cared enough to contribute further. If there was enough interest, I'd be happy to ask Rich about it.

Alex

Mikera

unread,
Apr 28, 2015, 12:22:08 AM4/28/15
to clo...@googlegroups.com
Complex numbers are tricky because:
- They need to be fast in order to be useful for numerical computing. The "obvious" implementations that you might create with boxed values, vectors/maps, multimethods and protocols are likely to be unacceptable for many use cases
- You still want to be able to use them in a generic way, with operations that play nicely with other values (Doubles etc.)

I have thought about this a lot w.r.t. core.matrix and have come to the conclusion that there is no simple, elegant answer that meets all use cases.

What I'd like to suggest is:
a) The community converge on a single, minimal, lightweight representation for a boxed complex scalar value. This is probably best as a Java class (for easy interop with Java libraries). I think http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/complex/Complex.html is a good candidate
b) A lightweight wrapper library that provides nice complex functions in Clojure, using the above type. Nothing fancy. But can make extensive use of type hints etc. for performance so should be pretty fast
c) A library using core.matrix that implements complex vectors, complex matrices etc but also uses a) for complex scalar values. This should use a underlying double-array backed implementation for performance, probably vectorz-clj would be best (though that could be hidden as an implementation detail). This library would also implement all the core.matrix protocols for the chosen complex number type, mostly just by calling b) directly

Nik

unread,
Apr 28, 2015, 7:42:23 AM4/28/15
to clo...@googlegroups.com
It does seem as though there is no way to meet all the criteria, unless the support for it comes from Java/Oracle. That said, I feel like having a complex type with reasonable performance is better than having nothing at all. 

What I would like is a complex type that plays well with Clojure's generic abstractions and functional style (much like Ratio), and is indistinguishable from other types - for example, the ability to work with (map/reduce/filter), the ability to be a part of seqs and use Clojure core functions on it, and so on. It might not as efficient as the complex type in, say C++, but depending on your definition of reasonable, it might be acceptable. I am willing to explore this further. 

Alex, would opening up the type system as you pointed be a way to go?

Also, I am not sure is this is possible for us to accomplish, but some academic work has been done where a Java complex class has been created, and through the use of semantic expansion, it has very high performance.

Gary Verhaegen

unread,
Apr 28, 2015, 8:35:39 AM4/28/15
to clo...@googlegroups.com
Your messages are a bit confusing. Playing nice with collection functions would depend on the collection, not on its contents.

Maybe you could elaborate a bit more on what you're trying to accomplish?

If you do not care about performance, you need to decide whether you want your type to work with clojure.core arithmetic operators, which from Alex's comments would seem to require modifying Clojure itself, or if it would be acceptable to you to define your own operators in your own namespace (which could check the type and default to the clojure.core versions, providing some transparency in exchange for some performance). Of course, you then have to worry about other functions that maybe call clojure.core operators indirectly, and the bahavior of functions such as min and max.
--

Plínio Balduino

unread,
Apr 28, 2015, 8:52:19 AM4/28/15
to Clojure Official
My two cents:

I started to develop some support to complex numbers in Clojure, but I don't know if the Core Team/Rich Hickey has any intererest in this subject.

Even it's an unfinished work, I didn't notice any lost of performance so far.

Regards

Plínio Balduino
complex.png

Nik

unread,
Apr 28, 2015, 10:20:44 AM4/28/15
to clo...@googlegroups.com
To put is simply, it would be nice to have a complex type in Clojure, not as a separate namespace, but something that is part of the language. It should interoperate with other Clojure types (like adding a double to a complex), as well as clojure.core.arithmetic. That's what I meant about playing nicely with collections - it should not matter that there is a complex type in a collection. The arithmetic operations on collections should work regardless. Sorry for the confusion. I will spend some time looking into the modifications needed to clojure.core to accomplish this.

I could be wrong but it seemed to me that Alex was suggesting there might be a way to open up the type system so that others can add types "easily". 

Also, I didn't mean to imply that I don't care about performance. It does matter, but if Clojure doesn't have Fortran-like speeds, then that is fine with me. Unfortunately, at this point I can't be more specific about performance - in either absolute or relative terms.

Andy Fingerhut

unread,
Apr 28, 2015, 10:56:27 AM4/28/15
to clo...@googlegroups.com
Most of Clojure's collections already can hold arbitrary type values inside of them, with no additional work required, whether those types are built into Clojure or not.  That is because most collections treat all contained items as Java Object references.

The only exceptions I can think of are the few Clojure data structures that were developed to save memory, and perhaps also improve performance, by avoiding the Object references and holding Java primitive types directly, e.g. (vector-of :int 1 2 3)

The tricky part is not that, but getting a new number type to be operated upon by existing Clojure math operators like + - * /

Andy

Plínio Balduino

unread,
Apr 28, 2015, 12:55:48 PM4/28/15
to Clojure Official
Not that tricky, really. But there's a lot of repetitive work.

I changed the Clojure readers to understand the a+bi format, created a ComplexNumber class and changed the class on charge of arithmetic to work with complex numbers.

So it's possible to make any operation mixing Numbers, Ratios and ComplexNumbers.

Plínio

Mikera

unread,
Apr 28, 2015, 11:56:54 PM4/28/15
to clo...@googlegroups.com
You can do virtually all of that already with the Apache commons Complex class. Any Java object can be just fine used with map / reduce / filter / seqs etc.

If you want to avoid Java interop and make things more "Clojure-like" then a lightweight wrapper library is all that is needed (my suggestion b) ). You could probably also support tagged reader literals for complex numbers pretty easily.

The only problem would be supporting complex types in numerical clojure.core/+. That is very unlikely to happen - I doubt Rich and co want to start adding complexity to the core functions which would hurt performance and break the assumptions that people have about the numerical functions in clojure.core. But that isn't ultimately a big problem, you can just use a specialised addition operator like clojure.complex/+ or clojure.core.matrix.operators/+ instead when you write complex-using code. That's part of my suggestions b) and c), basically to have separate APIs that understand complex types.



On Tuesday, 28 April 2015 19:42:23 UTC+8, Nik wrote:
....
What I would like is a complex type that plays well with Clojure's generic abstractions and functional style (much like Ratio), and is indistinguishable from other types - for example, the ability to work with (map/reduce/filter), the ability to be a part of seqs and use Clojure core functions on it, and so on. It might not as efficient as the complex type in, say C++, but depending on your definition of reasonable, it might be acceptable. I am willing to explore this further. 
.....

Plínio Balduino

unread,
Apr 29, 2015, 8:10:29 AM4/29/15
to Clojure Official
Hi

Before we try to guess what Rich will or won't think or want, are you interested in a proof of concept? So we could evaluate performance and complexity issues before the subject is definitively buried.

What do you think about it?

Plínio 

--

Nik

unread,
Apr 29, 2015, 8:22:59 AM4/29/15
to clo...@googlegroups.com
For me, having complex numbers not work seamlessly with other numbers and core arithmetic ops is not viable. Doing arithmetic ops with any kind of number is a real (pardon the pun) use case.

If  complex numbers are not likely to be supported fully, then maybe it makes sense to have complex numbers just inside of core.matrix. As you suggest, a complex number is two double arrays under the hood for performance, and wraps the Apache Commons Math library. If someone wants to use complex numbers, they have to use core.matrix. Yes, it involves taking on a whole library, but at least you can accomplish complex linear algebra.

Alan Shaw

unread,
Apr 29, 2015, 5:06:54 PM4/29/15
to clo...@googlegroups.com

Ideally math APIs would be cross-platform #ClojureScript

Christopher Small

unread,
Apr 29, 2015, 7:38:47 PM4/29/15
to clo...@googlegroups.com
Let me first say I would definitely like to see complex arithmetic support in Clojure. Major hole for scientific computing in my opinion. And with the momentum that Clojure has in ML / data science, I think it's one that needs patching.

As to you specific point Nik:


> For me, having complex numbers not work seamlessly with other numbers and core arithmetic ops is not viable. Doing arithmetic ops with any kind of number is a real (pardon the pun) use case.

I believe what's being suggested here is that any functions that might live in a specialized namespace would still support arithmetic between any combination of standard numeric types and the added complex type. The usage I envision, and which I imagine is being envisioned by others, is that you would require + - * / etc from this special namespace, and they'd serve as drop in replacements for the standard functions, except that they support complex types as well. This is roughly how core.matrix works (hat tip to M. Anderson, once again), and should be fine here as well. The only slightly tricky thing would be making sure that core.matrix, complex numbers and the standard numerics could all work together. Seems like one of core.matrix or the complex library will have to know about the other... Unless someone has a clever idea around this?

Chris

Christopher Small

unread,
Apr 29, 2015, 7:40:50 PM4/29/15
to clo...@googlegroups.com
Yes, it would be nice to have this available for cljs as well. With the new reader literals though, this doesn't preclude having a native java implementation that gets loaded in the :clj case, and some other implementation that gets loaded in the :cljs case.

Alan Forrester

unread,
Apr 30, 2015, 5:46:59 AM4/30/15
to clo...@googlegroups.com
On 28 April 2015 at 05:22, Mikera <mike.r.an...@gmail.com> wrote:
> Complex numbers are tricky because:
> - They need to be fast in order to be useful for numerical computing. The
> "obvious" implementations that you might create with boxed values,
> vectors/maps, multimethods and protocols are likely to be unacceptable for
> many use cases
> - You still want to be able to use them in a generic way, with operations
> that play nicely with other values (Doubles etc.)
>
> I have thought about this a lot w.r.t. core.matrix and have come to the
> conclusion that there is no simple, elegant answer that meets all use cases.
>
> What I'd like to suggest is:
> a) The community converge on a single, minimal, lightweight representation
> for a boxed complex scalar value. This is probably best as a Java class (for
> easy interop with Java libraries). I think
> http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/complex/Complex.html
> is a good candidate
> b) A lightweight wrapper library that provides nice complex functions in
> Clojure, using the above type. Nothing fancy. But can make extensive use of
> type hints etc. for performance so should be pretty fast

If somebody wrapped the commons math 3 complex library, what would
count as good performance?

Alan

Grahack

unread,
Nov 2, 2015, 8:14:49 AM11/2/15
to Clojure
I'm resurrecting this thread in case there is something new that happened concerning complex numbers that was not logged here.
So was there some progress made?

I also wanted to add that mixing rationals and complex wuold be super cool, like:

(* 1/2 i) => i/2)

Alan Forrester

unread,
Nov 2, 2015, 10:03:00 AM11/2/15
to clo...@googlegroups.com
There is now a complex number library that the Java commons-math3 Complex library:

https://github.com/alanforr/complex/.

This library does not mix rationals and complex since the underlying Java library uses doubles.

Mike Anderson has written a complex matrix library:

https://github.com/mikera/core.matrix.complex.

Alan

Christopher Small

unread,
Nov 2, 2015, 10:57:36 AM11/2/15
to clo...@googlegroups.com

I'll just add that core matrix complex doesn't prevent you from using rationals, as most of the math happens on real/imaginary matrix pairs. However, any time you try to return a scalar value (not a matrix), it wraps the result using the alanforr library, so you'd be potentially restricted there, though I'm not sure if the alanforr library would automatically cast or error out. If someone came up with another complex library, it probably wouldn't be too hard to make that swappable, just as the underlying matrix implantations are presently (in core.matrix.complex).

Chris


--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/lY1r6zw6LeU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
--

Chris

Sent via mobile

Alan Forrester

unread,
Nov 2, 2015, 12:38:52 PM11/2/15
to clo...@googlegroups.com
On 2 Nov 2015, at 15:57, Christopher Small <metas...@gmail.com> wrote:

I'll just add that core matrix complex doesn't prevent you from using rationals, as most of the math happens on real/imaginary matrix pairs. However, any time you try to return a scalar value (not a matrix), it wraps the result using the alanforr library, so you'd be potentially restricted there, though I'm not sure if the alanforr library would automatically cast or error out. If someone came up with another complex library, it probably wouldn't be too hard to make that swappable, just as the underlying matrix implantations are presently (in core.matrix.complex).

The complex number library basically casts non-doubles to doubles.

Alan

You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.

Mars0i

unread,
Nov 6, 2015, 11:28:54 PM11/6/15
to Clojure
I leave it to others to assess the tradeoffs, but: Anything that's done to better support scientific computing has potential to pay off in the long run with greater popularity for Clojure. Most, or many scientists work in universities. Professors have students--lots of students, over time. So getting n scientists using Clojure has the potential to result in (* n s y) new Clojure users, eventually.
Reply all
Reply to author
Forward
0 new messages