I'm trying creating a 3D class Vector and I have prepared the following code:
class Vector:
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
#return string 'Vector(x,y,z)'
def __repr__(self):
return ("Vector(x,y,z)")
# or alternatively
#def __str__(self):
#return str("Vector3({0.x},{0.y},{0.z})".format(self))
# v == w
def __eq__(self, other):
self.v = Vector(self.x,self.y,self.z)
other.w = Vector(other.x, other.y, other.z)
if self.v() == self.w():
return True
else:
return False
#def __eq__(self, other): # poly1 == poly2
# return (self - other).is_zero() # it works when the substraction is defined
# v != w
def __ne__(self, other):
self.v = Vector(self.x,self.y,self.z)
other.w = Vector(other.x, other.y, other.z)
if self.v() != self.w():
return True
else:
return False
#def __ne__(self, other): # poly1 != poly2
# return not self == other
# v + w
def __add__(self, other):
if other == 0:
return self
else:
return vector(self.x+other.x, self.y+other.y, self.z+other.z)
# v - w
def __sub__(self, other):
self.x -= other.x
self.y -= other.y
self.z -= other.z
# return the dot product (number)
def __mul__(self, other):
self.v = Vector(self.x + self.y + self.z)
self.w = Vector(other.x + other.y + other.z)
return Vector(self.x*other.x,self.y*other.y, self.z*other.z)
#cross product
def __pow__(self, other):
return Vector(self.y*other.z - self.z*other.y,
self.z*other.x - self.x*other.z,
self.z*other.y - self.y*other.x)
# the length of the vector
def length(self):
return len(self)
# we assume that vectors are immutable
def __hash__(self):
return hash((self.x, self.y, self.z))
However no one of the following assert tests seem to work:
import math
v = Vector(1, 2, 3)
w = Vector(2, -3, 2)
assert v != w
assert v + w == Vector(3, -1, 5)
assert v - w == Vector(-1, 5, 1)
assert v * w == 2
assert v.cross(w) == Vector(13, 4, -7)
If someone tries running the following assert code, some errors pop up but I am not able to figure out what the problem is. Moreover, if it is possible I would lie to ask for a possible way to return the hash, length and string representation. Thanks
Related
I'm using this code to add two points together using finite Fields
class FieldElement():
def __init__(self,num,prime):
if num>=prime or num < 0:
error = "num s not in field"
raise ValueError(error)
self.num = num
self.prime=prime
def __eq__(self,other):
if other is None:
return
return self.num == other.num and self.prime == other.prime
def __ne__(self,other):
return not (self == other)
def __add__ (self,other):
if self.prime != other.prime:
raise ValueError("cannot add two numbers in diffirent fields")
num = (self.num+other.num)%self.prime
return self.__class__(num,self.prime)
def __mul__(self,other):
if self.prime != other.prime:
raise ValueError("cannot add two numbers in different fields")
num = (self.num * other.num)%self.prime
return self.__class__(num,self.prime)
def __pow__(self,exponent):
n = exponent%(self.prime-1)
num = pow(self.num,n,self.prime)
return self.__class__(num,self.prime)
def __sub__(self,other):
if self.prime != other.prime:
raise ValueError("cannot add two numbers in different fields")
num = (other.num - self.num)%self.prime
return self.__class__(num,self.prime)
def __truediv__(self,other):
if self.prime != other.prime:
raise TypeError("cannot divide two numbers in different Fields")
num = self.num * pow(other.num,self.prime-2,self.prime)%self.prime
return self.__class__(num,self.prime)
class Point ():
def __init__(self, x,y,a,b):
self.a = a
self.b = b
self.y = y
self.x = x
if self.x is None and self.y is None:
return
if (self.y**2) != (self.x**3 + a*x + b):
raise ValueError("{} , {} not in the Curve".format(x.num,y.num))
def __repr__(self):
return "Point({},{}){}_{}".format(self.x,self.y,self.a,self.b)
def __eq__(self,other):
return self.x == other.x and self.y == other.y and self.a == other.a and self.b == other.b
def __add__(self,other):
if other.a != self.a or other.b != self.b:
raise TypeError("Points{},{} are the same curve".format(self,other))
if self.x is None:
return other
if other.x is None:
return self
if other.x == self.x and other.y != self.y:
return self.__class__(None,None,self.a,self.b)
if self != other:
s = (other.y-self.y)/(other.x-self.x)
x = (s**2 - self.x - other.x)
y = s*(self.x - x) - self.y
return self.__class__(x,y,self.a,self.b)
if self == other :
s = (3*self.x**2+self.a)/(2* self.y)
x = s**2-2*self.x
y = s*(self.x-x)-self.y
return self.__class__(x,y,self.a,self.b)
if self == other and self.y == 0*self.x:
return self.__class__(None,None,self.a,self.b)
def __eq__(self,other):
return self.x == other.x and self.y == other.y and self.a==other.a and self.b==other.b
def __mul__(self,other):
numX = self.x * other.x
numY = self.y * other.y
return self.__class__(numX,numY,self.a,self.b)
and the bellow code to test it ,
from test import FieldElement,Point
prime = 223
a = FieldElement(num=0,prime=prime)
b = FieldElement(num=7,prime=prime)
x1 = FieldElement(num=47,prime=prime)
y1 = FieldElement(num=71,prime=prime)
x2 = FieldElement(num=17,prime=prime)
y2 = FieldElement(num=56,prime=prime)
p1 = Point(x1,y1,a,b)
p2 = Point(x2,y2,a,b)
p3 = p1+p2
print(p3)
Whatever points I add I get the same error that the third point is not on the the curve, I think the problem is on if (self.y**2) != (self.x**3 + a*x + b) some how it's not checking the new point correctly or Point __add__ method does not calculate the new point correctly, what am missing here ?
You should test every module before use
In the Field, the subtraction is wrong! you calculate b-a not a-b
def __sub__(self,other):
if self.prime != other.prime:
raise ValueError("cannot add two numbers in different fields")
num = (other.num - self.num)%self.prime
return self.__class__(num,self.prime)
must be
def __sub__(self,other):
if self.prime != other.prime:
raise ValueError("cannot add two numbers in different fields")
num = (self.num - other.num)%self.prime
return self.__class__(num,self.prime)
The other problem as stated in the other answer doesn't make a problem since the first operand is the member of the class, however, you should use
if (self.y**2) != (self.x**3 + self.a*self.x + self.b):
You should also implement __str__ for your field and point classes to print easy to test your code!
def __str__(self):
return num
I've tested and now works. The below is the SageMath Code (test here) that you can compare the result and use a test base for your code.
E = EllipticCurve(GF(223),[0,7])
print(E)
R1 = E(47,71)
R2 = E(17,56)
print(R1+R2)
I think that the line:
if (self.y**2) != (self.x**3 + a*x + b):
should be
if (self.y**2) != (self.x**3 + self.a*self.x + self.b):
as a, x and b will not be treated as field elements.
I need to change the code in line # 39
I have approximately seen scripts that use with open ("file.txt", "r") as f: take data from a text document.
I have a list of "Point.txt"
g = Point(250,127)
g = Point(330,224)
g = Point(557,186)
g = Point(370,197)
g = Point(222,107)
Need to add a function so that the script takes data from the list of the document "Point.txt"
and the whole result was saved in one document "Save.txt"
class Point(object):
def __init__(self, _x, _y, _order = None): self.x, self.y, self.order = _x, _y, _order
def calc(self, top, bottom, other_x):
l = (top * inverse_mod(bottom)) % p
x3 = (l * l - self.x - other_x) % p
return Point(x3, (l * (self.x - x3) - self.y) % p)
def double(self):
if self == INFINITY: return INFINITY
return self.calc(3 * self.x * self.x, 2 * self.y, self.x)
def __add__(self, other):
if other == INFINITY: return self
if self == INFINITY: return other
if self.x == other.x:
if (self.y + other.y) % p == 0: return INFINITY
return self.double()
return self.calc(other.y - self.y, other.x - self.x, other.x)
def __mul__(self, e):
if self.order: e %= self.order
if e == 0 or self == INFINITY: return INFINITY
result, q = INFINITY, self
while e:
if e&1: result += q
e, q = e >> 1, q.double()
return result
def __str__(self):
if self == INFINITY: return "infinity"
return " %x %x" % (self.x, self.y)
def inverse_mod(a):
if a < 0 or a >= p: a = a % p
c, d, uc, vc, ud, vd = a, p, 1, 0, 0, 1
while c:
q, c, d = divmod(d, c) + (c,)
uc, vc, ud, vd = ud - q*uc, vd - q*vc, uc, vc
if ud > 0: return ud
return ud + p
p, INFINITY = 1693, Point(None, None)
g = Point(250,127)
wave = 78
result = ' ID: %x\n getID: %s' % (wave, g*wave)
f = open('Save.txt', 'a')
f.write(result)
f.close()
I have used regex to extract the parameters that you have to pass for Point creation :
import re
f = open('Save.txt', 'a')
with open('Point.txt', 'rb') as points_txt_file:
for line in points_txt_file:
found_points = re.search(r'Point\((\s*\d+\s*),(\s*\d+\s*)\)', f'{line}')
print(found_points.groups())
param1 = int(found_points.group(1))
param2 = int(found_points.group(2))
g = Point(param1, param2)
result = ' ID: %x\n getID: %s' % (wave, g*wave)
f.write(result)
f.close()
Remove your code from line #38 and use this code .
from math import pi
class Circle(object):
'Circle(x,y,r)'
def __init__(self, x=0, y=0, r=1):
self._r = r
self._x = x
self._y = y
def __repr__(self):
return 'Circle({},{},{})'.\
format(self.getx(), self.gety(),\
self.getr())
#silly, but has a point: str can be different from repr
def __str__(self):
return 'hello world'
def __contains__(self, item):
'point in circle'
px, py = item
return (self.getx() - px)**2 + \
(self.gety() - py)**2 < self.getr()**2
def getr(self):
'radius'
return self._r
def getx(self):
'x'
self._lst.append(self._x)
return self._x
def gety(self):
'y'
self._lst.append(self._y)
return self._y
def setr(self,r):
'set r'
self._r = r
def setx(self,x):
'set x'
self._x = x
def sety(self,y):
'set y'
self._y = y
def move(self,x,y):
self._x += x
self._y += y
def concentric(self, d):
d = self._list
def area(self):
'area of circle'
return (self.getr())**2*pi
def circumference(self):
'circumference of circle'
return 2*self.getr()*pi
My question is worded kinda awkwardly but what I am trying to do is check if 2 different circles have the same center (x,y). I think the easiest way to solve this would be to input the 2 points into a list but I am not sure how to compare the 2 lists as every time i try my code it adds everything to the same list
Add the following method to your Circle class.
def equal_center(self, other):
'check if another circle has same center'
return (self._x == other._x) & (self._y == other._y)
Usage
C1 = Circle(3, 5, 8)
C2 = Circle(3, 5, 10)
C3 = Circle(3, 2, 1)
C1.equal_center(C2) # True
C1.equal_center(C3) # False
I would recommend creating a function which takes two circle objects and returns if the coordinates are the same or not by comparing the x and y values of each object:
def same_center(circle_1, circle_2):
if circle_1.getx() == circle_2.getx() and circle_1.gety() == circle_2.gety():
return True
else:
return False
This solution is much easier than using lists and should be easy to implement.
If you have two instances of the class...
a = Circle(0,0,1)
b = Circle(0,0,1)
You could add them to a list of circles...
circles = [a,b]
And loop through the list, checking their values...
for i in circles:
for j in filter(lambda x : x != i, circles):
if i._x == j._x and i._y == j._y:
return True #two circles have same center
This should work for n instances of the class, though if its only two you want to check
if a._x == b._x and a._y == a._y:
return True
G'day! When I know the slope and y-intercept of a line, I need to calculate an x-value that is 1 unit out from the line.
For example, if pointA = (4,5), and I set a line going from it with 0 slope (and therefore 5 as the y-intercept), then the x value I want would be 5. If the slope were undefined (vertical), then the x value would be 4. And so on.
So far, I calculate x as x = m(point[0]+1)-b. This doesn't work so well for vertical lines, however.
This and this are similar, but I can't read C# for the first, and on the second one, I don't need to eliminate any possible points (yet).
This is kind of hitting a nail with a sledge hammer, but if you're going to be running into geometry problems often, I'd either write or find a Point/Vector class like
import math
class Vector():
def __init__(self, x=0.0, y=0.0, z=0.0):
self.x = x
self.y = y
self.z = z
def __add__(self, other):
self.x += other.x
self.y += other.y
self.z += other.z
return self
def __sub__(self, other):
self.x -= other.x
self.y -= other.y
self.z -= other.z
return self
def dot(self, other):
return self.x*other.x + self.y*other.y + self.z*other.z
def cross(self, other):
tempX = self.y*other.z - self.z*other.y
tempY = self.z*other.x - solf.x*other.z
tempZ = self.x*other.y - self.y*other.x
return Vector(tempX, tempY, tempZ)
def dist(self, other):
return math.sqrt((self.x-other.x)**2 + (self.y-other.y)**2 + (self.z-other.z)**2)
def unitVector(self):
mag = self.dist(Vector())
if mag != 0.0:
return Vector(self.x * 1.0/mag, self.y * 1.0/mag, self.z * 1.0/mag)
else:
return Vector()
def __repr__(self):
return str([self.x, self.y, self.z])
Then you can do all kinds of stuff like find the vector by subtracting two points
>>> a = Vector(4,5,0)
>>> b = Vector(5,6,0)
>>> b - a
[1, 1, 0]
Or adding an arbitrary unit vector to a point to find a new point (which is the answer to your original question)
>>> a = Vector(4,5,0)
>>> direction = Vector(10, 1, 0).unitVector()
>>> a + direction
[4.995037190209989, 5.099503719020999, 0.0]
You can add more utilities, like allowing Vector/Scalar operations for scaling, etc.
below classes are in pure python, but the are a little slow on heavily dense calculation and lead to about 1 minute to do about 5 million action.
the question:
Is there any way to write them in C and import them to python for more speed?
how?
the usage is something like this:
_cm=Unit(...) # Unit
_m =Unit(...) # Unit
a= 1*_cm # UnitValue
b= 2*_m # UnitValue
_m2 = _m**2 # Unit
b*a == 0.02 * _m2 # UnitValue
a*b == 200 * _cm2 # UnitValue # _cm2 is auto created unit based on Unit.__new__
b-a = 0.99*_m # UnitValue
a-b = -99*_cm # UnitValue
# and so on...
NOTE: the classes are bigger that what included here...
class Unit(object):
def __new__(self, *args, **kwargs):
# check if this unit not created before and if ues return before created-one.
# useful for cmp between units.
return created_or_new_unit_instance
def __div__(self, other):
return self * (other ** -1) # self / other
def __rdiv__(self, other):
return other * (self ** -1) # other / self
def __rmul__(self, other):
return self * other # other * self
def __mul__(self, other): # self * other
if isinstance(other, SUPPORTED_NUMBERS):
return UnitValue(other, self)
elif isinstance(other, UnitValue): # FIXME DOUBLICATED!
return (other.value * (other.unit * self))
elif isinstance(other, Unit): # multipling two units self * other
# calculate the other exchange factor againest self in `v`
if v == 1.0:
# the bases may differ from self.bases or other.bases
# so just create a new Unit and let __new__ handle doublication.
return Unit(bases)
else:
return v * Unit(bases)
return NotImplemented
def __pow__(self, other, modulo=None): # #UnusedVariable
# create new powered unit.
return new Unit
and the other Class:
class UnitValue(object):
def __init__(self, value, unit):
self.value = value
self.unit = unit
def __add__(self, other): # self + other
if isinstance(other, UnitValue):
o = self.unit.get_unitvalue_in_this_unit(other) # other is UnitValue
v = self.value + o.value
return UnitValue(v, self.unit)
if other == 0:
return UnitValue(self.value, self.unit)
return NotImplemented
def __mul__(self, other): # self * other
if isinstance(other, SUPPORTED_NUMBERS):
return UnitValue(other * self.value, self.unit)
elif isinstance(other, UnitValue):
return (self.value * other.value) * (self.unit * other.unit)
return NotImplemented
def __pow__(self, other, modulo=None):
v = self.value ** other
u = self.unit ** other
if modulo:
v = v % modulo
return UnitValue(v, u)
def __cmp__(self, other):
if isinstance(other, UnitValue):
vo = self.unit.get_unitvalue_in_this_unit(other).value
else:
vo = other
if vo is None:
vo = 0
diff = self.value - vo
epsi = 1e-10
if abs(diff) < epsi: return 0
elif diff > 0: return 1
elif diff < 0: return -1