ZeroDivisionError: float division by zero - python-2.7

I don't know what's going on, it worked before.
It had never happened to me.
someone help, i'm lost.
error line:
result = p0 + (EMA - d0) / (d1 - d0) * (p1 - p0) if p0 != 100.0 or p1 != 100.0 else 100.0
i try this:
if p0 != 100.0 or p1 != 100.0:
result = p0 + (EMA - d0) / (d1 - d0) * (p1 - p0)
else:
result = 100.0
code:
def requestCurData(self, damageRating, movingAvgDamage):
self.values = config.values[self.check_player_thread()][self.name]
if len(self.values) == 4:
tm = datetime.datetime.toordinal(datetime.datetime.utcnow()) - 1
self.values.extend([tm, tm])
config.values[self.check_player_thread()][self.name] = self.values
if movingAvgDamage not in self.values or datetime.datetime.toordinal(datetime.datetime.utcnow()) >= self.values[5] + 1:
p0 = self.values[2]
d0 = self.values[3]
t0 = self.values[5]
p1 = damageRating
d1 = movingAvgDamage
t1 = datetime.datetime.toordinal(datetime.datetime.utcnow())
self.values = [p0, d0, p1, d1, t0, t1]
config.values[self.check_player_thread()][self.name] = self.values
if self.values[0] == self.values[2] and self.values[1] == self.values[3]:
self.values[3] += 10
self.values[5] = datetime.datetime.toordinal(datetime.datetime.utcnow())
config.values[self.check_player_thread()][self.name] = self.values
EDn = self.battleDamage + max(self.RADIO_ASSIST, self.TRACK_ASSIST, self.STUN_ASSIST)
k = 0.0198019801980198022206547392443098942749202251434326171875 # 2 / (100.0 + 1)
EMA = k * EDn + (1 - k) * self.movingAvgDamage
p0, d0, p1, d1, t0, t1 = self.values
result = p0 + (EMA - d0) / (d1 - d0) * (p1 - p0) if p0 != 100.0 or p1 != 100.0 else 100.0
nextMark = round(min(100.0, result), 2) if result > 0 else 0.0
self.initiated = self.values[1] and not nextMark >= self.damageRating and not self.damageRating - nextMark > 3

The error message is not clear, but I suppose you might be trying to divide a float by an integer, and Python doesn't like that. Try:
result = p0 + (EMA - d0) / float( (d1 - d0) * (p1 - p0) ) if p0 != 100.0 or p1 != 100.0 else 100.0
If this didn't work, then may be you are trying to divide by zero, which is not possible, so wrap the calculation inside a try-catch block:
try:
result = p0 + (EMA - d0) / (d1 - d0) * (p1 - p0) if p0 != 100.0 or p1 != 100.0 else 100.0
except ZeroDivisionError:
result = "some default value"

Related

Can this Iron Python 2.7 code be sped up?

