-
Notifications
You must be signed in to change notification settings - Fork 0
Complex matrices
BIDMat includes a complex, single precision matrix type called CMat. Internally, real/complex pairs are stored in consecutive memory words as floats which supports the scientific library functions defined for complex matrices. There is however, no complex scalar type. Similar to Matlab, a complex scalar is realized as a 1x1 matrix.
To create a complex value, you can use the "i" method like this:
scala> val b = 3 + 4.i b: BIDMat.CMat = 3+4iwhich with some Scala magic implicitly casts the integer values as FMats, applies the ".i" operator to the second argument to produce a CMat, and then knows how to apply "+" to an FMat and a CMat. Not that you should know or care how this happens. The result is simply a CMat with a single value.
Note that we used the "." operator to invoke the "i" method rather than using a space:
scala> val b = 3 + 4 i b: BIDMat.CMat = 7isince in Scala's syntax, "+" has a higher precedence than "i".
scala> val b = 3 + (4 i) b: BIDMat.CMat = 3+4ialso works, as does (somewhat surprisingly) "3 + 4.0.i" However "3 + 4i" does not parse.
To create a large matrix of complex numbers, you can use any of the random number generators:
scala> val c = rand(4,10) + rand(4,10).i c: BIDMat.CMat = 0.21497+0.77080i 0.67449+0.28513i 0.93723+0.71991i... 0.37809+0.83195i 0.051680+0.89084i 0.038354+0.76330i... 0.36922+0.82463i 0.78521+0.27711i 0.67254+0.71312i... 0.87246+0.25732i 0.14137+0.19628i 0.98884+0.96585i...one syntactic snag is that we cannot access elements of complex matrices using "a(i,j)" syntax. This operation is shared by all matrices and must return the base (element) type. Trying to will produce:
scala> a(1,2) java.lang.RuntimeException: can't use a(i,j) indexing on CMat, use a.get(i,j) instead ...Accordingly, we instead apply the get operator:
scala> c.get(1,2) res1: BIDMat.CMat = 0.038354+0.76330iWe can however perform element updates with complex or real values:
scala> c(1,2) = 3 + 4.i res2: BIDMat.CMat = 3+4i scala> c c: BIDMat.CMat = 0.21497+0.77080i 0.67449+0.28513i 0.93723+0.71991i... 0.37809+0.83195i 0.051680+0.89084i 3+4i... 0.36922+0.82463i 0.78521+0.27711i 0.67254+0.71312i... 0.87246+0.25732i 0.14137+0.19628i 0.98884+0.96585i... scala> c(1,0) = 5 res3: Float = 5.0 scala> c c: BIDMat.CMat = 0.21497+0.77080i 0.67449+0.28513i 0.93723+0.71991i... 5 0.051680+0.89084i 3+4i... 0.36922+0.82463i 0.78521+0.27711i 0.67254+0.71312i... 0.87246+0.25732i 0.14137+0.19628i 0.98884+0.96585i...
To extract the real or imaginary parts of a complex matrix, use the operators ".r" and ".i". Like this:
scala> val a = rand(4,10) + rand(4,10).i a: BIDMat.CMat = 0.67636+0.34410i 0.15675+0.46375i 0.43748+0.57167i... 0.31279+0.63679i 0.69485+0.59093i 0.91233+0.15906i... 0.10547+0.46058i 0.88596+0.73404i 0.58793+0.86155i... 0.83065+0.87015i 0.84817+0.18380i 0.080891+0.78927i... scala> a.r res1: BIDMat.FMat = 0.67636 0.15675 0.43748 0.081511 0.46293 0.097704 0.71535... 0.31279 0.69485 0.91233 0.87120 0.12652 0.71330 0.35587... 0.10547 0.88596 0.58793 0.90858 0.45308 0.45136 0.069531... 0.83065 0.84817 0.080891 0.022294 0.73676 0.14168 0.91742... scala> a.i res2: BIDMat.FMat = 0.34410 0.46375 0.57167 0.64560 0.92401 0.32618 0.44249... 0.63679 0.59093 0.15906 0.68576 0.35331 0.12405 0.16163... 0.46058 0.73404 0.86155 0.19624 0.87816 0.48652 0.56278... 0.87015 0.18380 0.78927 0.065433 0.45076 0.87441 0.56792...
The operator ".i" therefore has two different meanings: When applied to an FMat, it returns a CMat which is sqrt(-1) times the original matrix. When applied to a CMat, it extracts the imaginary part and returns it as an FMat. This is done for simplicity but it could be confusing. If so, the operator ".im" is an alias which will extract the imaginary part of a CMat.
Most of the operations defined for real matrices will work on complex matrices (algebraic operators, concatenation, slicing, find functions). But comparison operators
<,>,==,>=,<=,!=
will not since complex numbers have no linear ordering.
Most of the standard matrix functions, exp, log etc., are not yet defined for complex matrices. Complex matrices are primarily used to support linear algebra routines that generate complex values from real ones - e.g. eigenvalues of non-symmetric matrices.