I am trying to obtain intensity values from an RGB image based on this formula:
And my code is:
def normalize(image): #normalize values to between 0 and 1
image -= image.min()
image /= image.max()
image = np.uint8(image * 255) #convert values to uint8 between 0-255
return image
def custom_intensity(image):
h, w, c = image.shape
intensity = np.zeros((h, w))
image = image.astype(float)
for i in range(h):
for j in range(w):
divider = image[i, j, 0] + image[i, j, 1] + image[i, j, 2]
if(divider == 0):
intensity[i, j] == 0
else:
intensity[i, j] = image[i, j, 0] * (image[i, j, 0] / divider) + \
image[i, j, 1] * (image[i, j, 1] / divider) + \
image[i, j, 2] * (image[i, j, 2] / divider)
intensity = normalize(intensity)
return intensity
Which works well but slow. I am beginner in python so could not improve this further. How can I make this code more efficient?
Try this:
image += (pow(10, -6), pow(10, -6), pow(10, -6))
intensity = (pow(image[:, :, 0], 2) + pow(image[:, :, 1], 2) + pow(image[:, :, 2], 2)) \
/ (image[:, :, 0] + image[:, :, 1] + image[:, :, 2])
You don't need to be an expert in Python.
Simplify your equation:
(R**2 + G**2 + B**2) / (R+G+B)
Related
So I am trying to find inverse of a matrix (using Python lists) by Gauss-Jordan Elimination. But I am facing this peculiar problem. In the code below, I apply my code to the given matrix and it reduces to the identity matrix as intended.
M = [[0, 2, 1], [4, 0, 1], [-1, 2, 0]]
P = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
n = len(P)
def inverse(a):
for k in range(n):
if abs(a[k][k]) < 1.0e-12:
for i in range(k+1, n):
if abs(a[i][k]) > abs(a[k][k]):
for j in range(k, n):
a[k][j], a[i][j] = a[i][j], a[k][j]
break
pivot = a[k][k]
for j in range(k, n):
a[k][j] /= pivot
for i in range(n):
if i == k or a[i][k] == 0: continue
factor = a[i][k]
for j in range(k, n):
a[i][j] -= factor * a[k][j]
return a
inverse(M)
The output is
[[1.0, 0.0, 0.0], [0, 1.0, 0.0], [0.0, 0.0, 1.0]]
But when I apply the same code, after adding lines of code for my identity matrix (which is part of the augmented matrix with the given matrix), It is not giving me the correct inverse when it should (as I am applying same operation on it as I'm applying on the given matrix).
M = [[0, 2, 1], [4, 0, 1], [-1, 2, 0]]
P = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
n = len(P)
def inverse(a, b):
for k in range(n):
if abs(a[k][k]) < 1.0e-12:
for i in range(k+1, n):
if abs(a[i][k]) > abs(a[k][k]):
for j in range(k, n):
a[k][j], a[i][j] = a[i][j], a[k][j]
b[k][j], b[i][j] = b[i][j], b[k][j]
b[k], b[i] = b[i], b[k]
break
pivot = a[k][k]
for j in range(k, n):
a[k][j] /= pivot
b[k][j] /= pivot
for i in range(n):
if i == k or a[i][k] == 0: continue
factor = a[i][k]
for j in range(k, n):
a[i][j] -= factor * a[k][j]
b[i][j] -= factor * b[k][j]
return a, b
inverse(M, P)
The output is not the inverse matrix, but something else (though the last column has correct entries).
([[1.0, 0.0, 0.0], [0, 1.0, 0.0], [0.0, 0.0, 1.0]],
[[0.0, 0.25, 0.3333333333333333],
[1, 0.0, 0.6666666666666666],
[0.0, 0.25, -1.3333333333333333]])
I tried using print statements while debugging, and I think the line where I divide the rows by the pivot, has some issue. It works fine in the original matrix but doesn't work with the identity matrix. Also, note that only the last column of the identity matrix gets converted to the correct entries of the inverse matrix.
The correct inverse matrix for reference is
I = [[-1/3, 1/3, 1/3], [-1/6, 1/6, 2/3], [4/3, -1/3, -4/3]]
Any help would be much appreciated.
Thanks in advance!
I could not figure out the problem in my code though I found a workaround and I'll be instead posting that. Hope that might help someone else.
Instead of doing the same operations on the two matrices of which I formed the augmented matrix, I decided to deal it as a n x 2n matrix. Here is the fully working code:
def inverse(a):
n = len(a) #defining the range through which loops will run
#constructing the n X 2n augmented matrix
P = [[0.0 for i in range(len(a))] for j in range(len(a))]
for i in range(3):
for j in range(3):
P[j][j] = 1.0
for i in range(len(a)):
a[i].extend(P[i])
#main loop for gaussian elimination begins here
for k in range(n):
if abs(a[k][k]) < 1.0e-12:
for i in range(k+1, n):
if abs(a[i][k]) > abs(a[k][k]):
for j in range(k, 2*n):
a[k][j], a[i][j] = a[i][j], a[k][j] #swapping of rows
break
pivot = a[k][k] #defining the pivot
if pivot == 0: #checking if matrix is invertible
print("This matrix is not invertible.")
return
else:
for j in range(k, 2*n): #index of columns of the pivot row
a[k][j] /= pivot
for i in range(n): #index the subtracted rows
if i == k or a[i][k] == 0: continue
factor = a[i][k]
for j in range(k, 2*n): #index the columns for subtraction
a[i][j] -= factor * a[k][j]
for i in range(len(a)): #displaying the matrix
for j in range(n, len(a[0])):
print(a[i][j], end = " ")
print()
I am trying to optimize my FEA truss solution using GEKKO. So I defined all the FEA solution as one function and tried making the forces as variables.SO the goal is to mimimize the forces with one constraint (sum of all forces=-100000).But after i run my code i get an error that I could not fix it googling also did not help(I am new to python).I will be grateful if someone could tell me where the problem is.Thanks in advance.
try:
from gekko import GEKKO
except:
# pip install gekko
import pip
pip.main(['install','gekko'])
from gekko import GEKKO
# from __future__ import division
import numpy as np
import matplotlib.pyplot as plt
# numElem=11
# numNodes=6
def calculate_truss_force(force):
# defined coordinate system
x_axis = np.array([1, 0])
y_axis = np.array([0, 1])
# elements coordinates
elemNodes = np.array([[0, 1], [0, 2], [1, 2], [1, 3],
[0, 3], [2, 3], [2, 5], [3, 4], [3, 5], [2, 4], [4, 5]])
# nodes coordinates
nodeCords = np.array([
[0.0, 0.0], [0.0, 100.0],
[100.0, 0.0], [100.0, 100.0],
[200.0, 0.0], [200.0, 100.0]])
modE = 200000
Area = 200
# assembling the model
numElem = elemNodes.shape[0]
numNodes = nodeCords.shape[0]
xx = nodeCords[:, 0]
yy = nodeCords[:, 1]
EA = modE * Area
tdof = 2 * numNodes # total number of degrees of freedom
disps = np.zeros((tdof, 1))
# force = np.zeros((tdof, 1))
sigma = np.zeros((numElem, 1))
stiffness = np.zeros((tdof, tdof))
np.set_printoptions(precision=3)
# applying the load
# force[3] = -20000.0
# force[7] = -50000.0
# force[11] = -30000.0
# defined boundary
presDof = np.array([0, 1, 9])
for e in range(numElem):
indice = elemNodes[e, :]
elemDof = np.array([indice[0] * 2, indice[0] * 2 + 1, indice[1] * 2, indice[1] * 2 + 1]) #dof corresponding to the global stifnessmatrix
xa = xx[indice[1]] - xx[indice[0]] #length of the elemnts in x dir
ya = yy[indice[1]] - yy[indice[0]] #lenth of the elemnt in y dir
len_elem = np.sqrt(xa * xa + ya * ya)
c = xa / len_elem
s = ya / len_elem
k1 = (EA / len_elem) * np.array([[c * c, c * s, -c * c, -c * s],
[c * s, s * s, -c * s, -s * s],
[-c * c, -c * s, c * c, c * s],
[-c * s, -s * s, c * s, s * s]])
stiffness[np.ix_(elemDof, elemDof)] += k1 # add elem K to the global K
actDof = np.setdiff1d(np.arange(tdof), presDof)
disp1 = np.linalg.solve(stiffness[np.ix_(actDof, actDof)], force[np.ix_(actDof)])
disps[np.ix_(actDof)] = disp1
# stresses at elements
for e in range(numElem):
indice = elemNodes[e, :]
elemDof = np.array([indice[0] * 2, indice[0] * 2 + 1, indice[1] * 2, indice[1] * 2 + 1])
xa = xx[indice[1]] - xx[indice[0]]
ya = yy[indice[1]] - yy[indice[0]]
len_elem = np.sqrt(xa * xa + ya * ya)
c = xa / len_elem
s = ya / len_elem
sigma[e] = (modE / len_elem) * np.dot(np.array([-c, -s, c, s]), disps[np.ix_(elemDof)])
#print (disps)
#print (sigma)
return np.max(np.abs(sigma))
m = GEKKO()
# Define variables
A = m.Array(m.Var, (12))
# initial guess
ig = [0, 0, 0, -20000, 0, 0, 0, -50000, 0, 0, 0, -30000]
# bounds
for i, Ai in enumerate(A):
Ai.value = ig[i]
Ai.lower = ig[i] * 0.95
Ai.upper = ig[i] * 1.05
m.Equation(np.sum(A) == -100000)
m.Obj(calculate_truss_force(A.reshape(12, 1)))
m.solve()
print(A.reshape(12, 1))
print(calculate_truss_force(np.array(ig).reshape(12, 1)))
I switched to SCipy and the code is below
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import minimize
# numElem=11
# numNodes=6
def calculate_truss_force(Area_elem):
# print("calc_truss")
# defined coordinate system
x_axis = np.array([1, 0])
y_axis = np.array([0, 1])
# elements coordinates
elemNodes = np.array([[0, 1], [0, 2], [1, 2], [1, 3],
[0, 3], [2, 3], [2, 5], [3, 4], [3, 5], [2, 4], [4, 5]])
# nodes coordinates
nodeCords = np.array([
[0.0, 0.0], [0.0, 100.0],
[100.0, 0.0], [100.0, 100.0],
[200.0, 0.0], [200.0, 100.0]])
modE = 200000
Area = 200
# assembling the model
numElem = elemNodes.shape[0]
numNodes = nodeCords.shape[0]
xx = nodeCords[:, 0]
yy = nodeCords[:, 1]
EA = modE * Area
tdof = 2 * numNodes # total number of degrees of freedom
disps = np.zeros((tdof, 1))
force = np.zeros((tdof, 1))
sigma = np.zeros((numElem, 1))
stiffness = np.zeros((tdof, tdof))
np.set_printoptions(precision=3)
# applying the load
force[3] = -20000.0
force[7] = -50000.0
force[11] = -30000.0
# defined boundary
presDof = np.array([0, 1, 9])
for e in range(numElem):
indice = elemNodes[e, :]
elemDof = np.array([indice[0] * 2, indice[0] * 2 + 1, indice[1] * 2,
indice[1] * 2 + 1]) # dof corresponding to the global stifnessmatrix
xa = xx[indice[1]] - xx[indice[0]] # length of the elemnts in x dir
ya = yy[indice[1]] - yy[indice[0]] # lenth of the elemnt in y dir
len_elem = np.sqrt(xa * xa + ya * ya)
c = xa / len_elem
s = ya / len_elem
k1 = (modE * Area_elem[e] / len_elem) * np.array([[c * c, c * s, -c * c, -c * s],
[c * s, s * s, -c * s, -s * s],
[-c * c, -c * s, c * c, c * s],
[-c * s, -s * s, c * s, s * s]])
stiffness[np.ix_(elemDof, elemDof)] += k1 # add elem K to the global K
actDof = np.setdiff1d(np.arange(tdof), presDof)
# Correct way
disp1 = np.linalg.solve(stiffness[np.ix_(actDof, actDof)], force[np.ix_(actDof)])
disps[np.ix_(actDof)] = disp1.reshape([9,1])
# stresses at elements
for e in range(numElem):
indice = elemNodes[e, :]
elemDof = np.array([indice[0] * 2, indice[0] * 2 + 1, indice[1] * 2, indice[1] * 2 + 1])
xa = xx[indice[1]] - xx[indice[0]]
ya = yy[indice[1]] - yy[indice[0]]
len_elem = np.sqrt(xa * xa + ya * ya)
c = xa / len_elem
s = ya / len_elem
sigma[e] = (modE / len_elem) * np.dot(np.array([-c, -s, c, s]), disps[np.ix_(elemDof)])
# print (disps)
#print (sigma)
# computing internal reactions
# react = np.dot(stiffness, disps)
# print (react.reshape((numNodes, 2)))
for i,sig in enumerate(sigma):
print("Elem: ",i, "\t Force: \t",sig*Area_elem[i],sig,sigma[i],Area_elem[i])
# input("break")
return np.max(np.abs(sigma))
def constraint1(A):
sum = 100000
for i in range(num_elem):
sum = sum - A[i]
return sum
con1 = {'type': 'eq', 'fun': constraint1}
for i in range(200):
print("Number iteration: ",i)
sol = minimize(calculate_truss_force, x0, method='SLSQP', bounds=bnds,tol=0.0000000000001, constraints=con1)
x0 = sol.x
print(x0)
print(calculate_truss_force(x0))
Gekko uses automatic differentiation to provide derivatives to the gradient-based solvers. Instead of using a linear solver inside of your function:
disp1 = np.linalg.solve(stiffness[np.ix_(actDof, actDof)],\
force[np.ix_(actDof)])
this needs to be given to Gekko as an implicit A x = b, not x= A^-1 b.
A = stiffness[np.ix_(actDof, actDof)]
b = np.array(force[np.ix_(actDof)])
disp1 = np.dot(A,b)
Gekko simultaneously solves the equation, not sequentially like with an inner loop. Also, Gekko only evaluates the objective function once to build symbolic expressions that it then compiles into byte-code for the solver. It does not have a callback to calculate_truss_force to evaluate it multiple times.
One other change is the use of np.max and np.abs to the Gekko versions of m.max2 or m.max3 and also with m.min2 or m.min3. These are versions of max and abs that have continuous first and second derivatives. The ...2 version is an MPCC while the ...3 version is a mixed integer problem.
for e in range(numElem):
indice = elemNodes[e, :]
elemDof = np.array([indice[0] * 2, indice[0] * 2 + 1, \
indice[1] * 2, indice[1] * 2 + 1])
xa = xx[indice[1]] - xx[indice[0]]
ya = yy[indice[1]] - yy[indice[0]]
len_elem = np.sqrt(xa * xa + ya * ya)
c = xa / len_elem
s = ya / len_elem
sigma[e] = m.abs2(m.Intermediate((modE / len_elem) * \
np.dot(np.array([-c, -s, c, s]), \
disps[np.ix_(elemDof)])))
return m.max2(sigma)
If you don't want to use the objective function as a "black-box" then I recommend scipy.optimize.minimize instead of Gekko. Here is a tutorial on Gekko and Scipy for optimization.
I am a python beginer and I was wondering why I got all unit ones in below script. I expected to get some integer numbers from 1-10.
import random
def random_walk(n):
"""Return coordinates after 'n' block random walk"""
x, y = 0, 0
for i in range(n):
(dx, dy) = random.choice([(0, 1), (0, -1), (1, 0), (-1, 0)])
x += dx
y += dy
return (x, y)
for i in range(5):
walk = random_walk(10)
print(walk, "Distance from home = ",
abs(walk[0]) + abs(walk[1]))
Output:
(-1, 0) Distance from home = 1
(-1, 0) Distance from home = 1
(-1, 0) Distance from home = 1
(-1, 0) Distance from home = 1
(0, -1) Distance from home = 1
I think this line:
return (x, y)
should be outside of the loop:
import random
def random_walk(n):
"""Return coordinates after 'n' block random walk"""
x, y = 0, 0
for i in range(n):
(dx, dy) = random.choice([(0, 1), (0, -1), (1, 0), (-1, 0)])
x += dx
y += dy
return (x, y)
for i in range(5):
walk = random_walk(10)
print(walk, "Distance from home = ",
abs(walk[0]) + abs(walk[1]))
Output:
(1, 1) Distance from home = 2
(-1, 1) Distance from home = 2
(-3, 3) Distance from home = 6
(0, -2) Distance from home = 2
(1, 3) Distance from home = 4
Program that finds the maximal rectangle containing only 1's of a binary matrix with the maximal histogram problem.
I am trying to do some tests on a code
def maximalRectangle(self, matrix):
if not matrix or not matrix[0]:
return 0
n = len(matrix[0])
height = [0] * (n + 1)
ans = 0
for row in matrix:
for i in range(n):
height[i] = height[i] + 1 if row[i] == '1' else 0
stack = [-1]
for i in range(n + 1):
while height[i] < height[stack[-1]]:
h = height[stack.pop()]
w = i - 1 - stack[-1]
ans = max(ans, h * w)
stack.append(i)
return ans
# Driver Code
if __name__ == '__main__':
matrix = [[0, 1, 0, 1],
[0, 1, 0, 1],
[0, 1, 1, 1],
[1, 1, 1, 1]]
print(maximalRectangle(matrix))
I get TypeError: maximalRectangle() missing 1 required positional argument: 'matrix' error
Solved by removing self and changing the print statement to:
print(maximalRectangle([
["1","0","1","0","0"],
["1","1","1","1","1"],
["1","1","1","1","1"],
["1","0","0","1","0"]]))
The following recursive relation solves a variation of the coin exchange problem. Count the number of ways in which we can sum to a required value, while keeping the number of summands even:
def count_even(coins, num_coins, req_sum, parity):
if req_sum < 0:
return 0
if req_sum == 0 and not parity:
return 1
if req_sum == 0 and parity:
return 0
if num_coins == 0:
return 0
count_wout_high_coin = count_even(coins, num_coins - 1, req_sum, parity)
count_with_high_coin = count_even(coins, num_coins, req_sum - coins[num_coins - 1], not parity)
return count_wout_high_coin + count_with_high_coin
This code would yield the required solution if called with parity = False.
I am having issues implementing a tabulation technique to optimize this algorithm. On a first attempt I tried to follow the same pattern as for other DP problems, and took the parity as another parameter to the problem, so I coded this triple loop:
def count_even_tabulation(S, m, n):
if m <= 0 or n < 0:
return 0
if n == 0:
return 1
table = [[[0 for x in range(m)] for x in range(n + 1)] for x in range(2)]
for j in range(m):
table[0][0][j] = 1
table[1][0][j] = 0
for p in range(2):
for i in range(1, n + 1):
for j in range(m):
y = table[p][i][j - 1] if j >= 1 else 0
x = table[1 - p][i - S[j]][j] if i - S[j] >= 0 else 0
table[p][i][j] = x + y
return table[0][n][m - 1]
However, this approach is not creating the right tables for parity equal to 0 and equal to 1:
[1, 1, 1]
[0, 0, 0]
[0, 0, 0]
[0, 0, 0]
[0, 0, 0]
[0, 0, 0]
[1, 1, 1]
[0, 1, 1]
[0, 0, 1]
[0, 0, 0]
How can I adequately implement a tabulation approach for the given recursion relation?