I have implemented Gray-Scott reaction diffusion in Iron Python 2, mapping grayscale values between 0 and 1.
But since it only gets interesting from about 6400 steps, it takes a lot of time.
So can someone smarter / more proficient in Python than me help me make this code more efficient?
Here is the code:
import random as rnd
dA = 1
dB = 0.5
feed = 0.055
kill = 0.062
wHalb = int(width/2)
hHalb = int(height/2)
#decides if gAA is random or 1
if gAA == 0:
gAA = rnd.random()
def main():
#create base grid of chemical A and B
gridA = [ [gAA for i in range(width)] for i in range(height)]
gridB = [ [0 for i in range(width)] for i in range(height)]
nextA = [ [1 for i in range(width)] for i in range(height)]
nextB = [ [0 for i in range(width)] for i in range(height)]
color = [ [0 for i in range(width)] for i in range(height)]
for x in range (wHalb-baseBlock,wHalb+baseBlock):
for y in range (hHalb-baseBlock,hHalb+baseBlock):
gridB[x][y] = 1
x, y, i, j = 0, 0, 0, 0
for n in range(steps):
for x in range (width):
for y in range (height):
a = gridA[x][y]
b = gridB[x][y]
nextA[x][y] = (a + (dA * laplaceA(x, y, gridA)) - (a * b*b) + (feed * (1 - a)))
nextB[x][y] = (b + (dB * laplaceB(x, y, gridB)) + (a * b*b) - ((kill + feed) * b))
tempA = gridA
gridA = nextA
nextA = tempA
tempB = gridB
gridB = nextB
nextB = tempB
color = [ [(nextA[i][j] - nextB[i][j]) for i in range(width)] for j in range(height)]
return color
def laplaceA(x, y, gridA):
sumA = 0;
xS = x - 1
xE = x + 1
yS = y - 1
yE = y + 1
if (x == 0):
xS = width-1
if (y == 0):
yS = height-1
if (x == width - 1):
xE = 0;
if (y == height - 1):
yE = 0;
sumA = sumA + gridA[x][y] * -1
sumA = sumA + gridA[xS][y] * 0.2
sumA = sumA + gridA[xE][y] * 0.2
sumA = sumA + gridA[x][yE] * 0.2
sumA = sumA + gridA[x][yS] * 0.2
sumA = sumA + gridA[xS][yS] * 0.05
sumA = sumA + gridA[xE][yS] * 0.05
sumA = sumA + gridA[xS][yE] * 0.05
sumA = sumA + gridA[xE][yE] * 0.05
return sumA
def laplaceB(x, y, gridB):
sumB = 0
xS = x - 1
xE = x + 1
yS = y - 1
yE = y + 1
if (x == 0):
xS = width-1
if (y == 0):
yS = height-1
if (x == width - 1):
xE = 0
if (y == height - 1):
yE = 0
sumB = sumB + gridB[x][y] * -1
sumB = sumB + gridB[xS][y] * 0.2
sumB = sumB + gridB[xE][y] * 0.2
sumB = sumB + gridB[x][yE] * 0.2
sumB = sumB + gridB[x][yS] * 0.2
sumB = sumB + gridB[xS][yS] * 0.05
sumB = sumB + gridB[xE][yS] * 0.05
sumB = sumB + gridB[xS][yE] * 0.05
sumB = sumB + gridB[xE][yE] * 0.05
return sumB
aOut = main()

Why can't the subs function of the sympy replace the value of the symbol sometimes?

I have the following code:
u_ini = 0.1
v_ini = 0.1
z_ini = 0.1 # 初始化三个拉格朗日乘子
q = 0
lis = list(range(2))
u = list(sp.symbols('u:{}'.format(len(lis))))
v = list(sp.symbols('v:{}'.format(len(lis))))
z = sp.symbols('z')
p = list(sp.symbols('p:{}'.format(len(lis))))
lag1 = 0
lag2 = 0
lag3 = 0
p_symbol_sum = np.sum(p)
for i in range(k):
if i < k-1:
lag1 += B*ts_ratio[i]*sp.log(1+g[i]*p[i]/(sgm_2+g[i]*np.sum(p[i+1:k])),2)-q*(af_eff*p[i]+Pc-eh_eff*(1-ts_ratio[i])*g[i]*p_symbol_sum)
lag2 -= u[i] * (R_min - ts_ratio[i] * B * sp.log(1 + g[i] * p[i] / (sgm_2 + g[i] * np.sum(p[i + 1:k])),2))
elif i == k-1:
lag1 += B*ts_ratio[i]*sp.log(1+g[i]*p[i]/(sgm_2+g[i]*p[i]),2)-q*(af_eff*p[i]+Pc-eh_eff*(1-ts_ratio[i])*g[i]*p_symbol_sum)
lag2 -= u[i] * (R_min - ts_ratio[i] * B * sp.log(1+g[i]*p[i]/(sgm_2+g[i]*p[i]),2))
lag3 -= v[i] * (E_min - (1 - ts_ratio[i])*eh_eff*g[i]*p_symbol_sum) + z * (p[i] - p_max)
lag_fun = lag1 + lag2 + lag3
print("lag_fun:",lag_fun)
for i in range(k):
lag_fun.subs([(u[i],u_ini), (v[i],v_ini), (z,z_ini), (p[i],p_ini)]).evalf()
print("lag_fun:",lag_fun)
Why does the value of the expression not change after I count down the subs of the second line。
This is the output of the program. The first line is the output before using subs. The second is the output after using subs. Why hasn't it changed?
lag_fun: -u0*(-0.5*log(0.0410609879149758*p0/(0.0410609879149758*p1 + 0.001) + 1)/log(2) + 2) - u1*(-0.5*log(0.0123909311217172*p1/(0.0123909311217172*p1 + 0.001) + 1)/log(2) + 2) - v0*(-0.00205304939574879*p0 - 0.00205304939574879*p1 + 0.2) - v1*(-0.000619546556085859*p0 - 0.000619546556085859*p1 + 0.2) - z*(p0 - 20) - z*(p1 - 20) + 0.5*log(0.0410609879149758*p0/(0.0410609879149758*p1 + 0.001) + 1)/log(2) + 0.5*log(0.0123909311217172*p1/(0.0123909311217172*p1 + 0.001) + 1)/log(2)
lag_fun: -u0*(-0.5*log(0.0410609879149758*p0/(0.0410609879149758*p1 + 0.001) + 1)/log(2) + 2) - u1*(-0.5*log(0.0123909311217172*p1/(0.0123909311217172*p1 + 0.001) + 1)/log(2) + 2) - v0*(-0.00205304939574879*p0 - 0.00205304939574879*p1 + 0.2) - v1*(-0.000619546556085859*p0 - 0.000619546556085859*p1 + 0.2) - z*(p0 - 20) - z*(p1 - 20) + 0.5*log(0.0410609879149758*p0/(0.0410609879149758*p1 + 0.001) + 1)/log(2) + 0.5*log(0.0123909311217172*p1/(0.0123909311217172*p1 + 0.001) + 1)/log(2)
subs doesn't change anything in place, you have to capture the result for the same reason that this loop fails to change x:
>>> x = 0
>>> for i in range(10): x + 1
>>> x
0
So it must be
lag_fun = lag_fun.subs(etc...)

