Example #1
0
def compose(value, sample_args, context=None):
    """E.g., "Let f(x)=2x+1, let g(x)=3x+10. What is f(g(x))?"."""
    del value  # unused
    if context is None:
        context = composition.Context()

    entropy, sample_args = sample_args.peel()
    entropy_f, entropy_g = entropy * np.random.dirichlet([1, 1])

    coeffs_f = polynomials.sample_coefficients([random.randint(1, 2)],
                                               entropy_f)
    coeffs_g = polynomials.sample_coefficients([random.randint(1, 2)],
                                               entropy_g)

    entity_f, entity_g = context.sample(
        sample_args,
        [composition.Polynomial(coeffs_f),
         composition.Polynomial(coeffs_g)])

    variable = sympy.var(context.pop())

    poly_f = polynomials.coefficients_to_polynomial(coeffs_f, variable)
    poly_g = polynomials.coefficients_to_polynomial(coeffs_g, variable)

    poly_f_g = poly_f.sympy().subs(variable, poly_g.sympy()).expand()

    expression = composition.FunctionHandle(entity_f, entity_g).apply(variable)

    template = random.choice(_TEMPLATES)
    return example.Problem(question=example.question(context,
                                                     template,
                                                     composed=expression),
                           answer=poly_f_g)
Example #2
0
def coefficient_named(value, sample_args, context=None):
    """E.g., "Express x^2 + 2x in the form h * x^2 + k * x + t and give h."."""
    del value  # not used
    if context is None:
        context = composition.Context()
    variable = sympy.Symbol(context.pop())

    entropy, sample_args = sample_args.peel()
    degree = random.randint(1, 4)
    if random.choice([False, True]):
        coefficients = polynomials.sample_coefficients(
            degree,
            entropy / 2,
            min_non_zero=random.randint(degree - 1, degree))
        expanded = polynomials.expand_coefficients(coefficients, entropy / 2)
        expression = polynomials.coefficients_to_polynomial(expanded, variable)
    else:
        expression = polynomials.sample_with_brackets(variable, degree,
                                                      entropy)
        coefficients = list(reversed(sympy.Poly(expression).all_coeffs()))

    named_coeffs = [sympy.Symbol(context.pop()) for _ in range(degree + 1)]
    canonical = polynomials.coefficients_to_polynomial(named_coeffs, variable)

    if random.random() < 0.2:  # only small probability of non-zero power
        power = random.randint(0, degree)
    else:
        non_zero_powers = [
            i for i in range(degree + 1) if coefficients[i] != 0
        ]
        power = random.choice(non_zero_powers)

    value = coefficients[power]
    named_coeff = named_coeffs[power]

    template = random.choice([
        'Выразите {expression} в форме {canonical} и найдите {target}.',
        'Преобразуйте {expression} в форму {canonical} и найдите {target}.',
        # 'Express {expression} in the form {canonical} and give {target}.',
        # 'Rearrange {expression} to the form {canonical} and give {target}.',
    ])
    return example.Problem(question=example.question(context,
                                                     template,
                                                     expression=expression,
                                                     canonical=canonical,
                                                     target=named_coeff),
                           answer=value)
 def testMultivariate(self):
   # Test generation for: x**2 + 2*x*y + 3*y**2 - x + 5
   x, y = sympy.symbols('x y')
   coeffs = [[5, 0, 3], [-1, 2, 0], [1, 0, 0]]
   for _ in range(10):
     expanded = polynomials.expand_coefficients(coeffs, 5.0, length=10)
     polynomial = polynomials.coefficients_to_polynomial(expanded, [x, y])
     sympified = sympy.sympify(polynomial)
     self.assertEqual(sympified, x*x + 2*x*y + 3*y*y - x + 5)
 def testUnivariate(self):
   # Test generation for: x**2 + 2*x + 1
   x = sympy.Symbol('x')
   coeffs = [1, 2, 3]
   for _ in range(10):
     expanded = polynomials.expand_coefficients(coeffs, 5.0)
     polynomial = polynomials.coefficients_to_polynomial(expanded, [x])
     sympified = sympy.sympify(polynomial)
     self.assertEqual(sympified, 1 + 2*x + 3*x*x)
