00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00024
00025 #include <QString>
00026 #include <QVVector>
00027 #include <QVMatrix>
00028
00029 QVVector::QVVector(const QVMatrix &matrix): QVector<double>(matrix.getCols() * matrix.getRows())
00030 {
00031 const int n = size();
00032 const double *matrixData = matrix.getReadData();
00033
00034 for(int i = 0; i < n; i++)
00035 operator[](i) = matrixData[i];
00036 }
00037
00038 double QVVector::dotProduct(const QVVector &vector) const
00039 {
00040 Q_ASSERT(size() == vector.size());
00041
00042 double accum = 0;
00043 for (int i = 0; i < size(); i++)
00044 accum += at(i) * vector[i];
00045
00046 return accum;
00047 }
00048
00049 QVVector QVVector::crossProduct(const QVVector &vector) const
00050 {
00051 Q_ASSERT(size() == vector.size());
00052 Q_ASSERT(size() == 3);
00053
00054 const double *source1 = data(),
00055 *source2 = vector.data();
00056
00057 const double x1 = source1[0], y1 = source1[1], z1 = source1[2],
00058 x2 = source2[0], y2 = source2[1], z2 = source2[2];
00059
00060 QVVector v(3);
00061
00062 double *destination = v.data();
00063 destination[0] = -y2*z1 + y1*z2;
00064 destination[1] = x2*z1 - x1*z2;
00065 destination[2] = -x2*y1 + x1*y2;
00066
00067 return v;
00068 }
00069
00070 QVMatrix QVVector::outerProduct(const QVVector &vector) const
00071 {
00072 const int m = size(), n = vector.size();
00073
00074 QVMatrix result(m,n);
00075
00076 double *rptr = result.getWriteData();
00077 const double *v1ptr = this->data(), *v2ptr;
00078
00079 for(int i=0; i<m; i++) {
00080 v2ptr = vector.data();
00081 for(int j=0; j<n; j++) {
00082 (*rptr) = (*v1ptr) * (*v2ptr);
00083 rptr++;
00084 v2ptr++;
00085 }
00086 v1ptr++;
00087 }
00088
00089 return result;
00090 }
00091
00092 QVVector QVVector::operator*(const QVMatrix &matrix) const
00093 {
00094 Q_ASSERT(size() == matrix.getRows());
00095 if (size() != matrix.getRows())
00096 {
00097 std::cout << "ERROR: tried to multiply matrices with incompatible sizes at QVMatrix::dotProduct(const QVMatrix &matrix)." << std::endl
00098 << "\tVector size:\t" << size() << std::endl
00099 << "\tMatrix dimensions:\t" << matrix.getRows() << "x" << matrix.getCols() << std::endl;
00100 exit(1);
00101 }
00102
00103 return matrix.dotProduct(*this, true);
00104 }
00105
00106 QVVector QVVector::add(const QVVector &vector) const
00107 {
00108 Q_ASSERT(size() == vector.size());
00109
00110 QVVector result(size());
00111
00112 const double *source1 = data(),
00113 *source2 = vector.data();
00114 double *destination = result.data();
00115
00116 for (int i = 0; i < size(); i++)
00117 destination[i] = source1[i] + source2[i];
00118
00119 return result;
00120 }
00121
00122 QVVector QVVector::substract(const QVVector &vector) const
00123 {
00124 Q_ASSERT(size() == vector.size());
00125
00126 QVVector result(size());
00127
00128 const double *source1 = data(),
00129 *source2 = vector.data();
00130 double *destination = result.data();
00131
00132 for (int i = 0; i < size(); i++)
00133 destination[i] = source1[i] - source2[i];
00134
00135 return result;
00136 }
00137
00138 bool QVVector::equals(const QVVector &vector) const
00139 {
00140 if (size() != vector.size())
00141 return false;
00142
00143 const double *source1 = data(),
00144 *source2 = vector.data();
00145
00146 for (int i = 0; i < size(); i++)
00147 if (source1[i] != source2[i])
00148 return false;
00149
00150 return true;
00151 }
00152
00153 QVVector QVVector::homogeneousCoordinates() const
00154 {
00155 return QVVector(*this) << 1;
00156 };
00157
00158 QVMatrix QVVector::crossProductMatrix() const
00159 {
00160 Q_ASSERT(size() == 3);
00161
00162 QVMatrix result(3,3);
00163 result(0,0) = 0; result(0,1) = -at(2); result(0,2) = at(1);
00164 result(1,0) = at(2); result(1,1) = 0; result(1,2) = -at(0);
00165 result(2,0) = -at(1); result(2,1) = at(0); result(2,2) = 0;
00166
00167 return result;
00168 }
00169
00170 QVMatrix QVVector::toRowMatrix() const
00171 {
00172 QVMatrix result(1,size());
00173 result.setRow(0,*this);
00174 return result;
00175 }
00176
00177 QVMatrix QVVector::toColumnMatrix() const
00178 {
00179 QVMatrix result(size(),1);
00180 result.setCol(0,*this);
00181 return result;
00182 }
00183
00184
00185 const QVVector QVVector::gaussianVector(const int radius, const double sigma)
00186 {
00187 const float sigma2 = sigma * sigma;
00188 QVVector result(2*radius+1);
00189 for (int j=-radius;j<=radius;j++)
00190 result[j+radius] = (float)expf(-((double)j*j)/(2.0*sigma2));
00191
00192 const double regularizer = sqrt(2*PI*sigma2);
00193 for (int i=0; i< result.size();i++)
00194 result[i] /= regularizer;
00195
00196 return result;
00197 }
00198
00199 QVVector QVVector::random(const int size)
00200 {
00201 QVVector result(size);
00202 for (int i = 0; i < size; i++)
00203 result[i] = (double)ABS(rand()) / (double)RAND_MAX;
00204 return result;
00205 }
00206
00207 const QVVector QVVector::mexicanHatWaveletVector(const int radius, const double sigma)
00208 {
00209 const float sigma2 = sigma * sigma;
00210 QVVector result(2*radius+1);
00211 for (int j=-radius;j<=radius;j++)
00212 result[j+radius] = (1-((double)j*j)/sigma2)*(float)expf(-((double)j*j)/(2.0*sigma2));
00213
00214 const double regularizer = sqrt(2*PI*sigma2*sigma);
00215 for (int i=0; i< result.size();i++)
00216 result[i] /= regularizer;
00217
00218 return result;
00219 }
00220
00221 const QVVector QVVector::homogeneousCoordinates(const QPointF &point)
00222 {
00223 QVVector result(3, 1);
00224 result[0] = point.x(); result[1] = point.y();
00225 return result;
00226 }
00227
00229
00230 double QVVector::norm2() const
00231 {
00232 return sqrt(*this * *this);
00233 }
00234
00235 bool QVVector::containsNaN() const
00236 {
00237 for (int i = 0; i < size(); i++)
00238 if (isnan(operator[](i)))
00239 return true;
00240
00241 return false;
00242 }
00243
00244 QVVector QVVector::normalize() const
00245 {
00246 return operator/(norm2());
00247 }
00248
00249 QVVector QVVector::abs() const
00250 {
00251 QVVector result (size());
00252
00253 for (int i = 0; i < size(); i++)
00254 result[i] = ABS(operator[](i));
00255 return result;
00256 }
00257
00258 double QVVector::max() const
00259 {
00260 double result = operator[](0);
00261 for (int i = 0; i < size(); i++)
00262 result = MAX(operator[](i), result);
00263 return result;
00264 }
00265
00266 double QVVector::min() const
00267 {
00268 double result = operator[](0);
00269 for (int i = 0; i < size(); i++)
00270 result = MIN(operator[](i), result);
00271 return result;
00272 }
00273
00274 double QVVector::sum() const
00275 {
00276 double accum = 0;
00277 foreach(double value, *this)
00278 accum += value;
00279
00280 return accum;
00281 }
00282
00283 double QVVector::mean() const
00284 {
00285 return sum() / (double) size();
00286 }
00287
00288 double QVVector::median() const
00289 {
00290 QVVector sortedV = *this;
00291 qSort(sortedV.begin(), sortedV.end());
00292
00293 return sortedV[sortedV.size() / 2];
00294 }
00295
00296 double QVVector::variance() const
00297 {
00298 const double avg = mean();
00299 double accum = 0;
00300 foreach(double value, *this)
00301 accum += POW2(value - avg);
00302
00303 return accum / (double) (size());
00304 }
00305
00306 double QVVector::entropy(const double base) const
00307 {
00308 const double s = sum();
00309
00310 double e = 0;
00311 foreach(double value, *this)
00312 e += (value == 0)? 0 : value * log(value / s);
00313
00314 return - e / (s * log(base));
00315 }
00316
00317 int QVVector::maxIndex() const
00318 {
00319 if (size() <= 0)
00320 return -1;
00321
00322 int maxIndex = 0;
00323 for (int i = 1; i < size(); i++)
00324 if (operator[](i) > operator[](maxIndex))
00325 maxIndex = i;
00326 return maxIndex;
00327 }
00328
00329 int QVVector::minIndex() const
00330 {
00331 if (size() <= 0)
00332 return -1;
00333
00334 int minIndex = 0;
00335 for (int i = 1; i < size(); i++)
00336 if (operator[](i) < operator[](minIndex))
00337 minIndex = i;
00338 return minIndex;
00339 }
00340
00341 int QVVector::maxAbsIndex() const
00342 {
00343 if (size() <= 0)
00344 return -1;
00345
00346 int maxIndex = 0;
00347 for (int i = 1; i < size(); i++)
00348 if ( ABS(operator[](i)) > ABS(operator[](maxIndex)) )
00349 maxIndex = i;
00350
00351 return maxIndex;
00352 }
00353
00354 int QVVector::minAbsIndex() const
00355 {
00356 if (size() <= 0)
00357 return -1;
00358
00359 int minIndex = 0;
00360 for (int i = 1; i < size(); i++)
00361 if ( ABS(operator[](i)) < ABS(operator[](minIndex)) )
00362 minIndex = i;
00363
00364 return minIndex;
00365 }
00366
00367 void QVVector::set(const double value)
00368 {
00369 for (int i = 0; i < size(); i++)
00370 operator[](i) = value;
00371 };
00372
00373 QVVector QVVector::subVector(const int firstIndex, const int lastIndex) const
00374 {
00375 Q_ASSERT(0 <= firstIndex);
00376 Q_ASSERT(firstIndex <= lastIndex);
00377 Q_ASSERT(lastIndex < this->size());
00378
00379 QVVector result(lastIndex - firstIndex +1);
00380 for (int r = 0, i = firstIndex; i <= lastIndex; i++, r++)
00381 result[r] = operator[](i);
00382
00383 return result;
00384 };
00385
00386 QVVector QVVector::scalarDivision(const double value) const
00387 {
00388 QVVector result = *this;
00389 for (int i = 0; i < size(); i++)
00390 result[i] /= value;
00391
00392 return result;
00393 };
00394
00395 QVVector QVVector::scalarAdd(const double value) const
00396 {
00397 QVVector result = *this;
00398 for (int i = 0; i < size(); i++)
00399 result[i] += value;
00400
00401 return result;
00402 };
00403
00404 QVVector QVVector::scalarSubstract(const double value) const
00405 {
00406 QVVector result = *this;
00407 for (int i = 0; i < size(); i++)
00408 result[i] -= value;
00409
00410 return result;
00411 };
00412
00413 QVVector QVVector::scalarMultiplication(const double value) const
00414 {
00415 std::cout << "DEPRECATED: QVVector::scalarMultiplication(). Use QVVector::scalarProduct() instead" << std::endl;
00416 return scalarProduct(value);
00417 }
00418
00419 QVVector QVVector::scalarProduct(const double value) const
00420 {
00421 QVVector result = *this;
00422 for (int i = 0; i < size(); i++)
00423 result[i] *= value;
00424 return result;
00425 };
00426
00427
00428 std::ostream& operator << ( std::ostream &os, const QVVector &vector )
00429 {
00430 const int size = vector.size();
00431
00432 os << "QVVector (" << size << ") [ ";
00433
00434 for (int i = 0; i < size; i++)
00435 os << qPrintable(QString("%1").arg(vector[i], -8, 'f', 6)) << " ";
00436
00437 os << "]";
00438 return os;
00439 }
00440
00441 uint qHash(const QVVector &vector)
00442 {
00443 const int size = vector.size();
00444 double accum = 0;
00445 for (int i = 0; i < size; i++)
00446 accum += vector[i] / vector[size-i-1];
00447
00448 return (uint) ((100000 * accum) / ((double) size));
00449 }
00450
00451
00452 QVVector operator*(const double value, const QVVector &vector)
00453 {
00454 return vector.scalarProduct(value);
00455 }
00456
00457 QVVector operator+(const double value, const QVVector &vector)
00458 {
00459 return vector.scalarAdd(value);
00460 }
00461
00462 QVVector operator-(const double value, const QVVector &vector)
00463 {
00464 return vector.scalarSubstract(value);
00465 }