How do I get correct answers using my code with the barycentric formula?

My function getHeightOfTerrain() is calling a barycentric formula function that is not returning the correct height for the one set test height in : heightMapFromArray[][].
I've tried watching OpenGL JAVA Game tutorials 14,21, 22, by "thin matrix" and I am confused on how to use my array: heightMapforBaryCentric in both of the supplied functions, and how to set the arguments that are passed to the baryCentic() function in some sort of manner so that I can solve the problem.
int creaateTerrain(int height, int width)
{
float holderY[6] = { 0.f ,0.f,0.f,0.f,0.f,0.f };
float scaleit = 1.5f;
float holder[6] = { 0.f,0.f,0.f,0.f,0.f,0.f };
for (int z = 0, z2 =0; z < iterationofHeightMap;z2++)
{
//each loop is two iterations and creates one quad (two triangles)
//however because each iteration is by two (i.e. : x=x+2) om bottom
//the amount of triangles is half the x value
//
//number of vertices : 80 x 80 x 6.
//column
for (int x = 0, x2 = 0; x < iterationofHeightMap;x2++)
{
//relevant - A : first triangle - on left triangle
//[row] [colum[]
holder[0] = heightMapFromArray[z][x];
//holder[0] = (float)imageData[(z / 2 * MAP_Z + (x / 2)) * 3];
//holder[0] = holder[0] / 255;// *scaleit;
vertices.push_back(glm::vec3(x, holder[0], z));
//match height map with online barycentric use
heightMapforBaryCentric[x2][z2] = holder[0];
holder[1] = heightMapFromArray[z+2][x];
//holder[1] = (float)imageData[(((z + 2) / 2 * MAP_Z + ((x) / 2))) * 3];
//holder[1] = holder[1] / 255;// 6 * scaleit;
vertices.push_back(glm::vec3(x, holder[1], z + 2));
//match height map with online barycentric use
heightMapforBaryCentric[x2][z2+1] = holder[1];
holder[2] = heightMapFromArray[z+2][x+2];
//holder[2] = (float)imageData[(((z + 2) / 2 * MAP_Z + ((x + 2) / 2))) * 3];
//holder[2] = holder[2] / 255;// *scaleit;
vertices.push_back(glm::vec3(x + 2, holder[2], z + 2));
////match height map with online barycentric use
heightMapforBaryCentric[x2+1][z2+1] = holder[2];
//relevant - B - second triangle (on right side)
holder[3] = heightMapFromArray[z][x];
//holder[3] = (float)imageData[((z / 2)*MAP_Z + (x / 2)) * 3];
//holder[3] = holder[3] / 255;// 256 * scaleit;
vertices.push_back(glm::vec3(x, holder[3], z));
holder[4] = heightMapFromArray[x+2][z+2];
//holder[4] = (float)imageData[(((z + 2) / 2 * MAP_Z + ((x + 2) / 2))) * 3];
//holder[4] = holder[4] / 255;// *scaleit;
vertices.push_back(glm::vec3(x + 2, holder[4], z + 2));
holder[5] = heightMapFromArray[x+2][z];
//holder[5] = (float)imageData[((z / 2)*MAP_Z + ((x + 2) / 2)) * 3];
//holder[5] = holder[5] / 255;// *scaleit;
vertices.push_back(glm::vec3(x + 2, holder[5], z));
x = x + 2;
}
z = z + 2;
}
return(1);
}
float getHeightOfTerrain(float worldX, float worldZ) {
float terrainX = worldX;
float terrainZ = worldZ;
int gridSquareSize = 2.0f;
gridX = (int)floor(terrainX / gridSquareSize);
gridZ = (int)floor(terrainZ / gridSquareSize);
xCoord = ((float)(fmod(terrainX, gridSquareSize)) / (float)gridSquareSize);
zCoord = ((float)(fmod(terrainZ, gridSquareSize)) / (float)gridSquareSize);
if (xCoord <= (1 - zCoord))
{
answer = baryCentric(
//left triangle
glm::vec3(0.0f, heightMapforBaryCentric[gridX][gridZ], 0.0f),
glm::vec3(0.0f, heightMapforBaryCentric[gridX][gridZ+1], 1.0f),
glm::vec3(1.0f, heightMapforBaryCentric[gridX+1][gridZ+1], 1.0f),
glm::vec2(xCoord, zCoord));
// if (answer != 1)
// {
// fprintf(stderr, "Z:gridx: %d gridz: %d answer: %f\n", gridX, gridZ,answer);
//
// }
}
else
{
//right triangle
answer = baryCentric(glm::vec3(0, heightMapforBaryCentric[gridX][gridZ], 0),
glm::vec3(1,heightMapforBaryCentric[gridX+1][gridZ+1], 1),
glm::vec3(1,heightMapforBaryCentric[gridX+1][gridZ], 0),
glm::vec2(xCoord, zCoord));
}
if (answer == 1)
{
answer = 0;
}
//answer = abs(answer - 1);
return(answer);
}
float baryCentric(glm::vec3 p1, glm::vec3 p2, glm::vec3 p3 , glm::vec2 pos) {
float det = (p2.z - p3.z) * (p1.x - p3.x) + (p3.x - p2.x) * (p1.z - p3.z);
float l1 = ((p2.z - p3.z) * (pos.x - p3.x) + (p3.x - p2.x) * (pos.y - p3.z)) / det;
float l2 = ((p3.z - p1.z) * (pos.x - p3.x) + (p1.x - p3.x) * (pos.y - p3.z)) / det;
float l3 = 1.0f - l1 - l2;
return (l1 * p1.y + l2 * p2.y + l3 * p3.y);
}
My expected results were that the center of the test grid's height to be the set value .5 and gradually less as the heights declined. My results were the heights being all the same, varied, or increasing. Usually these heights were under the value of one.

