I’m trying to solve the following problem for around 2 days, but have not had success.
I want to calculate the derivative using the sparse matrix, but the result doesn’t true. I think there is a mistake in the solution function, but I cannot find it.
class Cahn_Hillard(object):
def __init__(self, n, X, T, dt, skip):
self.n = n
self.X = X
self.dx = 1 / (n - 1)
self.T = T
self.dt = dt
self.N = int(self.T / self.dt)
def __call__(self):
central = self.forward_diff_sparse()
itr = int(self.T / self.dt)
for i in range(0, itr + 1):
if i == 0:
c = np.random.uniform(0, 1, (self.n, 1))
else:
c_next = self.solution(c, central)
c = c_next
print(i)
return c
def forward_diff_sparse(self):
sparse_mat = np.eye(self.n) - np.eye(self.n, k=-1)
return sparse_mat
def solution(self, c, central):
# calculate derivative of concentration
deriv = central.dot(c) / self.dx
# calculate difusion coeffcient
D_eff = (1 - 2 * self.X * c * (1 - c)) * deriv
Diff = central.dot(D_eff) / self.dx
# Calculate the next step concentration
next_c = c + self.dt * Diff
return next_c
It would be great if you help me.
Related
I wrote classes for Ray, Line, Point, and some other shapes, but I was stopped by the need for a function that takes a Line class object and a Ray class object as a parameter, and returns the point at which the line and the ray intersect.
Point class:
class Point:
def __init__(self, x: float, y: float):
self.x = x
self.y = y
def __getitem__(self, index):
if index == 0:
return self.x
elif index == 1:
return self.y
def __iter__(self):
yield self.x
yield self.y
def __str__(self):
return f"x = {self.x}; y = {self.y}"
Ray class:
class Ray:
def __init__(self, start: Point, end: Point):
self.start = start
self.end = end
def get_direction(self):
x_diff = self.end[0] - self.start[0]
y_diff = self.end[1] - self.start[1]
return (x_diff, y_diff)
Line class:
class Line:
def __init__(self, point1: Point, point2: Point):
self.point1 = point1
self.point2 = point2
def get_direction(self) -> tuple:
x_diff = abs(self.point2[0] - self.point1[0])
y_diff = abs(self.point2[1] - self.point1[1])
return (x_diff, y_diff)
def get_params(self) -> tuple:
x1, y1 = self.point1
x2, y2 = self.point2
a = y2 - y1
b = x1 - x2
c = x2 * y1 - x1 * y2
return a, b, c
def get_normal(self):
a, b, c = self.get_params()
return -b, a, c
And perhaps the following functions can help:
Is the point on the line?
def point_on_line(point: Point, line: Line):
x1, y1 = line.point1
x2, y2 = line.point2
x, y = point
return (y - y1) * (x2 - x1) == (y2 - y1) * (x - x1)
Is the point on the ray?
def point_on_ray(point: Point, ray: Ray) -> bool:
start = ray.start
end = ray.end
direction = ray.get_direction()
x_diff = point[0] - start[0]
y_diff = point[1] - start[1]
if x_diff * direction[1] == y_diff * direction[0]:
if x_diff >= 0 and y_diff >= 0:
return True
return False
I am bad in Math so i asked ChatGPT to help me, but he wrote some functions which will return wrong result
I tried giving ChatGPT several completely different prompts, and I got several completely different functions in response, but anyway, they all didn't work. Some of them returned the wrong points, some of them thought the ray and the line were parallel, although they have not worked correctly
You have to solve equation system
ray.start.x + t * ray.diff.x = line.point1.x + u * line.diff.x
ray.start.y + t * ray.diff.y = line.point1.y + u * line.diff.y
for unknowns t and u, then check that t >= 0
Then substitute t value into the left parts to get intersection point coordinates.
Standalone Python function
def ray_line_intersection(rx0, ry0, rdiffx, rdiffy, lx0, ly0, ldiffx, ldiffy):
denom = ldiffy * rdiffx - ldiffx * rdiffy
if denom == 0: #ray and line are parallel or coincident
return (1) if (lx0 - rx0) * rdiffy == (ly0 - ry0) * rdiffx else None
t = (ldiffx * (ry0 - ly0) + ldiffy * (lx0 - rx0)) / denom
return (rx0 + rdiffx * t, ry0 + rdiffy * t) if t >=0 else None
print(ray_line_intersection(0, 0, 1, 1, 3, 0, -1, 1))
print(ray_line_intersection(0, 0, 1, 1, 3, 0, 1, 1))
print(ray_line_intersection(0, 0, 1, 1, -1, -1, 4, 4))
print(ray_line_intersection(0, 0, 1, 1, -1, 0, 1, -1))
>>> (1.5, 1.5) normal intersection
>>> None parallel
>>> 1 ray lies in the line
>>> None intersection beyond ray range
I am using a loop to grab values from every csv row and run it through linear_regression_model for prediction. The needed output is, for every row in the csv, print the predicted value that ran through the model, like:
4.500
4.256
3.909
4.565
...
4.433
Here is what I did:
def prediction_loop():
for index, row in ml_sample.iterrows():
print(row['column'])
new_data = OrderedDict(['column', row])
new_data = pd.Series(new_data).values.reshape(1,-1)
print(linear_regression_model.predict(new_data))
The actual output I get is:
Traceback (most recent call last):
new_data = OrderedDict(['column', row])
ValueError: too many values to unpack (expected 2)
In the csv there are 87 rows and 1 column.
How can I optimise the code?
Thank you
If I understand the question correctly, then this can be done very efficiently without the aid of any external modules. We just need a trivial class to manage the statistics. The assumption is that the input file contains one numerical value per line and that such values are Y and the implied line number is X. Try this:-
class Stats():
def __init__(self):
self.n = 0
self.sx = 0
self.sy = 0
self.sxx = 0
self.syy = 0
self.sxy = 0
def add(self, x, y):
self.sx += x
self.sy += y
self.sxx += x * x
self.syy += y * y
self.sxy += x * y
self.n += 1
def r(self): # correlation coefficient
return (self.n * self.sxy - self.sx * self.sy) / ((self.n * self.sxx - self.sx * self.sx) * (self.n * self.syy - self.sy * self.sy)) ** 0.5
def b(self): # slope
return (self.n * self.sxy - self.sx * self.sy) / (self.n * self.sxx - self.sx * self.sx)
def a(self): # intercept
return self.my() - self.b() * self.mx()
def mx(self): # mean x
assert self.n > 0
return self.sx / self.n
def my(self): # mean y
assert self.n > 0
return self.sy / self.n
def y(self, x): # estimate of y for given x
return x * self.b() + self.a()
stats = Stats()
with open('lr.txt') as data:
for i, line in enumerate(data):
stats.add(i, float(line.split()[0]))
print(f'r={stats.r():.4f} slope={stats.b():.4f} intercept={stats.a():.4f}')
for x in range(stats.n):
print(f'Estimate for {x} = {stats.y(x):.2f}')
So far, finding the hypotenuse, "side c" works fine without problems, the problem is when I try to calculate the angle, I am pretty sure it's returning a wrong value for the angle.
import math
from math import sqrt
class Triangle:
def __init__(self, side_a, side_b, ):
self.side_a = side_a
self.side_b = side_b
def SidesCalculate(self, ):
side_c = sqrt(self.side_a ** 2 + self.side_b ** 2)
return side_c
def AnglesCalculate(self, side_c):
x = math.sin(self.side_a / side_c)
math.asin(x)
x = round(x * 180 / math.pi)
return x
g = Triangle(side_a=int(input("Enter side a: ")), side_b=int(input("Enter side b: ")))
print("side c =", + g.SidesCalculate())
print("angle is =", + g.AnglesCalculate(side_c=True), '°')
Here is a way to do what you want.
First when you compute side_c, save it as an attribute.
def SidesCalculate(self, ):
self.side_c = sqrt(self.side_a ** 2 + self.side_b ** 2)
return self.side_c
Secondly, give the parameter side_c a default value None. (You also have another math error in the following function pointed by CFLS)
def AnglesCalculate(self, side_c = None):
if side_c == None:
side_c = self.side_c
x = math.asin(self.side_a / side_c)
x = round(x * 180 / math.pi)
return x
Now, if you want the class to pick previously computed side_c, you can do this:
g = Triangle(side_a=int(input("Enter side a: ")), side_b=int(input("Enter side b: ")))
print("side c =", + g.SidesCalculate())
print("angle is =", + g.AnglesCalculate(), '°')
def AnglesCalculate(self, side_c):
x = math.asin(self.side_a / side_c)
x = round(x * 180 / math.pi)
return x
I'm trying to implement ECDSA using python as part of my homework, I have a function named multiplication which takes two arguments Point P and t calculates B= tP.I have implemented this algorith based on iterative double and add algorithm on this wikipedia page the problem is when p coordination is small(one or two digits), the algorithm works fine but when coordination is large (about 70 digits) the result is different than what it supposed to be. here is the part of my code which calculates multiplication:
def addition(self, p, q):
if p.is_infinite:
return q
elif q.is_infinite:
return p
else :
if (q.x - p.x) == 0:
point = Point.Point(0, 0)
point.is_infinite = True
return point
s = int(((q.y - p.y) * Utils.Utils.mode_inverse(q.x - p.x, self.prime)) % self.prime)
xr = int((math.pow(s, 2) - p.x - q.x) % self.prime)
yr = int(((s * (p.x - xr)) - p.y) % self.prime)
r = Point.Point(xr, yr)
return r
def double(self, p):
if p.is_infinite:
return p
if p.y == 0:
point = Point.Point(0, 0)
point.is_infinite = True
return point
s = int((((3 * math.pow(p.x, 2)) + self.a) * Utils.Utils.mode_inverse(2 * p.y, self.prime)) % self.prime)
xr = int((math.pow(s, 2) - p.x - p.x) % self.prime)
yr = int(((s * (p.x - xr)) - p.y) % self.prime)
r = Point.Point(xr, yr)
return r
def multiplication(self, p, t):
bin_t = bin(t)[2:]
Q = Point.Point(p.x, p.y)
Q.is_infinite = True
for i, digit in enumerate(bin_t):
Q = self.double(Q)
if digit == '1':
Q = self.addition(Q, p)
return Q
Here is my Util class:
class Utils(object):
#staticmethod
def mode_inverse(a, m):
return pow(a, m - 2, m)
Here is my Point class:
class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
self.is_infinite = False
I use Curve P-224 parameters which are:
p = 26959946667150639794667015087019630673557916260026308143510066298881
a = -3
b = 18958286285566608000408668544493926415504680968679321075787234672564
Gx = 19277929113566293071110308034699488026831934219452440156649784352033
Gy = 19926808758034470970197974370888749184205991990603949537637343198772
according to calculator http://www.christelbach.com/eccalculator.aspx I should get this result for calculating 2G:
Px = 11838696407187388799350957250141035264678915751356546206913969278886
Py = 2966624012289393637077209076615926844583158638456025172915528198331
but what I actually get is:
Px = 15364035107168693070617763393106849380516103015030577748254379737088
Py = 7033137909116168824469040716130881489351924269422358605872723100109
Is there any way to fix this?
This was just a guess:
math.pow returns a floating point number (which has finite precision). I'd suggest using e.g. s.x * s.x instead of math.pow(s.x,2) in case the issue is hitting precision issues with bigger numbers.
I wrote an implementation of the De Casteljau algorithm to create a Bezier curve. My problem is the function ignores the second control point, it does calculate some kind of curve, but it is not correct.
def DeCasteljau(CNTRL_P, t):
ReP = points.point()
Ret = points.point()
n = len(CNTRL_P)
k = 0
tmp = 0
while k < n:
tmp = (((1 - t)**((n-1) - k)) * (t**k))
ReP.addP(CNTRL_P[k])
#ReP.Prnt()
ReP.mulP(tmp)
Ret.addP(ReP)
ReP.Clr() #ReP => (0,0)
tmp = 0
k = k + 1
return Ret
For example: CNTRL_P = [P0, P1, P2]
It ignores P1
class point():
def __init__(self, X = 0, Y = 0):
self.x = X
self.y = Y
def addP(self, P1):
self.x = self.x + (P1.getX())
self.y = self.y + (P1.getY())
def subP(self, C = 0, D = 0):
self.x = self.x - C
self.y = self.y - D
def mulP(self, C):
self.x = self.x * C
self.y = self.y * C
def getX(self):
a = self.x
return a
def getY(self):
a = self.y
return a
def Prnt(self):
print "X:", self.x,"Y:", self.y
def Clr(self):
self.x = 0
self.y = 0
Implementation looks faulty. Where's the recursion?
Does this give you better results?
def DeCasteljau2(CNTRL_P, t):
tmp_points = CNTRL_P[:]
while len(tmp_points) > 1:
for k in range(len(tmp_points)-1):
ReP = point()
ReP2 = point()
ReP.addP(tmp_points[k])
ReP2.addP(tmp_points[k+1])
ReP.mulP((1-t))
ReP2.mulP(t)
ReP.addP(ReP2)
tmp_points[k] = ReP
tmp_points.pop()
return tmp_points[0]
This is the result after each iteration:
P0 | P1 | P2
P0 * (1-t) + P1 * t | P1 * (1-t) + P2
(P0 * (1-t) + P1 * t)*(1-t) + (P1 * (1-t) + P2)*t
You repeat the algorithm until you only have 1 point left. Each point P(n) in the next solution is the result of P(n) * (1-t) + p(n+1) * t from the last solution. At each iteration the last point is discarded since there is no next point that you could multiply and add with.
Wikipedia probably can explain that better than me: link