Skip to content
This repository was archived by the owner on Jan 30, 2023. It is now read-only.

Commit f696a38

Browse files
committed
Fix bug in checking validity of coordinate values on a chart (#22535)
1 parent fd5f71a commit f696a38

File tree

1 file changed

+81
-31
lines changed

1 file changed

+81
-31
lines changed

src/sage/manifolds/chart.py

Lines changed: 81 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -698,19 +698,67 @@ def valid_coordinates(self, *coordinates, **kwds):
698698
substitutions = dict(zip(self._xx, coordinates))
699699
if parameters:
700700
substitutions.update(parameters)
701-
for restrict in self._restrictions:
702-
if isinstance(restrict, tuple): # case of or conditions
703-
combine = False
704-
for expr in restrict:
705-
combine = combine or bool(expr.subs(substitutions))
706-
if not combine:
707-
return False
708-
else:
709-
if not bool(restrict.subs(substitutions)):
710-
return False
711-
# All tests have been passed:
701+
return self._check_restrictions(self._restrictions, substitutions)
712702
return True
713703

704+
def _check_restrictions(self, restrict, substitutions):
705+
r"""
706+
Recursive helper function to check the validity of coordinates
707+
given some restrictions
708+
709+
INPUT:
710+
711+
- restrict: a tuple of conditions (combined with 'or'), a list of
712+
conditions (combined with 'and') or a single coordinate condition
713+
- substitutions: dictionary (keys: coordinates of ``self``) giving the
714+
value of each coordinate
715+
716+
OUTPUT:
717+
718+
- boolean stating whether the conditions are fulfilled by the
719+
coordinate values
720+
721+
TESTS::
722+
723+
sage: M = Manifold(2, 'M', structure='topological')
724+
sage: X.<x,y> = M.chart()
725+
sage: X._check_restrictions(x>0, {x: pi, y: 0})
726+
True
727+
sage: X._check_restrictions(x>0, {x: -sqrt(2), y: 0})
728+
False
729+
sage: X._check_restrictions((x>0, [x<y, y<0]), {x: 1, y: 2})
730+
True
731+
sage: X._check_restrictions((x>0, [x<y, y<0]), {x: -1, y: 2})
732+
False
733+
sage: X._check_restrictions((x>0, [x<y, y<0]), {x: -1, y: -1/2})
734+
True
735+
sage: X._check_restrictions([(x<y, y<0), x>0], {x: 1, y: 2})
736+
True
737+
sage: X._check_restrictions([(x<y, y<0), x>0], {x: -1, y: 2})
738+
False
739+
sage: X._check_restrictions([(x<y, y<0), x>0], {x: 1, y: -2})
740+
True
741+
sage: X._check_restrictions([(x<y, y<0), x>0], {x: 2, y: 1})
742+
False
743+
744+
"""
745+
if isinstance(restrict, tuple): # case of 'or' conditions
746+
combine = False
747+
for cond in restrict:
748+
combine = combine or self._check_restrictions(cond,
749+
substitutions)
750+
return combine
751+
elif isinstance(restrict, list): # case of 'and' conditions
752+
combine = True
753+
for cond in restrict:
754+
combine = combine and self._check_restrictions(cond,
755+
substitutions)
756+
return combine
757+
# Case of a single condition:
758+
return bool(restrict.subs(substitutions))
759+
760+
761+
714762
def transition_map(self, other, transformations, intersection_name=None,
715763
restrictions1=None, restrictions2=None):
716764
r"""
@@ -1633,8 +1681,8 @@ def add_restrictions(self, restrictions):
16331681
for restrict in self._restrictions:
16341682
restrict_used = False # determines whether restrict is used
16351683
# to set some coordinate bound
1636-
if not isinstance(restrict, tuple): # case of 'or' conditions
1637-
# excluded
1684+
if not isinstance(restrict, (tuple, list)): # case of combined
1685+
# conditions excluded
16381686
operands = restrict.operands()
16391687
left = operands[0]
16401688
right = operands[1]
@@ -1812,6 +1860,20 @@ def valid_coordinates(self, *coordinates, **kwds):
18121860
sage: XD.valid_coordinates(0,0)
18131861
True
18141862
1863+
Another open subset of the square, defined by `x^2+y^2<1` or
1864+
(`x>0` and `|y|<1`)::
1865+
1866+
sage: B = M.open_subset('B',
1867+
....: coord_def={X: (x^2+y^2<1,
1868+
....: [x>0, abs(y)<1])})
1869+
sage: XB = X.restrict(B)
1870+
sage: XB.valid_coordinates(-1/2, 0)
1871+
True
1872+
sage: XB.valid_coordinates(-1/2, 3/2)
1873+
False
1874+
sage: XB.valid_coordinates(3/2, 1/2)
1875+
True
1876+
18151877
"""
18161878
n = len(coordinates)
18171879
if n != self._manifold._dim:
@@ -1836,31 +1898,19 @@ def valid_coordinates(self, *coordinates, **kwds):
18361898
if min_included:
18371899
if x < xmin:
18381900
return False
1839-
else:
1840-
if x <= xmin:
1841-
return False
1901+
elif x <= xmin:
1902+
return False
18421903
if max_included:
18431904
if x > xmax:
18441905
return False
1845-
else:
1846-
if x >= xmax:
1847-
return False
1906+
elif x >= xmax:
1907+
return False
18481908
# Check of additional restrictions:
1849-
if self._restrictions != []:
1909+
if self._restrictions:
18501910
substitutions = dict(zip(self._xx, coordinates))
18511911
if parameters:
18521912
substitutions.update(parameters)
1853-
for restrict in self._restrictions:
1854-
if isinstance(restrict, tuple): # case of or conditions
1855-
combine = False
1856-
for expr in restrict:
1857-
combine = combine or bool(expr.subs(substitutions))
1858-
if not combine:
1859-
return False
1860-
else:
1861-
if not bool(restrict.subs(substitutions)):
1862-
return False
1863-
# All tests have been passed:
1913+
return self._check_restrictions(self._restrictions, substitutions)
18641914
return True
18651915

18661916
@options(max_range=8, color='red', style='-', thickness=1, plot_points=75,

0 commit comments

Comments
 (0)