Post by Bill Page(79) -> h2323:=((h2*h3*h2*h3)^2);
Type: XDistributedPolynomial(OrderedVariableList([x,y,z,w,x1,x2,x3,x4,x5]),Fraction(Integer))
Time: 0.00 (IN) + 2.71 (EV) + 0.00 (OT) = 2.71 sec
(80) -> dc_fact h2323
(80)
[- y x + x y, - z y x + z x y + y z x - y x z - x z y + x y z, - y x + x y,
- z y x + z x y + y z x - y x z - x z y + x y z, - y x + x y,
- z y x + z x y + y z x - y x z - x z y + x y z, - y x + x y,
- z y x + z x y + y z x - y x z - x z y + x y z]
Type: List(XDistributedPolynomial(OrderedVariableList([x,y,z,w,x1,x2,x3,x4,x5]),Fraction(Integer)))
Time: 0.00 (IN) + 315.56 (EV) + 0.13 (OT) = 315.69 sec
Although you have already pointed out that this code is not yet
optimized I think it is interesting to compare this with Konrad's
Thanks for interestiong observation.
Actually Konrad's program performs quite a different computation.
In particular IIUC Konrad tries to preserve structure of the input.
That is good, but means that routines are hard to compare.
Probably more relevant is comparison to 'homo_fact' which in this
case is doint real work -- for homogeneous polynomial 'dc_fact'
just adds overhead. On my machine
(67) -> homo_fact(h2323)
(67)
[- y x + x y, - z y x + z x y + y z x - y x z - x z y + x y z, - y x + x y,^
- z y x + z x y + y z x - y x z - x z y + x y z, - y x + x y,
- z y x + z x y + y z x - y x z - x z y + x y z, - y x + x y,
- z y x + z x y + y z x - y x z - x z y + x y z]
Type: List(XDistributedPolynomial(OrderedVariableList([x,y,z,w,x1,x2,x3,x4,x5]),Fraction(Integer)))
Time: 0.32 (EV) = 0.32 sec
As you can see 'homo_fact' is about 1000 times faster than 'dc_fact'.
You may notice that 'homo_fact' is faster than multiplication that
produced 'h2323'. At first glance it may look reasonable, but
'homo_fact' checks result by multiplication. It turned out
that speed of multiplication depends strongly on order of operations.
Compare:
(70) -> h2323 := a2*(a3*(a2*(a3*(a2*a3*a2*a3))));
Type: XDistributedPolynomial(OrderedVariableList([x,y,z,w,x1,x2,x3,x4,x5]),Fraction(Integer))
Time: 0.12 (EV) = 0.12 sec
(71) -> h2323 := (a2*(a3*(a2*(a3*(a2*a3*a2)))))*a3;
Type: XDistributedPolynomial(OrderedVariableList([x,y,z,w,x1,x2,x3,x4,x5]),Fraction(Integer))
Time: 80.09 (EV) = 80.09 sec
'dc_fact' uses about 15-20 sec to multiply factors in unfavourable
order. As a quick hack I added routine to muliplay factors starting
from right, it gave expected speedup. But we probably should work
on noncommutative polynomial multiplication to make it faster.
Current code is in 'xpoly.spad' and main step is:
+/[[[t1.k*t2.k, t1.c*t2.c]$TERM for t2 in p2]
for t1 in p1]
that is we add list of multiples of p2 by single term of p1.
We could probably speed it up by having faster routine to add
list of elements of free abelian monoid. More precisely,
elements of free monoid are represented by ordered list.
For two lists of similar length addition is linear. But when
we add several such lists the "acumulator" gets quite long
and cost become quadratic. We probably could speed it up
by trying to balance length of lists. One idea would be
to add two shortest list as a basic step.
However, the main reason of slowness of this example is
slowness of Groebner bases (used via 'solve'), this takes
about 95% of time. We have system of 34560 equations
in 4 unknowns. This system is highly redundant, there
are only 18 distinct equations. After adding
'removeDuplicates' on list of equations (and workaround
for order of multiplication) on my machine time is down
to 16.25 sec. I did not measure how it splits between
routines, but printouts on the screen suggested that
most time went into 'removeDuplicates'.
Now concerning possible fixes: for users it is rather natural
to create large sets of equations with high redundancy.
So it would be good if 'solve' (or Groebner code) could
handle it. 'removeDuplicates' is not a good solution.
First, it is slow for long lists. And redundancy may
be more subtle than having duplicates: for example we
may have scalar multiples of the same equation. In our
case the system is kind of trivial: two variables can be
determined from linear equations and when values ot those
variables is plugged into other equations one gets enough
linear equations to determine values of two other variables.
Currently 'solve' checks if system is linear, clearly
there is place for smarter handling of linear equations.
Another thing is that 'dc_fact' could spend more effort and
solve linear equations intead of passing them to 'solve'.
In this way we would avoid generationg large number of
useless equations -- the example shows that 'dc_fact'
should do this, but improving 'solve' also would have
benefits.
Of course, for homogeneous polynomials we could directly
use result of 'homo_fact', but AFAICS the same issues
will appear for non-homogeneous polynomials. In fact,
currently 'dc_fact' treats homogeneous polynomials like
all others exactly because I wanted to get more testing
for main part of 'dc_fact' (in particular to get various
edge cases).
--
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+***@googlegroups.com.
To post to this group, send email to fricas-***@googlegroups.com.
Visit this group at https://groups.google.com/group/fricas-devel.
For more options, visit https://groups.google.com/d/optout.