static public void multiply(ref dense_matrix result, dense_matrix left, sparse_matrix right) { int left_height = left.rows, left_width = left.columns; if (left_width != right._height) { throw new ArgumentException("Operand size mismatch"); } Dictionary <int, double> right_row_ref; double[] left_row_ref, result_row_ref; double cur_element; result.clear(left_height, right._width); Dictionary <int, double>[] right_contents = right._contents; for (int cur_row = 0; cur_row < left_height; ++cur_row) { left_row_ref = left[cur_row]; result_row_ref = result[cur_row]; for (int sum_index = 0; sum_index < left_width; ++sum_index) { cur_element = left_row_ref[sum_index]; right_row_ref = right_contents[sum_index]; foreach (KeyValuePair <int, double> cur_horizontal in right_row_ref) { result_row_ref[cur_horizontal.Key] += cur_element * cur_horizontal.Value; } } } }
static public void multiply(ref dense_matrix result, sparse_matrix left, dense_matrix right) { int right_height = right.rows, right_width = right.columns; if (left._width != right_height) { throw new ArgumentException("Operand size mismatch"); } Dictionary <int, double> left_row_ref; double[] result_row_ref, right_row_ref; double cur_element; result.clear(left._height, right_width); int left_height = left._height; Dictionary <int, double>[] left_contents = left._contents; for (int cur_row = 0; cur_row < left_height; ++cur_row) { left_row_ref = left_contents[cur_row]; result_row_ref = result[cur_row]; foreach (KeyValuePair <int, double> cur_diagonal in left_row_ref) { cur_element = cur_diagonal.Value; right_row_ref = right[cur_diagonal.Key]; for (int cur_column = 0; cur_column < right_width; ++cur_column) { result_row_ref[cur_column] += cur_element * right_row_ref[cur_column]; } } } }
public void copy_from(sparse_matrix b) { clear(b._height, b._width); int height = _height; Dictionary <int, double>[] contents = _contents, source = b._contents; for (int cur_row = 0; cur_row < height; ++cur_row) { IDictionary <int, double> row_ref = contents[cur_row], src_row_ref = source[cur_row]; foreach (KeyValuePair <int, double> cur_element in src_row_ref) { row_ref.Add(cur_element); } } }
public static void exchange_columns(sparse_matrix a, int column_a, sparse_matrix b, int column_b) { if (a._height != b._height) { throw new ArgumentException("Row number mismatch"); } double a_value, b_value; bool non_zero_a, non_zero_b; Dictionary <int, double> a_row_ref, b_row_ref; int height = a._height; Dictionary <int, double>[] contents_a = a._contents, contents_b = b._contents; for (int cur_row = 0; cur_row < height; ++cur_row) { a_row_ref = contents_a[cur_row]; b_row_ref = contents_b[cur_row]; non_zero_a = a_row_ref.TryGetValue(column_a, out a_value); non_zero_b = b_row_ref.TryGetValue(column_b, out b_value); if (non_zero_a) { if (non_zero_b) { a_row_ref[column_a] = b_value; b_row_ref[column_b] = a_value; } else { b_row_ref.Add(column_b, a_value); a_row_ref.Remove(column_a); } } else if (non_zero_b) { a_row_ref.Add(column_a, b_value); b_row_ref.Remove(column_b); } } }
public static void subtract(dense_matrix minuend, sparse_matrix subtrahend) { if (minuend.columns != subtrahend._width || minuend.rows != subtrahend._height) { throw new ArgumentException("Attempt to subtract matrix of different size"); } double[] minuend_row_ref; Dictionary <int, double> subtrahend_row_ref; int height = subtrahend._height; Dictionary <int, double>[] subtrahend_contents = subtrahend._contents; for (int cur_row = 0; cur_row < height; ++cur_row) { minuend_row_ref = minuend[cur_row]; subtrahend_row_ref = subtrahend_contents[cur_row]; foreach (KeyValuePair <int, double> cur_element in subtrahend_row_ref) { minuend_row_ref[cur_element.Key] -= cur_element.Value; } } }
static public void multiply(ref sparse_matrix result, sparse_matrix left, sparse_matrix right) { if (left._width != right._height) { throw new ArgumentException("Operand size mismatch"); } Dictionary <int, double> result_row_ref, left_row_ref, right_row_ref; double cur_element; int cur_column; result.clear(left._height, right._width); int result_height = result._height; Dictionary <int, double>[] result_contents = result._contents, left_contents = left._contents, right_contents = right._contents; for (int cur_row = 0; cur_row < result_height; ++cur_row) { left_row_ref = left_contents[cur_row]; result_row_ref = result_contents[cur_row]; foreach (KeyValuePair <int, double> cur_diagonal in left_row_ref) { cur_element = cur_diagonal.Value; right_row_ref = right_contents[cur_diagonal.Key]; foreach (KeyValuePair <int, double> cur_horizontal in right_row_ref) { cur_column = cur_horizontal.Key; if (result_row_ref.ContainsKey(cur_column)) { result_row_ref[cur_column] += cur_element * cur_horizontal.Value; } else { result_row_ref.Add(cur_column, cur_element * cur_horizontal.Value); } } } } }
public void column_vector_from(sparse_matrix b, int column) { double value; bool non_zero; Dictionary <int, double> row_ref; clear(b._height, 1); int height = _height; Dictionary <int, double>[] contents = _contents, source = b._contents; for (int cur_row = 0; cur_row < height; ++cur_row) { row_ref = contents[cur_row]; non_zero = source[cur_row].TryGetValue(column, out value); if (non_zero) { row_ref[0] = value; } else if (row_ref.ContainsKey(0)) { row_ref.Remove(0); } } }
static public bool invert(ref sparse_matrix operand, ref sparse_matrix identity) { if (operand._width != operand._height || identity._width != identity._height || operand._height != identity._height) { throw new ArgumentException("Cannot invert non-square matrix"); } int operand_height = operand._height; Dictionary <int, double>[] operand_contents = operand._contents; for (int cur_item = 0; cur_item < operand_height; ++cur_item) { double cur_element; operand_contents[cur_item].TryGetValue(cur_item, out cur_element); double max_element = Math.Abs(cur_element), test_element, column_element; int max_row = cur_item; for (int cur_row = cur_item + 1; cur_row < operand_height; ++cur_row) { operand_contents[cur_row].TryGetValue(cur_item, out column_element); test_element = Math.Abs(column_element); if (test_element > max_element) { max_element = test_element; max_row = cur_row; } } if (max_row > cur_item) { operand.exchange_rows(cur_item, max_row); identity.exchange_rows(cur_item, max_row); } double divider, multiplier; operand_contents[cur_item].TryGetValue(cur_item, out divider); if (divider != 1.0) { if (divider >= -revised_simplex_solver.EPSILON && divider <= revised_simplex_solver.EPSILON) { MyLog.Default.WriteLine(string.Format("Singular column = {0}; PR = {1}", cur_item, max_row)); operand.log("O"); return(false); } operand.divide_row(cur_item, divider); operand_contents[cur_item][cur_item] = 1.0; identity.divide_row(cur_item, divider); } for (int cur_row = cur_item + 1; cur_row < operand_height; ++cur_row) { if (operand_contents[cur_row].TryGetValue(cur_item, out multiplier)) { operand.subtract_row(cur_row, cur_item, multiplier); operand_contents[cur_row].Remove(cur_item); identity.subtract_row(cur_row, cur_item, multiplier); } } } for (int cur_item = operand_height - 1; cur_item > 0; --cur_item) { double multiplier; for (int cur_row = 0; cur_row < cur_item; ++cur_row) { if (operand_contents[cur_row].TryGetValue(cur_item, out multiplier)) { operand_contents[cur_row].Remove(cur_item); identity.subtract_row(cur_row, cur_item, multiplier); } } } sparse_matrix temp = operand; operand = identity; identity = temp; return(true); }