1 /* linbox/vector/vector-domain.h
2  * Copyright (C) 2001-2002 Bradford Hovinen
3  *
4  * Written by Bradford Hovinen <hovinen@cis.udel.edu>
5  *
6  * ------------------------------------
7  * 2002-04-10 Bradford Hovinen <hovinen@cis.udel.edu>
8  *
9  * There are now two vector domain types: VectorDomainBase and
10  * VectorDomain. VectorDomainBase, which in principle can be used independently,
11  * contains all functions that require only one vector type (such as axpy, mul,
12  * read, and write). VectorDomain inherits VectorDomainBase and implements
13  * dotprod, which requires two vector types.
14  *
15  * ------------------------------------
16  * Modified by Dmitriy Morozov <linbox@foxcub.org>. May 27, 2002.
17  *
18  * Added the modifications for categories and vector traits that were designed
19  * at the Rootbeer meeting. Added parametrization of VectorTags by VectorTraits.
20  *
21  * ------------------------------------
22  * 2002-06-04 Bradford Hovinen <hovinen@cis.udel.edu>
23  *
24  * Reverted change of 2002-04-10, reintegrating VectorDomain and
25  * VectorDomainBase. Now using template specialization on the functions, now
26  * that I know how to do it.
27  *
28  * ------------------------------------
29  * 2002-06-21 Bradford Hovinen <hovinen@cis.udel.edu>
30  *
31  * Added methods add, addin, sub, subin, areEqual, isZero, and copy.
32  *
33  * ------------------------------------
34  * 2012Aug -bds
35  * VectorDomain<F> inherits from DotProductDomain<F>, which inherits from VectorDomainBase<F>.
36  * DotProductDomain<> has a generic definition here and
37  * has specializations in field/Modular/ and field/Givaro/.
38  * ------------------------------------
39  *
40  * ========LICENCE========
41  * This file is part of the library LinBox.
42  *
43  * LinBox is free software: you can redistribute it and/or modify
44  * it under the terms of the  GNU Lesser General Public
45  * License as published by the Free Software Foundation; either
46  * version 2.1 of the License, or (at your option) any later version.
47  *
48  * This library is distributed in the hope that it will be useful,
49  * but WITHOUT ANY WARRANTY; without even the implied warranty of
50  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
51  * Lesser General Public License for more details.
52  *
53  * You should have received a copy of the GNU Lesser General Public
54  * License along with this library; if not, write to the Free Software
55  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
56  * ========LICENCE========
57  *.
58  */
59 
60 #ifndef __LINBOX_field_vector_domain_H
61 #define __LINBOX_field_vector_domain_H
62 
63 #include <iostream>
64 
65 #include "linbox/linbox-config.h"
66 #include "linbox/util/debug.h"
67 #include "linbox/vector/vector-traits.h"
68 #include "linbox/util/field-axpy.h"
69 
70 namespace LinBox
71 { /*  VectorDomainBase */
72 	/** @name Vector domain base
73 	 *
74 	 * This class provides a virtual base for the VectorDomain and the
75 	 * DotProductDomain. Its purpose is to provide the field of computation
76 	 * in a single location.
77 	 \ingroup vector
78 	 */
79 	template <class Field>
80 	class VectorDomainBase {
81 	public:
VectorDomainBase()82 		VectorDomainBase () : _faxpy(nullptr) {std::cout<<"CST DEFAULT VDB"<<std::endl;}
VectorDomainBase(const Field & F)83 		VectorDomainBase (const Field &F) :  _faxpy(new FieldAXPY<Field>(F))
84                 { /*std::cerr << "VDD cstor " << this << std::endl;*/}
~VectorDomainBase()85                 ~VectorDomainBase()	{ if (_faxpy != nullptr) delete _faxpy; }
86 
init(const Field & F)87 		void init(const Field &F) { if (_faxpy != nullptr) delete _faxpy; _faxpy = new FieldAXPY<Field>(F); }
field()88 		inline const Field & field() const { return _faxpy->field(); }
faxpy()89 		inline const FieldAXPY<Field>& faxpy() const { return *_faxpy; }
90 
91 	protected:
92 		const FieldAXPY<Field> * _faxpy;
93 	};
94 }
95 
96 namespace LinBox
97 { /*  Dot Product */
98 	/** @name Dot product domain
99 	 * @brief Performance-critical dotproducts
100 	 *
101 	 * This class contains all of the "high-performance" dot product types
102 	 * for a vector domain, i.e. dense/dense and dense/sparse parallel. It
103 	 * allows these dot products to be specialized with very highly tuned
104 	 * and tightly optimized field-specific implementations, possibly in
105 	 * assembly language. The other dot products are not considered as
106 	 * critical for performance, so their implementations are in the derived
107 	 * class VectorDomain.
108 	 */
109 	template <class Field_>
110         //	class DotProductDomain : public virtual VectorDomainBase<Field_> {
111         class DotProductDomain : public VectorDomainBase<Field_> {
112 	public:
113 		//DotProductDomain () { /*std::cerr << "DPD def cstor" << std::endl;*/ }// no def cstor allowed
114 
115 		typedef Field_ Field;
116 		typedef typename Field::Element Element;
117 
DotProductDomain(const Field & F)118 		DotProductDomain (const Field &F) :
119 			VectorDomainBase<Field> (F)
120 		{  /*std::cerr << "DPD cstor " << this << std::endl; */}
121 
122 		using VectorDomainBase<Field>::field;
123 		using VectorDomainBase<Field>::init;
124 
125 
126 	protected:
127 		template <class Vector1, class Vector2>
128 		inline Element &dotSpecializedDD (Element &res, const Vector1 &v1, const Vector2 &v2) const;
129 
130 		template <class Vector1, class Vector2>
131 		inline Element &dotSpecializedDSP (Element &res, const Vector1 &v1, const Vector2 &v2) const;
132 
133 	};
134 
135 }
136 
137 namespace LinBox
138 { /*  Vector Domain */
139 /* public members
140 VectorDomain<F>()
141 VectorDomain<F>(VD)
142 VectorDomain (F)
143 VD1 = VD2
144 VD.field()
145 VD.write<V>(os, v)
146 VD.read<V>(os, v)
147 VD.copy<V1,V2>(v1,v2)
148 VD.copy<V1,V2>(v1,v2,i,n)
149 VD.areEqual<V1,V2>(v1,v2)
150 VD.isZero<V>(v)
151 VD.dot<V1,V2>(e,v1,v2) aka dotprod
152 VD.add<V1,V2,V3>(v1,v2,v3)
153 VD.addin<V1,V2>(v1,v2)
154 VD.sub<V1,V2,V3>(v1,v2,v3)
155 VD.subin<V1,V2>(v1,v2)
156 VD.neg<V1,V2>(v1,v2)
157 VD.negin<V>(v)
158 VD.mul<V1,V2>(v1,v2,e)
159 VD.mulin<V>(v,e)
160 VD.axpy<V1,V2,V3>(v1,e,v2,v3)
161 VD.axpyin<V1,V2>(v1,e,v2)
162 VD.swap<V1,V2>(v1,v2)
163 VD.random<V>(v)
164 class Transposition;
165 class Permutation;
166 VD.permute<V,PI>(v1,pb,pe)
167 */
168 
169 	/** @name Vector Domain
170 	 * @brief Vector arithmetic
171 	 *
172 	 * This is a generic wrapper around classes matching the
173 	 * \ref FieldArchetype  interface. It implements vector-vector
174 	 * operations such as axpy, mul, and dotprod. It also contains an
175 	 * interface to the underlying field whereby calls simply pass
176 	 * through. Template specializations permit optimizations to be done on
177 	 * these operations based on the characteristics of the field.
178 	 *
179 	 * This class is usable by itself. Simply supply any preexisting field
180 	 * as a template parameter and it will work as intended, though its
181 	 * operation may not be fully optimized.
182 	 */
183 	// JGD 01.10.2003 : Why inherit twice from VectorDomainBase<Field> ???
184 	// bds 2004Apr25 : well, g++ 3.4.3 wants explicit base domains on everything - eases that.
185 	template <class Field_>
186         //	class VectorDomain : public virtual DotProductDomain<Field_> , public virtual VectorDomainBase<Field_> {
187         class VectorDomain : public  DotProductDomain<Field_> {
188 	public:
189 
190 		typedef Field_ Field;
191 
192 		typedef typename Field::Element         Element;
193 
194 		// VectorDomain(): DotProductDomain<Field>() { /*std::cerr << "VD def cstor" << std::endl;*/ }
195 		//VectorDomain():DotProductDomain<Field>() {}
196 
197                 //using VectorDomainBase<Field>::init;
198                 using DotProductDomain<Field>::init;
199 
200 		/** Copy constructor.
201 		 * Constructs VectorDomain object by copying the domain.
202 		 * This is required to allow vector domain objects to be passed
203 		 * by value into functions.
204 		 * @param  VD VectorDomain object.
205 		 */
VectorDomain(const VectorDomain & VD)206 		VectorDomain (const VectorDomain &VD) :
207                         //VectorDomainBase<Field> (VD.field()),
208                         DotProductDomain<Field> (VD.field())
209 		{}
210 
211                 /** Construct from a field.
212 		 * @param F Field or ring
213 		 */
VectorDomain(const Field & F)214 		VectorDomain (const Field &F) :
215 			//VectorDomainBase<Field> (F), DotProductDomain<Field> (F)
216                         DotProductDomain<Field> (F)
217 		{/* std::cerr << "VD cstor " << this << std::endl;*/}
218 
219 
220 
221 		/** Assignment operator.
222 		 * Assigns VectorDomain object MD to field.
223 		 * @param  VD VectorDomain object.
224 		 */
225 		VectorDomain &operator = (const VectorDomain &VD)
226 		{
227 			this->init(VD.field());
228 			//this->_field = VD._field;
229 			//VectorDomainBase<Field>:: accu = VD.accu;
230 			return *this;
231 		}
232 
233 		/** Retrieve the underlying field
234 		 * Return a reference to the field that this vector domain
235 		 * object uses
236 		 * @return reference to field
237 		 */
238 
239 		//using VectorDomainBase<Field>::field;
240                 using DotProductDomain<Field>::field;
241 
242 		/** Vector input/output operations
243 		 * These routines are useful for reading and writing vectors to
244 		 * and from file streams. They are analagous to field read and
245 		 * write operations.
246 		 */
247 
248 		//@{
249 
250 		/** Print vector of field elements.
251 		 * This function assumes the field element has already been
252 		 * constructed and initialized.
253 		 * @return output stream to which field element is written.
254 		 * @param  os  output stream to which field element is written.
255 		 * @param  x   field element.
256 		 */
257 		template <class Vector>
write(std::ostream & os,const Vector & x)258 		inline std::ostream &write (std::ostream &os, const Vector &x) const
259 		{
260 			return writeSpecialized (os, x, typename VectorTraits<Vector>::VectorCategory ());
261 		}
262 
263 		/** Read vector of field elements.
264 		 * This function assumes the field element has already been
265 		 * constructed and initialized.
266 		 * @return input stream from which field element is read.
267 		 * @param  is  input stream from which field element is read.
268 		 * @param  x   field element.
269 		 */
270 		template <class Vector>
read(std::istream & is,Vector & x)271 		inline std::istream &read (std::istream &is, Vector &x) const
272 		{
273 			return readSpecialized (is, x, typename VectorTraits<Vector>::VectorCategory ());
274 		}
275 
276 		//@} Input/Output Operations
277 
278 		/** @name Vector arithmetic operations
279 		 * These routes are analogs of field arithmetic operations, but
280 		 * they take vectors of elements as input. Vector-vector dot
281 		 * product and vector-vector axpy are supported here.
282 		 */
283 
284 		//@{
285 
286 		/** Vector copy.
287 		 * Copy a vector to another vector, possibly converting to a
288 		 * different representation
289 		 * @param res Output vector
290 		 * @param v Input vector
291 		 * @returns reference to output vector
292 		 */
293 		template <class Vector1, class Vector2>
copy(Vector1 & res,const Vector2 & v)294 		inline Vector1 &copy (Vector1 &res, const Vector2 &v) const
295 		{
296 			return copySpecialized (res, v,
297 						typename VectorTraits<Vector1>::VectorCategory (),
298 						typename VectorTraits<Vector2>::VectorCategory ());
299 		}
300 
301 		/** Vector copy.
302 		 * Copy a vector to a portion of another vector, possibly
303 		 * converting to a different representation
304 		 * @param res Output vector
305 		 * @param i Index to which to copy
306 		 * @param len Length (in indices) of output vector to
307 		 *            invalidate. If len == 0, then copy the whole vector v
308 		 * @param v Input vector
309 		 * @returns reference to output vector
310 		 */
311 		template <class Vector1, class Vector2>
312 		inline Vector1 &copy (Vector1 &res, const Vector2 &v, size_t i, size_t len = 0) const
313 		{
314 			return copySpecialized (res, v, i, len,
315 						typename VectorTraits<Vector1>::VectorCategory ());
316 		}
317 
318 		/** Vector equality.
319 		 * @param v1 Input vector
320 		 * @param v2 Input vector
321 		 * @returns true if and only if the vectors v1 and v2 are equal
322 		 */
323 		template <class Vector1, class Vector2>
areEqual(const Vector1 & v1,const Vector2 & v2)324 		inline bool areEqual (const Vector1 &v1, const Vector2 &v2) const
325 		{
326 			return areEqualSpecialized (v1, v2,
327 						    typename VectorTraits<Vector1>::VectorCategory (),
328 						    typename VectorTraits<Vector2>::VectorCategory ());
329 		}
330 
331 		/** Vector equality with zero.
332 		 * @param v Input vector
333 		 * @returns true if and only if the vector v is zero
334 		 */
335 		template <class Vector>
isZero(const Vector & v)336 		inline bool isZero (const Vector &v) const
337 		{
338 			return isZeroSpecialized (v, typename VectorTraits<Vector>::VectorCategory ());
339 		}
340 
341 		/** Vector-vector dot product.
342 		 * @param res element into which to store result
343 		 * @param v1 Input vector
344 		 * @param v2 Input vector
345 		 */
346 		template <class Vector1, class Vector2>
dot(Element & res,const Vector1 & v1,const Vector2 & v2)347 		inline Element &dot (Element &res, const Vector1 &v1, const Vector2 &v2) const
348 		{
349 			return dotSpecialized (res, v1, v2,
350 					       typename VectorTraits<Vector1>::VectorCategory (),
351 					       typename VectorTraits<Vector2>::VectorCategory ());
352 		}
353 
354 		/** Vector-vector dot product.
355 		 * Alias for the above, to avoid source incompatibility.
356 		 * @param res element into which to store result
357 		 * @param v1 Input vector
358 		 * @param v2 Input vector
359 		 */
360 		template <class Vector1, class Vector2>
dotprod(Element & res,const Vector1 & v1,const Vector2 & v2)361 		inline Element &dotprod (Element &res, const Vector1 &v1, const Vector2 &v2) const
362 		{
363 			return dot (res, v1, v2);
364 		}
365 
366 		/** Vector add.
367 		 * res <- y + x
368 		 * @param res Vector into which to store result
369 		 * @param y Input vector y
370 		 * @param x Input vector x
371 		 */
372 		template <class Vector1, class Vector2, class Vector3>
add(Vector1 & res,const Vector2 & y,const Vector3 & x)373 		inline Vector1 &add (Vector1 &res, const Vector2 &y, const Vector3 &x) const
374 		{
375 			return addSpecialized (res, y, x,
376 					       typename VectorTraits<Vector1>::VectorCategory (),
377 					       typename VectorTraits<Vector2>::VectorCategory (),
378 					       typename VectorTraits<Vector3>::VectorCategory ());
379 		}
380 
381 		/** Vector in-place add.
382 		 * y <- y + x
383 		 * @param y Input vector y; result is stored here
384 		 * @param x Input vector x
385 		 */
386 		template <class Vector1, class Vector2>
addin(Vector1 & y,const Vector2 & x)387 		inline Vector1 &addin (Vector1 &y, const Vector2 &x) const
388 		{
389 			return addinSpecialized (y, x,
390 						 typename VectorTraits<Vector1>::VectorCategory (),
391 						 typename VectorTraits<Vector2>::VectorCategory ());
392 		}
393 
394 		/** Vector subtract.
395 		 * res <- y - x
396 		 * @param res Vector into which to store result
397 		 * @param y Input vector y
398 		 * @param x Input vector x
399 		 */
400 		template <class Vector1, class Vector2, class Vector3>
sub(Vector1 & res,const Vector2 & y,const Vector3 & x)401 		inline Vector1 &sub (Vector1 &res, const Vector2 &y, const Vector3 &x) const
402 		{
403 			return subSpecialized (res, y, x,
404 					       typename VectorTraits<Vector1>::VectorCategory (),
405 					       typename VectorTraits<Vector2>::VectorCategory (),
406 					       typename VectorTraits<Vector3>::VectorCategory ());
407 		}
408 
409 		/** Vector in-place subtract.
410 		 * y <- y - x
411 		 * @param y Input vector y; result is stored here
412 		 * @param x Input vector x
413 		 */
414 		template <class Vector1, class Vector2>
subin(Vector1 & y,const Vector2 & x)415 		inline Vector1 &subin (Vector1 &y, const Vector2 &x) const
416 		{
417 			return subinSpecialized (y, x,
418 						 typename VectorTraits<Vector1>::VectorCategory (),
419 						 typename VectorTraits<Vector2>::VectorCategory ());
420 		}
421 
422 		/** Vector negate.
423 		 * res <- -x
424 		 * @param res Vector into which to store result
425 		 * @param x Input vector x
426 		 */
427 		template <class Vector1, class Vector2>
neg(Vector1 & res,const Vector2 & x)428 		inline Vector1 &neg (Vector1 &res, const Vector2 &x) const
429 		{
430 			return negSpecialized (res, x,
431 					       typename VectorTraits<Vector1>::VectorCategory (),
432 					       typename VectorTraits<Vector2>::VectorCategory ());
433 		}
434 
435 		/** Vector in-place negate.
436 		 * y <- -y
437 		 * @param y Input vector y; result is stored here
438 		 */
439 		template <class Vector>
negin(Vector & y)440 		inline Vector &negin (Vector &y) const
441 		{
442 			return neginSpecialized (y, typename VectorTraits<Vector>::VectorCategory ());
443 		}
444 
445 		/** Scalar-vector multiplication.
446 		 * res <- a * x
447 		 * @param res Vector into which to store result
448 		 * @param x Input vector x
449 		 * @param a Input element a
450 		 */
451 		template <class Vector1, class Vector2>
mul(Vector1 & res,const Vector2 & x,const Element & a)452 		inline Vector1 &mul (Vector1 &res, const Vector2 &x, const Element &a) const
453 		{
454 			return mulSpecialized (res, x, a, typename VectorTraits<Vector1>::VectorCategory ());
455 		}
456 
457 		/** In-place scalar-vector multiplication.
458 		 * x <- a * x
459 		 * @param x Input vector x
460 		 * @param a Input element a
461 		 */
462 		template <class Vector>
mulin(Vector & x,const Element & a)463 		inline Vector &mulin (Vector &x, const Element &a) const
464 		{
465 			return mulinSpecialized (x, a, typename VectorTraits<Vector>::VectorCategory ());
466 		}
467 
468 		/** Vector axpy.
469 		 * res <- y + a*x
470 		 * @param res Vector into which to store result
471 		 * @param a Scalar element a
472 		 * @param x Input vector x
473 		 * @param y Input vector y
474 		 */
475 		template <class Vector1, class Vector2, class Vector3>
axpy(Vector1 & res,const Element & a,const Vector2 & x,const Vector3 & y)476 		inline Vector1 &axpy (Vector1 &res, const Element &a, const Vector2 &x, const Vector3 &y) const
477 		{
478 			return axpySpecialized (res, y, a, x, typename VectorTraits<Vector1>::VectorCategory ());
479 		}
480 
481 		/** Vector in-place axpy.
482 		 * y <- y + a*x
483 		 * @param y Input vector y; result is stored here
484 		 * @param a Scalar element a
485 		 * @param x Input vector x
486 		 */
487 		template <class Vector1, class Vector2>
axpyin(Vector1 & y,const Element & a,const Vector2 & x)488 		inline Vector1 &axpyin (Vector1 &y, const Element &a, const Vector2 &x) const
489 		{
490 			return axpyinSpecialized (y, a, x,
491 						  typename VectorTraits<Vector1>::VectorCategory (),
492 						  typename VectorTraits<Vector2>::VectorCategory ());
493 		}
494 
495 		//@} Vector arithmetic operations
496 
497 		/** @name Reordering and permutation operations
498 		 * These routines provide support for swapping vectors and
499 		 * permuting their entries.
500 		 */
501 
502 		//@{
503 
504 		/** Permutation.
505 		 *
506 		 * A permutation is represented as a vector of pairs, each
507 		 * pair representing a transposition.
508 		 */
509 		typedef std::pair<unsigned int, unsigned int> Transposition;
510 		typedef std::vector<Transposition> Permutation;
511 
512 		/** Swap the contents of the two given vectors.
513 		 *
514 		 * @param v1 First vector
515 		 * @param v2 Second vector
516 		 */
517 		template <class Vector>
swap(Vector & v1,Vector & v2)518 		inline void swap (Vector &v1, Vector &v2) const
519 		{
520 			swapSpecialized (v1, v2, typename VectorTraits<Vector>::VectorCategory ());
521 		}
522 
523 		/** Permute the entries of a given vector using the given
524 		 * permutation.
525 		 *
526 		 * @param v Vector to permute
527 		 * @param P_start Iterator of the start of the permutation to apply
528 		 * @param P_end Iterator of the end of the permutation to apply
529 		 * @return Reference to v
530 		 */
531 		template <class Vector, class Iterator>
permute(Vector & v,Iterator P_start,Iterator P_end)532 		inline Vector &permute (Vector   &v,
533 					Iterator  P_start,
534 					Iterator  P_end) const
535 		{
536 			return permuteSpecialized (v, P_start, P_end,
537 						   typename VectorTraits<Vector>::VectorCategory ());
538 		}
539 
540 		//@}
541 
542 
543 		/*! Random vector.
544 		 * @param v vector to be randomized.
545 		 */
546 		template <class Vector>
random(Vector & v)547 		Vector& random(Vector& v)
548 		{
549 			typename Field::RandIter r(field());
550 
551 			typedef typename Vector::iterator iterator;
552 			for (iterator p = v.begin(); p != v.end(); ++p) r.random(*p);
553 			return v;
554 		}
555 
556 	protected:
557 
558 		// Specialized function implementations
559 		template <class Vector>
560 		std::ostream &writeSpecialized (std::ostream &os, const Vector &x,
561 						VectorCategories::DenseVectorTag) const;
562 		template <class Vector>
563 		std::ostream &writeSpecialized (std::ostream &os, const Vector &x,
564 						VectorCategories::SparseSequenceVectorTag) const;
565 		template <class Vector>
566 		std::ostream &writeSpecialized (std::ostream &os, const Vector &x,
567 						VectorCategories::SparseAssociativeVectorTag) const;
568 		template <class Vector>
569 		std::ostream &writeSpecialized (std::ostream &os, const Vector &x,
570 						VectorCategories::SparseParallelVectorTag) const;
571 
572 		template <class Vector>
573 		std::istream &readSpecialized (std::istream &is, Vector &x,
574 					       VectorCategories::DenseVectorTag) const;
575 		template <class Vector>
576 		std::istream &readSpecialized (std::istream &is, Vector &x,
577 					       VectorCategories::SparseSequenceVectorTag) const;
578 		template <class Vector>
579 		std::istream &readSpecialized (std::istream &is, Vector &x,
580 					       VectorCategories::SparseAssociativeVectorTag) const;
581 		template <class Vector>
582 		std::istream &readSpecialized (std::istream &is, Vector &x,
583 					       VectorCategories::SparseParallelVectorTag) const;
584 
585 		template <class Vector1, class Vector2>
586 		bool areEqualSpecialized (const Vector1 &v1, const Vector2 &v2,
587 					  VectorCategories::DenseVectorTag,
588 					  VectorCategories::DenseVectorTag) const;
589 		template <class Vector1, class Vector2>
590 		bool areEqualSpecialized (const Vector1 &v1, const Vector2 &v2,
591 					  VectorCategories::SparseSequenceVectorTag,
592 					  VectorCategories::DenseVectorTag) const;
593 		template <class Vector1, class Vector2>
594 		bool areEqualSpecialized (const Vector1 &v1, const Vector2 &v2,
595 					  VectorCategories::SparseAssociativeVectorTag,
596 					  VectorCategories::DenseVectorTag) const;
597 		template <class Vector1, class Vector2>
598 		bool areEqualSpecialized (const Vector1 &v1, const Vector2 &v2,
599 					  VectorCategories::SparseParallelVectorTag,
600 					  VectorCategories::DenseVectorTag) const;
601 
602 		template <class Vector1, class Vector2>
areEqualSpecialized(const Vector1 & v1,const Vector2 & v2,VectorCategories::DenseVectorTag,VectorCategories::SparseSequenceVectorTag)603 		bool areEqualSpecialized (const Vector1 &v1, const Vector2 &v2,
604 					  VectorCategories::DenseVectorTag,
605 					  VectorCategories::SparseSequenceVectorTag) const
606 		{
607 			return areEqual (v2, v1);
608 		}
609 		template <class Vector1, class Vector2>
610 		bool areEqualSpecialized (const Vector1 &v1, const Vector2 &v2,
611 					  VectorCategories::SparseSequenceVectorTag,
612 					  VectorCategories::SparseSequenceVectorTag) const;
613 		template <class Vector1, class Vector2>
614 		bool areEqualSpecialized (const Vector1 &v1, const Vector2 &v2,
615 					  VectorCategories::SparseAssociativeVectorTag,
616 					  VectorCategories::SparseSequenceVectorTag) const;
617 		template <class Vector1, class Vector2>
618 		bool areEqualSpecialized (const Vector1 &v1, const Vector2 &v2,
619 					  VectorCategories::SparseParallelVectorTag,
620 					  VectorCategories::SparseSequenceVectorTag) const;
621 
622 		template <class Vector1, class Vector2>
areEqualSpecialized(const Vector1 & v1,const Vector2 & v2,VectorCategories::DenseVectorTag,VectorCategories::SparseAssociativeVectorTag)623 		bool areEqualSpecialized (const Vector1 &v1, const Vector2 &v2,
624 					  VectorCategories::DenseVectorTag,
625 					  VectorCategories::SparseAssociativeVectorTag) const
626 		{
627 			return areEqual (v2, v1);
628 		}
629 		template <class Vector1, class Vector2>
areEqualSpecialized(const Vector1 & v1,const Vector2 & v2,VectorCategories::SparseSequenceVectorTag,VectorCategories::SparseAssociativeVectorTag)630 		inline bool areEqualSpecialized (const Vector1 &v1, const Vector2 &v2,
631 						 VectorCategories::SparseSequenceVectorTag,
632 						 VectorCategories::SparseAssociativeVectorTag) const
633 		{
634 			return areEqual (v2, v1);
635 		}
636 		template <class Vector1, class Vector2>
637 		bool areEqualSpecialized (const Vector1 &v1, const Vector2 &v2,
638 					  VectorCategories::SparseAssociativeVectorTag,
639 					  VectorCategories::SparseAssociativeVectorTag) const;
640 		template <class Vector1, class Vector2>
641 		bool areEqualSpecialized (const Vector1 &v1, const Vector2 &v2,
642 					  VectorCategories::SparseParallelVectorTag,
643 					  VectorCategories::SparseAssociativeVectorTag) const;
644 
645 		template <class Vector1, class Vector2>
areEqualSpecialized(const Vector1 & v1,const Vector2 & v2,VectorCategories::DenseVectorTag,VectorCategories::SparseParallelVectorTag)646 		bool areEqualSpecialized (const Vector1 &v1, const Vector2 &v2,
647 					  VectorCategories::DenseVectorTag,
648 					  VectorCategories::SparseParallelVectorTag) const
649 		{
650 			return areEqual (v2, v1);
651 		}
652 		template <class Vector1, class Vector2>
areEqualSpecialized(const Vector1 & v1,const Vector2 & v2,VectorCategories::SparseSequenceVectorTag,VectorCategories::SparseParallelVectorTag)653 		inline bool areEqualSpecialized (const Vector1 &v1, const Vector2 &v2,
654 						 VectorCategories::SparseSequenceVectorTag,
655 						 VectorCategories::SparseParallelVectorTag) const
656 		{
657 			return areEqual (v2, v1);
658 		}
659 		template <class Vector1, class Vector2>
areEqualSpecialized(const Vector1 & v1,const Vector2 & v2,VectorCategories::SparseAssociativeVectorTag,VectorCategories::SparseParallelVectorTag)660 		inline bool areEqualSpecialized (const Vector1 &v1, const Vector2 &v2,
661 						 VectorCategories::SparseAssociativeVectorTag,
662 						 VectorCategories::SparseParallelVectorTag) const
663 		{
664 			return areEqual (v2, v1);
665 		}
666 		template <class Vector1, class Vector2>
667 		bool areEqualSpecialized (const Vector1 &v1, const Vector2 &v2,
668 					  VectorCategories::SparseParallelVectorTag,
669 					  VectorCategories::SparseParallelVectorTag) const;
670 
671 		template <class Vector>
672 		bool isZeroSpecialized (const Vector &v, VectorCategories::DenseVectorTag) const;
673 		template <class Vector>
674 		bool isZeroSpecialized (const Vector &v, VectorCategories::SparseSequenceVectorTag) const;
675 		template <class Vector>
676 		bool isZeroSpecialized (const Vector &v, VectorCategories::SparseAssociativeVectorTag) const;
677 		template <class Vector>
678 		bool isZeroSpecialized (const Vector &v, VectorCategories::SparseParallelVectorTag) const;
679 
680 		template <class Vector1, class Vector2>
copySpecialized(Vector1 & res,const Vector2 & v,VectorCategories::DenseVectorTag,VectorCategories::DenseVectorTag)681 		inline Vector1 &copySpecialized (Vector1 &res, const Vector2 &v,
682 						 VectorCategories::DenseVectorTag,
683 						 VectorCategories::DenseVectorTag) const
684 		{ std::copy (v.begin (), v.end (), res.begin ()); return res;
685 		}
686 		template <class Vector1, class Vector2>
687 		Vector1 &copySpecialized (Vector1 &res, const Vector2 &v,
688 					  VectorCategories::SparseSequenceVectorTag,
689 					  VectorCategories::DenseVectorTag) const;
690 		template <class Vector1, class Vector2>
691 		Vector1 &copySpecialized (Vector1 &res, const Vector2 &v,
692 					  VectorCategories::SparseAssociativeVectorTag,
693 					  VectorCategories::DenseVectorTag) const;
694 		template <class Vector1, class Vector2>
695 		Vector1 &copySpecialized (Vector1 &res, const Vector2 &v,
696 					  VectorCategories::SparseParallelVectorTag,
697 					  VectorCategories::DenseVectorTag) const;
698 
699 		template <class Vector1, class Vector2>
700 		Vector1 &copySpecialized (Vector1 &res, const Vector2 &v,
701 					  VectorCategories::DenseVectorTag,
702 					  VectorCategories::SparseSequenceVectorTag) const;
703 		template <class Vector1, class Vector2>
copySpecialized(Vector1 & res,const Vector2 & v,VectorCategories::SparseSequenceVectorTag,VectorCategories::SparseSequenceVectorTag)704 		inline Vector1 &copySpecialized (Vector1 &res, const Vector2 &v,
705 						 VectorCategories::SparseSequenceVectorTag,
706 						 VectorCategories::SparseSequenceVectorTag) const
707 		{
708 			res.resize (v.size ()); std::copy (v.begin (), v.end (), res.begin ()); return res;
709 		}
710 		template <class Vector1, class Vector2>
711 		Vector1 &copySpecialized (Vector1 &res, const Vector2 &v,
712 					  VectorCategories::SparseAssociativeVectorTag,
713 					  VectorCategories::SparseSequenceVectorTag) const;
714 		template <class Vector1, class Vector2>
715 		Vector1 &copySpecialized (Vector1 &res, const Vector2 &v,
716 					  VectorCategories::SparseParallelVectorTag,
717 					  VectorCategories::SparseSequenceVectorTag) const;
718 
719 		template <class Vector1, class Vector2>
720 		Vector1 &copySpecialized (Vector1 &res, const Vector2 &v,
721 					  VectorCategories::DenseVectorTag,
722 					  VectorCategories::SparseAssociativeVectorTag) const;
723 		template <class Vector1, class Vector2>
724 		Vector1 &copySpecialized (Vector1 &res, const Vector2 &v,
725 					  VectorCategories::SparseSequenceVectorTag,
726 					  VectorCategories::SparseAssociativeVectorTag) const;
727 		template <class Vector1, class Vector2>
728 		Vector1 &copySpecialized (Vector1 &res, const Vector2 &v,
729 					  VectorCategories::SparseAssociativeVectorTag,
730 					  VectorCategories::SparseAssociativeVectorTag) const;
731 		template <class Vector1, class Vector2>
732 		Vector1 &copySpecialized (Vector1 &res, const Vector2 &v,
733 					  VectorCategories::SparseParallelVectorTag,
734 					  VectorCategories::SparseAssociativeVectorTag) const;
735 
736 		template <class Vector1, class Vector2>
737 		Vector1 &copySpecialized (Vector1 &res, const Vector2 &v,
738 					  VectorCategories::DenseVectorTag,
739 					  VectorCategories::SparseParallelVectorTag) const;
740 		template <class Vector1, class Vector2>
741 		Vector1 &copySpecialized (Vector1 &res, const Vector2 &v,
742 					  VectorCategories::SparseSequenceVectorTag,
743 					  VectorCategories::SparseParallelVectorTag) const;
744 		template <class Vector1, class Vector2>
745 		Vector1 &copySpecialized (Vector1 &res, const Vector2 &v,
746 					  VectorCategories::SparseAssociativeVectorTag,
747 					  VectorCategories::SparseParallelVectorTag) const;
748 		template <class Vector1, class Vector2>
749 		Vector1 &copySpecialized (Vector1 &res, const Vector2 &v,
750 					  VectorCategories::SparseParallelVectorTag,
751 					  VectorCategories::SparseParallelVectorTag) const;
752 
753 		template <class Vector1, class Vector2>
754 		Vector1 &copySpecialized (Vector1 &res, const Vector2 &v, size_t i, size_t len,
755 					  VectorCategories::DenseVectorTag) const;
756 		template <class Vector1, class Vector2>
757 		Vector1 &copySpecialized (Vector1 &res, const Vector2 &v, size_t i, size_t len,
758 					  VectorCategories::SparseSequenceVectorTag) const;
759 		template <class Vector1, class Vector2>
760 		Vector1 &copySpecialized (Vector1 &res, const Vector2 &v, size_t i, size_t len,
761 					  VectorCategories::SparseAssociativeVectorTag) const;
762 		template <class Vector1, class Vector2>
763 		Vector1 &copySpecialized (Vector1 &res, const Vector2 &v, size_t i, size_t len,
764 					  VectorCategories::SparseParallelVectorTag) const;
765 
766 		// These versions are optimized for the case where one is
767 		// copying between vectors of the same type. It avoids
768 		// additional memory allocation and copying.
769 		template <class Vector>
770 		Vector &copySpecialized (Vector &res, const Vector &v, size_t i, size_t len,
771 					 VectorCategories::DenseVectorTag) const;
772 		template <class Vector>
773 		Vector &copySpecialized (Vector &res, const Vector &v, size_t i, size_t len,
774 					 VectorCategories::SparseSequenceVectorTag) const;
775 		template <class Vector>
776 		Vector &copySpecialized (Vector &res, const Vector &v, size_t i, size_t len,
777 					 VectorCategories::SparseAssociativeVectorTag) const;
778 		template <class Vector>
779 		Vector &copySpecialized (Vector &res, const Vector &v, size_t i, size_t len,
780 					 VectorCategories::SparseParallelVectorTag) const;
781 
782 		template <class Vector1, class Vector2>
dotSpecialized(Element & res,const Vector1 & v1,const Vector2 & v2,VectorCategories::DenseVectorTag,VectorCategories::DenseVectorTag)783 		inline Element &dotSpecialized (Element &res, const Vector1 &v1, const Vector2 &v2,
784 						VectorCategories::DenseVectorTag,
785 						VectorCategories::DenseVectorTag) const
786 		{
787 			return DotProductDomain<Field>:: dotSpecializedDD (res, v1, v2);
788 		}
789 
790 		template <class Vector1, class Vector2>
791 		inline Element &dotSpecialized (Element &res, const Vector1 &v1, const Vector2 &v2,
792 						VectorCategories::SparseSequenceVectorTag,
793 						VectorCategories::DenseVectorTag) const;
794 		template <class Vector1, class Vector2>
795 		inline Element &dotSpecialized (Element &res, const Vector1 &v1, const Vector2 &v2,
796 						VectorCategories::SparseAssociativeVectorTag,
797 						VectorCategories::DenseVectorTag) const;
798 		template <class Vector1, class Vector2>
dotSpecialized(Element & res,const Vector1 & v1,const Vector2 & v2,VectorCategories::SparseParallelVectorTag,VectorCategories::DenseVectorTag)799 		inline Element &dotSpecialized (Element &res, const Vector1 &v1, const Vector2 &v2,
800 						VectorCategories::SparseParallelVectorTag,
801 						VectorCategories::DenseVectorTag) const
802 		{
803 			return DotProductDomain<Field>::dotSpecializedDSP (res, v1, v2);
804 		}
805 
806 		template <class Vector1, class Vector2>
dotSpecialized(Element & res,const Vector1 & v1,const Vector2 & v2,VectorCategories::DenseVectorTag,VectorCategories::SparseSequenceVectorTag)807 		inline Element &dotSpecialized (Element &res, const Vector1 &v1, const Vector2 &v2,
808 						VectorCategories::DenseVectorTag,
809 						VectorCategories::SparseSequenceVectorTag) const
810 		{
811 			return dot (res, v2, v1);
812 		}
813 		template <class Vector1, class Vector2>
814 		inline Element &dotSpecialized (Element &res, const Vector1 &v1, const Vector2 &v2,
815 						VectorCategories::SparseSequenceVectorTag,
816 						VectorCategories::SparseSequenceVectorTag) const;
817 		template <class Vector1, class Vector2>
818 		inline Element &dotSpecialized (Element &res, const Vector1 &v1, const Vector2 &v2,
819 						VectorCategories::SparseAssociativeVectorTag,
820 						VectorCategories::SparseSequenceVectorTag) const;
821 		template <class Vector1, class Vector2>
822 		inline Element &dotSpecialized (Element &res, const Vector1 &v1, const Vector2 &v2,
823 						VectorCategories::SparseParallelVectorTag,
824 						VectorCategories::SparseSequenceVectorTag) const;
825 
826 		template <class Vector1, class Vector2>
dotSpecialized(Element & res,const Vector1 & v1,const Vector2 & v2,VectorCategories::DenseVectorTag,VectorCategories::SparseAssociativeVectorTag)827 		inline Element &dotSpecialized (Element &res, const Vector1 &v1, const Vector2 &v2,
828 						VectorCategories::DenseVectorTag,
829 						VectorCategories::SparseAssociativeVectorTag) const
830 		{
831 			return dot (res, v2, v1);
832 		}
833 		template <class Vector1, class Vector2>
dotSpecialized(Element & res,const Vector1 & v1,const Vector2 & v2,VectorCategories::SparseSequenceVectorTag,VectorCategories::SparseAssociativeVectorTag)834 		inline Element &dotSpecialized (Element &res, const Vector1 &v1, const Vector2 &v2,
835 						VectorCategories::SparseSequenceVectorTag,
836 						VectorCategories::SparseAssociativeVectorTag) const
837 		{
838 			return dot (res, v2, v1);
839 		}
840 		template <class Vector1, class Vector2>
841 		inline Element &dotSpecialized (Element &res, const Vector1 &v1, const Vector2 &v2,
842 						VectorCategories::SparseAssociativeVectorTag,
843 						VectorCategories::SparseAssociativeVectorTag) const;
844 		template <class Vector1, class Vector2>
845 		inline Element &dotSpecialized (Element &res, const Vector1 &v1, const Vector2 &v2,
846 						VectorCategories::SparseParallelVectorTag,
847 						VectorCategories::SparseAssociativeVectorTag) const;
848 
849 		template <class Vector1, class Vector2>
dotSpecialized(Element & res,const Vector1 & v1,const Vector2 & v2,VectorCategories::DenseVectorTag,VectorCategories::SparseParallelVectorTag)850 		inline Element &dotSpecialized (Element &res, const Vector1 &v1, const Vector2 &v2,
851 						VectorCategories::DenseVectorTag,
852 						VectorCategories::SparseParallelVectorTag) const
853 		{
854 			return dot (res, v2, v1);
855 		}
856 		template <class Vector1, class Vector2>
dotSpecialized(Element & res,const Vector1 & v1,const Vector2 & v2,VectorCategories::SparseSequenceVectorTag,VectorCategories::SparseParallelVectorTag)857 		inline Element &dotSpecialized (Element &res, const Vector1 &v1, const Vector2 &v2,
858 						VectorCategories::SparseSequenceVectorTag,
859 						VectorCategories::SparseParallelVectorTag) const
860 		{
861 			return dot (res, v2, v1);
862 		}
863 		template <class Vector1, class Vector2>
dotSpecialized(Element & res,const Vector1 & v1,const Vector2 & v2,VectorCategories::SparseAssociativeVectorTag,VectorCategories::SparseParallelVectorTag)864 		inline Element &dotSpecialized (Element &res, const Vector1 &v1, const Vector2 &v2,
865 						VectorCategories::SparseAssociativeVectorTag,
866 						VectorCategories::SparseParallelVectorTag) const
867 		{
868 			return dot (res, v2, v1);
869 		}
870 		template <class Vector1, class Vector2>
871 		inline Element &dotSpecialized (Element &res, const Vector1 &v1, const Vector2 &v2,
872 						VectorCategories::SparseParallelVectorTag,
873 						VectorCategories::SparseParallelVectorTag) const;
874 
875 		template <class Vector1, class Vector2, class Vector3>
876 		Vector1 &addSpecialized (Vector1 &res, const Vector2 &y, const Vector3 &x,
877 					 VectorCategories::DenseVectorTag,
878 					 VectorCategories::DenseVectorTag,
879 					 VectorCategories::DenseVectorTag) const;
880 		template <class Vector1, class Vector2, class Vector3>
881 		Vector1 &addSpecialized (Vector1 &res, const Vector2 &y, const Vector3 &x,
882 					 VectorCategories::SparseSequenceVectorTag,
883 					 VectorCategories::SparseSequenceVectorTag,
884 					 VectorCategories::SparseSequenceVectorTag) const;
885 		template <class Vector1, class Vector2, class Vector3>
886 		Vector1 &addSpecialized (Vector1 &res, const Vector2 &y, const Vector3 &x,
887 					 VectorCategories::SparseAssociativeVectorTag,
888 					 VectorCategories::SparseAssociativeVectorTag,
889 					 VectorCategories::SparseAssociativeVectorTag) const;
890 		template <class Vector1, class Vector2, class Vector3>
891 		Vector1 &addSpecialized (Vector1 &res, const Vector2 &y, const Vector3 &x,
892 					 VectorCategories::SparseParallelVectorTag,
893 					 VectorCategories::SparseParallelVectorTag,
894 					 VectorCategories::SparseParallelVectorTag) const;
895 
896 		template <class Vector1, class Vector2>
897 		Vector1 &addinSpecialized (Vector1 &y, const Vector2 &x,
898 					   VectorCategories::DenseVectorTag,
899 					   VectorCategories::DenseVectorTag) const;
900 		template <class Vector1, class Vector2>
901 		Vector1 &addinSpecialized (Vector1 &y, const Vector2 &x,
902 					   VectorCategories::SparseSequenceVectorTag,
903 					   VectorCategories::SparseSequenceVectorTag) const;
904 		template <class Vector1, class Vector2>
905 		Vector1 &addinSpecialized (Vector1 &y, const Vector2 &x,
906 					   VectorCategories::SparseAssociativeVectorTag,
907 					   VectorCategories::SparseAssociativeVectorTag) const;
908 		template <class Vector1, class Vector2>
909 		Vector1 &addinSpecialized (Vector1 &y, const Vector2 &x,
910 					   VectorCategories::SparseParallelVectorTag,
911 					   VectorCategories::SparseParallelVectorTag) const;
912 
913 		template <class Vector1, class Vector2, class Vector3>
914 		Vector1 &subSpecialized (Vector1 &res, const Vector2 &y, const Vector3 &x,
915 					 VectorCategories::DenseVectorTag,
916 					 VectorCategories::DenseVectorTag,
917 					 VectorCategories::DenseVectorTag) const;
918 		template <class Vector1, class Vector2, class Vector3>
919 		Vector1 &subSpecialized (Vector1 &res, const Vector2 &y, const Vector3 &x,
920 					 VectorCategories::SparseSequenceVectorTag,
921 					 VectorCategories::SparseSequenceVectorTag,
922 					 VectorCategories::SparseSequenceVectorTag) const;
923 		template <class Vector1, class Vector2, class Vector3>
924 		Vector1 &subSpecialized (Vector1 &res, const Vector2 &y, const Vector3 &x,
925 					 VectorCategories::SparseAssociativeVectorTag,
926 					 VectorCategories::SparseAssociativeVectorTag,
927 					 VectorCategories::SparseAssociativeVectorTag) const;
928 		template <class Vector1, class Vector2, class Vector3>
929 		Vector1 &subSpecialized (Vector1 &res, const Vector2 &y, const Vector3 &x,
930 					 VectorCategories::SparseParallelVectorTag,
931 					 VectorCategories::SparseParallelVectorTag,
932 					 VectorCategories::SparseParallelVectorTag) const;
933 
934 		template <class Vector1, class Vector2>
935 		Vector1 &subinSpecialized (Vector1 &y, const Vector2 &x,
936 					   VectorCategories::DenseVectorTag,
937 					   VectorCategories::DenseVectorTag) const;
938 		template <class Vector1, class Vector2>
939 		Vector1 &subinSpecialized (Vector1 &y, const Vector2 &x,
940 					   VectorCategories::SparseSequenceVectorTag,
941 					   VectorCategories::SparseSequenceVectorTag) const;
942 		template <class Vector1, class Vector2>
943 		Vector1 &subinSpecialized (Vector1 &y, const Vector2 &x,
944 					   VectorCategories::SparseAssociativeVectorTag,
945 					   VectorCategories::SparseAssociativeVectorTag) const;
946 		template <class Vector1, class Vector2>
947 		Vector1 &subinSpecialized (Vector1 &y, const Vector2 &x,
948 					   VectorCategories::SparseParallelVectorTag,
949 					   VectorCategories::SparseParallelVectorTag) const;
950 
951 		template <class Vector1, class Vector2>
952 		Vector1 &negSpecialized (Vector1 &res, const Vector2 &x,
953 					 VectorCategories::DenseVectorTag,
954 					 VectorCategories::DenseVectorTag) const;
955 		template <class Vector1, class Vector2>
956 		Vector1 &negSpecialized (Vector1 &res, const Vector2 &x,
957 					 VectorCategories::SparseSequenceVectorTag,
958 					 VectorCategories::SparseSequenceVectorTag) const;
959 		template <class Vector1, class Vector2>
960 		Vector1 &negSpecialized (Vector1 &res, const Vector2 &x,
961 					 VectorCategories::SparseAssociativeVectorTag,
962 					 VectorCategories::SparseAssociativeVectorTag) const;
963 		template <class Vector1, class Vector2>
964 		Vector1 &negSpecialized (Vector1 &res, const Vector2 &x,
965 					 VectorCategories::SparseParallelVectorTag,
966 					 VectorCategories::SparseParallelVectorTag) const;
967 
968 		template <class Vector>
969 		Vector &neginSpecialized (Vector &y,
970 					  VectorCategories::DenseVectorTag) const;
971 		template <class Vector>
972 		Vector &neginSpecialized (Vector &y,
973 					  VectorCategories::SparseSequenceVectorTag) const;
974 		template <class Vector>
975 		Vector &neginSpecialized (Vector &y,
976 					  VectorCategories::SparseAssociativeVectorTag) const;
977 		template <class Vector>
978 		Vector &neginSpecialized (Vector &y,
979 					  VectorCategories::SparseParallelVectorTag) const;
980 
981 		template <class Vector1, class Vector2>
982 		Vector1 &mulSpecialized (Vector1 &res, const Vector2 &x, const Element &a,
983 					 VectorCategories::DenseVectorTag) const;
984 		template <class Vector1, class Vector2>
985 		Vector1 &mulSpecialized (Vector1 &res, const Vector2 &x, const Element &a,
986 					 VectorCategories::SparseSequenceVectorTag) const;
987 		template <class Vector1, class Vector2>
988 		Vector1 &mulSpecialized (Vector1 &res, const Vector2 &x, const Element &a,
989 					 VectorCategories::SparseAssociativeVectorTag) const;
990 		template <class Vector1, class Vector2>
991 		Vector1 &mulSpecialized (Vector1 &res, const Vector2 &x, const Element &a,
992 					 VectorCategories::SparseParallelVectorTag) const;
993 
994 		template <class Vector>
995 		Vector &mulinSpecialized (Vector &x, const Element &a,
996 					  VectorCategories::DenseVectorTag) const;
997 		template <class Vector>
998 		Vector &mulinSpecialized (Vector &x, const Element &a,
999 					  VectorCategories::SparseSequenceVectorTag) const;
1000 		template <class Vector>
1001 		Vector &mulinSpecialized (Vector &x, const Element &a,
1002 					  VectorCategories::SparseAssociativeVectorTag) const;
1003 		template <class Vector>
1004 		Vector &mulinSpecialized (Vector &x, const Element &a,
1005 					  VectorCategories::SparseParallelVectorTag) const;
1006 
1007 		template <class Vector1, class Vector2, class Vector3>
1008 		Vector1 &axpySpecialized (Vector1 &res, const Vector2 &y,
1009 					  const Element &a, const Vector3 &x,
1010 					  VectorCategories::DenseVectorTag) const;
1011 		template <class Vector1, class Vector2, class Vector3>
1012 		Vector1 &axpySpecialized (Vector1 &res, const Vector2 &y,
1013 					  const Element &a, const Vector3 &x,
1014 					  VectorCategories::SparseSequenceVectorTag) const;
1015 		template <class Vector1, class Vector2, class Vector3>
1016 		Vector1 &axpySpecialized (Vector1 &res, const Vector2 &y,
1017 					  const Element &a, const Vector3 &x,
1018 					  VectorCategories::SparseAssociativeVectorTag) const;
1019 		template <class Vector1, class Vector2, class Vector3>
1020 		Vector1 &axpySpecialized (Vector1 &res, const Vector2 &y,
1021 					  const Element &a, const Vector3 &x,
1022 					  VectorCategories::SparseParallelVectorTag) const;
1023 
1024 		template <class Vector1, class Vector2>
1025 		Vector1 &axpyinSpecialized (Vector1 &y, const Element &a, const Vector2 &x,
1026 					    VectorCategories::DenseVectorTag,
1027 					    VectorCategories::DenseVectorTag) const;
1028 		template <class Vector1, class Vector2>
1029 		Vector1 &axpyinSpecialized (Vector1 &y, const Element &a, const Vector2 &x,
1030 					    VectorCategories::DenseVectorTag,
1031 					    VectorCategories::SparseSequenceVectorTag) const;
1032 		template <class Vector1, class Vector2>
1033 		Vector1 &axpyinSpecialized (Vector1 &y, const Element &a, const Vector2 &x,
1034 					    VectorCategories::DenseVectorTag,
1035 					    VectorCategories::SparseAssociativeVectorTag) const;
1036 		template <class Vector1, class Vector2>
1037 		Vector1 &axpyinSpecialized (Vector1 &y, const Element &a, const Vector2 &x,
1038 					    VectorCategories::DenseVectorTag,
1039 					    VectorCategories::SparseParallelVectorTag) const;
1040 		template <class Vector1, class Vector2>
1041 		Vector1 &axpyinSpecialized (Vector1 &y, const Element &a, const Vector2 &x,
1042 					    VectorCategories::SparseSequenceVectorTag,
1043 					    VectorCategories::SparseSequenceVectorTag) const;
1044 		template <class Vector1, class Vector2>
1045 		Vector1 &axpyinSpecialized (Vector1 &y, const Element &a, const Vector2 &x,
1046 					    VectorCategories::SparseAssociativeVectorTag,
1047 					    VectorCategories::SparseAssociativeVectorTag) const;
1048 		template <class Vector1, class Vector2>
1049 		Vector1 &axpyinSpecialized (Vector1 &y, const Element &a, const Vector2 &x,
1050 					    VectorCategories::SparseParallelVectorTag,
1051 					    VectorCategories::SparseParallelVectorTag) const;
1052 
1053 		// Specializations for the case where the two vectors are of
1054 		// different representations. This is provided for the benefit
1055 		// of MatrixDomain
1056 
1057 		template <class Vector1, class Vector2, class Vector3>
addSpecialized(Vector1 & res,const Vector2 & y,const Vector3 & x,VectorCategories::DenseVectorTag,VectorCategories::DenseVectorTag,VectorCategories::GenericVectorTag)1058 		inline Vector1 &addSpecialized (Vector1 &res, const Vector2 &y, const Vector3 &x,
1059 						VectorCategories::DenseVectorTag,
1060 						VectorCategories::DenseVectorTag,
1061 						VectorCategories::GenericVectorTag) const
1062 		{
1063 			typename LinBox::Vector<Field>::Dense v (res.size ());
1064 
1065 			copy (v, x);
1066 			add (res, y, v);
1067 
1068 			return res;
1069 		}
1070 
1071 		template <class Vector1, class Vector2, class Vector3>
addSpecialized(Vector1 & res,const Vector2 & y,const Vector3 & x,VectorCategories::DenseVectorTag,VectorCategories::GenericVectorTag,VectorCategories::DenseVectorTag)1072 		inline Vector1 &addSpecialized (Vector1 &res, const Vector2 &y, const Vector3 &x,
1073 						VectorCategories::DenseVectorTag,
1074 						VectorCategories::GenericVectorTag,
1075 						VectorCategories::DenseVectorTag) const
1076 		{
1077 			typename LinBox::Vector<Field>::Dense v (res.size ());
1078 
1079 			copy (v, y);
1080 			add (res, v, x);
1081 
1082 			return res;
1083 		}
1084 
1085 		template <class Vector1, class Vector2, class Vector3>
addSpecialized(Vector1 & res,const Vector2 & y,const Vector3 & x,VectorCategories::DenseVectorTag,VectorCategories::GenericVectorTag,VectorCategories::GenericVectorTag)1086 		inline Vector1 &addSpecialized (Vector1 &res, const Vector2 &y, const Vector3 &x,
1087 						VectorCategories::DenseVectorTag,
1088 						VectorCategories::GenericVectorTag,
1089 						VectorCategories::GenericVectorTag) const
1090 		{
1091 			typename LinBox::Vector<Field>::Dense v (res.size ());
1092 			typename LinBox::Vector<Field>::Dense w (res.size ());
1093 
1094 			copy (v, x);
1095 			copy (w, y);
1096 			add (res, w, v);
1097 
1098 			return res;
1099 		}
1100 
1101 		template <class Vector1, class Vector2, class Vector3>
addSpecialized(Vector1 & res,const Vector2 & y,const Vector3 & x,VectorCategories::GenericVectorTag,VectorCategories::GenericVectorTag,VectorCategories::GenericVectorTag)1102 		inline Vector1 &addSpecialized (Vector1 &res, const Vector2 &y, const Vector3 &x,
1103 						VectorCategories::GenericVectorTag,
1104 						VectorCategories::GenericVectorTag,
1105 						VectorCategories::GenericVectorTag) const
1106 		{
1107 			typename LinBox::Vector<Field>::Sparse v;
1108 			typename LinBox::Vector<Field>::Sparse w;
1109 			typename LinBox::Vector<Field>::Sparse u;
1110 
1111 			copy (v, x);
1112 			copy (w, y);
1113 			add (u, w, v);
1114 			copy (res, u);
1115 
1116 			return res;
1117 		}
1118 
1119 		template <class Vector1, class Vector2>
addinSpecialized(Vector1 & y,const Vector2 & x,VectorCategories::DenseVectorTag,VectorCategories::GenericVectorTag)1120 		inline Vector1 &addinSpecialized (Vector1 &y, const Vector2 &x,
1121 						  VectorCategories::DenseVectorTag,
1122 						  VectorCategories::GenericVectorTag) const
1123 		{
1124 			typename LinBox::Vector<Field>::Dense v (y.size ());
1125 
1126 			copy (v, x);
1127 			addin (y, v);
1128 
1129 			return y;
1130 		}
1131 
1132 		template <class Vector1, class Vector2>
addinSpecialized(Vector1 & y,const Vector2 & x,VectorCategories::GenericVectorTag,VectorCategories::GenericVectorTag)1133 		inline Vector1 &addinSpecialized (Vector1 &y, const Vector2 &x,
1134 						  VectorCategories::GenericVectorTag,
1135 						  VectorCategories::GenericVectorTag) const
1136 		{
1137 			typename LinBox::Vector<Field>::Sparse v;
1138 			typename LinBox::Vector<Field>::Sparse w;
1139 
1140 			copy (v, x);
1141 			addin (w, v);
1142 			copy (y, w);
1143 
1144 			return y;
1145 		}
1146 
1147 		template <class Vector1, class Vector2, class Vector3>
subSpecialized(Vector1 & res,const Vector2 & y,const Vector3 & x,VectorCategories::DenseVectorTag,VectorCategories::DenseVectorTag,VectorCategories::GenericVectorTag)1148 		inline Vector1 &subSpecialized (Vector1 &res, const Vector2 &y, const Vector3 &x,
1149 						VectorCategories::DenseVectorTag,
1150 						VectorCategories::DenseVectorTag,
1151 						VectorCategories::GenericVectorTag) const
1152 		{
1153 			typename LinBox::Vector<Field>::Dense v (res.size ());
1154 
1155 			copy (v, x);
1156 			sub (res, y, v);
1157 
1158 			return res;
1159 		}
1160 
1161 		template <class Vector1, class Vector2, class Vector3>
subSpecialized(Vector1 & res,const Vector2 & y,const Vector3 & x,VectorCategories::DenseVectorTag,VectorCategories::GenericVectorTag,VectorCategories::DenseVectorTag)1162 		inline Vector1 &subSpecialized (Vector1 &res, const Vector2 &y, const Vector3 &x,
1163 						VectorCategories::DenseVectorTag,
1164 						VectorCategories::GenericVectorTag,
1165 						VectorCategories::DenseVectorTag) const
1166 		{
1167 			typename LinBox::Vector<Field>::Dense v (res.size ());
1168 
1169 			copy (v, y);
1170 			sub (res, v, x);
1171 
1172 			return res;
1173 		}
1174 
1175 		template <class Vector1, class Vector2, class Vector3>
subSpecialized(Vector1 & res,const Vector2 & y,const Vector3 & x,VectorCategories::DenseVectorTag,VectorCategories::GenericVectorTag,VectorCategories::GenericVectorTag)1176 		inline Vector1 &subSpecialized (Vector1 &res, const Vector2 &y, const Vector3 &x,
1177 						VectorCategories::DenseVectorTag,
1178 						VectorCategories::GenericVectorTag,
1179 						VectorCategories::GenericVectorTag) const
1180 		{
1181 			typename LinBox::Vector<Field>::Dense v (res.size ());
1182 			typename LinBox::Vector<Field>::Dense w (res.size ());
1183 
1184 			copy (v, x);
1185 			copy (w, y);
1186 			sub (res, w, v);
1187 
1188 			return res;
1189 		}
1190 
1191 		template <class Vector1, class Vector2, class Vector3>
subSpecialized(Vector1 & res,const Vector2 & y,const Vector3 & x,VectorCategories::GenericVectorTag,VectorCategories::GenericVectorTag,VectorCategories::GenericVectorTag)1192 		inline Vector1 &subSpecialized (Vector1 &res, const Vector2 &y, const Vector3 &x,
1193 						VectorCategories::GenericVectorTag,
1194 						VectorCategories::GenericVectorTag,
1195 						VectorCategories::GenericVectorTag) const
1196 		{
1197 			typename LinBox::Vector<Field>::Sparse v;
1198 			typename LinBox::Vector<Field>::Sparse w;
1199 			typename LinBox::Vector<Field>::Sparse u;
1200 
1201 			copy (v, x);
1202 			copy (w, y);
1203 			sub (u, w, v);
1204 			copy (res, u);
1205 
1206 			return res;
1207 		}
1208 
1209 		template <class Vector1, class Vector2>
subinSpecialized(Vector1 & y,const Vector2 & x,VectorCategories::DenseVectorTag,VectorCategories::GenericVectorTag)1210 		inline Vector1 &subinSpecialized (Vector1 &y, const Vector2 &x,
1211 						  VectorCategories::DenseVectorTag,
1212 						  VectorCategories::GenericVectorTag) const
1213 		{
1214 			typename LinBox::Vector<Field>::Dense v (y.size ());
1215 
1216 			copy (v, x);
1217 			subin (y, v);
1218 
1219 			return y;
1220 		}
1221 
1222 		template <class Vector1, class Vector2>
subinSpecialized(Vector1 & y,const Vector2 & x,VectorCategories::GenericVectorTag,VectorCategories::GenericVectorTag)1223 		inline Vector1 &subinSpecialized (Vector1 &y, const Vector2 &x,
1224 						  VectorCategories::GenericVectorTag,
1225 						  VectorCategories::GenericVectorTag) const
1226 		{
1227 			typename LinBox::Vector<Field>::Sparse v;
1228 			typename LinBox::Vector<Field>::Sparse w;
1229 
1230 			copy (v, x);
1231 			subin (w, v);
1232 			copy (y, w);
1233 
1234 			return y;
1235 		}
1236 
1237 		template <class Vector1, class Vector2>
negSpecialized(Vector1 & y,const Vector2 & x,VectorCategories::DenseVectorTag,VectorCategories::GenericVectorTag)1238 		inline Vector1 &negSpecialized (Vector1 &y, const Vector2 &x,
1239 						VectorCategories::DenseVectorTag,
1240 						VectorCategories::GenericVectorTag) const
1241 		{
1242 			typename LinBox::Vector<Field>::Dense v (y.size ());
1243 
1244 			copy (v, x);
1245 			neg (y, v);
1246 
1247 			return y;
1248 		}
1249 
1250 		template <class Vector1, class Vector2>
negSpecialized(Vector1 & y,const Vector2 & x,VectorCategories::GenericVectorTag,VectorCategories::GenericVectorTag)1251 		inline Vector1 &negSpecialized (Vector1 &y, const Vector2 &x,
1252 						VectorCategories::GenericVectorTag,
1253 						VectorCategories::GenericVectorTag) const
1254 		{
1255 			typename LinBox::Vector<Field>::Sparse v;
1256 			typename LinBox::Vector<Field>::Sparse w;
1257 
1258 			copy (v, x);
1259 			neg (w, v);
1260 			copy (y, w);
1261 
1262 			return y;
1263 		}
1264 
1265 		template <class Vector1, class Vector2>
axpyinSpecialized(Vector1 & y,const Element & a,const Vector2 & x,VectorCategories::GenericVectorTag,VectorCategories::GenericVectorTag)1266 		inline Vector1 &axpyinSpecialized (Vector1 &y, const Element &a, const Vector2 &x,
1267 						   VectorCategories::GenericVectorTag,
1268 						   VectorCategories::GenericVectorTag) const
1269 		{
1270 			typename LinBox::Vector<Field>::Sparse v;
1271 			typename LinBox::Vector<Field>::Sparse w;
1272 
1273 			copy (v, x);
1274 			axpyin (w, a, v);
1275 			copy (y, w);
1276 
1277 			return y;
1278 		}
1279 
1280 		template<class Vector>
1281 		inline void swapSpecialized (Vector &v1, Vector &v2,
1282 					     VectorCategories::DenseVectorTag) const;
1283 
1284 		template<class _Vector> // BB : nvcc not happy with class Vector (and I agree :))
swapSpecialized(_Vector & v1,_Vector & v2,VectorCategories::SparseSequenceVectorTag)1285 		inline void swapSpecialized (_Vector &v1, _Vector &v2,
1286 					     VectorCategories::SparseSequenceVectorTag) const
1287 		{
1288 			typename LinBox::Vector<Field>::SparseSeq t;
1289 			t = v1; v1 = v2; v2 = t;
1290 		}
1291 
1292 		template <class _Vector>
swapSpecialized(_Vector & v1,_Vector & v2,VectorCategories::SparseAssociativeVectorTag)1293 		inline void swapSpecialized (_Vector &v1, _Vector &v2,
1294 					     VectorCategories::SparseAssociativeVectorTag) const
1295 		{
1296 			typename LinBox::Vector<Field>::SparseMap t;
1297 			t = v1; v1 = v2; v2 = t;
1298 		}
1299 
1300 		template <class _Vector>
swapSpecialized(_Vector & v1,_Vector & v2,VectorCategories::SparseParallelVectorTag)1301 		inline void swapSpecialized (_Vector &v1, _Vector &v2,
1302 					     VectorCategories::SparseParallelVectorTag) const
1303 		{
1304 			typename LinBox::Vector<Field>::SparsePar t;
1305 			t = v1; v1 = v2; v2 = t;
1306 		}
1307 
1308 		template <class Vector, class Iterator>
1309 		inline Vector &permuteSpecialized (Vector   &v,
1310 						   Iterator  P_start,
1311 						   Iterator  P_end,
1312 						   VectorCategories::DenseVectorTag) const;
1313 		template <class Vector, class Iterator>
1314 		inline Vector &permuteSpecialized (Vector   &v,
1315 						   Iterator  P_start,
1316 						   Iterator  P_end,
1317 						   VectorCategories::SparseSequenceVectorTag) const;
1318 		template <class Vector, class Iterator>
1319 		inline Vector &permuteSpecialized (Vector   &v,
1320 						   Iterator  P_start,
1321 						   Iterator  P_end,
1322 						   VectorCategories::SparseAssociativeVectorTag) const;
1323 		template <class Vector, class Iterator>
1324 		inline Vector &permuteSpecialized (Vector   &v,
1325 						   Iterator  P_start,
1326 						   Iterator  P_end,
1327 						   VectorCategories::SparseParallelVectorTag) const;
1328 	}; // class VectorDomain
1329 
1330 } // namespace LinBox
1331 
1332 
1333 #endif // __LINBOX_field_vector_domain_H
1334 
1335 #include "linbox/vector/vector-domain.inl"
1336 #include "linbox/vector/vector-domain-gf2.h"
1337 
1338 // Local Variables:
1339 // mode: C++
1340 // tab-width: 4
1341 // indent-tabs-mode: nil
1342 // c-basic-offset: 4
1343 // End:
1344 // vim:sts=4:sw=4:ts=4:et:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s
1345