Example #1
0
	def mod(self, a, b):
		if isinstance(a, float):
			if isinstance(b, float):
				if not (a.is_integer() and b.is_integer()):
					raise ComputorException('Illegal operation: ' + str(a) + ' % ' + str(b))
				return a % b
			elif isinstance(b, Complex):
				raise ComputorException('Illegal operation: Rational % Complex')
			elif isinstance(b, Matrix):
				raise ComputorException('Illegal operation: Rational % Matrix')
		elif isinstance(a, Complex):
			if isinstance(b, float):
				raise ComputorException('Illegal operation: Complex % Rational')
			elif isinstance(b, Complex):
				raise ComputorException('Illegal operation: Complex % Complex')
			elif isinstance(b, Matrix):
				raise ComputorException('Illegal operation: Complex % Matrix')
		elif isinstance(a, Matrix):
			if isinstance(b, float):
				raise ComputorException('Illegal operation: Matrix % Rational')
			elif isinstance(b, Complex):
				raise ComputorException('Illegal operation: Matrix % Complex')
			elif isinstance(b, Matrix):
				raise ComputorException('Illegal operation: Matrix % Matrix')
		raise ComputorException('Computor.mul(): something bad happened 🤷')
Example #2
0
	def deg(self, radians):
		if isinstance(radians, float):
			return radians * 180 / Computor.pi
		elif isinstance(radians, Complex):
			raise ComputorException('Illegal operation: deg(Complex)')
		elif isinstance(radians, Matrix):
			raise ComputorException('Illegal operation: deg(Matrix)')
		raise ComputorException('Computor.deg(): something bad happened 🤷')
Example #3
0
	def tan(self, radians):
		if isinstance(radians, float):
			return tan(radians)
		elif isinstance(radians, Complex):
			raise ComputorException('Illegal operation: tan(Complex)')
		elif isinstance(radians, Matrix):
			raise ComputorException('Illegal operation: tan(Matrix)')
		raise ComputorException('Computor.tan(): something bad happened 🤷')
Example #4
0
	def transp(self, a):
		if isinstance(a, float):
			raise ComputorException('Illegal operation: transp(Rational)')
		elif isinstance(a, Complex):
			raise ComputorException('Illegal operation: transp(Complex)')
		elif isinstance(a, Matrix):
			return a.get_transpose()
		raise ComputorException('Computor.inv(): something bad happened 🤷')
Example #5
0
	def rad(self, degrees):
		if isinstance(degrees, float):
			return degrees * Computor.pi / 180
		elif isinstance(degrees, Complex):
			raise ComputorException('Illegal operation: rad(Complex)')
		elif isinstance(degrees, Matrix):
			raise ComputorException('Illegal operation: rad(Matrix)')
		raise ComputorException('Computor.rad(): something bad happened 🤷')
Example #6
0
	def sqrt(self, a):
		if isinstance(a, float):
			if a >= 0:
				return a ** 0.5
			else:
				return Complex(0, (-a) ** 0.5)
		elif isinstance(a, Complex):
			raise ComputorException('Illegal operation: sqrt(Complex)')
		elif isinstance(a, Matrix):
			raise ComputorException('Illegal operation: sqrt(Matrix)')
		raise ComputorException('Computor.sqrt(): something bad happened 🤷')
Example #7
0
	def pow(self, base, power):
		if not (isinstance(power, float) and power.is_integer() and int(power) >= 0):
			raise ComputorException('Exponent ' + Fore.RED + str(power) + Fore.RESET + ' must be a non-negative integer')
		power = int(power)
		if isinstance(base, float):
			return base ** power
		elif isinstance(base, Complex):
			return Complex.pow(base, power)
		elif isinstance(base, Matrix):
			return Matrix.pow(base, power)
		raise ComputorException('Computor.pow(): something bad happened 🤷')
Example #8
0
	def pow(base, power):
		if base.shape[0] != base.shape[1]:
			raise ComputorException('Invalid Matrix shape: M' + str(base.shape) + ' ^ ' + str(power))
		product = Matrix.__identity(base.shape[0])
		for _ in range(power):
			product = Matrix.mat_mul(product, base)
		return product
