Beispiel #1
0
def local_optimize(cost, x0, lb, ub):
    from mystic.solvers import PowellDirectionalSolver
    from mystic.termination import NormalizedChangeOverGeneration as NCOG
    from mystic.monitors import VerboseMonitor, Monitor

    maxiter = 1000
    maxfun = 1e+6
    convergence_tol = 1e-4

    #stepmon = VerboseMonitor(100)
    stepmon = Monitor()
    evalmon = Monitor()

    ndim = len(lb)

    solver = PowellDirectionalSolver(ndim)
    solver.SetInitialPoints(x0)
    solver.SetStrictRanges(min=lb, max=ub)
    solver.SetEvaluationLimits(maxiter, maxfun)
    solver.SetEvaluationMonitor(evalmon)
    solver.SetGenerationMonitor(stepmon)

    tol = convergence_tol
    solver.Solve(cost, termination=NCOG(tol))

    solved_params = solver.bestSolution
    solved_energy = solver.bestEnergy
    func_evals = solver.evaluations
    return solved_params, solved_energy, func_evals
Beispiel #2
0
def local_optimize(cost,x0,lb,ub):
  from mystic.solvers import PowellDirectionalSolver
  from mystic.termination import NormalizedChangeOverGeneration as NCOG
  from mystic.monitors import VerboseMonitor, Monitor

  maxiter = 1000
  maxfun = 1e+6
  convergence_tol = 1e-4

 #def func_unpickle(filename):
 #  """ standard pickle.load of function from a File """
 #  import dill as pickle
 #  return pickle.load(open(filename,'r'))

 #stepmon = VerboseMonitor(100)
  stepmon = Monitor()
  evalmon = Monitor()

  ndim = len(lb)

  solver = PowellDirectionalSolver(ndim)
  solver.SetInitialPoints(x0)
  solver.SetStrictRanges(min=lb,max=ub)
  solver.SetEvaluationLimits(maxiter,maxfun)
  solver.SetEvaluationMonitor(evalmon)
  solver.SetGenerationMonitor(stepmon)

  tol = convergence_tol
 #cost = func_unpickle(cost)  #XXX: regenerate cost function from file
  solver.Solve(cost, termination=NCOG(tol))

  solved_params = solver.bestSolution
  solved_energy = solver.bestEnergy
  func_evals = solver.evaluations
  return solved_params, solved_energy, func_evals
    # max = [200.001, 100.001, numpy.inf]
    #  min = [-0.999, -0.999, 0.999]
    #  max = [2.001, 1.001, 1.001]
    print "Powell Direction Set Method"
    print "==========================="
    start = time.time()
    from mystic.monitors import Monitor, VerboseMonitor
    stepmon = VerboseMonitor(1, 1)
    #stepmon = Monitor() #VerboseMonitor(10)
    from mystic.termination import NormalizedChangeOverGeneration as NCOG

    #from mystic._scipyoptimize import fmin_powell
    from mystic.solvers import fmin_powell, PowellDirectionalSolver
    #print fmin_powell(rosen,x0,retall=0,full_output=0)#,maxiter=14)
    solver = PowellDirectionalSolver(len(x0))
    solver.SetInitialPoints(x0)
    solver.SetStrictRanges(min, max)
    #solver.SetEvaluationLimits(generations=13)
    solver.SetGenerationMonitor(stepmon)
    solver.SetConstraints(constrain)
    solver.enable_signal_handler()
    solver.Solve(rosen, NCOG(tolerance=1e-4), disp=1)
    print solver.bestSolution
    #print "Current function value: %s" % solver.bestEnergy
    #print "Iterations: %s" % solver.generations
    #print "Function evaluations: %s" % solver.evaluations

    times.append(time.time() - start)
    algor.append("Powell's Method\t")

    for k in range(len(algor)):
