1 /*
2  *  Copyright (C) 2010  Regents of the University of Michigan
3  *
4  *   This program is free software: you can redistribute it and/or modify
5  *   it under the terms of the GNU General Public License as published by
6  *   the Free Software Foundation, either version 3 of the License, or
7  *   (at your option) any later version.
8  *
9  *   This program is distributed in the hope that it will be useful,
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *   GNU General Public License for more details.
13  *
14  *   You should have received a copy of the GNU General Public License
15  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef __MATHVECTOR_H__
19 #define __MATHVECTOR_H__
20 
21 #include "StringBasics.h"
22 
23 #include <stdio.h>
24 #include <assert.h>
25 
26 class Matrix;
27 
28 class Vector
29 {
30 public:
31     int         dim, size;
32     double *    data;
33     String      label;
34 
Vector()35     Vector()
36     {
37         Init();
38     }
Vector(Vector & v)39     Vector(Vector & v)
40     {
41         Init();
42         Copy(v);
43     }
Vector(int d)44     Vector(int d)
45     {
46         Init();
47         Dimension(d);
48     }
Vector(const char * text)49     Vector(const char * text)
50     {
51         Init();
52         label = text;
53     }
Vector(const char * text,int d)54     Vector(const char * text, int d)
55     {
56         Init();
57         label = text;
58         Dimension(d);
59     }
Vector(const char * text,Vector & v)60     Vector(const char * text, Vector & v)
61     {
62         Init();
63         label = text;
64         Copy(v);
65     }
66 
67     ~Vector();
68 
69     void   Dimension(int d);
70     void   Dimension(int d, double value);
71 
GrowTo(int d)72     void   GrowTo(int d)
73     {
74         Dimension(d > dim ? d : dim);
75     }
GrowTo(int d,double value)76     void   GrowTo(int d, double value)
77     {
78         Dimension(d > dim ? d : dim, value);
79     }
80 
Length()81     int    Length() const
82     {
83         return dim;
84     }
85 
SetLabel(const char * text)86     void   SetLabel(const char * text)
87     {
88         label = text;
89     }
90 
91     void   Zero();
92     void   Set(double k);
Set(Vector & v)93     void   Set(Vector & v)
94     {
95         Copy(v);
96     };
97     void   SetMultiple(double k, Vector & v);
98 
99     void   Negate();
100     void   Add(double n);
101     void   Multiply(double k);
102 
103     double InnerProduct(Vector & v);
104     void   Copy(const Vector & v);
105     void   Add(Vector & v);
106     void   AddMultiple(double k, Vector & v);
107     void   Subtract(Vector & v);
108 
109     void Product(Matrix & m, Vector & v);
110 
111     double & operator [](int n)
112     {
113         assert(n < dim);
114         return data[n];
115     }
116     double operator [](int n) const
117     {
118         assert(n < dim);
119         return data[n];
120     }
121 
122     double operator [](double fraction)
123     {
124         return data[(int)(dim * fraction)];
125     }
126     double & operator [](double fraction) const
127     {
128         return data[(int)(dim * fraction)];
129     }
130 
131     Vector & operator = (const Vector & v);
132     bool operator == (const Vector & v) const;
133     bool operator != (const Vector & v) const
134     {
135         return !(*this == v);
136     }
137 
Swap(int i,int j)138     void Swap(int i, int j)
139     {
140         double swap = data[i];
141         data[i] = data[j];
142         data[j] = swap;
143     }
144     void Swap(Vector & rhs);
145 
146     Vector & operator *= (double rhs)
147     {
148         Multiply(rhs);
149         return *this;
150     }
151     Vector & operator += (double rhs)
152     {
153         Add(rhs);
154         return *this;
155     }
156     Vector & operator -= (double rhs)
157     {
158         return *this += -rhs;
159     }
160     Vector & operator /= (double rhs)
161     {
162         return *this *= 1/rhs;
163     }
164 
165     Vector & operator += (Vector & rhs)
166     {
167         Add(rhs);
168         return * this;
169     }
170     Vector & operator -= (Vector & rhs)
171     {
172         Subtract(rhs);
173         return * this;
174     }
175 
176     void DeleteDimension(int n);
Delete(int n)177     void Delete(int n)
178     {
179         DeleteDimension(n);
180     }
181     void Insert(int n, double value);
182 
183     // Calculates average and variance
184     void   AveVar(double & ave, double & var) const;
185     double Average() const;
186     double Var() const;
187     double StandardDeviation() const;
188 
189     double Average(double returnIfNull);
190     double Var(double returnIfNull);
191     double StandardDeviation(double returnIfNull);
192 
193     // Common descriptive functions
194     double Sum() const;
195     double SumSquares() const;
196     double Product() const;
197 
198     // Find extreme values
199     double Min() const;
200     double Max() const;
201 
202     // Return the number of elements in a subset
203     int  CountIfGreater(double treshold) const;
204     int  CountIfGreaterOrEqual(double treshold) const;
205 
206     // Append another vector to the end
207     void Stack(const Vector & v);
208 
209     void Print(int maxDim = -1)
210     {
211         Print(stdout, maxDim);
212     }
213     void Print(FILE * output, int maxDim = -1);
214 
215     // Routines for creating and searching through sorted vectors
216     void Sort();
217     void Reverse();
218     void Sort(Vector & freeRider);
219     int  BinarySearch(double value);
FastFind(double value)220     int  FastFind(double value)
221     {
222         return BinarySearch(value);
223     }
224 
225     // Remove consecutive duplicate elements from vector
226     void RemoveDuplicates();
227 
228     // Query first and last elements
229     //
230 
First()231     double & First()
232     {
233         return data[0];
234     }
Last()235     double & Last()
236     {
237         return data[dim - 1];
238     }
239 
240     // Routines for using a vector as a stack of doubles
241     //
242 
Clear()243     void   Clear()
244     {
245         dim = 0;
246     }
247     void   Push(double value);
Pop()248     double Pop()
249     {
250         return data[--dim];
251     }
Peek()252     double Peek() const
253     {
254         return data[dim-1];
255     }
256 
257     // This routine adds items to a sorted list
258     //
259 
260     void   InsertInSortedList(int item);
261 
262     static int alloc;
263 
264     bool   isAscending();
265     bool   isDescending();
266 
267     // Routines for dealing with vectors that include missing data
268     //
269 
270     int SafeCount() const;
271     double SafeMin() const;
272     double SafeMax() const;
273 
274 private:
275     static int CompareDouble(const double * a, const double * b);
276     void Init();
277 };
278 
279 
280 
281 class VectorFunc
282 // Wrapper for multi-dimensional functions
283 // so that they can be used as parameters
284 // and keep private data
285 {
286 private:
287     double(*f)(Vector &);
288 
289 public:
290     // Constructors
291     VectorFunc();
292     VectorFunc(double(*func)(Vector &));
293 
294     // Virtual destructor ensures that dynamic objects are
295     // handled correctly
~VectorFunc()296     virtual ~VectorFunc() { }
297 
298     virtual double Evaluate(Vector & v);
299 
300     // Calculate derivatives along each direction. Delta is a guess value
301     // for the initial stepsize in numerical derivation
302     virtual void   Derivative(Vector & point, Vector & d, double delta = 1.0);
303 
304     // Minimum function value found while evaluating derivative
305     // and its location...
306     double dfmin;
307     Vector dpmin;
308 };
309 
310 #endif
311 
312 
313 
314