Пример #1
0
def assemble_scaling_matrix(scaling=True):
    """Create and return the per-model scaling matrices.

    @keyword scaling:           If True, diagonal scaling is enabled during optimisation to allow the problem to be better conditioned.
    @type scaling:              bool
    @return:                    The list of diagonal and square scaling matrices.
    @rtype:                     list of numpy rank-2, float64 array or list of None
    """

    # The specific analysis API object and parameter object.
    api = return_api()
    param_object = return_parameter_object()

    # Initialise.
    scaling_matrix = []

    # Loop over the models.
    for model_info in api.model_loop():
        # No diagonal scaling.
        if not scaling:
            scaling_matrix.append(None)
            continue

        # Get the parameter names.
        names = api.get_param_names(model_info)

        # No parameters for this model.
        if names == None or len(names) == 0:
            scaling_matrix.append(None)
            continue

        # The parameter number.
        n = len(names)

        # Initialise.
        scaling_matrix.append(identity(n, float64))
        i = 0

        # Update the diagonal with the parameter specific scaling factor.
        for i in range(n):
            scaling_matrix[-1][i,
                               i] = param_object.scaling(names[i],
                                                         model_info=model_info)

    # Return the matrix.
    return scaling_matrix
Пример #2
0
def assemble_scaling_matrix(scaling=True):
    """Create and return the per-model scaling matrices.

    @keyword scaling:           If True, diagonal scaling is enabled during optimisation to allow the problem to be better conditioned.
    @type scaling:              bool
    @return:                    The list of diagonal and square scaling matrices.
    @rtype:                     list of numpy rank-2, float64 array or list of None
    """

    # The specific analysis API object and parameter object.
    api = return_api()
    param_object = return_parameter_object()

    # Initialise.
    scaling_matrix = []

    # Loop over the models.
    for model_info in api.model_loop():
        # No diagonal scaling.
        if not scaling:
            scaling_matrix.append(None)
            continue

        # Get the parameter names.
        names = api.get_param_names(model_info)

        # No parameters for this model.
        if names == None or len(names) == 0:
            scaling_matrix.append(None)
            continue

        # The parameter number.
        n = len(names)

        # Initialise.
        scaling_matrix.append(identity(n, float64))
        i = 0

        # Update the diagonal with the parameter specific scaling factor.
        for i in range(n):
            scaling_matrix[-1][i, i] = param_object.scaling(names[i], model_info=model_info)

    # Return the matrix.
    return scaling_matrix
