/// <summary>
        /// Performs the operation: result = transpose(<paramref name="dense"/>) * <paramref name="other"/> * <paramref name="dense"/>
        /// in an efficient way, by appropriately selecting which methods should be called for these matrices and in what order.
        /// </summary>
        /// <param name="dense">The matrix that will be multiplied "outside".</param>
        /// <param name="other">The matrix that will be multiplied "inside". It must be square.</param>
        public static Matrix ThisTransposeTimesOtherTimesThis(this Matrix dense, IMatrixView other)
        { //TODO: Perhaps this should not be a separate method than the one where other is Matrix
            if (other is Matrix otherDense)
            {
                return(dense.ThisTransposeTimesOtherTimesThis(otherDense));
            }

            //TODO: perhaps I should dedice about the order of multiplications depending on the number of columns of each matrix
            Matrix temp = other.MultiplyRight(dense, false, false);

            return(dense.MultiplyRight(temp, true, false));
        }
 public static Matrix ThisTimesOtherTimesThisTranspose(this IMatrixView thisMatrix, IMatrixView other)
 {
     return(thisMatrix.MultiplyLeft(thisMatrix.MultiplyRight(other, false, false), true, false));
 }