def argument(self): ''' Return the complex argument of a number. ''' from math import pi, atan r, i = abs(self.real), abs(self.imag) a = atan(i/r) if self.real >= 0 and self.imag >= 0: return handle_type(a) if self.real <= 0 and self.imag >= 0: return handle_type(pi - a) if self.real >= 0 and self.imag <= 0: return handle_type(-a) if self.real <= 0 and self.imag <= 0: return handle_type(a - pi)
def argument(self): ''' Return the complex argument of a number. ''' from math import pi, atan r, i = abs(self.real), abs(self.imag) a = atan(i / r) if self.real >= 0 and self.imag >= 0: return handle_type(a) if self.real <= 0 and self.imag >= 0: return handle_type(pi - a) if self.real >= 0 and self.imag <= 0: return handle_type(-a) if self.real <= 0 and self.imag <= 0: return handle_type(a - pi)
def __new__(self, x): small = 0.00001 x = complex(x) # Complex numbers sufficiently small in magnitide should be replaced # with zero. if abs(x.real) < small and abs(x.imag) < small: return Integer(0) # Complex numbers very close to Real numbers should be replaced with # the Real number. elif abs(x.imag) < small: return handle_type(x.real) else: a = complex.__new__(self, x) # Do not display brackets in multiplication if a number is close to # the set of imaginary numbers. if abs(x.real) < small: a._hints = {'a'} else: a._hints = {'d','m','p','a'} return a
def __new__(self, x): small = 0.00001 x = complex(x) # Complex numbers sufficiently small in magnitide should be replaced # with zero. if abs(x.real) < small and abs(x.imag) < small: return Integer(0) # Complex numbers very close to Real numbers should be replaced with # the Real number. elif abs(x.imag) < small: return handle_type(x.real) else: a = complex.__new__(self, x) # Do not display brackets in multiplication if a number is close to # the set of imaginary numbers. if abs(x.real) < small: a._hints = {'a'} else: a._hints = {'d', 'm', 'p', 'a'} return a
def __init__(self): # An array of accessible functions self.functions = { # Logarithms 'ln': ln, 'log': lambda a, b=10: dmath.log(a, b), # Trigonometric Functions 'sin': lambda x: handle_type(sin(x)), 'cos': lambda x: handle_type(cos(x)), 'tan': lambda x: handle_type(tan(x)), 'arcsin': lambda x: handle_type(dmath.asin(x)), 'arccos': lambda x: handle_type(dmath.acos(x)), 'arctan': lambda x: handle_type(dmath.atan(x)), 'sinh': lambda x: handle_type(dmath.sinh(x)), 'cosh': lambda x: handle_type(dmath.cosh(x)), 'tanh': lambda x: handle_type(dmath.tanh(x)), 'arcsinh': lambda z: handle_type(log(z + (Integer(1) + z**Integer(2))**Real('0.5'))), 'arccosh': lambda z: ht(log(z + (z + Integer(1))**Real('0.5') * (z - Integer(1))**Real('0.5'))), 'arctanh': lambda z: handle_type(log(Integer(1) + z) - log(Integer(1) - z))/Integer(2), 'degrees': lambda x: handle_type(degrees(x)), # Statistics 'nCr': nCr, 'nPr': nPr, 'binomialpdf': binomialpdf, 'binomialcdf': binomialcdf, 'poissonpdf': poissonpdf, 'poissoncdf': poissoncdf, 'normalcdf': normalcdf, 'mean': lambda a: a.mean(), 'median': lambda a: a.median(), 'mode': lambda a: a.mode(), 'variance': lambda a: a.variance(), 'stdev': lambda a: a.stdev(), 'sxx': lambda a: a.Sxx(), # Manipulation of functions 'expand': expand, 'differentiate': lambda a, b=Symbol('x'):\ partial_differential(a, b), 'integrate': lambda y, a=None, b=None, x=Symbol('x'):\ partial_integral(y, x) if a == None or b == None \ else partial_integral(y, x).limit(a, b, variable=x), 'romberg': lambda f, a, b, *n: f.romberg_integral(a, b, *n), 'trapeziumrule': lambda f, a, b, *n:\ f.trapezoidal_integral(a, b, *n), 'simpsonrule': lambda f, a, b, *n: f.simpson_integral(a, b, *n), 'simpsonthreeeightrule': lambda f, a, b, *n: f.simpson38_integral(a, b, *n), 'roots': lambda a, n=1000: List(*list(a.roots(n))), 'maxima': lambda a, n=100: List(*a.maxima(n)), 'minima': lambda a, n=100: List(*a.minima(n)), # Vectors 'norm': lambda a: a.norm(), # Matrices 'transpose': lambda a: a.transpose(), 'order': lambda a: '{}×{}'.format(*a.order()), 'eval': lambda a, b, c=None: a(b, variable=c), 'identity': identity_matrix, 'diag': diagonal_matrix, 'inv': lambda a: a.inverse(), 'invert': lambda a: a.inverse(), 'decompose': lambda a: List(*a.LU_decomposition()), 'trace': lambda a: a.trace(), 'poly': lambda a: a.characteristic_polynomial(), 'adj': lambda a: a.adjgate(), 'zero': Matrix, 'minor': lambda a, b, c: a.minor(b, c), 'det': lambda a: a.determinant(), 'eigenvalues': lambda a: List(*a.eigenvalues()), 'rank': lambda a: a.rank(), # Complex Numbers 're': lambda a: a.real, 'im': lambda a: a.imag, 'arg': lambda a: a.argument(), 'conj': lambda a: a.conjugate(), # Misc 'yum': pi, 'plot': lambda f, a=-10, b=10: StrWithHtml('testing...', '''<canvas id="{0}" onclick="new CartesianPlot('{0}').simplePlot('{1}',{2},{3})" width="600" height="600">{4}</canvas>'''.format('graph-' + str(random.randint(1, 1000)), f, a, b, gnuplot(f, a, b).html)), 'polarplot': lambda f, a=-pi(), b=pi(): StrWithHtml('testing...', '''<canvas id="{0}" onclick="new PolarPlot('{0}').simplePlot('{1}',{2},{3})" width="600" height="600"></canvas>'''.format('graph-' + str(random.randint(1, 1000)), f, a, b)), 'testcanvas': lambda: StrWithHtml('testing...', '''<canvas id="testcanvas" width="600" height="600"></canvas>'''), 'evalbetween': evalute_between, 'factorial': factorial, 'factors': lambda a: a.factors(), 'decimal': lambda a: Decimal(a) if not isinstance(a, List)\ else List(*list(map(Decimal, a))), 'complex': lambda a: complex(a) if not isinstance(a, List)\ else List(*list(map(complex, a))), 'round': lambda a: handle_type(round), 'list': lambda a: str(list(a)), 'gnuplot': gnuplot, 'type': lambda a: str(type(a)), 'typelist': lambda b: ', '.join(map(lambda a: str(type(a)), b)), 'typematrix': lambda c: '; '.join(map(lambda b: ', '.join(map(lambda a: str(type(a)), b)), c)), 'setprec': self.set_precision, 'setexact': self.set_exact, 'about': lambda:\ StrWithHtml('Copyright Tom Wright <*****@*****.**>', '''<img src="./images/about.png" /> <br>This program was written by Tom Wright <*****@*****.**>'''), 'help': help.help, 'quit': exit, } # An array of accessible post functions self.post_functions = { '!': factorial, 'degs': radians } # An array of standard constants self.consts = { 'pi': pi(), 'g': Real('9.81'), 'h': Real('6.62606896e-34'), } # An array of miscellaneous internal variables such as ans # which stores the previous result self.objects = {'ans': Integer(0)}
# Create an instance of the gnuplot class graph = Gnuplot() # Get the full file name and root_file_name (excluding extension) file_name, root_file_name = graph.file_name, graph.root_file_name # Plot the function graph.plot_function(f, *between) # Return a string / html representation of the graph return StrWithHtml('Image saved to ' + file_name, '''<img src="{}.svg" style="width: 100%" />'''.format(root_file_name)) # Miscellaneous small functions to be used within the calculator pi = lambda: Real(nm.pi()) pi.__doc__ = ''' An anonymous function to calculate the value of pi accurate to the current precision ''' radians = lambda x: x*pi()/handle_type(180) radians.__doc__ = ''' An anonymous function to convert degrees to radians ''' degrees = lambda x: x*handle_type(180)/pi() degrees.__doc__ = ''' An anonymous function to convert radians to degrees ''' wrapped_f = lambda f, g, x: f(x) if isinstance(x, Algebra)\ else handle_type(g(x)) wrapped_f.__doc__ = ''' An anonymous function to evaluate an instance of algebra or convert the output of a standard function to the appropriate type ''' ln = partial(wrapped_f, Ln, dmath.log) ln.__doc__ = ''' A wrapped version of dmath.log ''' sin = partial(wrapped_f, Sin, dmath.sin) sin.__doc__ = ''' A wrapped version of dmath.sin ''' cos = partial(wrapped_f, Cos, dmath.cos)