Пример #3
0
def grid_setup(lower=None,
               upper=None,
               inc=None,
               verbosity=1,
               skip_preset=True):
    """Determine the per-model grid bounds, allowing for the zooming grid search.

    @keyword lower:         The user supplied lower bounds of the grid search which must be equal to the number of parameters in the model.
    @type lower:            list of numbers
    @keyword upper:         The user supplied upper bounds of the grid search which must be equal to the number of parameters in the model.
    @type upper:            list of numbers
    @keyword inc:           The user supplied grid search increments.
    @type inc:              int or list of int
    @keyword verbosity:     The amount of information to print.  The higher the value, the greater the verbosity.
    @type verbosity:        int
    @keyword skip_preset:   This argument, when True, allows any parameter which already has a value set to be skipped in the grid search.
    @type skip_preset:      bool
    @return:                The per-model grid upper and lower bounds.  The first dimension of each structure corresponds to the model, the second the model parameters.
    @rtype:                 tuple of lists of lists of float, lists of lists of float, list of lists of int
    """

    # The specific analysis API object and parameter object.
    api = return_api()
    param_object = return_parameter_object()

    # Initialise.
    model_lower = []
    model_upper = []
    model_inc = []

    # Loop over the models.
    for model_info in api.model_loop():
        # Get the parameter names and current values.
        names = api.get_param_names(model_info)
        values = api.get_param_values(model_info)

        # No parameters for this model.
        if names == None or len(names) == 0:
            model_lower.append([])
            model_upper.append([])
            model_inc.append([])
            continue

        # The parameter number.
        n = len(names)

        # Make sure that the length of the parameter array is > 0.
        if n == 0:
            raise RelaxError(
                "Cannot run a grid search on a model with zero parameters.")

        # Check that the user supplied bound lengths are ok.
        if lower != None and len(lower) != n:
            raise RelaxLenError('lower bounds', n)
        if upper != None and len(upper) != n:
            raise RelaxLenError('upper bounds', n)

        # Check the user supplied increments.
        if isinstance(inc, list) and len(inc) != n:
            raise RelaxLenError('increment', n)
        if isinstance(inc, list):
            for i in range(n):
                if not (isinstance(inc[i], int) or inc[i] == None):
                    raise RelaxIntListIntError('increment', inc)
        elif not isinstance(inc, int):
            raise RelaxIntListIntError('increment', inc)

        # Convert to the model increment list.
        if isinstance(inc, int):
            model_inc.append([inc] * n)
        else:
            model_inc.append(inc)

        # Print out the model title.
        api.print_model_title(prefix="Grid search setup:  ",
                              model_info=model_info)

        # The grid zoom level.
        zoom = 0
        if hasattr(cdp, 'grid_zoom_level'):
            zoom = cdp.grid_zoom_level
        zoom_factor = 1.0 / 2.0**zoom
        if zoom > 0:
            print(
                "Zooming grid level of %s, scaling the grid size by a factor of %s.\n"
                % (zoom, zoom_factor))

        # Append empty lists for the bounds to be built up.
        model_lower.append([])
        model_upper.append([])

        # Loop over the parameters.
        data = []
        for i in range(n):
            # A comment for user feedback.
            comment = 'Default bounds'
            if lower != None and upper != None:
                comment = 'User supplied lower and upper bound'
            elif lower != None:
                comment = 'User supplied lower bound'
            elif upper != None:
                comment = 'User supplied upper bound'

            # Alias the number of increments for this parameter.
            incs = model_inc[-1][i]

            # Error checking for increment values of None.
            if incs == None and values[i] in [None, {}, []]:
                raise RelaxError(
                    "The parameter '%s' has no preset value, therefore a grid increment of None is not valid."
                    % names[i])

            # The lower bound for this parameter.
            if lower != None:
                lower_i = lower[i]
            else:
                lower_i = param_object.grid_lower(names[i],
                                                  incs=incs,
                                                  model_info=model_info)

            # The upper bound for this parameter.
            if upper != None:
                upper_i = upper[i]
            else:
                upper_i = param_object.grid_upper(names[i],
                                                  incs=incs,
                                                  model_info=model_info)

            # The skipping logic.
            skip = False
            if skip_preset:
                # Override the flag if the zoom is on.
                if zoom:
                    skip = False

                # No preset value.
                elif values[i] in [None, {}, []]:
                    skip = False

                # The preset value is a NaN value due to numpy conversions of None.
                elif isNaN(values[i]):
                    skip = False

                # Ok, now the parameter can be skipped.
                else:
                    skip = True

            # Override the skip flag if the incs value is None.
            if incs == None:
                skip = True

            # Skip preset values.
            if skip:
                lower_i = values[i]
                upper_i = values[i]
                model_inc[-1][i] = incs = 1
                comment = 'Preset value'

            # Zooming grid.
            elif zoom:
                # The full size and scaled size.
                size = upper_i - lower_i
                zoom_size = size * zoom_factor
                half_size = zoom_size / 2.0
                comment = 'Zoom grid width of %s %s' % (
                    zoom_size, param_object.units(names[i]))

                # The new size around the current value.
                lower_zoom = values[i] - half_size
                upper_zoom = values[i] + half_size

                # Outside of the original lower bound, so shift the grid to fit.
                if zoom > 0 and lower_zoom < lower_i:
                    # The amount to shift by.
                    shift = lower_i - lower_zoom

                    # Set the new bounds.
                    upper_i = upper_zoom + shift

                # Outside of the original upper bound, so shift the grid to fit.
                elif zoom > 0 and upper_zoom > upper_i:
                    # The amount to shift by.
                    shift = upper_i - upper_zoom

                    # Set the new bounds.
                    lower_i = lower_zoom + shift

                # Inside the original bounds.
                else:
                    lower_i = lower_zoom
                    upper_i = upper_zoom

            # Add to the data list for printing out.
            data.append([
                names[i],
                "%15s" % lower_i,
                "%15s" % upper_i,
                "%15s" % incs, comment
            ])

            # Scale the bounds.
            scaling = param_object.scaling(names[i], model_info=model_info)
            lower_i /= scaling
            upper_i /= scaling

            # Append.
            model_lower[-1].append(lower_i)
            model_upper[-1].append(upper_i)

        # Printout.
        if verbosity:
            write_data(out=sys.stdout,
                       headings=[
                           "Parameter", "Lower bound", "Upper bound",
                           "Increments", "Comment"
                       ],
                       data=data)
            sys.stdout.write('\n')

    # Return the bounds.
    return model_lower, model_upper, model_inc