Sum of increasing alternate terms in python

I need to evaluate the finite sum of numbers which are increasing in absolute value, but are alternate. Problem is: the abolute values grow too fast and it starts accumulating numerical errors. These the functions definitions, one (Gj_full) straight to it and the other (Gj) recursively. fact_quo is a simple factorial function.
def fact_quo(n, m=1):
if (type(n) != int) or (type(m) != int):
raise TypeError("Arguments must be integers.")
if (n < 0) or (m < 0):
raise ValueError("n=" + str(n) + "\t m=" + str(m))
if (n == 0) or (n == 1) or (n == m):
return 1
if (n < m):
raise ValueError("n=" + str(n) + "\t m=" + str(m))
f = n
while n > (m+1):
n -= 1
f *= n
return f
def Gj_full(X, Y, Xl, Yl, j=0, coef=1):
if (X - Y + Xl + Yl) % 2 or X < Y or Y < j:
raise ValueError
u = (X - Y + Xl + Yl) // 2
v = coef * (2 ** (X - Y) * fact_quo(X, Y-j) * fact_quo(u+j, j) *
4 ** j * (-1) ** j)
w = 3 ** (u+j) * fact_quo(X-Y+j)
den2 = fact_quo(X) * fact_quo(Xl) * fact_quo(Yl)
z = (np.sqrt(fact_quo(X)) * np.sqrt(fact_quo(Y))
* np.sqrt(fact_quo(Xl)) * np.sqrt(fact_quo(Yl)))
return (v / (den2 * w)) * z
def Gj(X, Y, Xl, Yl, j=0, coef=1):
if (X - Y + Xl + Yl) % 2 or X < Y or Y < j:
raise ValueError
kX, kY, kXl, kYl, kj = X % 2, Y % 2, Xl % 2, Yl % 2, 0
g = coef * Gj_full(kX, kY, kXl, kYl, kj)
while kX < X:
u = (kX - kY + kXl + kYl) // 2
v = 4 * (u + kj + 1)
w = 3 * (kX + 2 - kY + kj) * (kX + 1 - kY + kj)
g *= (v / w) * np.sqrt(kX + 2) * np.sqrt(kX + 1)
kX += 2
while kXl < Xl:
u = (kX - kY + kXl + kYl) // 2
v = u + kj + 1
w = 3 * (kXl + 2) * (kXl + 1)
g *= (v / w) * np.sqrt(kXl + 2) * np.sqrt(kXl + 1)
kXl += 2
while kYl < Yl:
u = (kX - kY + kXl + kYl) // 2
v = u + kj + 1
w = 3 * (kYl + 2) * (kYl + 1)
g *= (v / w) * np.sqrt(kYl + 2) * np.sqrt(kYl + 1)
kYl += 2
while kY < Y:
u = (kX - kY + kXl + kYl) // 2
v = 3 * (kX - kY + kj) * (kX - kY - 1 + kj)
w = 4 * (kY + 2 - kj) * (kY + 1 - kj) * (u + kj)
g *= (v / w) * np.sqrt(kY + 2) * np.sqrt(kY + 1)
kY += 2
while kj < j:
u = (kX - kY + kXl + kYl) // 2
v = -4 * (kY - kj) * (u + kj + 1)
w = 3 * (kX - kY + kj + 1) * (kj + 1)
g *= (v / w)
kj += 1
return g
The (4/3) ** j and the factorials quicly increase the absolute value of the summing terms. The sum, however, are supposed to be smaller than 1. In fact, for X = Y and Xl = Yl = 0, the sum equals to (-1/3) ** X.
The precision for infinitely large numbers for floats are not available yet without using a lib. Therefore you should look into the decimal lib, you can even set the precision. Eg.
import decimal
decimal.getcontext().prec = 100
def pi():
pi = decimal.Decimal(0)
for k in range(350):
pi += (decimal.Decimal(4)/(decimal.Decimal(8)*decimal.Decimal(k+1))...)
If you manage to force all the numbers to be integers, you don't need to worry about it

