This commit is contained in:
2024-11-25 10:04:18 +00:00
commit 7baabd7b0f

97
Vektorrechnung.py Normal file
View File

@@ -0,0 +1,97 @@
import math
import decimal
decimal.getcontext().prec = 30
class Vector(object):
CANNOT_NORMALIZE_ZERO_VECTOR_MSG = 'Cannot normalize the zero vector'
def __init__(self, coordinates):
try:
if not coordinates:
raise ValueError
self.coordinates = tuple([decimal.Decimal(x) for x in coordinates])
self.dimension = len(coordinates)
except ValueError:
raise ValueError('The coordinates must be nonempty')
except TypeError:
raise TypeError('The coordinates must be an iterable')
def __str__(self):
return 'Vector: {}'.format(self.coordinates)
def __eq__(self, v):
return self.coordinates == v.coordinates
# LINEAR ALGEBRA METHODS
def plus(self, v):
new_coordinates = [x+y for x,
y in zip(self.coordinates, v.coordinates)]
return Vector(new_coordinates)
def minus(self, v):
new_coordinates = [x-y for x,y in zip(self.coordinates, v.coordinates)]
return Vector(new_coordinates)
def times_scalar(self,c):
new_coordinates = [c*x for x in self.coordinates]
return Vector(new_coordinates)
def magnitude(self):
coordinates_squared = [x**2 for x in self.coordinates]
return decimal.Decimal(math.sqrt(sum(coordinates_squared)))
def normalized(self):
try:
magnitude = self.magnitude()
return self.times_scalar(decimal.Decimal('1.0')/magnitude)
except ZeroDivisionError:
raise Exception(self.CANNOT_NORMALIZE_ZERO_VECTOR_MSG)
def dot(self,v):
return sum([x*y for x,y in zip(self.coordinates, v.coordinates)])
def angle_inner_with(self, v, in_degrees = False):
try:
u1 = self.normalized()
u2 = v.normalized()
#Capture within range of dot product to be within 1 & -1
u1u2dot = replace_if_within_tolerance(u1.dot(u2),1)
u1u2dot = replace_if_within_tolerance(u1.dot(u2),-1)
angle_in_radians = math.acos(u1u2dot)
if in_degrees:
return math.degrees(angle_in_radians)
else:
return angle_in_radians
except Exception as e:
if str(e) == self.CANNOT_NORMALIZE_ZERO_VECTOR_MSG:
raise Exception('Cannot compute an angle with the zero vector')
else:
raise e def is_zero(self, tolerance = 1e-10):
#returns true if magnitude is less than tolerance
return self.magnitude() < tolerance
def is_parallel_to(self, v):
return ( self.is_zero() or
v.is_zero() or
self.angle_inner_with(v) == 0 or
self.angle_inner_with(v) == math.pi )
def is_orthogonal_to(self, v, tolerance = 1e-10):
return abs(self.dot(v)) < tolerance
def replace_if_within_tolerance(val, compared_against, tolerance = 1e-10):
if abs(val - compared_against) < tolerance:
return compared_against
else:
return val
#Values from Parallel Orthogonal Quiz, math domain error
v = Vector([-7.579, -7.88])
w = Vector([22.737, 23.64])
print(v.is_parallel_to(w)) print(v.is_orthogonal_to(w))
#v = Vector([-2.029, 9.97, 4.172]) w = Vector([-9.231, -6.639, -7.245]) print(v.is_parallel_to(w)) print(v.is_orthogonal_to(w)) v = Vector([-2.328, -7.284, -1.214]) w = Vector([-1.821, 1.072, -2.94]) print(v.is_parallel_to(w)) print(v.is_orthogonal_to(w)) v = Vector([2.118, 4.827]) w = Vector([0, 0]) print(v.is_parallel_to(w)) print(v.is_orthogonal_to(w))