Skip to content

Commit f873bbf

Browse files
author
Andrew Luo
committed
Add check for generic directions. Add specialized smooth and transverse functions.
1 parent 4487362 commit f873bbf

File tree

2 files changed

+82
-37
lines changed

2 files changed

+82
-37
lines changed

sage_acsv/asymptotics.py

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,9 @@
129129
from sage.rings.asymptotic.asymptotic_ring import AsymptoticRing
130130
from sage.rings.ideal import Ideal
131131
from sage.rings.imaginary_unit import I
132-
from sage.rings.fraction_field import FractionField
133132
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
134133
from sage.rings.qqbar import AA, QQbar
135134
from sage.rings.rational_field import QQ
136-
from sage.schemes.affine.affine_space import AffineSpace
137135
from sage.symbolic.constants import pi
138136
from sage.symbolic.ring import SR
139137

@@ -751,7 +749,7 @@ def diagonal_asymptotics_combinatorial(
751749

752750
return result
753751

754-
def compute_asymptotic_contribution(
752+
def compute_contribution(
755753
F,
756754
critical_point,
757755
r=None
@@ -798,13 +796,25 @@ def compute_asymptotic_contribution(
798796
valid_set.setminus(
799797
[all_factors[j].subs(subs_dict) for j in range(len(all_factors)) if j not in combo]
800798
)
801-
print(valid_set)
802799

803800
# Determine whether it's possible for the critical point vanish in this
804801
# combination of factors
805-
if any([f.subs(subs_dict) != 0 for f in factors]):
802+
if any([f.subs(subs_dict) != 0 for f in factors]):
806803
valid_set.intersection([f.subs(subs_dict) for f in factors])
807804

805+
# Remove critical points of higher dimensional strata
806+
for factors_subset in Combinations(factors):
807+
if not factors_subset or len(factors_subset) == len(factors):
808+
continue
809+
cp_eqns = matrix(
810+
[[v * f.derivative(v) for v in vs] for f in factors_subset] + [r]
811+
).minors(d-len(factors_subset)+1) + factors_subset
812+
813+
cp_eqns = [f.subs(subs_dict) for f in cp_eqns]
814+
815+
valid_set.setminus(cp_eqns)
816+
817+
# Check transverse factorization
808818
s = len(factors)
809819
normals = matrix(
810820
[[f.derivative(v).subs(subs_dict) for v in vs] for f in factors]
@@ -814,14 +824,8 @@ def compute_asymptotic_contribution(
814824
"Not a transverse intersection. Cannot deal with this case."
815825
)
816826
else:
817-
try:
818-
Id_minors = [Rf(f) for f in normals.minors(s)]
819-
valid_set.setminus(Id_minors)
820-
except:
821-
valid_set = None
822-
823-
# Check conditions needed for point to be contributing
824-
# Might just need for point to be non-critical in upper dimensional component?
827+
normals_minors = normals.minors(s)
828+
valid_set.setminus(normals_minors)
825829

826830
# Find the locally parametrizing coordinates of the point pt
827831
# Since we have d variables and s factors, there should be d-s of these
@@ -859,10 +863,52 @@ def compute_asymptotic_contribution(
859863
asymptotics.append(base**n * n**exponent * (pi ** (s - d)).sqrt() * constant * expansion)
860864
restrictions.append(valid_set)
861865

862-
# TODO: If input parameters are rational, do some extra checking of validity
863-
864866
return restrictions, asymptotics
865867

868+
def compute_contribution_smooth(F, critical_point, r=None):
869+
G, H, variable_map = _prepare_symbolic_fraction(F)
870+
vs = list(variable_map.values())
871+
d = len(vs)
872+
subs_dict = {vs[i]: critical_point[i] for i in range(d)}
873+
if r is None:
874+
r = [1 for _ in range(d)]
875+
876+
expansion, constant_squared, base, exponent, _ = _compute_asm_quantity(
877+
G, H, vs, critical_point, r, subs_dict,
878+
unit=1,
879+
factors=[H],
880+
multiplicities=[1],
881+
expansion_precision=1
882+
)
883+
constant = constant_squared.sqrt()
884+
885+
n = SR.var("n")
886+
return base**n * n**exponent * (pi ** (1 - d)).sqrt() * constant * expansion
887+
888+
def compute_contribution_transverse(F, factors, multiplicities, critical_point, r=None):
889+
G, H, variable_map = _prepare_symbolic_fraction(F)
890+
vs = list(variable_map.values())
891+
d = len(vs)
892+
subs_dict = {vs[i]: critical_point[i] for i in range(d)}
893+
894+
# Make coefficients integers to get the correct constants
895+
factors = [f.subs(variable_map)*f.denominator() for f in factors]
896+
897+
if r is None:
898+
r = [1 for _ in range(d)]
899+
900+
expansion, constant_squared, base, exponent, s = _compute_asm_quantity(
901+
G, H, vs, critical_point, r, subs_dict,
902+
unit=1,
903+
factors=factors,
904+
multiplicities=multiplicities,
905+
expansion_precision=1
906+
)
907+
constant = constant_squared.sqrt()
908+
909+
n = SR.var("n")
910+
return base**n * n**exponent * (pi ** (s - d)).sqrt() * constant * expansion
911+
866912
def _compute_asm_quantity(G, H, vs, cp, r, subs_dict, unit, factors, multiplicities, expansion_precision):
867913
s = len(factors)
868914
d = len(vs)

sage_acsv/helpers.py

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -585,18 +585,10 @@ def __init__(self, base_ring):
585585
self.exclusion = Ideal(base_ring.one())
586586

587587
def intersection(self, eqns):
588+
eqns, denoms = self._convert_equations(eqns)
588589
if self.base_ring != SR:
589-
try:
590-
eqns = [self.base_field(f) for f in eqns]
591-
denoms = [f.denominator() for f in eqns]
592-
Id = compute_radical(Ideal([self.base_ring.zero()] + [self.base_ring(f * prod(denoms)) for f in eqns]))
593-
self.inclusion += Id
594-
except:
595-
print(1)
596-
self.inclusion = eqns + [SR(f) for f in self.inclusion.gens()]
597-
self.exclusion = [SR(f) for f in self.exclusion.gens()]
598-
self.base_ring = SR
599-
self.base_field = SR
590+
Id = compute_radical(Ideal([self.base_ring.zero()] + [self.base_ring(f * prod(denoms)) for f in eqns]))
591+
self.inclusion += Id
600592
else:
601593
self.inclusion += eqns
602594

@@ -605,23 +597,30 @@ def intersection(self, eqns):
605597
def setminus(self, eqns):
606598
if not eqns:
607599
return
600+
eqns, denoms = self._convert_equations(eqns)
608601
if self.base_ring != SR:
609-
try:
610-
eqns = [self.base_field(f) for f in eqns]
611-
denoms = [f.denominator() for f in eqns]
612-
Id = compute_radical(Ideal([self.base_ring(f * prod(denoms)) for f in eqns]))
613-
self.exclusion = self.exclusion.intersection(Id)
614-
except:
615-
print(2)
616-
self.inclusion = [SR(f) for f in self.inclusion.gens()]
617-
self.exclusion = eqns + [SR(f) for f in self.exclusion.gens()]
618-
self.base_ring = SR
619-
self.base_field = SR
602+
Id = compute_radical(Ideal([self.base_ring(f * prod(denoms)) for f in eqns]))
603+
self.exclusion = self.exclusion.intersection(Id)
620604
else:
621605
self.exclusion += eqns
622606

623607
return self
624608

609+
def _convert_equations(self, eqns):
610+
try:
611+
eqns = [self.base_field(f) for f in eqns]
612+
denoms = [f.denominator() for f in eqns]
613+
except:
614+
print("Error - cannot represent as quasi variety.")
615+
self.convert_to_symbolic()
616+
return eqns, denoms
617+
618+
def convert_to_symbolic(self):
619+
self.inclusion = [SR(f) for f in self.inclusion.gens()]
620+
self.exclusion = [SR(f) for f in self.exclusion.gens()]
621+
self.base_ring = SR
622+
self.base_field = SR
623+
625624
def simplify(self):
626625
if self.base_ring == SR:
627626
return

0 commit comments

Comments
 (0)