Пример #4
0
def grid_setup(lower=None, upper=None, inc=None, verbosity=1, skip_preset=True):
    """Determine the per-model grid bounds, allowing for the zooming grid search.

    @keyword lower:         The user supplied lower bounds of the grid search which must be equal to the number of parameters in the model.
    @type lower:            list of numbers
    @keyword upper:         The user supplied upper bounds of the grid search which must be equal to the number of parameters in the model.
    @type upper:            list of numbers
    @keyword inc:           The user supplied grid search increments.
    @type inc:              int or list of int
    @keyword verbosity:     The amount of information to print.  The higher the value, the greater the verbosity.
    @type verbosity:        int
    @keyword skip_preset:   This argument, when True, allows any parameter which already has a value set to be skipped in the grid search.
    @type skip_preset:      bool
    @return:                The per-model grid upper and lower bounds.  The first dimension of each structure corresponds to the model, the second the model parameters.
    @rtype:                 tuple of lists of lists of float, lists of lists of float, list of lists of int
    """

    # The specific analysis API object and parameter object.
    api = return_api()
    param_object = return_parameter_object()

    # Initialise.
    model_lower = []
    model_upper = []
    model_inc = []

    # Loop over the models.
    for model_info in api.model_loop():
        # Get the parameter names and current values.
        names = api.get_param_names(model_info)
        values = api.get_param_values(model_info)

        # No parameters for this model.
        if names == None or len(names) == 0:
            model_lower.append([])
            model_upper.append([])
            model_inc.append([])
            continue

        # The parameter number.
        n = len(names)

        # Make sure that the length of the parameter array is > 0.
        if n == 0:
            raise RelaxError("Cannot run a grid search on a model with zero parameters.")

        # Check that the user supplied bound lengths are ok.
        if lower != None and len(lower) != n:
            raise RelaxLenError('lower bounds', n)
        if upper != None and len(upper) != n:
            raise RelaxLenError('upper bounds', n)

        # Check the user supplied increments.
        if isinstance(inc, list) and len(inc) != n:
            raise RelaxLenError('increment', n)
        if isinstance(inc, list):
            for i in range(n):
                if not (isinstance(inc[i], int) or inc[i] == None):
                    raise RelaxIntListIntError('increment', inc)
        elif not isinstance(inc, int):
            raise RelaxIntListIntError('increment', inc)

        # Convert to the model increment list.
        if isinstance(inc, int):
            model_inc.append([inc]*n)
        else:
            model_inc.append(inc)

        # Print out the model title.
        api.print_model_title(prefix="Grid search setup:  ", model_info=model_info)

        # The grid zoom level.
        zoom = 0
        if hasattr(cdp, 'grid_zoom_level'):
            zoom = cdp.grid_zoom_level
        zoom_factor = 1.0 / 2.0**zoom
        if zoom > 0:
            print("Zooming grid level of %s, scaling the grid size by a factor of %s.\n" % (zoom, zoom_factor))

        # Append empty lists for the bounds to be built up.
        model_lower.append([])
        model_upper.append([])

        # Loop over the parameters.
        data = []
        for i in range(n):
            # A comment for user feedback.
            comment = 'Default bounds'
            if lower != None and upper != None:
                comment = 'User supplied lower and upper bound'
            elif lower != None:
                comment = 'User supplied lower bound'
            elif upper != None:
                comment = 'User supplied upper bound'

            # Alias the number of increments for this parameter.
            incs = model_inc[-1][i]

            # Error checking for increment values of None.
            if incs == None and values[i] in [None, {}, []]:
                raise RelaxError("The parameter '%s' has no preset value, therefore a grid increment of None is not valid." % names[i])

            # The lower bound for this parameter.
            if lower != None:
                lower_i = lower[i]
            else:
                lower_i = param_object.grid_lower(names[i], incs=incs, model_info=model_info)

            # The upper bound for this parameter.
            if upper != None:
                upper_i = upper[i]
            else:
                upper_i = param_object.grid_upper(names[i], incs=incs, model_info=model_info)

            # The skipping logic.
            skip = False
            if skip_preset:
                # Override the flag if the zoom is on.
                if zoom:
                    skip = False

                # No preset value.
                elif values[i] in [None, {}, []]:
                    skip = False

                # The preset value is a NaN value due to numpy conversions of None.
                elif isNaN(values[i]):
                    skip = False

                # Ok, now the parameter can be skipped.
                else:
                    skip = True

            # Override the skip flag if the incs value is None.
            if incs == None:
                skip = True

            # Skip preset values.
            if skip:
                lower_i = values[i]
                upper_i = values[i]
                model_inc[-1][i] = incs = 1
                comment = 'Preset value'

            # Zooming grid.
            elif zoom:
                # The full size and scaled size.
                size = upper_i - lower_i
                zoom_size = size * zoom_factor
                half_size = zoom_size / 2.0
                comment = 'Zoom grid width of %s %s' % (zoom_size, param_object.units(names[i]))

                # The new size around the current value.
                lower_zoom = values[i] - half_size
                upper_zoom = values[i] + half_size

                # Outside of the original lower bound, so shift the grid to fit.
                if zoom > 0 and lower_zoom < lower_i:
                    # The amount to shift by.
                    shift = lower_i - lower_zoom

                    # Set the new bounds.
                    upper_i = upper_zoom + shift

                # Outside of the original upper bound, so shift the grid to fit.
                elif zoom > 0 and upper_zoom > upper_i:
                    # The amount to shift by.
                    shift = upper_i - upper_zoom

                    # Set the new bounds.
                    lower_i = lower_zoom + shift

                # Inside the original bounds.
                else:
                    lower_i = lower_zoom
                    upper_i = upper_zoom

            # Add to the data list for printing out.
            data.append([names[i], "%15s" % lower_i, "%15s" % upper_i, "%15s" % incs, comment])

            # Scale the bounds.
            scaling = param_object.scaling(names[i], model_info=model_info)
            lower_i /= scaling
            upper_i /= scaling

            # Append.
            model_lower[-1].append(lower_i)
            model_upper[-1].append(upper_i)

        # Printout.
        if verbosity:
            write_data(out=sys.stdout, headings=["Parameter", "Lower bound", "Upper bound", "Increments", "Comment"], data=data)
            sys.stdout.write('\n')

    # Return the bounds.
    return model_lower, model_upper, model_inc