Skip to content

Instantly share code, notes, and snippets.

@AlecZorab
Created August 28, 2012 23:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AlecZorab/3505149 to your computer and use it in GitHub Desktop.
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)
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