 /// 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 rT1 = Rot2(0), rT2 = Rot2(0);
+    let expected = Rot2(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 rT1 = Rot2(0), rT2 = Rot2(2);
+    let expected = Rot2(2);
     let actual = between(rT1, rT2);
 
     assert(actual == expected);
   }
 
   func testBetweenDerivatives() {
-    let rT1 = Rot2(theta: 0), rT2 = Rot2(theta: 2);
+    let rT1 = Rot2(0), rT2 = Rot2(1);
     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);
+    for _ in 0..<400 {
+      let (loss, 𝛁loss) = valueWithGradient(at: model) { model -> Double in
+        var loss: Double = 0
+        let x = Rot2(0);
         let y = rT2;
         let ŷ = model(x)
-        let error = atan2(between(y, ŷ).c_, between(y, ŷ).s_)
-        loss = loss + Float(error * error / 2)
+        let error = between(y, ŷ).theta
+        loss = loss + (error * error / 2)
 
         return loss
       }

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

  @differentiable
  init(theta: Double) {
    // theta_ = theta;
    (c_, s_) = (cos(theta), sin(theta));
  }

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

  public typealias TangentVector = Double;

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

  public var zeroTangentVector: TangentVector {
    Double.zero
  }
}


    return (lhs.c_, lhs.s_) == (rhs.c_, rhs.s_);
  }

  @differentiable(vjp: _vjpMultiply(lhs:rhs:))
  static func * (lhs: Rot2, rhs: Rot2) -> Rot2 {
    return Rot2(
      c: lhs.c_ * rhs.c_ - lhs.s_ * rhs.s_,
      s: lhs.s_ * rhs.c_ + lhs.c_ * rhs.s_
    );
  }

  @inlinable
  static func _vjpMultiply(lhs: Rot2, rhs: Rot2) -> (Rot2, (Double) -> (Double, Double)) {
      return (lhs * rhs, { v in
          let lhsGrad = v
          let rhsGrad = v
          return (lhsGrad, rhsGrad)
      })
  }
}

@differentiable(vjp: _vjpInverse(r:))
public func inverse(_ r: Rot2) -> Rot2 {
  return Rot2(c: r.c_, s: -r.s_);
}

@inlinable
func _vjpInverse(r: Rot2) -> (Rot2, (Double) -> (Double)) {
    return (inverse(r), { v in
        let rGrad = -v
        return (rGrad)
    })
}

/// Calculate relative rotation between two rotations rT1 and rT2
