# Pynac interface¶

sage.libs.pynac.pynac.doublefactorial(n)

The double factorial combinatorial function:

n!! == n * (n-2) * (n-4) * … * ({1|2}) with 0!! == (-1)!! == 1.

INPUT:

• n – an integer > = 1

EXAMPLES:

sage: from sage.libs.pynac.pynac import doublefactorial
sage: doublefactorial(-1)
1
sage: doublefactorial(0)
1
sage: doublefactorial(1)
1
sage: doublefactorial(5)
15
sage: doublefactorial(20)
3715891200
sage: prod( [20,18,..,2] )
3715891200

sage.libs.pynac.pynac.get_fn_serial()

Return the overall size of the Pynac function registry which corresponds to the last serial value plus one.

EXAMPLES:

sage: from sage.libs.pynac.pynac import get_fn_serial
sage: from sage.symbolic.function import get_sfunction_from_serial
sage: get_fn_serial() > 125
True
sage: print(get_sfunction_from_serial(get_fn_serial()))
None
sage: get_sfunction_from_serial(get_fn_serial() - 1) is not None
True

sage.libs.pynac.pynac.get_ginac_serial()

Number of C++ level functions defined by GiNaC. (Defined mainly for testing.)

EXAMPLES:

sage: sage.libs.pynac.pynac.get_ginac_serial() >= 35
True

sage.libs.pynac.pynac.init_function_table()

Initializes the function pointer table in Pynac. This must be called before Pynac is used; otherwise, there will be segfaults.

sage.libs.pynac.pynac.init_pynac_I()

Initialize the numeric I object in pynac. We use the generator of QQ(i).

EXAMPLES:

sage: from sage.libs.pynac.pynac import I as symbolic_I
sage: symbolic_I
I
sage: symbolic_I^2
-1


Note that conversions to real fields will give TypeErrors:

sage: float(symbolic_I)
Traceback (most recent call last):
...
TypeError: unable to simplify to float approximation
sage: gp(symbolic_I)
I
sage: RR(symbolic_I)
Traceback (most recent call last):
...
TypeError: unable to convert '1.00000000000000*I' to a real number


We can convert to complex fields:

sage: C = ComplexField(200); C
Complex Field with 200 bits of precision
sage: C(symbolic_I)
1.0000000000000000000000000000000000000000000000000000000000*I
sage: symbolic_I._complex_mpfr_field_(ComplexField(53))
1.00000000000000*I

sage: symbolic_I._complex_double_(CDF)
1.0*I
sage: CDF(symbolic_I)
1.0*I

sage: z = symbolic_I + symbolic_I; z
2*I
sage: C(z)
2.0000000000000000000000000000000000000000000000000000000000*I
sage: 1e8*symbolic_I
1.00000000000000e8*I

sage: complex(symbolic_I)
1j

sage: QQbar(symbolic_I)
I

sage: abs(symbolic_I)
1

sage: symbolic_I.minpoly()
x^2 + 1
sage: maxima(2*symbolic_I)
2*%i

sage.libs.pynac.pynac.paramset_from_Expression(e)

EXAMPLES:

sage: from sage.libs.pynac.pynac import paramset_from_Expression
sage: f = function('f')
sage: paramset_from_Expression(f(x).diff(x))
[0L] # 32-bit
[0]  # 64-bit

sage.libs.pynac.pynac.py_atan2_for_doctests(x, y)

Wrapper function to test py_atan2.

sage.libs.pynac.pynac.py_denom_for_doctests(n)

This function is used to test py_denom().

EXAMPLES:

sage: from sage.libs.pynac.pynac import py_denom_for_doctests
sage: py_denom_for_doctests(2/3)
3

sage.libs.pynac.pynac.py_eval_infinity_for_doctests()

This function tests py_eval_infinity.

sage.libs.pynac.pynac.py_eval_neg_infinity_for_doctests()

This function tests py_eval_neg_infinity.

sage.libs.pynac.pynac.py_eval_unsigned_infinity_for_doctests()

This function tests py_eval_unsigned_infinity.

sage.libs.pynac.pynac.py_exp_for_doctests(x)

This function tests py_exp.

EXAMPLES:

sage: from sage.libs.pynac.pynac import py_exp_for_doctests
sage: py_exp_for_doctests(CC(2))
7.38905609893065

sage.libs.pynac.pynac.py_factorial_py(x)

This function is a python wrapper around py_factorial(). This wrapper is needed when we override the eval() method for GiNaC’s factorial function in sage.functions.other.Function_factorial.

sage.libs.pynac.pynac.py_float_for_doctests(n, kwds)

This function is for testing py_float.

EXAMPLES:

