Esempio n. 1
0
        private bool solve_phase(int item_count, int num_vars, ref int iterations)
        {
            int    art_var_index   = num_vars - 2;
            bool   use_Blands_rule = false;
            double increase        = 0.0;

            while (true)
            {
                sparse_matrix.multiply(ref _z, _cB, _B_inv);
                sparse_matrix.multiply(ref _z_c, _z, _N);
                sparse_matrix.subtract(_z_c, _cN);
                _z_c.zero_roundoff_errors();
                sparse_matrix.multiply(ref _result, _B_inv, _b);
                _result.zero_roundoff_errors();

                int      entering_var  = -1;
                double   min_neg_coeff = 0.0;
                double[] z_c_ref       = _z_c[0];
                if (use_Blands_rule)
                {
                    for (int cur_var = 0; cur_var < item_count; ++cur_var)
                    {
                        if (z_c_ref[cur_var] < 0.0 && (_vN[cur_var] < art_var_index || _vN[cur_var] >= num_vars))
                        {
                            min_neg_coeff = z_c_ref[cur_var];
                            entering_var  = cur_var;
                            break;
                        }
                    }
                }
                else
                {
                    for (int cur_var = 0; cur_var < item_count; ++cur_var)
                    {
                        if (min_neg_coeff > z_c_ref[cur_var] && (_vN[cur_var] < art_var_index || _vN[cur_var] >= num_vars))
                        {
                            min_neg_coeff = z_c_ref[cur_var];
                            entering_var  = cur_var;
                        }
                    }
                }
                if (entering_var < 0)
                {
                    if (engine_control_unit.CALIBRATION_DEBUG)
                    {
                        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");
                            _z.log("cB * B^-1");
                            _z_c.log("cB * B^-1 * N - cN");
                            _result.log("B^-1 * b");
                        }
                        MyLog.Default.WriteLine("<< FINISHED >>");
                        sparse_matrix.multiply(ref _total, _cB, _result);
                        MyLog.Default.WriteLine(string.Format("Iteration = {0}; total = {1}", iterations, _total[0][0]));
                    }
                    return(true);
                }

                _entering_column.column_vector_from(_N, entering_var);
                sparse_matrix.multiply(ref _dividers, _B_inv, _entering_column);
                _dividers.zero_roundoff_errors();
                double min_ratio = double.MaxValue, cur_ratio;
                int    leaving_var = -1;
                for (int cur_var = 0; cur_var < num_vars; ++cur_var)
                {
                    if (_dividers[cur_var][0] > 0.0 && _result[cur_var][0] >= 0.0)
                    {
                        cur_ratio = _result[cur_var][0] / _dividers[cur_var][0];
                        if (min_ratio > cur_ratio)
                        {
                            min_ratio   = cur_ratio;
                            leaving_var = cur_var;
                        }
                    }
                }
                if (leaving_var < 0)
                {
                    MyLog.Default.WriteLine("<< ABORTED >>");
                    sparse_matrix.multiply(ref _total, _cB, _result);
                    log_var("Entering", _vN[entering_var], num_vars);
                    MyLog.Default.WriteLine(string.Format("Iteration = {0}; total = {1}", iterations, _total[0][0]));
                    return(false);
                }

                increase -= min_neg_coeff * min_ratio;
                if (engine_control_unit.CALIBRATION_DEBUG)
                {
                    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");
                        _z.log("cB * B^-1");
                        _z_c.log("cB * B^-1 * N - cN");
                        _result.log("B^-1 * b");
                        _dividers.log("B^-1 * N[e]");
                    }
                    log_var("Entering", _vN[entering_var], num_vars);
                    log_var("Leaving", _vB[leaving_var], num_vars);
                    sparse_matrix.multiply(ref _total, _cB, _result);
                    MyLog.Default.WriteLine(string.Format("Iteration = {2}; increase = {0}; Bland's rule = {1}; total = {3}", -min_neg_coeff * min_ratio, use_Blands_rule, iterations, _total[0][0] - min_neg_coeff * min_ratio));
                }
                if ((iterations & 3) == 3)
                {
                    use_Blands_rule = increase < EPSILON;
                    increase        = 0.0;
                }
                bool singular_B = !perform_pivot(num_vars, entering_var, leaving_var, iterations++);
                if (singular_B)
                {
                    MyLog.Default.WriteLine("<< SINGULAR >>");
                    _cB.log("cB");
                    _cN.log("cN");
                    _B.log("B");
                    _N.log("N");
                    return(false);
                }
            }
        }
Esempio n. 2
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);
        }