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 #include <qvmath.h>
00030
00031 QVVector::QVVector(const QVMatrix &matrix): QVector<double>(matrix.getCols() * matrix.getRows())
00032 {
00033 const int n = size();
00034 const double *matrixData = matrix.getReadData();
00035
00036 for(int i = 0; i < n; i++)
00037 operator[](i) = matrixData[i];
00038 }
00039
00040 double QVVector::dotProduct(const QVVector &vector) const
00041 {
00042 Q_ASSERT(size() == vector.size());
00043
00044 double accum = 0;
00045 for (int i = 0; i < size(); i++)
00046 accum += at(i) * vector[i];
00047
00048 return accum;
00049 }
00050
00051 QVVector QVVector::crossProduct(const QVVector &vector) const
00052 {
00053 Q_ASSERT(size() == vector.size());
00054 Q_ASSERT(size() == 3);
00055
00056 const double x1 = at(0), y1 = at(1), z1 = at(2),
00057 x2 = vector[0], y2 = vector[1], z2 = vector[2];
00058
00059 QVVector v(3);
00060
00061 v[0] = -y2*z1 + y1*z2;
00062 v[1] = x2*z1 - x1*z2;
00063 v[2] = -x2*y1 + x1*y2;
00064
00065 return v;
00066 }
00067
00068 QVVector QVVector::operator*(const QVMatrix &matrix) const
00069 {
00070 Q_ASSERT(size() == matrix.getRows());
00071 if (size() != matrix.getRows())
00072 {
00073 std::cout << "ERROR: tried to multiply matrices with incompatible sizes at QVMatrix::dotProduct(const QVMatrix &matrix)." << std::endl
00074 << "\tVector size:\t" << size() << std::endl
00075 << "\tMatrix dimentions:\t" << matrix.getRows() << "x" << matrix.getCols() << std::endl;
00076 exit(1);
00077 }
00078
00079 return this->toRowMatrix().dotProduct(matrix).getRow(0);
00080 }
00081
00082 QVVector QVVector::add(const QVVector &vector) const
00083 {
00084 Q_ASSERT(size() == vector.size());
00085
00086 QVVector result(size());
00087 for (int i = 0; i < size(); i++)
00088 result[i] = at(i) + vector[i];
00089
00090 return result;
00091 }
00092
00093 QVVector QVVector::substract(const QVVector &vector) const
00094 {
00095 Q_ASSERT(size() == vector.size());
00096
00097 QVVector result(size());
00098 for (int i = 0; i < size(); i++)
00099 result[i] = at(i) - vector[i];
00100
00101 return result;
00102 }
00103
00104 bool QVVector::equals(const QVVector &vector) const
00105 {
00106 if (size() != vector.size())
00107 return false;
00108
00109 for (int i = 0; i < size(); i++)
00110 if (at(i) != vector[i])
00111 return false;
00112
00113 return true;
00114 }
00115
00116 QVVector QVVector::homogeneousCoordinates() const
00117 {
00118 return QVVector(*this) << 1;
00119 };
00120
00121 QVMatrix QVVector::crossProductMatrix() const
00122 {
00123 Q_ASSERT(size() == 3);
00124
00125 QVMatrix result(3,3);
00126 result(0,0) = 0; result(0,1) = -at(2); result(0,2) = at(1);
00127 result(1,0) = at(2); result(1,1) = 0; result(1,2) = -at(0);
00128 result(2,0) = -at(1); result(2,1) = at(0); result(2,2) = 0;
00129
00130 return result;
00131 }
00132
00133 QVMatrix QVVector::toRowMatrix() const
00134 {
00135 QVMatrix result(1,size());
00136 result.setRow(0,*this);
00137 return result;
00138 }
00139
00140 QVMatrix QVVector::toColumnMatrix() const
00141 {
00142 QVMatrix result(size(),1);
00143 result.setCol(0,*this);
00144 return result;
00145 }
00146
00147
00148 const QVVector QVVector::gaussianVector(const int radius, const double sigma)
00149 {
00150 const float sigma2 = sigma * sigma;
00151 QVVector result(2*radius+1);
00152 for (int j=-radius;j<=radius;j++)
00153 result[j+radius] = (float)expf(-((double)j*j)/(2.0*sigma2));
00154
00155 const double regularizer = sqrt(2*PI*sigma2);
00156 for (int i=0; i< result.size();i++)
00157 result[i] /= regularizer;
00158
00159 return result;
00160 }
00161
00162 const QVVector QVVector::mexicanHatWaveletVector(const int radius, const double sigma)
00163 {
00164 const float sigma2 = sigma * sigma;
00165 QVVector result(2*radius+1);
00166 for (int j=-radius;j<=radius;j++)
00167 result[j+radius] = (1-((double)j*j)/sigma2)*(float)expf(-((double)j*j)/(2.0*sigma2));
00168
00169 const double regularizer = sqrt(2*PI*sigma2*sigma);
00170 for (int i=0; i< result.size();i++)
00171 result[i] /= regularizer;
00172
00173 return result;
00174 }
00175
00176 const QVVector QVVector::homogeneousCoordinates(const QPointF &point)
00177 {
00178 QVVector result(3, 1);
00179 result[0] = point.x(); result[1] = point.y();
00180 return result;
00181 }
00182
00184
00185 double QVVector::max() const
00186 {
00187 double result = operator[](0);
00188 for (int i = 0; i < size(); i++)
00189 result = MAX(operator[](i), result);
00190 return result;
00191 }
00192
00193 double QVVector::min() const
00194 {
00195 double result = operator[](0);
00196 for (int i = 0; i < size(); i++)
00197 result = MIN(operator[](i), result);
00198 return result;
00199 }
00200
00201 double QVVector::sum() const
00202 {
00203 double accum = 0;
00204 foreach(double value, *this)
00205 accum += value;
00206
00207 return accum;
00208 }
00209
00210 double QVVector::mean() const
00211 {
00212 return sum() / (double) size();
00213 }
00214
00215 double QVVector::variance() const
00216 {
00217 const double avg = mean();
00218 double accum = 0;
00219 foreach(double value, *this)
00220 accum += POW2(value - avg);
00221
00222 return accum / (double) (size()+1);
00223 }
00224
00225 double QVVector::entropy(const double base) const
00226 {
00227 const double s = sum();
00228
00229 double e = 0;
00230 foreach(double value, *this)
00231 e += (value == 0)? 0 : value * log(value / s);
00232
00233 return - e / (s * log(base));
00234 }
00235
00236 std::ostream& operator << ( std::ostream &os, const QVVector &vector )
00237 {
00238 const int size = vector.size();
00239
00240 os << "QVVector (" << size << ") [ ";
00241
00242 for (int i = 0; i < size; i++)
00243 os << qPrintable(QString("%1").arg(vector[i], -8, 'f', 6)) << " ";
00244
00245 os << "]";
00246 return os;
00247 }
00248
00249 uint qHash(const QVVector &vector)
00250 {
00251 const int size = vector.size();
00252 double accum = 0;
00253 for (int i = 0; i < size; i++)
00254 accum += vector[i] / vector[size-i-1];
00255
00256 return (uint) ((100000 * accum) / ((double) size));
00257 }
00258