Complex numbers in clojure

As part of an effort to learn the Clojure language, I've set about implementing a basic set of functions for working with complex numbers. There is undoubtedly a better implementation already accessible in Clojure, but implementing this from first principles was great fun and practice.

download.png

Clojure is a Lisp implemented on the Java JVM. This is a functional language, and the syntax can be a bit tricky at first. The functional paradigm offers new ways of looking at code, potentially leading to new insights in program construction.

In order to work with complex numbers, the first thing to do is to define a complex number type; A complex number consists of a real part and an imaginary part:

; Define the basic type
(deftype complex
  [^double real ^double imag])

The next part is to implement a utility function that can output our complex numbers is a user-friendly, readable way. Though not strictly necessary for performing algebra, I found this to be useful:

; Print the complex number in a reasonable way
(defn print-complex
  [^complex z]
  (str (.real z) " + " (.imag z) "i"))

We can check that we get the output expected by calling the function

(print-complex (complex. 1.0 2.5))

gives the output "1.0 + 2.5i".

Next, to implement addition:

; Define the addition operator
; Since arity is used to determine overloads of functions,
; we will call this function "plus" instead of "+"

(defn plus
  [^complex z1 ^complex z2]
  (complex. 
   (+ (.real z1) (.real z2))
   (+ (.imag z1) (.imag z2))))

And finally, multiplication:

; Define vector multiplication

(defn mult
  [^complex z1 ^complex z2]
  (complex.
   (+ (* (.real z1) (.real z2)) (* (.imag z1) (.imag z2)))
   (+ (* (.real z1) (.imag z2)) (* (.real z2) (.imag z1)))))

The construction for multiplication is based on the derivation:

(a + bi) * (c + di) = (ac - bd + (ad + bc)i)


Posted via proofofbrain.io

Sort:  

Nice to see the clojure tutorial on this platform. Though a small one its good effort. Keep studying and coding.

Thanks. Perhaps I'll try do some more of these code tutorial type of posts.

Posted Using LeoFinance Beta

Nice. Next step is to support polar form.

Good idea!

Posted Using LeoFinance Beta

I find it strange that there is no decimal number class in Boost for C++. C# has a special decimal type built-in. I mention this because I think there is a greater need for that kind of stuff than complex numbers. The ability to save monetary amounts with no internal repeating decimals.

Python has both complex numbers builtin and a Decimal numbers module.


Posted via proofofbrain.io

I haven't used the Boost libraries at all, been out of the C++ ecosystem for a while now.

Complex numbers are super useful for physics stuff and also for optimisation. I just implemented it as a practice exercise, would be really surprised if there isn't a library for complex numbers already existing in Clojure.

One really cool feature in Clojure is the symbolic representation of rational numbers:

(/ 1 3)

evaluates to 1/3 rather than 0.3333. This allows more precise calculations, as rounding only needs to be done at the end.

Posted Using LeoFinance Beta

Oh wow. If you write 0.20, it will be a repeated decimal in Clojure, won't it? So instead you could handle 0.2 by writing (/ 1 5).

Yes exactly. 0.2 would be of type double and 1/5 is called "ratio" type in Clojure.

Posted Using LeoFinance Beta

Congratulations @chasmic-cosm! You have completed the following achievement on the Hive blockchain and have been rewarded with new badge(s) :

You distributed more than 37000 upvotes.
Your next target is to reach 38000 upvotes.

You can view your badges on your board and compare yourself to others in the Ranking
If you no longer want to receive notifications, reply to this comment with the word STOP

Check out the last post from @hivebuzz:

False-Positive phishing alert reported by antivirus software
Feedback from the May 1st Hive Power Up Day
Support the HiveBuzz project. Vote for our proposal!

Test comment

\int x dx