Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 10 months ago.
Improve this question
This problem has been occurring for a couple months now with any project that uses complicated sets of equations (such as for composite mechanics analysis or thrust/fluid flow analysis). Simple calculations, iterative methods, and Numpy matrices seem to work fine on their own though. And just to be sure, I have tried completely uninstalling and reinstalling Python and Pycharm, but the same problem persists.
For the past couple months, any code that incorporates more complex mathematics, such as those described above, will output different values despite all input values and calculations being constant. The different codes have no means of variation or randomness. I've noticed these incorrect outputs usually occur within arrays/matrices, and I can tell the output values are incorrect because the expected numbers are instead absurdly large.
For example, an element within a matrix is expected to be 5.197e+7, but instead, the code outputs 3.322e+257 for that same element. However, upon running the code a second time, the code produces an output of 2.822e+204 for the exact same element. Only upon the third run does the code output the correct value for that element, which is 5.197e+7. This process can take anywhere from 1 to 15 separate runs for the same, unchanging code in order to output the correct value.
Another interesting aspect is that the calculations I am coding usually require multiple iterations of said code. However, even though I am resetting the arrays that temporarily save all values (other than final values that no longer affect the calculations), whatever is causing these "errors is being carried through the code until the end of the iterations. To my understanding, this shouldn't be the case since, at the end of an iteration, the code is setting all values, other than the known initial values, to 0 and recalculating. This would mean that the code is continuously making the same error.
Below are some examples of the program's expected output vs actual outputs.
Expected Output for First Iteration
NM = [[ 2.57939977e+04]
[ 3.03926820e+04]
[-3.55271368e-13]
[ 1.00000000e+00]
[ 1.00000000e+00]
[ 2.60208521e-16]]
[A] =
[[1.50155575e+08 4.45004838e+07 0.00000000e+00]
[4.44974703e+07 1.07288531e+08 0.00000000e+00]
[0.00000000e+00 0.00000000e+00 5.19662175e+07]]
[D] =
[[60.771 7.663 4.019]
[ 7.659 12.322 4.019]
[ 4.019 4.019 9.567]]
1st Attempt: Actual Output for First Iteration
NM =
[[2.57939977e+004]
[7.26576487e+225]
[2.35904846e+253]
[7.25895469e+242]
[1.18107381e+291]
[1.61312569e+291]]
[A] =
[[1.50155575e+08 4.45004838e+07 0.00000000e+00]
[4.44974703e+07 1.07288531e+08 0.00000000e+00]
[0.00000000e+00 0.00000000e+00 5.19662175e+07]]
[D] =
[[60.771 7.663 4.019]
[ 7.659 12.322 4.019]
[ 4.019 4.019 9.567]]
2nd Try: First Iteration
NM = [[2.18479897e+158]
[3.03926820e+004]
[1.62552246e+034]
[1.00000121e+000]
[1.07935186e+000]
[2.60208521e-016]]
[A] =
[[1.50155575e+08 4.45004838e+07 0.00000000e+00]
[4.44974703e+07 1.07288531e+08 0.00000000e+00]
[0.00000000e+00 0.00000000e+00 5.19662175e+07]]
[D] =
[[60.771 7.663 4.019]
[ 7.659 12.322 4.019]
[ 4.019 4.019 9.567]]
3rd Try: First Iteration
NM = [[ 2.57939977e+004]
[ 3.03926820e+004]
[-3.55271368e-013]
[ 4.54183603e+225]
[ 6.28847407e+094]
[ 2.60208521e-016]]
[A] =
[[1.50155575e+08 4.45004838e+07 0.00000000e+00]
[4.44974703e+07 1.07288531e+08 0.00000000e+00]
[0.00000000e+00 0.00000000e+00 5.19662175e+07]]
[D] =
[[60.771 7.663 4.019]
[ 7.659 12.322 4.019]
[ 4.019 4.019 9.567]]
4th Try: First Iteration
NM = [[ 2.57939977e+04]
[ 3.03926820e+04]
[-3.55271368e-13]
[ 1.00000000e+00]
[ 1.00000000e+00]
[ 2.60208521e-16]]
[A] =
[[1.50155575e+008 4.45004838e+007 0.00000000e+000]
[4.44974703e+007 1.07288531e+008 0.00000000e+000]
[0.00000000e+000 0.00000000e+000 2.39203287e+198]]
[D] =
[[60.771 7.663 4.019]
[ 7.659 12.322 4.019]
[ 4.019 4.019 9.567]]
As can be seen, the fourth iteration finally produced the correct NM matrix; however, the [A] matrix goes from having the correct values to an incorrect A[3][3] element. However, after a few more attempts at re-running the program, the program finally outputs all three correct matrices. As stated before, this can take anywhere between 1 and 15 attempts.
At this point, I'm lost with what could be causing these issues. I've given my code to others to run on their own computers and the program seems to have no issue. Any advice on how I can resolve this would be greatly appreciated. The full code and instructions for viewing the first iteration is below. If anything else is needed, please let me know.
To Re-create
Run the code making sure C.stress_critical_loads() is commented out and C.tsai_wu() is not commented out in the main method.
After running, scroll to the top of the output and then scroll down until the first instances of NM, [A], [B], and [D].
If you see an error message in the middle of the output code, it's because the NM matrix is wrong. The error message goes away when the NM matrix is correct. The program also runs despite the error message.
Thanks again for any advice anyone can give.
import numpy as np
import math
from tabulate import *
def stress_transformation_matrix(x):
# This function calculates the stress transformation
# matrix given an input value for the ply angle
return np.array([
[math.cos(x)**2, math.sin(x)**2, 2*math.sin(x)*math.cos(x)],
[math.sin(x)**2, math.cos(x)**2, -2*math.sin(x)*math.cos(x)],
[-math.sin(x)*math.cos(x), math.sin(x)*math.cos(x), math.cos(x)**2 - math.sin(x)**2]
])
def strain_transformation_matrix(x):
# This function calculates the strain transformation
# matrix given an input value for the ply angle
return np.array([
[math.cos(x)**2, math.sin(x)**2, math.sin(x)*math.cos(x)],
[math.sin(x)**2, math.cos(x)**2, -math.sin(x)*math.cos(x)],
[-2*math.sin(x)*math.cos(x), 2*math.sin(x)*math.cos(x), math.cos(x)**2-math.sin(x)**2]
])
def local_stiffness_matrix(E11, E22, G12, v12, v21):
# This function calculates the local stiffness
# given the material properties at each ply
return np.array([
[E11 / (1 - v12 * v21), v21 * E11 / (1 - v12 * v21), 0],
[v12 * E22 / (1 - v12 * v21), E22 / (1 - v12 * v21), 0],
[0, 0, G12]
])
class Properties:
def __init__(self):
# Material Properties
self.M_E11 = np.array([181E9, 204E9, 138E9, 38.6E9, 76E9])
self.M_E22 = np.array([10.3E9, 18.5E9, 9E9, 8.3E9, 5.5E9])
self.M_G12 = np.array([7.17E9, 5.59E9, 7.1E9, 4.14E9, 2.3E9])
self.M_v12 = np.array([0.280, 0.230, 0.300, 0.260, 0.340])
self.M_v21 = np.array([0.016, 0.021, 0.019, 0.056, 0.33])
self.E11 = np.array([])
self.E22 = np.array([])
self.G12 = np.array([])
self.v12 = np.array([])
self.v21 = np.array([])
# Ultimate Failure Strengths
self.P_SLT = np.array([1500E6, 1260E6, 1447E6, 1062E6, 1400E6])
self.P_SLc = np.array([1500E6, 2499E6, 1447E6, 610E6, 235E6])
self.P_STt = np.array([40E6, 61E6, 52E6, 31E6, 12E6])
self.P_STc = np.array([246E6, 202E6, 206E6, 118E6, 53E6])
self.P_SLTs = np.array([68E6, 67E6, 93E6, 72E6, 34E6])
self.SLT = np.array([])
self.SLc = np.array([])
self.STt = np.array([])
self.STc = np.array([])
self.SLTs = np.array([])
# Ultimate Failure Strains
self.P_epsLtf = np.array([1.087E-2, 0, 1.380E-2, 2.807E-2, 0])
self.P_epsLcf = np.array([0.652E-2, 0, 1.175E-2, 1.754E-2, 0])
self.P_epsCtf = np.array([0.245E-2, 0, 0.436E-2, 0.456E-2, 0])
self.P_epsCcf = np.array([1.818E-2, 0, 2E-2, 1.2E-2, 0])
self.P_epsLTs = np.array([4E-2, 0, 2E-2, 4E-2, 0])
self.epsLtf = np.array([])
self.epsLcf = np.array([])
self.epsCtf = np.array([])
self.epsCcf = np.array([])
self.epsLTs = np.array([])
# Strength Ratios for stress and strain
self.R11_s = np.array([])
self.R22_s = np.array([])
self.R12_s = np.array([])
self.R11_e = np.array([])
self.R22_e = np.array([])
self.R12_e = np.array([])
self.R_crit_s = np.array([])
self.R_crit_e = np.array([])
# Tsai-Wu Coefficients
self.F11 = np.array([])
self.F22 = np.array([])
self.F12 = np.array([])
self.F66 = np.array([])
self.F1 = np.array([])
self.F2 = np.array([])
# Stiffness and Transformation Matrices
self.Q = np.array([])
self.Q_hat = np.array([])
self.T = np.array([])
self.T_hat = np.array([])
# ABD Matrices
self.A = np.empty(shape=(3, 3))
self.B = np.empty(shape=(3, 3))
self.D = np.empty(shape=(3, 3))
self.ABD = np.empty(shape=(6, 6))
# Laminate Loads
self.Nxx = 200
self.Nyy = 200
self.Nxy = 0
self.Mxx = 1
self.Myy = 1
self.Mxy = 0
self.N_mech = np.array([])
self.M_mech = np.array([])
self.NT = np.empty(shape=(3, 1))
self.MT = np.empty(shape=(3, 1))
self.NM = np.array([])
self.Nxx_cs = np.array([])
self.Mxx_cs = np.array([])
self.Nxx_ce = np.array([])
self.Mxx_ce = np.array([])
# Mid-plane Strains and Curvatures
self.e0_k = np.array([])
self.e0 = np.array([])
self.k0 = np.array([])
# Stresses and Strains
self.sg = np.array([]) # global stress
self.sl = np.array([]) # local stress
self.eg = np.array([]) # global strain
self.el = np.array([]) # local strain
# Ply Orientations
self.lam = None # total laminate thickness
self.z_lam = np.array([]) # laminate thickness from to pto bottom
self.z_m = np.array([]) # mid-plane laminate thickness
# Table and Material Properties
self.mat = np.array([])
self.mat_list = np.array([])
# Total Ply Failure
self.Beta = np.array([])
# Angle at Each Ply (deg)
self.angle = np.array([0, 0, 45, 45, -45, -45, 90, 90, -45, -45, 45, 45, 0, 0])
self.a = np.array([])
# Thickness at Each Ply (m)
self.z = np.array([0.125E-3, 0.125E-3, 0.125E-3, 0.125E-3, 0.125E-3, 0.125E-3, 0.125E-3, 0.125E-3, 0.125E-3,
0.125E-3, 0.125E-3, 0.125E-3, 0.125E-3, 0.125E-3])
# Number of Ply
self.n = self.angle.size
# Material at Each Ply
self.m = np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
# 0: T300/5208
# 1: B(4) 5505
# 2: AS4/3501
# 3: Scotchply 1002
# 4: Kevlar49/Epoxy
# Thermal Properties
self.a1 = -0.018E-6 # longitudinal thermal expansion, deg. C
self.a2 = 24.3E-6 # transverse thermal expansion, deg. C
self.a3 = 0 # shear thermal expansion, deg. C
self.dT = 100 # change in temperature, deg. C
def ply_angle(self):
a = np.array([])
for i in range(self.n):
a = np.append(a, math.radians(self.angle[i]))
self.a = a
def ply(self):
# set total laminate ply failure array
self.Beta = np.full(self.n, 1)
# Determine the thickness of each ply
self.lam = sum(self.z)
print('Total Thickness =', self.lam)
for i in range(self.n):
self.z_lam = np.append(self.z_lam, -self.lam / 2 + (i + 1) * self.z[i])
print('Top-Bottom =', self.z_lam)
for i in range(self.n):
self.z_m = np.append(self.z_m, -self.lam / 2 - self.z[i] / 2 + (i + 1) * self.z[i])
print('Mid-plane =', self.z_m)
def material(self):
for i in range(self.n):
m = self.m[i]
# Material Properties
self.E11 = np.append(self.E11, self.M_E11[m])
self.E22 = np.append(self.E22, self.M_E22[m])
self.G12 = np.append(self.G12, self.M_G12[m])
self.v12 = np.append(self.v12, self.M_v12[m])
self.v21 = np.append(self.v21, self.M_v21[m])
self.mat_list = np.append(self.mat_list, m)
# Ultimate Failure Strengths
self.SLT = np.append(self.SLT, self.P_SLT[m])
self.SLc = np.append(self.STc, self.P_SLc[m])
self.STt = np.append(self.STt, self.P_STt[m])
self.STc = np.append(self.STc, self.P_STc[m])
self.SLTs = np.append(self.SLTs, self.P_SLTs[m])
# Ultimate Failure Strains
self.epsLtf = np.append(self.epsLtf, self.P_epsLtf[m])
self.epsLcf = np.append(self.epsLcf, self.P_epsLcf[m])
self.epsCtf = np.append(self.epsCtf, self.P_epsCtf[m])
self.epsCcf = np.append(self.epsCcf, self.P_epsCcf[m])
self.epsLTs = np.append(self.epsLTs, self.P_epsLTs[m])
# Tsai-Wu Coefficients
self.F11 = np.append(self.F11, 1 / (self.P_SLT[m] * self.P_SLc[m]))
self.F22 = np.append(self.F22, 1 / (self.P_STt[m] * self.P_STc[m]))
self.F12 = np.append(self.F12, -math.sqrt(self.F11[i] * self.F22[i]) / 2)
self.F66 = np.append(self.F66, 1 / self.P_SLTs[m] ** 2)
self.F1 = np.append(self.F1, 1 / self.P_SLT[m] - 1 / self.P_SLc[m])
self.F2 = np.append(self.F2, 1 / self.P_STt[m] - 1 / self.P_STc[m])
if m == 0: self.mat = np.append(self.mat, 'T300/5208')
elif m == 1: self.mat = np.append(self.mat, 'B(4)/5505')
elif m == 2: self.mat = np.append(self.mat, 'AS4/3501')
elif m == 3: self.mat = np.append(self.mat, 'Scotchply 1002')
else: self.mat = np.append(self.mat, 'Kevlar49/Epoxy')
print('F11 = ', self.F11)
print('F22 =', self.F22)
print('F12 =', self.F12)
print('F66 =', self.F66)
print('F1 =', self.F1)
print('F2 =', self.F2)
def mechanical_loads(self):
self.N_mech = np.array([
[self.Nxx],
[self.Nyy],
[self.Nxy]
])
self.M_mech = np.array([
[self.Mxx],
[self.Myy],
[self.Mxy]
])
def local_thermal_coef(self):
al = np.array([
[self.a1],
[self.a2],
[self.a3]
])
return al
def material_properties(self):
# Creates a table for the material properties of each different ply
mat_list = list(map(int, set(self.mat_list)))
for i in mat_list:
data = np.array([[self.E11[i], self.E22[i], self.G12[i], self.v12[i], self.v21[i]]])
Q = local_stiffness_matrix(self.E11[i], self.E22[i], self.G12[i], self.v12[i], self.v21[i])
print('\nMaterial =', self.mat[i], '(in SI units)')
print(tabulate(data, headers=['E11', 'E22', 'G12', 'v12', 'v21']))
print('\nMaterial =', self.mat[i], '(in Pa)')
print('[Q] =\n', np.round(Q, 3))
print('')
def table(self):
# Creates a table of ply number, thickness, orientation and material
table = np.array([])
for i in range(self.n):
data = np.array([[i+1, self.mat[i], self.z[i], math.degrees(self.a[i])]])
if i == 0:
table = np.append(table, data)
else:
table = np.vstack([table, data])
print(tabulate(table, headers=['Lamina', 'Material', 'Thickness', 'Orientation']))
class Calculations(Properties):
def __init__(self):
super().__init__()
self.NM = np.array([]) # Loads and Moments
self.e0_k = np.array([]) # Mid-plane strains and curvatures
self.fail_order = np.array([]) # Ply order of failure
def a_matrix(self):
for i in range(self.n):
T = stress_transformation_matrix(self.a[i])
T_hat = strain_transformation_matrix(self.a[i])
if self.Beta[i] == 1:
Q = local_stiffness_matrix(self.E11[i], self.E22[i], self.G12[i], self.v12[i], self.v21[i])
else:
Q = np.array([
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
])
Q_hat = np.matmul(np.linalg.inv(T), Q)
Q_hat = np.matmul(Q_hat, T_hat)
A = Q_hat * (self.z_lam[i] - (self.z_lam[i] - self.z[i]))
self.A = np.add(self.A, A)
# print('\nLamina', i, '\t\u03B8 =', math.degrees(self.a[i]), 't =', self.z[i], 'Material =', self.mat[i-1])
# print('[Q\u0302] =\n', np.round(Q_hat, 3))
print('\nLaminate Stiffness Matrices\n[A] =\n', np.round(self.A, 3))
def b_matrix(self):
for i in range(self.n):
T = stress_transformation_matrix(self.a[i])
T_hat = strain_transformation_matrix(self.a[i])
if self.Beta[i] == 1:
Q = local_stiffness_matrix(self.E11[i], self.E22[i], self.G12[i], self.v12[i], self.v21[i])
else:
Q = np.array([
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
])
Q_hat = np.matmul(np.linalg.inv(T), Q)
Q_hat = np.matmul(Q_hat, T_hat)
B = Q_hat * (self.z_lam[i] ** 2 - (self.z_lam[i] - self.z[i]) ** 2)
self.B = np.add(self.B, B)
self.B /= 2
print('\n[B] =\n', np.round(self.B, 3))
def d_matrix(self):
for i in range(self.n):
T = stress_transformation_matrix(self.a[i])
T_hat = strain_transformation_matrix(self.a[i])
if self.Beta[i] == 1:
Q = local_stiffness_matrix(self.E11[i], self.E22[i], self.G12[i], self.v12[i], self.v21[i])
else:
Q = np.array([
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
])
Q_hat = np.matmul(np.linalg.inv(T), Q)
Q_hat = np.matmul(Q_hat, T_hat)
D = Q_hat * (self.z_lam[i] ** 3 - (self.z_lam[i] - self.z[i]) ** 3)
self.D = np.add(self.D, D)
self.D /= 3
print('\n[D] =\n', np.round(self.D, 3))
def matrices_combined(self):
self.a_matrix() # call A matrix method
self.b_matrix() # call B matrix method
self.d_matrix() # call D matrix method
self.ABD = np.array([
[np.array(self.A[0][0]), np.array(self.A[0][1]), np.array(self.A[0][2]), np.array(self.B[0][0]), np.array(self.B[0][1]), np.array(self.B[0][2])],
[np.array(self.A[1][0]), np.array(self.A[1][1]), np.array(self.A[1][2]), np.array(self.B[1][0]), np.array(self.B[1][1]), np.array(self.B[1][2])],
[np.array(self.A[2][0]), np.array(self.A[2][1]), np.array(self.A[2][2]), np.array(self.B[2][0]), np.array(self.B[2][1]), np.array(self.B[2][2])],
[np.array(self.B[0][0]), np.array(self.B[0][1]), np.array(self.B[0][2]), np.array(self.D[0][0]), np.array(self.D[0][1]), np.array(self.D[0][2])],
[np.array(self.B[1][0]), np.array(self.B[1][1]), np.array(self.B[1][2]), np.array(self.D[1][0]), np.array(self.D[1][1]), np.array(self.D[1][2])],
[np.array(self.B[2][0]), np.array(self.B[2][1]), np.array(self.B[2][2]), np.array(self.D[2][0]), np.array(self.D[2][1]), np.array(self.D[2][2])],
])
def calculated_loads(self):
self.NM = np.matmul(self.ABD, self.e0_k)
print('\nResulting Loads and Moments\n', np.round(self.NM, 3))
def thermal_loads(self):
al = self.local_thermal_coef()
for i in range(self.n):
T = stress_transformation_matrix(self.a[i])
T_hat = strain_transformation_matrix(self.a[i])
if self.Beta[i] == 1:
Q = local_stiffness_matrix(self.E11[i], self.E22[i], self.G12[i], self.v12[i], self.v21[i])
else:
Q = np.array([
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
])
Q_hat = np.matmul(np.linalg.inv(T), Q)
Q_hat = np.matmul(Q_hat, T_hat)
ag = np.matmul(np.linalg.inv(T_hat), al)
NT = np.matmul(Q_hat, ag) * (self.z_lam[i] - (self.z_lam[i] - self.z[i]))
self.NT = np.add(self.NT, NT)
MT = np.matmul(Q_hat, ag) * (self.z_lam[i] ** 2 - (self.z_lam[i] - self.z[i]) ** 2)
self.MT = np.add(self.MT, MT)
self.NT *= self.dT
self.MT *= (self.dT / 2)
def combined_loads(self):
# Combine the mechanical and thermal loads
self.mechanical_loads()
self.thermal_loads()
N = self.N_mech + self.NT
M = self.M_mech + self.MT
self.NM = np.vstack((N, M))
print('\nNM =', self.NM)
def calculated_midplane_strains_curvatures(self):
self.matrices_combined() # call ABD matrix method
# self.loads()
self.e0_k = np.matmul(np.linalg.inv(self.ABD), self.NM)
# print('\nResulting Mid-Plane Strains and Curvatures\n', self.e0_k)
self.e0 = np.array([
self.e0_k[0],
self.e0_k[1],
self.e0_k[2]
])
self.k0 = np.array([
self.e0_k[3],
self.e0_k[4],
self.e0_k[5]
])
def calculated_stresses_and_strains(self):
self.combined_loads() # call calculated loads method
self.calculated_midplane_strains_curvatures() # call mid-plane strains and curvature method
for i in range(self.n):
eg = np.array([self.e0 + self.z_m[i] * self.k0])
if i == 0:
self.eg = np.array(eg)
else:
self.eg = np.append(self.eg, eg, axis=0)
for i in range(self.n):
T_hat = strain_transformation_matrix(self.a[i])
el = np.matrix(np.matmul(T_hat, self.eg[i]))
if i == 0:
self.el = np.array(el)
else:
self.el = np.append(self.el, el, axis=1)
# All values of local strains are 1x3 arrays, so
# each time the strain is needed, the specific
# array must be selected and then transposed
self.el = np.transpose(self.el)
# print('[Local Strain] =', self.el)
for i in range(self.n):
Q = local_stiffness_matrix(self.E11[i], self.E22[i], self.G12[i], self.v12[i], self.v21[i])
sl = np.matrix(np.matmul(Q, np.transpose(np.matrix(self.el[i]))))
if i == 0:
self.sl = np.array(sl)
else:
self.sl = np.append(self.sl, sl, axis=1)
# All values of local stress are 1x3 arrays, so
# each time the stress is needed, the specific
# array must be selected and then transposed
self.sl = np.transpose(self.sl)
print('\n[Local Stress] =\n', self.sl)
def stress_strength_ratio_11(self):
for i in range(self.n):
sl = np.transpose(self.sl[i])
if float(sl[0]) >= 0:
self.R11_s = np.append(self.R11_s, self.SLT[i] / float(sl[0]))
else:
self.R11_s = np.append(self.R11_s, self.SLc[i] / abs(float(sl[0])))
def stress_strength_ratio_22(self):
for i in range(self.n):
sl = np.transpose(self.sl[i])
if float(sl[1]) >= 0:
self.R22_s = np.append(self.R22_s, self.STt[i] / float(sl[1]))
else:
self.R22_s = np.append(self.R22_s, self.STc[i] / abs(float(sl[1])))
def stress_strength_ratio_12(self):
for i in range(self.n):
sl = np.transpose(self.sl[i])
self.R12_s = np.append(self.R12_s, self.SLTs[i] / abs(float(sl[2])))
def stress_critical_loads(self):
self.calculated_stresses_and_strains()
self.stress_strength_ratio_11() # call R11 method
self.stress_strength_ratio_22() # call R22 method
self.stress_strength_ratio_12() # call R12 method
for i in range(self.n):
R = np.array([
[self.R11_s[i], self.R22_s[i], self.R12_s[i]]
])
if self.Beta[i] == 1:
R_crit = np.min(R)
else:
R_crit = 9999
self.R_crit_s = np.append(self.R_crit_s, R_crit)
self.Nxx_cs = np.append(self.Nxx_cs, R_crit * self.Nxx)
self.Mxx_cs = np.append(self.Mxx_cs, R_crit * self.Mxx)
Nxx_c = np.min(self.Nxx_cs)
N_pos = np.where(self.Nxx_cs == Nxx_c)[0]
Mxx_c = np.min(self.Mxx_cs)
self.fail_order = np.append(self.fail_order, N_pos + 1)
print('\nPly Failure in ply', N_pos + 1)
print('R_crit =', np.min(self.R_crit_s))
print('Critical in-plane loading at ply', N_pos + 1, '=', Nxx_c, '')
print('Critical bending loading at ply', N_pos + 1, '=', Mxx_c, '')
print('Stress: Nxx_c =', Nxx_c)
print('Stress: Mxx_c =', Mxx_c)
Beta = np.full(self.n, 0)
if not np.array_equal(self.Beta, Beta):
self.Beta[N_pos] = 0
print(self.Beta)
# Reset all values
self.A = np.zeros(shape=(3, 3))
self.B = np.zeros(shape=(3, 3))
self.D = np.zeros(shape=(3, 3))
self.ABD = np.zeros(shape=(6, 6))
self.eg = np.zeros([])
self.el = np.zeros([])
self.sl = np.zeros([])
self.NT = np.zeros(shape=(3, 1))
self.MT = np.zeros(shape=(3, 1))
self.NM = np.zeros(shape=(6, 1))
self.R11_s = np.zeros([])
self.R22_s = np.zeros([])
self.R12_s = np.zeros([])
self.R_crit_s = np.zeros([])
self.Nxx_cs = np.zeros([])
self.Mxx_cs = np.zeros([])
# re-run calculations
if not np.array_equal(self.Beta, Beta):
self.stress_critical_loads()
else:
print('Ply Fail Order =', self.fail_order)
def tsai_wu(self):
self.calculated_stresses_and_strains()
a = np.array([])
b = np.array([])
c = np.array([])
R1 = np.array([])
R2 = np.array([])
for i in range(self.n):
sl = np.transpose(self.sl[i])
a = np.append(a, self.F11[i] * sl[0] ** 2 + 2 * self.F12[i] * sl[0] * sl[1]
+ self.F22[i] * sl[1] ** 2 + self.F66[i] * sl[2] ** 2)
b = np.append(b, self.F1[i] * sl[0] + self.F2[i] * sl[1])
c = np.append(c, -1)
for i in range(self.n):
if self.Beta[i] == 1:
R1 = np.append(R1, (-b[i] + math.sqrt(b[i]**2 - 4 * a[i] * c[i])) / (2 * a[i]))
R2 = np.append(R2, (-b[i] - math.sqrt(b[i]**2 - 4 * a[i] * c[i])) / (2 * a[i]))
else:
R1 = np.append(R1, 9999)
R2 = np.append(R2, -9999)
R_crit = np.min(R1)
R_crit_pos = np.where(R1 == R_crit)[0]
# print('R1 =', R1)
# print('R2 =', R2)
print('\nR_cr at ply', R_crit_pos + 1, '=', R_crit, '')
self.fail_order = np.append(self.fail_order, R_crit_pos + 1)
NTW_xxc = R_crit * self.Nxx
MTW_xxc = R_crit * self.Mxx
print('N_xx,cr for ply', R_crit_pos + 1, '=', NTW_xxc)
print('M_xx,cr for ply', R_crit_pos + 1, '=', MTW_xxc)
Beta = np.full(self.n, 0)
if not np.array_equal(self.Beta, Beta):
self.Beta[R_crit_pos] = 0
print('\nFailure Progression =', self.Beta)
# Reset all values
self.A = np.zeros(shape=(3, 3))
self.B = np.zeros(shape=(3, 3))
self.D = np.zeros(shape=(3, 3))
self.ABD = np.zeros(shape=(6, 6))
self.eg = np.zeros([])
self.el = np.zeros([])
self.sl = np.zeros([])
self.NT = np.zeros(shape=(3, 1))
self.MT = np.zeros(shape=(3, 1))
self.NM = np.zeros(shape=(6, 1))
# re-run all values
if not np.array_equal(self.Beta, Beta):
self.tsai_wu()
else:
print('Ply Fail Order =', self.fail_order)
def main():
C = Calculations()
C.ply_angle()
C.ply()
C.material()
C.material_properties()
C.table()
# Comment out for Tsai-Wu failure calculations
# print('\nCritical Stress Criterion')
# C.stress_critical_loads()
# Comment out for Maximum Stress failure calculations
print('\nTsai-Wu Criterion\n')
C.tsai_wu()
if __name__ == '__main__':
main()
I don't know if it's the cause of your problem, but your code has six calls to np.empty. I don't see any later initialization of these arrays.
np.empty causes the array to not be initialized, and the memory will contain random garbage. Try replace those with np.zeros and see if you get better results.
Related
Good day to you.
From a previous model with cplex (MIP 1), I use M0 as a parameter.
Total_P = 8
M0 = np.array([[0,1,0,1,0,0,0,2]]).reshape(Total_P,1)
Then, I tried to develop a different model (MIP 2) with adjusted objectives and constraints from MIP2, however, the M0 now becomes a decision variable and use for several constraints (#constraint 38). So, I created a code as follows:
Total_P = 8
M0 = np.empty((Total_P,1), dtype = object)
for l in range(0,Total_P):
M0[l][0]= mdl.integer_var(name='M0'+ str(',') + str(l+1))
for l in range(0,Total_P):
if M0[l][0] is not None:
mdl.add_constraint((M0[1][0] + M0[5][0]) == 1)
mdl.add_constraint((M0[3][0] + M0[6][0]) == 1)
mdl.add_constraint((M0[0][0] + M0[2][0] + M0[4][0] + M0[7][0]) == 2)
After running the cplex with the same parameters input:
The result from MIP 1: obj_lambda=213
The result from MIP 2: obj_lamba= 205.0 and the M0 is [[0,1,1,0,0,0,1,1]]
The correct result of M0 from the MIP 2 should be [[0,1,0,1,0,0,0,2]] as in the M0 (parameter in MIP 1) and obj_lambda=213.
Here is the full code of MIP 1:
import cplex
from docplex.mp.model import Model
import numpy as np
mdl = Model(name='Scheduling MIP 1')
inf = cplex.infinity
bigM= 10000
Total_P = 8 # number of places
Total_T = 6 # number of transitions
r1 = 100 #processing time for PM1 (second)
r2 = 200 #processing time for PM2 (second)
v = 3 #robot moving time (second)
w = 5 #loading or unloading time (second)
M0 = np.array([[0,1,1,0,0,0,1,1]]).reshape(Total_P,1)
M0_temp = M0.reshape(1,Total_P)
M0_final = M0_temp.tolist()*Total_T
h = np.array([v+w,w+r1,v+w,w+r2,v+w,0,0,0]).reshape(Total_P,1)
#Parameter
AT =np.array([[1,-1,0,0,0,0],
[0,1,-1,0,0,0],
[0,0,1,-1,0,0],
[0,0,0,1,-1,0],
[0,0,0,0,1,-1],
[0,-1,1,0,0,0],
[0,0,0,-1,1,0],
[-1,1,-1,1,-1,1]])
AT_temp = AT.transpose()
places = np.array(['p1','p2','p3','p4','p5','p6','p7','p8'])
P_conflict = np.empty((1,Total_P), dtype = object)
P_zero = np.empty((1,Total_P), dtype = object)
#Define the place without conflict place
CP = np.count_nonzero(AT, axis=1, keepdims=True) #calculate the nonzero elements for each row
P_conflict = []
P_zero = []
for a in range(0, len(CP)):
if CP[a].item(0) > 2:
P_conflict.append(places[a])
else:
P_zero.append(places[a])
print('p_zero', np.shape(P_zero))
obj_lambda = [ ]
obj_lambda = mdl.continuous_var(lb = 0, ub=inf, name='obj_lambda')
x = np.array(mdl.continuous_var_list(Total_T, 0, inf, name='x')).reshape(Total_T,)
ind_x = np.where(AT[0] == 1)
print('ind_x', ind_x)
def get_index_value(input):
data = []
for l in range(len(P_zero)):
ind_x = np.where(AT[l] == input)
get_value = x[ind_x]
data.append(get_value)
return data
x_in = get_index_value(1)
x_out = get_index_value(-1)
#constraint 16
for l in range(0,len(P_zero)): #only for P non conflict
#if x_in is not None and x_out is not None and obj_lambda is not None:
mdl.add_constraint(x_out[l][0]-x_in[l][0] >= h[l][0] - M0[l][0]*obj_lambda)
#Decision Var
Z = np.empty((Total_T, Total_T), dtype = object)
for k in range(Total_T):
for i in range(Total_T):
Z[k][i] = mdl.binary_var(name='Z' + str(k+1) + str(',') + str(i+1))
storage_ZAT = []
for k in range(Total_T):
ZAT = np.matmul(Z[k].reshape(1,Total_T),AT_temp)
storage_ZAT.append(ZAT) #storage_ZAT = np.append(storage_ZAT, ZAT, axis=0)
ZAT_final = np.asarray(storage_ZAT).reshape(Total_T,Total_P)
M = np.empty((Total_T, Total_P), dtype = object)
for k in range(0,Total_T):
for l in range (0,Total_P):
if k == Total_T-1:
M[Total_T-1][l] = M0_final[0][l]
else:
M[k][l] = mdl.continuous_var(name='M' + str(k + 1) + str(',') + str(l + 1))
M_prev = np.empty((Total_T, Total_P), dtype = object)
if M is not None:
for k in range(0,Total_T):
for l in range (0,Total_P):
if k is not 0:
M_prev[k][l] = M[k-1][l]
else:
M_prev[0][l] = M0_final[0][l]
#Constraint 17
for k in range(Total_T):
for l in range(Total_P):
mdl.add_constraint(M[k][l] == M_prev[k][l] + ZAT_final[k][l])
#Constraint 18
mdl.add_constraints(mdl.sum(Z[k][i] for k in range(Total_T)) == 1 for i in range(Total_T))
# Constraint 19
mdl.add_constraints(mdl.sum(Z[k][i] for i in range(Total_T)) == 1 for k in range(Total_T))
# # Parameters
VW_temp = [[v + w]]
VW_temp = VW_temp*Total_T
VW = np.array(VW_temp) #eshape(Total_T,)
#Define S
S = np.array(mdl.continuous_var_list(Total_T, 0, inf, name='S')).reshape(Total_T,1)
#Constraint 20
for k in range(Total_T-1):
mdl.add_constraint(S[k][0] - S[k+1][0] <= -VW[k][0])
# # Constraint 21
mdl.add_constraint(S[Total_T-1][0] - (S[0][0] + obj_lambda) <=-VW[Total_T-1][0])
x_temp = x.reshape(Total_T,1)
print('x_temp',x_temp)
# Constraint 22
for k in range(Total_T):
for i in range(Total_T):
mdl.add_constraint(S[k][0] - x_temp[i][0] <= (1-Z[k][i])*bigM) #why x_temp? because it is the reshape of x
# Constraint 23
for k in range(Total_T):
for i in range(Total_T):
mdl.add_constraint(S[k][0] - x_temp[i][0] >= (Z[k][i]-1)*bigM)
mdl.minimize(obj_lambda)
mdl.print_information()
solver = mdl.solve() #(log_output=True)
if solver is not None:
mdl.print_solution()
miu = 1 / obj_lambda.solution_value
print('obj_lamba=', obj_lambda.solution_value)
print('miu =', miu)
else:
print("Solver is error")
Here is the code of MIP 2:
import cplex
from docplex.mp.model import Model
import numpy as np
mdl = Model(name='Scheduling MILP 2')
inf = cplex.infinity
bigM= 10000
Total_P = 8 # number of places
Total_T = 6 # number of transitions
r1 = 100 #processing time for PM1 (second)
r2 = 200 #processing time for PM2 (second)
v = 3 #robot moving time (second)
w = 5 #loading or unloading time (second)
h = np.array([v+w,w+r1,v+w,w+r2,v+w,0,0,0]).reshape(Total_P,1)
#Parameter
AT =np.array([[1,-1,0,0,0,0],
[0,1,-1,0,0,0],
[0,0,1,-1,0,0],
[0,0,0,1,-1,0],
[0,0,0,0,1,-1],
[0,-1,1,0,0,0],
[0,0,0,-1,1,0],
[-1,1,-1,1,-1,1]])
AT_temp = AT.transpose()
places = np.array(['p1','p2','p3','p4','p5','p6','p7','p8'])
P_conflict = np.empty((1,Total_P), dtype = object)
P_zero = np.empty((1,Total_P), dtype = object)
#Define the place without conflict place
CP = np.count_nonzero(AT, axis=1, keepdims=True) #calculate the nonzero elements for each row
P_conflict = []
P_zero = []
for a in range(0, len(CP)):
if CP[a].item(0) > 2:
P_conflict.append(places[a])
else:
P_zero.append(places[a])
print('p_zero', P_zero)
y = [ ] #miu
y = mdl.continuous_var(lb = 0, ub=inf, name='miu') #error: docplex.mp.utils.DOcplexException: Variable obj_lambda cannot be used as denominator of 1
x = np.array(mdl.continuous_var_list(Total_T, 0, inf, name='x')).reshape(Total_T,)
ind_x = np.where(AT[0] == 1)
def get_index_value(input):
data = []
for l in range(len(P_zero)):
ind_x = np.where(AT[l] == input)
get_value = x[ind_x]
data.append(get_value)
return data
x_in_hat = get_index_value(1)
x_out_hat = get_index_value(-1)
M0 = np.empty((Total_P,1), dtype = object)
for l in range(0,Total_P):
M0[l][0]= mdl.integer_var(name='M0'+ str(',') + str(l+1))
M0_temp= M0.reshape(1,Total_P)
M0_final = M0_temp.tolist()*Total_T
for k in range(Total_T):
for l in range(Total_P):
if M0_final[k][l] is not None:
mdl.add_constraint((M0_final[0][1] + M0_final[0][5]) == 1)
mdl.add_constraint((M0_final[0][3] + M0_final[0][6]) == 1)
mdl.add_constraint((M0_final[0][0] + M0_final[0][2] + M0_final[0][4] + M0_final[0][7]) == 2)
#constraint 30
for l in range(0,len(P_zero)): #only for P non conflict
mdl.add_constraint(x_out_hat[l][0]-x_in_hat[l][0] >= h[l][0]*y - M0[l][0])
#Decision Var
Z = np.empty((Total_T, Total_T), dtype = object)
for k in range(Total_T):
for i in range(Total_T):
# if k == 0 and i == 0:
# Z[0][0]=1
# else:
Z[k][i] = mdl.binary_var(name='Z' + str(k+1) + str(',') + str(i+1))
#
storage_ZAT = []
for k in range(Total_T):
ZAT = np.matmul(Z[k].reshape(1,Total_T),AT_temp)
storage_ZAT.append(ZAT) #storage_ZAT = np.append(storage_ZAT, ZAT, axis=0)
ZAT_final = np.asarray(storage_ZAT).reshape(Total_T,Total_P)
M = np.empty((Total_T, Total_P), dtype = object)
for k in range(0,Total_T):
for l in range (0,Total_P):
if k == Total_T-1:
M[Total_T-1][l] = M0_final[0][l]
else:
M[k][l] = mdl.continuous_var(name='M' + str(k + 1) + str(',') + str(l + 1))
M_prev = np.empty((Total_T, Total_P), dtype = object)
if M is not None:
for k in range(0,Total_T):
for l in range (0,Total_P):
if k is not 0:
M_prev[k][l] = M[k-1][l]
else:
M_prev[0][l] = M0_final[0][l]
#
#Constraint 31
for k in range(Total_T):
for l in range(Total_P):
mdl.add_constraint(M[k][l] == M_prev[k][l] + ZAT_final[k][l])
#
#Constraint 32
mdl.add_constraints(mdl.sum(Z[k][i] for k in range(Total_T)) == 1 for i in range(Total_T))
# Constraint 33
mdl.add_constraints(mdl.sum(Z[k][i] for i in range(Total_T)) == 1 for k in range(Total_T))
# #
# # # # Parameters
VW_temp = [[v + w]]
VW_temp = VW_temp*Total_T
VW = np.array(VW_temp) #eshape(Total_T,)
#
S_hat = np.array(mdl.continuous_var_list(Total_T, 0, inf, name='S_hat')).reshape(Total_T,1)
#Constraint 34
for k in range(0,Total_T-1):
if k < (Total_T-1):
mdl.add_constraint(S_hat[k][0] - S_hat[k+1][0] <= -VW[k][0]*y)
if k == (Total_T - 1):
mdl.add_constraint(S_hat[k][0] - (S_hat[0][0] + 1) <= -VW[Total_T - 1][0] * y)# Constraint 35
#
#
x_temp_hat = x.reshape(Total_T,1)
#
# Constraint 36
for k in range(Total_T):
for i in range(Total_T):
mdl.add_constraint((S_hat[k][0] - x_temp_hat[i][0]) <= (1-Z[k][i])*bigM) #why x_temp? because it is the reshape of x
# Constraint 37
for k in range(Total_T):
for i in range(Total_T):
mdl.add_constraint((S_hat[k][0] - x_temp_hat[i][0]) >= (Z[k][i]-1)*bigM)
mdl.maximize(y)
mdl.print_information()
solver = mdl.solve()
if solver is not None:
mdl.print_solution()
obj_lambda = 1/y.solution_value
print('miu =', y.solution_value)
print('obj_lamba=', obj_lambda)
print('M0 final=', M0_temp)
else:
print("Solver is error")
In this case, could anyone tell me: did I define the M0 as a decision variable and put them into the constraints correctly, please?
Thank you.
I have some code that is mapping data to a matrix... Most of this is all setup so that my problem can be easily reproduced but the only part I need to speed up is what's after the comment # the part I want to speed up
import numpy as np
# config
matrix_height = 100
matrix_width = 200
# fake data
x_data = np.array(range(10000))
y_data = [{i:i for i in range(100)} for t in range(len(x_data))]
# fake mapping
x_to_index = {x: np.random.randint(matrix_width) for x in x_data }
y_to_index = {}
for y_dict in y_data:
for y_key, y_val in y_dict.items():
y_start = np.random.randint(matrix_height-2)
y_to_index[y_key] = (y_start, y_start+2 )
# data that must be stored
total_matrix = np.zeros([matrix_height, matrix_width]).astype(int)
n_matrix = np.zeros([matrix_height, matrix_width]).astype(int)
latest_value = np.zeros([matrix_height, matrix_width]).astype(int)
# the part I want to speed up
for x, y_dict in zip(x_data, y_data):
x_index = x_to_index[x]
for y_key, y_data in y_dict.items():
y_slice = slice(*y_to_index[y_key])
total_matrix[ y_slice, x_index ] += y_data
latest_value[ y_slice, x_index ] = y_data
n_matrix[ y_slice, x_index ] += 1
Again, I'm only concerned with the part below the comment # the part I want to speed up.
I'm not sure how to speed this up but it seems like it should be possible to use a mapping function that can do this all in parallel...
I'm looking for a marked improvement in that last section. Any ideas?
Tailored to number of cores.
For total_matrix, addition is commutative.
For latest_value, apply the split cols in reverse order.
import numpy as np
import time
import multiprocessing as mp
def func(cols, zz, tm, nm, lv, setOrder):
for c in cols:
for t in zz:
tm[slice(*t[0]), c] += t[1]
lv[slice(*t[0]), c] = t[1]
nm[slice(*t[0]), c] += 1
return [tm, nm, lv, setOrder]
if __name__ == '__main__':
mp.freeze_support()
matrix_height = 100
matrix_width = 200
total_range = 10000
x_data = np.array(range(total_range))
y_data = [{i:i for i in range(matrix_height)} for t in range(len(x_data))]
x_to_index = {x: np.random.randint(matrix_width) for x in x_data}
# potential general purpose cols list
#cols = np.random.randint(0, total_range, (1, total_range))[0]
cols = [np.int(x_to_index[k]) for k in x_to_index]
y_to_index = {}
for y_dict in y_data:
for y_key, y_val in y_dict.items():
y_start = np.random.randint(matrix_height-2)
y_to_index[y_key] = (y_start, y_start+2)
# potential general purpose rows list
#rows = [(np.random.randint(matrix_height), np.random.randint(matrix_height)) for x in range(matrix_height)]
rows = [y_to_index[k] for k in y_to_index]
# potential general purpose y data
#y_dat = np.random.randint(0, matrix_height, (1, matrix_height))[0]
y_dat = [i for i in range(matrix_height)]
o_total_matrix = np.zeros([matrix_height, matrix_width]).astype(int)
o_n_matrix = np.zeros([matrix_height, matrix_width]).astype(int)
o_latest_value = np.zeros([matrix_height, matrix_width]).astype(int)
startTime = time.time()
for x, y_dict in zip(x_data, y_data):
x_index = x_to_index[x]
for y_key, y_data in y_dict.items():
y_slice = slice(*y_to_index[y_key])
o_total_matrix[ y_slice, x_index ] += y_data
o_latest_value[ y_slice, x_index ] = y_data
o_n_matrix[ y_slice, x_index ] += 1
print('original time was {0:5.2f} sec'.format(time.time() - startTime))
procs = mp.cpu_count()
i_tm = [np.zeros([matrix_height, matrix_width]).astype(int)] * procs
i_nm = [np.zeros([matrix_height, matrix_width]).astype(int)] * procs
i_lv = [np.zeros([matrix_height, matrix_width]).astype(int)] * procs
zz = list(zip(rows, y_dat))
procs_split = np.array_split(cols, procs)
itup = []
for x in range(procs):
itup.append(((list(procs_split[x])), zz, i_tm[x], i_nm[x], i_lv[x], x))
startTime = time.time()
with mp.Pool(processes=procs) as pool:
ret = pool.starmap(func, itup)
i_total_matrix = ret[0][0]
i_n_matrix = ret[0][1]
for x in range(1, procs):
i_total_matrix = np.add(i_total_matrix, ret[x][0])
i_n_matrix = np.add(i_n_matrix, ret[x][1])
colOrder = [0] * procs
for x in range(procs):
colOrder[x] = (procs-1) - ret[x][3]
i_latest_value = ret[colOrder[0]][2]
for x in range(1, procs):
np.putmask(i_latest_value, i_latest_value == 0, ret[x][2])
print('improved time was {0:5.2f} sec'.format(time.time() - startTime))
comparison = i_total_matrix == o_total_matrix
if not comparison.all():
print('ERROR TOTAL MATRIX')
comparison = i_n_matrix == o_n_matrix
if not comparison.all():
print('ERROR N MATRIX')
comparison = i_latest_value == o_latest_value
if not comparison.all():
print('ERROR LATEST VALUE')
After a trial run, the results showed approx. twice as fast:
original time was 7.12 sec
improved time was 2.29 sec
Implementation of 4bit up counter. First, I have implemented the model without using the bias term. the model seems to have worked correctly but after adding the bias term the model overfits at the very initial stage and the loss becomes zero. Even for the unseen data, the model predicts the same output as of training data. Below is the implementation of the same. What is the problem...
import numpy as np
import matplotlib.pyplot as plt
#Batch training
#input & output
x = np.array([[0,0,1,0],[0,0,0,0],[0,0,0,1],[0,0,1,1],[0,1,0,0],[0,1,0,1],[0,1,1,0],[0,1,1,1],[1,0,0,0],[1,0,0,1]]) # 10*4
y = np.array([[0,0,1,1],[0,0,0,1],[0,0,1,0],[0,1,0,0],[0,1,0,1],[0,1,1,0],[0,1,1,1],[1,0,0,0],[1,0,0,1],[1,0,1,0]]) # 10*4
def sigmoid(x):
return 1/(1+np.exp(-x))
def sigmoid_prime(x):
return sigmoid(x)*(1-sigmoid(x))
Input_Size = 4
Output_Size = 4
Hidden_Layer_Neurons = 8
Learning_Rate = 0.01
weight1 = np.random.uniform( size = ( Input_Size, Hidden_Layer_Neurons ) ) # 4*8
weight2 = np.random.uniform( size = ( Hidden_Layer_Neurons, Output_Size ) ) # 8*4
loss = []
iteration = []
bias1 = np.random.uniform( size = ( x.shape[0], Hidden_Layer_Neurons ) )
bias2 = np.random.uniform( size = ( x.shape[0], Output_Size ) )
for i in range(30000):
a1 = x #10*4
z2 = np.dot( a1, weight1 ) + bias1 # 10*4 ** 4*8 = 10*8
a2 = sigmoid(z2) # 10*8
z3 = np.dot( a2, weight2 ) + bias2 # 10*8 ** 8*4 = 10*4
val = 0
err1 = 0
if i > 100:
for j in range(10):
for k in range(4):
val += (y[j][k]-z3[j][k])*(y[j][k]-z3[j][k])
val = val/(2*10)
loss.append(val);
iteration.append(i)
del_out = ( z3 - y ) # 10*4 - 10*4 = 10*4
weight2 -= Learning_Rate*np.dot( a2.T, del_out )#8*10 ** 10*4= 8*4
bias2 -= Learning_Rate*del_out
err = np.dot(del_out, weight2.T)*sigmoid_prime(z2) #10*4 ** 4*8 = 10*8 * 10*8= 10*8
weight1 -= Learning_Rate*np.dot( a1.T, err ) #4*10 ** 10*8 = 4*8
bias1 -= Learning_Rate*err
print(z3)
plt.plot( iteration, loss )
plt.show()
def model():
q = np.array([[1,0,1,0],[1,0,1,1],[1,1,0,0], [1,1,0,1], [1,1,1,0], [1,0,0,0],[1,1,1,1],[0,0,1,1],[0,0,0,1],[0,0,1,0]])
z = np.dot(q, weight1) + bias1
act_hidden = sigmoid(z)
output = np.dot(act_hidden, weight2) + bias2
print(output)
model()
Why bias adding creates a problem here and when we should add bias?
I am converting an IDL code (written by Oleg Kochukhov) to Python. The code generates star surface map over spectral line profiles using Tikhonov or Maximum Entropy methods.
I use scipy.optimize.minimize to generate map over line profiles. But process is too slow and results is not compatible. I search solution on internet but i dont find any usefull solution.
I added a runnable code below:
import numpy as np
from scipy.optimize import minimize
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
import matplotlib.gridspec as gridspec
#syc = 0
def DI_GridInit(ntot):
# generate stellar surface grid
nlat = int(round(0.5 * (1.0 + np.sqrt(1.0 + np.pi * ntot))) - 1)
nlon = np.zeros(nlat, dtype=int)
xlat = np.pi * (np.arange(nlat, dtype=float) + 0.5) / nlat - np.pi / 2.0
xcirc = 2.0 * np.cos(xlat[1:])
nlon[1:] = np.around(xcirc * nlat) + 1
nlon[0] = ntot - sum(nlon[1:])
if abs(nlon[0] - nlon[nlat - 1]) > nlat:
nlon[1:] = nlon[1:] + (nlon[0] - nlon[nlat - 1]) / nlat
nlon[0] = ntot - sum(nlon[1:])
if nlon[0] < nlon[nlat - 1]:
nlon[1:] = nlon[1:] - 1
nlon[0] = ntot - sum(nlon[1:])
# generate Descartes coordinates for the surface grid in
# stellar coordinates, areas of surface elements and
# regularization indices: (lower, upper, right, left)
x0, j = np.zeros((ntot, 3), dtype=float), 0
latitude, longitude = np.zeros(ntot, dtype=float), np.zeros(ntot, dtype=float)
sa, ireg = np.zeros(ntot, dtype=float), np.zeros((ntot, 4), dtype=int)
slt = np.hstack((0., (xlat[1:nlat] + xlat[0:nlat - 1]) / 2. + np.pi / 2., np.pi))
for i in range(nlat):
coslat = np.cos(xlat[i])
sinlat = np.sin(xlat[i])
xlon = 2 * np.pi * (np.arange(nlon[i]) + 0.5) / nlon[i]
sinlon = np.sin(xlon)
coslon = np.cos(xlon)
x0[:, 0][j:j + nlon[i]] = coslat * sinlon
x0[:, 1][j:j + nlon[i]] = -coslat * coslon
x0[:, 2][j:j + nlon[i]] = sinlat
latitude[j:j + nlon[i]] = xlat[i]
longitude[j:j + nlon[i]] = xlon
sa[j:j + nlon[i]] = 2. * np.pi * (np.cos(slt[i]) - np.cos(slt[i + 1])) / nlon[i]
ireg[:, 2][j:j + nlon[i]] = np.roll(j + np.arange(nlon[i], dtype=int), -1)
ireg[:, 3][j:j + nlon[i]] = np.roll(j + np.arange(nlon[i], dtype=int), 1)
if (i > 0):
il_lo = j - nlon[i - 1] + np.arange(nlon[i - 1], dtype=int)
else:
il_lo = j + nlon[i] + np.arange(nlon[i + 1], dtype=int)
if (i < nlat - 1):
il_up = j + nlon[i] + np.arange(nlon[i + 1], dtype=int)
else:
il_up = il_lo
for k in range(j, j + nlon[i]):
dlat_lo = longitude[k] - longitude[il_lo]
ll = np.argmin(abs(dlat_lo))
ireg[k][0] = il_lo[ll]
dlat_up = longitude[k] - longitude[il_up]
ll = np.argmin(abs(dlat_up))
ireg[k][1] = il_up[ll]
j += nlon[i]
theta = np.arccos(x0[:, 2])
phi = np.arctan2(x0[:, 0], -x0[:, 1])
ii = np.argwhere(phi < 0).T[0]
nii = len(ii)
phi[ii] = 2.0 * np.pi - abs(phi[ii]) if nii else None
grid = {'ntot': ntot, 'nlat': nlat, 'nlon': nlon, 'xyz': x0, 'lat': latitude,
'lon': longitude, 'area': sa, 'ireg': ireg, 'phi': phi, 'theta': theta}
return grid
def DI_Map(grid, spots):
map = np.ones(grid['ntot'], dtype=float)
for i in range(spots['n']):
dlon = grid['lon'] - np.deg2rad(spots['tbl'][i, 0])
dlat = grid['lat'] - np.deg2rad(spots['tbl'][i, 1])
da = (2.0 * np.arcsin(np.sqrt(np.sin(0.5 * dlat) ** 2 +
np.cos(np.deg2rad(spots['tbl'][i, 1])) *
np.cos(grid['lat']) * np.sin(0.5 * dlon) ** 2)))
ii = np.argwhere(da <= np.deg2rad(spots['tbl'][i, 2])).T[0]
ni = len(ii)
map[ii] = spots['tbl'][i, 3] if ni > 0 else None
return map
def DI_Prf(grid, star, map, phase=None, vv=None, vr=None, nonoise=None):
# velocity array
if vv is not None:
nv = len(vv)
else:
nv = int(np.ceil(2.0 * star['vrange'] / star['vstep']))
vv = -star['vrange'] + np.arange(nv, dtype=float) * star['vstep']
# phase array
if phase is None:
phase = np.arange(star['nphases'], dtype=float) / star['nphases']
# velocity correction for each phase
vr = np.zeros(star['nphases'], dtype=float) if vr == None else None
# fixed trigonometric quantities
cosi = np.cos(np.deg2rad(star['incl'])); sini = np.sin(np.deg2rad(star['incl']))
coslat = np.cos(grid['lat']); sinlat = np.sin(grid['lat'])
# FWHM to Gaussian sigma
sigm = star['fwhm'] / np.sqrt(8.0 * np.log(2.0))
isig = (-0.5 / sigm ** 2)
# initialize line profile and integrated field arrays
prf = np.zeros((nv, len(phase)), dtype=float)
# gradient if called with 5 - variable input
grad = np.zeros((nv, len(phase), grid['ntot']), dtype=float)
# phase loop
for i in range(len(phase)):
coslon = np.cos(grid['lon'] + 2.0 * np.pi * phase[i])
sinlon = np.sin(grid['lon'] + 2.0 * np.pi * phase[i])
mu = sinlat * cosi + coslat * sini * coslon
ivis = np.argwhere(mu > 0.).T[0]
dv = -sinlon[ivis] * coslat[ivis] * star['vsini']
avis = grid['area'][ivis] * mu[ivis] * (1.0 - star['limbd'] + star['limbd'] * mu[ivis])
if star['type'] == 0:
wgt = avis * map[ivis]
wgtn = sum(wgt)
for j in range(nv):
plc = 1.0 - star['d'] * np.exp(isig * (vv[j] + dv - vr[i]) ** 2)
prf[j][i] = sum(wgt * plc) / wgtn
grad[j][i][ivis] = avis * plc / wgtn - avis * prf[j][i] / wgtn
elif star['type'] == 1:
wgt = avis
wgtn = sum(wgt)
for j in range(nv):
plc = 1.0 - map[ivis] * star['d'] * np.exp(isig * (vv[j] + dv - vr[i]) ** 2)
prf[j][i] = sum(wgt * plc) / wgtn
grad[j][i][ivis] = -wgt / wgtn * star['d'] * np.exp(isig * (vv[j] + dv - vr[i]) ** 2)
# output structure
syn = {'v': vv, 'phase': phase, 'prf': prf}
# add noise
if star['snr'] != -1 and nonoise != None:
obs = syn['prf'] * 0.0
for i in range(star['nphases']):
obs[:, i] = syn['prf'][:, i] + np.random.standard_normal((len(syn['v']),)) / star['snr']
syn['obs'] = obs
return syn, grad
def DI_func(cmap, functargs):
# global syc
star = functargs['star']
grid = functargs['grid']
obs = functargs['obs']
invp = functargs['invp']
nv = len(obs['v'])
er = 1.0 / abs(star['snr'])
if 'vr' in obs.keys():
syn, grad = DI_Prf(grid, star, cmap, phase=obs['phase'], vv=obs['v'], vr=obs['vr'])
else:
syn, grad = DI_Prf(grid, star, cmap, phase=obs['phase'], vv=obs['v'])
# shf = 0
# for i in range(len(obs['phase'])):
# plt.plot(obs['v'], obs['obs'][:, i] + shf, 'bo')
# plt.plot(obs['v'], syn['prf'][:, i] + shf, 'r')
# plt.plot(obs['v'], obs['obs'][:, i] - syn['prf'][:, i] + shf, 'k')
# shf += 0.1
# plt.show()
fchi = 0.0
sign = (-1) ** invp['regtype']
for i in range(star['nphases']):
fchi = fchi + sign * sum((syn['prf'][:, i] - obs['obs'][:, i]) ** 2 / er ** 2) / nv
freg = 0
if invp['lambda'] > 0:
if invp['regtype'] == 0:
ir = grid['ireg']
for k in range(len(ir[0, :])):
freg = freg + invp['lambda'] / grid['ntot'] * sum((cmap - cmap[ir[:, k]]) ** 2)
elif invp['regtype'] == 1:
mmap = sum(cmap) / grid['ntot']
nmap = cmap / mmap
freg = freg - invp['lambda'] / grid['ntot'] * sum(nmap * np.log(nmap))
ftot = fchi + freg
syn['obs'] = obs['obs']
# syc += 1
# if syc % 1000 == 0:
# plotting(grid, cmap, syn, star['incl'], typ=star['type'])
#
# print(syc, ftot, sum(cmap))
return ftot
def plotting(grid, map, syn, incl, typ):
nlon = grid['nlon']
nln = max(nlon)
nlt = len(nlon)
ll = np.zeros(nlt + 1, dtype=int)
ll[0] = 0
for i in range(nlt):
ll[i + 1] = ll[i] + nlon[i]
map1 = np.zeros((nlt, nln), dtype=float)
x = np.arange(nln, dtype=float) + 0.5
for i in range(nlt):
lll = ((np.arange(nlon[i] + 2, dtype=float) - 0.5) * nln) / nlon[i]
y = np.hstack((map[ll[i + 1] - 1], map[ll[i]:ll[i+1]-1], map[ll[i]]))
for j in range(nln):
imin = np.argmin(abs(x[j] - lll))
map1[i, j] = y[imin]
light = (190 * (map1 - np.min(map1)) / (np.max(map1) - np.min(map1))) + 50
light_rect = np.flipud(light)
if typ == 0:
cmap = 'gray'
else:
cmap = 'gray_r'
fig = plt.figure()
fig.clear()
spec = gridspec.GridSpec(ncols=3, nrows=3, left=0.10, right=0.98,
top=0.97, bottom=0.07, hspace=0.2, wspace=0.36)
# naive IDW-like interpolation on regular grid
shape = light.shape
nrows, ncols = (shape[0], shape[1])
lon, lat = np.meshgrid(np.linspace(0, 360, ncols), np.linspace(-90, 90, nrows))
for i, item in enumerate([[(0, 0), -0], [(0, 1), -90], [(1, 0,), -180], [(1, 1), -270]]):
ax = fig.add_subplot(spec[item[0]])
# set up map projection
m = Basemap(projection='ortho', lat_0=90 - incl, lon_0=item[1], ax=ax)
# draw lat/lon grid lines every 30 degrees.
m.drawmeridians(np.arange(0, 360, 30))
m.drawparallels(np.arange(-90, 90, 30))
# compute native map projection coordinates of lat/lon grid.
x, y = m(lon, lat)
# contour data over the map.
m.contourf(x, y, light, 15, vmin=0., vmax=255., cmap=cmap)
if i in [0, 2]:
x2, y2 = m(180 - item[1], incl)
else:
x2, y2 = m(180 + item[1], incl)
x1, y1 = (-10, 5)
ax.annotate(str('%0.2f' % (abs(item[1]) / 360.)), xy=(x2, y2), xycoords='data',
xytext=(x1, y1), textcoords='offset points',
color='r')
ax5 = fig.add_subplot(spec[-1, :2])
ax5.imshow(light_rect, vmin=0., vmax=255., cmap=cmap, interpolation='none', extent=[0, 360, -90, 90])
ax5.set_xticks(np.arange(0, 420, 60))
ax5.set_yticks(np.arange(-90, 120, 30))
ax5.set_xlabel('Longitude ($^\circ$)', fontsize=7)
ax5.set_ylabel('Latitude ($^\circ$)', fontsize=7)
ax5.tick_params(labelsize=7)
ax6 = fig.add_subplot(spec[0:, 2])
shf = 0.0
for i in range(len(syn['phase'])):
ax6.plot(syn['v'], syn['obs'][:, -i - 1] + shf, 'bo', ms=2)
ax6.plot(syn['v'], syn['prf'][:, -i - 1] + shf, 'r', linewidth=1)
ax6.text(min(syn['v']), max(syn['obs'][:, -i - 1] + shf), str('%0.2f' % syn['phase'][-i - 1]),
fontsize=7)
shf += 0.1
p1 = ax6.lines[0]
p2 = ax6.lines[-1]
p1datay = p1.get_ydata()
p1datax = p1.get_xdata()
p2datay = p2.get_ydata()
y1, y2 = min(p1datay) - min(p1datay) / 20.,max(p2datay) + min(p1datay) / 10.
ax6.set_ylim([y1, y2])
ax6.set_xlabel('V ($km s^{-1}$)', fontsize=7)
ax6.set_ylabel('I / Ic', fontsize=7)
ax6.tick_params(labelsize=7)
max_ = int(max(p1datax))
ax6.set_xticks([-max_, np.floor(-max_ / 2.), 0.0, np.ceil(max_ / 2.), max_])
plt.show()
if __name__ == "__main__":
# Star parameters
star = {'ntot': 1876, 'type': 0, 'incl': 70, 'vsini': 50, 'fwhm': 7.0, 'd': 0.6,
'limbd': 0.5, 'nphases': 5, 'vrange': np.sqrt(50 ** 2 + 7.0 ** 2) * 1.4,
'vstep': 1.0, 'snr': 500}
# Spot parameters
lon_spot = [40, 130, 220, 310]
lat_spot = [-30, 0, 60, 30]
r_spot = [20, 20, 20, 20]
c_spot = [0.1, 0.2, 0.25, 0.3]
tbl = np.array([lon_spot, lat_spot, r_spot, c_spot]).T
spots = {'n': len(lon_spot), 'type': star['type'], 'tbl': tbl}
# Generate grid
grid = DI_GridInit(star['ntot'])
# Generate map
cmap = DI_Map(grid, spots)
# Generate spectral line profiles
csyn, grad = DI_Prf(grid, star, cmap, nonoise=True)
# Plotting map and line profiles
plotting(grid, cmap, csyn, star['incl'], star['type'])
# Generate map over the line profiles using scipy.optimize.minimize
invp = {'lambda': 20, 'regtype': 0, 'maxiter': 10}
grid_inv = DI_GridInit(star['ntot'])
functargs = {'star': star, 'grid': grid_inv, 'obs': csyn, 'invp': invp}
cmap = np.ones(star['ntot'])
cmap[0] = 0.99
bnd = list(zip(np.zeros(len(cmap), dtype=float), np.ones(len(cmap), dtype=float)))
minimize(DI_func, cmap, args=functargs, method='TNC', bounds=bnd,
callback=None, options={'eps': 0.1, 'maxiter': 5, 'disp': True})
The code includes followed parts.
'DI_GridInit' : Generates grids for the map
'DI_Map' : Generates star surface map according to starspot parameters (such as longitude, latitude, radius and contrast)
'DI_Prf' : Generates spectral line profiles according to map
Now I want to obtain the surface map over the generated and noised line profiles. I use scipy.optimize.minimize (TNC method) for obtain the surface map. I use 'DI_func' as function in minimize. But 'minimize' is so slow. What is the problem. How can I speed this up.
Here is a modified version of DI_Prf, where is the major computation time during the execution of DI_func:
def DI_Prf(grid, star, map, phase=None, vv=None, vr=None, nonoise=None):
# velocity array
if vv is not None:
nv = len(vv)
else:
nv = int(np.ceil(2.0 * star['vrange'] / star['vstep']))
vv = -star['vrange'] + np.arange(nv, dtype=float) * star['vstep']
# phase array
if phase is None:
phase = np.arange(star['nphases'], dtype=float) / star['nphases']
# velocity correction for each phase
vr = np.zeros(star['nphases'], dtype=float) if vr == None else None
# fixed trigonometric quantities
cosi = np.cos(np.deg2rad(star['incl'])); sini = np.sin(np.deg2rad(star['incl']))
coslat = np.cos(grid['lat']); sinlat = np.sin(grid['lat'])
# FWHM to Gaussian sigma
sigm = star['fwhm'] / np.sqrt(8.0 * np.log(2.0))
isig = (-0.5 / sigm ** 2)
# initialize line profile and integrated field arrays
prf = np.zeros((nv, len(phase)), dtype=float)
# gradient if called with 5 - variable input
grad = np.zeros((nv, len(phase), grid['ntot']), dtype=float)
# phase loop
for i in range(len(phase)):
coslon = np.cos(grid['lon'] + 2.0 * np.pi * phase[i])
sinlon = np.sin(grid['lon'] + 2.0 * np.pi * phase[i])
mu = sinlat * cosi + coslat * sini * coslon
ivis = np.argwhere(mu > 0.).T[0]
dv = -sinlon[ivis] * coslat[ivis] * star['vsini']
avis = grid['area'][ivis] * mu[ivis] * (1.0 - star['limbd'] + star['limbd'] * mu[ivis])
if star['type'] == 0:
wgt = avis * map[ivis]
wgtn = sum(wgt)
#for j in range(nv):
# plc = 1.0 - star['d'] * np.exp(isig * (vv[j] + dv - vr[i]) ** 2)
# prf[j][i] = sum(wgt * plc) / wgtn
# grad[j][i][ivis] = avis * plc / wgtn - avis * prf[j][i] / wgtn
plc = 1.0 - star['d'] * np.exp(isig * (vv[:, np.newaxis] + dv[np.newaxis, :] - vr[i]) ** 2)
prf[:, i] = np.sum(wgt * plc, axis=1) / wgtn
grad[:, i, ivis] = avis * plc / wgtn - (avis[:, np.newaxis]*prf[:, i]).T / wgtn
elif star['type'] == 1:
wgt = avis
wgtn = sum(wgt)
for j in range(nv): # to be modified too
plc = 1.0 - map[ivis] * star['d'] * np.exp(isig * (vv[j] + dv - vr[i]) ** 2)
prf[j][i] = sum(wgt * plc) / wgtn
grad[j][i][ivis] = -wgt / wgtn * star['d'] * np.exp(isig * (vv[j] + dv - vr[i]) ** 2)
# output structure
syn = {'v': vv, 'phase': phase, 'prf': prf}
# add noise
if star['snr'] != -1 and nonoise != None:
#for i in range(star['nphases']):
obs = syn['prf'] + np.random.standard_normal(size=syn['prf'].shape) / star['snr']
syn['obs'] = obs
return syn, grad
It reduces the time by 3:
%%timeit
syn, grad = DI_Prf(grid, star, cmap, phase=obs['phase'], vv=obs['v'])
# 127 ms ± 2.61 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
# 40.7 ms ± 683 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
The main idea with Numpy is to not use loops, but work with multidimensional array, and use the broadcasting capabilities.
For instance:
fchi = 0.0
for i in range(star['nphases']):
fchi = fchi + sign * sum((syn['prf'][:, i] - obs['obs'][:, i]) ** 2 / er ** 2) / nv
could be replaced with:
fchi = sign / nv / er ** 2 * np.sum( np.sum((syn['prf'] - obs['obs']) ** 2, axis=1 ) )
same for np.random.standard_normal(size=syn['prf'].shape)
It's not a big improvement here because star['nphases'] is small, but it is relatively important for the other axis. You could go further and remove the for loop over the phases in DI_Prf but it requires some thinking
I've set up numpy.seterr as follows:
np.seterr(invalid='raise', over ='raise', under='raise')
And I'm getting the following error:
c = beta[j,i] + oneminusbeta[j,i]
FloatingPointError: overflow encountered in double_scalars
I've checked what beta[j,i] and oneminusbeta[j,i] are at the point of crash, and these are their values:
beta: -131.340389182
oneminusbeta: 0.0
Please note, this line of addition (beta[j,i] + oneminusbeta[j,i]) has run for thousands of lines in a loop (that performs image classification) before crashing here at this point.
How can I deal with this? Is it necessary to change the type of the numpy arrays?
This is how I've initialized them:
beta = np.empty([m,n])
oneminusbeta = np.empty([m,n])
Is it possible to cast the individual values before adding them up? Rather than changing the entire array declarations? Or is this even a serious issue? Would it be safe to simply turn off the numpy.seterr configuration and let the calculations go ahead without raising the error?
Edit
Someone suggested below, and I suspected as well, that the values being added shouldn't cause an overflow. Then how can I find out where the overflow is really happening?
This is my code:
epthreshold = 709
enthreshold = -708
f.write("weights["+str(i)+", " + str(j)+"] = math.exp(beta: " +str(beta[j,i])+ " + oneminusbeta: " + str(oneminusbeta[j,i])+")\n" )
c = beta[j,i] + oneminusbeta[j,i]
weights[i,j] = math.exp(np.clip(c, enthreshold, epthreshold))
And when I check my log file, this is the line I get:
weights[5550, 13] = math.exp(beta: -131.340389182 + oneminusbeta: 0.0)
Edit 2
Here's the rest of my code, where variables n,m and H have already been initialized to integer values:
import numba
import numpy as np
import statsmodels.api as sm
weights = np.empty([n,m])
for curr_n in range(n):
for curr_m in range(m):
weights[curr_n,curr_m] = 1.0/(n)
beta = np.empty([m,n])
oneminusbeta = np.empty([m,n])
for curr_class in range(m):
for curr_sample in range(n):
beta[curr_class,curr_sample] = 1./m
epthreshold = 709 # positive exponential threshold
enthreshold = -708
for h in range(H):
print "Boosting round %d ... " % h
z = np.empty([n,m])
for j in range(m): # computing working responses and weights, Step 2(a)(i)
for i in range(no_samples):
i_class = y[i] #get the correct class for the current sample
if h == 0:
z[i,j] = (int(j==i_class) - beta[j,i])/((beta[j,i])*(1. - beta[j,i]))
weights[i,j] = beta[j,i]*(1. - beta[j,i])
else:
if j == i_class:
z[i,j] = math.exp(np.clip(-beta[j,i],enthreshold, epthreshold))
else:
z[i,j] = -math.exp(np.clip(oneminusbeta[j,i], enthreshold, epthreshold))
f.write("weights["+str(i)+", " + str(j)+"] = math.exp(beta: " +str(beta[j,i])+ " + oneminusbeta: " + str(oneminusbeta[j,i])+")\n" )
c = beta[j,i] + oneminusbeta[j,i]
weights[i,j] = math.exp(np.clip(c, enthreshold, epthreshold))
g_h = np.zeros([1,1])
j = 0
# Calculating regression coefficients per class
# building the parameters per j class
for y1_w in zip(z.T, weights.T):
y1, w = y1_w
temp_g = sm.WLS(y1, X, w).fit() # Step 2(a)(ii)
if np.allclose(g_h,0):
g_h = temp_g.params
else:
g_h = np.c_[g_h, temp_g.params]
j = j + 1
if np.allclose(g,0):
g = g_h
else:
g = g + g_h # Step(2)(a)(iii)
# now set g(x), function coefficients according to new formula, step (2)(b)
sum_g = g.sum(axis=1)
for j in range(m):
diff = (g[:,j] - ((1./m) * sum_g))
g[:,j] = ((m-1.)/m) * diff
g_per_round[h,:,j] = g[:,j]
#Now computing beta, Step 2(c)...."
Q = 0.
e = 0.
for j in range(m):
# Calculating beta and oneminusbeta for class j
aj = 0.0
for i in range(no_samples):
i_class = y[i]
X1 = X[i].reshape(1, no_features)
g1 = g[:,j].reshape(no_features, 1)
gc = g[:,i_class].reshape(no_features, 1)
dot = 1. + float(np.dot(X1, g1)) - float(np.dot(X1,gc))
aj = dot
sum_e = 0.
a_q = []
a_q.append(0.)
for j2 in range(m): # calculating sum of e's except for all j except where j=i_class
if j2 != i_class: # g based on j2, not necessarily g1?
g2 = g[:,j2].reshape(no_features, 1)
dot1 = 1. + float(np.dot(X1, g2)) - float(np.dot(X1,gc))
e2 = math.exp(np.clip(dot1,enthreshold, epthreshold))
sum_e = sum_e + e2
a_q.append(dot1)
if (int(j==i_class) == 1):
a_q_arr = np.array(a_q)
alpha = np.array(a_q_arr[1:])
Q = mylogsumexp(f,a_q_arr, 1, 0)
sumalpha = mylogsumexp(f,alpha, 1, 0)
beta[j,i] = -Q
oneminusbeta[j,i] = sumalpha - Q
else:
alpha = a_q
alpha = np.array(alpha[1:])
a_q_arr = np.array(a_q)
Q = mylogsumexp(f,a_q_arr, 0, aj)
sumalpha = log(math.exp(np.clip(Q, enthreshold, epthreshold)) - math.exp(np.clip(aj, enthreshold, epthreshold)))
beta[j,i] = aj - Q
oneminusbeta[j,i] = sumalpha - Q
and the function mylogsumexp is:
def mylogsumexp(f, a, is_class, maxaj, axis=None, b=None):
np.seterr(over="raise", under="raise", invalid="raise")
threshold = -sys.float_info.max
maxthreshold = sys.float_info.max
epthreshold = 709 # positive exponential threshold
enthreshold = -708
a = asarray(a)
if axis is None:
a = a.ravel()
else:
a = rollaxis(a, axis)
if is_class == 1:
a_max = a.max(axis=0)
else:
a_max = maxaj
#bnone = " none "
if b is not None:
a_max = maxaj
b = asarray(b)
if axis is None:
b = b.ravel()
else:
b = rollaxis(b, axis)
a = np.clip(a - a_max, enthreshold, epthreshold)
midout = np.sum(np.exp(a), axis=0)
midout = 1.0 + np.clip(midout - math.exp(a_max), threshold, maxthreshold)
out = np.log(midout)
else:
a = np.clip(a - a_max, enthreshold, epthreshold)
out = np.log(np.sum(np.exp(a)))
out += a_max
if out == float("inf"):
out = maxthreshold
if out == float("-inf"):
out = threshold
return out