/// <summary>
 /// Asset that this matrix
 /// </summary>
 /// <param name="storage"></param>
 private static void AssertIsNotReferenceMatrix(ManagedStorage <T> storage)
 {
     if (storage._storageStart != 0 || storage._stride != storage.RowCount)
     {
         throw Exceptions.OperationNotSupportedForReferenceMatrices();
     }
 }
        private void CopyRegionTo(ManagedStorage <T> target, MatrixRegion region)
        {
            switch (region)
            {
            case MatrixRegion.All:
                CopySubMatrixTo(target, 0, 0, RowCount, 0, 0, ColumnCount);
                break;

            case MatrixRegion.LowerTriangle:
                for (int i = 0; i < RowCount; ++i)
                {
                    for (int j = 0; j <= i; ++j)
                    {
                        target[i, j] = this[i, j];
                    }
                }
                break;

            case MatrixRegion.UpperTriangle:
                for (int i = 0; i < RowCount; ++i)
                {
                    for (int j = i; j < ColumnCount; ++j)
                    {
                        target[i, j] = this[i, j];
                    }
                }
                break;
            }
        }
        internal override NArrayStorage <T> Clone(MatrixRegion region = MatrixRegion.All)
        {
            if (RowCount != ColumnCount && region != MatrixRegion.All)
            {
                throw new ArgumentException("only square matrices can be upper or lower triangular");
            }
            var clone = new ManagedStorage <T>(RowCount, ColumnCount);

            CopyRegionTo(clone, region);
            return(clone);
        }
        internal override NArrayStorage <T> Transpose()
        {
            AssertIsNotReferenceMatrix(this);
            var transpose = new ManagedStorage <T>(ColumnCount, RowCount);

            for (int i = 0; i < RowCount; ++i)
            {
                for (int j = 0; j < ColumnCount; ++j)
                {
                    transpose[j, i] = this[i, j];
                }
            }
            return(transpose);
        }
        internal override NArrayStorage <T> Diagonal(int rowCount, int columnCount)
        {
            int minDimension = Math.Min(rowCount, columnCount);

            if (this.Length != minDimension)
            {
                throw new ArgumentException("diagonalArray must have length equal to the lesser of the row count and column count of matrixToFill");
            }
            var diagonal = new ManagedStorage <T>(rowCount, columnCount);

            for (int i = 0; i < minDimension; ++i)
            {
                diagonal[i, i] = this[i];
            }
            return(diagonal);
        }