Example #9
0
	def add(a, b):
		if a.shape != b.shape:
			raise ComputorException('Invalid Matrix shapes: M' + str(a.shape) + ' + M' + str(b.shape))
		data = []
		for i in range(a.shape[0]):
			data.append(list(map(lambda x, y: x + y, a.data[i], b.data[i])))
		return Matrix(data)
Example #10
0
	def inv(self, a):
		if isinstance(a, float):
			return self.div(1.0, a)
		elif isinstance(a, Complex):
			return self.div(1.0, a)
		elif isinstance(a, Matrix):
			return a.get_inverse()
		raise ComputorException('Computor.inv(): something bad happened 🤷')
Example #11
0
	def neg(self, a):
		if isinstance(a, float):
			return -a
		elif isinstance(a, Complex):
			return Complex.neg(a)
		elif isinstance(a, Matrix):
			return Matrix.neg(a)
		raise ComputorException('Computor.neg(): something bad happened 🤷')
Example #12
0
	def __init__(self, data):
		rows = len(data)
		cols = len(data[0])
		self.shape = (rows, cols)
		self.data = data
		for row in self.data:
			if len(row) != cols:
				raise ComputorException('Invalid matrix shape')
Example #13
0
	def validate_func(self, func_name, num_args):
		func_name_lc = func_name.lower()
		# check name matches
		if func_name_lc in self.__funcs:
			function = self.__funcs[func_name_lc]
			# check number of args match
			if len(function.local_vars) == num_args:
				return
		raise ComputorException('No such function: ' + Fore.BLUE + func_name + Fore.RESET)
Example #14
0
 def div(a, b):
     if b.__is_zero():
         raise ComputorException('Division by zero')
     conjugate = b.__get_conjugate()
     numerator = Complex.mul(a, conjugate)
     denominator = Complex.mul(b, conjugate)
     assert denominator.imag == 0.0
     return Complex(numerator.real / denominator.real,
                    numerator.imag / denominator.real)
Example #15
0
	def mat_mul(a, b):
		if a.shape[1] != b.shape[0]:
			raise ComputorException('Invalid Matrix shapes: M' + str(a.shape) + ' ** M' + str(b.shape))
		data = []
		for i in range(a.shape[0]):
			data.append( [None] * b.shape[1] )
			for j in range(b.shape[1]):
				data[i][j] = sum([ a.data[i][k] * b.data[k][j] for k in range(a.shape[1]) ])
		return Matrix(data)
Example #16
0
	def get_var(self, var_name):
		var_name_lc = var_name.lower()
		# Search in stack of local variables
		for local_var in reversed(self.__local_vars):
			if local_var[0].lower() == var_name_lc:
				return local_var[1]
		# Search in dictionary of global variables
		if var_name_lc in self.__vars:
			return self.__vars[var_name_lc].value
		raise ComputorException('Variable \'' + Fore.BLUE + var_name + Fore.RESET + '\' is not defined')
Example #17
0
	def show_func(self, func_name, args):
		func_name = func_name.lower()
		# check if func_name matches
		if func_name in self.__funcs:
			function = self.__funcs[func_name]
			# check if args match
			if len(function.local_vars) == len(args) and \
				all([ x.lower() == y.lower() for x, y in zip(function.local_vars, args) ]):
				print(function)
				return
		raise ComputorException('No such function: ' + Fore.BLUE + func_name + '(' + ', '.join(args) + ')' + Fore.RESET)
Example #18
0
	def __init__(self):
		if Computor.instance is None:
			Computor.instance = self
			self.__parser = Parser()
			self.__simplifier = Simplifier()
			self.__evaluator = evaluator.Evaluator()
			self.__solver = Solver()
			self.__vars = {}
			self.__funcs = {}
			self.__local_vars = []		# list of tuple (name, value), to be used as stack
		else:
			raise ComputorException('Computor.instance already instantiated')
Example #19
0
	def resolve_var(self, var_name):
		var_name_lc = var_name.lower()
		# Search in stack of local variables
		# if found, return the variable name as string
		for local_var in reversed(self.__local_vars):
			if local_var[0].lower() == var_name_lc:
				return var_name
		# Search in dictionary of global variables
		# if found, return the variable's value
		if var_name_lc in self.__vars:
			return self.__vars[var_name_lc].value
		raise ComputorException('Variable \'' + Fore.BLUE + var_name + Fore.RESET + '\' is not defined')