sage: from sage.libs.pynac.pynac import py_float_for_doctests
sage: py_float_for_doctests(pi, {'parent':RealField(80)})
3.1415926535897932384626
sage: py_float_for_doctests(I, {'parent':RealField(80)})
1.0000000000000000000000*I
sage: py_float_for_doctests(I, {'parent':float})
1j
sage: py_float_for_doctests(pi, {'parent':complex})
(3.141592653589793+0j)

sage.libs.pynac.pynac.py_imag_for_doctests(x)

Used for doctesting py_imag.

sage.libs.pynac.pynac.py_is_cinteger_for_doctest(x)

Returns True if pynac should treat this object as an element of $$\ZZ(i)$$.

sage.libs.pynac.pynac.py_is_crational_for_doctest(x)

Returns True if pynac should treat this object as an element of $$\QQ(i)$$.

sage.libs.pynac.pynac.py_is_integer_for_doctests(x)

Used internally for doctesting purposes.

sage.libs.pynac.pynac.py_latex_fderivative_for_doctests(id, params, args)

Used internally for writing doctests for certain cdef’d functions.

EXAMPLES:

sage: from sage.libs.pynac.pynac import py_latex_fderivative_for_doctests as py_latex_fderivative, get_ginac_serial, get_fn_serial

sage: var('x,y,z')
(x, y, z)
sage: from sage.symbolic.function import get_sfunction_from_serial
sage: foo = function('foo', nargs=2)
sage: for i in range(get_ginac_serial(), get_fn_serial()):
....:   if get_sfunction_from_serial(i) == foo: break

sage: get_sfunction_from_serial(i) == foo
True
sage: py_latex_fderivative(i, (0, 1, 0, 1), (x, y^z))
\mathrm{D}_{0, 1, 0, 1}\left({\rm foo}\right)\left(x, y^{z}\right)


Test latex_name:

sage: foo = function('foo', nargs=2, latex_name=r'\mathrm{bar}')
sage: for i in range(get_ginac_serial(), get_fn_serial()):
....:   if get_sfunction_from_serial(i) == foo: break

sage: get_sfunction_from_serial(i) == foo
True
sage: py_latex_fderivative(i, (0, 1, 0, 1), (x, y^z))
\mathrm{D}_{0, 1, 0, 1}\left(\mathrm{bar}\right)\left(x, y^{z}\right)


Test custom func:

sage: def my_print(self, *args): return "func_with_args(" + ', '.join(map(repr, args)) +')'
sage: foo = function('foo', nargs=2, print_latex_func=my_print)
sage: for i in range(get_ginac_serial(), get_fn_serial()):
....:   if get_sfunction_from_serial(i) == foo: break

sage: get_sfunction_from_serial(i) == foo
True
sage: py_latex_fderivative(i, (0, 1, 0, 1), (x, y^z))
\mathrm{D}_{0, 1, 0, 1}func_with_args(x, y^z)

sage.libs.pynac.pynac.py_latex_function_pystring(id, args, fname_paren=False)

Return a string with the latex representation of the symbolic function specified by the given id applied to args.

EXAMPLES:

sage: from sage.libs.pynac.pynac import py_latex_function_pystring, get_ginac_serial, get_fn_serial
sage: from sage.symbolic.function import get_sfunction_from_serial
sage: var('x,y,z')
(x, y, z)
sage: foo = function('foo', nargs=2)
sage: for i in range(get_ginac_serial(), get_fn_serial()):
....:   if get_sfunction_from_serial(i) == foo: break

sage: get_sfunction_from_serial(i) == foo
True
sage: py_latex_function_pystring(i, (x,y^z))
'{\\rm foo}\\left(x, y^{z}\\right)'
sage: py_latex_function_pystring(i, (x,y^z), True)
'\\left({\\rm foo}\\right)\\left(x, y^{z}\\right)'
sage: py_latex_function_pystring(i, (int(0),x))
'{\\rm foo}\\left(0, x\\right)'


Test latex_name:

sage: foo = function('foo', nargs=2, latex_name=r'\mathrm{bar}')
sage: for i in range(get_ginac_serial(), get_fn_serial()):
....:   if get_sfunction_from_serial(i) == foo: break

sage: get_sfunction_from_serial(i) == foo
True
sage: py_latex_function_pystring(i, (x,y^z))
'\\mathrm{bar}\\left(x, y^{z}\\right)'


Test custom func:

sage: def my_print(self, *args): return "my args are: " + ', '.join(map(repr, args))
sage: foo = function('foo', nargs=2, print_latex_func=my_print)
sage: for i in range(get_ginac_serial(), get_fn_serial()):
....:   if get_sfunction_from_serial(i) == foo: break

