public static Quaternion cosh(Quaternion q) {
   Double3Vector imag = q.imag();
   final double imagNorm = imag.norm();
   return new Quaternion(
       ExtraMath.cosh(q.re) * Math.cos(imagNorm),
       (Double3Vector) imag.normalize().scalarMultiply(ExtraMath.sinh(q.re) * Math.sin(imagNorm)));
 }
 public static Quaternion exp(Quaternion q) {
   final double k = Math.exp(q.re);
   Double3Vector imag = q.imag();
   final double imagNorm = imag.norm();
   return new Quaternion(
       k * Math.cos(imagNorm),
       (Double3Vector) imag.normalize().scalarMultiply(k * Math.sin(imagNorm)));
 }
 /**
  * Returns the subtraction of this quaternion by an imaginary part.
  *
  * @param imag an imaginary part
  */
 public Quaternion subtractImag(final Double3Vector imag) {
   return new Quaternion(
       re, imi - imag.getComponent(0), imj - imag.getComponent(1), imk - imag.getComponent(2));
 }
 /** Constructs a quaternion. */
 public Quaternion(final double real, final Double3Vector imag) {
   re = real;
   imi = imag.getComponent(0);
   imj = imag.getComponent(1);
   imk = imag.getComponent(2);
 }
 /**
  * Returns the addition of this quaternion with an imaginary part.
  *
  * @param imag an imaginary part
  */
 public Quaternion addImag(final Double3Vector imag) {
   return new Quaternion(
       re, imi + imag.getComponent(0), imj + imag.getComponent(1), imk + imag.getComponent(2));
 }