Example #20
0
	def div(self, a, b):
		if isinstance(a, float):
			if isinstance(b, float):
				if b == 0:
					raise ComputorException('Division by zero')
				return a / b
			elif isinstance(b, Complex):
				return Complex.div(Complex(a), b)
			elif isinstance(b, Matrix):
				raise ComputorException('Illegal operation: Rational / Matrix')
		elif isinstance(a, Complex):
			if isinstance(b, float):
				return Complex.div(a, Complex(b))
			elif isinstance(b, Complex):
				return Complex.div(a, b)
			elif isinstance(b, Matrix):
				raise ComputorException('Illegal operation: Complex / Matrix')
		elif isinstance(a, Matrix):
			if isinstance(b, float):
				if b == 0:
					raise ComputorException('Division by zero')
				return Matrix.scalar_mul(1 / b, a)
			elif isinstance(b, Complex):
				raise ComputorException('Illegal operation: Matrix / Complex')
			elif isinstance(b, Matrix):
				return Matrix.mat_mul(a, b.get_inverse())
		raise ComputorException('Computor.div(): something bad happened 🤷')
Example #21
0
	def get_inverse(self):
		# Check if it is square matrix
		if self.shape[0] != self.shape[1]:
			raise ComputorException('M' + str(self.shape) + ' is not invertible')
		
		# 1 x 1 Matrix
		if self.shape[0] == 1:
			if self.data[0][0] == 0:
				raise ComputorException('Matrix is singular')
			else:
				data = [[ 1 / self.data[0][0] ]]
				return Matrix(data)
		
		# Check determinant
		determinant = self.__get_determinant()
		if determinant == 0:
			raise ComputorException('Matrix is singular')
		
		# 2 x 2 Matrix
		# inv = 1/determinant * [[d, -b], [-c, a]]
		if self.shape[0] == 2:
			data = [[ 1 / determinant * self.data[1][1], -1 / determinant * self.data[0][1] ],
				[ -1 / determinant * self.data[1][0], 1 / determinant * self.data[0][0] ]]
			return Matrix(data)

		# 3 x 3 or Bigger Matrix
		cofactors = []
		for r in range(self.shape[0]):
			cofactor_row = []
			for c in range(self.shape[0]):
				minor = self.__get_minor(r, c)
				cofactor_row.append( ((-1)**(r+c)) * minor.__get_determinant() )
			cofactors.append(cofactor_row)
		inv = Matrix(cofactors).get_transpose()
		for r in range(inv.shape[0]):
			for c in range(inv.shape[0]):
				inv.data[r][c] /= determinant
		return inv
Example #22
0
	def add(self, a, b):
		if isinstance(a, float):
			if isinstance(b, float):
				return a + b
			elif isinstance(b, Complex):
				return Complex.add(Complex(a), b)
			elif isinstance(b, Matrix):
				raise ComputorException('Illegal operation: Rational + Matrix')
		elif isinstance(a, Complex):
			if isinstance(b, float):
				return Complex.add(a, Complex(b))
			elif isinstance(b, Complex):
				return Complex.add(a, b)
			elif isinstance(b, Matrix):
				raise ComputorException('Illegal operation: Complex + Matrix')
		elif isinstance(a, Matrix):
			if isinstance(b, float):
				raise ComputorException('Illegal operation: Matrix + Rational')
			elif isinstance(b, Complex):
				raise ComputorException('Illegal operation: Matrix + Complex')
			elif isinstance(b, Matrix):
				return Matrix.add(a, b)
		raise ComputorException('Computor.add(): something bad happened 🤷')
