/// <summary>
        ///
        /// </summary>
        /// <param name="other"></param>
        /// <param name="tolerance"></param>
        /// <returns></returns>
        public bool ApproxEquals(ref Matrix4d other, double tolerance = SlurMath.ZeroTolerance)
        {
            return
                (SlurMath.ApproxEquals(M00, other.M00, tolerance) &&
                 SlurMath.ApproxEquals(M01, other.M01, tolerance) &&
                 SlurMath.ApproxEquals(M02, other.M02, tolerance) &&
                 SlurMath.ApproxEquals(M03, other.M03, tolerance) &&

                 SlurMath.ApproxEquals(M10, other.M10, tolerance) &&
                 SlurMath.ApproxEquals(M11, other.M11, tolerance) &&
                 SlurMath.ApproxEquals(M12, other.M12, tolerance) &&
                 SlurMath.ApproxEquals(M13, other.M13, tolerance) &&

                 SlurMath.ApproxEquals(M20, other.M20, tolerance) &&
                 SlurMath.ApproxEquals(M21, other.M21, tolerance) &&
                 SlurMath.ApproxEquals(M22, other.M22, tolerance) &&
                 SlurMath.ApproxEquals(M23, other.M23, tolerance) &&

                 SlurMath.ApproxEquals(M30, other.M30, tolerance) &&
                 SlurMath.ApproxEquals(M31, other.M31, tolerance) &&
                 SlurMath.ApproxEquals(M32, other.M32, tolerance) &&
                 SlurMath.ApproxEquals(M33, other.M33, tolerance));
        }
        /// <summary>
        /// Returns true on success
        /// </summary>
        public bool Invert(out Matrix4d result)
        {
            // inversion via cofactors
            // https://en.wikipedia.org/wiki/Minor_(linear_algebra)

            var d = Determinant;

            if (d > 0.0)
            {
                d = 1.0 / d;

                result.M00 = Minor00 * d;
                result.M01 = -Minor10 * d;
                result.M02 = Minor20 * d;
                result.M03 = -Minor30 * d;

                result.M10 = -Minor01 * d;
                result.M11 = Minor11 * d;
                result.M12 = -Minor21 * d;
                result.M13 = Minor31 * d;

                result.M20 = Minor02 * d;
                result.M21 = -Minor12 * d;
                result.M22 = Minor22 * d;
                result.M23 = -Minor32 * d;

                result.M30 = -Minor03 * d;
                result.M31 = Minor13 * d;
                result.M32 = -Minor23 * d;
                result.M33 = Minor33 * d;

                return(true);
            }

            result = Identity;
            return(false);
        }
 /// <summary>
 /// Applies this transformation to the given transformation in place.
 /// </summary>
 /// <param name="vector"></param>
 /// <returns></returns>
 public void Apply(ref Matrix4d other)
 {
     Apply(ref other, ref other);
 }
 /// <summary>
 /// Applies this transformation to the given transformation.
 /// </summary>
 /// <param name="vector"></param>
 /// <returns></returns>
 public Matrix4d Apply(Matrix4d other)
 {
     Apply(ref other, ref other);
     return(other);
 }