Newer
Older
#ifndef MANTID_GEOMETRY_V3R_H_
#define MANTID_GEOMETRY_V3R_H_
#include "MantidGeometry/DllConfig.h"
#include "MantidKernel/Exception.h"
#include "MantidKernel/V3D.h"
#include "MantidKernel/Matrix.h"
#include <boost/rational.hpp>
namespace Mantid {
namespace Geometry {
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/** V3R :
In crystallography, many operations use rational numbers like 1/2, 1/4
or 2/3. Floating point numbers can approximate these, but calculations
involving these approximations are never exact.
V3R is a vector with three rational components, implemented using
boost::rational<int>. This way, crystallographic calculations involving
fractional vectors may be carried out exactly (for example symmetry
operations with a translational component).
@author Michael Wedel, Paul Scherrer Institut - SINQ
@date 26/09/2014
Copyright © 2014 PSI-MSS
This file is part of Mantid.
Mantid is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
Mantid is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
File change history is stored at: <https://github.com/mantidproject/mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
typedef boost::rational<int> RationalNumber;
V3R();
V3R(const RationalNumber &x, const RationalNumber &y,
const RationalNumber &z);
V3R(const std::vector<int> &vector);
const RationalNumber &x() const;
void setX(const RationalNumber &newX);
const RationalNumber &y() const;
void setY(const RationalNumber &newY);
const RationalNumber &z() const;
void setZ(const RationalNumber &newZ);
RationalNumber &operator[](size_t index);
const RationalNumber &operator[](size_t index) const;
// Operations with other vectors of rational numbers
V3R operator+(const V3R &other) const;
V3R &operator+=(const V3R &other);
V3R operator-() const;
V3R operator-(const V3R &other) const;
V3R &operator-=(const V3R &other);
// Operations with integers
V3R operator+(int other) const;
V3R &operator+=(int other);
V3R operator-(int other) const;
V3R &operator-=(int other);
V3R operator*(int other) const;
V3R &operator*=(int other);
V3R operator/(int other) const;
V3R &operator/=(int other);
// Operations with rational numbers
V3R operator+(const RationalNumber &other) const;
V3R &operator+=(const RationalNumber &other);
V3R operator-(const RationalNumber &other) const;
V3R &operator-=(const RationalNumber &other);
V3R operator*(const RationalNumber &other) const;
V3R &operator*=(const RationalNumber &other);
V3R operator/(const RationalNumber &other) const;
V3R &operator/=(const RationalNumber &other);
// Operations with V3D
operator Kernel::V3D() const;
Kernel::V3D operator+(const Kernel::V3D &other) const;
Kernel::V3D operator-(const Kernel::V3D &other) const;
// Comparison operators
bool operator==(const V3R &other) const;
bool operator!=(const V3R &other) const;
bool operator<(const V3R &other) const;
bool operator==(int other) const;
bool operator!=(int other) const;
V3R getPositiveVector() const;
// std::vector<double> operator
operator std::vector<double>() const;
protected:
RationalNumber m_x;
RationalNumber m_y;
RationalNumber m_z;
/// Performs a matrix multiplication v' = M * v, throws
/// Kernel::Exception::MisMatch<size_t> if M does not have exactly 3 columns.
template <typename T>
V3R operator*(const Kernel::Matrix<T> &lhs, const V3R &rhs) {
size_t rows = lhs.numRows();
size_t cols = lhs.numCols();
if (cols != 3) {
throw Kernel::Exception::MisMatch<size_t>(cols, 3,
"operator*(IntMatrix, V3R)");
}
V3R result;
for (size_t r = 0; r < rows; ++r) {
for (size_t c = 0; c < cols; ++c) {
result[r] +=
static_cast<typename RationalNumber::int_type>(lhs[r][c]) * rhs[c];
}
}
return result;
}
} // namespace Geometry
} // namespace Mantid
#endif /* MANTID_GEOMETRY_V3R_H_ */