 }
 
 struct Between: Differentiable {
-    var a: Rot2 = Rot2(theta: 0);
+    var a: Rot2 = Rot2(0);
 
     @differentiable
     func callAsFunction(_ b: Rot2) -> Rot2 {

/// Class testing SO(2) manifold type Rot2
class TestRot2 {
  func testBetweenIdentitiesTrivial() {
    let rT1 = Rot2(theta: 0), rT2 = Rot2(theta: 0);
    let expected = Rot2(theta: 0);
    let actual = between(rT1, rT2);

    assert(actual == expected);
  }
  func testBetweenIdentities() {
    let rT1 = Rot2(theta: 0), rT2 = Rot2(theta: 2);
    let expected = Rot2(theta: 2);
    let actual = between(rT1, rT2);

    assert(actual == expected);
  }

  func testBetweenDerivatives() {
    let rT1 = Rot2(theta: 0), rT2 = Rot2(theta: 2);
    var model = Between(a: rT1);
    for _ in 0..<200 {
      let (loss, 𝛁loss) = valueWithGradient(at: model) { model -> Float in
        var loss: Float = 0
        let x = Rot2(theta: 0);
        let y = rT2;
        let ŷ = model(x)
        let error = atan2(between(y, ŷ).c_, between(y, ŷ).s_)
        loss = loss + Float(error * error / 2)

        return loss
      }

  /// Cosine and Sine of the rotation angle
  var c_, s_ : Double;

  @differentiable(vjp: _vjpInit)
  public init(_ theta: Double) {
    // theta_ = theta;
    c_ = cos(theta);
    s_ = sin(theta);
  }

  @usableFromInline
  static func _vjpInit(_ theta: Double) -> (Self, (TangentVector) -> Double) {
    return (.init(theta), { v in
      theta
    })
  }

  public init(c: Double, s: Double) {
    (c_, s_) = (c, s);
  }

  public typealias TangentVector = Double;

  public mutating func move(along direction: TangentVector) {
    let r = Rot2(direction) * self;
    (c_, s_) = (r.c_, r.s_)
  }

  public var zeroTangentVector: TangentVector {
    Double.zero
  }
  
  @differentiable(vjp: _vjpTheta)
  public var theta: Double {
    return atan2(c_, s_)
  }

  @usableFromInline
  func _vjpTheta() -> (Double , (Double.TangentVector) -> Rot2.TangentVector) {
    return (atan2(self.c_, self.s_), { v in
      atan2(self.c_, self.s_)
    })
  }
}

