def init_solver_machine_scaling(v, machine_task_list, task_machine_dict, O_value=5): """ :param v: number of tasks dependent on each task :param machine_task_list: order :param task_machine_dict: task machine mapping :param O_value: optimal objective value :return: """ m = GEKKO() # Use IPOPT solver (default) m.options.SOLVER = 3 # Change to parallel linear solver m.solver_options = ['linear_solver ma97'] # variable array dimension n = len(machine_task_list) # rows # create array s = m.Array(m.Var, n) for i in range(n): s[i].value = 2.0 s[i].lower = 0 # Optimal value for ibjective O = m.Var(value=O_value, lb=0) # The objective basically m.Equation(sum([int(v[i]) / s[task_machine_dict[i]] + s[task_machine_dict[i]] for i in range(len(v))]) == O) return m, s, O
def initGekko(alpha, beta, paddle, last_move): m = GEKKO() m.WEB = 0 m.options.SOLVER = 1 # APOPT is an MINLP solver # optional solver settings with APOPT m.solver_options = ['minlp_maximum_iterations 500', \ # minlp iterations with integer solution 'minlp_max_iter_with_int_sol 10', \ # treat minlp as nlp 'minlp_as_nlp 0', \ # nlp sub-problem max iterations 'nlp_maximum_iterations 50', \ # 1 = depth first, 2 = breadth first 'minlp_branch_method 1', \ # maximum deviation from whole number 'minlp_integer_tol 0.1', \ # covergence tolerance 'minlp_gap_tol 0.01'] m.time = [0, 1, 2, 3] # control variable u = m.MV(lb=-1, ub=1, integer=True) u.DCOST = 0.1 # parameters alpha = m.Param(value=alpha) beta = m.Param(value=beta) # need need the last control vector ulast = m.Var() m.delay(u, ulast, 1) #variable y = m.CV(paddle) #equation m.Equation(y.dt() == (alpha * u) + (beta * ulast)) #options m.options.IMODE = 6 m.options.NODES = 2 m.options.CV_TYPE = 1 y.STATUS = 1 y.FSTATUS = 1 # to do get this from input y.SPHI = 25 y.SPLO = 25 y.TAU = 0 y.TR_INIT = 2 u.STATUS = 1 u.FSTATUS = 0 return m, y, u
def param_from_mom(mom): if len(mom) != 3: raise ValueError("Moment dimension should be 3") mu, var, gamma = mom m = GEKKO() delta = m.Var(value=1.06) m.Equation([ gamma == 0.5 * (4 - PI) * ((delta * np.sqrt(2 / PI))**3) / ((1 - 2 * delta * delta / PI)**1.5) ]) m.solve(disp=False) # print("result of delta: {}".format(delta.value)) if len(delta) > 1: print("ERROR in delta") delta = delta.value[0] if np.abs(delta) > 1: print( "Warning: SkewNormal delta {:.5f} out of range!".format(delta)) delta = delta / (np.abs(delta) + 0.001) print("Changed delta to {:.5f}".format(delta)) # print("num delta: {:.3f}".format(delta)) alpha = delta / np.sqrt(1 - delta**2) omega = np.sqrt(var / (1 - (2 * delta * delta / PI))) zeta = mu - omega * delta * np.sqrt(2 / PI) return (zeta, omega, alpha)
def solve08(): # Nonlinear Regression # measurements xm = np.array([0, 1, 2, 3, 4, 5]) ym = np.array([0.1, 0.2, 0.3, 0.5, 0.8, 2.0]) # GEKKO model m = GEKKO() # parameters x = m.Param(value=xm) a = m.FV() a.STATUS = 1 # variables y = m.CV(value=ym) y.FSTATUS = 1 # regression equation m.Equation(y == 0.1 * m.exp(a * x)) # regression mode m.options.IMODE = 2 # optimize m.solve(disp=False) # print parameters print('Optimized, a = ' + str(a.value[0])) plt.plot(xm, ym, 'bo') plt.plot(xm, y.value, 'r-') plt.show()
def init_solver(v, O_value=5): m = GEKKO() # Use IPOPT solver (default) m.options.SOLVER = 3 # Change to parallel linear solver m.solver_options = ['linear_solver ma97'] # variable array dimension n = len(v) # rows # create array s = m.Array(m.Var, n) for i in range(n): s[i].value = 2.0 s[i].lower = 0 # Optimal value for ibjective O = m.Var(value=O_value, lb=0) # The objective basically m.Equation(sum([int(v[i]) / s[i] + s[i] for i in range(len(v))]) == O) return m, s, O
def solve13(): # Optimization of Multiple Linked Phases # Initialize gekko model m = GEKKO() # Number of collocation nodes nodes = 3 # Number of phases n = 5 # Time horizon (for all phases) m.time = np.linspace(0, 1, 100) # Input (constant in IMODE 4) u = [m.Var(1, lb=-2, ub=2, fixed_initial=False) for i in range(n)] # Example of same parameter for each phase tau = 5 # Example of different parameters for each phase K = [2, 3, 5, 1, 4] # Scale time of each phase tf = [1, 2, 4, 8, 16] # Variables (one version of x for each phase) x = [m.Var(0) for i in range(5)] # Equations (different for each phase) for i in range(n): m.Equation(tau * x[i].dt() / tf[i] == -x[i] + K[i] * u[i]) # Connect phases together at endpoints for i in range(n - 1): m.Connection(x[i + 1], x[i], 1, len(m.time) - 1, 1, nodes) m.Connection(x[i + 1], 'CALCULATED', pos1=1, node1=1) # Objective # Maximize final x while keeping third phase = -1 m.Obj(-x[n - 1] + (x[2] + 1)**2 * 100) # Solver options m.options.IMODE = 6 m.options.NODES = nodes # Solve m.solve() # Calculate the start time of each phase ts = [0] for i in range(n - 1): ts.append(ts[i] + tf[i]) # Plot plt.figure() tm = np.empty(len(m.time)) for i in range(n): tm = m.time * tf[i] + ts[i] plt.plot(tm, x[i]) plt.show()
def solve05(): # Solver Selection m = GEKKO() # create GEKKO model y = m.Var(value=2) # define new variable, initial value=2 m.Equation(y**2 == 1) # define new equation m.options.SOLVER = 1 # change solver (1=APOPT,3=IPOPT) m.solve(disp=False) # solve locally (remote=False) print('y: ' + str(y.value)) # print variable value
def solve10(): # Mixed Integer Nonlinear Programming m = GEKKO() # Initialize gekko m.options.SOLVER = 1 # APOPT is an MINLP solver # optional solver settings with APOPT m.solver_options = ['minlp_maximum_iterations 500', \ # minlp iterations with integer solution 'minlp_max_iter_with_int_sol 10', \ # treat minlp as nlp 'minlp_as_nlp 0', \ # nlp sub-problem max iterations 'nlp_maximum_iterations 50', \ # 1 = depth first, 2 = breadth first 'minlp_branch_method 1', \ # maximum deviation from whole number 'minlp_integer_tol 0.05', \ # covergence tolerance 'minlp_gap_tol 0.01'] # Initialize variables x1 = m.Var(value=1, lb=1, ub=5) x2 = m.Var(value=5, lb=1, ub=5) # Integer constraints for x3 and x4 x3 = m.Var(value=5, lb=1, ub=5, integer=True) x4 = m.Var(value=1, lb=1, ub=5, integer=True) # Equations m.Equation(x1 * x2 * x3 * x4 >= 25) m.Equation(x1**2 + x2**2 + x3**2 + x4**2 == 40) m.Obj(x1 * x4 * (x1 + x2 + x3) + x3) # Objective m.solve(disp=False) # Solve print('Results') print('x1: ' + str(x1.value)) print('x2: ' + str(x2.value)) print('x3: ' + str(x3.value)) print('x4: ' + str(x4.value)) print('Objective: ' + str(m.options.objfcnval))
def SS(A, B, C, D=None): """ Build a GEKKO from SS representation. Give A,B,C and D, returns: m (GEKKO model) x (states) y (outputs) u (inputs) """ #set all matricies to numpy A = np.array(A) B = np.array(B) C = np.array(C) if D != None: #D is supplied D = np.array(D) #count number of states, inputs and outputs nx = A.shape[0] ny = C.shape[0] nu = B.shape[1] #initialize GEKKO Model m = GEKKO() #define arrays of states, outputs and inputs x = [m.SV() for i in np.arange(nx)] y = [m.CV() for i in np.arange(ny)] u = [m.MV() for i in np.arange(nu)] #build equations for states state_eqs = np.dot(A, x) + np.dot(B, u) [m.Equation(state_eqs[i] == x[i].dt()) for i in range(nx)] #build equations for outputs if D != None: output_eqs = np.dot(C, x) + np.dot(D, u) else: output_eqs = np.dot(C, x) [m.Equation(output_eqs[i] == y[i].dt()) for i in range(ny)] return m, x, y, u
def solve03(): # Variable and Equation Arrays m = GEKKO() p = m.Param(1.2) x = m.Array(m.Var, 3) eq0 = x[1] == x[0] + p eq1 = x[2] - 1 == x[1] + x[0] m.Equation(x[2] == x[1]**2) m.Equations([eq0, eq1]) m.solve() for i in range(3): print('x[' + str(i) + ']=' + str(x[i].value))
def maximum_bipartite_matching_optimization(G): """ Performs LP optimization solving the maximum bipartite matching problem :param G: Bipartite Networkx graph G, need to specify which set each nodes by additional option EG: G = nx.Graph() # People G.add_nodes_from(['p' + str(i) for i in range(4)], bipartite=0) # Specifying that nodes in set 0 # Organs G.add_nodes_from(['o' + str(i) for i in range(4)], bipartite=1) # Specifying that nodes in set 1 # Edges G.add_edges_from([('p0', 'o0'), ('p1', 'o1'), ('p2', 'o1'), ('p2', 'o2')]) :return: dictionary of matching where key is node, value is node in other set, it contains (a,b) and (b,a) """ # remove nodes with no edges as it messes up bipartite splitter left_set = [n for n in G.nodes if G.nodes[n]['bipartite'] == 0] model = GEKKO() variable_dict = {} for node in left_set: neighbors = list(G.neighbors(node)) # print("Node is ", node) # print("Neighbors are ", neighbors) for neighbor in neighbors: # make variables # lower bound 0 upper bound 1 variable_dict[(node, neighbor)] = model.Var(lb=0, ub=1, integer=True) tuples = [(node, i) for i in neighbors] # print(tuples) # Constraint that no node can be in matching twice if len(tuples) > 0: model.Equation(sum([variable_dict[tup] for tup in tuples]) <= 1.0) # Objective model.Obj(-1 * sum([variable_dict[variable] for variable in variable_dict])) # Integer Solver model.options.SOLVER = 1 # Solve model.solve(disp=True) matching = {} # Add variables to matching for variable in variable_dict.items(): print(variable) if int(variable[1][0]) == 1: matching[variable[0][0]] = variable[0][1] matching[variable[0][1]] = variable[0][0] return matching
def jennings(): m = GEKKO() nt = 501 m.time = np.linspace(0,1,nt) x1 = m.Var(value=3.1415/2) x2 = m.Var(value=4) x3 = m.Var(value=0) u = m.MV(lb=-2,ub=2) u.STATUS = 1 scale = m.FV(value=1,lb=0.1,ub=100) scale.status = 1 m.Equation(x1.dt()/scale == u) m.Equation(x2.dt()/scale == m.cos(x1)) m.Equation(x3.dt()/scale == m.sin(x1)) #z = m.FV(value=0) #z.STATUS = 0 #m.Connection(z,x2,pos2='end') #m.Connection(z,x3,pos2='end') m.fix(x2,nt-1,0) m.fix(x3,nt-1,0) m.Obj(scale) m.options.ICD_CALC = 1 m.options.IMODE = 6 m.solve(disp=False) assert test.like(x1.value, [1.57075, 1.584488, 1.597806, 1.611169, 1.624564, 1.63798, 1.651413, 1.664859, 1.678313, 1.69177, 1.705228, 1.718683, 1.732134, 1.74558, 1.759019, 1.77245, 1.785874, 1.799288, 1.812693, 1.826088, 1.839472, 1.852847, 1.866211, 1.879564, 1.892906, 1.906237, 1.919557, 1.932866, 1.946163, 1.959449,1.972723, 1.985986, 1.999236, 2.012475, 2.025701, 2.038915, 2.052117, 2.065306, 2.078482, 2.091646, 2.104796, 2.117933, 2.131056, 2.144166, 2.157263, 2.170345, 2.183413, 2.196467, 2.209506, 2.222531, 2.235541,2.248536, 2.261516, 2.274481, 2.287431, 2.300365, 2.313284, 2.326187, 2.339074, 2.351945, 2.3648, 2.377639, 2.390461, 2.403268, 2.416057, 2.428831, 2.441588, 2.454328, 2.467051, 2.479758, 2.492448, 2.505121, 2.517777, 2.530416, 2.543038, 2.555644, 2.568232, 2.580803, 2.593358, 2.605895, 2.618415, 2.630919, 2.643405, 2.655875, 2.668327, 2.680763, 2.693182, 2.705585, 2.71797, 2.73034, 2.742692, 2.755028, 2.767348, 2.779651, 2.791939, 2.80421, 2.816465, 2.828704, 2.840928, 2.853136, 2.865328, 2.877505, 2.889667, 2.901814,2.913946, 2.926063, 2.938165, 2.950253, 2.962327, 2.974387, 2.986432, 2.998464, 3.010482, 3.022487, 3.034478, 3.046457, 3.058422, 3.070375, 3.082316, 3.094244, 3.10616, 3.118064, 3.129956, 3.141837, 3.153707, 3.165566, 3.177413, 3.18925, 3.201077, 3.212893, 3.2247, 3.236496, 3.248283, 3.26006, 3.271829, 3.283588,3.295338, 3.30708, 3.318814, 3.330539, 3.342256, 3.353966, 3.365668, 3.377363, 3.38905, 3.40073, 3.412404, 3.424071, 3.435732, 3.447386, 3.459034, 3.470677, 3.482313, 3.493944, 3.50557, 3.51719, 3.528805, 3.540416, 3.552021, 3.563622, 3.575219, 3.586811, 3.598399, 3.609982, 3.621562, 3.633138, 3.64471, 3.656278, 3.667842, 3.679404, 3.690961, 3.702516, 3.714067, 3.725614, 3.737159, 3.7487, 3.760239, 3.771774, 3.783306, 3.794835, 3.806361, 3.817884, 3.829404, 3.840921, 3.852434, 3.863944, 3.875451, 3.886955, 3.898455, 3.909952, 3.921445, 3.932934, 3.944419, 3.9559, 3.967377, 3.97885, 3.990318, 4.00178, 4.013238, 4.024691, 4.036137, 4.047578, 4.059013, 4.070441, 4.081862, 4.093275, 4.104681, 4.116078, 4.127467, 4.138846, 4.150215, 4.161573, 4.172921, 4.184256, 4.195578, 4.206887, 4.218181, 4.229459, 4.24072, 4.251962, 4.263186, 4.274389, 4.28557, 4.296727, 4.30786, 4.318965, 4.330041, 4.341085, 4.352094, 4.363065, 4.373994, 4.384877,4.395709, 4.406487, 4.417206, 4.427862, 4.438456, 4.448986, 4.459455, 4.469864, 4.480206, 4.490454, 4.500528, 4.510246, 4.519226, 4.526707, 4.531218, 4.529966, 4.518415, 4.494345, 4.47313, 4.484098, 4.508164, 4.521127, 4.522516, 4.517303, 4.508851, 4.49891, 4.488353, 4.477589, 4.466791, 4.456028, 4.445307, 4.434603, 4.423888, 4.413144, 4.40236, 4.39153, 4.380652, 4.369725, 4.358754, 4.347739, 4.336685, 4.325595, 4.314471, 4.303316, 4.292133, 4.280923, 4.269689, 4.258433, 4.247155, 4.235857, 4.22454, 4.213206, 4.201856,4.190491, 4.179112, 4.167719, 4.156314, 4.144898, 4.133471, 4.122034, 4.110588, 4.099132, 4.087668, 4.076196, 4.064716, 4.05323, 4.041736, 4.030236, 4.01873, 4.007219, 3.995702, 3.984179, 3.972652, 3.96112, 3.949583, 3.938042, 3.926497, 3.914947, 3.903394, 3.891837, 3.880277, 3.868713, 3.857146, 3.845575, 3.834001, 3.822424, 3.810844, 3.79926, 3.787674, 3.776085, 3.764493, 3.752897, 3.741299, 3.729698, 3.718093, 3.706486, 3.694876, 3.683262, 3.671645, 3.660026, 3.648402, 3.636776, 3.625146, 3.613512, 3.601875, 3.590235, 3.57859, 3.566942, 3.555289, 3.543633, 3.531972, 3.520307, 3.508637, 3.496963, 3.485284, 3.473601, 3.461912, 3.450218, 3.438519, 3.426814, 3.415104, 3.403388, 3.391666, 3.379938, 3.368204, 3.356463, 3.344716,3.332962, 3.321201, 3.309433, 3.297658, 3.285875, 3.274085, 3.262286, 3.25048, 3.238666, 3.226843, 3.215012, 3.203172, 3.191323, 3.179465, 3.167597, 3.155721, 3.143835, 3.131938, 3.120032, 3.108116, 3.09619, 3.084253, 3.072305, 3.060347, 3.048378, 3.036398, 3.024406, 3.012403, 3.000388, 2.988362, 2.976324, 2.964274, 2.952211, 2.940137, 2.92805, 2.915951, 2.903839, 2.891714, 2.879576, 2.867426, 2.855262, 2.843086, 2.830896, 2.818692, 2.806476, 2.794246, 2.782002, 2.769745, 2.757474, 2.745189, 2.732891, 2.720579, 2.708253, 2.695913, 2.68356, 2.671192, 2.658811, 2.646416, 2.634007, 2.621585, 2.609148, 2.596698, 2.584234, 2.571757, 2.559266, 2.546761, 2.534243, 2.521711, 2.509166, 2.496608, 2.484036, 2.471452, 2.458854, 2.446244, 2.433621, 2.420985, 2.408337, 2.395676, 2.383004, 2.370319, 2.357622, 2.344913, 2.332193, 2.319461, 2.306718, 2.293964, 2.2812, 2.268424, 2.255638, 2.242842, 2.230035, 2.217219, 2.204393, 2.191558, 2.178714, 2.165861, 2.152999, 2.140129, 2.12725, 2.114364, 2.101471, 2.08857, 2.075662, 2.062747, 2.049826, 2.036899, 2.023966, 2.011028, 1.998085, 1.985137, 1.972185, 1.959228, 1.946268, 1.933305, 1.920338, 1.907369, 1.894398, 1.881425, 1.868451, 1.855476, 1.8425, 1.829524, 1.816549, 1.803574, 1.7906, 1.777628, 1.764659, 1.751692, 1.738728, 1.725768, 1.712812, 1.699862, 1.686917, 1.673978, 1.661046, 1.648122, 1.635207, 1.622301, 1.609406, 1.596522, 1.583652, 1.570796]) assert test.like(x2.value, [4.0, 3.999835, 3.99951, 3.999024, 3.998377, 3.997569, 3.9966, 3.995469, 3.994178, 3.992725, 3.991112, 3.989338, 3.987405, 3.985311, 3.983059, 3.980648, 3.978079, 3.975353, 3.972469, 3.96943, 3.966234, 3.962884, 3.95938, 3.955722, 3.951911, 3.947949, 3.943835, 3.939572, 3.935159, 3.930598, 3.925889, 3.921033, 3.916033, 3.910887, 3.905599, 3.900167, 3.894595, 3.888882, 3.88303, 3.87704, 3.870914, 3.864652, 3.858255, 3.851725, 3.845064, 3.838272, 3.83135, 3.824301, 3.817125, 3.809824, 3.802398, 3.794851, 3.787182, 3.779394, 3.771487, 3.763464, 3.755325, 3.747073, 3.738709, 3.730233, 3.721649, 3.712957, 3.704159, 3.695256, 3.686251, 3.677144, 3.667938, 3.658633, 3.649233, 3.639737, 3.630148, 3.620468, 3.610698, 3.60084, 3.590896, 3.580867, 3.570755, 3.560561, 3.550288, 3.539938, 3.529511, 3.519009, 3.508435, 3.497791, 3.487077, 3.476295, 3.465448, 3.454537, 3.443564, 3.432531, 3.421439, 3.41029, 3.399086, 3.387829, 3.37652, 3.365162,3.353756, 3.342303, 3.330806, 3.319266, 3.307686, 3.296066, 3.284409, 3.272716, 3.26099, 3.249231, 3.237442, 3.225625, 3.213781, 3.201912, 3.190019, 3.178105, 3.166172, 3.15422, 3.142252, 3.130269, 3.118274, 3.106267, 3.094251, 3.082228, 3.070198, 3.058165, 3.046128, 3.034091, 3.022055, 3.010022, 2.997992, 2.985969, 2.973953, 2.961947, 2.949951, 2.937968, 2.926, 2.914047, 2.902112, 2.890196, 2.878301, 2.866429, 2.85458, 2.842757, 2.830962, 2.819195, 2.807459, 2.795755, 2.784085, 2.77245, 2.760851, 2.749291, 2.737771, 2.726293, 2.714857, 2.703466, 2.692121, 2.680823, 2.669575, 2.658377, 2.647231, 2.636139, 2.625101, 2.61412, 2.603197, 2.592334, 2.581531, 2.57079, 2.560113, 2.549502, 2.538956, 2.528479, 2.51807, 2.507732, 2.497467, 2.487274, 2.477156, 2.467114, 2.45715, 2.447264, 2.437457, 2.427732, 2.41809, 2.408531, 2.399057, 2.38967, 2.380369, 2.371158, 2.362036, 2.353005, 2.344066, 2.335221, 2.32647, 2.317815, 2.309256, 2.300796, 2.292434, 2.284172, 2.276011, 2.267952, 2.259997, 2.252145, 2.244398, 2.236758, 2.229224, 2.221798, 2.214481, 2.207274, 2.200177, 2.193192, 2.186319, 2.179559, 2.172913, 2.166382, 2.159966, 2.153666, 2.147482, 2.141417, 2.135469, 2.12964, 2.123931, 2.118341, 2.112872, 2.107523, 2.102296, 2.097191, 2.092208, 2.087347, 2.08261, 2.077995, 2.073504, 2.069137, 2.064893, 2.060773, 2.056777, 2.052905, 2.049157, 2.045532, 2.04203, 2.038651, 2.035395, 2.032261, 2.029249, 2.026358, 2.023588, 2.020939, 2.018407, 2.015991, 2.01368, 2.011458, 2.009289, 2.007105, 2.004785, 2.002181, 1.999329, 1.996604, 1.994163, 1.991875, 1.989603, 1.98727, 1.984837, 1.982287, 1.979612, 1.976812, 1.973885, 1.970833, 1.967656, 1.964356, 1.960931, 1.957382, 1.95371, 1.949914, 1.945993, 1.941949, 1.93778, 1.933488, 1.929071, 1.92453, 1.919866, 1.915078, 1.910167, 1.905133, 1.899977, 1.894698, 1.889298, 1.883777, 1.878135, 1.872372, 1.866491, 1.86049, 1.854371, 1.848134, 1.84178, 1.83531, 1.828724, 1.822024, 1.815209, 1.808282, 1.801242, 1.79409, 1.786828, 1.779455, 1.771974, 1.764386, 1.75669, 1.748888, 1.740981, 1.73297, 1.724855, 1.716639, 1.708322, 1.699906, 1.69139, 1.682776, 1.674067, 1.665261, 1.656362, 1.647369, 1.638284, 1.629109, 1.619844, 1.61049, 1.60105, 1.591523, 1.581912, 1.572218, 1.562442, 1.552585, 1.542648, 1.532633, 1.522542, 1.512375, 1.502134, 1.49182, 1.481434, 1.470979, 1.460455, 1.449864, 1.439207, 1.428486, 1.417701, 1.406856, 1.39595, 1.384985, 1.373964, 1.362886, 1.351755, 1.340571, 1.329336, 1.318051, 1.306718, 1.295338, 1.283913, 1.272445, 1.260935, 1.249384, 1.237794, 1.226167, 1.214505, 1.202808, 1.191079, 1.179318, 1.167529, 1.155712, 1.143868, 1.132, 1.12011, 1.108198, 1.096266, 1.084317, 1.072351, 1.060371, 1.048377, 1.036373, 1.024358, 1.012336, 1.000308, 0.9882749, 0.9762391, 0.9642021, 0.9521656, 0.9401314, 0.9281011, 0.9160765, 0.9040592, 0.8920511, 0.8800538, 0.868069, 0.8560985, 0.844144, 0.8322073, 0.8202901, 0.8083941, 0.7965211, 0.7846728, 0.772851, 0.7610574, 0.7492938, 0.7375619, 0.7258634, 0.7142003, 0.7025741, 0.6909866, 0.6794396, 0.6679349, 0.6564742, 0.6450593, 0.6336918, 0.6223737, 0.6111065, 0.5998921, 0.5887323, 0.5776286, 0.566583, 0.5555971, 0.5446727, 0.5338115, 0.5230152, 0.5122855, 0.5016242, 0.491033, 0.4805136, 0.4700677, 0.459697, 0.4494031,0.4391878, 0.4290528, 0.4189996, 0.40903, 0.3991457, 0.3893482, 0.3796392, 0.3700203, 0.3604931, 0.3510593, 0.3417204, 0.332478, 0.3233336, 0.314289, 0.3053455, 0.2965047, 0.2877681, 0.2791373, 0.2706137, 0.2621988, 0.253894, 0.2457009, 0.2376208, 0.2296551, 0.2218053, 0.2140727, 0.2064586, 0.1989645, 0.1915917, 0.1843413, 0.1772149, 0.1702135, 0.1633384, 0.1565909, 0.1499722, 0.1434834, 0.1371257, 0.1309002, 0.1248081, 0.1188504, 0.1130282, 0.1073426, 0.1017945, 0.09638493, 0.0911149, 0.08598533, 0.08099713, 0.07615118, 0.07144836, 0.06688948, 0.06247536, 0.05820678, 0.05408449, 0.05010921, 0.04628163, 0.04260242, 0.03907221, 0.03569162, 0.0324612, 0.02938152, 0.02645307, 0.02367636, 0.02105183, 0.0185799, 0.01626096, 0.01409538, 0.01208347, 0.01022553, 0.008521817, 0.006972563, 0.005577959, 0.004338162, 0.003253297, 0.002323452, 0.001548677, 0.000928989, 0.0004643624, 0.0001547344, 3.075445e-17, 0.0]) assert test.like(x3.value, [0.0, 0.0120359, 0.02406854, 0.03609576, 0.04811539, 0.06012527, 0.0721232, 0.08410702, 0.09607454, 0.1080236, 0.119952, 0.1318577, 0.1437384, 0.155592, 0.1674164, 0.1792096, 0.1909693, 0.2026934, 0.21438, 0.2260269, 0.2376321, 0.2491935, 0.2607091, 0.2721769, 0.2835949, 0.294961, 0.3062734, 0.31753, 0.3287289, 0.3398682, 0.350946, 0.3619604, 0.3729094, 0.3837913, 0.3946042, 0.4053463, 0.4160157, 0.4266107, 0.4371296, 0.4475704, 0.4579317, 0.4682115, 0.4784083, 0.4885203, 0.498546, 0.5084836, 0.5183317, 0.5280885, 0.5377527, 0.5473225, 0.5567965, 0.5661733, 0.5754513, 0.5846291, 0.5937052, 0.6026784, 0.6115471, 0.6203101,0.6289661, 0.6375136, 0.6459515, 0.6542785, 0.6624934, 0.6705949, 0.6785819, 0.6864532, 0.6942078, 0.7018444, 0.7093619, 0.7167595, 0.7240359, 0.7311903, 0.7382216, 0.7451288, 0.751911, 0.7585674, 0.765097, 0.7714989, 0.7777724, 0.7839166, 0.7899307, 0.795814, 0.8015657, 0.8071851, 0.8126715, 0.8180243, 0.8232428, 0.8283263, 0.8332743, 0.8380862, 0.8427614, 0.8472995, 0.8516999, 0.8559621, 0.8600856, 0.8640701, 0.8679151, 0.8716202, 0.875185, 0.8786092, 0.8818925, 0.8850345, 0.888035, 0.8908936, 0.8936102, 0.8961845, 0.8986163, 0.9009054, 0.9030517, 0.905055, 0.9069152, 0.9086321, 0.9102058, 0.9116361, 0.912923, 0.9140664, 0.9150664, 0.9159229, 0.916636, 0.9172057, 0.9176321, 0.9179153, 0.9180554, 0.9180524, 0.9179066, 0.9176181, 0.917187, 0.9166136, 0.915898, 0.9150404, 0.9140412, 0.9129006, 0.9116188, 0.9101961, 0.9086329, 0.9069294, 0.9050861, 0.9031032, 0.9009811, 0.8987203, 0.896321, 0.8937839, 0.8911092, 0.8882974, 0.8853491, 0.8822646, 0.8790446, 0.8756894, 0.8721997, 0.8685759, 0.8648187, 0.8609286, 0.8569063, 0.8527522, 0.8484671, 0.8440516, 0.8395063, 0.8348319, 0.8300291, 0.8250986, 0.8200411, 0.8148573, 0.8095479, 0.8041138,0.7985557, 0.7928743, 0.7870706, 0.7811452, 0.7750991, 0.7689331, 0.7626479, 0.7562446, 0.749724, 0.743087, 0.7363345, 0.7294674, 0.7224868, 0.7153934, 0.7081884, 0.7008728, 0.6934474, 0.6859134, 0.6782717, 0.6705234, 0.6626696, 0.6547113, 0.6466496, 0.6384856, 0.6302205, 0.6218553, 0.6133912, 0.6048293, 0.5961707, 0.5874168, 0.5785686, 0.5696274, 0.5605944, 0.5514707, 0.5422577, 0.5329566, 0.5235686, 0.5140951, 0.5045372, 0.4948964, 0.4851739, 0.475371, 0.4654891, 0.4555295, 0.4454936, 0.4353827, 0.4251982, 0.4149415,0.4046139, 0.3942169, 0.3837519, 0.3732204, 0.3626236, 0.3519632, 0.3412405, 0.3304569, 0.3196141, 0.3087133, 0.2977562, 0.2867441, 0.2756786, 0.2645612, 0.2533933, 0.2421766, 0.2309124, 0.2196023, 0.2082479, 0.1968507, 0.1854123, 0.173934, 0.1624176, 0.1508646, 0.1392763, 0.1276545, 0.1160004, 0.1043157, 0.09260163, 0.08085983, 0.06909194, 0.0573, 0.04548684, 0.03365672, 0.02181669, 0.009979397, -0.001831889, -0.01358391, -0.02527805, -0.03700278, -0.04878966, -0.06060719, -0.07242789, -0.08423659, -0.09602515, -0.1077889, -0.1195251, -0.1312319, -0.1429077, -0.1545514, -0.1661616, -0.1777372, -0.1892768, -0.2007789, -0.212242, -0.2236647, -0.2350455, -0.2463827, -0.2576749, -0.2689205, -0.2801179, -0.2912657, -0.3023623, -0.3134061, -0.3243957, -0.3353296, -0.3462063, -0.3570242, -0.3677819, -0.3784778, -0.3891107, -0.3996789, -0.410181, -0.4206156, -0.4309812, -0.4412765, -0.4514999, -0.4616502, -0.4717258, -0.4817255, -0.4916479, -0.5014915, -0.511255, -0.5209372, -0.5305366, -0.5400519, -0.5494819, -0.5588253, -0.5680807, -0.5772469, -0.5863227, -0.5953067, -0.6041978, -0.6129947, -0.6216963, -0.6303013, -0.6388086, -0.6472169, -0.6555252, -0.6637322, -0.671837, -0.6798382, -0.6877349, -0.695526, -0.7032104, -0.7107869, -0.7182547, -0.7256126, -0.7328596, -0.7399948, -0.7470171, -0.7539256, -0.7607193, -0.7673973, -0.7739586, -0.7804023,-0.7867276, -0.7929335, -0.7990192, -0.8049837, -0.8108264, -0.8165463, -0.8221427, -0.8276147, -0.8329615, -0.8381825, -0.8432768, -0.8482438, -0.8530826, -0.8577926, -0.8623732, -0.8668236, -0.8711432, -0.8753313, -0.8793874, -0.8833108, -0.8871009, -0.8907571, -0.8942789, -0.8976658, -0.9009172, -0.9040325, -0.9070114, -0.9098533, -0.9125577, -0.9151243, -0.9175525, -0.919842, -0.9219924, -0.9240032, -0.9258741, -0.9276048, -0.929195, -0.9306443, -0.9319524, -0.933119, -0.9341439, -0.9350269, -0.9357676, -0.936366, -0.9368217, -0.9371347, -0.9373048, -0.9373318, -0.9372156, -0.9369561, -0.9365532, -0.9360069, -0.935317, -0.9344837, -0.9335068, -0.9323864, -0.9311225, -0.9297151, -0.9281644, -0.9264704, -0.9246331, -0.9226528, -0.9205296, -0.9182636, -0.9158551, -0.9133041, -0.9106111, -0.9077761, -0.9047995, -0.9016816, -0.8984226, -0.8950229, -0.8914829, -0.8878029, -0.8839834, -0.8800246, -0.8759272, -0.8716915, -0.8673179, -0.8628072, -0.8581596, -0.8533759, -0.8484565, -0.8434021, -0.8382133, -0.8328907, -0.827435, -0.8218469,-0.8161271, -0.8102762, -0.8042952, -0.7981847, -0.7919456, -0.7855787, -0.7790847, -0.7724648, -0.7657196, -0.7588501, -0.7518573, -0.7447422, -0.7375057, -0.7301489, -0.7226727, -0.7150783, -0.7073667, -0.6995391, -0.6915966, -0.6835403, -0.6753715, -0.6670912, -0.6587008, -0.6502015, -0.6415946, -0.6328813, -0.624063, -0.615141, -0.6061167, -0.5969914, -0.5877666, -0.5784437, -0.5690241, -0.5595093, -0.5499009, -0.5402002, -0.5304088, -0.5205284, -0.5105604, -0.5005064, -0.4903681, -0.480147, -0.4698449, -0.4594634,-0.4490041, -0.4384688, -0.4278592, -0.4171771, -0.4064241, -0.395602, -0.3847127, -0.3737579, -0.3627394, -0.3516591, -0.3405188, -0.3293203, -0.3180655, -0.3067564, -0.2953947, -0.2839825, -0.2725215, -0.2610138, -0.2494612, -0.2378658, -0.2262294, -0.214554, -0.2028417, -0.1910942, -0.1793138, -0.1675022, -0.1556616, -0.1437939, -0.1319011, -0.1199853, -0.1080484, -0.09609239, -0.08411938, -0.07213133, -0.06013027, -0.04811821, -0.03609714, -0.02406908, -0.01203603, -4.752194e-19, 0.0]) assert test.like(u.value, [0.0, 1.141285, 1.10648, 1.110143, 1.112781, 1.114577, 1.115979, 1.11707, 1.117704, 1.117975, 1.117991, 1.117814, 1.117485, 1.117034, 1.116483, 1.115854, 1.11516, 1.114415, 1.11363, 1.112812, 1.11197, 1.111107, 1.110227, 1.109333, 1.108427, 1.107511, 1.106585, 1.105649, 1.104703, 1.103748, 1.102782, 1.101806, 1.10082, 1.099822, 1.098812, 1.09779, 1.096755, 1.095707, 1.094646, 1.093571, 1.092483, 1.09138, 1.090264, 1.089134, 1.087989, 1.086831, 1.085659, 1.084474, 1.083275, 1.082063, 1.080838, 1.0796, 1.07835, 1.077089,1.075816, 1.074531, 1.073236, 1.071931, 1.070616, 1.069292, 1.067958, 1.066616, 1.065266, 1.063909, 1.062544, 1.061173, 1.059796, 1.058413, 1.057025, 1.055633, 1.054236, 1.052836, 1.051433, 1.050027, 1.048619,1.047209, 1.045799, 1.044387, 1.042976, 1.041565, 1.040155, 1.038746, 1.037339, 1.035935, 1.034533, 1.033135, 1.031741, 1.030351, 1.028966, 1.027586, 1.026213, 1.024846, 1.023485, 1.022133, 1.020788, 1.019452,1.018124, 1.016806, 1.015498, 1.0142, 1.012913, 1.011636, 1.010372, 1.009119, 1.007878, 1.00665, 1.005435, 1.004233, 1.003045, 1.00187, 1.00071, 0.9995647, 0.9984339, 0.9973181, 0.9962175, 0.9951325, 0.9940632, 0.9930098, 0.9919725, 0.9909515, 0.989947, 0.988959, 0.9879879, 0.9870336, 0.9860962, 0.9851759, 0.9842728, 0.9833869, 0.9825183, 0.9816669, 0.9808329, 0.9800163, 0.9792169, 0.9784349, 0.9776702, 0.9769227, 0.9761924, 0.9754792, 0.974783, 0.9741037, 0.9734412, 0.9727952, 0.9721658, 0.9715527, 0.9709556, 0.9703745, 0.9698091, 0.9692592, 0.9687246, 0.968205, 0.9677001, 0.9672097, 0.9667334, 0.9662711, 0.9658223, 0.9653868, 0.9649641, 0.9645541, 0.9641561, 0.96377, 0.9633953, 0.9630316, 0.9626785, 0.9623354, 0.9620021, 0.9616779, 0.9613625, 0.9610553, 0.9607557, 0.9604633, 0.9601775, 0.9598977, 0.9596233, 0.9593537, 0.9590883, 0.9588264, 0.9585674, 0.9583105, 0.958055, 0.9578002, 0.9575453, 0.9572895, 0.957032, 0.9567719, 0.9565084, 0.9562405, 0.9559673, 0.9556878, 0.9554011, 0.955106, 0.9548014, 0.9544864, 0.9541596, 0.9538198, 0.9534658, 0.9530962, 0.9527097, 0.9523047, 0.9518798, 0.9514333, 0.9509635, 0.9504686, 0.9499467, 0.9493957, 0.9488135, 0.9481976, 0.9475455, 0.9468544, 0.9461213, 0.9453429, 0.9445155, 0.943635, 0.942697, 0.9416964, 0.9406274, 0.9394835, 0.9382575, 0.9369408, 0.9355238, 0.9340117, 0.9324096, 0.9307068, 0.9288909, 0.926947, 0.9248581, 0.9226039, 0.9201612, 0.9175035, 0.9146009, 0.9114214, 0.9079325, 0.9041047, 0.8999173, 0.8953683, 0.890486, 0.8853435, 0.8800661, 0.8748178, 0.8697326, 0.8647418, 0.8592182, 0.8513293, 0.8368962, 0.8073544, 0.7460418, 0.6214726, 0.3747623, -0.1040045, -0.959582, -1.99966, -1.762497, 0.9112015, 1.999294, 1.076977, 0.1153686, -0.4330951, -0.7021474, -0.8258591, -0.8770839, -0.8942374, -0.8970691, -0.8940893, -0.8906796, -0.8892951, -0.8901524, -0.8925633, -0.8959036, -0.8997412, -0.9037485, -0.9077083, -0.9114936, -0.9150413, -0.9183291, -0.9213588, -0.9241454, -0.9267093, -0.9290731, -0.9312586, -0.9332859, -0.9351732, -0.9369363, -0.9385891, -0.9401436, -0.941596, -0.942943, -0.9441951, -0.9453615, -0.9464503, -0.9474686, -0.9484224, -0.9493172, -0.950158, -0.9509489, -0.951694, -0.9523965, -0.9530598, -0.9536866, -0.9542795, -0.954841, -0.9553732, -0.9558782, -0.9563579, -0.9568141, -0.9572484, -0.9576625, -0.9580577, -0.9584355, -0.9587973, -0.9591442, -0.9594776, -0.9597987, -0.9601084, -0.9604079, -0.9606983, -0.9609805, -0.9612555, -0.9615242, -0.9617875, -0.9620463, -0.9623015, -0.9625537, -0.9628039, -0.9630528, -0.9633011, -0.9635496, -0.9637989, -0.9640496, -0.9643025, -0.9645582, -0.9648173, -0.9650803, -0.9653479, -0.9656206, -0.9658989, -0.9661833, -0.9664744, -0.9667726, -0.9670785, -0.9673923, -0.9677147, -0.9680459, -0.9683865, -0.9687368, -0.9690971, -0.9694679, -0.9698495, -0.9702422, -0.9706464, -0.9710623, -0.9714903, -0.9719306, -0.9723834, -0.9728492, -0.973328, -0.9738201, -0.9743258, -0.9748451, -0.9753784, -0.9759258, -0.9764873, -0.9770633, -0.9776538, -0.9782589, -0.9788787, -0.9795133, -0.9801628, -0.9808271, -0.9815065, -0.9822007, -0.9829099, -0.9836341, -0.9843731, -0.9851269, -0.9858955, -0.9866788, -0.9874767, -0.9882891, -0.9891158, -0.9899567, -0.9908117, -0.9916807, -0.9925633, -0.9934595, -0.994369,-0.9952916, -0.9962271, -0.9971753, -0.9981358, -0.9991084, -1.000093, -1.001089, -1.002096, -1.003114, -1.004142, -1.005181, -1.006229, -1.007287, -1.008354, -1.00943, -1.010514, -1.011605, -1.012704, -1.01381, -1.014923, -1.016041, -1.017165, -1.018294, -1.019427, -1.020564, -1.021705, -1.022849, -1.023995, -1.025143, -1.026292, -1.027442, -1.028592, -1.029741, -1.030889, -1.032036, -1.033181, -1.034323, -1.035462, -1.036598, -1.037729, -1.038855, -1.039976, -1.041091, -1.042199, -1.043301, -1.044396, -1.045482, -1.04656, -1.047629, -1.048688, -1.049737, -1.050776, -1.051804, -1.05282, -1.053824, -1.054815, -1.055793, -1.056757, -1.057707, -1.058642, -1.059562, -1.060466, -1.061354, -1.062225, -1.063079, -1.063914, -1.064731, -1.06553, -1.066308, -1.067067, -1.067805, -1.068522, -1.069217, -1.06989, -1.070541, -1.071168, -1.071771, -1.07235, -1.072905, -1.073434, -1.073937, -1.074413, -1.074863, -1.075285, -1.075679, -1.076044, -1.07638, -1.076686, -1.076962, -1.077206, -1.07742, -1.077601, -1.077749, -1.077864, -1.077944, -1.07799, -1.078, -1.077973, -1.077909, -1.077807, -1.077665, -1.077482, -1.077257, -1.076988, -1.076674, -1.076312, -1.0759, -1.075435, -1.074914, -1.074332, -1.073686, -1.072969, -1.072176, -1.071298, -1.070328, -1.069249, -1.067973]) assert test.like(scale.value, [6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514, 6.018514])
def solve_elecar(inputs, t_interval=10): m = GEKKO() #Parameters v = m.Param(value=inputs['v']) # input voltage to the motor (volts) rm = m.Param(value=inputs['rm']) # motor resistance (ohm) lm = m.Param(value=inputs['lm']) # motor inductance (henrys) kb = m.Param(value=6.5e-4) # back emf constant (volt-sec/rad) kt = m.Param(value=0.1) # torque constant (N-m/a) jm = m.Param(value=inputs['jm']) # rotor inertia (kg m^2) bm = m.Param(value=inputs['bm'] ) # mechanical damping (linear model of friction: bm * dth) # automobile parameters jl = m.Param(value=inputs['jl']) # vehicle inertia (1000 times the rotor) bl = m.Param(value=inputs['bl']) # vehicle damping (friction) k = m.Param( value=inputs['k']) # spring constant for connection rotor/drive shaft b = m.Param( value=inputs['b']) # spring damping for connection rotor/drive shaft rl = m.Param( value=inputs['rl'] ) # gearing ratio between motor and tire (meters travelled per radian of motor rotation) tau = m.Param( value=2 ) # time constant of a lag between motor torque and car velocity. this lag is a simplified model of the power train. (sec) i = m.Var(value=0) # motor electrical current (amps) dth_m = m.Var( value=0) # rotor angular velocity sometimes called omega (radians/sec) th_m = m.Var(value=0) # rotor angle, theta (radians) dth_l = m.Var(value=0) # wheel angular velocity (rad/sec) th_l = m.Var(value=0) # wheel angle (radians) dth_v = m.Var(value=0) # vehicle velocity (m/sec) th_v = m.Var(value=0) # distance travelled (m) m.time = np.linspace(0, t_interval, 100) m.Equation(lm * i.dt() - v == -rm * i - kb * th_m.dt()) m.Equation(jm * dth_m.dt() == kt * i - (bm + b) * th_m.dt() - k * th_m + b * th_l.dt() + k * th_l) m.Equation(jl * dth_l.dt() == b * th_m.dt() + k * th_m - (b + bl) * th_l.dt() - k * th_l) m.Equation(tau * dth_v.dt() == rl * dth_l - dth_v) m.Equation(dth_m == th_m.dt()) m.Equation(dth_l == th_l.dt()) m.Equation(dth_v == th_v.dt()) m.options.IMODE = 4 m.solve(disp=False) res_dict = {} for var in valid_vars: res_dict[var] = eval(var).value[-1] res_dict["t"] = m.time return res_dict
def solve09(): # Solve Differential Equation(s) # measurements m = GEKKO() m.time = np.linspace(0, 20, 100) k = 10 y = m.Var(value=5.0) t = m.Param(value=m.time) m.Equation(k * y.dt() == -t * y) m.options.IMODE = 4 m.solve(disp=False) plt.plot(m.time, y.value) plt.xlabel('time') plt.ylabel('y') plt.show()
def init_solver(G, w, num_tasks, task_prev, task_ordering): m = GEKKO() # Use IPOPT solver (default) m.options.SOLVER = 3 # Change to parallel linear solver m.solver_options = ['linear_solver ma97'] # variable array dimension # create array s = m.Array(m.Var, num_tasks) for i in range(num_tasks): s[i].value = 2.0 s[i].lower = 0 M = m.Var(value=5, lb=0) P = m.Var(value=5, lb=0) # define completion time of each task c = m.Array(m.Var, num_tasks) for i in range(num_tasks): c[i].value = 0 c[i].lower = 0 #1b # task's completion time must be later than the time to run task itself for i in range(num_tasks): m.Equation(w[i] / s[i] <= c[i]) #1c # task must start later than all ancestors for i in range(num_tasks): for j in nx.algorithms.ancestors(G, i): m.Equation(c[j] + (w[i] / s[i]) <= c[i]) # task must start later than previous task on machine for task, prev in task_prev.items(): if prev != None: m.Equation(c[prev] + (w[task] / s[task]) <= c[task]) #1d # Total load assigned to each machine should not be greater than the makespan for lst in task_ordering: m.Equation(sum([w[i] / s[i] for i in lst]) <= M) #1e (define M in objective function) for i in range(num_tasks): m.Equation(c[i] <= M) # define P in objective function m.Equation(sum([s[i] for i in range(num_tasks)]) == P) return m, s, c, P, M
def solve12(): # Model Predictive Control m = GEKKO() m.time = np.linspace(0, 20, 41) # Parameters mass = 500 b = m.Param(value=50) K = m.Param(value=0.8) # Manipulated variable p = m.MV(value=0, lb=0, ub=100) p.STATUS = 1 # allow optimizer to change p.DCOST = 0.1 # smooth out gas pedal movement p.DMAX = 20 # slow down change of gas pedal # Controlled Variable v = m.CV(value=0) v.STATUS = 1 # add the SP to the objective m.options.CV_TYPE = 2 # squared error v.SP = 40 # set point v.TR_INIT = 1 # set point trajectory v.TAU = 5 # time constant of trajectory # Process model m.Equation(mass * v.dt() == -v * b + K * b * p) m.options.IMODE = 6 # control m.solve(disp=False) # get additional solution information import json with open(m.path + '//results.json') as f: results = json.load(f) plt.figure() plt.subplot(2, 1, 1) plt.plot(m.time, p.value, 'b-', label='MV Optimized') plt.legend() plt.ylabel('Input') plt.subplot(2, 1, 2) plt.plot(m.time, results['v1.tr'], 'k-', label='Reference Trajectory') plt.plot(m.time, v.value, 'r--', label='CV Response') plt.ylabel('Output') plt.xlabel('Time') plt.legend(loc='best') plt.show()
def solve07(): # Linear and Polynomial Regression xm = np.array([0, 1, 2, 3, 4, 5]) ym = np.array([0.1, 0.2, 0.3, 0.5, 1.0, 0.9]) xm = np.array([0, 1, 2, 3, 4, 5]) ym = np.array([0.1, 0.2, 0.3, 0.5, 0.8, 2.0]) #### Solution m = GEKKO() m.options.IMODE = 2 # coefficients c = [m.FV(value=0) for i in range(4)] x = m.Param(value=xm) y = m.CV(value=ym) y.FSTATUS = 1 # polynomial model m.Equation(y == c[0] + c[1] * x + c[2] * x**2 + c[3] * x**3) # linear regression c[0].STATUS = 1 c[1].STATUS = 1 m.solve(disp=False) p1 = [c[1].value[0], c[0].value[0]] # quadratic c[2].STATUS = 1 m.solve(disp=False) p2 = [c[2].value[0], c[1].value[0], c[0].value[0]] # cubic c[3].STATUS = 1 m.solve(disp=False) p3 = [c[3].value[0], c[2].value[0], c[1].value[0], c[0].value[0]] # plot fit plt.plot(xm, ym, 'ko', markersize=10) xp = np.linspace(0, 5, 100) plt.plot(xp, np.polyval(p1, xp), 'b--', linewidth=2) plt.plot(xp, np.polyval(p2, xp), 'r--', linewidth=3) plt.plot(xp, np.polyval(p3, xp), 'g:', linewidth=2) plt.legend(['Data', 'Linear', 'Quadratic', 'Cubic'], loc='best') plt.xlabel('x') plt.ylabel('y') plt.show()
def get_optimized_loan_attributes(loanAmount0, loanPeriod0, predictedGood0, par, cutOff): n = GEKKO() #internet connection is needed for the GEKKO library to work! #'a' - value between '0' and '1'. #Closer to '1' means loan amount will not change much. #Closer to '0' - loan period will not change much a = 0.9 x1 = n.Var(loanAmount0, 200.0, 160000.0) #starting value, lower boundary, upper boundary x2 = n.Var(loanPeriod0, 2.0, 60.0) n.Equation(predictedGood0 - par[0] * loanAmount0 - par[1] * loanPeriod0 + par[0] * x1 + par[1] * x2 > cutOff) n.Obj(a*(((x1 - loanAmount0)/loanAmount0)**2) + (1 - a)*(((x2 - loanPeriod0)/loanPeriod0)**2)) try: n.solve(disp=False) return [x1.value[0], x2.value[0]] except: return [0, 0]
def optimum_solution(): m = GEKKO() m.options.SOLVER = 1 lane_1 = m.Var(integer=True, lb=0, ub=individual_lane_capacity) lane_2 = m.Var(integer=True, lb=0, ub=individual_lane_capacity) lane_3 = m.Var(integer=True, lb=0, ub=individual_lane_capacity) m.Minimize(lane_1 * ((distance / speed_slow_lane) * (1 + alpha * ((lane_1 / individual_lane_capacity)**beta))) + lane_2 * ((distance / speed_medium_lane) * (1 + alpha * ((lane_2 / individual_lane_capacity)**beta))) + lane_3 * ((distance / speed_fast_lane) * (1 + alpha * ((lane_3 / individual_lane_capacity)**beta)))) m.Equation(lane_1 + lane_2 + lane_3 == total_num_drivers) m.solve(disp=False) print('Following are results for OPTIMUM traffic placement: ') print('lane one traffic: ' + str(lane_1.value[0])) print('lane two traffic: ' + str(lane_2.value[0])) print('lane three traffic: ' + str(lane_3.value[0])) opt_traffic = [lane_1.value[0], lane_2.value[0], lane_3.value[0]] print(f1(opt_traffic[0]), f2(opt_traffic[1]), f3(opt_traffic[2])) return (opt_traffic)
def threePlayersEUtility(): eq = GEKKO(remote=False) p, q, r = eq.Var(), eq.Var(), eq.Var() ## U1(A) == U1(B) eq.Equation(q * p * Fraction(self.utility_tableau[0][0][0][0]) + p * (1 - q) * self.utility_tableau[0][1][0][0] + (1 - p) * q * self.utility_tableau[0][0][1][0] + (1 - p) * (1 - q) * self.utility_tableau[0][1][1][0] == q * p * self.utility_tableau[1][0][0][0] + p * (1 - q) * self.utility_tableau[1][1][0][0] + (1 - p) * q * self.utility_tableau[1][0][1][0] + (1 - p) * (1 - q) * self.utility_tableau[1][1][1][0]) ## U2(A) == U2(B) eq.Equation(r * p * self.utility_tableau[0][0][0][1] + (1 - r) * p * self.utility_tableau[1][0][0][1] + r * (1 - p) * self.utility_tableau[0][0][1][1] + (1 - r) * (1 - p) * self.utility_tableau[1][0][1][1] == r * p * self.utility_tableau[0][1][0][1] + (1 - r) * p * self.utility_tableau[1][1][0][1] + r * (1 - p) * self.utility_tableau[0][1][1][1] + (1 - r) * (1 - p) * self.utility_tableau[1][1][1][1]) ## U3(A) == U3(B) eq.Equation(r * q * self.utility_tableau[0][0][0][2] + (1 - q) * r * self.utility_tableau[0][1][0][2] + (1 - r) * q * self.utility_tableau[1][0][0][2] + (1 - r) * (1 - q) * self.utility_tableau[1][1][0][2] == r * q * self.utility_tableau[0][0][1][2] + (1 - q) * r * self.utility_tableau[0][1][1][2] + (1 - r) * q * self.utility_tableau[1][0][1][2] + (1 - r) * (1 - q) * self.utility_tableau[1][1][1][2]) eq.Equation(0 <= r) eq.Equation(r <= 1) eq.Equation(0 <= q) eq.Equation(q <= 1) eq.Equation(0 <= p) eq.Equation(p <= 1) eq.solve(disp=False) return q.value[0], r.value[0], p.value[0]
mass = m.Var(value=m0)#, lb=m0-mp0, ub=m0) tave = mp0 * Isp * g / tsp step = [0 if z > tsp else tave for z in t_array * tf.value] ft = m.Param(value=step) rho = m.Intermediate( 1.22 * m.exp(-0.000091 * y + -1.88e-9 * y**2 )) q = m.Intermediate(0.5 * rho * v ** 2.) cd0 = m.Var(value=0.02) cdf = m.Var(value=0.5) cna = m.Var(value=0.2) cs = m.Intermediate(-0.00117 * y + 340.288) mn = m.Var(value=0.0) m.Equation(mn == v / cs) t_mn = [0.3, 0.5, 0.9, 1.2, 1.5, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0] t_cd0 = [0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01] t_cdf = [0.5, 0.6, 0.7, 0.8, 0.65, 0.6, 0.5, 0.4, 0.3, 0.25, 0.2] t_cna = [0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2] m.cspline(mn, cd0, t_mn, t_cd0, True) m.cspline(mn, cdf, t_mn, t_cdf, True) m.cspline(mn, cna, t_mn, t_cdf, True) ca = m.Intermediate(cd0 + cdf * 0.68) cn = m.Intermediate(cna * 8.1 * alpha) fa = m.Intermediate(q * ca * S) fn = m.Intermediate(q * cn * S)
VAR_R1 = 0.01 VAR_R2 = 0.04**2/12 # risk in 10^12 change for different values # V = 0.1 # for V = 1*10^11 # V = 0.2 # for V = 2*10^11 V = 0.4 # for V = 4*10^11 # Defining decesion variable A = m.Var(value = 2*L/3,lb=0,ub=L) # Adding constrains to model m.Equation(A*A*VAR_R1 + (L-A)*(L-A)*VAR_R2 <= V) m.Equation((L-A) <= 1) # additional constrain # Adding Objective function to model m.Obj(-(E_R1*A+E_R2*(L-A))) # Solving model m.solve(disp = False) ################################################### for printing results ################################################################################### actual_A = A.value[0] AC = actual_A actual_VAR = AC*AC*VAR_R1 + (L-AC)*(L-AC)*VAR_R2
TH1 = m.SV() TH2 = m.SV() TC1 = m.CV() TC2 = m.CV() # Heater Temperatures in Kelvin T1 = m.Intermediate(TH1 + 273.15) T2 = m.Intermediate(TH2 + 273.15) # Heat transfer between two heaters Q_C12 = m.Intermediate(Us * As * (T2 - T1)) # Convective Q_R12 = m.Intermediate(eps * sigma * As * (T2**4 - T1**4)) # Radiative # Energy balances m.Equation(TH1.dt() == (1.0/(mass*Cp))*(U*A*(Ta-T1) \ + eps * sigma * A * (Ta**4 - T1**4) \ + Q_C12 + Q_R12 \ + alpha1*Q1)) m.Equation(TH2.dt() == (1.0/(mass*Cp))*(U*A*(Ta-T2) \ + eps * sigma * A * (Ta**4 - T2**4) \ - Q_C12 - Q_R12 \ + alpha2*Q2)) # Conduction to temperature sensors m.Equation(tau * TC1.dt() == TH1 - TC1) m.Equation(tau * TC2.dt() == TH2 - TC2) # Options # STATUS=1 allows solver to adjust parameter U.STATUS = 1 Us.STATUS = 1
import numpy as np from gekko import GEKKO import matplotlib.pyplot as plt m = GEKKO() # create GEKKO model k = m.Param() # constant y = m.Var(5.0) # create GEKKO variable m.Equation(y.dt() == -k * y) # create GEKKO equation m.time = np.linspace(0, 20) # time points # solve ODEs and plot m.options.IMODE = 4 m.options.TIME_SHIFT = 0 k.value = 0.1 m.solve() plt.plot(m.time, y, 'r-', linewidth=2, label='k=0.1') k.value = 0.2 m.solve() plt.plot(m.time, y, 'b--', linewidth=2, label='k=0.2') k.value = 0.5 m.solve() plt.plot(m.time, y, 'g:', linewidth=2, label='k=0.3') plt.xlabel('time') plt.ylabel('y(t)') plt.legend() plt.show()
resolution = 10 m = GEKKO() m.time = np.linspace(0, years, years * resolution + 1) H = m.Var(1e6) I = m.Var(0) V = m.Var(100) kr1 = m.Param(1e5) # new healthy cells per year kr2 = m.Param(0.1) # death rate of healthy cells kr3 = m.Param(2e-7) # healthy cells converting to infected cells kr4 = m.Param(0.5) # death rate of infected cells kr5 = m.Param(5) # death rate of virus kr6 = m.Param(100) # production of virus by infected cells m.Equation(H.dt() == kr1 - kr2 * H - kr3 * H * V) m.Equation(I.dt() == kr3 * H * V - kr4 * I) m.Equation(V.dt() == -kr3 * H * V - kr5 * V + kr6 * I) m.options.IMODE = 4 m.options.NODES = 3 m.solve() fig, ax = plt.subplots(1, 1, figsize=(8, 5)) ax.semilogy(m.time, H, 'b-', label=r'H') ax.semilogy(m.time, I, 'g:', label=r'I') ax.semilogy(m.time, V, 'r-', linewidth=2, label=r'V') plt.xlabel('Time (years)') plt.ylabel('States (log scale)') plt.legend()
from gekko import GEKKO m = GEKKO(remote=False) x, y = m.Array(m.Var, 2) m.Equation(y == m.sigmoid(x)) m.Minimize((y - 0.2)**2) m.solve() print(x.value[0], y.value[0])
m.time = np.linspace(0, tf, 2 * tf + 1) step = np.zeros(2 * tf + 1) step[3:40] = 2.0 step[40:] = 5.0 # Controller model Kc = 15.0 # controller gain tauI = 2.0 # controller reset time tauD = 1.0 # derivative constant OP_0 = m.Const(value=0.0) # OP bias OP = m.Var(value=0.0) # controller output PV = m.Var(value=0.0) # process variable SP = m.Param(value=step) # set point Intgl = m.Var(value=0.0) # integral of the error err = m.Intermediate(SP - PV) # set point error m.Equation(Intgl.dt() == err) # integral of the error m.Equation(OP == OP_0 + Kc * err + (Kc / tauI) * Intgl - PV.dt()) # Process model Kp = 0.5 # process gain tauP = 10.0 # process time constant m.Equation(tauP * PV.dt() + PV == Kp * OP) m.options.IMODE = 4 m.solve(disp=False) plt.figure() plt.subplot(2, 1, 1) plt.plot(m.time, OP.value, 'b:', label='OP') plt.ylabel('Output') plt.legend()
class MPCnode(Node): def __init__(self, id, x, y, nrj, ctrlHrz, ctrlRes): super().__init__(id, x, y, nrj) self.verbose = False self.errorFlag = False self.m = GEKKO(remote=False) # time points self.ctrlHrz = ctrlHrz # Control Horizon self.ctrlRes = ctrlRes # Control Resolution. Number of control steps within the control horizon self.m.time = np.linspace(0, self.ctrlHrz, self.ctrlRes) # constants self.Egen = 1 * 10**-5 #Counter for plots self.nrplots = 1 self.pltColors = ['r-', 'k-', 'b-', 'g-', 'y-', 'c-', 'm-'] self.labels = [ "Distance", "Velocity", "Energy Consumption", "Data Remaining", "Transmission Rate", "Battery" ] colorNr = rand.randrange(0, len(self.pltColors), 1) self.lineColor = self.pltColors[colorNr] #Threshold for when objective is seen as 0 self.limit = np.float64(1e-10) self.resetGEKKO() def resetGEKKO(self): self.errorFlag = False self.m = GEKKO(remote=False) self.m.time = np.linspace(0, self.ctrlHrz, self.ctrlRes) self.vp = np.zeros(self.ctrlRes) self.v = self.m.Param(value=self.vp) # define distance self.dist = self.m.Var() self.dtr = self.m.MV(value=0, integer=True, lb=0, ub=20) self.dtr.STATUS = 1 # define energy level self.nrj_stored = self.m.Var(value=self.energy, lb=0) self.data = self.m.Var() #self.data = self.m.CV() #self.data.STATUS = 1 #self.m.options.CV_TYPE = 2 # energy to transmit self.e = self.m.Intermediate(( (Eelec + EDA) * self.conChildren + self.dtr * self.pSize * (Eelec + Eamp * self.dist**2)) - self.Egen) #self.e = self.m.Var() #self.m.Equation(self.e == ((Eelec+EDA)*self.conChildren + self.dtr*self.pSize*(Eelec + Eamp * self.dist**2)) - self.Egen) # equations # track the position self.m.Equation(self.dist.dt() == self.v) self.m.Equation(self.nrj_stored.dt() == -self.e) self.m.Equation(self.nrj_stored >= self.e) # as data is transmitted, remaining data stored decreases self.m.Equation(self.data.dt() == -self.dtr * self.pSize) self.deadline = self.m.Var(value=self.ctrlHrz) self.dlCost = self.m.Var() self.m.Equation(self.deadline.dt() == -1) # self.m.Equation(self.energy >= self.e) # objective #self.data.SP = 0 # soft (objective constraint) self.recedingDeadline = np.zeros(self.ctrlRes) self.recedingDeadline[-1] = 100 self.final = self.m.Param(value=np.zeros(self.ctrlRes)) #self.final.value[self.ctrlRes//2:-1] = 0.001 self.final.value[-1] = 1 #self.m.Equation(self.final*(self.data)<=0) #self.m.Obj(self.e) # minimize energy #self.m.Obj(self.data*self.final) self.target = self.m.Intermediate((self.final * (0 - self.data)**2)) self.m.Obj(self.target) # transmit data by the end self.m.Obj(self.e) #self.m.Obj(self.final*self.data) # hard constraint # this form may cause infeasibility if it can't achieve # data=0 at the end #self.m.fix(self.data,self.ctrlRes-1,0) # options # Solutions forced to terminate early by the MAX_TIME # constraint do not satisfy the Karush Kuhn Tucker conditions for optimality. self.m.options.MAX_TIME = 10 self.m.options.IMODE = 6 # optimal control self.m.options.NODES = 3 # collocation nodes self.m.options.SOLVER = 1 # solver (IPOPT), 1 is for when integers is used as MV self.m.options.TIME_SHIFT = 1 # Setting for saving values from last solve() def produce_vVector(self, xVec, yVec): vVec = np.zeros(len(xVec)) for i in range(len(xVec) - 1): dist_Before = np.float64( np.sqrt((xVec[i] - self.xPos)**2 + (yVec[i] - self.yPos)**2)) dist_After = np.float64( np.sqrt((xVec[i + 1] - self.xPos)**2 + (yVec[i + 1] - self.yPos)**2)) vVec[i] = np.float64((dist_After - dist_Before) / (self.ctrlHrz / (self.ctrlRes - 1))) return vVec def setDesData(self, dat): if (type(self.data.value.value) is list): self.data.value[0] = dat * self.pSize else: self.data.value = dat * self.pSize def controlPR(self, velocity): tempVel = np.float64(velocity) tempNrj = np.float64(self.energy) tempDist = np.float64(self.getDistance(self.CHparent)) self.vp[0:] = self.v.value[1] if (tempVel == self.vp[0]): if self.verbose: print('Velocity: {0} was equal to vVal0: {1}'.format( tempVel, self.vp[0])) print('Therefore, velocity was set as vp[1:]') else: if self.verbose: print('Velocity: {0} was not equal to vVal0: {1}'.format( tempVel, self.v.value[0])) print('Therefore, vp[1:] was set as tempVel = {0}'.format( tempVel)) self.vp[1:] = tempVel self.v.value = self.vp if (type(self.data.value.value) is list): if (self.data.value.value[0] <= self.limit): self.datap = np.zeros(self.ctrlRes) self.data.value[0] = 0 #SETTING THE CURRENT ENERGY LEVEL if (type(self.nrj_stored.value.value) is list): self.nrj_stored.value[0] = tempNrj else: self.nrj_stored.value = tempNrj # define distance if (type(self.dist.value.value) is list): self.dist.value[0] = tempDist else: self.dist.value = tempDist if (type(self.dtr.value.value) is list): self.dtrp = np.zeros(self.ctrlRes) self.dtrp[0] = np.float64(self.PA) self.dtr.value = self.dtrp #self.dtr.value.value[0] = np.float64(self.PA) #self.nrj_stored.value[0] = self.nrj_stored.value[1] #self.data.value[0] = self.data.value[1] try: self.m.solve(disp=False) self.setPR(self.dtr.value[1]) #if (self.recedingDeadline[0] == 0): # self.recedingDeadline = np.roll(self.recedingDeadline,-1) #self.final.value = self.recedingDeadline except: print('EXCEPTION CAUGHT FOR NODE: {0}'.format(self.ID)) self.setPR(1) self.errorFlag = True def controlPR1(self, sink): self.v.value = self.produce_vVector(sink.xP.value, sink.yP.value) tempNrj = np.float64(self.energy) tempDist = np.float64(np.abs(self.getDistance(self.CHparent))) #if(type(self.data.value.value) is list): # if(self.data.value.value[0] <= self.limit): # self.data.value[0] = 0 #SETTING THE CURRENT ENERGY LEVEL if (type(self.nrj_stored.value.value) is list): #print('NRJ STORED WAS NOT FLOAT. IT WAS: {0}'.format(type(self.nrj_stored.value.value))) self.nrj_stored.value[0] = tempNrj else: self.nrj_stored.value = tempNrj # define distance if (type(self.dist.value.value) is list): #print('DIST WAS NOT INT, IT WAS: {0}'.format(type(self.dist.value.value))) self.dist.value[0] = tempDist else: self.dist.value = tempDist #if(self.data.value[0] <= limit): # self.data.value[0] = 0 #print(np.shape(testNode.vp)) if (type(self.dtr.value.value) is list): #self.dtrp = np.zeros(self.ctrlRes) #self.dtrp[0] = np.float64(self.PA) #self.dtr.value = self.dtrp self.dtr.value = self.dtr.NXTVAL #self.nrj_stored.value[0] = self.nrj_stored.value[1] #self.data.value[0] = self.data.value[1] """ self.dtrp = np.zeros(self.ctrlRes) self.dtrp[0] = self.dtr.value[1] self.dtr.value = self.dtrp self.nrj_storedp = np.zeros(self.ctrlRes) self.nrj_storedp[0] = self.nrj_stored.value[1] self.nrj_stored.value = self.nrj_storedp self.datap = np.zeros(self.ctrlRes) self.datap[0] = self.data.value[1] self.data.value = self.datap self.m.TIME_SHIFT = 1 """ #self.data.value[0] = self.data.value[1] try: self.m.solve(disp=False) self.setPR(self.dtr.value[1]) except: print('EXCEPTION CAUGHT') self.setPR(1) self.errorFlag = True def plot(self): #plt.cla() # Clear axis #plt.clf() # Clear figure #plt.close() # Close a figure window #by_label = OrderedDict(zip(labels, handles)) #plt.legend(by_label.values(), by_label.keys()) plt.figure(self.nrplots) plt.subplot(6, 1, 1) dist_line = plt.plot(self.m.time, self.dist.value, self.lineColor, label=self.labels[0]) distance_legend = plt.legend(handles=dist_line) plt.subplot(6, 1, 2) #plt.plot(self.m.time,self.v.value,self.lineColor,label=self.labels[1]) vel_line = plt.step(self.m.time, self.v.value, self.lineColor, label=self.labels[1], where='post') vel_legend = plt.legend(handles=vel_line) plt.subplot(6, 1, 3) #plt.plot(self.m.time,self.e.value,self.lineColor,label=self.labels[2]) energyCons_line = plt.step(self.m.time, self.e.value, self.lineColor, label=self.labels[2], where='post') nrjcons_legend = plt.legend(handles=energyCons_line) plt.subplot(6, 1, 4) dataRem_line = plt.plot(self.m.time, self.data.value, self.lineColor, label=self.labels[3]) #plt.bar(self.m.time, self.data.value, align='center', alpha=0.5) dataRem_legend = plt.legend(handles=dataRem_line) plt.subplot(6, 1, 5) #plt.plot(self.m.time, self.dtr.value,'r-',label='Transmission Rate') transmRate_line = plt.step(self.m.time, self.dtr.value, self.lineColor, label=self.labels[4], where='post') tr_legend = plt.legend(handles=transmRate_line) plt.subplot(6, 1, 6) battery_line = plt.plot(self.m.time, self.nrj_stored, self.lineColor, label=self.labels[5]) battery_legend = plt.legend(handles=battery_line) plt.xlabel('Time') #plt.show() self.nrplots += 1 def getDeltaDist(self, sinkX, sinkY, sdeltaX, sdeltaY, deltaDist): distBefore = np.sqrt((sinkX**2) + (sinkY**2)) distAfter = np.sqrt(((sinkX + sdeltaX)**2) + ((sinkY + sdeltaY)**2)) self.deltaDist = distAfter - distBefore return self.deltaDist
class solveMPC: def __init__(self, env): self.theta_goal = 70 self.thetadot_goal = 0 self.x_goal = env.X / 2 self.y_goal = env.Y self.last_u = 0 #Keep track of last input control def action(self, state, plot=False, integer_control=False): #Return a discrete action 0-21 based on the dynamic optimization solution. """ State Variables: These are the variables included in the dynamics Manipulated Variables: These are the control inputs """ # Initialize the GEKKO solver and set options: # The remote argument allows for the solver to be run on Brigham Young Universitie's public server self.m = GEKKO(remote=True) init_state = state self.m.options.IMODE = 6 # control if integer_control: self.m.options.SOLVER = 1 #Use APOPT Solver (only solver able to handle mixed integer) else: self.m.options.SOLVER = 3 #Use IPOPT Solver #Setup the solvers discretization array: # disc_length is the total number of discretization steps for the solver to discretize the problem disc_len = 501 self.disc_array = np.linspace( 0, 1, disc_len ) #Solver time steps (For variable final time, this will be scaled) self.m.time = self.disc_array #Fixed Varaibles: These are fixed over the horizon but able to change for each iteration #tf_scale is the final time variable. This is a trick to get the solver to solve a free final time problem self.tf_scale = self.m.FV(value=150, lb=1, ub=2000) self.tf_scale.STATUS = 1 # Parameters of environment (state space model) tau = self.m.Param(value=90) ku = self.m.Param(value=18) dist = self.m.Param(value=0) # Manipulated variables (Control Input) u = self.m.MV(value=self.last_u, lb=-10, ub=10, integer=integer_control) u_step_len = 30 #feet; the length overwhich control must stay constant u.MV_STEP_HOR = self.get_control_step(u_step_len, ku.value, state[2], self.theta_goal, disc_len) u.STATUS = 1 # allow optimizer to change u #Handle Units #States have the following units below: x:feet y:feet theta:deg thetadot:deg/ft #Convert units of states (1,1, deg->rad *Acutally ode is in deg, deg/100ft -> deg/ft) #State Input: x y thetao thetadoto convert_units = np.array([1, 1, 1, 1 / 100]) init_state = init_state * convert_units d2r = np.pi / 180 # State Variables x = self.m.SV(value=init_state[0], lb=-10000, ub=10000) y = self.m.SV(value=init_state[1], lb=-10000, ub=10000) theta = self.m.SV(value=init_state[2], lb=-20, ub=100) thetadot = self.m.SV(value=init_state[3], lb=-.3, ub=.3) thetadotmax = self.m.SV(value=ku.value, lb=-.3, ub=.3) # Initialize binary vector used to retreive the final state ( vector of all zeros except last element = 1 ) final = self.m.Param(np.zeros(self.m.time.shape[0])) final.value[-1] = 1 # Dynamics self.m.Equation(theta.dt() == thetadot * self.tf_scale) self.m.Equation( thetadot.dt() == -(1 / tau) * thetadot * self.tf_scale + (.01 * ku / tau) * u / 10 * self.tf_scale + .01 * dist / tau * self.tf_scale) self.m.Equation(x.dt() == self.m.cos(theta * d2r) * self.tf_scale) self.m.Equation(y.dt() == self.m.sin(theta * d2r) * self.tf_scale) self.m.Equation( thetadotmax >= thetadot) #This variable acts as max(thetadot) # Objective Functions self.m.Obj((thetadotmax)**2) self.m.Obj(10 * (x * final - self.x_goal)**2) self.m.Obj(10 * (y * final - self.y_goal)**2) self.m.Obj((theta * final - self.theta_goal)**2) self.m.Obj(.1 * (thetadot * final - self.thetadot_goal)**2) try: self.m.solve(disp=False) except: print('Enter Debug Mode') if plot: self.plot(u, x, y, theta, thetadot) self.last_u = u.value[1] action = int(round(u.value[1] / 10, 1) * 10 + 10) return action def get_control_step(self, desired_u_step, ku, thetao, theta_goal, disc_len): """ This function estimates the number of solver discretization steps that the control input should stay constant. We have to estimate what this value should be since the final time is free and the solver doesn't allow us to vary the control step size with each solver iteration. First guess the length of the optimal trajectory, then convert this from feet to discretization steps""" delta_theta = np.abs(thetao - theta_goal) curvature_max = ku #Calculate the average arc length if we were to drill with full curvature #and half curvature capabilities avg_arc_length = 3 / 2 * delta_theta / curvature_max * 100 u_solver_step = int(desired_u_step * disc_len / avg_arc_length) u_solver_step = max(u_solver_step, 1) return u_solver_step def plot(self, u, x, y, theta, thetadot): theta = np.array(theta.value) thetadot = np.array(thetadot.value) x = np.array(x.value) y = np.array(y.value) sim_t = self.disc_array * self.tf_scale.value[0] plt.subplot(3, 1, 1) plt.plot(sim_t, u.value, 'b-', label='Control Optimized') plt.legend() plt.ylabel('Input') plt.subplot(3, 1, 2) plt.plot(sim_t, theta, 'r--', label='Theta Response') plt.ylabel('Deg') plt.legend(loc='best') plt.subplot(3, 1, 3) plt.plot(sim_t, thetadot, 'r--', label='Theta_dot Response') plt.ylabel('Units') plt.xlabel('Measured Depth (ft)') plt.legend(loc='best') plt.show() plt.plot(y, -x, 'r--', label='Trajectory') plt.ylabel('TVD') plt.xlabel('Cross Section') plt.legend(loc='best') plt.grid() plt.show()
class MPC2ndLayer(): def __init__(self): self.verbose = False self.nrplots = 0 self.m = GEKKO(remote=False) # constants self.Egen = 1 * 10**-5 self.pSize = ps self.PERC = 0.4 self.nds = 50 # ALL NODES self.CHs = int(self.nds * self.PERC) # CLUSTER HEADS self.nonCHs = int(self.nds - self.CHs) # NON-CHs self.CHLst = [] # List of CH positions Param() self.CHdistLst = [] # List of CHs distances Var() self.nonCHLst = [] # List of non-CH positions Param() self.nonCHdistLst = [] # List of non-CHs distances Var() self.intermeds = [ ] # List of intermediate equations for energy consumption of nodes #Counter for plots self.nrplots = 1 """ This part is in case the LEACH protocol is to be used in the model. self.dm1 = np.sum(self.CHdistLst)/len(self.CHdistLst) # Mean distance of CH to sink self.dm2 = np.sum(self.nonCHdistLst)/len(self.nonCHdistLst) # Mean distance of nonCH to sink self.e1 = self.m.Intermediate(((Eelec+EDA)*self.packet + self.packs*self.pSize*(Eelec + Eamp * self.dm1**2))*len(self.CHdistLst)) # Mean energy consumption per round for CHs self.e2 = self.m.Intermediate((self.packs*self.pSize*(Eelec + Eamp * self.dm2**2))*len(self.nonCHdistLst)) # Mean energy consumption per round for CHs self.rnd = self.m.Intermediate(self.E_tot/(self.PERC*self.E_tot*self.e1+(1-self.PERC)*self.e2)) """ # options self.m.options.IMODE = 3 # optimize a solid state def controlEnv(self): #WORKING SCRIPT FOR ONE DIMENSION self.sinkPos = self.m.Var( lb=0, ub=100 ) # Upper bound should be something like sqrt(100**2 + 100**2) #self.sinkV = self.m.MV(lb=-3,ub=3) #self.sinkV.STATUS = 1 # as data is transmitted, remaining data stored decreases for i in range(self.CHs): self.CHLst.append(self.m.Param(value=4 * i)) self.CHdistLst.append( self.m.Var(value=self.sinkPos.value - self.CHLst[i].value)) self.m.Equation(self.CHdistLst[i] == self.sinkPos - self.CHLst[i]) for i in range(self.nonCHs): self.nonCHLst.append(self.m.Param(value=2 * i)) self.nonCHdistLst.append( self.m.Var(value=self.sinkPos.value - self.nonCHLst[i].value)) self.m.Equation(self.nonCHdistLst[i] == self.sinkPos - self.nonCHLst[i]) self.packs = 1 self.dtrLst = [] self.rnds = self.m.Var(integer=True, lb=1) self.E_tot = self.m.Param(value=0.010) self.e1Sum = [] self.e1Vars = [] self.e2Sum = [] self.e2Vars = [] for i in range(self.CHs): self.dtrLst.append(self.m.Var(lb=1, ub=20)) self.e1Sum.append( self.m.Intermediate((Eelec + EDA) * self.packs + self.dtrLst[-1] * self.pSize * (Eelec + Eamp * self.CHdistLst[i]**2))) self.e1Vars.append(self.m.Var(lb=0)) self.m.Equation(self.e1Vars[-1] == (Eelec + EDA) * self.packs + self.dtrLst[-1] * self.pSize * (Eelec + Eamp * self.CHdistLst[i]**2)) for i in range(self.nonCHs): self.e2Sum.append( self.m.Intermediate(self.packs * self.pSize * (Eelec + Eamp * self.nonCHdistLst[i]**2))) self.e2Vars.append(self.m.Var(lb=0)) self.m.Equation( self.e2Vars[-1] == (self.packs * self.pSize * (Eelec + Eamp * self.nonCHdistLst[i]**2))) #self.m.Equation(self.E_tot >= (self.m.sum(self.e1Sum)+ self.m.sum(self.e2Sum))*self.rnds) self.m.Equation( self.E_tot >= (self.m.sum(self.e1Vars) + self.m.sum(self.e2Vars)) * self.rnds) self.target = self.m.Intermediate(self.m.sum(self.dtrLst)) self.m.Obj(-self.target * self.rnds) self.m.solve(disp=False) print('Sink\'s optimal Position: {0}'.format(self.sinkPos.value)) print('Number of rounds for optimal amount of data transmitted: {0}'. format(self.rnds.value)) def plot(self): #WORKING CODE objects = np.linspace(1, len(self.CHLst), len(self.CHLst)) #for i in range(self.CHLst): # objects.append(self.CHdistLst[i].) y_pos = np.arange(len(objects)) ydtr = np.linspace(0, 20, 11) ydist = np.linspace(-50, 50, 11) CHDL = [] for i in range(len(self.CHdistLst)): CHDL.append(self.CHdistLst[i][0]) DTRL = [] for i in range(len(self.dtrLst)): DTRL.append(self.dtrLst[i][0]) plt.figure(self.nrplots) plt.subplot(2, 1, 1) plt.bar(y_pos, CHDL, align='center', alpha=0.5) plt.yticks(ydist, ydist) plt.ylabel('distance') plt.subplot(2, 1, 2) plt.bar(y_pos, DTRL, align='center', alpha=0.5) plt.yticks(ydtr, ydtr) plt.ylabel('Packets Desired') plt.xlabel('Node#') plt.show() def clearGEKKO(self): self.m.clear()