예제 #1
0
 def optimize(self):
     """Optimize the objective function with respect to varying params."""
     p, d = [], []
     for param in self.varyingParams:
         p.append(param.getValue())
         d.append(param.delta)
     p = array(p)
     d = identity(len(d)) * array(d,Float)
     return powell(self._objective, p, drxns=d)
예제 #2
0
    def optimize(self, method=None, tol=None):
        """
        Optimize with respect to varying params.

        The call returns a 3-tuple (params, extremum, extra):
          params = array of best-fit parameter values
          extremum = the optimized statistic (min or max as appropriate)
          extra = any add'l value or values (in a tuple) returned by
                  the specified minimization method (e.g., # iters)
        """
        if method:
            method = method.lower()
        elif self.min_method:
            method = self.min_method.lower()
        else:
            raise InferenceError, 'No minimization method has been specified!'
        if tol is None:
            if self.min_tol is None:
                raise InferenceError, 'No minimization tolerance has been specified!'
        # Most methods require a vector of starting param values and
        # a scale for each; collect this info here (transformed if necessary).
        p, d = [], []
        if self.varying_params == []:
            raise InferenceError, 'No parameters are set to vary for fitting!'
        if self.use_unbounded:
            for param in self.varying_params:
                # Calculate delta for the unbounded version.
                uv = param._unbounded_get_value()
                v = param.get_value()
                try:  # We may need to try a step in both directions.
                    param.set_value(v+param.delta)
                    uv2 = param._unbounded_get_value()
                    d.append(uv2-uv)
                except ParamRangeError:
                    param.set_value(v-param.delta)
                    uv2 = param._unbounded_get_value()
                    d.append(uv-uv2)
                param.set_value(v)
                p.append(uv)
        else:
            for param in self.varying_params:
                p.append(param.get_value())
                d.append(param.delta)
        p = array(p)
        if method == 'powell':
            # Use a diagonal matrix for Powell's start directions.
            dd = identity(len(d)) * array(d, float)
            # For Powell, extra = # of iters
            params, extremum, extra = powell(self._score, p, drxns=dd,
                    ftol=1.e-3, maxit=300)
            # Repeat from the 1st fit, with smaller scales and shuffling
            # the directions to avoid Powell's too-common collapsing to a
            # subspace.
            dd = 0.2 * identity(len(d)) * array(d, float)
            params, extremum, extra = powell(self._score, params[:], drxns=dd,
                    ftol=1.e-3, maxit=200, shuffle=True)
        else:
            raise InferenceError, 'Invalid minimization method specified!'
        if self.extremize == maximize:  # adjust for sign reversal
            extremum = -extremum
        if self.use_unbounded:  # Convert unbounded values back to normal.
            for i, param in enumerate(self.varying_params):
                params[i] = param.get_value()
        return params, extremum, extra