Esempio n. 1
0
def solve(measurements, method):
    """Find reasonable marker positions based on a set of measurements."""
    print(method)

    marker_measurements = measurements
    if np.size(measurements) == 21:
        marker_measurements = measurements[(21 - 15) :]
    # m0 has known positions (0, 0, 0)
    # m1 has unknown x-position
    # All others have unknown xy-positions
    num_params = 0 + 1 + 2 + 2 + 2 + 2

    bound = 400.0
    lower_bound = [
        0.0,
        0.0,
        0.0,
        0.0,
        0.0,
        -bound,
        0.0,
        -bound,
        0.0,
    ]
    upper_bound = [
        bound,
        bound,
        bound,
        bound,
        bound,
        bound,
        bound,
        bound,
        bound,
    ]

    def costx_no_nozzle(posvec):
        """Identical to cost_no_nozzle, except the shape of inputs"""
        positions = posvec2matrix_no_nozzle(posvec)
        return cost_no_nozzle(positions, marker_measurements)

    guess_0 = [0.0] * num_params

    intermediate_cost = 0.0
    intermediate_solution = []
    if method == "SLSQP":
        sol = scipy.optimize.minimize(
            costx_no_nozzle,
            guess_0,
            method="SLSQP",
            bounds=list(zip(lower_bound, upper_bound)),
            tol=1e-20,
            options={"disp": True, "ftol": 1e-40, "eps": 1e-10, "maxiter": 500},
        )
        intermediate_cost = sol.fun
        intermediate_solution = sol.x
    elif method == "L-BFGS-B":
        sol = scipy.optimize.minimize(
            costx_no_nozzle,
            guess_0,
            method="L-BFGS-B",
            bounds=list(zip(lower_bound, upper_bound)),
            options={"disp": True, "ftol": 1e-12, "gtol": 1e-12, "maxiter": 50000, "maxfun": 1000000},
        )
        intermediate_cost = sol.fun
        intermediate_solution = sol.x
    elif method == "PowellDirectionalSolver":
        from mystic.solvers import PowellDirectionalSolver
        from mystic.termination import Or, CollapseAt, CollapseAs
        from mystic.termination import ChangeOverGeneration as COG
        from mystic.monitors import VerboseMonitor
        from mystic.termination import VTR, And, Or

        solver = PowellDirectionalSolver(num_params)
        solver.SetRandomInitialPoints(lower_bound, upper_bound)
        solver.SetEvaluationLimits(evaluations=3200000, generations=100000)
        solver.SetTermination(Or(VTR(1e-25), COG(1e-10, 20)))
        solver.SetStrictRanges(lower_bound, upper_bound)
        solver.SetGenerationMonitor(VerboseMonitor(5))
        solver.Solve(costx_no_nozzle)
        intermediate_cost = solver.bestEnergy
        intermediate_solution = solver.bestSolution
    elif method == "differentialEvolutionSolver":
        from mystic.solvers import DifferentialEvolutionSolver2
        from mystic.monitors import VerboseMonitor
        from mystic.termination import VTR, ChangeOverGeneration, And, Or
        from mystic.strategy import Best1Exp, Best1Bin

        stop = Or(VTR(1e-18), ChangeOverGeneration(1e-9, 500))
        npop = 3
        stepmon = VerboseMonitor(100)
        solver = DifferentialEvolutionSolver2(num_params, npop)
        solver.SetEvaluationLimits(evaluations=3200000, generations=100000)
        solver.SetRandomInitialPoints(lower_bound, upper_bound)
        solver.SetStrictRanges(lower_bound, upper_bound)
        solver.SetGenerationMonitor(stepmon)
        solver.Solve(
            costx_no_nozzle,
            termination=stop,
            strategy=Best1Bin,
        )
        intermediate_cost = solver.bestEnergy
        intermediate_solution = solver.bestSolution
    else:
        print("Method %s is not supported!" % method)
        sys.exit(1)
    print("Best intermediate cost: ", intermediate_cost)
    print("Best intermediate positions: \n%s" % posvec2matrix_no_nozzle(intermediate_solution))
    if np.size(measurements) == 15:
        print("Got only 15 samples, so will not try to find nozzle position\n")
        return
    nozzle_measurements = measurements[: (21 - 15)]
    # Look for nozzle's xyz-offset relative to marker 0
    num_params = 3
    lower_bound = [
        0.0,
        0.0,
        -bound,
    ]
    upper_bound = [bound, bound, 0.0]

    def costx_nozzle(posvec):
        """Identical to cost_nozzle, except the shape of inputs"""
        positions = posvec2matrix_nozzle(posvec, intermediate_solution)
        return cost_nozzle(positions, measurements)

    guess_0 = [0.0, 0.0, 0.0]
    final_cost = 0.0
    final_solution = []
    if method == "SLSQP":
        sol = scipy.optimize.minimize(
            costx_nozzle,
            guess_0,
            method="SLSQP",
            bounds=list(zip(lower_bound, upper_bound)),
            tol=1e-20,
            options={"disp": True, "ftol": 1e-40, "eps": 1e-10, "maxiter": 500},
        )
        final_cost = sol.fun
        final_solution = sol.x
    elif method == "L-BFGS-B":
        sol = scipy.optimize.minimize(
            costx_nozzle,
            guess_0,
            method="L-BFGS-B",
            bounds=list(zip(lower_bound, upper_bound)),
            options={"disp": True, "ftol": 1e-12, "gtol": 1e-12, "maxiter": 50000, "maxfun": 1000000},
        )
        final_cost = sol.fun
        final_solution = sol.x
    elif method == "PowellDirectionalSolver":
        from mystic.solvers import PowellDirectionalSolver
        from mystic.termination import Or, CollapseAt, CollapseAs
        from mystic.termination import ChangeOverGeneration as COG
        from mystic.monitors import VerboseMonitor
        from mystic.termination import VTR, And, Or

        solver = PowellDirectionalSolver(num_params)
        solver.SetRandomInitialPoints(lower_bound, upper_bound)
        solver.SetEvaluationLimits(evaluations=3200000, generations=100000)
        solver.SetTermination(Or(VTR(1e-25), COG(1e-10, 20)))
        solver.SetStrictRanges(lower_bound, upper_bound)
        solver.SetGenerationMonitor(VerboseMonitor(5))
        solver.Solve(costx_nozzle)
        final_cost = solver.bestEnergy
        final_solution = solver.bestSolution
    elif method == "differentialEvolutionSolver":
        from mystic.solvers import DifferentialEvolutionSolver2
        from mystic.monitors import VerboseMonitor
        from mystic.termination import VTR, ChangeOverGeneration, And, Or
        from mystic.strategy import Best1Exp, Best1Bin

        stop = Or(VTR(1e-18), ChangeOverGeneration(1e-9, 500))
        npop = 3
        stepmon = VerboseMonitor(100)
        solver = DifferentialEvolutionSolver2(num_params, npop)
        solver.SetEvaluationLimits(evaluations=3200000, generations=100000)
        solver.SetRandomInitialPoints(lower_bound, upper_bound)
        solver.SetStrictRanges(lower_bound, upper_bound)
        solver.SetGenerationMonitor(stepmon)
        solver.Solve(
            costx_nozzle,
            termination=stop,
            strategy=Best1Bin,
        )
        final_cost = solver.bestEnergy
        final_solution = solver.bestSolution

    print("Best final cost: ", final_cost)
    print("Best final positions:")
    final = posvec2matrix_nozzle(final_solution, intermediate_solution)[1:]
    for num in range(0, 6):
        print(
            "{0: 8.3f} {1: 8.3f} {2: 8.3f} <!-- Marker {3} -->".format(final[num][0], final[num][1], final[num][2], num)
        )
Esempio n. 2
0
solver = DifferentialEvolutionSolver(3, 40)
solver.SetRandomInitialPoints([0., 0., 0.], [10., 10., 10.])
term = VTR()
solver.SetSaveFrequency(0)
solver.Solve(rosen, term)
x = solver.bestSolution
y = solver.bestEnergy
assert solver._state == None
assert LoadSolver(solver._state) == None

solver = DifferentialEvolutionSolver(3, 40)
solver.SetRandomInitialPoints([0., 0., 0.], [10., 10., 10.])
term = When(VTR())
solver.SetSaveFrequency(10, tmpfile)
solver.SetTermination(term)
solver.Solve(rosen)
x = solver.bestSolution
y = solver.bestEnergy
_solver = LoadSolver(tmpfile)
os.remove(tmpfile)
assert all(x == _solver.bestSolution)
assert y == _solver.bestEnergy

solver = DifferentialEvolutionSolver(3, 40)
solver.SetRandomInitialPoints([0., 0., 0.], [10., 10., 10.])
term = Or(VTR(), ChangeOverGeneration())
solver.SetSaveFrequency(10, tmpfile)
solver.SetTermination(term)
solver.Solve(rosen)
x = solver.bestSolution
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)