New norms and division by scalar
Some checks failed
Merge-Checker / build_and_test (pull_request) Failing after 21s
Some checks failed
Merge-Checker / build_and_test (pull_request) Failing after 21s
This commit is contained in:
@@ -337,6 +337,22 @@ Matrix<rows, columns> Matrix<rows, columns>::operator*(float scalar) const {
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <uint8_t rows, uint8_t columns>
|
||||||
|
Matrix<rows, columns> Matrix<rows, columns>::operator/(float scalar) const {
|
||||||
|
Matrix<rows, columns> buffer = *this;
|
||||||
|
if (scalar == 0) {
|
||||||
|
buffer.Fill(1e+10);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint8_t row = 0; row < rows; row++) {
|
||||||
|
for (uint8_t column = 0; column < columns; column++) {
|
||||||
|
buffer[row][column] /= scalar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
template <uint8_t rows, uint8_t columns>
|
template <uint8_t rows, uint8_t columns>
|
||||||
template <uint8_t vector_size>
|
template <uint8_t vector_size>
|
||||||
float Matrix<rows, columns>::DotProduct(const Matrix<1, vector_size> &vec1,
|
float Matrix<rows, columns>::DotProduct(const Matrix<1, vector_size> &vec1,
|
||||||
@@ -423,7 +439,7 @@ Matrix<rows, columns>::adjugate(Matrix<rows, columns> &result) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <uint8_t rows, uint8_t columns>
|
template <uint8_t rows, uint8_t columns>
|
||||||
Matrix<rows, columns> Matrix<rows, columns>::EuclideanNorm() const {
|
float Matrix<rows, columns>::EuclideanNorm() const {
|
||||||
|
|
||||||
float sum{0};
|
float sum{0};
|
||||||
for (uint8_t row_idx{0}; row_idx < rows; row_idx++) {
|
for (uint8_t row_idx{0}; row_idx < rows; row_idx++) {
|
||||||
@@ -433,21 +449,17 @@ Matrix<rows, columns> Matrix<rows, columns>::EuclideanNorm() const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix<rows, columns> result{};
|
return sqrt(sum);
|
||||||
if (sum == 0) {
|
}
|
||||||
// this wouldn't do anything anyways
|
template <uint8_t rows, uint8_t columns>
|
||||||
result.Fill(0);
|
float Matrix<rows, columns>::L2Norm() const {
|
||||||
return result;
|
float sum{0};
|
||||||
|
Matrix<rows, 1> columnMatrix{};
|
||||||
|
for (uint8_t column = 0; column < columns; column++) {
|
||||||
|
this.GetColumn(column, columnMatrix);
|
||||||
|
sum += columnMatrix.EuclideanNorm();
|
||||||
}
|
}
|
||||||
|
return sqrt(sum);
|
||||||
sum = sqrt(sum);
|
|
||||||
for (uint8_t row_idx{0}; row_idx < rows; row_idx++) {
|
|
||||||
for (uint8_t column_idx{0}; column_idx < columns; column_idx++) {
|
|
||||||
result[row_idx][column_idx] = this->Get(row_idx, column_idx) / sum;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <uint8_t rows, uint8_t columns>
|
template <uint8_t rows, uint8_t columns>
|
||||||
|
|||||||
@@ -132,7 +132,9 @@ public:
|
|||||||
* @brief reduce the matrix so the sum of its elements equal 1
|
* @brief reduce the matrix so the sum of its elements equal 1
|
||||||
* @param result a buffer to store the result into
|
* @param result a buffer to store the result into
|
||||||
*/
|
*/
|
||||||
Matrix<rows, columns> EuclideanNorm() const;
|
float EuclideanNorm() const;
|
||||||
|
|
||||||
|
float L2Norm() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get a row from the matrix
|
* @brief Get a row from the matrix
|
||||||
@@ -201,6 +203,8 @@ public:
|
|||||||
|
|
||||||
Matrix<rows, columns> operator*(float scalar) const;
|
Matrix<rows, columns> operator*(float scalar) const;
|
||||||
|
|
||||||
|
Matrix<rows, columns> operator/(float scalar) const;
|
||||||
|
|
||||||
template <uint8_t sub_rows, uint8_t sub_columns, uint8_t row_offset,
|
template <uint8_t sub_rows, uint8_t sub_columns, uint8_t row_offset,
|
||||||
uint8_t column_offset>
|
uint8_t column_offset>
|
||||||
Matrix<sub_rows, sub_columns> SubMatrix() const;
|
Matrix<sub_rows, sub_columns> SubMatrix() const;
|
||||||
|
|||||||
@@ -9,8 +9,7 @@
|
|||||||
Quaternion Quaternion::FromAngleAndAxis(float angle, const Matrix<1, 3> &axis) {
|
Quaternion Quaternion::FromAngleAndAxis(float angle, const Matrix<1, 3> &axis) {
|
||||||
const float halfAngle = angle / 2;
|
const float halfAngle = angle / 2;
|
||||||
const float sinHalfAngle = sin(halfAngle);
|
const float sinHalfAngle = sin(halfAngle);
|
||||||
Matrix<1, 3> normalizedAxis{};
|
Matrix<1, 3> normalizedAxis = axis / axis.EuclideanNorm();
|
||||||
normalizedAxis = axis.EuclideanNorm();
|
|
||||||
return Quaternion{static_cast<float>(cos(halfAngle)),
|
return Quaternion{static_cast<float>(cos(halfAngle)),
|
||||||
normalizedAxis.Get(0, 0) * sinHalfAngle,
|
normalizedAxis.Get(0, 0) * sinHalfAngle,
|
||||||
normalizedAxis.Get(0, 1) * sinHalfAngle,
|
normalizedAxis.Get(0, 1) * sinHalfAngle,
|
||||||
|
|||||||
@@ -373,13 +373,15 @@ float matrixSum(const Matrix<rows, columns> &matrix) {
|
|||||||
return std::sqrt(sum);
|
return std::sqrt(sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Add test for scalar division
|
||||||
|
|
||||||
TEST_CASE("Normalization", "Matrix") {
|
TEST_CASE("Normalization", "Matrix") {
|
||||||
|
|
||||||
SECTION("2x2 Normalize") {
|
SECTION("2x2 Normalize") {
|
||||||
Matrix<2, 2> mat1{1, 2, 3, 4};
|
Matrix<2, 2> mat1{1, 2, 3, 4};
|
||||||
Matrix<2, 2> mat2{};
|
Matrix<2, 2> mat2{};
|
||||||
|
|
||||||
mat2 = mat1.EuclideanNorm();
|
mat2 = mat1 / mat1.EuclideanNorm();
|
||||||
|
|
||||||
float sqrt_30{static_cast<float>(sqrt(30.0f))};
|
float sqrt_30{static_cast<float>(sqrt(30.0f))};
|
||||||
|
|
||||||
@@ -394,7 +396,7 @@ TEST_CASE("Normalization", "Matrix") {
|
|||||||
SECTION("2x1 (Vector) Normalize") {
|
SECTION("2x1 (Vector) Normalize") {
|
||||||
Matrix<2, 1> mat1{-0.878877044, 2.92092276};
|
Matrix<2, 1> mat1{-0.878877044, 2.92092276};
|
||||||
Matrix<2, 1> mat2{};
|
Matrix<2, 1> mat2{};
|
||||||
mat2 = mat1.EuclideanNorm();
|
mat2 = mat1 / mat1.EuclideanNorm();
|
||||||
|
|
||||||
REQUIRE_THAT(mat2.Get(0, 0),
|
REQUIRE_THAT(mat2.Get(0, 0),
|
||||||
Catch::Matchers::WithinRel(-0.288129855179f, 1e-6f));
|
Catch::Matchers::WithinRel(-0.288129855179f, 1e-6f));
|
||||||
@@ -408,13 +410,13 @@ TEST_CASE("Normalization", "Matrix") {
|
|||||||
SECTION("Normalized vectors sum to 1") {
|
SECTION("Normalized vectors sum to 1") {
|
||||||
Matrix<9, 1> mat1{1, 2, 3, 4, 5, 6, 7, 8, 9};
|
Matrix<9, 1> mat1{1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
Matrix<9, 1> mat2;
|
Matrix<9, 1> mat2;
|
||||||
mat2 = mat1.EuclideanNorm();
|
mat2 = mat1 / mat1.EuclideanNorm();
|
||||||
float sum = matrixSum(mat2);
|
float sum = matrixSum(mat2);
|
||||||
REQUIRE_THAT(sum, Catch::Matchers::WithinRel(1.0f, 1e-6f));
|
REQUIRE_THAT(sum, Catch::Matchers::WithinRel(1.0f, 1e-6f));
|
||||||
|
|
||||||
Matrix<2, 3> mat3{1, 2, 3, 4, 5, 6};
|
Matrix<2, 3> mat3{1, 2, 3, 4, 5, 6};
|
||||||
Matrix<2, 3> mat4{};
|
Matrix<2, 3> mat4{};
|
||||||
mat4 = mat3.EuclideanNorm();
|
mat4 = mat3 / mat3.EuclideanNorm();
|
||||||
sum = matrixSum(mat4);
|
sum = matrixSum(mat4);
|
||||||
REQUIRE_THAT(sum, Catch::Matchers::WithinRel(1.0f, 1e-6f));
|
REQUIRE_THAT(sum, Catch::Matchers::WithinRel(1.0f, 1e-6f));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ TEST_CASE("Timing Tests", "Matrix") {
|
|||||||
|
|
||||||
SECTION("Normalize") {
|
SECTION("Normalize") {
|
||||||
for (uint32_t i{0}; i < 10000; i++) {
|
for (uint32_t i{0}; i < 10000; i++) {
|
||||||
mat3 = mat1.EuclideanNorm();
|
mat3 = mat1 / mat1.EuclideanNorm();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user