00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "MathVector.h"
00019 #include "MathMatrix.h"
00020 #include "MathConstant.h"
00021 #include "Sort.h"
00022 #include "Error.h"
00023
00024 #ifdef _MSC_VER
00025 #define _USE_MATH_DEFINES
00026 #endif
00027
00028 #include <string.h>
00029 #include <math.h>
00030
00031 int Vector::alloc = 32;
00032
00033 void Vector::Init()
00034 {
00035 dim = size = 0;
00036 label = "Unknown";
00037 data = NULL;
00038 }
00039
00040 Vector::~Vector()
00041 {
00042
00043 if (data != NULL) delete [] data;
00044 }
00045
00046 void Vector::Dimension(int d)
00047 {
00048 if (d > size)
00049 {
00050 if (size < 1024)
00051 {
00052 size = (d + alloc) / alloc * alloc;
00053 double * newData = new double [size];
00054 if (data != NULL)
00055 {
00056 for (int i = 0; i < dim; i++)
00057 newData[i] = data[i];
00058 delete [] data;
00059 }
00060 data = newData;
00061 }
00062 else
00063 {
00064 while (size <= d)
00065 size *= 2;
00066
00067 double * newData = new double [size];
00068 if (data != NULL)
00069 {
00070 for (int i = 0; i < dim; i++)
00071 newData[i] = data[i];
00072 delete [] data;
00073 }
00074 data = newData;
00075 }
00076 }
00077 dim = d;
00078 }
00079
00080 void Vector::Dimension(int d, double value)
00081 {
00082 int original = dim;
00083
00084 Dimension(d);
00085
00086 for (int i = original; i < dim; i++)
00087 data[i] = value;
00088 }
00089
00090 void Vector::Negate()
00091 {
00092 for (int i = 0; i < dim; i++)
00093 data[i] = -data[i];
00094 }
00095
00096 void Vector::Add(double n)
00097 {
00098 for (int i = 0; i< dim; i++)
00099 data[i] += n;
00100 }
00101
00102 void Vector::Multiply(double k)
00103 {
00104 for (int i = 0; i < dim; i++)
00105 data[i] *= k;
00106 }
00107
00108 void Vector::Copy(const Vector & v)
00109 {
00110 Dimension(v.dim);
00111
00112 if (v.data != NULL)
00113 for (int i=0; i < dim; i++)
00114 data[i] = v.data[i];
00115 }
00116
00117 Vector & Vector::operator = (const Vector & rhs)
00118 {
00119 Copy(rhs);
00120 return *this;
00121 }
00122
00123 void Vector::Add(Vector & v)
00124 {
00125 if (dim != v.dim)
00126 error("Vector::Add - vectors have different dimensions\n"
00127 "Vectors - %s [%d] + %s [%d] ",
00128 (const char *) label, dim, (const char *) v.label, v.dim);
00129
00130 for (int i = 0; i < dim; i++)
00131 data[i] += v.data[i];
00132 }
00133
00134 void Vector::AddMultiple(double k, Vector & v)
00135 {
00136 if (dim != v.dim)
00137 error("Vector::AddMultiple - vectors are incompatible\n"
00138 "Vectors - %s [%d] + %s [%d] ",
00139 (const char *) label, dim, (const char *) v.label, v.dim);
00140
00141 for (int i = 0; i < dim; i++)
00142 data[i] += k * v.data[i];
00143 }
00144
00145
00146 void Vector::Subtract(Vector & v)
00147 {
00148 if (dim != v.dim)
00149 error("Vector::Subtract - vectors have different dimensions\n"
00150 "Vectors - %s [%d] + %s [%d] ",
00151 (const char *) label, dim, (const char *) v.label, v.dim);
00152
00153 for (int i = 0; i < dim; i++)
00154 data[i] -= v.data[i];
00155 }
00156
00157
00158 void Vector::Zero()
00159 {
00160 for (int i = 0; i < dim; i++)
00161 data[i] = 0.0;
00162 }
00163
00164 void Vector::Set(double k)
00165 {
00166 for (int i = 0; i < dim; i++)
00167 data[i] = k;
00168 }
00169
00170 void Vector::SetMultiple(double k, Vector & v)
00171 {
00172 Dimension(v.dim);
00173
00174 for (int i = 0; i < dim; i++)
00175 data[i] = k * v[i];
00176 }
00177
00178 double Vector::InnerProduct(Vector & v)
00179 {
00180 if (dim != v.dim)
00181 error("Vector::InnerProduct - vectors have different dimensions\n"
00182 "Vectors - %s[%d] * %s[%d] ",
00183 (const char *) label, dim, (const char *) v.label, v.dim);
00184
00185 double sum = 0.0;
00186 for (int i = 0; i < dim; i++)
00187 sum += data[i] * v.data[i];
00188
00189 return sum;
00190 }
00191
00192 void Vector::Insert(int n, double value)
00193 {
00194 Dimension(dim + 1);
00195
00196 for (int i = dim - 1; i > n; i--)
00197 data[i] = data[i - 1];
00198 data[n] = value;
00199 }
00200
00201 void Vector::DeleteDimension(int n)
00202 {
00203 for (int i = n; i < dim - 1; i++)
00204 data[i] = data[i + 1];
00205 dim --;
00206 }
00207
00208 void Vector::Product(Matrix & m, Vector & v)
00209 {
00210 if (m.cols != v.dim)
00211 error("Vector::Product - Cannot Multiply Matrix by Vector\n"
00212 "Vectors - %s [%d, %d] * %s [%d]\n",
00213 (const char *) m.label, m.rows, m.cols,
00214 (const char *) v.label, v.dim);
00215
00216 Dimension(m.rows);
00217 Zero();
00218
00219 for (int i = 0; i < m.rows; i++)
00220 for (int j = 0; j < m.cols; j++)
00221 data[i] += m[i][j] * v[j];
00222 }
00223
00224 double Vector::Average() const
00225 {
00226 if (dim == 0)
00227 error("Average undefined for null vector %s",
00228 (const char *) label);
00229
00230 return Sum() / dim;
00231 }
00232
00233 double Vector::Product() const
00234 {
00235 double product = 1.0;
00236
00237 for (int j = 0; j < dim; j++)
00238 product *= data[j];
00239
00240 return product;
00241 }
00242
00243 double Vector::Sum() const
00244 {
00245 double sum = 0.0;
00246
00247 for (int j=0; j<dim; j++)
00248 sum += data[j];
00249
00250 return sum;
00251 }
00252
00253 double Vector::SumSquares() const
00254 {
00255 double sum = 0.0;
00256
00257 for (int j=0; j<dim; j++)
00258 sum += data[j] * data[j];
00259
00260 return sum;
00261 }
00262
00263 void Vector::AveVar(double & ave, double & var) const
00264 {
00265
00266
00267
00268 if (dim == 0)
00269 error("Average and Variance undefined for null vector %s",
00270 (const char *) label);
00271
00272 double s, ep;
00273
00274 ave = var = ep = 0.0;
00275
00276 for (int j=0; j<dim; j++)
00277 ave += data[j];
00278
00279 ave /= dim;
00280
00281 for (int j=0; j<dim; j++)
00282 {
00283 s = data[j] - ave;
00284 ep += s;
00285 var += s*s;
00286 }
00287
00288 if (dim > 1)
00289 var = (var - ep*ep/dim)/(dim-1);
00290 }
00291
00292 double Vector::Var() const
00293 {
00294 double mean, var;
00295 AveVar(mean, var);
00296 return var;
00297 }
00298
00299 double Vector::StandardDeviation() const
00300 {
00301 double var = Var();
00302
00303 if (var < 0.0) var = 0.0;
00304
00305 return sqrt(var);
00306 }
00307
00308 void Vector::Print(FILE * f, int d)
00309 {
00310 if (d == -1 || d > dim) d = dim;
00311
00312 fprintf(f, "%.15s : ", (const char *) label);
00313 for (int i = 0; i < d; i++)
00314 fprintf(f, "%7.3f ", data[i]);
00315 fprintf(f, "\n");
00316 }
00317
00318 int Vector::CompareDouble(const double * a, const double * b)
00319 {
00320 if (*a < *b) return -1;
00321 if (*a > *b) return 1;
00322 return 0;
00323 }
00324
00325 void Vector::Sort()
00326 {
00327 QuickSort(data, dim, sizeof(double), COMPAREFUNC CompareDouble);
00328 }
00329
00330 void Vector::Sort(Vector & freeRider)
00331 {
00332 QuickSort2(data, freeRider.data, dim, sizeof(double),
00333 COMPAREFUNC CompareDouble);
00334 }
00335
00336 int Vector::BinarySearch(double element)
00337 {
00338 void * pointer = ::BinarySearch
00339 (&element, data, dim, sizeof(double), COMPAREFUNC CompareDouble);
00340
00341 if (pointer == NULL)
00342 return -1;
00343
00344 return ((double *) pointer) - data;
00345 }
00346
00347 void Vector::RemoveDuplicates()
00348 {
00349 int out = 0;
00350
00351 for (int in = 1; in < Length(); in++)
00352 if (data[in] != data[out])
00353 data[++out] = data[in];
00354
00355 Dimension(out + 1);
00356 }
00357
00358 bool Vector::operator == (const Vector & rhs) const
00359 {
00360 if (rhs.dim != dim) return false;
00361
00362 for (int i = 0; i < dim; i++)
00363 if (data[i] != rhs[i])
00364 return false;
00365 return true;
00366 }
00367
00368
00369
00370
00371 int Vector::CountIfGreater(double threshold) const
00372 {
00373 int count = 0;
00374
00375 for (int i = 0; i < dim; i++)
00376 if (data[i] > threshold)
00377 count++;
00378
00379 return count;
00380 }
00381
00382 int Vector::CountIfGreaterOrEqual(double treshold) const
00383 {
00384 int count = 0;
00385
00386 for (int i = 0; i < dim; i++)
00387 if (data[i] >= treshold)
00388 count++;
00389
00390 return count;
00391 }
00392
00393
00394
00395
00396 double Vector::Min() const
00397 {
00398 if (dim == 0)
00399 return 0.0;
00400
00401 double min = data[0];
00402
00403 for (int i = 1; i < dim; i++)
00404 if (data[i] < min)
00405 min = data[i];
00406
00407 return min;
00408 }
00409
00410 double Vector::Max() const
00411 {
00412 if (dim == 0)
00413 return 0.0;
00414
00415 double max = data[0];
00416
00417 for (int i = 1; i < dim; i++)
00418 if (data[i] > max)
00419 max = data[i];
00420
00421 return max;
00422 }
00423
00424
00425
00426
00427 void Vector::Push(double value)
00428 {
00429 Dimension(dim + 1);
00430 data[dim - 1] = value;
00431 }
00432
00433 void Vector::Stack(const Vector & v)
00434 {
00435 int end = dim;
00436
00437 Dimension(dim + v.dim);
00438
00439 for (int i = 0; i < v.dim; i++)
00440 data[i + end] = v[i];
00441 }
00442
00443
00444
00445
00446 bool Vector::isAscending()
00447 {
00448 for (int i = 1; i < dim; i++)
00449 if (data[i] < data[i - 1])
00450 return false;
00451 return true;
00452 }
00453
00454 bool Vector::isDescending()
00455 {
00456 for (int i = 1; i < dim; i++)
00457 if (data[i] > data[i - 1])
00458 return false;
00459 return true;
00460 }
00461
00462
00463
00464
00465 VectorFunc::VectorFunc()
00466 {
00467 f = NULL;
00468 }
00469
00470 VectorFunc::VectorFunc(double(*func)(Vector &))
00471 {
00472 f = func;
00473 }
00474
00475 double VectorFunc::Evaluate(Vector & v)
00476 {
00477 return f(v);
00478 }
00479
00480 #ifndef M_SQRT2
00481 #define M_SQRT2 1.41421356
00482 #endif
00483
00484 #define MAXROUNDS 10
00485 #define SQRT_HALF (1.0/M_SQRT2)
00486 #define TWO (M_SQRT2 * M_SQRT2)
00487
00488 void VectorFunc::Derivative(Vector & x, Vector & d, double h_start)
00489 {
00490 double a[MAXROUNDS][MAXROUNDS];
00491
00492
00493 for (int k = 0; k < x.dim; k++)
00494 {
00495 double left, right;
00496 double save_x = x[k];
00497 double h = h_start;
00498
00499
00500 x[k] = save_x - h;
00501 left = Evaluate(x);
00502
00503
00504 if (k == 0 || left < dfmin)
00505 dfmin = left, dpmin = x;
00506
00507
00508 x[k] = save_x + h;
00509 right = Evaluate(x);
00510
00511
00512 if (right < dfmin)
00513 dfmin = left, dpmin = x;
00514
00515
00516 a[0][0] = (right - left) / (2.0 * h);
00517
00518
00519 double err = 1e30;
00520
00521
00522
00523 for (int i = 1; i < MAXROUNDS; i++)
00524 {
00525
00526 h *= SQRT_HALF;
00527
00528
00529 x[k] = save_x - h;
00530 left = Evaluate(x);
00531 if (left < dfmin) dfmin = left, dpmin = x;
00532 x[k] = save_x + h;
00533 right = Evaluate(x);
00534 if (right < dfmin) dfmin = right, dpmin = x;
00535
00536
00537 a[0][i] = (right - left) / (2.0 * h);
00538
00539
00540 double factor = TWO;
00541
00542 for (int j = 1; j <= i; j++)
00543 {
00544 a[j][i] = (a[j-1][i] * factor - a[j-1][i-1])/(factor - 1.0);
00545
00546 factor *= TWO;
00547
00548 double error = max(fabs(a[j][i] - a[j-1][i]), fabs(a[j][i] - a[j-1][i-1]));
00549
00550
00551 if (error < err)
00552 {
00553 err = error;
00554 d[k] = a[j][i];
00555 }
00556 }
00557
00558
00559 if (fabs(a[i][i] - a[i-1][i-1]) >= 2.0 * err)
00560 {
00561 x[k] = save_x;
00562 break;
00563 }
00564 }
00565
00566 x[k] = save_x;
00567 }
00568 }
00569
00570 int Vector::SafeCount() const
00571 {
00572 int nonMissing = dim;
00573
00574 for (int i = 0; i < dim; i++)
00575 if (data[i] == _NAN_)
00576 nonMissing--;
00577
00578 return nonMissing;
00579 }
00580
00581 double Vector::SafeMin() const
00582 {
00583 double min = _NAN_;
00584 int i;
00585
00586 for (i = 0; i < dim; i++)
00587 if (data[i] != _NAN_)
00588 {
00589 min = data[i];
00590 break;
00591 }
00592
00593 for (; i < dim; i++)
00594 if (data[i] != _NAN_ && data[i] < min)
00595 min = data[i];
00596
00597 return min;
00598 }
00599
00600 double Vector::SafeMax() const
00601 {
00602 double max = _NAN_;
00603 int i;
00604
00605 for (i = 0; i < dim; i++)
00606 if (data[i] != _NAN_)
00607 {
00608 max = data[i];
00609 break;
00610 }
00611
00612 for (; i < dim; i++)
00613 if (data[i] != _NAN_ && data[i] > max)
00614 max = data[i];
00615
00616 return max;
00617 }
00618
00619 void Vector::Reverse()
00620 {
00621 for (int i = 0, j = dim - 1; i < j; i++, j--)
00622 Swap(i, j);
00623 }
00624
00625 void Vector::InsertInSortedList(int value)
00626 {
00627
00628 int pos = dim - 1;
00629
00630 while (pos >= 0 && data[pos] > value)
00631 pos--;
00632
00633
00634 if (pos >= 0 && data[pos] == value)
00635 return;
00636
00637
00638 Dimension(dim + 1);
00639
00640
00641 pos++;
00642 for (int i = dim - 1; i > pos; i--)
00643 data[i] = data[i - 1];
00644
00645 data[pos] = value;
00646 }
00647
00648 void Vector::Swap(Vector & rhs)
00649 {
00650 double * temp = rhs.data;
00651 rhs.data = data;
00652 data = temp;
00653
00654 int swap = rhs.dim;
00655 rhs.dim = dim;
00656 dim = swap;
00657
00658 swap = rhs.size;
00659 rhs.size = size;
00660 size = swap;
00661 }
00662
00663 double Vector::Average(double returnIfNull)
00664 {
00665 if (Length() == 0)
00666 return returnIfNull;
00667
00668 return Average();
00669 }
00670
00671 double Vector::Var(double returnIfNull)
00672 {
00673 if (Length() == 0)
00674 return returnIfNull;
00675
00676 return Var();
00677 }
00678
00679 double Vector::StandardDeviation(double returnIfNull)
00680 {
00681 if (Length() == 0)
00682 return returnIfNull;
00683
00684 return StandardDeviation();
00685 }