1/* $Id: CoinDenseVector.hpp 1372 2011-01-03 23:31:00Z lou $ */
2// Copyright (C) 2003, International Business Machines
3// Corporation and others. All Rights Reserved.
4// This code is licensed under the terms of the Eclipse Public License (EPL).
5
6#ifndef CoinDenseVector_H
7#define CoinDenseVector_H
8
9#if defined(_MSC_VER)
10// Turn off compiler warning about long names
11# pragma warning(disable:4786)
12#endif
13
14#include <cassert>
15#include <cstdlib>
16#include <cmath>
17#include "CoinHelperFunctions.hpp"
18
19//#############################################################################
20/** A function that tests the methods in the CoinDenseVector class. The
21 only reason for it not to be a member method is that this way it doesn't
22 have to be compiled into the library. And that's a gain, because the
23 library should be compiled with optimization on, but this method should be
24 compiled with debugging. */
25 template <typename T> void
26 CoinDenseVectorUnitTest(T dummy);
27
28//#############################################################################
29/** Dense Vector
30
31Stores a dense (or expanded) vector of floating point values.
32Type of vector elements is controlled by templating.
33(Some working quantities such as accumulated sums
34are explicitly declared of type double). This allows the
35components of the vector integer, single or double precision.
36
37Here is a sample usage:
38@verbatim
39 const int ne = 4;
40 double el[ne] = { 10., 40., 1., 50. }
41
42 // Create vector and set its value
43 CoinDenseVector<double> r(ne,el);
44
45 // access each element
46 assert( r.getElements()[0]==10. );
47 assert( r.getElements()[1]==40. );
48 assert( r.getElements()[2]== 1. );
49 assert( r.getElements()[3]==50. );
50
51 // Test for equality
52 CoinDenseVector<double> r1;
53 r1=r;
54
55 // Add dense vectors.
56 // Similarly for subtraction, multiplication,
57 // and division.
58 CoinDenseVector<double> add = r + r1;
59 assert( add[0] == 10.+10. );
60 assert( add[1] == 40.+40. );
61 assert( add[2] == 1.+ 1. );
62 assert( add[3] == 50.+50. );
63
64 assert( r.sum() == 10.+40.+1.+50. );
65@endverbatim
66*/
67template <typename T> class CoinDenseVector {
68private:
69 /**@name Private member data */
70 //@{
71 /// Size of element vector
72 int nElements_;
73 ///Vector elements
74 T * elements_;
75 //@}
76
77public:
78 /**@name Get methods. */
79 //@{
80 /// Get the size
81 inline int getNumElements() const { return nElements_; }
82 inline int size() const { return nElements_; }
83 /// Get element values
84 inline const T * getElements() const { return elements_; }
85 /// Get element values
86 inline T * getElements() { return elements_; }
87 //@}
88
89 //-------------------------------------------------------------------
90 // Set indices and elements
91 //-------------------------------------------------------------------
92 /**@name Set methods */
93 //@{
94 /// Reset the vector (i.e. set all elemenets to zero)
95 void clear();
96 /** Assignment operator */
97 CoinDenseVector & operator=(const CoinDenseVector &);
98 /** Member of array operator */
99 T & operator[](int index) const;
100
101 /** Set vector size, and elements.
102 Size is the length of the elements vector.
103 The element vector is copied into this class instance's
104 member data. */
105 void setVector(int size, const T * elems);
106
107
108 /** Elements set to have the same scalar value */
109 void setConstant(int size, T elems);
110
111
112 /** Set an existing element in the dense vector
113 The first argument is the "index" into the elements() array
114 */
115 void setElement(int index, T element);
116 /** Resize the dense vector to be the first newSize elements.
117 If length is decreased, vector is truncated. If increased
118 new entries, set to new default element */
119 void resize(int newSize, T fill=T());
120
121 /** Append a dense vector to this dense vector */
122 void append(const CoinDenseVector &);
123 //@}
124
125 /**@name norms, sum and scale */
126 //@{
127 /// 1-norm of vector
128 inline T oneNorm() const {
129 T norm = 0;
130 for (int i=0; i<nElements_; i++)
131 norm += CoinAbs(elements_[i]);
132 return norm;
133 }
134 /// 2-norm of vector
135 inline double twoNorm() const {
136 double norm = 0.;
137 for (int i=0; i<nElements_; i++)
138 norm += elements_[i] * elements_[i];
139 // std namespace removed because it was causing a compile
140 // problem with Microsoft Visual C++
141 return /*std::*/sqrt(norm);
142 }
143 /// infinity-norm of vector
144 inline T infNorm() const {
145 T norm = 0;
146 for (int i=0; i<nElements_; i++)
147 norm = CoinMax(norm, CoinAbs(elements_[i]));
148 return norm;
149 }
150 /// sum of vector elements
151 inline T sum() const {
152 T sume = 0;
153 for (int i=0; i<nElements_; i++)
154 sume += elements_[i];
155 return sume;
156 }
157 /// scale vector elements
158 inline void scale(T factor) {
159 for (int i=0; i<nElements_; i++)
160 elements_[i] *= factor;
161 return;
162 }
163 //@}
164
165 /**@name Arithmetic operators. */
166 //@{
167 /// add <code>value</code> to every entry
168 void operator+=(T value);
169 /// subtract <code>value</code> from every entry
170 void operator-=(T value);
171 /// multiply every entry by <code>value</code>
172 void operator*=(T value);
173 /// divide every entry by <code>value</code>
174 void operator/=(T value);
175 //@}
176
177 /**@name Constructors and destructors */
178 //@{
179 /** Default constructor */
180 CoinDenseVector();
181 /** Alternate Constructors - set elements to vector of Ts */
182 CoinDenseVector(int size, const T * elems);
183 /** Alternate Constructors - set elements to same scalar value */
184 CoinDenseVector(int size, T element=T());
185 /** Copy constructors */
186 CoinDenseVector(const CoinDenseVector &);
187
188 /** Destructor */
189 ~CoinDenseVector ();
190 //@}
191
192private:
193 /**@name Private methods */
194 //@{
195 /// Copy internal data
196 void gutsOfSetVector(int size, const T * elems);
197 /// Set all elements to a given value
198 void gutsOfSetConstant(int size, T value);
199 //@}
200};
201
202//#############################################################################
203
204/**@name Arithmetic operators on dense vectors.
205
206 <strong>NOTE</strong>: Because these methods return an object (they can't
207 return a reference, though they could return a pointer...) they are
208 <em>very</em> inefficient...
209 */
210//@{
211/// Return the sum of two dense vectors
212template <typename T> inline
213CoinDenseVector<T> operator+(const CoinDenseVector<T>& op1,
214 const CoinDenseVector<T>& op2){
215 assert(op1.size() == op2.size());
216 int size = op1.size();
217 CoinDenseVector<T> op3(size);
218 const T *elements1 = op1.getElements();
219 const T *elements2 = op2.getElements();
220 T *elements3 = op3.getElements();
221 for(int i=0; i<size; i++)
222 elements3[i] = elements1[i] + elements2[i];
223 return op3;
224}
225
226/// Return the difference of two dense vectors
227template <typename T> inline
228CoinDenseVector<T> operator-(const CoinDenseVector<T>& op1,
229 const CoinDenseVector<T>& op2){
230 assert(op1.size() == op2.size());
231 int size = op1.size();
232 CoinDenseVector<T> op3(size);
233 const T *elements1 = op1.getElements();
234 const T *elements2 = op2.getElements();
235 T *elements3 = op3.getElements();
236 for(int i=0; i<size; i++)
237 elements3[i] = elements1[i] - elements2[i];
238 return op3;
239}
240
241
242/// Return the element-wise product of two dense vectors
243template <typename T> inline
244CoinDenseVector<T> operator*(const CoinDenseVector<T>& op1,
245 const CoinDenseVector<T>& op2){
246 assert(op1.size() == op2.size());
247 int size = op1.size();
248 CoinDenseVector<T> op3(size);
249 const T *elements1 = op1.getElements();
250 const T *elements2 = op2.getElements();
251 T *elements3 = op3.getElements();
252 for(int i=0; i<size; i++)
253 elements3[i] = elements1[i] * elements2[i];
254 return op3;
255}
256
257/// Return the element-wise ratio of two dense vectors
258template <typename T> inline
259CoinDenseVector<T> operator/(const CoinDenseVector<T>& op1,
260 const CoinDenseVector<T>& op2){
261 assert(op1.size() == op2.size());
262 int size = op1.size();
263 CoinDenseVector<T> op3(size);
264 const T *elements1 = op1.getElements();
265 const T *elements2 = op2.getElements();
266 T *elements3 = op3.getElements();
267 for(int i=0; i<size; i++)
268 elements3[i] = elements1[i] / elements2[i];
269 return op3;
270}
271//@}
272
273/**@name Arithmetic operators on dense vector and a constant.
274 These functions create a dense vector as a result. That dense vector will
275 have the same indices as <code>op1</code> and the specified operation is
276 done entry-wise with the given value. */
277//@{
278/// Return the sum of a dense vector and a constant
279template <typename T> inline
280CoinDenseVector<T> operator+(const CoinDenseVector<T>& op1, T value){
281 int size = op1.size();
282 CoinDenseVector<T> op3(size);
283 const T *elements1 = op1.getElements();
284 T *elements3 = op3.getElements();
285 double dvalue = value;
286 for(int i=0; i<size; i++)
287 elements3[i] = elements1[i] + dvalue;
288 return op3;
289}
290
291/// Return the difference of a dense vector and a constant
292template <typename T> inline
293CoinDenseVector<T> operator-(const CoinDenseVector<T>& op1, T value){
294 int size = op1.size();
295 CoinDenseVector<T> op3(size);
296 const T *elements1 = op1.getElements();
297 T *elements3 = op3.getElements();
298 double dvalue = value;
299 for(int i=0; i<size; i++)
300 elements3[i] = elements1[i] - dvalue;
301 return op3;
302}
303
304/// Return the element-wise product of a dense vector and a constant
305template <typename T> inline
306CoinDenseVector<T> operator*(const CoinDenseVector<T>& op1, T value){
307 int size = op1.size();
308 CoinDenseVector<T> op3(size);
309 const T *elements1 = op1.getElements();
310 T *elements3 = op3.getElements();
311 double dvalue = value;
312 for(int i=0; i<size; i++)
313 elements3[i] = elements1[i] * dvalue;
314 return op3;
315}
316
317/// Return the element-wise ratio of a dense vector and a constant
318template <typename T> inline
319CoinDenseVector<T> operator/(const CoinDenseVector<T>& op1, T value){
320 int size = op1.size();
321 CoinDenseVector<T> op3(size);
322 const T *elements1 = op1.getElements();
323 T *elements3 = op3.getElements();
324 double dvalue = value;
325 for(int i=0; i<size; i++)
326 elements3[i] = elements1[i] / dvalue;
327 return op3;
328}
329
330/// Return the sum of a constant and a dense vector
331template <typename T> inline
332CoinDenseVector<T> operator+(T value, const CoinDenseVector<T>& op1){
333 int size = op1.size();
334 CoinDenseVector<T> op3(size);
335 const T *elements1 = op1.getElements();
336 T *elements3 = op3.getElements();
337 double dvalue = value;
338 for(int i=0; i<size; i++)
339 elements3[i] = elements1[i] + dvalue;
340 return op3;
341}
342
343/// Return the difference of a constant and a dense vector
344template <typename T> inline
345CoinDenseVector<T> operator-(T value, const CoinDenseVector<T>& op1){
346 int size = op1.size();
347 CoinDenseVector<T> op3(size);
348 const T *elements1 = op1.getElements();
349 T *elements3 = op3.getElements();
350 double dvalue = value;
351 for(int i=0; i<size; i++)
352 elements3[i] = dvalue - elements1[i];
353 return op3;
354}
355
356/// Return the element-wise product of a constant and a dense vector
357template <typename T> inline
358CoinDenseVector<T> operator*(T value, const CoinDenseVector<T>& op1){
359 int size = op1.size();
360 CoinDenseVector<T> op3(size);
361 const T *elements1 = op1.getElements();
362 T *elements3 = op3.getElements();
363 double dvalue = value;
364 for(int i=0; i<size; i++)
365 elements3[i] = elements1[i] * dvalue;
366 return op3;
367}
368
369/// Return the element-wise ratio of a a constant and dense vector
370template <typename T> inline
371CoinDenseVector<T> operator/(T value, const CoinDenseVector<T>& op1){
372 int size = op1.size();
373 CoinDenseVector<T> op3(size);
374 const T *elements1 = op1.getElements();
375 T *elements3 = op3.getElements();
376 double dvalue = value;
377 for(int i=0; i<size; i++)
378 elements3[i] = dvalue / elements1[i];
379 return op3;
380}
381//@}
382
383#endif
384