sage: get_sfunction_from_serial(i) == foo
True
sage: py_latex_function_pystring(i, (x,y^z))
'my args are: x, y^z'

sage.libs.pynac.pynac.py_latex_variable_for_doctests(x)

Internal function used so we can doctest a certain cdef’d method.

EXAMPLES:

sage: sage.libs.pynac.pynac.py_latex_variable_for_doctests('x')
x
sage: sage.libs.pynac.pynac.py_latex_variable_for_doctests('sigma')
\sigma

sage.libs.pynac.pynac.py_lgamma_for_doctests(x)

This function tests py_lgamma.

EXAMPLES:

sage: from sage.libs.pynac.pynac import py_lgamma_for_doctests
sage: py_lgamma_for_doctests(CC(I))
-0.650923199301856 - 1.87243664726243*I

sage.libs.pynac.pynac.py_li2_for_doctests(x)

This function is a python wrapper so py_psi2 can be tested. The real tests are in the docstring for py_psi2.

EXAMPLES:

sage: from sage.libs.pynac.pynac import py_li2_for_doctests
sage: py_li2_for_doctests(-1.1)
-0.890838090262283

sage.libs.pynac.pynac.py_li_for_doctests(x, n, parent)

This function is a python wrapper so py_li can be tested. The real tests are in the docstring for py_li.

EXAMPLES:

sage: from sage.libs.pynac.pynac import py_li_for_doctests
sage: py_li_for_doctests(0,2,float)
0.000000000000000

sage.libs.pynac.pynac.py_log_for_doctests(x)

This function tests py_log.

EXAMPLES:

sage: from sage.libs.pynac.pynac import py_log_for_doctests
sage: py_log_for_doctests(CC(e))
1.00000000000000

sage.libs.pynac.pynac.py_mod_for_doctests(x, n)

This function is a python wrapper so py_mod can be tested. The real tests are in the docstring for py_mod.

EXAMPLES:

sage: from sage.libs.pynac.pynac import py_mod_for_doctests
sage: py_mod_for_doctests(5, 2)
1

sage.libs.pynac.pynac.py_numer_for_doctests(n)

This function is used to test py_numer().

EXAMPLES:

sage: from sage.libs.pynac.pynac import py_numer_for_doctests
sage: py_numer_for_doctests(2/3)
2

sage.libs.pynac.pynac.py_print_fderivative_for_doctests(id, params, args)

Used for testing a cdef’d function.

EXAMPLES:

sage: from sage.libs.pynac.pynac import py_print_fderivative_for_doctests as py_print_fderivative, get_ginac_serial, get_fn_serial
sage: var('x,y,z')
(x, y, z)
sage: from sage.symbolic.function import get_sfunction_from_serial
sage: foo = function('foo', nargs=2)
sage: for i in range(get_ginac_serial(), get_fn_serial()):
....:     if get_sfunction_from_serial(i) == foo: break

sage: get_sfunction_from_serial(i) == foo
True
sage: py_print_fderivative(i, (0, 1, 0, 1), (x, y^z))
D[0, 1, 0, 1](foo)(x, y^z)


Test custom print function:

sage: def my_print(self, *args): return "func_with_args(" + ', '.join(map(repr, args)) +')'
sage: foo = function('foo', nargs=2, print_func=my_print)
sage: for i in range(get_ginac_serial(), get_fn_serial()):
....:     if get_sfunction_from_serial(i) == foo: break

sage: get_sfunction_from_serial(i) == foo
True
sage: py_print_fderivative(i, (0, 1, 0, 1), (x, y^z))
D[0, 1, 0, 1]func_with_args(x, y^z)

sage.libs.pynac.pynac.py_print_function_pystring(id, args, fname_paren=False)

Return a string with the representation of the symbolic function specified by the given id applied to args.

INPUT:

• id – serial number of the corresponding symbolic function

• params – Set of parameter numbers with respect to which to take the derivative.

• args – arguments of the function.

EXAMPLES:

sage: from sage.libs.pynac.pynac import py_print_function_pystring, get_ginac_serial, get_fn_serial
sage: from sage.symbolic.function import get_sfunction_from_serial
sage: var('x,y,z')
(x, y, z)
sage: foo = function('foo', nargs=2)
sage: for i in range(get_ginac_serial(), get_fn_serial()):
....:   if get_sfunction_from_serial(i) == foo: break

