Exemplo n.º 1
0
 def check_response(self, answer, student_input, **kwargs):
     try:
         with MathArray.enable_negative_powers(self.config['negative_powers']):
             result = super(MatrixGrader, self).check_response(answer, student_input, **kwargs)
     except ShapeError as err:
         if self.config['suppress_matrix_messages']:
             return {'ok': False, 'msg': '', 'grade_decimal': 0}
         elif self.config['shape_errors']:
             raise
         else:
             return {'ok': False, 'msg': err.message, 'grade_decimal': 0}
     except InputTypeError as err:
         if self.config['suppress_matrix_messages']:
             return {'ok': False, 'msg': '', 'grade_decimal': 0}
         elif self.config['answer_shape_mismatch']['is_raised']:
             raise
         else:
             return {'ok': False, 'grade_decimal': 0, 'msg': err.message}
     except (ArgumentShapeError, MathArrayError) as err:
         # If we're using matrix quantities for noncommutative scalars, we
         # might get an ArgumentShapeError from using functions of matrices,
         # or a MathArrayError from taking a funny power of a matrix.
         # Suppress these too.
         if self.config['suppress_matrix_messages']:
             return {'ok': False, 'msg': '', 'grade_decimal': 0}
         raise
     return result
Exemplo n.º 2
0
        def random_function(*args):
            """Function that generates the random values"""
            # Check that the dimensions are correct
            if len(args) != input_dim:
                msg = "Expected {} arguments, but received {}".format(
                    input_dim, len(args))
                raise ConfigError(msg)

            # Turn the inputs into an array
            xvec = np.array(args)
            # Repeat it into the shape of A, B and C
            xarray = np.tile(xvec, (output_dim, num_terms, 1))
            # Compute the output matrix
            output = A * np.sin(B * xarray + C)
            # Sum over the j and k terms
            # We have an old version of numpy going here, so we can't use
            # fullsum = np.sum(output, axis=(1, 2))
            fullsum = np.sum(np.sum(output, axis=2), axis=1)

            # Scale and translate to fit within center and amplitude
            fullsum = fullsum * self.config["amplitude"] / self.config[
                "num_terms"]
            fullsum += self.config["center"]

            # Return the result
            return MathArray(fullsum) if output_dim > 1 else fullsum[0]
Exemplo n.º 3
0
    def gen_sample(self):
        """
        Generates an array sample and returns it as a MathArray.

        This calls generate_sample, which is the routine that should be subclassed if
        needed, rather than this one.
        """
        array = self.generate_sample()
        return MathArray(array)
Exemplo n.º 4
0
 def gen_sample(self):
     """
     Generates an identity matrix of specified dimension multiplied by a random scalar
     """
     # Sample the multiplicative constant
     scaling = self.config['sampler'].gen_sample()
     # Create the numpy matrix
     array = scaling * np.eye(self.config['dimension'])
     # Return the result as a MathArray
     return MathArray(array)
Exemplo n.º 5
0
 def gen_sample(self):
     """
     Generates a random matrix of shape and norm determined by config.
     """
     desired_norm = self.norm.gen_sample()
     # construct an array with entries in [-0.5, 0.5)
     array = np.random.random_sample(self.config['shape']) - 0.5
     actual_norm = np.linalg.norm(array)
     # convert the array to a matrix with desired norm
     return MathArray(array) * desired_norm / actual_norm
Exemplo n.º 6
0
    def validate_student_input_shape(student_input, expected_shape, detail):
        """
        Checks that student_input has expected_shape and raises a ShapeError
        if it does not.

        Arguments:
            student_input (number | MathArray): The numerically-sampled student
                input
            expected_shape (tuple): A numpy shape tuple
            detail (None|'shape'|'type') detail-level of ShapeError message
        """
        try:
            input_shape = student_input.shape
        except AttributeError:
            if isinstance(student_input, Number):
                input_shape = tuple()
            else:
                raise

        if expected_shape == input_shape:
            return True

        if detail is None:
            raise InputTypeError('')

        if detail == 'shape':
            expected = MathArray.get_description(expected_shape)
            received = MathArray.get_description(input_shape)
        else:
            expected = MathArray.get_shape_name(len(expected_shape))
            received = MathArray.get_shape_name(len(input_shape))

        if detail != 'shape' and expected == received:
            msg = ("Expected answer to be a {0}, but input is a {1} "
                   "of incorrect shape".format(expected, received))
        else:
            msg = ("Expected answer to be a {0}, but input is a {1}".format(
                expected, received))

        raise InputTypeError(msg)
Exemplo n.º 7
0
 def check_response(self, answer, student_input, **kwargs):
     try:
         with MathArray.enable_negative_powers(
                 self.config['negative_powers']):
             result = super(MatrixGrader,
                            self).check_response(answer, student_input,
                                                 **kwargs)
     except ShapeError as err:
         if self.config['shape_errors']:
             raise
         else:
             return {'ok': False, 'msg': err.message, 'grade_decimal': 0}
     except InputTypeError as err:
         if self.config['answer_shape_mismatch']['is_raised']:
             raise
         else:
             return {'ok': False, 'grade_decimal': 0, 'msg': err.message}
     return result