1 /* linbox/vector/stream.h
2  * Copyright (C) 2002 Bradford Hovinen
3  *
4  * Written by Bradford Hovinen <hovinen@cis.udel.edu>
5  *
6  * ------------------------------------
7  * 2003-02-03 Bradford Hovinen <bghovinen@math.uwaterloo.ca>
8  *
9  * RandomSparseStream::RandomSparseStream: put probability parameter before
10  * vector dimension
11  * ------------------------------------
12  * 2002-09-05 Bradford Hovinen <bghovine@math.uwaterloo.ca>
13  *
14  *  - Renamed to stream.h and moved to linbox/vector
15  *  - VectorFactory is now called VectorStream, which fits its purpose
16  *    somewhat better
17  *  - The interface is now closer to the interface for istream
18  *  - RandomDenseVectorFactory, et al. are refactored into classes
19  *    parameterized on the vector type and specialized appropriately. This
20  *    allows, e.g. construction of a random dense vector in sparse
21  *    representation and so on.
22  *  - New constructor interface for RandomSparseStream accepts proportion of
23  *    nonzero entries; removed existing constructors
24  *  - Reindented, since the other changes are so numerous that diffs aren't a
25  *    big deal anyway
26  *
27  * ------------------------------------
28  * 2002-05-18 Bradford Hovinen <hovinen@cis.udel.edu>
29  *
30  * Refactor: Create one class StandardBasisFactory, parameterized by vector
31  * type, with specializations for dense, sparse map, and sparse associative
32  * vectors.
33  *
34  * ------------------------------------
35  * Modified by Dmitriy Morozov <linbox@foxcub.org>. May 27, 2002.
36  *
37  * Added parametrization of the VectorCategroy tags by VectorTraits (see
38  * vector-traits.h for more details).
39  *
40  * ------------------------------------
41  *
42  *
43  * ========LICENCE========
44  * This file is part of the library LinBox.
45  *
46  * LinBox is free software: you can redistribute it and/or modify
47  * it under the terms of the  GNU Lesser General Public
48  * License as published by the Free Software Foundation; either
49  * version 2.1 of the License, or (at your option) any later version.
50  *
51  * This library is distributed in the hope that it will be useful,
52  * but WITHOUT ANY WARRANTY; without even the implied warranty of
53  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
54  * Lesser General Public License for more details.
55  *
56  * You should have received a copy of the GNU Lesser General Public
57  * License along with this library; if not, write to the Free Software
58  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
59  * ========LICENCE========
60  *.
61  */
62 
63 /**
64  * @file vector/stream.h
65  *
66  * @brief Generation of sequences of random vectors.
67  *
68  * Random, sparse, basis vectors,...
69  */
70 
71 #ifndef __LINBOX_vector_stream_H
72 #define __LINBOX_vector_stream_H
73 
74 
75 #include <givaro/givranditer.h>
76 #include "linbox/util/debug.h"
77 #include "linbox/randiter/mersenne-twister.h"
78 #include "linbox/vector/vector-traits.h"
79 #include <vector>
80 #include <cmath>
81 
82 
83 // stream
84 namespace LinBox
85 {
86 
87 	/** \brief Vector factory.
88 
89 	 * This is an abstract base class that generates a sequence of vectors
90 	 * in a generic way. Typical uses would be in tests, where the same test
91 	 * might be run on a sequence of random vectors or on e_1, ..., e_n.
92 	 \ingroup vector
93 	 */
94 	template <class _Vector>
95 	class VectorStream {
96 	public:
97 		typedef _Vector Vector;
98 		typedef VectorStream<Vector> Self_t;
99 
100 
~VectorStream()101 		virtual ~VectorStream () {}
102 
103 		/** Get the next vector from the factory and store it in v
104 		*/
105 
106 		virtual Vector &get (Vector &v) = 0;
107 
108 		/** Extraction operator form
109 		*/
110 		Self_t &operator >> (Vector &v)
111 		{ get (v); return *this; }
112 
113 		/** Get the number of vectors to be constructed in this stream
114 		*/
115 		virtual size_t size () const = 0;
116 
117 		/** Get the number of vectors constructed so far
118 		*/
119 		virtual size_t pos () const = 0;
120 
121 		/** Get the dimension of each vector
122 		*/
123 		virtual size_t dim () const = 0;
124 
125 		/** Return true if and only if the vector stream still has more vectors
126 		 * to construct
127 		 */
128 		virtual operator bool () const = 0;
129 
130 		/** Reset the vector stream to the beginning.
131 		*/
132 		virtual void reset () = 0;
133 
134 		/** Alias for reset
135 		*/
rewind()136 		void rewind () { reset (); }
137 
138 		/** @name Legacy interface
139 		 * These functions provide compatiblity with older parts of the
140 		 * library. Their use is deprecated.
141 		 */
142 
143 		//@{
144 
next(Vector & v)145 		Vector &next (Vector &v) { return get (v); }
j()146 		size_t j () const { return pos (); }
m()147 		size_t m () const { return size (); }
n()148 		size_t n () const { return dim (); }
149 
150 		//@}
151 	};
152 
153 	/** @brief Constant vector factory.
154 	 * Returns the same vector repeatedly
155 	 */
156 	template <class _Vector>
157 	class ConstantVectorStream : public VectorStream<_Vector> {
158 	public:
159 		typedef _Vector Vector;
160 		typedef ConstantVectorStream<Vector> Self_t;
161 
162 		/** Constructor.
163 		 * Construct a new factory with the given field and vector size.
164 		 * @param v Vector to return on next
165 		 * @param m Number of vectors to return (0 for unlimited)
166 		 */
ConstantVectorStream(Vector & v,size_t m)167 		ConstantVectorStream (Vector &v, size_t m) :
168 		       	_v (v), _m (m), _j (0)
169 	       	{}
170 
171 		/** Retrieve vector
172 		 * @param v Vector to use
173 		 */
get(Vector & v)174 		Vector &get (Vector &v)
175 		{
176 			if (_m == 0 || _j < _m)
177 				std::copy (_v.begin (), _v.end (), v.begin ());
178 #ifdef _LB_DEBUG
179 			else {
180 				std::cerr << "Vector stream: nothing to get" << std::endl;
181 			}
182 #endif
183 			return v; }
184 
185 		/** Extraction operator form
186 		*/
187 		Self_t &operator >> (Vector &v)
188 		{ get (v); return *this; }
189 		/** Number of vectors to be created
190 		*/
size()191 		size_t size () const { return _m; }
192 
193 		/** Number of vectors created so far
194 		*/
pos()195 		size_t pos () const { return _j; }
196 
197 		/** Dimension of the space
198 		*/
dim()199 		size_t dim () const { return _v.size (); }
200 
201 		/** Check whether we have reached the end
202 		*/
203 		operator bool () const { return _m == 0 || _j < _m; }
204 
205 		/** Reset the factory to start at the beginning
206 		*/
reset()207 		void reset () { _j = 0; }
208 
209 	private:
210 		Vector &_v;
211 		size_t  _m;
212 		size_t  _j;
213 	};
214 }
215 
216 
217 // #include "linbox/vector/blas-vector.h"
218 // Dense
219 namespace LinBox
220 {
221 	template<class _Field, class _Rep> class BlasVector ;
222 
223 	/** @brief Random dense vector stream.
224 	 * Generates a sequence of random dense vectors over a given field
225 	 */
226 	template <typename Field, typename _Vector = BlasVector<Field, typename Vector<Field>::Dense>,
227               class RandIter = typename Field::RandIter,
228               class Trait = typename VectorTraits<_Vector>::VectorCategory>
229 	class RandomDenseStream : public VectorStream<_Vector> {
230 	public:
231 		typedef _Vector Vector;
232 		typedef RandomDenseStream<Field, Vector, RandIter, Trait> Self_t;
233 
234 		/** Constructor.
235 		 * Construct a new stream with the given field and vector size.
236 		 * @param F Field over which to create random vectors
237 		 * @param r
238 		 * @param n Size of vectors
239 		 * @param m Number of vectors to return (0 for unlimited)
240 		 */
241 		RandomDenseStream (const Field &F, RandIter &r, size_t n, size_t m = 0);
242 
243 		/** Get next element
244 		 * @param v Vector into which to generate random vector
245 		 * @return reference to new random vector
246 		 */
247 		Vector &get (Vector &v);
248 
249 		/** Extraction operator form
250 		*/
251 		Self_t &operator >> (Vector &v)
252 		{ get (v); return *this; }
253 		/** Number of vectors to be created
254 		*/
255 		size_t size () const;
256 
257 		/** Number of vectors created so far
258 		*/
259 		size_t pos () const;
260 
261 		/** Dimension of the space
262 		*/
263 		size_t dim () const;
264 
265 		/** Check whether we have reached the end
266 		*/
267 		operator bool () const;
268 
269 		/** Reset the stream to start at the beginning
270 		*/
271 		void reset ();
272 	};
273 
274 	//! Specialization of random dense stream for dense vectors
275 	template <class Field, class _Vector, class RandIter>
276 	class RandomDenseStream<Field, _Vector, RandIter, VectorCategories::DenseVectorTag > : public VectorStream<_Vector> {
277 	public:
278 		typedef _Vector Vector;
279 		typedef RandomDenseStream<Field, Vector, RandIter, VectorCategories::DenseVectorTag > Self_t;
280 
281 		RandomDenseStream (const Field &F, RandIter &r, size_t nn, size_t mm = 0) :
_field(F)282 			_field (F), _r (r), _n (nn), _m (mm), _j (0)
283 		{}
284 
get(Vector & v)285 		Vector &get (Vector &v)
286 		{
287 			typename Vector::iterator i;
288 
289 			if ( (_m > 0) && (_j++ >= _m) )
290 				return v;
291 
292 			for (i = v.begin (); i != v.end (); ++i)
293 				_r.random (*i);
294 
295 			return v;
296 		}
297 
298 		/** Extraction operator form
299 		*/
300 		Self_t &operator >> (Vector &v)
301 		{ get (v); return *this; }
size()302 		size_t size () const { return _m; }
pos()303 		size_t pos () const { return _j; }
dim()304 		size_t dim () const { return _n; }
305 		operator bool () const { return _m == 0 || _j < _m; }
reset()306 		void reset () { _j = 0; }
307 
308 	private:
309 		const Field &_field;
310 		RandIter     & _r;
311 		size_t       _n;
312 		size_t       _m;
313 		size_t       _j;
314 	};
315 
316 }
317 
318 #include "linbox/vector/sparse.h"
319 //Sparse
320 namespace LinBox
321 {
322 	/** @brief Random sparse vector stream.
323 	 * Generates a sequence of random sparse vectors over a given field
324 	 */
325 	template <class Field, class _Vector = Sparse_Vector<typename Field::Element>, class RandIter = typename Field::RandIter, class Trait = typename VectorTraits<_Vector>::VectorCategory>
326 	class RandomSparseStream : public VectorStream<_Vector> {
327 	public:
328 		typedef _Vector Vector;
329 		typedef RandomSparseStream<Field, Vector, RandIter, Trait > Self_t;
330 
331 		/** Constructor.
332 		 * Construct a new stream with the given field and vector size.
333 		 * @param F Field over which to create random vectors
334 		 * @param r
335 		 * @param n Size of vectors
336 		 * @param p Proportion of nonzero entries
337 		 * @param m Number of vectors to return (0 for unlimited)
338 		 * @param seed
339 		 */
340 		RandomSparseStream (const Field &F, RandIter &r, double p, size_t n, size_t m = 0, uint64_t seed=(uint64_t)time (NULL));
341 
342 		/** Get next element
343 		 * @param v Vector into which to generate random vector
344 		 * @return reference to new random vector
345 		 */
346 		Vector &get (Vector &v);
347 
348 		/** Extraction operator form
349 		*/
350 		Self_t &operator >> (Vector &v)
351 		{ get (v); return *this; }
352 		/** Number of vectors to be created
353 		*/
354 		size_t size () const;
355 
356 		/** Number of vectors created so far
357 		*/
358 		size_t pos () const;
359 
360 		/** Dimension of the space
361 		*/
362 		size_t dim () const;
363 
364 		/** Check whether we have reached the end
365 		*/
366 		operator bool () const;
367 
368 		/** Reset the stream to start at the beginning
369 		*/
370 		void reset ();
371 
372 		/** Set the probability of a nonzero entry
373 		*/
374 		void setP (double p);
375 	};
376 
377 	//! Specialization of RandomSparseStream for dense vectors
378 	template <class Field, class _Vector, class RandIter>
379 	class RandomSparseStream<Field, _Vector, RandIter, VectorCategories::DenseVectorTag > : public VectorStream<_Vector> {
380 	public:
381 		typedef _Vector Vector;
382 		typedef RandomSparseStream<Field, Vector, RandIter, VectorCategories::DenseVectorTag > Self_t;
383 
384 		RandomSparseStream (const Field &F, RandIter &r, double p, size_t n, size_t m = 0, uint64_t seed=(uint64_t)time (NULL)) :
_field(F)385 			_field (F), _r1 (r), _r (_r1), _n (n), _p (p), _m (m), _j (0),
386 			MT (static_cast<uint32_t>(seed))
387 		{
388 			linbox_check ((p >= 0.0) && (p <= 1.0));
389 		}
390 
get(Vector & v)391 		Vector &get (Vector &v)
392 		{
393 
394 			if (_m > 0 && _j++ >= _m)
395 				return v;
396 
397 			for (typename Vector::iterator i = v.begin (); i != v.end (); ++i) {
398 				double val;
399 				val = MT.randomDouble ();
400 
401 				if (val < _p)
402 					_r.random (*i);
403 				else
404 					_field.assign (*i, _field.zero);
405 			}
406 
407 			return v;
408 		}
409 		/** Extraction operator form
410 		*/
411 		Self_t &operator >> (Vector &v)
412 		{ get (v); return *this; }
413 
size()414 		size_t size () const { return _m; }
pos()415 		size_t pos () const { return _j; }
dim()416 		size_t dim () const { return _n; }
417 		operator bool () const { return _m == 0 || _j < _m; }
reset()418 		void reset () { _j = 0; }
setP(double p)419 		void setP (double p) { linbox_check ((p >= 0.0) && (p <= 1.0)); _p = p; }
420 
421 	private:
422 		const Field                      &_field;
423 		RandIter                         & _r1;
424         Givaro::GeneralRingNonZeroRandIter<Field, RandIter>  _r;
425 		size_t                            _n;
426 		double                            _p;
427 		size_t                            _m;
428 		size_t                            _j;
429 		MersenneTwister                   MT;
430 	};
431 
432 	//! Specialization of RandomSparseStream for sparse sequence vectors
433 	template <class Field, class _Vector, class RandIter>
434 	class RandomSparseStream<Field, _Vector, RandIter, VectorCategories::SparseSequenceVectorTag > : public VectorStream<_Vector> {
435 	public:
436 		typedef RandomSparseStream<Field, _Vector, RandIter, VectorCategories::SparseSequenceVectorTag > Self_t;
437 		typedef _Vector Vector;
438 
439 		RandomSparseStream (const Field &F, RandIter &r, double p,
440 				    size_t N, size_t M = 0, uint64_t seed= time (NULL)) :
_field(F)441                 _field (F),
442                 _r1 (r),
443                 _r (r),
444                 _n (N),
445                 _p (p),
446                 _m (M),
447                 _j (0),
448                 MT (static_cast<uint32_t>(seed))
449 		{ setP (p); }
450 
get(Vector & v)451 		Vector &get (Vector &v)
452 		{
453 			typename Field::Element x;
454 			size_t i = (size_t) -1;
455 
456 			if (_m > 0 && _j++ >= _m)
457 				return v;
458 
459 			v.clear ();
460 
461 			while (1) {
462 
463 				double val;
464 				int skip;
465 
466 				val = MT.randomDouble ();
467 				skip = (int) (ceil (log (val) * _1_log_1mp));
468 
469 				if (skip <= 0)
470 					++i;
471 				else
472 					i += (size_t)skip;
473 
474 				if (i >= _n) break;
475 
476 				_r.random (x);
477 				v.push_back (std::pair<size_t, typename Field::Element> (i, x));
478 			}
479 
480 			return v;
481 		}
482 		/** Extraction operator form
483 		*/
484 		Self_t &operator >> (Vector &v)
485 		{ get (v); return *this; }
486 
size()487 		size_t size () const { return _m; }
pos()488 		size_t pos () const { return _j; }
dim()489 		size_t dim () const { return _n; }
490 		operator bool () const { return _m == 0 || _j < _m; }
reset()491 		void reset () { _j = 0; }
492 
setP(double p)493 		void setP (double p)
494 		{
495 			linbox_check ((p >= 0.0) && (p <= 1.0));
496 			_p = p;
497 			_1_log_1mp   = 1 / log (1 - _p);
498 		}
499 
500 	private:
501 		const Field                      &_field;
502 		RandIter                         & _r1;
503 		Givaro::GeneralRingNonZeroRandIter<Field, RandIter>  _r;
504 		size_t                            _n;
505 		double                            _p;
506 		double                            _1_log_1mp;
507 		size_t                            _m;
508 		size_t                            _j;
509 		MersenneTwister                   MT;
510 	};
511 
512 	//! Specialization of RandomSparseStream for sparse associative vectors
513 	template <class Field, class _Vector, class RandIter>
514 	class RandomSparseStream<Field, _Vector, RandIter, VectorCategories::SparseAssociativeVectorTag > : public VectorStream<_Vector> {
515 	public:
516 		typedef _Vector Vector;
517 		typedef RandomSparseStream<Field, Vector, RandIter, VectorCategories::SparseAssociativeVectorTag > Self_t;
518 
519 		RandomSparseStream (const Field &F, RandIter &r, double p, size_t N,
520 				    size_t M = 0, uint64_t seed= time (NULL)) :
_field(F)521 			_field (F), _r1 (r), _r (_r1), _n (N), _k ((long) (p * N)), _j (0), _m (M),
522 			MT (static_cast<uint32_t>(seed))
523 		{}
524 
get(Vector & v)525 		Vector &get (Vector &v)
526 		{
527 			typename Field::Element x;
528 			int i;
529 
530 			if (_m > 0 && _j++ >= _m)
531 				return v;
532 
533 			v.clear ();
534 
535 			for (i = 0; i < _k; ++i) {
536 				size_t idx;
537 				_r.random (x);
538 				while (!_field.isZero (v[idx = MT.randomIntRange (0, (uint32_t)_n)])) ;
539 				v[idx] = x;
540 			}
541 
542 			return v;
543 		}
544 		/** Extraction operator form
545 		*/
546 		Self_t &operator >> (Vector &v)
547 		{ get (v); return *this; }
548 
size()549 		size_t size () const { return _m; }
pos()550 		size_t pos () const { return _j; }
dim()551 		size_t dim () const { return _n; }
552 		operator bool () const { return _m == 0 || _j < _m; }
reset()553 		void reset () { _j = 0; }
setP(double p)554 		void setP (double p) { _k = (long) (p * _n); }
555 
556 	private:
557 		const Field                      &_field;
558 		RandIter                         & _r1;
559 		Givaro::GeneralRingNonZeroRandIter<Field, RandIter> _r;
560 		size_t                            _n;
561 		long                              _k;
562 		size_t                            _j;
563 		size_t                            _m;
564 		MersenneTwister                   MT;
565 	};
566 
567 	//! Specialization of RandomSparseStream for sparse parallel vectors
568 	template <class Field, class _Vector, class RandIter>
569 	class RandomSparseStream<Field, _Vector, RandIter, VectorCategories::SparseParallelVectorTag > : public VectorStream<_Vector> {
570 	public:
571 		typedef _Vector Vector;
572 		typedef RandomSparseStream<Field, Vector, RandIter, VectorCategories::SparseParallelVectorTag > Self_t;
573 
574 		RandomSparseStream (const Field &F, RandIter &r, double p, size_t nn, size_t mm = 0, uint64_t  seed= time (NULL)) :
_field(F)575 			_field (F), _r1 (r), _r (_r1), _n (nn), _m (mm), _j (0),
576 			MT (static_cast<uint32_t>(seed))
577 		{ setP (p); }
578 
get(Vector & v)579 		Vector &get (Vector &v)
580 		{
581 			typename Field::Element x;
582 			size_t i = (size_t) -1;
583 
584 			if (_m > 0 && _j++ >= _m)
585 				return v;
586 
587 			v.first.clear ();
588 			v.second.clear ();
589 
590 			while (1) {
591 
592 				double val;
593 			int skip;
594 
595 				val = MT.randomDouble ();
596 				skip = (int) (ceil (log (val) * _1_log_1mp));
597 
598 				if (skip <= 0)
599 					++i;
600 				else
601 					i += (size_t) skip;
602 
603 				if (i >= _n) break;
604 
605 				_r.random (x);
606 				v.first.push_back (i);
607 				v.second.push_back (x);
608 			}
609 
610 			return v;
611 		}
612 
613 		/** Extraction operator form
614 		*/
615 		Self_t &operator >> (Vector &v)
616 		{ get (v); return *this; }
617 
size()618 		size_t size () const { return _m; }
pos()619 		size_t pos () const { return _j; }
dim()620 		size_t dim () const { return _n; }
621 		operator bool () const { return _m == 0 || _j < _m; }
reset()622 		void reset () { _j = 0; }
623 
setP(double p)624 		void setP (double p)
625 		{
626 			linbox_check ((p >= 0.0) && (p <= 1.0));
627 			_p = p;
628 			_1_log_1mp   = 1 / log (1 - _p);
629 		}
630 
631 	private:
632 		const Field                      &_field;
633 		RandIter                         & _r1;
634         Givaro::GeneralRingNonZeroRandIter<Field, RandIter>  _r;
635 		size_t                            _n;
636 		double                            _p;
637 		double                            _1_log_1mp;
638 		size_t                            _m;
639 		size_t                            _j;
640 		MersenneTwister                   MT;
641 	};
642 }
643 
644 // standard basis
645 namespace LinBox
646 {
647 	/** @brief Stream for \f$e_1,\cdots,e_n\f$.
648 	 * Generates the sequence (e_1,...,e_n) over a given field
649 	 *
650 	 * This class is generic with respect to the underlying vector
651 	 * representation.
652 	 */
653 	template <class Field, class _Vector, class Trait = typename VectorTraits<_Vector>::VectorCategory>
654 	class StandardBasisStream : public VectorStream<_Vector> {
655 	public:
656 		typedef _Vector Vector;
657 		typedef StandardBasisStream<Field, Vector, Trait > Self_t;
658 
659 		/** Constructor.
660 		 * Construct a new stream with the given field and vector size.
661 		 * @param F Field over which to create vectors
662 		 * @param n Size of vectors
663 		 */
664 		StandardBasisStream (Field &F, size_t n);
665 
666 		/** Get next element
667 		 * @param v Vector into which to generate vector
668 		 * @return reference to new vector
669 		 */
670 		Vector &get (Vector &v);
671 
672 		/** Extraction operator form
673 		*/
674 		Self_t &operator >> (Vector &v)
675 		{ get (v); return *this; }
676 		/** Number of vectors to be created
677 		*/
678 		size_t size () const;
679 
680 		/** Number of vectors created so far
681 		*/
682 		size_t pos () const;
683 
684 		/** Dimension of the space
685 		*/
686 		size_t dim () const;
687 
688 		/** Check whether we have reached the end
689 		*/
690 		operator bool () const;
691 
692 		/** Reset the stream to start at the beginning
693 		*/
694 		void reset ();
695 
696 	private:
697 		const Field              &_field;
698 		size_t                    _n;
699 		size_t                    _j;
700 	};
701 
702 	//! Specialization of standard basis stream for dense vectors
703 	template <class Field, class _Vector>
704 	class StandardBasisStream<Field, _Vector, VectorCategories::DenseVectorTag > : public VectorStream<_Vector> {
705 	public:
706 		typedef _Vector Vector;
707 		typedef StandardBasisStream<Field, Vector, VectorCategories::DenseVectorTag > Self_t;
708 
StandardBasisStream(const Field & F,size_t N)709 		StandardBasisStream (const Field &F, size_t N) :
710 			_field (F), _n (N), _j (0)
711 		{}
712 
get(Vector & v)713 		Vector &get (Vector &v)
714 		{
715 			typename Vector::iterator i;
716 
717 			size_t idx;
718 			for (i = v.begin (), idx = 0; i != v.end (); ++i, ++idx) {
719 				if (idx == _j)
720 					_field.assign(*i, _field.one);
721 				else
722 					_field.assign (*i, _field.zero);
723 			}
724 
725 			++_j;
726 
727 			return v;
728 		}
729 
730 		/** Extraction operator form
731 		*/
732 		Self_t &operator >> (Vector &v)
733 		{
734 			get (v);
735 			return *this;
736 		}
737 
size()738 		size_t size () const { return _n; }
739 
pos()740 		size_t pos () const { return _j; }
741 
dim()742 		size_t dim () const { return _n; }
743 
744 		operator bool () const { return _j < _n; }
745 
reset()746 		void reset () { _j = 0; }
747 
748 	private:
749 		const Field              &_field;
750 		size_t                    _n;
751 		size_t                    _j;
752 	};
753 
754 	//! Specialization of standard basis stream for sparse sequence vectors
755 	template <class Field, class _Vector>
756 	class StandardBasisStream<Field, _Vector, VectorCategories::SparseSequenceVectorTag > : public VectorStream<_Vector> {
757 	public:
758 		typedef _Vector Vector;
759 		typedef StandardBasisStream<Field, Vector, VectorCategories::SparseSequenceVectorTag > Self_t;
760 
StandardBasisStream(Field & F,size_t N)761 		StandardBasisStream (Field &F, size_t N) :
762 			_field (F), _n (N), _j (0)
763 		{
764 		}
765 
get(Vector & v)766 		Vector &get (Vector &v)
767 		{
768 			v.clear ();
769 
770 			if (_j < _n)
771 				v.push_back (std::pair <size_t, typename Field::Element> (_j++, _field.one));
772 
773 			return v;
774 		}
775 		/** Extraction operator form
776 		*/
777 		Self_t &operator >> (Vector &v)
778 		{ get (v); return *this; }
779 
size()780 		size_t size () const { return _n; }
pos()781 		size_t pos () const { return _j; }
dim()782 		size_t dim () const { return _n; }
783 		operator bool () const { return _j < _n; }
reset()784 		void reset () { _j = 0; }
785 
786 	private:
787 		const Field              &_field;
788 		size_t                    _n;
789 		size_t                    _j;
790 	};
791 
792 	//! Specialization of standard basis stream for sparse associative vectors
793 	template <class Field, class _Vector>
794 	class StandardBasisStream<Field, _Vector, VectorCategories::SparseAssociativeVectorTag > : public VectorStream<_Vector> {
795 	public:
796 		typedef _Vector Vector;
797 		typedef StandardBasisStream<Field, Vector, VectorCategories::SparseAssociativeVectorTag > Self_t;
798 
StandardBasisStream(Field & F,size_t N)799 		StandardBasisStream (Field &F, size_t N) :
800 			_field (F), _n (N), _j (0)
801 		{
802 		}
803 
get(Vector & v)804 		Vector &get (Vector &v)
805 		{
806 			v.clear ();
807 
808 			if (_j < _n)
809 				v.insert (std::pair <size_t, typename Field::Element> (_j++, _field.one));
810 
811 			return v;
812 		}
813 
814 		/** Extraction operator form
815 		*/
816 		Self_t &operator >> (Vector &v)
817 		{ get (v); return *this; }
pos()818 		size_t pos () const { return _j; }
size()819 		size_t size () const { return _n; }
dim()820 		size_t dim () const { return _n; }
821 		operator bool () const { return _j < _n; }
reset()822 		void reset () { _j = 0; }
823 
824 	private:
825 		const Field              &_field;
826 		size_t                    _n;
827 		size_t                    _j;
828 	};
829 
830 	//! Specialization of standard basis stream for sparse parallel vectors
831 	template <class Field, class _Vector>
832 	class StandardBasisStream<Field, _Vector, VectorCategories::SparseParallelVectorTag > : public VectorStream<_Vector> {
833 	public:
834 		typedef _Vector Vector;
835 		typedef StandardBasisStream<Field, Vector, VectorCategories::SparseParallelVectorTag> Self_t;
836 
StandardBasisStream(Field & F,size_t N)837 		StandardBasisStream (Field &F, size_t N) :
838 			_field (F), _n (N), _j (0)
839 		{  }
840 
get(Vector & v)841 		Vector &get (Vector &v)
842 		{
843 			v.first.clear ();
844 			v.second.clear ();
845 
846 			if (_j < _n) {
847 				v.first.push_back (_j++);
848 				v.second.push_back (_field.one);
849 			}
850 
851 			return v;
852 		}
853 
854 		/** Extraction operator form
855 		*/
856 		Self_t &operator >> (Vector &v)
857 		{ get (v); return *this; }
size()858 		size_t size () const { return _n; }
pos()859 		size_t pos () const { return _j; }
dim()860 		size_t dim () const { return _n; }
861 		operator bool () const { return _j < _n; }
reset()862 		void reset () { _j = 0; }
863 
864 	private:
865 		const Field              &_field;
866 		size_t                    _n;
867 		size_t                    _j;
868 	};
869 
870 } // namespace LinBox
871 
872 #include "linbox/vector/stream-gf2.h"
873 
874 #endif // __LINBOX_vector_stream_H
875 
876 // Local Variables:
877 // mode: C++
878 // tab-width: 4
879 // indent-tabs-mode: nil
880 // c-basic-offset: 4
881 // End:
882 // vim:sts=4:sw=4:ts=4:et:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s
883