sage: get_sfunction_from_serial(i) == foo
True
sage: py_print_function_pystring(i, (x,y))
'foo(x, y)'
sage: py_print_function_pystring(i, (x,y), True)
'(foo)(x, y)'
sage: def my_print(self, *args): return "my args are: " + ', '.join(map(repr, args))
sage: foo = function('foo', nargs=2, print_func=my_print)
sage: for i in range(get_ginac_serial(), get_fn_serial()):
....:   if get_sfunction_from_serial(i) == foo: break

sage: get_sfunction_from_serial(i) == foo
True
sage: py_print_function_pystring(i, (x,y))
'my args are: x, y'

sage.libs.pynac.pynac.py_psi2_for_doctests(n, x)

This function is a python wrapper so py_psi2 can be tested. The real tests are in the docstring for py_psi2.

EXAMPLES:

sage: from sage.libs.pynac.pynac import py_psi2_for_doctests
sage: py_psi2_for_doctests(1, 2)
0.644934066848226

sage.libs.pynac.pynac.py_psi_for_doctests(x)

This function is a python wrapper so py_psi can be tested. The real tests are in the docstring for py_psi.

EXAMPLES:

sage: from sage.libs.pynac.pynac import py_psi_for_doctests
sage: py_psi_for_doctests(2)
0.422784335098467

sage.libs.pynac.pynac.py_real_for_doctests(x)

Used for doctesting py_real.

sage.libs.pynac.pynac.py_stieltjes_for_doctests(x)

This function is for testing py_stieltjes().

EXAMPLES:

sage: from sage.libs.pynac.pynac import py_stieltjes_for_doctests
sage: py_stieltjes_for_doctests(0.0)
0.577215664901533

sage.libs.pynac.pynac.py_tgamma_for_doctests(x)

This function is for testing py_tgamma().

sage.libs.pynac.pynac.py_zeta_for_doctests(x)

This function is for testing py_zeta().

EXAMPLES:

sage: from sage.libs.pynac.pynac import py_zeta_for_doctests
sage: py_zeta_for_doctests(CC.0)
0.00330022368532410 - 0.418155449141322*I

sage.libs.pynac.pynac.register_symbol(obj, conversions)

Add an object to the symbol table, along with how to convert it to other systems such as Maxima, Mathematica, etc. This table is used to convert from other systems back to Sage.

INPUT:

• $$obj$$ – a symbolic object or function.

• $$conversions$$ – a dictionary of conversions, where the keys

are the names of interfaces (e.g., ‘maxima’), and the values are the string representation of obj in that system.

EXAMPLES:

sage: sage.libs.pynac.pynac.register_symbol(SR(5),{'maxima':'five'})
sage: SR(maxima_calculus('five'))
5

sage.libs.pynac.pynac.test_binomial(n, k)

The Binomial coefficients. It computes the binomial coefficients. For integer n and k and positive n this is the number of ways of choosing k objects from n distinct objects. If n is negative, the formula binomial(n,k) == (-1)^k*binomial(k-n-1,k) is used to compute the result.

INPUT:

• n, k – integers, with k >= 0.

OUTPUT:

integer

EXAMPLES:

sage: import sage.libs.pynac.pynac
sage: sage.libs.pynac.pynac.test_binomial(5,2)
10
sage: sage.libs.pynac.pynac.test_binomial(-5,3)
-35
sage: -sage.libs.pynac.pynac.test_binomial(3-(-5)-1, 3)
-35

sage.libs.pynac.pynac.tolerant_is_symbol(a)

Utility function to test if something is a symbol.

Returns False for arguments that do not have an is_symbol attribute. Returns the result of calling the is_symbol method otherwise.

EXAMPLES:

sage: from sage.libs.pynac.pynac import tolerant_is_symbol
sage: tolerant_is_symbol(var("x"))
True
sage: tolerant_is_symbol(None)
False
sage: None.is_symbol()
Traceback (most recent call last):
...
AttributeError: 'NoneType' object has no attribute 'is_symbol'

sage.libs.pynac.pynac.unpack_operands(ex)

EXAMPLES:

sage: from sage.libs.pynac.pynac import unpack_operands
sage: t = SR._force_pyobject((1, 2, x, x+1, x+2))
sage: unpack_operands(t)
(1, 2, x, x + 1, x + 2)
sage: type(unpack_operands(t))
<... 'tuple'>
sage: list(map(type, unpack_operands(t)))
[<type 'sage.rings.integer.Integer'>, <type 'sage.rings.integer.Integer'>, <type 'sage.symbolic.expression.Expression'>, <type 'sage.symbolic.expression.Expression'>, <type 'sage.symbolic.expression.Expression'>]
sage: u = SR._force_pyobject((t, x^2))
sage: unpack_operands(u)
((1, 2, x, x + 1, x + 2), x^2)
sage: type(unpack_operands(u)[0])
<... 'tuple'>