On Sat, Jul 15, 2023 at 01:12:08AM +0200, Ralf Hemmecke wrote:
> 
> But hey, I see
> 
> https://github.com/fricas/fricas/blob/master/src/algebra/multpoly.spad#L647
> 
>       degree p ==
>         p case R => 0
>         degree(leadingCoefficient(p.ts)) + monomial(degree(p.ts), p.v)
> 
> Oh, no! That computes the degree over all variables. It basically treat the
> polynomial like in a distributed fashion. Sorry, I have not recognized this
> before.
> 
> For an implementation of the smaller? from Compare in SMP, I would
> definitely use the univariate recursive structure, i.e. consider the degree
> function from D and eventually break ties with smaller? from R.

I have now version of 'smaller?' for SMP.  I tried to get the same
results as older version.  Good news is that when it works it
seem to be about 4 times faster than old version.  Bad news is
that at least using sbcl it breaks in strange ways: printouts
show correct values, but it from time to time it dies with
Lisp errors.  To complicate matter, it seem that after
succesfull call with given argument some time later it can
fail with the same arguments.  It seems to work with ecl.  ATM
it looks to me like a miscomplilation.  But it is not clear
whom to blame, if our declaration/initialization is wrong
or it the error is on Lisp side.

If anybody wants to try this code and investigate problems
the patch is in attachement.

BTW: There is a chunk for ZMOD, this one seem to be working
fine.

-- 
                              Waldek Hebisch

-- 
You received this message because you are subscribed to the Google Groups 
"FriCAS - computer algebra system" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to fricas-devel+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/fricas-devel/ZLRVr78748xllTd3%40fricas.math.uni.wroc.pl.
diff --git a/src/algebra/fmod.spad b/src/algebra/fmod.spad
index efc75dad..878b93cf 100644
--- a/src/algebra/fmod.spad
+++ b/src/algebra/fmod.spad
@@ -54,6 +54,8 @@ IntegerMod(p : PositiveInteger):
 
     hashUpdate!(hs, s) == update!(hs, s pretend SingleInteger)$HashState
 
+    smaller?(x : %, y : %) : Boolean == x <$Rep y
+
   else
     Rep := Integer
 
@@ -84,6 +86,8 @@ IntegerMod(p : PositiveInteger):
 
     hashUpdate!(hs, s) == update!(hs, SXHASH(s)$Lisp)$HashState
 
+    smaller?(x : %, y : %) : Boolean == x <$Rep y
+
 --Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
 --All rights reserved.
 --
diff --git a/src/algebra/multpoly.spad b/src/algebra/multpoly.spad
index 36be6dc8..a1b806ca 100644
--- a/src/algebra/multpoly.spad
+++ b/src/algebra/multpoly.spad
@@ -414,6 +414,49 @@ SparseMultivariatePolynomial(R : Join(SemiRng, AbelianMonoid),
               s := hashUpdate!(s, p.v)
               hashUpdate!(s, p.ts)
 
+      if R has Comparable then
+
+          triage(p : %, q : %) : SingleInteger ==
+              p case R =>
+                  q case R =>
+                      p =$R q => 0
+                      smaller?(p, q)$R => 1
+                      -1
+                  smaller?(0$R, leadingCoefficient(q))$R => 1
+                  -1
+              q case R =>
+                  smaller?(leadingCoefficient(p), 0$R)$R => 1
+                  -1
+              pv := p@VPoly
+              qv := q@VPoly
+              pv.v < qv.v =>
+                  smaller?(0$R, leadingCoefficient(q))$R => 1
+                  -1
+              not(pv.v = qv.v) =>
+                  smaller?(leadingCoefficient(p), 0$R)$R => 1
+              -- pv.v = qv.v
+              pu := pv.ts
+              qu := qv.ts
+              repeat
+                  (dp := degree(pu)) < (dq := degree(qu)) => return
+                      lcq := leadingCoefficient(qu)
+                      smaller?(0$R, leadingCoefficient(lcq))$R => 1
+                      -1
+                  dq < dp => return
+                      lcp := leadingCoefficient(pu)
+                      smaller?(leadingCoefficient(lcp), 0$R)$R => 1
+                      -1
+                  lcp := leadingCoefficient(pu)
+                  lcq := leadingCoefficient(qu)
+                  tr1 := triage(lcp, lcq)
+                  not(tr1 = 0) or dp = 0 => return tr1
+                  pu := reductum(pu)
+                  qu := reductum(qu)
+
+          smaller?(p : %, q : %) : Boolean ==
+              triage(p, q) = 1
+
+
       if R has IntegralDomain then
          UnitCorrAssoc ==> Record(unit : %, canonical : %, associate : %)
          unitNormal(p) ==

Reply via email to