> For bigger inputs, I think current implementation is bad both ways:
>
> a) For sparse cases, simply chain the MxN terms together, sort and
> dedupe is O(N^2*log(N)) better than current O(N^3).
For sparse cases, another important factor is cell allocation:
M terms times N terms could result in MxN terms or (M+N-1) terms.
Current implementation is efficient in allocation but at the cost
of (worst case) O(n^3) traversal.
The above method is O(n^2) allocation and O(n^2*log(n)) traversal,
but I think following method can achieve minimal allocation (same
as current) and still O(n^2*log(n)) traversal:
Simply put, instead of doing a N-way merge of M-length lists
(assume n < m), we do a N-way merge of streams -- we use a heap
to do the comparison, and the term multiplication happens "lazily",
to reduce unnecessary memory allocation.
> b) For dense cases, using actual dense representation like array
> should be a great improvement over current implementation:
> we only need a (slightly larger than) (M+N) length array to store
> the temp result.
For dense cases, the implementation will look like this:
(Note that this is only valid for "E is NNI", aka this is valid
for SUP instead of more general PR.)
- Qian
vec_to_poly(minDegree : E, vec : PrimitiveArray R) : % ==
res : Rep := []
for i in 0..(# vec - 1) repeat
if not zero? vec.i then res := cons([i + minDegree,
vec.i], res)
res
NNI ==> NonNegativeInteger
mult_dense(p1 : %, p2 : %) : % ==
max_deg1 : NNI := degree p1; min_deg1 : NNI :=
minimumDegree p1
max_deg2 : NNI := degree p2; min_deg2 : NNI :=
minimumDegree p2
new_len := (max_deg1 + max_deg2 - min_deg1 - min_deg2 +
1)::NNI
new_vec : PrimitiveArray R := new(new_len, 0$R)
new_minDegree := min_deg1 + min_deg2
-- for i in 0..(# new_vec - 1) repeat
-- for j in max(0, i - maxIndex a2)..min(i, maxIndex a1)
repeat
-- new_vec.i := new_vec.i + a1.j * a2.(i-j)
for t1 in listOfTerms p1 repeat
t1k := t1.k
t1c := t1.c
for t2 in listOfTerms p2 repeat
i := t1k + t2.k - new_minDegree
new_vec.i := new_vec.i + t1c * t2.c
vec_to_poly(new_minDegree, new_vec)