Example #5
0
def collect(value, sample_args, context=None):
    """Collect terms in an unsimplified polynomial."""
    is_question = context is None
    if context is None:
        context = composition.Context()

    entropy, sample_args = sample_args.peel()
    if value is None:
        entropy_value, entropy = entropy * np.random.dirichlet([2, 3])
        degrees = [random.randint(1, 3)]
        value = composition.Polynomial(
            polynomials.sample_coefficients(degrees, entropy_value))

    assert isinstance(value, composition.Polynomial)
    coefficients = value.coefficients

    all_coefficients_are_integer = True
    for coeff in coefficients.flat:
        if not number.is_integer(coeff):
            all_coefficients_are_integer = False
            break

    if all_coefficients_are_integer:
        coefficients = polynomials.expand_coefficients(coefficients, entropy)
    else:
        # put back the unused entropy
        sample_args = composition.SampleArgs(sample_args.num_modules,
                                             sample_args.entropy + entropy)

    num_variables = coefficients.ndim
    variables = [sympy.Symbol(context.pop()) for _ in range(num_variables)]
    unsimplified = polynomials.coefficients_to_polynomial(
        coefficients, variables)
    simplified = unsimplified.sympy().expand()

    # Bit of a hack: handle the very rare case where no number constants appearing
    if not ops.number_constants(unsimplified):
        unsimplified = ops.Add(unsimplified, ops.Constant(0))
    context.sample_by_replacing_constants(sample_args, unsimplified)

    if is_question:
        template = 'Упростите {unsimplified}.'
        return example.Problem(question=example.question(
            context, template, unsimplified=unsimplified),
                               answer=simplified)
    else:
        function_symbol = context.pop()
        function = sympy.Function(function_symbol)(*variables)
        return composition.Entity(
            context=context,
            value=value,
            handle=composition.FunctionHandle(function_symbol),
            expression=unsimplified,
            polynomial_variables=variables,
            description='Пусть {function} = {unsimplified}.',
            function=function,
            unsimplified=unsimplified)
 def testPolynomialRoots(self):
     variable = sympy.Symbol('x')
     for _ in range(10):
         roots = random.sample(list(range(-9, 10)), 3)
         coeffs = algebra._polynomial_coeffs_with_roots(roots,
                                                        scale_entropy=10.0)
         polynomial = polynomials.coefficients_to_polynomial(
             coeffs, variable)
         calc_roots = sympy.polys.polytools.real_roots(polynomial)
         self.assertEqual(calc_roots, sorted(roots))
Example #7
0
def add(value, sample_args, context=None):
    """E.g., "Let f(x)=2x+1, g(x)=3x+2. What is 5*f(x) - 7*g(x)?"."""
    is_question = context is None
    if context is None:
        context = composition.Context()

    entropy, sample_args = sample_args.peel()

    if value is None:
        max_degree = 3
        degree = random.randint(1, max_degree)
        entropy -= math.log10(max_degree)
        entropy_value = entropy / 2
        entropy -= entropy_value
        value = polynomials.sample_coefficients(degree,
                                                entropy=entropy_value,
                                                min_non_zero=random.randint(
                                                    1, 3))
        value = composition.Polynomial(value)

    c1, c2, coeffs1, coeffs2 = polynomials.coefficients_linear_split(
        value.coefficients, entropy)
    coeffs1 = polynomials.trim(coeffs1)
    coeffs2 = polynomials.trim(coeffs2)

    c1, c2, fn1, fn2 = context.sample(sample_args, [
        c1, c2,
        composition.Polynomial(coeffs1),
        composition.Polynomial(coeffs2)
    ])

    var = sympy.var(context.pop())

    expression = (c1.handle * fn1.handle.apply(var) +
                  c2.handle * fn2.handle.apply(var))

    if is_question:
        answer = polynomials.coefficients_to_polynomial(
            value.coefficients, var)
        answer = answer.sympy()
        template = random.choice(_TEMPLATES)
        return example.Problem(question=example.question(context,
                                                         template,
                                                         composed=expression),
                               answer=answer)
    else:
        intermediate_symbol = context.pop()
        intermediate = sympy.Function(intermediate_symbol)(var)
        return composition.Entity(
            context=context,
            value=value,
            description='Пусть {intermediate} = {composed}.',
            handle=composition.FunctionHandle(intermediate_symbol),
            intermediate=intermediate,
            composed=expression)
