/*! * \brief OiMat::operator * * Multiply v by this matrix * \param v * \return */ OiVec OiMat::operator*(const OiVec &v) const{ if( this->getColCount() == v.getSize() && v.getSize() > 0 ){ OiVec result(this->getRowCount()); OiVec::myLinearAlgebra->multiply(result, *this, v); return result; }else{ throw logic_error("Cannot multiply a vector by a matrix with incompatible size"); return OiVec(); } }
/*! * \brief OiMat::getCol * Get column vector at the specified position * \param col * \return */ OiVec OiMat::getCol(const int col) const{ OiVec result; if(this->values.size() > 0 && this->values.at(0).size() > col){ for(int i = 0; i < this->values.size(); i++){ result.add(this->values.at(i).at(col)); } }else{ throw runtime_error("Size of matrix less than requested position"); } return result; }
/*! * \brief LAArmadillo::multiply * Multiply v by s * \param result * \param s * \param v */ void LAArmadillo::multiply(OiVec &result, const double &s, const OiVec &v){ arma::vec va(v.getSize()); this->oiVec2Arma(va, v); this->arma2OiVec(result, (s * va)); }
/*! * \brief OiMat::setCol * Replace the column at index by the given column * \param index * \param col */ void OiMat::setCol(const int index, const OiVec &col){ if(this->getColCount() > index){ //if there is a column at index if(this->getRowCount() == col.getSize()){ //if the given column has the right number of elements for(unsigned int i = 0; i < col.getSize(); i++){ this->values.at(i).at(index) = col.getAt(i); } }else{ throw logic_error("Cannot replace a column of a matrix by a given column with incompatible size"); } }else{ throw logic_error("Cannot replace a column of a matrix by a given column because of an invalid index"); } }
/*! * \brief LAArmadillo::substract * Substract v2 from v1 * \param result * \param v1 * \param v2 */ void LAArmadillo::substract(OiVec &result, const OiVec &v1, const OiVec &v2){ int vecSize = v1.getSize(); arma::vec v1a(vecSize), v2a(vecSize); this->oiVec2Arma(v1a, v1); this->oiVec2Arma(v2a, v2); this->arma2OiVec(result, (v1a - v2a)); }
/*! * \brief LAArmadillo::dot * Calculate scalar product of a and b * \param result * \param a * \param b */ void LAArmadillo::dot(double &result, const OiVec &a, const OiVec &b){ int vecSize = b.getSize(); arma::vec aa(vecSize), ba(vecSize); this->oiVec2Arma(aa, a); this->oiVec2Arma(ba, b); result = arma::dot(aa, ba); }
/*! * \brief LAArmadillo::cross * Calculate cross product of a and b * \param result * \param a * \param b */ void LAArmadillo::cross(OiVec &result, const OiVec &a, const OiVec &b){ int vecSize = b.getSize(); arma::vec aa(vecSize), ba(vecSize); this->oiVec2Arma(aa, a); this->oiVec2Arma(ba, b); this->arma2OiVec(result, arma::cross(aa, ba)); }
/*! * \brief LAArmadillo::multiply * Multiply v by m * \param result * \param m * \param v */ void LAArmadillo::multiply(OiVec &result, const OiMat &m, const OiVec &v){ int vecSize = v.getSize(); arma::vec va(vecSize); arma::mat ma(m.getRowCount(), vecSize); this->oiVec2Arma(va, v); this->oiMat2Arma(ma, m); this->arma2OiVec(result, (ma * va)); }
/*! * \brief Torus::setUnknownParameters * \param parameters */ void Torus::setUnknownParameters(const QMap<GeometryParameters, double> ¶meters){ //get current parameters OiVec position = this->center.getVector(); OiVec direction = this->normal.getVector(); double radiusA = this->radiusA.getRadius(); double radiusB = this->radiusB.getRadius(); //update parameters QList<GeometryParameters> keys = parameters.keys(); foreach(const GeometryParameters &key, keys){ switch(key){ case eUnknownX: position.setAt(0, parameters.value(eUnknownX)); break; case eUnknownY: position.setAt(1, parameters.value(eUnknownY)); break; case eUnknownZ: position.setAt(2, parameters.value(eUnknownZ)); break; case eUnknownPrimaryI: direction.setAt(0, parameters.value(eUnknownPrimaryI)); break; case eUnknownPrimaryJ: direction.setAt(1, parameters.value(eUnknownPrimaryJ)); break; case eUnknownPrimaryK: direction.setAt(2, parameters.value(eUnknownPrimaryK)); break; case eUnknownRadiusA: radiusA = parameters.value(eUnknownRadiusA); break; case eUnknownRadiusB: radiusB = parameters.value(eUnknownRadiusA); break; } } //update torus definition direction.normalize(); Position torusPosition(position); Direction torusDirection(direction); Radius torusRadiusA(radiusA); Radius torusRadiusB(radiusB); this->setTorus(torusPosition, torusDirection, torusRadiusA, torusRadiusB); }
/*! * \brief Reading::errorPropagationPolarToCart * Variance propagation to get sigma values for cartesian coordinates * \return */ OiVec Reading::errorPropagationPolarToCart(){ OiVec sigmaCartXyz; OiMat F(3,3); F.setAt(0, 0, qSin(this->rPolar.zenith) * qCos(this->rPolar.azimuth)); F.setAt(0, 1, this->rPolar.distance * qSin(this->rPolar.zenith) * -qSin(this->rPolar.azimuth)); F.setAt(0, 2, this->rPolar.distance * qCos(this->rPolar.zenith) * qCos(this->rPolar.azimuth)); F.setAt(1, 0, qSin(this->rPolar.zenith) * qSin(this->rPolar.azimuth)); F.setAt(1, 1, this->rPolar.distance * qSin(this->rPolar.zenith) * qCos(this->rPolar.azimuth)); F.setAt(1, 2, this->rPolar.distance * qCos(this->rPolar.zenith) * qSin(this->rPolar.azimuth)); F.setAt(2, 0, qCos(this->rPolar.zenith)); F.setAt(2, 1, 0.0); F.setAt(2, 2, this->rPolar.distance * -qSin(this->rPolar.zenith)); OiMat Sll(3,3); Sll.setAt(0, 0, this->rPolar.sigmaDistance * this->rPolar.sigmaDistance); Sll.setAt(1, 1, this->rPolar.sigmaAzimuth * this->rPolar.sigmaAzimuth); Sll.setAt(2, 2, this->rPolar.sigmaZenith * this->rPolar.sigmaZenith); OiMat Qxx = F * Sll * F.t(); //transform Qxx into homogeneous coordinates OiMat Qxx_hc(4,4); for(int i = 0; i < 3; i++){ for(int j = 0; j < 3; j++){ Qxx_hc.setAt(i,j, Qxx.getAt(i,j)); } } sigmaCartXyz.add(qSqrt(Qxx.getAt(0,0))); sigmaCartXyz.add(qSqrt(Qxx.getAt(1,1))); sigmaCartXyz.add(qSqrt(Qxx.getAt(2,2))); sigmaCartXyz.add(1.0); if(this->obs != NULL){ this->obs->myStatistic.qxx = Qxx_hc; this->obs->myStatistic.s0_apriori = 1.0; this->obs->myOriginalStatistic = this->obs->myStatistic; } return sigmaCartXyz; }
/*! * \brief OiMat::setRow * Replace the row at index by the given row * \param index * \param row */ void OiMat::setRow(const int index, const OiVec &row){ if(this->getRowCount() > index){ //if there is a row at index if(this->getColCount() == row.getSize()){ //if the given row has the right number of elements //fill vector with the given values... vector<double> rowVec; for(unsigned int i = 0; i < row.getSize(); i++){ rowVec.push_back(row.getAt(i)); } //...and replace the row of the matrix at index this->values.at(index) = rowVec; }else{ throw logic_error("Cannot replace a row of a matrix by a given row with incompatible size"); } }else{ throw logic_error("Cannot replace a row of a matrix by a given row because of an invalid index"); } }
/*! * \brief Line::setUnknownParameters * \param parameters */ void Line::setUnknownParameters(const QMap<GeometryParameters, double> ¶meters){ //get current parameters OiVec position = this->xyz.getVector(); OiVec direction = this->axis.getVector(); //update parameters QList<GeometryParameters> keys = parameters.keys(); foreach(const GeometryParameters &key, keys){ switch(key){ case eUnknownX: position.setAt(0, parameters.value(eUnknownX)); break; case eUnknownY: position.setAt(1, parameters.value(eUnknownY)); break; case eUnknownZ: position.setAt(2, parameters.value(eUnknownZ)); break; case eUnknownPrimaryI: direction.setAt(0, parameters.value(eUnknownPrimaryI)); break; case eUnknownPrimaryJ: direction.setAt(1, parameters.value(eUnknownPrimaryJ)); break; case eUnknownPrimaryK: direction.setAt(2, parameters.value(eUnknownPrimaryK)); break; } } //update line definition direction.normalize(); Position linePosition(position); Direction lineDirection(direction); this->setLine(linePosition, lineDirection); }
/*! * \brief OiMat::getRotationMatrix * Get the rotation matrix corresponding to a rotation around an arbitrary rotation axis by the given amount * \param angle * \param axis * \return */ OiMat OiMat::getRotationMatrix(double angle, OiVec axis){ if(axis.getSize() == 3){ OiMat result(3, 3); axis = axis.normalize(); double w = qCos(angle / 2.0); OiVec x = qSin(angle / 2.0) * axis; result.setAt(0, 0, 1.0 - 2.0 * (x.getAt(1)*x.getAt(1) + x.getAt(2)*x.getAt(2))); result.setAt(0, 1, 2.0 * (x.getAt(0)*x.getAt(1) - w * x.getAt(2))); result.setAt(0, 2, 2.0 * (x.getAt(0)*x.getAt(2) + w * x.getAt(1))); result.setAt(1, 0, 2.0 * (x.getAt(0)*x.getAt(1) + w * x.getAt(2))); result.setAt(1, 1, 1.0 - 2.0 * (x.getAt(0)*x.getAt(0) + x.getAt(2)*x.getAt(2))); result.setAt(1, 2, 2.0 * (x.getAt(1)*x.getAt(2) - w * x.getAt(0))); result.setAt(2, 0, 2.0 * (x.getAt(0)*x.getAt(2) - w * x.getAt(1))); result.setAt(2, 1, 2.0 * (x.getAt(1)*x.getAt(2) + w * x.getAt(0))); result.setAt(2, 2, 1.0 - 2.0 * (x.getAt(0)*x.getAt(0) + x.getAt(1)*x.getAt(1))); return result; }else{ throw logic_error("To set up the rotation matrix the given axis has to be of size 3"); return OiMat(); } }
/*! * \brief LAArmadillo::arma2OiVec * \param result * \param v */ void LAArmadillo::arma2OiVec(OiVec &result, const arma::vec &v){ for(int i = 0; i < v.n_rows; i++){ result.setAt(i, v[i]); } }
/*! * \brief LAArmadillo::oiVec2Arma * \param result * \param v */ void LAArmadillo::oiVec2Arma(arma::vec &result, const OiVec &v){ for(int i = 0; i < v.getSize(); i++){ result[i] = v.getAt(i); } }
/*! * \brief Ellipse::setUnknownParameters * \param parameters */ void Ellipse::setUnknownParameters(const QMap<GeometryParameters, double> ¶meters){ //get current parameters OiVec position = this->center.getVector(); OiVec directionA = this->normal.getVector(); OiVec directionB = this->semiMajorAxis.getVector(); double a = this->a; double b = this->b; //update parameters QList<GeometryParameters> keys = parameters.keys(); foreach(const GeometryParameters &key, keys){ switch(key){ case eUnknownX: position.setAt(0, parameters.value(eUnknownX)); break; case eUnknownY: position.setAt(1, parameters.value(eUnknownY)); break; case eUnknownZ: position.setAt(2, parameters.value(eUnknownZ)); break; case eUnknownPrimaryI: directionA.setAt(0, parameters.value(eUnknownPrimaryI)); break; case eUnknownPrimaryJ: directionA.setAt(1, parameters.value(eUnknownPrimaryJ)); break; case eUnknownPrimaryK: directionA.setAt(2, parameters.value(eUnknownPrimaryK)); break; case eUnknownA: a = parameters.value(eUnknownA); break; case eUnknownB: b = parameters.value(eUnknownB); break; case eUnknownSecondaryI: directionB.setAt(0, parameters.value(eUnknownSecondaryI)); break; case eUnknownSecondaryJ: directionB.setAt(1, parameters.value(eUnknownSecondaryJ)); break; case eUnknownSecondaryK: directionB.setAt(2, parameters.value(eUnknownSecondaryK)); break; } } //update ellipse definition directionA.normalize(); directionB.normalize(); Position ellipsePosition(position); Direction ellipseDirectionA(directionA); Direction ellipseDirectionB(directionB); this->setEllipse(ellipsePosition, ellipseDirectionA, a, b, ellipseDirectionB); }