00001 /*
00002 File: SparseVec.h
00003
00004 Function: Defines a sparse vector.
00005
00006 Author(s): Andrew Willmott
00007
00008 Copyright: (c) 1995-2000, Andrew Willmott
00009 */
00010
00011 #ifndef __SparseVec__
00012 #define __SparseVec__
00013
00014 #include "vl/VL.h"
00015 #include "vl/Vec.h"
00016 #include "vl/SubSVec.h"
00017 #include "cl/Array.h"
00018 #include <iostream.h>
00019
00020 #define TSVList Array< TSparsePair >
00021
00022 class TSparsePair
00023 {
00024 public:
00025
00026 TSparsePair() {};
00027 TSparsePair(Int i, TVReal elt) : index(i), elt(elt) {};
00028
00029 Int index; // Index
00030 TVReal elt; // Non-zero element at that index
00031
00032 Bool operator == (const TSparsePair &sp) const
00033 { return(index == sp.index && elt == sp.elt); };
00034 Bool operator != (const TSparsePair &sp) const
00035 { return(index != sp.index || elt != sp.elt); };
00036
00037 friend ostream &operator << (ostream &s, const TSparsePair &sp);
00038 friend istream &operator >> (istream &s, TSparsePair &sp);
00039 };
00040
00041 class TSubSVec;
00042 class TSVIter;
00043
00044 class TSparseVec : public TSVList
00045 /*
00046 Function: Provides a sparse vector class
00047
00048 NOTE: SparseVecs can be manipulated as follows:
00049
00050 1] Use SetElts() -- e.g.,
00051 sv.SetSize(5); sv.SetElts(1, 1.0, 4, 4.0, VL_SV_END);
00052 Sets sv to [0.0, 1.0, 0.0, 0.0 4.0]
00053
00054 2] Use the SVIter iterator. (See description below.)
00055
00056 3] Use the Overlay method: a.Overlay(b) performs a[i] = b[i] for all non-zero b[i].
00057
00058 4] Direct access:
00059 SetNumElts(size), Begin(), AddElt()/AddNZElt() new element pairs in
00060 order, then End(). (Use AddNZElt if you know the element will
00061 be non-zero.)
00062
00063 5] As a last resort, use Get()/Set().
00064 These calls are not efficient for multiple accesses.
00065 */
00066 {
00067 public:
00068 TSparseVec(); // Null vector: space allocated later
00069 TSparseVec(Int n);
00070 TSparseVec(Int n, Int indices[], TVReal elts[]);
00071 TSparseVec(Int n, Int idx0, double elt0, ...);
00072 TSparseVec(const TSparseVec &v); // Copy constructor
00073 TSparseVec(const TSubSVec &v);
00074 TSparseVec(const TVec &v);
00075 TSparseVec(Int n, ZeroOrOne); // Zero or all-ones vector
00076 TSparseVec(Int n, Axis a); // Unit vector
00077
00078 ~TSparseVec(); // Destructor
00079
00080 // Accessor functions
00081
00082 Int Elts() const { return elts; };
00083
00084 TSparseVec &operator = (const TSparseVec &v);
00085 TSparseVec &operator = (ZeroOrOne k) { MakeBlock(k); return(SELF); };
00086 TSparseVec &operator = (Axis k) { MakeUnit(k); return(SELF); };
00087 TSparseVec &operator = (const TSubSVec &v);
00088 TSparseVec &operator = (const TVec &v);
00089
00090 Void SetSize(Int n);
00091
00092 // Sparse methods
00093
00094 TSparseVec Overlay(const TSparseVec &a) const;
00095 Void SetElts(Int idx0, double elt0, ...);
00096 Void Set(Int index, TVReal elt);
00097 TVReal Get(Int index) const;
00098
00099 // Vector initialisers
00100
00101 Void MakeZero();
00102 Void MakeUnit(Int i, TVReal k = vl_one);
00103 Void MakeBlock(TVReal k = vl_one);
00104
00105 // Low level Utils
00106
00107 Void SetNumElts(Int n)
00108 { elts = n; };
00109 Void Begin()
00110 { Clear(); };
00111 Void AddElt(Int i, TVReal a)
00112 { if (len(a) > fuzz) {Add(); Last().index = i; Last().elt = a;} };
00113 Void AddNZElt(Int i, TVReal a)
00114 { Add(); Last().index = i; Last().elt = a; };
00115 Void AddNZElt(const TSparsePair &p)
00116 { Append(p); };
00117 Void End()
00118 { Add(); Last().index = VL_SV_MAX_INDEX; };
00119
00120 // Settings
00121
00122 static Void SetCompactPrint(Bool on);
00123 static Bool IsCompact() { return compactPrint; };
00124 static Void SetFuzz(TVReal fuzz);
00125 static Bool IsNonZero(TVReal a)
00126 { return(len(a) > fuzz); };
00127
00128 protected:
00129 // Private...
00130 static Bool compactPrint; // Print in normal or compact (only non-zero elts) style
00131 static TVReal fuzz; // x s.t. |x| <= fuzz is considered zero.
00132 Int elts;
00133 };
00134
00135 class TSVIter
00136 /*
00137 Function: Useful for iterating over a sparse vector.
00138
00139 Data() : returns the current element's data
00140 Index() : returns the current element's index
00141
00142 1] Use Begin(), Inc(), AtEnd() to iterate over the non-zero elements
00143 of the vector:
00144
00145 // sv = sv * 2
00146 for (j.Begin(sv); !j.AtEnd(); j.Inc())
00147 j.Data() *= 2.0;
00148
00149 2] Use one of the following:
00150
00151 Inc(Int i) moves on to elt i, where i will increase by 1 on each call
00152 IncTo(Int i) moves on to elt i, where i will increase monotonically
00153
00154 within another for-loop to access the elements of the sparse vector
00155 corresponding to i. For example:
00156
00157 // v = v + sv
00158 for (j.Begin(sv), i = 0; i < v.NumItems(); i++)
00159 {
00160 j.Inc(i);
00161 if (j.Exists())
00162 v[i] += j.Data();
00163 }
00164
00165 // a += dot(sv1, sv2)
00166 for (j.Begin(sv2), k.Begin(sv1); !k.AtEnd(); k.Inc())
00167 {
00168 j.IncTo(k.Index()); // find corresponding elt in sv2
00169 if (j.Exists())
00170 a += j.Data() * k.Data();
00171 }
00172 */
00173 {
00174 public:
00175 TSVIter() {};
00176 TSVIter(const TSparseVec &sv) : pairIdx(0), list(&sv) {};
00177
00178 Void Begin()
00179 { pairIdx = 0; };
00180 // move to the beginning of the current sparse vector
00181
00182 Void Begin(const TSparseVec &sv)
00183 { pairIdx = 0; list = &sv; };
00184 // move to the beginning of sparse vector sv
00185
00186 Void Inc()
00187 { pairIdx++; };
00188 // move to the next non-zero element in the vector
00189
00190 Bool AtEnd()
00191 { return(pairIdx >= list->NumItems() - 1); };
00192 // returns true if we're at the end of the vector
00193
00194 TVReal Data()
00195 { return(list->Item(pairIdx).elt); };
00196 // WARNING: only call this if you *know* the element is non-zero
00197 Int Index()
00198 { return(list->Item(pairIdx).index); };
00199 TSparsePair Pair()
00200 { return(list->Item(pairIdx)); };
00201
00202 Void Inc(Int i)
00203 { if (i > list->Item(pairIdx).index) pairIdx++; };
00204 // Move on to the element indicated by i. i must increase by
00205 // 1 on each subsequent call.
00206
00207 Bool IncTo(Int i)
00208 { OrdFindBinary(i); return(i == list->Item(pairIdx).index); };
00209 // Move on to the element with index i.
00210 // returns true if element i is non-zero.
00211
00212 Bool Exists(Int i)
00213 { return(i == list->Item(pairIdx).index); };
00214
00215 Int PairIdx()
00216 { return(pairIdx); };
00217
00218 Void OrdFindBinary(Int i); // Find the pair with index i using binary search
00219 Void OrdFindLinear(Int i); // Find the pair with index i using linear search
00220
00221 protected:
00222 Int pairIdx; // current index into sparse list
00223 const TSVList *list; // sparse list
00224 };
00225
00226
00227 // --- Vec In-Place operators -------------------------------------------------
00228
00229 TSparseVec &operator += (TSparseVec &a, const TSparseVec &b);
00230 TSparseVec &operator -= (TSparseVec &a, const TSparseVec &b);
00231 TSparseVec &operator *= (TSparseVec &a, const TSparseVec &b);
00232 TSparseVec &operator *= (TSparseVec &v, TVReal s);
00233 TSparseVec &operator /= (TSparseVec &a, const TSparseVec &b);
00234 TSparseVec &operator /= (TSparseVec &v, TVReal s);
00235
00236 // --- Vec Comparison Operators -----------------------------------------------
00237
00238 Bool operator == (const TSparseVec &a, const TSparseVec &b);
00239 Bool operator != (const TSparseVec &a, const TSparseVec &b);
00240
00241 // --- Vec Arithmetic Operators -----------------------------------------------
00242
00243 TSparseVec operator + (const TSparseVec &a, const TSparseVec &b);
00244 TSparseVec operator - (const TSparseVec &a, const TSparseVec &b);
00245 TSparseVec operator - (const TSparseVec &v);
00246 TSparseVec operator * (const TSparseVec &a, const TSparseVec &b);
00247 TSparseVec operator * (const TSparseVec &v, TVReal s);
00248 TSparseVec operator / (const TSparseVec &a, const TSparseVec &b);
00249 TSparseVec operator / (const TSparseVec &v, TVReal s);
00250 TSparseVec operator * (TVReal s, const TSparseVec &v);
00251
00252
00253 TVReal dot(const TSparseVec &a, const TSparseVec &b);
00254 TVReal dot(const TSparseVec &a, const TVec &b);
00255 TVReal len(const TSparseVec &v);
00256 TVReal sqrlen(const TSparseVec &v);
00257 TSparseVec norm(const TSparseVec &v);
00258
00259 // --- Vec Input & Output -----------------------------------------------------
00260
00261 ostream &operator << (ostream &s, const TSparseVec &v);
00262 istream &operator >> (istream &s, TSparseVec &v);
00263
00264
00265 #endif