private void fill_matrices(int item_count) { int num_vars = item_count + 2; if (item_count != _last_item_count) { _vB = new int[num_vars]; _vN = new int[item_count]; _last_item_count = item_count; } int[] vB = _vB, vN = _vN; List <solver_entry> items = this.items; _E.set_to_identity(num_vars); _cB.clear(1, num_vars); _cN.clear(1, item_count); _B.set_to_identity(num_vars); _B_inv.clear(num_vars); _N.clear(num_vars, item_count); _b.clear(num_vars, 1); //_B_inv.set_to_identity(num_vars); _z.clear(1, num_vars); _z_c.clear(1, item_count); _result.clear(num_vars, 1); _entering_column.clear(num_vars, 1); _dividers.clear(num_vars, 1); sparse_row_ref B0_ref = _B[0], B1_ref = _B[1]; int cur_index; for (int cur_item = 0; cur_item < item_count; ++cur_item) { cur_index = cur_item + 2; vB [cur_index] = cur_item; vN [cur_item] = cur_item + num_vars; B0_ref[cur_index] = items[cur_item].x; B1_ref[cur_index] = items[cur_item].y; _N[cur_index][cur_item] = 1.0; _b[cur_index][0] = items[cur_item].max_value; } vB[0] = item_count; vB[1] = item_count + 1; }
private bool solve(int item_count) { int num_vars = item_count + 2; bool singular_B; fill_matrices(item_count); sparse_row_ref cN_ref = _cN[0], cB_ref = _cB[0]; cB_ref[0] = cB_ref[1] = -1.0; _B_inv.copy_from(_B); singular_B = !sparse_matrix.invert(ref _B_inv, ref _E); if (singular_B) { return(false); } _B_inv.purge_zeroes(); sparse_matrix.multiply(ref _result, _B_inv, _b); _result.zero_roundoff_errors(); if (engine_control_unit.FULL_CALIBRATION_DEBUG) { sparse_matrix.multiply(ref _E, _B, _B_inv); _E.log("E"); _E.set_to_identity(); _cB.log("cB"); _cN.log("cN"); _B.log("B"); _N.log("N"); _B_inv.log("B^-1"); _result.log("B^-1 * b"); sparse_matrix.multiply(ref _total, _cB, _result); _total.log("Total"); MyLog.Default.WriteLine(string.Format("Total = {0}", _total[0][0])); } bool reinvert_B = false; for (int art_var = 0; art_var <= 1; ++art_var) { if (_result[art_var][0] < 0.0) { sparse_row_ref B_row_ref = _B[art_var]; for (int cur_column = 2; cur_column < num_vars; ++cur_column) { B_row_ref[cur_column] = -B_row_ref[cur_column]; } reinvert_B = true; } } if (reinvert_B) { _B_inv.copy_from(_B); singular_B = !sparse_matrix.invert(ref _B_inv, ref _E); if (singular_B) { return(false); } _B_inv.purge_zeroes(); } int num_iterations = 1; bool initial_BFS_present = solve_phase(item_count, num_vars, ref num_iterations); if (!initial_BFS_present) { return(false); } sparse_matrix.multiply(ref _total, _cB, _result); if (_total[0][0] < -EPSILON) { return(false); } initial_BFS_present = remove_artificial_variables(ref item_count, num_vars, ref num_iterations); if (!initial_BFS_present) { return(false); } for (int cur_var = 0; cur_var < item_count; ++cur_var) { cN_ref[cur_var] = (_vN[cur_var] >= num_vars) ? 0.0 : 1.0; } for (int cur_var = 0; cur_var < num_vars; ++cur_var) { cB_ref[cur_var] = (_vB[cur_var] >= num_vars) ? 0.0 : 1.0; } return(solve_phase(item_count, num_vars, ref num_iterations)); }