Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make Complex arithmetic the default within a Clojure project

you've been spectacularly helpful to me so far, I hope you can help me get my mind around this one. I am building a project that does computations with complex matrices. I have been using mikera/core.matrix.complex, which uses mikera/core.matrix for matrix stuff, and complex.core for defining complex numbers in clojure.

I want to be able to do any and all arithmetic, including using irrational numbers like e (def e (Math/E)) and pi (def pi (Math/PI)), and including matrix math that may or may not be complex. The problem comes when I mix functions from different libraries.

Right now my namespace looks like this:

(ns qgame.utils.math
(:require 
        [clojure.walk :as w :refer [postwalk
                                    prewalk]]
        [clojure.core.matrix :as mat]
        [clojure.core.matrix.complex :as compl]
        [incanter.core :as ic]
        [complex.core :as c :refer [+ - / *]]))

If I do (mat/mmul matrix1 matrix2), then everything is treated as a regular number, and using complex numbers messes it up. I get a lot of ClassCastException org.apache.commons.math3.complex.Complex cannot be cast to java.lang.Number. If I just require core.matrix.complex without requiring core.matrix, then none of the matrix functions work.

The same goes for stuff like (+ 3 4). If I directly (use 'complex.core) in a repl, then that will evaluate to (7.0, 0.0), which is what I want, otherwise it just comes out as 7.

I feel like I'm making this more complicated than it is, the core.matrix.complex looks like it has extensions for everything in core.matrix and clojure.core, but it doesn't utilize it with the namespace declaration that I have. I'm not that familiar with Clojure protocols, so there is definitely something that I am missing. I just want all three libraries to be included, and to have any and all math be done in the context of complex numbers, i.e 1 = (1.0, 0.0), and (Math/exp (* pi (complex 0 1)) => (-1.0, 0.0)

How can I go about doing this? Sorry if I'm not being clear, I'll try and clear up any questions people have about what I'm asking.

Edit: I've been thinking about the problem, and really the best place to start is the last equation that I listed: Getting e^pi*i to equal -1. If I try to use Math/exp with complex numbers, I get a casting exception.

like image 538
Phylth Avatar asked Nov 09 '22 19:11

Phylth


1 Answers

I'm not familiar with core.matrix.complex but here are some points you are probably not aware of. This is technically not an answer but it's too long to fix in a comment.

  1. core.matrix defined a set of API, in the form of protocols, defined here.

  2. core.matrix.complex does not extend all protocols to complex matrices. For example, the mat/mmul defined here relies on the protocol PMatrixMultiply. But this protocol is not extended to complex matrices.

  3. (+ 3 4) returns (7.0, 0.0) after use-ing complex.core because complex.core rewrote the function/operator +. But I doubt whether you should refer these operators. complex.core is merely a thin wrapper around org.apache.commons.math3.complex.Complex and it knows nothing about matrices. Perhaps you'll be better off using functions/operators in core.matrix API like add.

like image 93
Davyzhu Avatar answered Nov 15 '22 05:11

Davyzhu