def solve(samp, xyz_of_samp, _cost, method, cx_is_positive=False):
    """Find reasonable positions and anchors given a set of samples.
    """

    u = np.shape(samp)[0]
    ux = np.shape(xyz_of_samp)[0]
    number_of_params_pos = 3*(u - ux)

    def costx(posvec, anchvec):
        """Identical to cost, except the shape of inputs and capture of samp, xyz_of_samp, ux, and u

        Parameters
        ----------
        x : [A_ay A_az A_bx A_by A_bz A_cx A_cy A_cz A_dz
               x1   y1   z1   x2   y2   z2   ...  xu   yu   zu
        """
        anchors = anchorsvec2matrix(anchvec)
        pos = np.zeros((u, 3))
        if(np.size(xyz_of_samp) != 0):
            pos[0:ux] = xyz_of_samp
        pos[ux:] = np.reshape(posvec, (u-ux,3))
        return _cost(anchors, pos, samp)

    l_long = 5000.0
    l_short = 1700.0
    data_z_min = -20.0
    # Limits of anchor positions:
    #     |ANCHOR_XY|    < 4000
    #      ANCHOR_B_X    > 0
    #      ANCHOR_C_X    < 0
    #     |ANCHOR_ABC_Z| < 1700
    # 0 <  ANCHOR_D_Z    < 4000
    # Limits of data collection volume:
    #         |x| < 1700
    #         |y| < 1700
    # -20.0 <  z  < 3400.0
    # Define bounds
    lb = [      -l_long, # A_ay > -4000.0
               -l_short, # A_az > -1700.0
                    0.0, # A_bx > 0
                    0.0, # A_by > 0
               -l_short, # A_bz > -1700.0
                -l_long, # A_cx > -4000
                    0.0, # A_cy > 0
               -l_short, # A_cz > -1700.0
                    0.0, # A_dz > 0
          ] + [-l_short, -l_short, data_z_min]*(u-ux)
    ub = [          0.0, # A_ay < 0
                l_short, # A_az < 1700
                 l_long, # A_bx < 4000
                 l_long, # A_by < 4000
                l_short, # A_bz < 1700
                    0.0, # A_cx < 0
                 l_long, # A_cy < 4000.0
                l_short, # A_cz < 1700
                 l_long, # A_dz < 4000.0
          ] + [l_short, l_short, 2*l_short]*(u-ux)

    # If the user has input xyz data, then signs should be ok anyways
    if(ux > 2):
        lb[A_bx] = -l_long

    # It would work to just swap the signs of bx and cx after the optimization
    # But there are fewer assumptions involved in setting correct bounds from the start instead
    if(cx_is_positive):
        tmp = lb[A_bx]
        lb[A_bx] = lb[A_cx]
        lb[A_cx] = tmp
        tmp = ub[A_bx]
        ub[A_bx] = ub[A_cx]
        ub[A_cx] = tmp

    pos_est0 = np.zeros((u-ux,3)) # The positions we need to estimate
    anchors_est = np.array([[0.0, 0.0, 0.0],
                            [0.0, 0.0, 0.0],
                            [0.0, 0.0, 0.0],
                            [0.0, 0.0, 0.0]])
    x_guess0 = list(anchorsmatrix2vec(anchors_est)) + list(posmatrix2vec(pos_est0))

    if(method == 'PowellDirectionalSolver'):
        from mystic.termination import ChangeOverGeneration, NormalizedChangeOverGeneration, VTR
        from mystic.solvers import PowellDirectionalSolver
        from mystic.termination import Or, CollapseAt, CollapseAs
        from mystic.termination import ChangeOverGeneration as COG
        target = 1.0
        term = Or((COG(generations=100), CollapseAt(target, generations=100)))
        # Solver 0
        solver0 = PowellDirectionalSolver(number_of_params_pos+params_anch)
        solver0.SetEvaluationLimits(evaluations=3200000, generations=10000)
        solver0.SetTermination(term)
        solver0.SetInitialPoints(x_guess0)
        solver0.SetStrictRanges(lb, ub)
        solver0.Solve(lambda x: costx(x[params_anch:], x[0:params_anch]))
        x_guess0 = solver0.bestSolution
        # PowellDirectional sometimes finds new ways if kickstarted anew
        for i in range(1,20):
            solver0 = PowellDirectionalSolver(number_of_params_pos+params_anch)
            solver0.SetInitialPoints(x_guess0)
            solver0.SetStrictRanges(lb, ub)
            solver0.Solve(lambda x: costx(x[params_anch:], x[0:params_anch]))
            x_guess0 = solver0.bestSolution
        return x_guess0
    elif(method == 'SLSQP'):
        # 'SLSQP' is crazy fast and lands on 0.0000 error
        x_guess0 = scipy.optimize.minimize(lambda x: costx(x[params_anch:], x[0:params_anch]), x_guess0, method=method, bounds=list(zip(lb,ub)),
                options={'disp':True,'ftol':1e-20, 'maxiter':150000})
        return x_guess0.x
    elif(method == 'L-BFGS-B'):
        ## 'L-BFGS-B' Is crazy fast but doesn't quite land at 0.0000 error
        x_guess0 = scipy.optimize.minimize(lambda x: costx(x[params_anch:], x[0:params_anch]), x_guess0, method=method, bounds=list(zip(lb,ub)),
                options={'ftol':1e-12, 'maxiter':150000})
        return x_guess0.x
    else:
        print("Method %s is not supported!" % method)
        sys.exit(1)