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