Jean-Guillaume, I like your idea very much.
FieldAXPY has proved it's worth and is ready to be "mainstreamed".
I recommend the version where the unnormalized values live in a type declared in
the lazy field,
rather than using values wrapped in a FieldAXPY object. One reason for this is
to mainstream the
laziness idea in FieldAXPY. Another reason is that one pays a penalty for
wrapping a basic type.
Compilers often cannot fully blow away these wrappers.
A third reason is that the knowledge of how to do the lazy operations lies
within the Field.
I find that Each FieldAXPY specialization is in the file containing the
corresponding field.
There is good reason for this. It is a maintenance issue.
Any change to the field may affect the lazy stuff as well.
It might as well be right in the field.
In fact, I would go so far as to say that the FieldAXPY members should just be
added to the Field concept. Template/inheritance mixing is too damn fragile!
[ Aside: Where LinBox says "Field", it really means "BasicRing". (Muchly...
In FieldAXPY for sure.)
I'll have more on this thought in a separate email. ]
Virtually every BB needs the lazy functionality for it's apply(), either
directly or via a dot().
I admit that dense matrix elimination stuff may not need it,
but there is a simple default for fields not wanting to bother with real laziness.
However, there is more to think about. I looked around.
There is virtually no use of FieldAXPY other than in vector dot products.
(J-G, do you have other uses in mind -- lurking behind this proposal?)
Dot products can be further improved. I survey the FieldAXPY's then talk about
dot().
The specializations of FieldAXPY are of 4 types.
1. counting: normalizes when sum reaches a threshold length.
2. detecting: detects overflow with a comparison and corrects.
3. dummy: normalize every operation (the default).
4. invalid: no check on overflow (in never-used field classes like Modular<uint16>).
We ought to fix the invalid ones, but, more important, the invalid approach is
more efficient and
can be used with higher level counting in dot(). In other words, the loop
control in dot() can handle
counting at no extra cost, so counting or detecting at the FieldAXPY level is
wasteful for dot().
-dave
----------------- proposed signatures for the better fields -------------------
Lazy fields have these members in addition to the Field interface.
Alternatively expressed: Fields have these members in addition to the BasicField
interface.
class SomeField {
public:
// Basic Field interface, then this ... //
// Support for self controlled laziness: //
type LazyElement;
//Because this type may be the same primitive type as Element, the function
names include "Lazy".
LazyElement& initLazy(LazyElement&); // init to 0. FieldAXPY::reset()
LazyElement& axpyinLazy(LazyElement&, const Element&, const Element&); //
FieldAXPY::mulacc()
LazyElement& addinLazy(LazyElement&, const Element&); // FieldAXPY::accumulate()
Element& normalizeLazy(Element&, const LazyElement&); // FieldAXPY::get()
// Support for externally controled laziness [primarily in VectorDomain::dot()]: //
size_t veryLazySumProdBound; // In the prime field case this is max val of
type Element / (p-1)^2.
LazyElement& axpyinVeryLazy(LazyElement&, const Element&, const Element&);
// just axpyin with no normalization and no internal overflow check.
size_t veryLazySumBound; // In the prime field case this is max val of type
Elememt / (p-1).
LazyElement& addinVeryLazy(LazyElement&, const Element&);
// just addin with no normalization and no internal overflow check. For use
by zero-one BB's.
};
Default case:
LazyElement = Element
initLazy = init
axpyinLazy = axpyin
addinLazy = addin
normalizeLazy = copy
veryLazySumProdBound = max val of size_t
axpyinVeryLazy = axpyin
veryLazySumBound = max val of size_t
addinVeryLazy = addin
Jean-Guillaume Dumas wrote:
> Currently the FieldAXPY objects stores a field and an element.
> This is a lot of storage for a single scalar element.
> I would rather see the FieldAXPY object be more like a field object, i.e.
> leave the element to be a parameter of the FieldAXPY methods e.g. :
> inline Element& accumulate (Element& _y, const Element &t)
> instead of
> inline Element& accumulate (const Element &t) { _y = ... };
> The goal is to be able to implement of LazyField object which could make
> some delayed operations.
> Apart form this change of interface for the specific FieldAXPY methods
> which I regards as mandatory, I see two solutions :
> 1/ Give the field interface to the FieldAXPY object so that it can be
> used directly as field.
> For the specializations, it is very easy, it suffices for the FieldAXPY
> specializations to inherit from their Field.
> 2/ Implement a LazyField class inheriting from both the Field and the
> FieldAXPY
> Other points of view on this ?
> Best,