Skip to content

Commit

Permalink
Optimize speed for FGColumnVector3.
Browse files Browse the repository at this point in the history
  • Loading branch information
bcoconni committed Feb 23, 2025
1 parent e6208a3 commit 50de871
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 64 deletions.
20 changes: 6 additions & 14 deletions src/math/FGColumnVector3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,20 +52,12 @@ namespace JSBSim {
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/

FGColumnVector3::FGColumnVector3(void)
{
data[0] = data[1] = data[2] = 0.0;
// Debug(0);
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

string FGColumnVector3::Dump(const string& delimiter) const
{
ostringstream buffer;
buffer << std::setprecision(16) << data[0] << delimiter;
buffer << std::setprecision(16) << data[1] << delimiter;
buffer << std::setprecision(16) << data[2];
buffer << std::setprecision(16) << data[2] << delimiter;
buffer << std::setprecision(16) << data[3];
return buffer.str();
}

Expand All @@ -86,7 +78,7 @@ FGColumnVector3 FGColumnVector3::operator/(const double scalar) const

cerr << "Attempt to divide by zero in method \
FGColumnVector3::operator/(const double scalar), \
object " << data[0] << " , " << data[1] << " , " << data[2] << endl;
object " << data[1] << " , " << data[2] << " , " << data[3] << endl;
return FGColumnVector3();
}

Expand All @@ -99,7 +91,7 @@ FGColumnVector3& FGColumnVector3::operator/=(const double scalar)
else
cerr << "Attempt to divide by zero in method \
FGColumnVector3::operator/=(const double scalar), \
object " << data[0] << " , " << data[1] << " , " << data[2] << endl;
object " << data[1] << " , " << data[2] << " , " << data[3] << endl;

return *this;
}
Expand All @@ -108,7 +100,7 @@ FGColumnVector3& FGColumnVector3::operator/=(const double scalar)

double FGColumnVector3::Magnitude(void) const
{
return sqrt( data[0]*data[0] + data[1]*data[1] + data[2]*data[2] );
return sqrt( data[1]*data[1] + data[2]*data[2] + data[3]*data[3] );
}

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Expand All @@ -126,7 +118,7 @@ FGColumnVector3& FGColumnVector3::Normalize(void)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

double FGColumnVector3::Magnitude(const int idx1, const int idx2) const {
return sqrt( data[idx1-1]*data[idx1-1] + data[idx2-1]*data[idx2-1] );
return sqrt( data[idx1]*data[idx1] + data[idx2]*data[idx2] );
}


Expand Down
96 changes: 46 additions & 50 deletions src/math/FGColumnVector3.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ INCLUDES

#include <iosfwd>
#include <string>
#include <string.h>

#include "JSBSim_API.h"

Expand All @@ -67,44 +68,41 @@ class JSBSIM_API FGColumnVector3
public:
/** Default initializer.
Create a zero vector. */
FGColumnVector3(void);
FGColumnVector3(void) noexcept {
memset(data, 0, sizeof(data));
}

