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 QVMatrix QVVector::crossProductMatrix() const
00117 {
00118 Q_ASSERT(size() == 3);
00119
00120 QVMatrix result(3,3);
00121 result(0,0) = 0; result(0,1) = -at(2); result(0,2) = at(1);
00122 result(1,0) = at(2); result(1,1) = 0; result(1,2) = -at(0);
00123 result(2,0) = -at(1); result(2,1) = at(0); result(2,2) = 0;
00124
00125 return result;
00126 }
00127
00128 QVMatrix QVVector::toRowMatrix() const
00129 {
00130 QVMatrix result(1,size());
00131 result.setRow(0,*this);
00132 return result;
00133 }
00134
00135 QVMatrix QVVector::toColumnMatrix() const
00136 {
00137 QVMatrix result(size(),1);
00138 result.setCol(0,*this);
00139 return result;
00140 }
00141
00142
00143 const QVVector QVVector::gaussianVector(const int radius, const double sigma)
00144 {
00145 const float sigma2 = sigma * sigma;
00146 QVVector result(2*radius+1);
00147 for (int j=-radius;j<=radius;j++)
00148 result[j+radius] = (float)expf(-((double)j*j)/(2.0*sigma2));
00149
00150 const double regularizer = sqrt(2*PI*sigma2);
00151 for (int i=0; i< result.size();i++)
00152 result[i] /= regularizer;
00153
00154 return result;
00155 }
00156
00157 const QVVector QVVector::mexicanHatWaveletVector(const int radius, const double sigma)
00158 {
00159 const float sigma2 = sigma * sigma;
00160 QVVector result(2*radius+1);
00161 for (int j=-radius;j<=radius;j++)
00162 result[j+radius] = (1-((double)j*j)/sigma2)*(float)expf(-((double)j*j)/(2.0*sigma2));
00163
00164 const double regularizer = sqrt(2*PI*sigma2*sigma);
00165 for (int i=0; i< result.size();i++)
00166 result[i] /= regularizer;
00167
00168 return result;
00169 }
00170
00171 const QVVector QVVector::homogeneousCoordinates(const QPointF &point)
00172 {
00173 QVVector result(3, 1);
00174 result[0] = point.x(); result[1] = point.y();
00175 return result;
00176 }
00177
00179
00180 double QVVector::max() const
00181 {
00182 double result = operator[](0);
00183 for (int i = 0; i < size(); i++)
00184 result = MAX(operator[](i), result);
00185 return result;
00186 }
00187
00188 double QVVector::min() const
00189 {
00190 double result = operator[](0);
00191 for (int i = 0; i < size(); i++)
00192 result = MIN(operator[](i), result);
00193 return result;
00194 }
00195
00196 double QVVector::sum() const
00197 {
00198 double accum = 0;
00199 foreach(double value, *this)
00200 accum += value;
00201
00202 return accum;
00203 }
00204
00205 double QVVector::mean() const
00206 {
00207 return sum() / (double) size();
00208 }
00209
00210 double QVVector::variance() const
00211 {
00212 const double avg = mean();
00213 double accum = 0;
00214 foreach(double value, *this)
00215 accum += POW2(value - avg);
00216
00217 return accum / (double) (size()+1);
00218 }
00219
00220 double QVVector::entropy(const double base) const
00221 {
00222 const double s = sum();
00223
00224 double e = 0;
00225 foreach(double value, *this)
00226 e += (value == 0)? 0 : value * log(value / s);
00227
00228 return - e / (s * log(base));
00229 }
00230
00231 std::ostream& operator << ( std::ostream &os, const QVVector &vector )
00232 {
00233 const int size = vector.size();
00234
00235 os << "QVVector (" << size << ") [ ";
00236
00237 for (int i = 0; i < size; i++)
00238 os << qPrintable(QString("%1").arg(vector[i], -8, 'f', 6)) << " ";
00239
00240 os << "]";
00241 return os;
00242 }
00243
00244 uint qHash(const QVVector &vector)
00245 {
00246 const int size = vector.size();
00247 double accum = 0;
00248 for (int i = 0; i < size; i++)
00249 accum += vector[i] / vector[size-i-1];
00250
00251 return (uint) ((100000 * accum) / ((double) size));
00252 }
00253