Example #23
0
	def sub(self, a, b):
		if isinstance(a, float):
			if isinstance(b, float):
				return a - b
			elif isinstance(b, Complex):
				return Complex.sub(Complex(a), b)
			elif isinstance(b, Matrix):
				raise ComputorException('Illegal operation: Rational - Matrix')
		elif isinstance(a, Complex):
			if isinstance(b, float):
				return Complex.sub(a, Complex(b))
			elif isinstance(b, Complex):
				return Complex.sub(a, b)
			elif isinstance(b, Matrix):
				raise ComputorException('Illegal operation: Complex - Matrix')
		elif isinstance(a, Matrix):
			if isinstance(b, float):
				raise ComputorException('Illegal operation: Matrix - Rational')
			elif isinstance(b, Complex):
				raise ComputorException('Illegal operation: Matrix - Complex')
			elif isinstance(b, Matrix):
				return Matrix.sub(a, b)
		raise ComputorException('Computor.sub(): something bad happened 🤷')
Example #24
0
	def mul(self, a, b):
		if isinstance(a, float):
			if isinstance(b, float):
				return a * b
			elif isinstance(b, Complex):
				return Complex.mul(Complex(a), b)
			elif isinstance(b, Matrix):
				return Matrix.scalar_mul(a, b)
		elif isinstance(a, Complex):
			if isinstance(b, float):
				return Complex.mul(a, Complex(b))
			elif isinstance(b, Complex):
				return Complex.mul(a, b)
			elif isinstance(b, Matrix):
				raise ComputorException('Illegal operation: Complex * Matrix')
		elif isinstance(a, Matrix):
			if isinstance(b, float):
				return Matrix.scalar_mul(b, a)
			elif isinstance(b, Complex):
				raise ComputorException('Illegal operation: Matrix * Complex')
			elif isinstance(b, Matrix):
				return Matrix.element_mul(a, b)
		raise ComputorException('Computor.mul(): something bad happened 🤷')
Example #25
0
	def mat_mul(self, a, b):
		if isinstance(a, float):
			if isinstance(b, float):
				raise ComputorException('Illegal operation: Rational ** Rational')
			elif isinstance(b, Complex):
				raise ComputorException('Illegal operation: Rational ** Complex')
			elif isinstance(b, Matrix):
				raise ComputorException('Illegal operation: Rational ** Matrix')
		elif isinstance(a, Complex):
			if isinstance(b, float):
				raise ComputorException('Illegal operation: Complex ** Rational')
			elif isinstance(b, Complex):
				raise ComputorException('Illegal operation: Complex ** Complex')
			elif isinstance(b, Matrix):
				raise ComputorException('Illegal operation: Complex ** Matrix')
		elif isinstance(a, Matrix):
			if isinstance(b, float):
				raise ComputorException('Illegal operation: Matrix ** Rational')
			elif isinstance(b, Complex):
				raise ComputorException('Illegal operation: Matrix ** Complex')
			elif isinstance(b, Matrix):
				return Matrix.mat_mul(a, b)
		raise ComputorException('Computor.mat_mul(): something bad happened 🤷')
Example #26
0
	def eval_function(self, func_name, args):
		function = self.get_func(func_name)

		if len(function.local_vars) != len(args):
			raise ComputorException('Invalid parameters for ' + str(function))

		# push local variables on stack
		for var_name, value in zip(function.local_vars, args):
			self.__local_vars.append((var_name, value))

		# evaluate
		# result = self.__parser.parse(function.expr)
		result = self.__evaluator.eval(function.expr)

		# pop local variables from stack
		for _ in self.__local_vars:
			self.__local_vars.pop()

		return result
Example #27
0
	def mat_mul(self, a, b):
		if isinstance(a, Matrix) and isinstance(b, Matrix):
			return Matrix.mat_mul(a, b)
		else:
			raise ComputorException('**: both operands must be Matrix')
Example #28
0
		def build_term_var(self, var_name):
			value = computor.Computor.instance.get_var(var_name)
			if not isinstance(value, float):
				raise ComputorException('Variables must be rational')
			return [ Term(value, 0) ]
Example #29
0
		def parse_func(self, token):
			func_name = token.value
			function = computor.Computor.instance.get_func(func_name)
			if not (len(function.local_vars) == 1 and function.local_vars[0].upper() == 'X'):
				raise ComputorException('Invalid function: ' + str(function))
			return function
Example #30
0
	def get_func(self, func_name):
		func_name_lc = func_name.lower()
		if func_name_lc in self.__funcs:
			return (self.__funcs[func_name_lc])
		else:
			raise ComputorException('Function \'' + Fore.GREEN + func_name + Fore.RESET + '\' is not defined')