/** Initialization by given values.
@param X value of the x-conponent.
@param Y value of the y-conponent.
@param Z value of the z-conponent.
Create a vector from the doubles given in the arguments. */
FGColumnVector3(const double X, const double Y, const double Z) {
data[0] = X;
data[1] = Y;
data[2] = Z;
FGColumnVector3(const double X, const double Y, const double Z) noexcept {
data[1] = X;
data[2] = Y;
data[3] = Z;
}

/** Copy constructor.
@param v Vector which is used for initialization.
Create copy of the vector given in the argument. */
FGColumnVector3(const FGColumnVector3& v) {
data[0] = v.data[0];
data[1] = v.data[1];
data[2] = v.data[2];
FGColumnVector3(const FGColumnVector3& v) noexcept {
memcpy(data, v.data, sizeof(data));
}

/// Destructor.
~FGColumnVector3(void) { }

/** Read access the entries of the vector.
@param idx the component index.
Return the value of the matrix entry at the given index.
Indices are counted starting with 1.
Note that the index given in the argument is unchecked. */
double operator()(const unsigned int idx) const { return data[idx-1]; }
double operator()(const unsigned int idx) const noexcept { return data[idx]; }

/** Write access the entries of the vector.
@param idx the component index.
Return a reference to the vector entry at the given index.
Indices are counted starting with 1.
Note that the index given in the argument is unchecked. */
double& operator()(const unsigned int idx) { return data[idx-1]; }
double& operator()(const unsigned int idx) noexcept { return data[idx]; }

/** Read access the entries of the vector.
@param idx the component index.
Expand All @@ -114,7 +112,7 @@ class JSBSIM_API FGColumnVector3
operator()(unsigned int idx) const</tt> function. It is
used internally to access the elements in a more convenient way.
Note that the index given in the argument is unchecked. */
double Entry(const unsigned int idx) const { return data[idx-1]; }
double Entry(const unsigned int idx) const noexcept { return data[idx]; }

/** Write access the entries of the vector.
@param idx the component index.
Expand All @@ -124,7 +122,7 @@ class JSBSIM_API FGColumnVector3
operator()(unsigned int idx)</tt> function. It is
used internally to access the elements in a more convenient way.
Note that the index given in the argument is unchecked. */
double& Entry(const unsigned int idx) { return data[idx-1]; }
double& Entry(const unsigned int idx) noexcept { return data[idx]; }

/** Prints the contents of the vector
@param delimeter the item separator (tab or comma)
Expand All @@ -134,42 +132,40 @@ class JSBSIM_API FGColumnVector3
/** Assignment operator.
@param b source vector.
Copy the content of the vector given in the argument into *this. */
FGColumnVector3& operator=(const FGColumnVector3& b) {
data[0] = b.data[0];
data[1] = b.data[1];
data[2] = b.data[2];
FGColumnVector3& operator=(const FGColumnVector3& v) noexcept {
memcpy(data, v.data, sizeof(data));
return *this;
}

/** Assignment operator.
@param lv initializer list of at most 3 values (i.e. {x, y, Z})
Copy the content of the list into *this. */
FGColumnVector3& operator=(std::initializer_list<double> lv) {
FGColumnVector3& operator=(std::initializer_list<double> lv) noexcept {
double *v = data;
for(auto &x : lv)
*(v++) = x;
*(++v) = x;

return *this;
}

/** Comparison operator.
@param b other vector.
Returns true if both vectors are exactly the same. */
bool operator==(const FGColumnVector3& b) const {
return data[0] == b.data[0] && data[1] == b.data[1] && data[2] == b.data[2];
bool operator==(const FGColumnVector3& b) const noexcept {
return data[1] == b.data[1] && data[2] == b.data[2] && data[3] == b.data[3];
}

/** Comparison operator.
@param b other vector.
Returns false if both vectors are exactly the same. */
bool operator!=(const FGColumnVector3& b) const { return ! operator==(b); }
bool operator!=(const FGColumnVector3& b) const noexcept { return ! operator==(b); }

/** Multiplication by a scalar.
@param scalar scalar value to multiply the vector with.
@return The resulting vector from the multiplication with that scalar.
Multiply the vector with the scalar given in the argument. */
FGColumnVector3 operator*(const double scalar) const {
return FGColumnVector3(scalar*data[0], scalar*data[1], scalar*data[2]);
FGColumnVector3 operator*(const double scalar) const noexcept {
return FGColumnVector3(scalar*data[1], scalar*data[2], scalar*data[3]);
}

/** Multiply by 1/scalar.
Expand All @@ -183,55 +179,55 @@ class JSBSIM_API FGColumnVector3
@return The resulting vector from the cross product multiplication.
Compute and return the cross product of the current vector with
the given argument. */
FGColumnVector3 operator*(const FGColumnVector3& V) const {
return FGColumnVector3( data[1] * V.data[2] - data[2] * V.data[1],
data[2] * V.data[0] - data[0] * V.data[2],
data[0] * V.data[1] - data[1] * V.data[0] );
FGColumnVector3 operator*(const FGColumnVector3& V) const noexcept {
return FGColumnVector3( data[2] * V.data[3] - data[3] * V.data[2],
data[3] * V.data[1] - data[1] * V.data[3],
data[1] * V.data[2] - data[2] * V.data[1] );
}

/// Addition operator.
FGColumnVector3 operator+(const FGColumnVector3& B) const {
return FGColumnVector3( data[0] + B.data[0], data[1] + B.data[1],
data[2] + B.data[2] );
FGColumnVector3 operator+(const FGColumnVector3& B) const noexcept {
return FGColumnVector3( data[1] + B.data[1], data[2] + B.data[2],
data[3] + B.data[3] );
}

/// Subtraction operator.
FGColumnVector3 operator-(const FGColumnVector3& B) const {
return FGColumnVector3( data[0] - B.data[0], data[1] - B.data[1],
data[2] - B.data[2] );
FGColumnVector3 operator-(const FGColumnVector3& B) const noexcept {
return FGColumnVector3( data[1] - B.data[1], data[2] - B.data[2],
data[3] - B.data[3] );
}

/// Subtract an other vector.
FGColumnVector3& operator-=(const FGColumnVector3 &B) {
data[0] -= B.data[0];
FGColumnVector3& operator-=(const FGColumnVector3 &B) noexcept {
data[1] -= B.data[1];
data[2] -= B.data[2];
data[3] -= B.data[3];
return *this;
}

/// Add an other vector.
FGColumnVector3& operator+=(const FGColumnVector3 &B) {
data[0] += B.data[0];
FGColumnVector3& operator+=(const FGColumnVector3 &B) noexcept {
data[1] += B.data[1];
data[2] += B.data[2];
data[3] += B.data[3];
return *this;
}

/// Scale by a scalar.
FGColumnVector3& operator*=(const double scalar) {
data[0] *= scalar;
FGColumnVector3& operator*=(const double scalar) noexcept {
data[1] *= scalar;
data[2] *= scalar;
data[3] *= scalar;
return *this;
}

/// Scale by a 1/scalar.
FGColumnVector3& operator/=(const double scalar);

void InitMatrix(void) { data[0] = data[1] = data[2] = 0.0; }
void InitMatrix(const double a) { data[0] = data[1] = data[2] = a; }
void InitMatrix(const double a, const double b, const double c) {
data[0]=a; data[1]=b; data[2]=c;
void InitMatrix(void) noexcept { memset(data, 0, sizeof(data)); }
void InitMatrix(const double a) noexcept { data[1] = data[2] = data[3] = a; }
void InitMatrix(const double a, const double b, const double c) noexcept {
data[1]=a; data[2]=b; data[3]=c;
}

/** Length of the vector.
Expand All @@ -249,13 +245,13 @@ class JSBSIM_API FGColumnVector3
FGColumnVector3& Normalize(void);

private:
double data[3];
double data[4];
};

/** Dot product of two vectors
Compute and return the euclidean dot (or scalar) product of two vectors
v1 and v2 */
inline double DotProduct(const FGColumnVector3& v1, const FGColumnVector3& v2) {
inline double DotProduct(const FGColumnVector3& v1, const FGColumnVector3& v2) noexcept {
return v1(1)*v2(1) + v1(2)*v2(2) + v1(3)*v2(3);
}

Expand All @@ -264,7 +260,7 @@ inline double DotProduct(const FGColumnVector3& v1, const FGColumnVector3& v2) {
@param A Vector to multiply.
Multiply the Vector with a scalar value. Note: At this time, this
operator MUST be inlined, or a multiple definition link error will occur.*/
inline FGColumnVector3 operator*(double scalar, const FGColumnVector3& A) {
inline FGColumnVector3 operator*(double scalar, const FGColumnVector3& A) noexcept {
// use already defined operation.
return A*scalar;
}
Expand Down

0 comments on commit 50de871

Please sign in to comment.