Esempio n. 1
0
def test_core_numbers():
    for c in (Catalan, Catalan(), ComplexInfinity, ComplexInfinity(),
              EulerGamma, EulerGamma(), Exp1, Exp1(), GoldenRatio, GoldenRatio(),
              Half, Half(), ImaginaryUnit, ImaginaryUnit(), Infinity, Infinity(),
              Integer, Integer(2), NaN, NaN(), NegativeInfinity,
              NegativeInfinity(), NegativeOne, NegativeOne(), Number, Number(15),
              NumberSymbol, NumberSymbol(), One, One(), Pi, Pi(), Rational,
              Rational(1,2), Real, Real("1.2"), Zero, Zero()):
        check(c)
Esempio n. 2
0
def test_sympy__core__numbers__NaN():
    from sympy.core.numbers import NaN
    assert _test_args(NaN())
Esempio n. 3
0
def resolve_balance_sheet(x0: np.ndarray, eqs: List[Eq], plug_keys: Sequence[str],
                          subs_dict: Dict[IndexedBase, float], forecast_dates: pd.DatetimeIndex,
                          config: StatementsConfigManager,
                          sympy_namespace: Dict[str, IndexedBase], bs_diff_max: float,
                          balance_groups: List[Set[str]], timeout: float) -> Dict[IndexedBase, float]:
    plug_solutions = _x_arr_to_plug_solutions(x0, plug_keys, sympy_namespace)
    all_to_solve: Dict[IndexedBase, Expr] = {}
    for eq in eqs:
        expr = eq.rhs - eq.lhs
        if expr == NaN():
            raise InvalidForecastEquationException(f'got NaN forecast equation. LHS: {eq.lhs}, RHS: {eq.rhs}')
        if eq.lhs in all_to_solve:
            raise InvalidForecastEquationException(
                f'got multiple equations to solve for {eq.lhs}. Already had {all_to_solve[eq.lhs]}, now got {expr}'
            )
        all_to_solve[eq.lhs] = expr
    for sol_dict in [subs_dict, plug_solutions]:
        # Plug solutions second here so that they are at end of array
        for lhs, rhs in sol_dict.items():
            expr = rhs - lhs
            if expr == NaN():
                raise MissingDataException(f'got NaN for {lhs} but that is needed for resolving the forecast')
            if lhs in all_to_solve:
                existing_value = all_to_solve[lhs]
                if isinstance(existing_value, float):
                    had_message = f'forecast/plug value of {existing_value}'
                else:
                    had_message = f'equation of {existing_value}'
                raise InvalidForecastEquationException(
                    f'got forecast/plug value for {lhs} but already had an existing {had_message}, now got {expr}'
                )
            all_to_solve[lhs] = expr
    to_solve_for = list(all_to_solve.keys())
    solve_exprs = list(all_to_solve.values())
    _check_for_invalid_system_of_equations(eqs, subs_dict, plug_solutions, to_solve_for, solve_exprs)
    eq_arrs = _symbolic_to_matrix(solve_exprs, to_solve_for)

    # Get better initial x0 by adding to appropriate plug
    _adjust_x0_to_initial_balance_guess(x0, plug_keys, eq_arrs, forecast_dates, to_solve_for, config, balance_groups)

    result = PlugResult(timeout=timeout)
    res: Optional[OptimizeResult] = None
    try:
        res = minimize(
            _resolve_balance_sheet_check_diff,
            x0,
            args=(eq_arrs, forecast_dates, to_solve_for, bs_diff_max, balance_groups, result),
            bounds=[(0, None) for _ in range(len(x0))],  # all positive
            method='TNC',
            options=dict(
                maxCGit=0,
                maxfun=1000000000,
            )
        )
    except (BalanceSheetBalancedException, BalanceSheetNotBalancedException):
        pass
    if not result.met_goal:
        if result.fun is None or result.res is None:
            # Mainly for mypy purposes
            raise BalanceSheetNotBalancedException(
                'Unexpected balancing error. Did not evaluate the balancing function even once'
            )
        plug_solutions = _x_arr_to_plug_solutions(result.res, plug_keys, sympy_namespace)
        avg_error = (result.fun ** 2 / len(result.res)) ** 0.5
        message = (
            f'final solution {plug_solutions} still could not meet max difference of '
            f'${bs_diff_max:,.0f} within timeout of {result.timeout}s. '
            f'Average difference was ${avg_error:,.0f}.\nIf the make_forecast or plug '
            f'configuration for any items were changed, ensure that changes in {plug_keys} can flow through '
            f'to Total Assets and Total Liabilities and Equity. For example, if make_forecast=True for Total Debt '
            f'and make_forecast=False for ST Debt, then using LT debt as a plug will not work as ST debt will '
            f'go down when LT debt goes up.\nOtherwise, consider '
            f'passing to .forecast a timeout greater than {result.timeout}, '
            f'a bs_diff_max at a value greater than {avg_error:,.0f}, or pass '
            f'balance=False to skip balancing entirely.'
        )
        raise BalanceSheetNotBalancedException(message)
    else:
        logger.info(f'Balanced in {result.time_elapsed:.1f}s')
    plug_solutions = _x_arr_to_plug_solutions(result.res, plug_keys, sympy_namespace)
    solutions_dict = _solve_eqs_with_plug_solutions(
        eqs, plug_solutions, subs_dict, forecast_dates, config.items
    )
    return solutions_dict