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)
Exemple #2
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)

  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),
        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='Misalkan {fn} ({variables}) menjadi turunan ke-{nth} dari {eq}.',
        handle=composition.FunctionHandle(fn_symbol),
        fn=fn_symbol, variables=variables_string, nth=nth, eq=polynomial)
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='Misalkan {intermediate} = {composed}.',
            handle=composition.FunctionHandle(intermediate_symbol),
            intermediate=intermediate,
            composed=expression)
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 = 'Sederhanakan {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='Misalkan {function} = {unsimplified}.',
            function=function,
            unsimplified=unsimplified)
def evaluate(value, sample_args, context=None):
    """Entity for evaluating an integer-valued polynomial at a given point."""
    is_question = context is None
    if context is None:
        context = composition.Context()

    entropy, sample_args = sample_args.peel()

    if value is None:
        entropy_value = random.uniform(1, 1 + entropy / 3)
        entropy = max(0, entropy - entropy_value)
        value = number.integer(entropy_value, signed=True)

    entropy_input = random.uniform(1, 1 + entropy / 3)
    entropy = max(0, entropy - entropy_input)
    input_ = number.integer(entropy_input, signed=True)

    degree = random.randint(1, 3)

    entropies = entropy * np.random.dirichlet(list(range(1, degree + 1)))
    # Calculate coefficients in reverse order.
    target = value
    coeffs_reversed = []
    for i, coeff_entropy in enumerate(entropies):
        power = degree - i
        coeff = number.integer(coeff_entropy, signed=True)
        if input_ != 0:
            coeff += int(round(target / input_**power))
        if coeff == 0 and i == 0:
            # Don't allow zero in leading coefficient.
            coeff += random.choice([-1, 1])
        coeffs_reversed.append(coeff)
        target -= coeff * (input_**power)
    coeffs_reversed.append(target)

    coefficients = list(reversed(coeffs_reversed))

    (polynomial_entity,
     input_) = context.sample(sample_args,
                              [composition.Polynomial(coefficients), input_])
    composed = polynomial_entity.handle.apply(input_.handle)

    if is_question:
        template = random.choice(_TEMPLATES)
        return example.Problem(question=example.question(context,
                                                         template,
                                                         composed=composed),
                               answer=value)
    else:
        return composition.Entity(context=context,
                                  value=value,
                                  expression=composed,
                                  description='Misalkan {self} be {composed}.',
                                  composed=composed)
Exemple #6
0
def polynomial_roots(value, sample_args, context=None):
    """E.g., "Solve 2*x**2 - 18 = 0."."""
    del value  # not currently used
    # is_question = context is None
    if context is None:
        context = composition.Context()

    entropy, sample_args = sample_args.peel()
    scale_entropy = min(entropy / 2, 1)

    roots = _sample_roots(entropy - scale_entropy)
    solutions = sorted(list(sympy.FiniteSet(*roots)))
    coeffs = _polynomial_coeffs_with_roots(roots, scale_entropy)
    (polynomial_entity, ) = context.sample(sample_args,
                                           [composition.Polynomial(coeffs)])

    if random.choice([False, True]):
        # Ask for explicit roots.
        if len(solutions) == 1:
            answer = solutions[0]
        else:
            answer = display.NumberList(solutions)

        if polynomial_entity.has_expression():
            equality = ops.Eq(polynomial_entity.expression, 0)
            variable = polynomial_entity.polynomial_variables[0]
        else:
            variable = sympy.Symbol(context.pop())
            equality = ops.Eq(polynomial_entity.handle.apply(variable), 0)
        template = random.choice([
            'Misalkan {equality}. Berapakah {variable}?',
            'Misalkan {equality}. Hitung {variable}.',
            'Misalkan {equality}. Berapakah {variable}?',
            'Misalkan {equality}. Hitung {variable}.',
            'Berapakah {variable} dalam {equality}?',
            'Selesaikan {equality} untuk {variable}.',
            'Temukan {variable} sehingga {equality}.',
            'Temukan {variable}, mengingat {equality}.',
            'Tentukan {variable} sehingga {equality}.',
            'Tentukan {variable}, mengingat bahwa {equality}.',
            'Selesaikan {equality}.'
        ])
        return example.Problem(question=example.question(context,
                                                         template,
                                                         equality=equality,
                                                         variable=variable),
                               answer=answer)
    else:
        if polynomial_entity.has_expression():
            expression = polynomial_entity.expression
            variable = polynomial_entity.polynomial_variables[0]
        else:
            variable = sympy.Symbol(context.pop())
            expression = polynomial_entity.handle.apply(variable)
        factored = sympy.factor(
            polynomials.coefficients_to_polynomial(coeffs, variable))
        template = random.choice([
            'Faktor dari {expression}.',
        ])
        return example.Problem(question=example.question(
            context, template, expression=expression),
                               answer=factored)