Arbitrary precision complex intervals¶
This is a simple complex interval package, using intervals which are axis-aligned rectangles in the complex plane. It has very few special functions, and it does not use any special tricks to keep the size of the intervals down.
AUTHORS:
These authors wrote complex_mpfr.pyx
(renamed from complex_number.pyx
):
- William Stein (2006-01-26): complete rewrite
- Joel B. Mohler (2006-12-16): naive rewrite into pyrex
- William Stein(2007-01): rewrite of Mohler's rewrite
Then complex_number.pyx
was copied to complex_interval.pyx
and
heavily modified:
Carl Witty (2007-10-24): rewrite to become a complex interval package
Travis Scrimshaw (2012-10-18): Added documentation to get full coverage.
Warning
Mixing symbolic expressions with intervals (in particular, converting constant symbolic expressions to intervals), can lead to incorrect results:
sage: ref = ComplexIntervalField(100)(ComplexBallField(100).one().airy_ai())
sage: ref
0.135292416312881415524147423515?
sage: val = CIF(airy_ai(1)); val # known bug
0.13529241631288142?
sage: val.overlaps(ref) # known bug
False
>>> from sage.all import *
>>> ref = ComplexIntervalField(Integer(100))(ComplexBallField(Integer(100)).one().airy_ai())
>>> ref
0.135292416312881415524147423515?
>>> val = CIF(airy_ai(Integer(1))); val # known bug
0.13529241631288142?
>>> val.overlaps(ref) # known bug
False
ref = ComplexIntervalField(100)(ComplexBallField(100).one().airy_ai()) ref val = CIF(airy_ai(1)); val # known bug val.overlaps(ref) # known bug
Todo
Implement ComplexIntervalFieldElement
multiplicative
order similar to ComplexNumber
multiplicative
order with _set_multiplicative_order(n)
and
ComplexNumber.multiplicative_order()
methods.
- class sage.rings.complex_interval.ComplexIntervalFieldElement[source]¶
Bases:
FieldElement
A complex interval.
EXAMPLES:
sage: I = CIF.gen() sage: b = 3/2 + 5/2*I sage: TestSuite(b).run()
>>> from sage.all import * >>> I = CIF.gen() >>> b = Integer(3)/Integer(2) + Integer(5)/Integer(2)*I >>> TestSuite(b).run()
I = CIF.gen() b = 3/2 + 5/2*I TestSuite(b).run()
- arg()[source]¶
Same as
argument()
.EXAMPLES:
sage: i = CIF.0 sage: (i^2).arg() 3.141592653589794?
>>> from sage.all import * >>> i = CIF.gen(0) >>> (i**Integer(2)).arg() 3.141592653589794?
i = CIF.0 (i^2).arg()
- argument()[source]¶
The argument (angle) of the complex number, normalized so that \(-\pi < \theta.lower() \leq \pi\).
We raise a
ValueError
if the interval strictly contains 0, or if the interval contains only 0.Warning
We do not always use the standard branch cut for argument! If the interval crosses the negative real axis, then the argument will be an interval whose lower bound is less than \(\pi\) and whose upper bound is more than \(\pi\); in effect, we move the branch cut away from the interval.
EXAMPLES:
sage: i = CIF.0 sage: (i^2).argument() 3.141592653589794? sage: (1+i).argument() 0.785398163397449? sage: i.argument() 1.570796326794897? sage: (-i).argument() -1.570796326794897? sage: (-1/1000 - i).argument() -1.571796326461564? sage: CIF(2).argument() 0 sage: CIF(-2).argument() 3.141592653589794?
>>> from sage.all import * >>> i = CIF.gen(0) >>> (i**Integer(2)).argument() 3.141592653589794? >>> (Integer(1)+i).argument() 0.785398163397449? >>> i.argument() 1.570796326794897? >>> (-i).argument() -1.570796326794897? >>> (-Integer(1)/Integer(1000) - i).argument() -1.571796326461564? >>> CIF(Integer(2)).argument() 0 >>> CIF(-Integer(2)).argument() 3.141592653589794?
i = CIF.0 (i^2).argument() (1+i).argument() i.argument() (-i).argument() (-1/1000 - i).argument() CIF(2).argument() CIF(-2).argument()
Here we see that if the interval crosses the negative real axis, then the argument can exceed \(\pi\), and we we violate the standard interval guarantees in the process:
sage: CIF(-2, RIF(-0.1, 0.1)).argument().str(style='brackets') '[3.0916342578678501 .. 3.1915510493117365]' sage: CIF(-2, -0.1).argument() -3.091634257867851?
>>> from sage.all import * >>> CIF(-Integer(2), RIF(-RealNumber('0.1'), RealNumber('0.1'))).argument().str(style='brackets') '[3.0916342578678501 .. 3.1915510493117365]' >>> CIF(-Integer(2), -RealNumber('0.1')).argument() -3.091634257867851?
CIF(-2, RIF(-0.1, 0.1)).argument().str(style='brackets') CIF(-2, -0.1).argument()
- bisection()[source]¶
Return the bisection of
self
into four intervals whose union isself
and intersection iscenter()
.EXAMPLES:
sage: z = CIF(RIF(2, 3), RIF(-5, -4)) sage: z.bisection() (3.? - 5.?*I, 3.? - 5.?*I, 3.? - 5.?*I, 3.? - 5.?*I) sage: for z in z.bisection(): ....: print(z.real().endpoints()) ....: print(z.imag().endpoints()) (2.00000000000000, 2.50000000000000) (-5.00000000000000, -4.50000000000000) (2.50000000000000, 3.00000000000000) (-5.00000000000000, -4.50000000000000) (2.00000000000000, 2.50000000000000) (-4.50000000000000, -4.00000000000000) (2.50000000000000, 3.00000000000000) (-4.50000000000000, -4.00000000000000) sage: # needs sage.symbolic sage: z = CIF(RIF(sqrt(2), sqrt(3)), RIF(e, pi)) sage: a, b, c, d = z.bisection() sage: a.intersection(b).intersection(c).intersection(d) == CIF(z.center()) True sage: zz = a.union(b).union(c).union(c) sage: zz.real().endpoints() == z.real().endpoints() True sage: zz.imag().endpoints() == z.imag().endpoints() True
>>> from sage.all import * >>> z = CIF(RIF(Integer(2), Integer(3)), RIF(-Integer(5), -Integer(4))) >>> z.bisection() (3.? - 5.?*I, 3.? - 5.?*I, 3.? - 5.?*I, 3.? - 5.?*I) >>> for z in z.bisection(): ... print(z.real().endpoints()) ... print(z.imag().endpoints()) (2.00000000000000, 2.50000000000000) (-5.00000000000000, -4.50000000000000) (2.50000000000000, 3.00000000000000) (-5.00000000000000, -4.50000000000000) (2.00000000000000, 2.50000000000000) (-4.50000000000000, -4.00000000000000) (2.50000000000000, 3.00000000000000) (-4.50000000000000, -4.00000000000000) >>> # needs sage.symbolic >>> z = CIF(RIF(sqrt(Integer(2)), sqrt(Integer(3))), RIF(e, pi)) >>> a, b, c, d = z.bisection() >>> a.intersection(b).intersection(c).intersection(d) == CIF(z.center()) True >>> zz = a.union(b).union(c).union(c) >>> zz.real().endpoints() == z.real().endpoints() True >>> zz.imag().endpoints() == z.imag().endpoints() True
z = CIF(RIF(2, 3), RIF(-5, -4)) z.bisection() for z in z.bisection(): print(z.real().endpoints()) print(z.imag().endpoints()) # needs sage.symbolic z = CIF(RIF(sqrt(2), sqrt(3)), RIF(e, pi)) a, b, c, d = z.bisection() a.intersection(b).intersection(c).intersection(d) == CIF(z.center()) zz = a.union(b).union(c).union(c) zz.real().endpoints() == z.real().endpoints() zz.imag().endpoints() == z.imag().endpoints()
- center()[source]¶
Return the closest floating-point approximation to the center of the interval.
EXAMPLES:
sage: CIF(RIF(1, 2), RIF(3, 4)).center() 1.50000000000000 + 3.50000000000000*I
>>> from sage.all import * >>> CIF(RIF(Integer(1), Integer(2)), RIF(Integer(3), Integer(4))).center() 1.50000000000000 + 3.50000000000000*I
CIF(RIF(1, 2), RIF(3, 4)).center()
- conjugate()[source]¶
Return the complex conjugate of this complex number.
EXAMPLES:
sage: i = CIF.0 sage: (1+i).conjugate() 1 - 1*I
>>> from sage.all import * >>> i = CIF.gen(0) >>> (Integer(1)+i).conjugate() 1 - 1*I
i = CIF.0 (1+i).conjugate()
- contains_zero()[source]¶
Return
True
ifself
is an interval containing zero.EXAMPLES:
sage: CIF(0).contains_zero() True sage: CIF(RIF(-1, 1), 1).contains_zero() False
>>> from sage.all import * >>> CIF(Integer(0)).contains_zero() True >>> CIF(RIF(-Integer(1), Integer(1)), Integer(1)).contains_zero() False
CIF(0).contains_zero() CIF(RIF(-1, 1), 1).contains_zero()
- cos()[source]¶
Compute the cosine of this complex interval.
EXAMPLES:
sage: CIF(1,1).cos() 0.833730025131149? - 0.988897705762865?*I sage: CIF(3).cos() -0.9899924966004455? sage: CIF(0,2).cos() 3.762195691083632?
>>> from sage.all import * >>> CIF(Integer(1),Integer(1)).cos() 0.833730025131149? - 0.988897705762865?*I >>> CIF(Integer(3)).cos() -0.9899924966004455? >>> CIF(Integer(0),Integer(2)).cos() 3.762195691083632?
CIF(1,1).cos() CIF(3).cos() CIF(0,2).cos()
Check that Issue #17285 is fixed:
sage: CIF(cos(2/3)) # needs sage.symbolic 0.7858872607769480?
>>> from sage.all import * >>> CIF(cos(Integer(2)/Integer(3))) # needs sage.symbolic 0.7858872607769480?
CIF(cos(2/3)) # needs sage.symbolic
ALGORITHM:
The implementation uses the following trigonometric identity
\[\cos(x + iy) = \cos(x) \cosh(y) - i \sin(x) \sinh(y)\]
- cosh()[source]¶
Return the hyperbolic cosine of this complex interval.
EXAMPLES:
sage: CIF(1,1).cosh() 0.833730025131149? + 0.988897705762865?*I sage: CIF(2).cosh() 3.762195691083632? sage: CIF(0,2).cosh() -0.4161468365471424?
>>> from sage.all import * >>> CIF(Integer(1),Integer(1)).cosh() 0.833730025131149? + 0.988897705762865?*I >>> CIF(Integer(2)).cosh() 3.762195691083632? >>> CIF(Integer(0),Integer(2)).cosh() -0.4161468365471424?
CIF(1,1).cosh() CIF(2).cosh() CIF(0,2).cosh()
ALGORITHM:
The implementation uses the following trigonometric identity
\[\cosh(x+iy) = \cos(y) \cosh(x) + i \sin(y) \sinh(x)\]
- crosses_log_branch_cut()[source]¶
Return
True
if this interval crosses the standard branch cut forlog()
(and hence for exponentiation) and for argument. (Recall that this branch cut is infinitesimally below the negative portion of the real axis.)EXAMPLES:
sage: z = CIF(1.5, 2.5) - CIF(0, 2.50000000000000001); z 1.5000000000000000? + -1.?e-15*I sage: z.crosses_log_branch_cut() False sage: CIF(-2, RIF(-0.1, 0.1)).crosses_log_branch_cut() True
>>> from sage.all import * >>> z = CIF(RealNumber('1.5'), RealNumber('2.5')) - CIF(Integer(0), RealNumber('2.50000000000000001')); z 1.5000000000000000? + -1.?e-15*I >>> z.crosses_log_branch_cut() False >>> CIF(-Integer(2), RIF(-RealNumber('0.1'), RealNumber('0.1'))).crosses_log_branch_cut() True
z = CIF(1.5, 2.5) - CIF(0, 2.50000000000000001); z z.crosses_log_branch_cut() CIF(-2, RIF(-0.1, 0.1)).crosses_log_branch_cut()
- diameter()[source]¶
Return a somewhat-arbitrarily defined “diameter” for this interval.
The diameter of an interval is the maximum of the diameter of the real and imaginary components, where diameter on a real interval is defined as absolute diameter if the interval contains zero, and relative diameter otherwise.
EXAMPLES:
sage: CIF(RIF(-1, 1), RIF(13, 17)).diameter() 2.00000000000000 sage: CIF(RIF(-0.1, 0.1), RIF(13, 17)).diameter() 0.266666666666667 sage: CIF(RIF(-1, 1), 15).diameter() 2.00000000000000
>>> from sage.all import * >>> CIF(RIF(-Integer(1), Integer(1)), RIF(Integer(13), Integer(17))).diameter() 2.00000000000000 >>> CIF(RIF(-RealNumber('0.1'), RealNumber('0.1')), RIF(Integer(13), Integer(17))).diameter() 0.266666666666667 >>> CIF(RIF(-Integer(1), Integer(1)), Integer(15)).diameter() 2.00000000000000
CIF(RIF(-1, 1), RIF(13, 17)).diameter() CIF(RIF(-0.1, 0.1), RIF(13, 17)).diameter() CIF(RIF(-1, 1), 15).diameter()
- edges()[source]¶
Return the 4 edges of the rectangle in the complex plane defined by this interval as intervals.
OUTPUT: a 4-tuple of complex intervals (left edge, right edge, lower edge, upper edge)
See also
endpoints()
which returns the 4 corners of the rectangle.EXAMPLES:
sage: CIF(RIF(1,2), RIF(3,4)).edges() (1 + 4.?*I, 2 + 4.?*I, 2.? + 3*I, 2.? + 4*I) sage: ComplexIntervalField(20)(-2).log().edges() (0.69314671? + 3.14160?*I, 0.69314766? + 3.14160?*I, 0.693147? + 3.1415902?*I, 0.693147? + 3.1415940?*I)
>>> from sage.all import * >>> CIF(RIF(Integer(1),Integer(2)), RIF(Integer(3),Integer(4))).edges() (1 + 4.?*I, 2 + 4.?*I, 2.? + 3*I, 2.? + 4*I) >>> ComplexIntervalField(Integer(20))(-Integer(2)).log().edges() (0.69314671? + 3.14160?*I, 0.69314766? + 3.14160?*I, 0.693147? + 3.1415902?*I, 0.693147? + 3.1415940?*I)
CIF(RIF(1,2), RIF(3,4)).edges() ComplexIntervalField(20)(-2).log().edges()
- endpoints()[source]¶
Return the 4 corners of the rectangle in the complex plane defined by this interval.
OUTPUT: a 4-tuple of complex numbers (lower left, upper right, upper left, lower right)
See also
edges()
which returns the 4 edges of the rectangle.EXAMPLES:
sage: CIF(RIF(1,2), RIF(3,4)).endpoints() (1.00000000000000 + 3.00000000000000*I, 2.00000000000000 + 4.00000000000000*I, 1.00000000000000 + 4.00000000000000*I, 2.00000000000000 + 3.00000000000000*I) sage: ComplexIntervalField(20)(-2).log().endpoints() (0.69315 + 3.1416*I, 0.69315 + 3.1416*I, 0.69315 + 3.1416*I, 0.69315 + 3.1416*I)
>>> from sage.all import * >>> CIF(RIF(Integer(1),Integer(2)), RIF(Integer(3),Integer(4))).endpoints() (1.00000000000000 + 3.00000000000000*I, 2.00000000000000 + 4.00000000000000*I, 1.00000000000000 + 4.00000000000000*I, 2.00000000000000 + 3.00000000000000*I) >>> ComplexIntervalField(Integer(20))(-Integer(2)).log().endpoints() (0.69315 + 3.1416*I, 0.69315 + 3.1416*I, 0.69315 + 3.1416*I, 0.69315 + 3.1416*I)
CIF(RIF(1,2), RIF(3,4)).endpoints() ComplexIntervalField(20)(-2).log().endpoints()
- exp()[source]¶
Compute \(e^z\) or \(\exp(z)\) where \(z\) is the complex number
self
.EXAMPLES:
sage: i = ComplexIntervalField(300).0 sage: z = 1 + i sage: z.exp() 1.46869393991588515713896759732660426132695673662900872279767567631093696585951213872272450? + 2.28735528717884239120817190670050180895558625666835568093865811410364716018934540926734485?*I
>>> from sage.all import * >>> i = ComplexIntervalField(Integer(300)).gen(0) >>> z = Integer(1) + i >>> z.exp() 1.46869393991588515713896759732660426132695673662900872279767567631093696585951213872272450? + 2.28735528717884239120817190670050180895558625666835568093865811410364716018934540926734485?*I
i = ComplexIntervalField(300).0 z = 1 + i z.exp()
- imag()[source]¶
Return imaginary part of
self
.EXAMPLES:
sage: i = ComplexIntervalField(100).0 sage: z = 2 + 3*i sage: x = z.imag(); x 3 sage: x.parent() Real Interval Field with 100 bits of precision
>>> from sage.all import * >>> i = ComplexIntervalField(Integer(100)).gen(0) >>> z = Integer(2) + Integer(3)*i >>> x = z.imag(); x 3 >>> x.parent() Real Interval Field with 100 bits of precision
i = ComplexIntervalField(100).0 z = 2 + 3*i x = z.imag(); x x.parent()
- intersection(other)[source]¶
Return the intersection of the two complex intervals
self
andother
.EXAMPLES:
sage: CIF(RIF(1, 3), RIF(1, 3)).intersection(CIF(RIF(2, 4), RIF(2, 4))).str(style='brackets') '[2.0000000000000000 .. 3.0000000000000000] + [2.0000000000000000 .. 3.0000000000000000]*I' sage: CIF(RIF(1, 2), RIF(1, 3)).intersection(CIF(RIF(3, 4), RIF(2, 4))) Traceback (most recent call last): ... ValueError: intersection of non-overlapping intervals
>>> from sage.all import * >>> CIF(RIF(Integer(1), Integer(3)), RIF(Integer(1), Integer(3))).intersection(CIF(RIF(Integer(2), Integer(4)), RIF(Integer(2), Integer(4)))).str(style='brackets') '[2.0000000000000000 .. 3.0000000000000000] + [2.0000000000000000 .. 3.0000000000000000]*I' >>> CIF(RIF(Integer(1), Integer(2)), RIF(Integer(1), Integer(3))).intersection(CIF(RIF(Integer(3), Integer(4)), RIF(Integer(2), Integer(4)))) Traceback (most recent call last): ... ValueError: intersection of non-overlapping intervals
CIF(RIF(1, 3), RIF(1, 3)).intersection(CIF(RIF(2, 4), RIF(2, 4))).str(style='brackets') CIF(RIF(1, 2), RIF(1, 3)).intersection(CIF(RIF(3, 4), RIF(2, 4)))
- is_NaN()[source]¶
Return
True
if this is not-a-number.EXAMPLES:
sage: CIF(2, 1).is_NaN() False sage: CIF(NaN).is_NaN() # needs sage.symbolic True sage: (1 / CIF(0, 0)).is_NaN() True
>>> from sage.all import * >>> CIF(Integer(2), Integer(1)).is_NaN() False >>> CIF(NaN).is_NaN() # needs sage.symbolic True >>> (Integer(1) / CIF(Integer(0), Integer(0))).is_NaN() True
CIF(2, 1).is_NaN() CIF(NaN).is_NaN() # needs sage.symbolic (1 / CIF(0, 0)).is_NaN()
- is_exact()[source]¶
Return whether this complex interval is exact (i.e. contains exactly one complex value).
EXAMPLES:
sage: CIF(3).is_exact() True sage: CIF(0, 2).is_exact() True sage: CIF(-4, 0).sqrt().is_exact() True sage: CIF(-5, 0).sqrt().is_exact() False sage: CIF(0, 2*pi).is_exact() # needs sage.symbolic False sage: CIF(e).is_exact() # needs sage.symbolic False sage: CIF(1e100).is_exact() True sage: (CIF(1e100) + 1).is_exact() False
>>> from sage.all import * >>> CIF(Integer(3)).is_exact() True >>> CIF(Integer(0), Integer(2)).is_exact() True >>> CIF(-Integer(4), Integer(0)).sqrt().is_exact() True >>> CIF(-Integer(5), Integer(0)).sqrt().is_exact() False >>> CIF(Integer(0), Integer(2)*pi).is_exact() # needs sage.symbolic False >>> CIF(e).is_exact() # needs sage.symbolic False >>> CIF(RealNumber('1e100')).is_exact() True >>> (CIF(RealNumber('1e100')) + Integer(1)).is_exact() False
CIF(3).is_exact() CIF(0, 2).is_exact() CIF(-4, 0).sqrt().is_exact() CIF(-5, 0).sqrt().is_exact() CIF(0, 2*pi).is_exact() # needs sage.symbolic CIF(e).is_exact() # needs sage.symbolic CIF(1e100).is_exact() (CIF(1e100) + 1).is_exact()
- is_square()[source]¶
Return
True
as \(\CC\) is algebraically closed.EXAMPLES:
sage: CIF(2, 1).is_square() True
>>> from sage.all import * >>> CIF(Integer(2), Integer(1)).is_square() True
CIF(2, 1).is_square()
- lexico_cmp(left, right)[source]¶
Intervals are compared lexicographically on the 4-tuple:
(x.real().lower(), x.real().upper(), x.imag().lower(), x.imag().upper())
EXAMPLES:
sage: a = CIF(RIF(0,1), RIF(0,1)) sage: b = CIF(RIF(0,1), RIF(0,2)) sage: c = CIF(RIF(0,2), RIF(0,2)) sage: a.lexico_cmp(b) -1 sage: b.lexico_cmp(c) -1 sage: a.lexico_cmp(c) -1 sage: a.lexico_cmp(a) 0 sage: b.lexico_cmp(a) 1
>>> from sage.all import * >>> a = CIF(RIF(Integer(0),Integer(1)), RIF(Integer(0),Integer(1))) >>> b = CIF(RIF(Integer(0),Integer(1)), RIF(Integer(0),Integer(2))) >>> c = CIF(RIF(Integer(0),Integer(2)), RIF(Integer(0),Integer(2))) >>> a.lexico_cmp(b) -1 >>> b.lexico_cmp(c) -1 >>> a.lexico_cmp(c) -1 >>> a.lexico_cmp(a) 0 >>> b.lexico_cmp(a) 1
a = CIF(RIF(0,1), RIF(0,1)) b = CIF(RIF(0,1), RIF(0,2)) c = CIF(RIF(0,2), RIF(0,2)) a.lexico_cmp(b) b.lexico_cmp(c) a.lexico_cmp(c) a.lexico_cmp(a) b.lexico_cmp(a)
- log(base=None)[source]¶
Complex logarithm of \(z\).
Warning
This does always not use the standard branch cut for complex log! See the docstring for
argument()
to see what we do instead.EXAMPLES:
sage: a = CIF(RIF(3, 4), RIF(13, 14)) sage: a.log().str(style='brackets') '[2.5908917751460420 .. 2.6782931373360067] + [1.2722973952087170 .. 1.3597029935721503]*I' sage: a.log().exp().str(style='brackets') '[2.7954667135098274 .. 4.2819545928390213] + [12.751682453911920 .. 14.237018048974635]*I' sage: a in a.log().exp() True
>>> from sage.all import * >>> a = CIF(RIF(Integer(3), Integer(4)), RIF(Integer(13), Integer(14))) >>> a.log().str(style='brackets') '[2.5908917751460420 .. 2.6782931373360067] + [1.2722973952087170 .. 1.3597029935721503]*I' >>> a.log().exp().str(style='brackets') '[2.7954667135098274 .. 4.2819545928390213] + [12.751682453911920 .. 14.237018048974635]*I' >>> a in a.log().exp() True
a = CIF(RIF(3, 4), RIF(13, 14)) a.log().str(style='brackets') a.log().exp().str(style='brackets') a in a.log().exp()
If the interval crosses the negative real axis, then we don’t use the standard branch cut (and we violate the interval guarantees):
sage: CIF(-3, RIF(-1/4, 1/4)).log().str(style='brackets') '[1.0986122886681095 .. 1.1020725100903968] + [3.0584514217013518 .. 3.2247338854782349]*I' sage: CIF(-3, -1/4).log() 1.102072510090397? - 3.058451421701352?*I
>>> from sage.all import * >>> CIF(-Integer(3), RIF(-Integer(1)/Integer(4), Integer(1)/Integer(4))).log().str(style='brackets') '[1.0986122886681095 .. 1.1020725100903968] + [3.0584514217013518 .. 3.2247338854782349]*I' >>> CIF(-Integer(3), -Integer(1)/Integer(4)).log() 1.102072510090397? - 3.058451421701352?*I
CIF(-3, RIF(-1/4, 1/4)).log().str(style='brackets') CIF(-3, -1/4).log()
Usually if an interval contains zero, we raise an exception:
sage: CIF(RIF(-1,1),RIF(-1,1)).log() Traceback (most recent call last): ... ValueError: Can...t take the argument of interval strictly containing zero
>>> from sage.all import * >>> CIF(RIF(-Integer(1),Integer(1)),RIF(-Integer(1),Integer(1))).log() Traceback (most recent call last): ... ValueError: Can...t take the argument of interval strictly containing zero
CIF(RIF(-1,1),RIF(-1,1)).log()
But we allow the exact input zero:
sage: CIF(0).log() [-infinity .. -infinity]
>>> from sage.all import * >>> CIF(Integer(0)).log() [-infinity .. -infinity]
CIF(0).log()
If a base is passed from another function, we can accommodate this:
sage: CIF(-1,1).log(2) 0.500000000000000? + 3.39927010637040?*I
>>> from sage.all import * >>> CIF(-Integer(1),Integer(1)).log(Integer(2)) 0.500000000000000? + 3.39927010637040?*I
CIF(-1,1).log(2)
- magnitude()[source]¶
The largest absolute value of the elements of the interval, rounded away from zero.
OUTPUT: a real number with rounding mode
RNDU
EXAMPLES:
sage: CIF(RIF(-1,1), RIF(-1,1)).magnitude() 1.41421356237310 sage: CIF(RIF(1,2), RIF(3,4)).magnitude() 4.47213595499958 sage: parent(CIF(1).magnitude()) Real Field with 53 bits of precision and rounding RNDU
>>> from sage.all import * >>> CIF(RIF(-Integer(1),Integer(1)), RIF(-Integer(1),Integer(1))).magnitude() 1.41421356237310 >>> CIF(RIF(Integer(1),Integer(2)), RIF(Integer(3),Integer(4))).magnitude() 4.47213595499958 >>> parent(CIF(Integer(1)).magnitude()) Real Field with 53 bits of precision and rounding RNDU
CIF(RIF(-1,1), RIF(-1,1)).magnitude() CIF(RIF(1,2), RIF(3,4)).magnitude() parent(CIF(1).magnitude())
- mignitude()[source]¶
The smallest absolute value of the elements of the interval, rounded towards zero.
OUTPUT: a real number with rounding mode
RNDD
EXAMPLES:
sage: CIF(RIF(-1,1), RIF(-1,1)).mignitude() 0.000000000000000 sage: CIF(RIF(1,2), RIF(3,4)).mignitude() 3.16227766016837 sage: parent(CIF(1).mignitude()) Real Field with 53 bits of precision and rounding RNDD
>>> from sage.all import * >>> CIF(RIF(-Integer(1),Integer(1)), RIF(-Integer(1),Integer(1))).mignitude() 0.000000000000000 >>> CIF(RIF(Integer(1),Integer(2)), RIF(Integer(3),Integer(4))).mignitude() 3.16227766016837 >>> parent(CIF(Integer(1)).mignitude()) Real Field with 53 bits of precision and rounding RNDD
CIF(RIF(-1,1), RIF(-1,1)).mignitude() CIF(RIF(1,2), RIF(3,4)).mignitude() parent(CIF(1).mignitude())
- multiplicative_order()[source]¶
Return the multiplicative order of this complex number, if known, or raise a
NotImplementedError
.EXAMPLES:
sage: C = CIF sage: i = C.0 sage: i.multiplicative_order() 4 sage: C(1).multiplicative_order() 1 sage: C(-1).multiplicative_order() 2 sage: (i^2).multiplicative_order() 2 sage: (-i).multiplicative_order() 4 sage: C(2).multiplicative_order() +Infinity sage: w = (1 + C(-3).sqrt())/2 ; w 0.50000000000000000? + 0.866025403784439?*I sage: w.multiplicative_order() Traceback (most recent call last): ... NotImplementedError: order of element not known
>>> from sage.all import * >>> C = CIF >>> i = C.gen(0) >>> i.multiplicative_order() 4 >>> C(Integer(1)).multiplicative_order() 1 >>> C(-Integer(1)).multiplicative_order() 2 >>> (i**Integer(2)).multiplicative_order() 2 >>> (-i).multiplicative_order() 4 >>> C(Integer(2)).multiplicative_order() +Infinity >>> w = (Integer(1) + C(-Integer(3)).sqrt())/Integer(2) ; w 0.50000000000000000? + 0.866025403784439?*I >>> w.multiplicative_order() Traceback (most recent call last): ... NotImplementedError: order of element not known
C = CIF i = C.0 i.multiplicative_order() C(1).multiplicative_order() C(-1).multiplicative_order() (i^2).multiplicative_order() (-i).multiplicative_order() C(2).multiplicative_order() w = (1 + C(-3).sqrt())/2 ; w w.multiplicative_order()
- norm()[source]¶
Return the norm of this complex number.
If \(c = a + bi\) is a complex number, then the norm of \(c\) is defined as the product of \(c\) and its complex conjugate:
\[\text{norm}(c) = \text{norm}(a + bi) = c \cdot \overline{c} = a^2 + b^2.\]The norm of a complex number is different from its absolute value. The absolute value of a complex number is defined to be the square root of its norm. A typical use of the complex norm is in the integral domain \(\ZZ[i]\) of Gaussian integers, where the norm of each Gaussian integer \(c = a + bi\) is defined as its complex norm.
EXAMPLES:
sage: CIF(2, 1).norm() 5 sage: CIF(1, -2).norm() 5
>>> from sage.all import * >>> CIF(Integer(2), Integer(1)).norm() 5 >>> CIF(Integer(1), -Integer(2)).norm() 5
CIF(2, 1).norm() CIF(1, -2).norm()
- overlaps(other)[source]¶
Return
True
ifself
andother
are intervals with at least one value in common.EXAMPLES:
sage: CIF(0).overlaps(CIF(RIF(0, 1), RIF(-1, 0))) True sage: CIF(1).overlaps(CIF(1, 1)) False
>>> from sage.all import * >>> CIF(Integer(0)).overlaps(CIF(RIF(Integer(0), Integer(1)), RIF(-Integer(1), Integer(0)))) True >>> CIF(Integer(1)).overlaps(CIF(Integer(1), Integer(1))) False
CIF(0).overlaps(CIF(RIF(0, 1), RIF(-1, 0))) CIF(1).overlaps(CIF(1, 1))
- plot(pointsize=10, **kwds)[source]¶
Plot a complex interval as a rectangle.
EXAMPLES:
sage: sum(plot(CIF(RIF(1/k, 1/k), RIF(-k, k))) for k in [1..10]) # needs sage.plot Graphics object consisting of 20 graphics primitives
>>> from sage.all import * >>> sum(plot(CIF(RIF(Integer(1)/k, Integer(1)/k), RIF(-k, k))) for k in (ellipsis_range(Integer(1),Ellipsis,Integer(10)))) # needs sage.plot Graphics object consisting of 20 graphics primitives
sum(plot(CIF(RIF(1/k, 1/k), RIF(-k, k))) for k in [1..10]) # needs sage.plot
Exact and nearly exact points are still visible:
sage: # needs sage.plot sage.symbolic sage: plot(CIF(pi, 1), color='red') + plot(CIF(1, e), color='purple') + plot(CIF(-1, -1)) Graphics object consisting of 6 graphics primitives
>>> from sage.all import * >>> # needs sage.plot sage.symbolic >>> plot(CIF(pi, Integer(1)), color='red') + plot(CIF(Integer(1), e), color='purple') + plot(CIF(-Integer(1), -Integer(1))) Graphics object consisting of 6 graphics primitives
# needs sage.plot sage.symbolic plot(CIF(pi, 1), color='red') + plot(CIF(1, e), color='purple') + plot(CIF(-1, -1))
A demonstration that \(z \mapsto z^2\) acts chaotically on \(|z|=1\):
sage: # needs sage.plot sage.symbolic sage: z = CIF(0, 2*pi/1000).exp() sage: g = Graphics() sage: for i in range(40): ....: z = z^2 ....: g += z.plot(color=(1./(40-i), 0, 1)) ... sage: g Graphics object consisting of 80 graphics primitives
>>> from sage.all import * >>> # needs sage.plot sage.symbolic >>> z = CIF(Integer(0), Integer(2)*pi/Integer(1000)).exp() >>> g = Graphics() >>> for i in range(Integer(40)): ... z = z**Integer(2) ... g += z.plot(color=(RealNumber('1.')/(Integer(40)-i), Integer(0), Integer(1))) ... >>> g Graphics object consisting of 80 graphics primitives
# needs sage.plot sage.symbolic z = CIF(0, 2*pi/1000).exp() g = Graphics() for i in range(40): z = z^2 g += z.plot(color=(1./(40-i), 0, 1)) g
- prec()[source]¶
Return precision of this complex number.
EXAMPLES:
sage: i = ComplexIntervalField(2000).0 sage: i.prec() 2000
>>> from sage.all import * >>> i = ComplexIntervalField(Integer(2000)).gen(0) >>> i.prec() 2000
i = ComplexIntervalField(2000).0 i.prec()
- real()[source]¶
Return real part of
self
.EXAMPLES:
sage: i = ComplexIntervalField(100).0 sage: z = 2 + 3*i sage: x = z.real(); x 2 sage: x.parent() Real Interval Field with 100 bits of precision
>>> from sage.all import * >>> i = ComplexIntervalField(Integer(100)).gen(0) >>> z = Integer(2) + Integer(3)*i >>> x = z.real(); x 2 >>> x.parent() Real Interval Field with 100 bits of precision
i = ComplexIntervalField(100).0 z = 2 + 3*i x = z.real(); x x.parent()
- sin()[source]¶
Compute the sine of this complex interval.
EXAMPLES:
sage: CIF(1,1).sin() 1.298457581415978? + 0.634963914784736?*I sage: CIF(2).sin() 0.909297426825682? sage: CIF(0,2).sin() 3.626860407847019?*I
>>> from sage.all import * >>> CIF(Integer(1),Integer(1)).sin() 1.298457581415978? + 0.634963914784736?*I >>> CIF(Integer(2)).sin() 0.909297426825682? >>> CIF(Integer(0),Integer(2)).sin() 3.626860407847019?*I
CIF(1,1).sin() CIF(2).sin() CIF(0,2).sin()
Check that Issue #17825 is fixed:
sage: CIF(sin(2/3)) # needs sage.symbolic 0.618369803069737?
>>> from sage.all import * >>> CIF(sin(Integer(2)/Integer(3))) # needs sage.symbolic 0.618369803069737?
CIF(sin(2/3)) # needs sage.symbolic
ALGORITHM:
The implementation uses the following trigonometric identity
\[\sin(x + iy) = \sin(x) \cosh(y) + i \cos (x) \sinh(y)\]
- sinh()[source]¶
Return the hyperbolic sine of this complex interval.
EXAMPLES:
sage: CIF(1,1).sinh() 0.634963914784736? + 1.298457581415978?*I sage: CIF(2).sinh() 3.626860407847019? sage: CIF(0,2).sinh() 0.909297426825682?*I
>>> from sage.all import * >>> CIF(Integer(1),Integer(1)).sinh() 0.634963914784736? + 1.298457581415978?*I >>> CIF(Integer(2)).sinh() 3.626860407847019? >>> CIF(Integer(0),Integer(2)).sinh() 0.909297426825682?*I
CIF(1,1).sinh() CIF(2).sinh() CIF(0,2).sinh()
ALGORITHM:
The implementation uses the following trigonometric identity
\[\sinh(x+iy) = \cos(y) \sinh(x) + i \sin(y) \cosh(x)\]
- sqrt(all=False, **kwds)[source]¶
The square root function.
Warning
We approximate the standard branch cut along the negative real axis, with
sqrt(-r^2) = i*r
for positive realr
; but if the interval crosses the negative real axis, we pick the root with positive imaginary component for the entire interval.INPUT:
all
– boolean (default:False
); ifTrue
, return a list of all square roots
EXAMPLES:
sage: CIF(-1).sqrt()^2 -1 sage: sqrt(CIF(2)) 1.414213562373095? sage: sqrt(CIF(-1)) 1*I sage: sqrt(CIF(2-I))^2 2.00000000000000? - 1.00000000000000?*I sage: CC(-2-I).sqrt()^2 -2.00000000000000 - 1.00000000000000*I
>>> from sage.all import * >>> CIF(-Integer(1)).sqrt()**Integer(2) -1 >>> sqrt(CIF(Integer(2))) 1.414213562373095? >>> sqrt(CIF(-Integer(1))) 1*I >>> sqrt(CIF(Integer(2)-I))**Integer(2) 2.00000000000000? - 1.00000000000000?*I >>> CC(-Integer(2)-I).sqrt()**Integer(2) -2.00000000000000 - 1.00000000000000*I
CIF(-1).sqrt()^2 sqrt(CIF(2)) sqrt(CIF(-1)) sqrt(CIF(2-I))^2 CC(-2-I).sqrt()^2
Here, we select a non-principal root for part of the interval, and violate the standard interval guarantees:
sage: CIF(-5, RIF(-1, 1)).sqrt().str(style='brackets') '[-0.22250788030178321 .. 0.22250788030178296] + [2.2251857651053086 .. 2.2581008643532262]*I' sage: CIF(-5, -1).sqrt() 0.222507880301783? - 2.247111425095870?*I
>>> from sage.all import * >>> CIF(-Integer(5), RIF(-Integer(1), Integer(1))).sqrt().str(style='brackets') '[-0.22250788030178321 .. 0.22250788030178296] + [2.2251857651053086 .. 2.2581008643532262]*I' >>> CIF(-Integer(5), -Integer(1)).sqrt() 0.222507880301783? - 2.247111425095870?*I
CIF(-5, RIF(-1, 1)).sqrt().str(style='brackets') CIF(-5, -1).sqrt()
- str(base=10, style=None)[source]¶
Return a string representation of
self
.EXAMPLES:
sage: CIF(1.5).str() '1.5000000000000000?' sage: CIF(1.5, 2.5).str() '1.5000000000000000? + 2.5000000000000000?*I' sage: CIF(1.5, -2.5).str() '1.5000000000000000? - 2.5000000000000000?*I' sage: CIF(0, -2.5).str() '-2.5000000000000000?*I' sage: CIF(1.5).str(base=3) '1.1111111111111111111111111111111112?' sage: CIF(1, pi).str(style='brackets') # needs sage.symbolic '[1.0000000000000000 .. 1.0000000000000000] + [3.1415926535897931 .. 3.1415926535897936]*I'
>>> from sage.all import * >>> CIF(RealNumber('1.5')).str() '1.5000000000000000?' >>> CIF(RealNumber('1.5'), RealNumber('2.5')).str() '1.5000000000000000? + 2.5000000000000000?*I' >>> CIF(RealNumber('1.5'), -RealNumber('2.5')).str() '1.5000000000000000? - 2.5000000000000000?*I' >>> CIF(Integer(0), -RealNumber('2.5')).str() '-2.5000000000000000?*I' >>> CIF(RealNumber('1.5')).str(base=Integer(3)) '1.1111111111111111111111111111111112?' >>> CIF(Integer(1), pi).str(style='brackets') # needs sage.symbolic '[1.0000000000000000 .. 1.0000000000000000] + [3.1415926535897931 .. 3.1415926535897936]*I'
CIF(1.5).str() CIF(1.5, 2.5).str() CIF(1.5, -2.5).str() CIF(0, -2.5).str() CIF(1.5).str(base=3) CIF(1, pi).str(style='brackets') # needs sage.symbolic
See also
RealIntervalFieldElement.str()
- tan()[source]¶
Return the tangent of this complex interval.
EXAMPLES:
sage: CIF(1,1).tan() 0.27175258531952? + 1.08392332733870?*I sage: CIF(2).tan() -2.185039863261519? sage: CIF(0,2).tan() 0.964027580075817?*I
>>> from sage.all import * >>> CIF(Integer(1),Integer(1)).tan() 0.27175258531952? + 1.08392332733870?*I >>> CIF(Integer(2)).tan() -2.185039863261519? >>> CIF(Integer(0),Integer(2)).tan() 0.964027580075817?*I
CIF(1,1).tan() CIF(2).tan() CIF(0,2).tan()
- tanh()[source]¶
Return the hyperbolic tangent of this complex interval.
EXAMPLES:
sage: CIF(1,1).tanh() 1.08392332733870? + 0.27175258531952?*I sage: CIF(2).tanh() 0.964027580075817? sage: CIF(0,2).tanh() -2.185039863261519?*I
>>> from sage.all import * >>> CIF(Integer(1),Integer(1)).tanh() 1.08392332733870? + 0.27175258531952?*I >>> CIF(Integer(2)).tanh() 0.964027580075817? >>> CIF(Integer(0),Integer(2)).tanh() -2.185039863261519?*I
CIF(1,1).tanh() CIF(2).tanh() CIF(0,2).tanh()
- union(other)[source]¶
Return the smallest complex interval including the two complex intervals
self
andother
.EXAMPLES:
sage: CIF(0).union(CIF(5, 5)).str(style='brackets') '[0.0000000000000000 .. 5.0000000000000000] + [0.0000000000000000 .. 5.0000000000000000]*I'
>>> from sage.all import * >>> CIF(Integer(0)).union(CIF(Integer(5), Integer(5))).str(style='brackets') '[0.0000000000000000 .. 5.0000000000000000] + [0.0000000000000000 .. 5.0000000000000000]*I'
CIF(0).union(CIF(5, 5)).str(style='brackets')
- zeta(a=None)[source]¶
Return the image of this interval by the Hurwitz zeta function.
For
a = 1
(ora = None
), this computes the Riemann zeta function.EXAMPLES:
sage: zeta(CIF(2, 3)) 0.7980219851462757? - 0.1137443080529385?*I sage: _.parent() Complex Interval Field with 53 bits of precision sage: CIF(2, 3).zeta(1/2) -1.955171567161496? + 3.123301509220897?*I
>>> from sage.all import * >>> zeta(CIF(Integer(2), Integer(3))) 0.7980219851462757? - 0.1137443080529385?*I >>> _.parent() Complex Interval Field with 53 bits of precision >>> CIF(Integer(2), Integer(3)).zeta(Integer(1)/Integer(2)) -1.955171567161496? + 3.123301509220897?*I
zeta(CIF(2, 3)) _.parent() CIF(2, 3).zeta(1/2)
- sage.rings.complex_interval.create_ComplexIntervalFieldElement(s_real, s_imag=None, pad=0, min_prec=53)[source]¶
Return the complex number defined by the strings
s_real
ands_imag
as an element ofComplexIntervalField(prec=n)
, where \(n\) potentially has slightly more (controlled by pad) bits than given by \(s\).INPUT:
s_real
– string that defines a real number (or something whose string representation defines a number)s_imag
– string that defines a real number (or something whose string representation defines a number)pad
– integer at least 0min_prec
– number will have at least this many bits of precision, no matter what
EXAMPLES:
sage: ComplexIntervalFieldElement('2.3') 2.300000000000000? sage: ComplexIntervalFieldElement('2.3','1.1') 2.300000000000000? + 1.100000000000000?*I sage: ComplexIntervalFieldElement(10) 10 sage: ComplexIntervalFieldElement(10,10) 10 + 10*I sage: ComplexIntervalFieldElement(1.000000000000000000000000000,2) 1 + 2*I sage: ComplexIntervalFieldElement(1,2.000000000000000000000) 1 + 2*I sage: ComplexIntervalFieldElement(1.234567890123456789012345, 5.4321098654321987654321) 1.234567890123456789012350? + 5.432109865432198765432000?*I
>>> from sage.all import * >>> ComplexIntervalFieldElement('2.3') 2.300000000000000? >>> ComplexIntervalFieldElement('2.3','1.1') 2.300000000000000? + 1.100000000000000?*I >>> ComplexIntervalFieldElement(Integer(10)) 10 >>> ComplexIntervalFieldElement(Integer(10),Integer(10)) 10 + 10*I >>> ComplexIntervalFieldElement(RealNumber('1.000000000000000000000000000'),Integer(2)) 1 + 2*I >>> ComplexIntervalFieldElement(Integer(1),RealNumber('2.000000000000000000000')) 1 + 2*I >>> ComplexIntervalFieldElement(RealNumber('1.234567890123456789012345'), RealNumber('5.4321098654321987654321')) 1.234567890123456789012350? + 5.432109865432198765432000?*I
ComplexIntervalFieldElement('2.3') ComplexIntervalFieldElement('2.3','1.1') ComplexIntervalFieldElement(10) ComplexIntervalFieldElement(10,10) ComplexIntervalFieldElement(1.000000000000000000000000000,2) ComplexIntervalFieldElement(1,2.000000000000000000000) ComplexIntervalFieldElement(1.234567890123456789012345, 5.4321098654321987654321)
- sage.rings.complex_interval.is_ComplexIntervalFieldElement(x)[source]¶
Check if
x
is aComplexIntervalFieldElement
.EXAMPLES:
sage: from sage.rings.complex_interval import is_ComplexIntervalFieldElement as is_CIFE sage: is_CIFE(CIF(2)) doctest:warning... DeprecationWarning: The function is_ComplexIntervalFieldElement is deprecated; use 'isinstance(..., ComplexIntervalFieldElement)' instead. See https://github.com/sagemath/sage/issues/38128 for details. True sage: is_CIFE(CC(2)) False
>>> from sage.all import * >>> from sage.rings.complex_interval import is_ComplexIntervalFieldElement as is_CIFE >>> is_CIFE(CIF(Integer(2))) doctest:warning... DeprecationWarning: The function is_ComplexIntervalFieldElement is deprecated; use 'isinstance(..., ComplexIntervalFieldElement)' instead. See https://github.com/sagemath/sage/issues/38128 for details. True >>> is_CIFE(CC(Integer(2))) False
from sage.rings.complex_interval import is_ComplexIntervalFieldElement as is_CIFE is_CIFE(CIF(2)) is_CIFE(CC(2))
- sage.rings.complex_interval.make_ComplexIntervalFieldElement0(fld, re, im)[source]¶
Construct a
ComplexIntervalFieldElement
for pickling.