First of all, I`m sorry if I might ask this question and if it was already answered somewhere else. I couldnt find any solution for the following Problem:
I want to create a list where I apply multiple restricions. But instead of using over hundreads of if statements i just want to use a dictionary in one if statement to apply the requirements. So to say I want to use the keys of the dictionary as requirements and its values as factors for the data.
Lets take a look at a small example:
I want to create data for a countourplot where x/y range from [-50,50] in steps of 1 and the z function has requirements based on the if statements:
The following code is what works, but the more requirements I add the longer and more unreadalbe the code gets:
x = np.linspace(-50 , 50, 100)
y = np.linspace(-50 , 50, 100)
z = []
z_0 = 100
for i in x:
for j in y:
if i**2 + j**2 <= 10**2:
z.append(1.9 * z_0)
elif i**2 + j**2 <= 20**2:
z.append(1.5 * z_0)
elif i**2 + j**2 <= 30**2:
z.append(1.4 * z_0)
elif i**2 + j**2 <= 40**2:
z.append(1.05 * z_0)
else
z.append(z_0)
This would create a map with radial decreasing hight as a function of z on different positions. Is it possible to do this in the following way which is way less redundant? My main problem is how to assing the correct value.
x = np.linspace(-50 , 50, 100)
y = np.linspace(-50 , 50, 100)
z = []
requirements_dict = {10:1,9, 20:1.5, 30:1.4, 40:1.05}
z_0 = 100
for i in x:
for j in y:
if i**2 + j**2 <= (each key of the requirements_dict) :
z.append( (corresponding value of the requirements dict) * z_0)
else
z.append(z_0)
Thanks in advance for the help and sorry again if this question was already asked.
Is this what you're looking for?
EDIT:
import numpy as np
x = np.linspace(-50 , 50, 100)
y = np.linspace(-50 , 50, 100)
z = []
requirements_dict = {10: 1.9, 20: 1.5, 30: 1.4, 40: 1.05}
z_0 = 100
for i in x:
for j in y:
for key, value in requirements_dict.items():
if i**2 + j**2 <= key:
z.append(value * z_0)
break
else:
z.append(z_0)
Related
Is there a efficient and convenient solution in Python to do something like -
Find largest combination of two numbers x and y, with the following conditions -
0 < x < 1000
0 < y < 2000
x/y = 0.75
x & y are integers
It's easy to do it using a simple graphing calculator but trying to find the best way to do it in Python
import pulp
My_optimization_prob = pulp.LpProblem('My_Optimization_Problem', pulp.LpMaximize)
# Creating the variables
x = pulp.LpVariable("x", lowBound = 1, cat='Integer')
y = pulp.LpVariable("y", lowBound = 1, cat='Integer')
# Adding the Constraints
My_optimization_prob += x + y #Maximize X and Y
My_optimization_prob += x <= 999 # x < 1000
My_optimization_prob += y <= 1999 # y < 2000
My_optimization_prob += x - 0.75*y == 0 # x/y = 0.75
#Printing the Problem and Constraints
print(My_optimization_prob)
My_optimization_prob.solve()
#printing X Y
print('x = ',pulp.value(x))
print('y = ',pulp.value(y))
Probably just -
z = [(x, y) for x in range(1, 1000) for y in range(1, 2000) if x/y==0.75]
z.sort(key=lambda x: sum(x), reverse=True)
z[0]
#Returns (999, 1332)
This is convenient, not sure if this is the most efficient way.
Another possible relatively efficient solution is -
x_upper_limit = 1000
y_upper_limit = 2000
x = 0
y = 0
temp_variable = 0
ratio = 0.75
for i in range(x_upper_limit, 0, -1):
temp_variable = i/ratio
if temp_variable.is_integer() and temp_variable < y_upper_limit:
x = i
y = int(temp_variable)
break
print(x,y)
I'm currently using cvxpy to optimize a really big problem but now facing the current issue.
I run multiple iterations of the solver (every iteration reduces the flexibility of some variables).
Every run has 50 constraints in total, of which only 2 of them are different on every run. The remaining 48 constraints are identical.
During every iteration I rebuild from scratch those 2 constraints, the problem, and the obj function.
If I don't rebuild the remaining (same) 48 constraints, the final solution makes no sense.
I read this post CVXPY: how to efficiently solve a series of similar problems but here in my case, I don't need to change parameters and re-optimize.
I just managed to prepare an example that shows this issue:
x = cvx.Variable(3)
y = cvx.Variable(3)
tc = np.array([1.0, 1.0,1.0])
constraints2 = [x >= 2]
constraints3 = [x <= 4]
constraints4 = [y >= 0]
for i in range(2):
if i == 0:
constraints1 = [x - y >= 0]
else:
x = cvx.Variable(3)
y = cvx.Variable(3)
constraints1 = [x + y == 1,
x - y >= 1,
x - y >= 0,
x >= 0]
constraints = constraints1 + constraints2 + constraints3 + constraints4
# Form objective.
obj = cvx.Minimize( (tc.T # x ) - (tc.T # y ) )
# Form and solve problem.
prob = cvx.Problem(obj, constraints)
prob.solve()
solution_value = prob.value
solution = str(prob.status).lower()
print("\n\n** SOLUTION: {} Value: {} ".format(solution, solution_value))
print("* optimal (x + y == 1) dual variable", constraints[0].dual_value)
print("optimal (x - y >= 1) dual variable", constraints[1].dual_value)
print("x - y value:", (x - y).value)
print("x = {}".format(x.value))
print("y = {}".format(y.value))
As you can see, constraints2 requires all the values in the x vector to be greater than 2. constraints2 is added in both iterations to "constraints" that is used in the solver.
The second solution should give you values of vector x that are less than 2.
Why? How to avoid this issue?
Thank you
You need to use parameters as described in the linked post. Suppose you have the constraint rhs >= lhs which is sometimes used and other times not, where rhs and lhs have dimensions m x n. Write the following code:
param = cp.Parameter((m, n))
slack = cp.Variable((m, n))
param_constraint = [rhs >= lhs + cp.multiply(param, slack)]
Now to turn off the constraint, set param.values = np.ones((m, n)). To turn the constraint on, set param.values = np.zeros((m, n)). You can turn some entries of the constraint off/on by setting some entries of param to be 1 and others to be 0.
I have a variable s and i want to divide that variable with the number of inputs there are. I am a beginner, can anyone tell me the code that can perform that action?
I haven't tried anything because i don't know the specific code that can perform that action.
x = int(input("Insert x: "))
y = int(input("Insert y: "))
s = x + y
print(s/number of inputs)
I expect the output of s/number of inputs.
Not sure why this is needed but you can define your own function that inputs and increments a global counter:
number_of_inputs = 0
def my_input(msg):
global number_of_inputs
x = input(msg)
number_of_inputs += 1
return x
x = int(my_input("Insert x: "))
y = int(my_input("Insert y: "))
s = x + y
print(s / number_of_inputs)
Input:
Insert x: 10
Insert y: 20
Output:
15.0
I am trying to integrate numerically using simpson integration rule for f(x) = 2x from 0 to 1, but keep getting a large error. The desired output is 1 but, the output from python is 1.334. Can someone help me find a solution to this problem?
thank you.
import numpy as np
def f(x):
return 2*x
def simpson(f,a,b,n):
x = np.linspace(a,b,n)
dx = (b-a)/n
for i in np.arange(1,n):
if i % 2 != 0:
y = 4*f(x)
elif i % 2 == 0:
y = 2*f(x)
return (f(a)+sum(y)+f(x)[-1])*dx/3
a = 0
b = 1
n = 1000
ans = simpson(f,a,b,n)
print(ans)
There is everything wrong. x is an array, everytime you call f(x), you are evaluating the function over the whole array. As n is even and n-1 odd, the y in the last loop is 4*f(x) and from its sum something is computed
Then n is the number of segments. The number of points is n+1. A correct implementation is
def simpson(f,a,b,n):
x = np.linspace(a,b,n+1)
y = f(x)
dx = x[1]-x[0]
return (y[0]+4*sum(y[1::2])+2*sum(y[2:-1:2])+y[-1])*dx/3
simpson(lambda x:2*x, 0, 1, 1000)
which then correctly returns 1.000. You might want to add a test if n is even, and increase it by one if that is not the case.
If you really want to keep the loop, you need to actually accumulate the sum inside the loop.
def simpson(f,a,b,n):
dx = (b-a)/n;
res = 0;
for i in range(1,n): res += f(a+i*dx)*(2 if i%2==0 else 4);
return (f(a)+f(b) + res)*dx/3;
simpson(lambda x:2*x, 0, 1, 1000)
But loops are generally slower than vectorized operations, so if you use numpy, use vectorized operations. Or just use directly scipy.integrate.simps.
I wrote a function that takes two lists, Fahrenheit values and Celsius Values. I used a selection sort method that should sort the values from least to greatest. The possible Fahr Values are between and including -150 and 350 (I wrote a function to make sure input is within those numbers). When I type the following inputs: (30, 60, 10, -523235, -22, 30) it disregards the -523235 as it should but the output is: (10, 30, 60, -22, 30) which is not correct. It sorts only the first 3 numbers but once a negative is typed it doesn't sort that... I'm confused.
(The celsius values were generated by another function I wrote to convert the Fahr values to Cels values but that doesn't matter for this question)
def selection_sort_Fahr_Cels(temp_values_Fahr, temp_values_Cels):
for i in range(0, len(temp_values_Fahr)):
minIndex = i
for val in range(i+1, len(temp_values_Fahr)):
if temp_values_Fahr[val] < temp_values_Fahr[i]:
minIndex = val
if minIndex != i:
temp_values_Fahr[i], temp_values_Fahr[minIndex] = temp_values_Fahr[minIndex], temp_values_Fahr[i]
for i in range(0, len(temp_values_Cels)):
minIndex = i
for val in range(i+1, len(temp_values_Cels)):
if temp_values_Cels[val] < temp_values_Cels[i]:
minIndex = val
if minIndex != i:
temp_values_Cels[i], temp_values_Cels[minIndex] = temp_values_Cels[minIndex], temp_values_Cels[i]
print(" ", " Fahr "," ", " Cels ")
print(" ", "======="," ", "=======")
for i in range(len(temp_values_Fahr)):
print(" ","{0: 6}{1:14.1f}".format(temp_values_Fahr[i], temp_values_Cels[i]))
print(" ", "======="," ", "=======")
The entire program is over 100 lines, I can post a link to the entire program if needed.
Update: I can not use any library functions as to sort.
you don't really want to use all that complicated code to remove illegal values and sort them. There's a more pythonic way (I only did the Fahr values):
def selection_sort_Fahr_Cels(temp_values_Fahr, temp_values_Cels):
temp_values_Fahr[:] = sorted(filter(lambda x: x < 350 and x >= -150, temp_values_Fahr))
farh=[30, 60, 10, -523235, -22, 30]
selection_sort_Fahr_Cels(farh,[])
print(farh)
result (list is modified in-place):
[-22, 10, 30, 30, 60]
the code is using filter method using your criteria, and the result is passed to the sorted method that takes an iterable and creates a list out of it.
Not to mention that python sorted method is way more efficient than bubble sort.
def selectionsort( aList ):
for i in range( len( aList ) ):
least = i
for k in range( i + 1 , len( aList ) ):
if aList[k] < aList[least]:
least = k
swap( aList, least, i )
print(aList)
def swap( A, x, y ):
tmp = A[x]
A[x] = A[y]
A[y] = tmp
selectionsort(aList)
I found a better selection sort method. I noticed that before, I didn't have any swap method going on.