Merge pull request #17366 from mitodl/pdpinch/complex-calc

Update functions in calc.py to work in complex plane
This commit is contained in:
Ned Batchelder
2018-02-09 15:17:12 -05:00
committed by GitHub
2 changed files with 17 additions and 16 deletions

View File

@@ -30,6 +30,11 @@ from pyparsing import (
import functions
# Functions available by default
# We use scimath variants which give complex results when needed. For example:
# np.sqrt(-4+0j) = 2j
# np.sqrt(-4) = nan, but
# np.lib.scimath.sqrt(-4) = 2j
DEFAULT_FUNCTIONS = {
'sin': numpy.sin,
'cos': numpy.cos,
@@ -37,13 +42,13 @@ DEFAULT_FUNCTIONS = {
'sec': functions.sec,
'csc': functions.csc,
'cot': functions.cot,
'sqrt': numpy.sqrt,
'log10': numpy.log10,
'log2': numpy.log2,
'ln': numpy.log,
'sqrt': numpy.lib.scimath.sqrt,
'log10': numpy.lib.scimath.log10,
'log2': numpy.lib.scimath.log2,
'ln': numpy.lib.scimath.log,
'exp': numpy.exp,
'arccos': numpy.arccos,
'arcsin': numpy.arcsin,
'arccos': numpy.lib.scimath.arccos,
'arcsin': numpy.lib.scimath.arcsin,
'arctan': numpy.arctan,
'arcsec': functions.arcsec,
'arccsc': functions.arccsc,
@@ -59,11 +64,12 @@ DEFAULT_FUNCTIONS = {
'coth': functions.coth,
'arcsinh': numpy.arcsinh,
'arccosh': numpy.arccosh,
'arctanh': numpy.arctanh,
'arctanh': numpy.lib.scimath.arctanh,
'arcsech': functions.arcsech,
'arccsch': functions.arccsch,
'arccoth': functions.arccoth
}
DEFAULT_VARIABLES = {
'i': numpy.complex(0, 1),
'j': numpy.complex(0, 1),

View File

@@ -190,19 +190,14 @@ class EvaluatorTest(unittest.TestCase):
self.assert_function_values('tan', angles, tan_values)
# Include those where the real part is between -pi/2 and pi/2
arcsin_inputs = ['-0.707', '0', '0.5', '0.588', '1.298 + 0.635*j']
arcsin_angles = [-0.785, 0, 0.524, 0.629, 1 + 1j]
arcsin_inputs = ['-0.707', '0', '0.5', '0.588', '1.298 + 0.635*j', '-1.1', '1.1']
arcsin_angles = [-0.785, 0, 0.524, 0.629, 1 + 1j, -1.570 + 0.443j, 1.570 - 0.443j]
self.assert_function_values('arcsin', arcsin_inputs, arcsin_angles)
# Rather than a complex number, numpy.arcsin gives nan
self.assertTrue(numpy.isnan(calc.evaluator({}, {}, 'arcsin(-1.1)')))
self.assertTrue(numpy.isnan(calc.evaluator({}, {}, 'arcsin(1.1)')))
# Include those where the real part is between 0 and pi
arccos_inputs = ['1', '0.866', '0.809', '0.834-0.989*j']
arccos_angles = [0, 0.524, 0.628, 1 + 1j]
arccos_inputs = ['1', '0.866', '0.809', '0.834-0.989*j', '-1.1', '1.1']
arccos_angles = [0, 0.524, 0.628, 1 + 1j, 3.141 - 0.443j, 0.443j]
self.assert_function_values('arccos', arccos_inputs, arccos_angles)
self.assertTrue(numpy.isnan(calc.evaluator({}, {}, 'arccos(-1.1)')))
self.assertTrue(numpy.isnan(calc.evaluator({}, {}, 'arccos(1.1)')))
# Has the same range as arcsin
arctan_inputs = ['-1', '0', '0.577', '0.727', '0.272 + 1.084*j']