public void Decompose(ObjectMatrix2D[][] parts, ObjectMatrix2D matrix) { CheckRectangularShape(parts); int rows = parts.Length; int columns = 0; if (parts.Length > 0) { columns = parts.GetLength(1); } if (rows == 0 || columns == 0) { return; } // determine maximum column width of each column int[] maxWidths = new int[columns]; for (int column = columns; --column >= 0;) { int maxWidth = 0; for (int row = rows; --row >= 0;) { ObjectMatrix2D part = parts[row][column]; if (part != null) { int width = part.Columns; if (maxWidth > 0 && width > 0 && width != maxWidth) { throw new ArgumentException("Different number of columns."); } maxWidth = System.Math.Max(maxWidth, width); } } maxWidths[column] = maxWidth; } // determine row height of each row int[] maxHeights = new int[rows]; for (int row = rows; --row >= 0;) { int maxHeight = 0; for (int column = columns; --column >= 0;) { ObjectMatrix2D part = parts[row][column]; if (part != null) { int height = part.Rows; if (maxHeight > 0 && height > 0 && height != maxHeight) { throw new ArgumentException("Different number of rows."); } maxHeight = System.Math.Max(maxHeight, height); } } maxHeights[row] = maxHeight; } // shape of result parts int resultRows = 0; for (int row = rows; --row >= 0;) { resultRows += maxHeights[row]; } int resultCols = 0; for (int column = columns; --column >= 0;) { resultCols += maxWidths[column]; } if (matrix.Rows < resultRows || matrix.Columns < resultCols) { throw new ArgumentException("Parts larger than matrix."); } // copy int r = 0; for (int row = 0; row < rows; row++) { int c = 0; for (int column = 0; column < columns; column++) { ObjectMatrix2D part = parts[row][column]; if (part != null) { part.Assign(matrix.ViewPart(r, c, part.Rows, part.Columns)); } c += maxWidths[column]; } r += maxHeights[row]; } }