How to Solve Rendering Artifact in Blinn/Loop's Resolution Independent Curve Rendering?

In implementing Blinn/Loop's algorithm on curve rendering, I realize there is a special case on Loop Curve Type. As described in their paper (subsection 4.4, page 6-7), they said the curve should be divided into two but I'm really confused how to obtain the intersection point.
Here's my rendering result:
As stated in the paper, this artifact occurs when either td/sd or te/se lie in between value [0, 1].
My source code:
...
case CURVE_TYPE_LOOP:
td = d2 + sqrt(4.0 * d1 * d3 - 3.0 * d2 *d2);
sd = 2.0 * d1;
te = d2 - sqrt(4.0 * d1 * d3 - 3.0 * d2 * d2);
se = 2.0 * d1;
if((td / sd > 0.0 && td/ sd < 1.0) || (te / se > 0.0 && te/ se < 1.0))
std::cout << "error\n";
// F matrix will be multiplied with inverse M3 to obtain tex coords (I use Eigen library btw...)
F << td * te, td * td * te, td * te * te, 1,
(-se * td) - (se * te), (-se * td * td) - (2.0 * sd * te * td), (-sd * te * te) - (2.0 * se * td * te), 0,
sd * se, te * sd * sd + 2.0 * se * td* sd, td * se * se + 2 * sd * te * se, 0,
0, -sd * sd * se, -sd * se * se, 0;
break;
...
Solved it,
I should get the splitting value t,
here's my code:
// get t
double splitLoop = -1.0;
switch (curve_type)
{
case CURVE_TYPE_UNKNOWN:
break;
case CURVE_TYPE_SERPENTINE:
tl = d2 + ((1.0 / sqrt(3.0)) * sqrt(3.0 * d2 * d2 - 4.0 * d1 * d3));
sl = 2.0 * d1;
tm = d2 - ((1.0 / sqrt(3.0)) * sqrt(3.0 * d2 * d2 - 4.0 * d1 * d3));
sm = 2.0 * d1;
F << tl * tm, tl * tl * tl, tm * tm * tm, 1,
-(sm * tl) -(sl * tm), -(3.0 * sl * tl * tl), -(3.0 * sm * tm * tm), 0,
sl * sm, 3.0 * sl * sl * tl, 3.0 * sm * sm * tm, 0,
0, -(sl * sl * sl), -(sm * sm * sm), 0;
break;
case CURVE_TYPE_LOOP:
td = d2 + sqrt(4.0 * d1 * d3 - 3.0 * d2 *d2);
sd = 2.0 * d1;
te = d2 - sqrt(4.0 * d1 * d3 - 3.0 * d2 * d2);
se = 2.0 * d1;
// Get splitting t
if((td / sd) > 0.0 && (td / sd) < 1.0)
{
splitLoop = td / sd;
}
else if((te / se) > 0.0 && (te/ se) < 1.0)
{
splitLoop = te / se;
}
F << td * te, td * td * te, td * te * te, 1,
(-se * td) - (se * te), (-se * td * td) - (2.0 * sd * te * td), (-sd * te * te) - (2.0 * se * td * te), 0,
sd * se, te * sd * sd + 2.0 * se * td* sd, td * se * se + 2 * sd * te * se, 0,
0, -sd * sd * se, -sd * se * se, 0;
break;
case CURVE_TYPE_QUADRATIC:
break;
case CURVE_TYPE_LINE:
break;
}
if(splitLoop > 0.0 && splitLoop < 1.0)
{
// SPLIT
double x01 = (x1 - x0) * splitLoop + x0;
double y01 = (y1 - y0) * splitLoop + y0;
double x12 = (x2 - x1) * splitLoop + x1;
double y12 = (y2 - y1) * splitLoop + y1;
double x23 = (x3 - x2) * splitLoop + x2;
double y23 = (y3 - y2) * splitLoop + y2;
double x012 = (x12 - x01) * splitLoop + x01;
double y012 = (y12 - y01) * splitLoop + y01;
double x123 = (x23 - x12) * splitLoop + x12;
double y123 = (y23 - y12) * splitLoop + y12;
double x0123 = (x123 - x012) * splitLoop + x012;
double y0123 = (y123 - y012) * splitLoop + y012;
// CURVE A (recursive)
DrawCubic(x0, y0, x01, y01, x012, y012, x0123, y0123);
// CURVE B (recursive)
DrawCubic(x0123, y0123, x123, y123, x23, y23, x3, y3);
}
else
{
// Draw as usual...
}
== EDIT ==
After i experimented again for a while, There's a numerical error on my program when the values of td/sd or te/se on subcurves lie again in between [0, 1], since my program use recursive by calling DrawCubic(), it causes recursive heap error.
In the meantime, I use 'hack' solution where I will not call DrawCurve() inside the recursive call (making sure the recursive is called only once). So far the result is quite satisfying and I don't see any artifact.
Any feedback is really welcomed since I'm not really good in numerical calculation :)