Skip to content

Commit

Permalink
Removing some dead code, and doing some cleanup in, ComplexMatrix
Browse files Browse the repository at this point in the history
  • Loading branch information
Strilanc committed Sep 18, 2013
1 parent a96cf39 commit fe21e15
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 93 deletions.
111 changes: 52 additions & 59 deletions QuantumPseudoTelepathy/Math/ComplexMatrix.cs
Expand Up @@ -11,29 +11,59 @@ public struct ComplexMatrix {
private ComplexMatrix(IEnumerable<IEnumerable<Complex>> columns) {
if (columns == null) throw new ArgumentNullException("columns");
this._columns = columns.Select(e => e.ToArray()).ToArray();
//if (_columns.Any(col => col.Count != _columns.Count)) throw new ArgumentException("Not square");

var span = _columns.Length;
if (_columns.Any(e => e.Length != span)) throw new ArgumentOutOfRangeException("columns", "Not square");
}

public int Span { get { return _columns == null ? 0 : _columns.Length; } }
public IReadOnlyList<IReadOnlyList<Complex>> Columns { get { return _columns ?? ReadOnlyList.Empty<IReadOnlyList<Complex>>(); } }
public IReadOnlyList<IReadOnlyList<Complex>> Rows {
get {
var r = Columns;
return new AnonymousReadOnlyList<IReadOnlyList<Complex>>(
r.Count,
row => new AnonymousReadOnlyList<Complex>(
r.Count,
col => r[col][row]));
}
}

public static ComplexMatrix FromColumns(IEnumerable<IEnumerable<Complex>> columns) {
return new ComplexMatrix(columns);
}
public static ComplexMatrix FromSquareData(params Complex[] cells) {
if (cells == null) throw new ArgumentNullException("cells");

var size = (int)Math.Round(Math.Sqrt(cells.Length));
if (size * size != cells.Length) throw new ArgumentOutOfRangeException("cells", "cells.Length is not square");

var cols = cells.Deinterleave(size);
return FromColumns(cols);
}

public bool IsIdentity() {
return Columns.Select((e, i) => e.Select((f, j) => (f - (j == i ? 1 : 0)).Magnitude < 0.0001).All(f => f)).All(e => e);
}
public bool IsUnitary() {
return (this*this.Dagger()).IsIdentity();
}
public static ComplexMatrix FromCellData(params Complex[] cells) {
var size = (int)Math.Sqrt(cells.Length);
var cols = cells.Deinterleave(size);
return FromColumns(cols);
/// <summary>Determines if this * c == other, for some c where |c| == 1</summary>
public bool IsPhased(ComplexMatrix other) {
var self = this;
return (from c in self.Span.Range()
from r in self.Span.Range()
let v = self.Columns[c][r]
where v != 0
let ov = other.Columns[c][r]
select self * (ov / v) == other
).FirstOrDefault();
}
public static ComplexMatrix FromMatrixData(params ComplexMatrix[] cells) {
var inSize = cells.First().Span;
var outSize = (int)Math.Sqrt(cells.Length);
var size = inSize * outSize;
return FromColumns(size.Range().Select(c => size.Range().Select(r => cells.Deinterleave(outSize)[c / inSize][r / inSize].Columns[c % inSize][r % inSize]).ToArray()).ToArray());
/// <summary>Determines adjusting the row phases of other can make it equal to this.</summary>
public bool IsMultiRowPhased(ComplexMatrix other) {
return Rows.Zip(other.Rows, (c1, c2) => new ComplexVector(c1).IsPhased(new ComplexVector(c2))).All(e => e);
}

public ComplexMatrix TensorSquare() {
return this.TensorProduct(this);
}
Expand All @@ -49,56 +79,12 @@ public struct ComplexMatrix {
public ComplexMatrix Transpose() {
return FromColumns(Rows);
}
public ComplexMatrix ExpandToApplyToMoreWires(int wireCount, int[] correspondingWiresForEachState) {
if ((1 << correspondingWiresForEachState.Length) != Span) throw new ArgumentOutOfRangeException();
if ((1 << wireCount) < Span) throw new ArgumentOutOfRangeException();

var otherWires = wireCount.Range().Except(correspondingWiresForEachState).ToArray();
var x = this;
var result = from col in new[] {0, 1}.ChooseWithReplacement(wireCount)
select from row in new[] {0, 1}.ChooseWithReplacement(wireCount)
let r = correspondingWiresForEachState.Select((e, i) => row[e] << i).Sum()
let c = correspondingWiresForEachState.Select((e, i) => col[e] << i).Sum()
let xr = otherWires.Select((e, i) => row[e] << i).Sum()
let xc = otherWires.Select((e, i) => col[e] << i).Sum()
select xr == xc ? x.Columns[c][r] : 0;
return FromColumns(result);
}

///<summary>Returns the result of conjugating the elements of and tranposing this matrix.</summary>
public ComplexMatrix Dagger() {
return FromColumns(this.Rows.Select(e => e.Select(x => new Complex(x.Real, -x.Imaginary))));
}
public int Span { get { return _columns == null ? 0 : _columns.Length; } }
public IReadOnlyList<IReadOnlyList<Complex>> Columns { get { return _columns ?? ReadOnlyList.Empty<IReadOnlyList<Complex>>(); } }
public IReadOnlyList<IReadOnlyList<Complex>> Rows {
get {
var r = Columns;
return new AnonymousReadOnlyList<IReadOnlyList<Complex>>(
r.Count,
row => new AnonymousReadOnlyList<Complex>(
r.Count,
col => r[col][row]));
}
}
public bool IsMultiRowPhased(ComplexMatrix other) {
return Rows.Zip(other.Rows, (c1, c2) => new ComplexVector(c1).IsPhased(new ComplexVector(c2))).All(e => e);
}
public bool IsPhased(ComplexMatrix other) {
var self = this;
return (from c in self.Span.Range()
from r in self.Span.Range()
let v = self.Columns[c][r]
where v != 0
let ov = other.Columns[c][r]
select self*(ov/v) == other
).FirstOrDefault();
}
public bool IsSuperSimple() {
return Columns.Select((e, i) => (e[i].Magnitude - 1).Abs() < 0.00001).All(e => e);
}
public bool IsSimple() {
return Columns.All(e => e.Count(c => c != 0) == 1);
}

public static ComplexVector operator *(ComplexMatrix matrix, ComplexVector vector) {
return new ComplexVector(
matrix.Rows
Expand Down Expand Up @@ -139,9 +125,16 @@ public struct ComplexMatrix {
return obj is ComplexMatrix && (ComplexMatrix)obj == this;
}
public override int GetHashCode() {
return Columns.SelectMany(e => e).Aggregate(Span.GetHashCode(), (a, e) => a*3 + Math.Round(e.Real*1000).GetHashCode()*5 + Math.Round(e.Imaginary*1000).GetHashCode());
// This is a hack that works in the cases that I needed it to work in.
// It groups most approximately equal matrices, but not ones across the third digit after decimal boundaries.
return Columns.SelectMany(e => e).Aggregate(
Span.GetHashCode(),
(a, e) => a*3 + Math.Round(e.Real*1000).GetHashCode()*5 + Math.Round(e.Imaginary*1000).GetHashCode());
}
public override string ToString() {
return Rows.Select(r => r.Select(c => "| " + c.ToPrettyString().PadRight(6)).StringJoin("") + " |").StringJoin(Environment.NewLine);
return Rows.Select(r => r.Select(c => "| " + c.ToPrettyString().PadRight(6))
.StringJoin("")
+ " |")
.StringJoin(Environment.NewLine);
}
}
}
32 changes: 16 additions & 16 deletions QuantumPseudoTelepathy/Quantum/Gates.cs
Expand Up @@ -3,77 +3,77 @@

public static class Gates {
private static readonly Complex i = Complex.ImaginaryOne;
public static readonly ComplexMatrix NoGate = ComplexMatrix.FromCellData(
public static readonly ComplexMatrix NoGate = ComplexMatrix.FromSquareData(
1, 0,
0, 1);

// Hadamard gate
public static readonly ComplexMatrix H = ComplexMatrix.FromCellData(
public static readonly ComplexMatrix H = ComplexMatrix.FromSquareData(
1, 1,
1, -1)/Math.Sqrt(2);
// Pauli X gate
public static readonly ComplexMatrix X = ComplexMatrix.FromCellData(
public static readonly ComplexMatrix X = ComplexMatrix.FromSquareData(
0, 1,
1, 0);
// Pauli Y gate
public static readonly ComplexMatrix Y = ComplexMatrix.FromCellData(
public static readonly ComplexMatrix Y = ComplexMatrix.FromSquareData(
0, -i,
i, 0);
// Pauli Z gate
public static readonly ComplexMatrix Z = ComplexMatrix.FromCellData(
public static readonly ComplexMatrix Z = ComplexMatrix.FromSquareData(
1, 0,
0, -1);
// R2 gate = pi/2 phase gate
public static readonly ComplexMatrix Phase = ComplexMatrix.FromCellData(
public static readonly ComplexMatrix Phase = ComplexMatrix.FromSquareData(
1, 0,
0, i);
// 'Square root of not' gate
public static readonly ComplexMatrix SqrtNot = ComplexMatrix.FromCellData(
public static readonly ComplexMatrix SqrtNot = ComplexMatrix.FromSquareData(
1, -1,
1, 1) / Math.Sqrt(2);
// Half-mirror gate
public static readonly ComplexMatrix BeamSplit = ComplexMatrix.FromCellData(
public static readonly ComplexMatrix BeamSplit = ComplexMatrix.FromSquareData(
1, i,
i, 1) / Math.Sqrt(2);

public static readonly ComplexMatrix ControlledNot2When1 = ComplexMatrix.FromCellData(
public static readonly ComplexMatrix ControlledNot2When1 = ComplexMatrix.FromSquareData(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 0, 1,
0, 0, 1, 0);
public static readonly ComplexMatrix ControlledNot1When2 = ComplexMatrix.FromCellData(
public static readonly ComplexMatrix ControlledNot1When2 = ComplexMatrix.FromSquareData(
1, 0, 0, 0,
0, 0, 0, 1,
0, 0, 1, 0,
0, 1, 0, 0);
public static readonly ComplexMatrix Swap = ComplexMatrix.FromCellData(
public static readonly ComplexMatrix Swap = ComplexMatrix.FromSquareData(
1, 0, 0, 0,
0, 0, 1, 0,
0, 1, 0, 0,
0, 0, 0, 1);
public static readonly ComplexMatrix Increment = ComplexMatrix.FromCellData(
public static readonly ComplexMatrix Increment = ComplexMatrix.FromSquareData(
0, 0, 0, 1,
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0);
public static readonly ComplexMatrix Decrement = Increment.Dagger();

public static readonly ComplexMatrix Phase00 = ComplexMatrix.FromCellData(
public static readonly ComplexMatrix Phase00 = ComplexMatrix.FromSquareData(
i, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
public static readonly ComplexMatrix Phase01 = ComplexMatrix.FromCellData(
public static readonly ComplexMatrix Phase01 = ComplexMatrix.FromSquareData(
1, 0, 0, 0,
0, i, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
public static readonly ComplexMatrix Phase10 = ComplexMatrix.FromCellData(
public static readonly ComplexMatrix Phase10 = ComplexMatrix.FromSquareData(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, i, 0,
0, 0, 0, 1);
public static readonly ComplexMatrix Phase11 = ComplexMatrix.FromCellData(
public static readonly ComplexMatrix Phase11 = ComplexMatrix.FromSquareData(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
Expand Down
12 changes: 6 additions & 6 deletions QuantumPseudoTelepathy/Quantum/PseudoTelepathyCircuits.cs
Expand Up @@ -18,7 +18,7 @@ public static class PseudoTelepathyCircuits {
.Then(Gates.Swap)
:
//matrix (row phases are arbitrary):
ComplexMatrix.FromCellData(
ComplexMatrix.FromSquareData(
1, 0, 0, i,
0, 1,-i, 0,
0,-i, 1, 0,
Expand All @@ -37,7 +37,7 @@ public static class PseudoTelepathyCircuits {
.Then(Gates.ControlledNot2When1)
:
//matrix (row phases are arbitrary):
ComplexMatrix.FromCellData(
ComplexMatrix.FromSquareData(
1, i, i, 1,
1,-i, i,-1,
1, i,-i,-1,
Expand All @@ -55,7 +55,7 @@ public static class PseudoTelepathyCircuits {
.Then(Gates.H.OnWire1Of2())
:
//matrix (row phases are arbitrary):
ComplexMatrix.FromCellData(
ComplexMatrix.FromSquareData(
1, 1, 1,-1,
1, 1,-1, 1,
1,-1, 1, 1,
Expand All @@ -73,7 +73,7 @@ public static class PseudoTelepathyCircuits {
.Then(Gates.Swap)
:
//matrix (row phases are arbitrary):
ComplexMatrix.FromCellData(
ComplexMatrix.FromSquareData(
1,-1, i, i,
1, 1,-i, i,
1, 1, i,-i,
Expand All @@ -91,7 +91,7 @@ public static class PseudoTelepathyCircuits {
.Then(Gates.BeamSplit.OnWire1Of2())
:
//matrix (row phases are arbitrary):
ComplexMatrix.FromCellData(
ComplexMatrix.FromSquareData(
1, i,-1, i,
1,-i, 1, i,
1, i, 1,-i,
Expand All @@ -108,7 +108,7 @@ public static class PseudoTelepathyCircuits {
.Then(Gates.SqrtNot.OnWire2Of2())
:
//matrix (row phases are arbitrary):
ComplexMatrix.FromCellData(
ComplexMatrix.FromSquareData(
0, 1,-1, 0,
0, 1, 1, 0,
1, 0, 0,-1,
Expand Down
24 changes: 12 additions & 12 deletions QuantumPseudoTelepathyTest/ComplexMatrixTest.cs
Expand Up @@ -7,10 +7,10 @@ public class ComplexMatrixTest {
[TestMethod]
public void TestIsMultiPhase() {
var i = Complex.ImaginaryOne;
var r1 = ComplexMatrix.FromCellData(1, 0, 0, 1);
var r2 = ComplexMatrix.FromCellData(i, 0, 0, 1);
var r3 = ComplexMatrix.FromCellData(0, 1, 1, 0);
var r4 = ComplexMatrix.FromCellData(1, 1, 1, -1)/Math.Sqrt(2);
var r1 = ComplexMatrix.FromSquareData(1, 0, 0, 1);
var r2 = ComplexMatrix.FromSquareData(i, 0, 0, 1);
var r3 = ComplexMatrix.FromSquareData(0, 1, 1, 0);
var r4 = ComplexMatrix.FromSquareData(1, 1, 1, -1)/Math.Sqrt(2);

Assert.IsTrue(r1.IsMultiRowPhased(r1));
Assert.IsTrue(r1.IsMultiRowPhased(r2));
Expand All @@ -25,17 +25,17 @@ public class ComplexMatrixTest {
}
[TestMethod]
public void TestMultiplication() {
var M1 = ComplexMatrix.FromCellData(
var M1 = ComplexMatrix.FromSquareData(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 0, 1,
0, 0, 1, 0);
var M2 = ComplexMatrix.FromCellData(
var M2 = ComplexMatrix.FromSquareData(
1, 0, 0, 0,
0, 0, 1, 0,
0, 1, 0, 0,
0, 0, 0, 1);
var M3 = ComplexMatrix.FromCellData(
var M3 = ComplexMatrix.FromSquareData(
1, 0, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1,
Expand All @@ -44,7 +44,7 @@ public class ComplexMatrixTest {
}
[TestMethod]
public void TestVectorMultiplication() {
var M1 = ComplexMatrix.FromCellData(
var M1 = ComplexMatrix.FromSquareData(
10, 11, 12,
13, 14, 15,
16, 17, 18);
Expand All @@ -54,7 +54,7 @@ public class ComplexMatrixTest {
}
[TestMethod]
public void TestVectorMultiplication2() {
var M1 = ComplexMatrix.FromCellData(
var M1 = ComplexMatrix.FromSquareData(
10, 11, 12,
13, 14, 15,
16, 17, 18);
Expand All @@ -64,15 +64,15 @@ public class ComplexMatrixTest {
}
[TestMethod]
public void TestMultiplication2() {
var M1 = ComplexMatrix.FromCellData(
var M1 = ComplexMatrix.FromSquareData(
-1, 2, 3,
4, 5, 6,
7, 8, 9);
var M2 = ComplexMatrix.FromCellData(
var M2 = ComplexMatrix.FromSquareData(
10, 11, 12,
13, 14, 15,
16, 17, 18);
var M3 = ComplexMatrix.FromCellData(
var M3 = ComplexMatrix.FromSquareData(
64, 68, 72,
201, 216, 231,
318, 342, 366);
Expand Down

0 comments on commit fe21e15

Please sign in to comment.