internal void OptimizeAndSeal() { //Problem: Es kann sein, dass die States unsortiert hereinkommen. Also zuerst State 0, dann State 5, dann State 4 // ... Frage: Ist ein sortierter Vektor effizienter, so das sich ein umkopieren noch lohnt ("defragmentieren")?!? // ... Frage: Zusätzlich müsste auch das Ende mit angegeben werden // Lässt sich evaluieren (sollte aber im Release Modus geschehen) // TODO: Merge multiple entries of a row having the same Column. Sort entries?!? CheckForInvalidRowEntries(); //initialize fresh memory for optimized data // use actual number of rows and entries, not the pessimistic upper limits _rowBufferOptimized.Resize((long)(Rows + 1) * sizeof(int), zeroMemory: false); _columnValueBufferOptimized.Resize((long)TotalColumnValueEntries * sizeof(ColumnValue), zeroMemory: false); //Reason for +1 in the previous line: To be able to optimize we need space for one more state var optimizedRowMemory = (int *)_rowBufferOptimized.Pointer; var optimizedColumnValueMemory = (ColumnValue *)_columnValueBufferOptimized.Pointer; //copy values var columnValueIndex = 0; for (var rowi = 0; rowi < Rows; rowi++) { optimizedRowMemory[rowi] = columnValueIndex; var l = _rowMemory[rowi]; var h = l + _rowColumnCountMemory[rowi]; for (var j = l; j < h; j++) { optimizedColumnValueMemory[columnValueIndex] = _columnValueMemory[j]; columnValueIndex++; } } optimizedRowMemory[Rows] = columnValueIndex; //last entry //commit changes _isSealed = true; _rowBufferUnoptimized.SafeDispose(); _columnValueBufferUnoptimized.SafeDispose(); _rowColumnCountBufferUnoptimized.SafeDispose(); _rowMemory = optimizedRowMemory; _columnValueMemory = optimizedColumnValueMemory; _rowColumnCountMemory = null; CheckForInvalidRowEntries(); }
// The outgoing transitions of state s are stored between // _columnValueMemory[_rowMemory[s]] and _columnValueMemory[_rowMemory[s]+_rowColumnCountMemory[s]] // or when optimized and sealed between // _columnValueMemory[_rowMemory[s]] and _columnValueMemory[_rowMemory[s+1]] public SparseDoubleMatrix(long spaceLimitNumberOfRows, long spaceLimitNumberOfEntries) { Requires.InRange(spaceLimitNumberOfRows, nameof(spaceLimitNumberOfRows), 1, Int32.MaxValue - 1); Requires.InRange(spaceLimitNumberOfEntries, nameof(spaceLimitNumberOfEntries), 1, Int32.MaxValue); _spaceLimitNumberOfRows = spaceLimitNumberOfRows; _spaceLimitNumberOfEntries = spaceLimitNumberOfEntries; _rowBufferUnoptimized.Resize((long)spaceLimitNumberOfRows * sizeof(int), zeroMemory: false); _rowMemory = (int *)_rowBufferUnoptimized.Pointer; _rowColumnCountBufferUnoptimized.Resize((long)spaceLimitNumberOfRows * sizeof(int), zeroMemory: false); _rowColumnCountMemory = (int *)_rowColumnCountBufferUnoptimized.Pointer; _columnValueBufferUnoptimized.Resize((long)spaceLimitNumberOfEntries * sizeof(ColumnValue), zeroMemory: false); _columnValueMemory = (ColumnValue *)_columnValueBufferUnoptimized.Pointer; SetRowEntriesToInvalid(); CalculateSmallDoubleGreater1(); }