def _polynomial_entity(value, context):
    """Create a generic `Entity` describing a polynomial."""
    assert isinstance(value, Polynomial)
    coefficients = np.asarray(value.coefficients)
    num_variables = coefficients.ndim
    variables = [sympy.Symbol(context.pop()) for _ in range(num_variables)]
    function_symbol = context.pop()
    handle = FunctionHandle(function_symbol)
    handle_description = sympy.Function(function_symbol)(*variables)

    polynomial = polynomials.coefficients_to_polynomial(
        coefficients, variables)
    polynomial = polynomial.sympy()

    return Entity(context=context,
                  value=value,
                  expression=polynomial,
                  polynomial_variables=variables,
                  description='Пусть {function} = {polynomial}.',
                  handle=handle,
                  function=handle_description,
                  polynomial=polynomial)
 def testCoefficientsToPolynomial(self):
   coeffs = [3, 2, 1]
   x = sympy.Symbol('x')
   polynomial = polynomials.coefficients_to_polynomial(coeffs, [x])
   polynomial = sympy.sympify(polynomial)
   self.assertEqual(polynomial, x*x + 2*x + 3)
Example #10
0
def _differentiate_polynomial(value, sample_args, context, num_variables):
    """Generates a question for differentiating a polynomial."""
    is_question = context is None
    if context is None:
        context = composition.Context()

    if value is not None:
        num_variables = value.coefficients.ndim

    entropy, sample_args = sample_args.peel()
    max_derivative_order = 3
    derivative_order = random.randint(1, max_derivative_order)
    entropy = max(0, entropy - math.log10(max_derivative_order))

    derivative_axis = random.randint(0, num_variables - 1)
    if value is None:
        coefficients = _generate_polynomial(num_variables, entropy,
                                            derivative_order, derivative_axis)
    else:
        coefficients = _sample_integrand(value.coefficients, derivative_order,
                                         derivative_axis, entropy)

    (entity, ) = context.sample(sample_args,
                                [composition.Polynomial(coefficients)])

    value = coefficients
    for _ in range(derivative_order):
        value = polynomials.differentiate(value, axis=derivative_axis)
    nth = display.StringOrdinal(derivative_order)
    nth_fem = display.StringOrdinal_fem(derivative_order)
    nth_fem_gen = display.StringOrdinal_fem_gen(derivative_order)

    if entity.has_expression():
        polynomial = entity.expression
        variables = entity.polynomial_variables
    else:
        variables = [sympy.Symbol(context.pop()) for _ in range(num_variables)]
        polynomial = entity.handle.apply(*variables)
    variable = variables[derivative_axis]

    if is_question:
        template = _template(context.module_count, derivative_order,
                             len(variables))
        answer = polynomials.coefficients_to_polynomial(value,
                                                        variables).sympy()
        return example.Problem(question=example.question(
            context,
            template,
            eq=polynomial,
            var=variable,
            nth=nth,
            nth_fem=nth_fem,
            nth_fem_gen=nth_fem_gen),
                               answer=answer)
    else:
        fn_symbol = context.pop()
        variables_string = ', '.join(str(variable) for variable in variables)
        assert len(
            variables) == 1  # since below we don't specify var we diff wrt
        return composition.Entity(
            context=context,
            value=composition.Polynomial(value),
            description=
            'Пусть {fn}({variables}) - это {nth_fem} производная функции {eq}.',
            handle=composition.FunctionHandle(fn_symbol),
            fn=fn_symbol,
            variables=variables_string,
            nth=nth,
            nth_fem=nth_fem,
            nth_fem_gen=nth_fem_gen,
            eq=polynomial)