private CompressionStats Compress( IGrid grid, ICompressor compressor, double[] errors, string outName, ProgressViewModel progressBar ) { double[] leftBorders = new double[grid.ColumnCount]; double[] rightBorders = new double[grid.ColumnCount]; var qs = new IQuantization[grid.ColumnCount]; var distrs = new IDistribution[grid.ColumnCount]; progressBar.Status = "Quantizing columns..."; Parallel.For( 0, grid.ColumnCount, column => { var distr = new EmpiricalDistribution( grid, column ); leftBorders[column] = double.MaxValue; rightBorders[column] = double.MinValue; for ( int row = 0; row < grid.RowCount; ++row ) { double value = grid.GetValue( row, column ); leftBorders[column] = leftBorders[column] < value ? leftBorders[column] : value; rightBorders[column] = rightBorders[column] > value ? rightBorders[column] : value; } var quantizer = new Quantizer( leftBorders[column], rightBorders[column] ); var quantization = quantizer.Quantize( errors[column], distr ); lock ( _lockGuard ) { progressBar.Progress += 1.0 / ( grid.ColumnCount + 1 ); distrs[column] = distr; qs[column] = quantization; } } ); var quantizations = new List<IQuantization>( qs ); var distributions = new List<IDistribution>( distrs ); progressBar.Status = "Writing archive..."; progressBar.Progress = ( double )grid.ColumnCount / ( grid.ColumnCount + 1 ); ICompressionResult result; using ( var stream = new FileOutputStream( outName ) ) { result = compressor.Compress( grid, quantizations, stream ); } progressBar.Progress = 1.0; progressBar.TryClose( ); return new CompressionStats { CompressionResult = result, Distributions = distributions, LeftBorders = leftBorders, RightBorders = rightBorders, Quantizations = quantizations }; }