changeset 466:604a93b0b24d

Add equal, conjugate transpose, slices, diagonal, magnitudes and angles
author Chris Cannam
date Fri, 25 Oct 2013 14:37:32 +0100
parents c8b59d379cab
children a9376197529d
files src/may/matrix/complex.yeti src/may/matrix/test/test_complexmatrix.yeti
diffstat 2 files changed, 99 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/may/matrix/complex.yeti	Fri Oct 25 14:37:09 2013 +0100
+++ b/src/may/matrix/complex.yeti	Fri Oct 25 14:37:32 2013 +0100
@@ -40,14 +40,65 @@
         esac;
     cpx.complex (partAt cm.real row col) (partAt cm.imaginary row col));
 
+maybe' lambda f = // like maybe but with lazy default
+   \case of
+    Some v: f v;
+    None _: lambda ();
+    esac;
+
 getRow n cm = 
-   (pget = maybe (vec.zeros cm.size.columns) (mat.getRow n);
+   (pget = maybe' \(vec.zeros cm.size.columns) (mat.getRow n);
     array (map2 cpx.complex (pget cm.real) (pget cm.imaginary)));
 
 getColumn n cm = 
-   (pget = maybe (vec.zeros cm.size.rows) (mat.getColumn n);
+   (pget = maybe' \(vec.zeros cm.size.rows) (mat.getColumn n);
     array (map2 cpx.complex (pget cm.real) (pget cm.imaginary)));
 
+getDiagonal k cm = 
+   (ioff = if k < 0 then -k else 0 fi;
+    joff = if k > 0 then  k else 0 fi;
+    n = min (cm.size.columns - joff) (cm.size.rows - ioff);
+    pget = maybe' \(vec.zeros n) (mat.getDiagonal k);
+    array (map2 cpx.complex (pget cm.real) (pget cm.imaginary)));
+
+rowSlice cm start end =
+   (pget = maybe none (Some . do m: mat.rowSlice m start end done);
+    {
+        size = { rows = end - start, columns = cm.size.columns },
+        real = pget cm.real,
+        imaginary = pget cm.imaginary
+    });
+
+columnSlice cm start end =
+   (pget = maybe none (Some . do m: mat.columnSlice m start end done);
+    {
+        size = { columns = end - start, rows = cm.size.rows },
+        real = pget cm.real,
+        imaginary = pget cm.imaginary
+    });
+
+equal cm1 cm2 =
+    cm1.size == cm2.size and
+        case cm1.real of
+        Some m1:
+            case cm2.real of
+            Some m2: mat.equal m1 m2;
+            None (): mat.equal m1 (mat.zeroMatrix cm1.size);
+            esac;
+        None ():
+            case cm2.real of
+            Some m2: mat.equal m2 (mat.zeroMatrix cm2.size);
+            None (): true;
+            esac;
+        esac;
+
+conjugateTransposed cm =
+    {
+        size = { rows = cm.size.columns, columns = cm.size.rows },
+        real = maybe none (Some . mat.transposed) cm.real,
+        imaginary = maybe none (Some . mat.negative . mat.transposed) cm.imaginary,
+    };
+
 transposed cm =
     {
         size = { rows = cm.size.columns, columns = cm.size.rows },
@@ -67,9 +118,19 @@
    (sc = maybe none (Some . (mat.scaled factor));
     cm with { real = sc cm.real, imaginary = sc cm.imaginary });
 
-real cm = maybe (mat.zeroMatrix cm.size) id cm.real;
+real cm = maybe' \(mat.zeroMatrix cm.size) id cm.real;
 
-imaginary cm = maybe (mat.zeroMatrix cm.size) id cm.imaginary;
+imaginary cm = maybe' \(mat.zeroMatrix cm.size) id cm.imaginary;
+
+magnitudes cm =
+    mat.generate do row col:
+        cpx.magnitude (at cm row col);
+    done cm.size;
+
+angles cm =
+    mat.generate do row col:
+        cpx.angle (at cm row col);
+    done cm.size;
 
 addParts p1 p2 =
     case p1 of
@@ -180,6 +241,9 @@
     at,
     getColumn,
     getRow,
+    getDiagonal,
+    equal,
+    conjugateTransposed,
     transposed,
     toSparse,
     toDense,
@@ -191,6 +255,10 @@
     fromImaginary,
     real,
     imaginary,
+    magnitudes,
+    angles,
+    rowSlice,
+    columnSlice,
     newComplexMatrix,
     enumerate,
 } as {
@@ -201,6 +269,9 @@
     at is complexmatrix -> number -> number -> cplx,
     getColumn is number -> complexmatrix -> array<cplx>,
     getRow is number -> complexmatrix -> array<cplx>,
+    getDiagonal is number -> complexmatrix -> array<cplx>,
+    equal is complexmatrix -> complexmatrix -> boolean,
+    conjugateTransposed is complexmatrix -> complexmatrix,
     transposed is complexmatrix -> complexmatrix,
     toSparse is complexmatrix -> complexmatrix,
     toDense is complexmatrix -> complexmatrix,
@@ -215,6 +286,10 @@
     fromImaginary is matrix -> complexmatrix,
     real is complexmatrix -> matrix,
     imaginary is complexmatrix -> matrix,
+    magnitudes is complexmatrix -> matrix,
+    angles is complexmatrix -> matrix,
+    rowSlice is complexmatrix -> number -> number -> complexmatrix,
+    columnSlice is complexmatrix -> number -> number -> complexmatrix,
     newComplexMatrix is (ColumnMajor () | RowMajor ()) -> list?<list?<cplx>> -> complexmatrix,
     enumerate is complexmatrix -> list<{ .i is number, .j is number, .v is cplx }>,
 }
--- a/src/may/matrix/test/test_complexmatrix.yeti	Fri Oct 25 14:37:09 2013 +0100
+++ b/src/may/matrix/test/test_complexmatrix.yeti	Fri Oct 25 14:37:32 2013 +0100
@@ -41,5 +41,25 @@
        (sortEntries all);
 ),
     
+"magnitudes": \(
+    // 1+0i 0-2i
+    // 0+0i 4-3i
+    reals = mat.newMatrix (RowMajor ()) (map vec.fromList [[1,0],[0,4]]);
+    imags = mat.newMatrix (RowMajor ()) (map vec.fromList [[0,-2],[0,-3]]);
+    m = cm.complex reals imags;
+    mags = cm.magnitudes m;
+    compare (map vec.list (mat.asRows mags)) [[1,2],[0,5]];
+),
+ 
+"angles": \(
+    // 1+0i 0-2i
+    // 0+0i -4-4i
+    reals = mat.newMatrix (RowMajor ()) (map vec.fromList [[1,0],[0,-4]]);
+    imags = mat.newMatrix (RowMajor ()) (map vec.fromList [[0,-2],[0,-4]]);
+    m = cm.complex reals imags;
+    mags = cm.angles m;
+    compare (map vec.list (mat.asRows mags)) [[0,-pi/2],[0,-3*pi/4]];
+),
+
 ] is hash<string, () -> boolean>;