In this work, I wrote a code. There are 3 points, and y(4th point) is the point which is the point sum of euclidean minimum to other 3 points.
Firt I wrote it to work for first 50 iterations. It works perfect. And it finds the right y point.
But I want it to work when, |yi+1 - yi| is higher than "error(in this case I choose it 10**-5)" value.
|yi+1 - yi| =>> euclidean distance between last and current
iteration
Here is my code;
"e" is the last iteration. But "e" updates(equals to current iteration) everytime when program exits "for loops". So in 2nd iteration "eps" equals to "0" and my code executes. I can not understand why :(
import math as m
a = ([1.0, 2.0, 3.0],
[20.0, 18.0, 25.0],
[10.0, 12.0, 42.0])
y = ([0.0, 0.0, 0.0])
x = ([0.0, 0.0, 0.0])
r = 0
t = 0
e = [0.0 , 0.0, 0.0]
eps = 10
while (eps > 10**-5):
for i in range(3):
for j in range(3):
c = (a[j][i]/(m.sqrt((a[j][0]-y[0])**2+(a[j][1]-y[1])**2+(a[j][2]-y[2])**2)))
b = 1/(m.sqrt((a[j][0]-y[0])**2+(a[j][1]-y[1])**2+(a[j][2]-y[2])**2))
r += c
t += b
x[i] = r/t
r = 0
t = 0
y = x
eps = (m.sqrt((y[0]-e[0])**2+(y[1]-e[1])**2+(y[2]-e[2])**2))
e = y
print("y= ", y)
I solved the problem. Thanks for -1. You helped a lot.
import math as m
a = ([1.0, 2.0, 3.0],
[20.0, 18.0, 25.0],
[10.0, 12.0, 42.0])
def euclideanminpoint(a):
y = ([0.0, 0.0, 0.0])
x = ([0.0, 0.0, 0.0])
r = 0
t = 0
e = [0.0 , 0.0, 0.0]
eps = 10
k = 0
while (eps > 10**-5):
for i in range(3):
for j in range(3):
c = (a[j][i]/(m.sqrt((a[j][0]-y[0])**2+(a[j][1]-y[1])**2+(a[j][2]-y[2])**2)))
b = 1/(m.sqrt((a[j][0]-y[0])**2+(a[j][1]-y[1])**2+(a[j][2]-y[2])**2))
r += c
t += b
x[i] = r/t
r = 0
t = 0
y = x
eps = (m.sqrt((y[0]-e[0])**2+(y[1]-e[1])**2+(y[2]-e[2])**2))
for i in range(3):
e[i] = y[i]
k += 1
print("i= ","y= ","\n", k, y)
euclideanminpoint(a)
Related
I try to solve an optimization problem with Gekko in google Collab and this error is shown (in line 91 m.Obj(m.sum(m.sum(((xl[i](D_input[i] + D_output[i])/0.5)+ (xf[i][j]((D_input[i] / ru[i][j]) + (D_output[i] / rd[i][j]) +((D_input[i] + D_output[i]) / rf[i][j])))+ (xc*((D_input[i] / ru[i][j]) + (D_output[i] / rd...):
TypeError: x must be a python list of GEKKO parameters, variables, or expressions
!pip install gekko
from gekko import GEKKO
m = GEKKO()
MU = 5
FN = 3
Cloud = 1
D_input = m.Param(value=[2, 4, 7, 6, 9])
D_output = m.Param(value=[0.2, 0.25, 0.6, 0.35, 0.81])
RF_total = m.Param(value=[10, 10, 10])
RU_total = m.Param(value=[72, 72, 72])
RD_total = m.Param(value=[72, 72, 72])
c = m.Param(value=[0.2, 0.4, 0.7, 0.6, 0.9])
tr = m.Param(value=[10, 10, 10, 10, 10])
fl = m.Param(value=[0.5, 0.5, 0.5, 0.5, 0.5])
nu = m.Const(1.37)
fc = m.Const(10)
wc = m.Const(5)
eu = m.Const(0.142)
ed = m.Const(0.142)
euc = m.Const(0.658)
edc = m.Const(0.278)
el = m.Param(value=[0.0, 0.0, 0.0, 0.0, 0.0])
eed = m.Param(value=[[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0,
0.0]])
eeu = m.Param(value=[[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0,
0.0]])
eedc = m.Param(value=[0.0, 0.0, 0.0, 0.0, 0.0])
eeuc = m.Param(value=[0.0, 0.0, 0.0, 0.0, 0.0])
eef = m.Param(value=[[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0,
0.0]])
eec = m.Param(value=[0.0, 0.0, 0.0, 0.0, 0.0])
for i in range(MU) :
el[i] = nu * c[i]
for i in range(MU) :
for j in range(FN) :
eed[i][j] = D_output[i] * ed
eeu[i][j] = D_input[i] * eu
for i in range(MU) :
for j in range(FN) :
eef[i][j] = eeu[i][j] + eed[i][j]
for i in range(MU) :
eedc[i] = edc * D_output[i]
eeuc[i] = euc * D_input[i]
for i in range(MU) :
eec[i] = eeuc[i] + eedc[i]
xf = [[m.Var(value=0,lb=0,ub=1,integer=True) for j in range(FN)] for i in range(MU)]
xc = m.Var(value=0,lb=0,ub=1,integer=True)
xl = [m.Var(value=0,lb=0,ub=1,integer=True) for i in range(MU)]
ru = [[m.Var(value=0.01, lb=0.01, ub=72.0) for j in range(FN)] for i in range(MU)]
rd = [[m.Var(value=0.01, lb=0.01, ub=72.0) for j in range(FN)] for i in range(MU)]
rf = [[m.Var(value=0.01, lb=0.01, ub=10.0) for j in range(FN)] for i in range(MU)]
for j in range(FN):
m.Equation(sum(rf[i][j] for i in range(MU)) <= 10)
for j in range(FN):
m.Equation(sum(ru[i][j] for i in range(MU)) <= 72)
for j in range(FN):
m.Equation(sum(rd[i][j] for i in range(MU)) <= 72)
for i in range(MU):
m.Equation(xc + xl[i] + sum(xf[i][j] for j in range(FN)) == 1)
for i in range(MU):
m.Equation(xl[i]*(( D_input[i] + D_output[i])/0.5) <= 7)
for j in range(FN):
for i in range(MU):
m.Equation(((xf[i][j]*((D_input[i] / ru[i][j]) + (D_output[i] / rd[i][j]) + ((D_input[i] +
D_output[i]) / rf[i][j])))) <= 7)
for i in range(MU):
m.Equation(((xc*((D_input[i] / ru[i][j]) + (D_output[i] / rd[i][j]) + (3*(D_input[i] +
D_output[i]) / 10)))) <= 7)
for i in range(MU):
m.Equation(((D_input[i] + D_output[i])/0.5) <= tr[i])
for j in range(FN):
for i in range(MU):
m.Equation(((((D_input[i] / ru[i][j]) + (D_output[i] / rd[i][j]) + ((D_input[i] + D_output[i])
/ rf[i][j])))) <= tr[i])
for i in range(MU):
m.Equation(((((D_input[i] / ru[i][j]) + (D_output[i] / rd[i][j]) + (3*(D_input[i] + D_output[i]) / 10)))) <= tr[i])
m.Obj(m.sum(m.sum(((xl[i]*(D_input[i] + D_output[i])/0.5)+\
(xf[i][j]*((D_input[i] / ru[i][j]) + (D_output[i] / rd[i][j]) +((D_input[i] + D_output[i]) /
rf[i][j])))+\
(xc*((D_input[i] / ru[i][j]) + (D_output[i] / rd[i][j]) + (3*(D_input[i] + D_output[i]) /
10))))+\
(xf[i][j]*eef[i][j]) + (xc*eec[i]) + (xl[i]*el[i]) for i in range(MU)) for j in range(FN)))
m.options.SOLVER=1
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']
m.solve()
print('Results')
print('Objective: ' + str(m.options.objfcnval))
please help me
Thanks.
Use m.Array() to define multidimensional m.Param and m.Var values.
D_input = m.Array(m.Param,5)
for v in [2,4,7,6,9]:
D_input[i].value = v
or
eef = m.Array(m.Param,(5,3),value=0)
Here is a minimal example problem:
from gekko import GEKKO
import numpy as np
m = GEKKO(remote=False)
ni = 3; nj = 2; nk = 4
# solve AX=B
A = m.Array(m.Var,(ni,nj),lb=0)
X = m.Array(m.Var,(nj,nk),lb=0)
AX = np.dot(A,X)
B = m.Array(m.Var,(ni,nk),lb=0)
# equality constraints
m.Equations([AX[i,j]==B[i,j] for i in range(ni) \
for j in range(nk)])
m.Equation(5==m.sum([m.sum([A[i][j] for i in range(ni)]) \
for j in range(nj)]))
m.Equation(2==m.sum([m.sum([X[i][j] for i in range(nj)]) \
for j in range(nk)]))
# objective function
m.Minimize(m.sum([m.sum([B[i][j] for i in range(ni)]) \
for j in range(nk)]))
m.solve()
print(A)
print(X)
print(B)
Here are some additional matrix operations with Numpy:
import numpy as np
from gekko import GEKKO
m = GEKKO(remote=False)
# Random 3x3
A = np.random.rand(3,3)
# Random 3x1
b = np.random.rand(3,1)
# Gekko array 3x3
p = m.Array(m.Param,(3,3))
# Gekko array 3x1
y = m.Array(m.Var,(3,1))
# Dot product of A p
x = np.dot(A,p)
# Dot product of x y
w = np.dot(x,y)
# Dot product of p y
z = np.dot(p,y)
# Trace (sum of diag) of p
t = np.trace(p)
# solve Ax = b
s = m.axb(A,b)
m.solve()
xf = [[m.Var(value=0,lb=0,ub=1,integer=True) for j in range(FN)] for i in range(MU)]
xc = m.Var(value=0,lb=0,ub=1,integer=True)
xl = [m.Var(value=0,lb=0,ub=1,integer=True) for i in range(MU)]
ru = [[m.Var(value=0.01, lb=0.01, ub=72.0) for j in range(FN)] for i in range(MU)]
rd = [[m.Var(value=0.01, lb=0.01, ub=72.0) for j in range(FN)] for i in range(MU)]
rf = [[m.Var(value=0.01, lb=0.01, ub=10.0) for j in range(FN)] for i in range(MU)]
They are lists of lists of m.Var() objects.
We need to make it a list of m.Var() objects.
Not so familiar with Gekko but still hope this could help.
The question is simple.
Suppose we have Series with this values:
srs = pd.Series([7.0, 2.0, 1.0, 2.0, 3.0, 5.0, 4.0])
How can I find place (index) of subseries 1.0, 2.0, 3.0?
Using a rolling window we can find the first occurrence of a list a.It puts a 'marker' (e.g. 0, any non-Nan value will be fine) at the end (right border) of the window. Then we use first_valid_index to find the index of this element and correct this value by the window size:
a = [1.0, 2.0, 3.0]
srs.rolling(len(a)).apply(lambda x: 0 if (x == a).all() else np.nan).first_valid_index()-len(a)+1
Output:
2
The simplest solution might be to use list comprehension:
a = srs.tolist() # [7.0, 2.0, 1.0, 2.0, 3.0, 5.0, 4.0]
b = [1.0, 2.0, 3.0]
[x for x in range(len(a)) if a[x:x+len(b)] == b]
# [2]
One naive way is to iterate over the series, subset the n elements and compare if they are equal to the given list:
Here the code:
srs = pd.Series([7.0, 2.0, 1.0, 2.0, 3.0, 5.0, 4.0])
sub_list = [1.0, 2.0, 3.0]
n = len(sub_list)
index_matching = []
for i in range(srs.shape[0] - n + 1):
sub_srs = srs.iloc[i: i+n]
if (sub_srs == sub_list).all():
index_matching.append(sub_srs.index)
print(index_matching)
# [RangeIndex(start=2, stop=5, step=1)]
Or in one line with list comprehension:
out = [srs.iloc[i:i+n].index for i in range(srs.shape[0] - n + 1) if (srs.iloc[i: i+n] == sub_list).all()]
print(out)
# [RangeIndex(start=2, stop=5, step=1)]
If you want an explicit list:
real_values = [[i for i in idx] for idx in out]
print(real_values)
# [[2, 3, 4]]
I define a simple computational graph involving a variable. When I change a value of the variable it has an expected influence on the output of the computational graph (so, everything works fine, as expected):
s = tf.Session()
x = tf.placeholder(tf.float32)
c = tf.Variable([1.0, 1.0, 1.0], tf.float32)
y = x + c
c = tf.assign(c, [3.0, 3.0, 3.0])
s.run(c)
print 'Y1:', s.run(y, {x : [10.0, 20.0, 30.0]})
c = tf.assign(c, [2.0, 2.0, 2.0])
s.run(c)
print 'Y2:', s.run(y, {x : [10.0, 20.0, 30.0]})
When I call this code I get:
Y1: [ 13. 23. 33.]
Y2: [ 12. 22. 32.]
So, the values after the Y1 and Y2 are different, as expected, because they are calculated with different values of c.
The problems start if I assign a value to the variable c before I define how it is involved into calculation of y. In this case I cannot assign a new value of c.
s = tf.Session()
x = tf.placeholder(tf.float32)
c = tf.Variable([1.0, 1.0, 1.0], tf.float32)
c = tf.assign(c, [4.0, 4.0, 4.0]) # this is the line that causes problems
y = x + c
c = tf.assign(c, [3.0, 3.0, 3.0])
s.run(c)
print 'Y1:', s.run(y, {x : [10.0, 20.0, 30.0]})
c = tf.assign(c, [2.0, 2.0, 2.0])
s.run(c)
print 'Y2:', s.run(y, {x : [10.0, 20.0, 30.0]})
As the output I get:
Y1: [ 14. 24. 34.]
Y2: [ 14. 24. 34.]
As you can see, each time I calculate y, I get results involving the old values of c. Why is that?
With TensorFlow, always keep in mind that you're building a computation graph. In your first code snippet, you basically define y = tf.placeholder(tf.float32) + tf.Variable([1.0, 1.0, 1.0], tf.float32). In your second example, you define y = tf.placeholder(tf.float32) + tf.assign(tf.Variable([1.0, 1.0, 1.0], tf.float32), [4.0, 4.0, 4.0]).
So, no matter which value you assign to c, the computation graph contains the assign operation and will always assign [4.0, 4.0, 4.0] to it before computing the sum.
I think this is because that you define the the add operation y = x + c right after c = tf.assign(c, [4.0, 4.0, 4.0]), so each time you run y out, c = tf.assign(c, [4.0, 4.0, 4.0]) this op will always be excuted and although other assign operations will also be excuted but don't affect the final result.
I have a list of elements with certain values of type float. I want to iterate over the elements and count them if they are over a certain value, but also only count them if they appear over the treshold value a minimum_count of times. So for example, if a have following input:
list_of_values = [2.0, 2.0, 2.0, 2.0, 0, 0, 2.0, 2.0, 2.0, 0, 0]
treshold_value = 1.0
minimum_count = 4
the answer should be 4, since the treshold_value 1.0 is consecutively exceeded 4 times only at indexes 0-3. I now have the code below,
for value in list_of_values:
if value >= treshold_value:
counter += 1
if counter >= (minimum_count):
time_use += 1
if value < min_treshold_value:
counter = 0
print(time_use)
I know there should be some pythonic way to achieve this :)
Edit: The sum of all consecutive subsequence values over the threshold should be counted.
The following use of groupby with a conditional generator and max with appropriate key function should work:
from itertools import groupby
len(max((list(g) for k, g in groupby(list_ov, key=lambda x: x > threshold) if k), key=len))
groupby groups an iterable by consecutive identical values wrt to the key function. It produces pairs of the key value and according sub-iterable.
You could use itertools.groupby() to help:
from itertools import groupby
def count_runs(list_of_values, threshold_value=1.0, minimum_count=4):
count = 0
for k, g in groupby(list_of_values, key=lambda x: x >= threshold_value):
if k:
g = list(g)
if len(g) >= minimum_count:
count += len(g)
return count
>>> count_runs([2.0, 2.0, 2.0, 0.0, 0, 0, 2.0, 2.0, 2.0, 0, 0])
0
>>> count_runs([2.0, 2.0, 2.0, 2.0, 0, 0, 2.0, 2.0, 2.0, 0, 0])
4
>>> count_runs([2.0, 2.0, 2.0, 2.0, 0, 0, 3.0, 2.0, 2.0, 2.0, 10.0, 0, 0])
9
This will provide the count of the number of values that are above the threshold in groups of minimum_count or more. Note that it handles multiple groups that match the criteria.
For example the groupby() for the last example will return the following:
>>> list_of_values = [2.0, 2.0, 2.0, 2.0, 0, 0, 3.0, 2.0, 2.0, 2.0, 10.0, 0, 0]
>>> for k, g in groupby(list_of_values, key=lambda x: x >= threshold_value):
... print(k, list(g))
...
True [2.0, 2.0, 2.0, 2.0]
False [0, 0]
True [3.0, 2.0, 2.0, 2.0, 10.0]
False [0, 0]
Any group of 1 or more values >= the threshold will appear in a group with key True. Only those with a length >= the minimum count will be considered further, where its length will be tallied with other such groups.
This code can be written more succinctly, and far less readably, like this:
def count_runs(list_of_values, threshold_value=1.0, minimum_count=4):
return sum(count for count in (len(list(g)) for k, g in groupby(list_of_values, key=lambda x: x >= threshold_value) if k) if count >= minimum_count)
just iterate over the list and create a dictionary with key = the float number and value = the number of times you encounter this number. and only add to dict floats that are greater then threshold . something like this:
d = {}
for f in list_of_values :
if f > treshold:
if d.get(f,False):
d[f] +=1
else:
d[f] = 1
max = 0
for k,v in d.iteritems():
if v> max:
max = v
return max
It looks like you don't care about the order. In this case, groupby isn't correct because it only groups adjacent elements.
You could use a Counter and two list comprehensions to filter values:
list_of_values = [2.0, 2.0, 2.0, 2.0, 0, 0, 3.0, 2.0, 2.0, 2.0, 10.0, 0, 0]
threshold_value = 1.0
minimum_count = 4
from collections import Counter
counter = Counter([x for x in list_of_values if x > threshold_value])
print(counter)
# Counter({2.0: 7, 3.0: 1, 10.0: 1})
print([(x, count) for x, count in counter.items() if count > minimum_count])
# [(2.0, 7)]
This question already exists:
Python - Make an Array: n by n [duplicate]
Closed 6 years ago.
I am trying to create this matrix AxB with a specific pattern in Python :
[1.0, 0.0, 0.0],
[-1.0, 0.0, 0.0],
[0.0, 1.0, 0.0],
[0.0, -1.0, 0.0],
[0.0, 0.0, 1.0],
[0.0, 0.0, -1.0]
The problem is that I want to create this matrix without having to resort to hard coding it. Can someone help me to isolate the pattern, and fill the matrix dynamically?
Here is what I've tried so far :
matrix_test = [[0.0 for i in range(3)] for i in range(6)]
for x in range(3):
matrix_test [x][x] = 1.0
matrix_test = [[0.0 for i in range(3)] for i in range(6)]
for x in range(3):
matrix_test [2 * x][x] = 1.0
matrix_test [2 * x + 1][x] = -1.0