Files
Vektoren/Vektorrechnung.py
2024-11-25 10:04:18 +00:00

98 lines
4.0 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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))