Created
August 28, 2012 23:06
-
-
Save AlecZorab/3505149 to your computer and use it in GitHub Desktop.
Hacky attempt at representing Bra-Ket notation. Term simplification could be best described as "unstructured". (or appalling, your choice)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object BraKet3_SmokeyIsTheBraket extends App { | |
sealed trait Expr { | |
e1 => | |
def *(e2: Expr): Expr = Prod(e1, e2) | |
def +(e2: Expr): Expr = Sum(e1, e2) | |
def simplify: Expr = this | |
def <(bs: Basis*) = new { | |
def build(l: List[Basis]): Expr = l match { | |
case t :: Nil => Bra(t) | |
case h :: t => Bra(h) * build(t) | |
} | |
def | = e1 * build(bs.toList) | |
} | |
def |(bs: Basis*) = new { | |
def build(l: List[Basis]): Expr = l match { | |
case t :: Nil => Ket(t) | |
case h :: t => Ket(h) * build(t) | |
} | |
def > = e1 * build(bs.toList) | |
} | |
} | |
trait Scalar extends Expr | |
case class KnownScalar(d: Double) extends Scalar { | |
override def toString = f"$d%.2f" | |
} | |
case class VarScalar(s: Symbol) extends Scalar { | |
override def toString = s"$s" | |
} | |
case class Bra(d: Symbol) extends Expr { | |
override def toString = s"<$d|" | |
} | |
case class Ket(d: Symbol) extends Expr { | |
override def toString = s"|$d>" | |
} | |
case class BraKet(d1: Symbol, d2: Symbol) extends Expr { | |
override def toString = s"<$d1|$d2>" | |
override def simplify = if (d1 == d2) KnownScalar(1.0) else KnownScalar(0.0) | |
} | |
type Basis = Symbol | |
object * { | |
def unapply(e: Expr) = e match { | |
case Prod(e1, e2) => Some((e1, e2)) | |
case _ => None | |
} | |
} | |
object + { | |
def unapply(e: Expr) = e match { | |
case Sum(e1, e2) => Some((e1, e2)) | |
case _ => None | |
} | |
} | |
case class Prod(e1: Expr, e2: Expr) extends Expr { | |
override def toString = s"($e1 * $e2)" | |
override def simplify: Expr = this match { | |
case KnownScalar(0.0) * e => KnownScalar(0.0) | |
case e * KnownScalar(0.0) => KnownScalar(0.0) | |
case KnownScalar(1.0) * e => e | |
case e * KnownScalar(1.0) => e | |
case KnownScalar(a) * KnownScalar(b) => KnownScalar(a * b) | |
case KnownScalar(a) * (e1 + e2) => (KnownScalar(a) * e1) + (KnownScalar(a) * e2) | |
case ((b: Bra) * (s1 + s2)) => ((b * s1).simplify + (b * s2).simplify).simplify | |
case ((s1 + s2) * (k: Ket)) => ((s1 * k).simplify + (s2 * k).simplify).simplify | |
case Bra(b) * Ket(k) => BraKet(b, k) | |
case (Bra(b1) * Bra(b2)) * Ket(k) => Bra(b1) * (Bra(b2) * Ket(k)) | |
case (e1 * ((s: Scalar) * e2)) => ((s * e1).simplify * e2).simplify | |
case (e1 * (e2 * (s: Scalar))) => ((s * e1).simplify * e2).simplify | |
case ((s: Scalar) * e1) * e2 => s * (e1 * e2).simplify | |
case (e1 * (s: Scalar)) * e2 => s * (e1 * e2).simplify | |
case e1 * e2 => e1.simplify * e2.simplify | |
case _ => this | |
} | |
} | |
case class Sum(e1: Expr, e2: Expr) extends Expr { | |
override def toString = s"($e1 + $e2)" | |
override def simplify: Expr = this match { | |
case KnownScalar(a) + KnownScalar(b) => KnownScalar(a + b) | |
case KnownScalar(0.0) + e => e | |
case e + KnownScalar(0.0) => e | |
case (KnownScalar(d1) * e) + KnownScalar(d2) => KnownScalar(d1) * (e + KnownScalar(d2 / d1)) | |
case e1 + e2 => e1.simplify + e2.simplify | |
case _ => this | |
} | |
} | |
implicit def doubleToScalar(d: Double) = KnownScalar(d) | |
val seen = collection.mutable.Set.empty[Expr] | |
var last: Expr = ((1.1 < 'e1 |) + (2.2 < 'e2 |)) * (3.3 | 'e2 >) | |
while (!seen(last)) { | |
println(last) | |
seen += last | |
last = last.simplify | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment