123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #include <Fixture.h>
- #include <FeatureMatrixMinMaxScaler.h>
- namespace EMotionFX::MotionMatching
- {
- class MinMaxScalerFixture
- : public Fixture
- {
- public:
- void SetUp() override
- {
- Fixture::SetUp();
- // Construct 3x3 matrix:
- // 1 2 3
- // 4 5 6
- // 7 8 9
- m_featureMatrix.resize(3, 3);
- float counter = 1.0f;
- for (size_t row = 0; row < 3; ++row)
- {
- for (size_t column = 0; column < 3; ++column)
- {
- m_featureMatrix(row, column) = counter;
- counter++;
- }
- }
- }
- FeatureMatrix m_featureMatrix;
- static constexpr float s_testEpsilon = 0.000001f;
- };
- TEST_F(MinMaxScalerFixture, MinMaxValues)
- {
- FeatureMatrix m;
- m.resize(3, 3);
- m(0,0) = 0.0f; m(0,1) =-1.0f; m(0,2) = 9.0f;
- m(1,0) = 0.5f; m(1,1) = 5.0f; m(1,2) = 6.0f;
- m(2,0) = 7.0f; m(2,1) = 0.1f; m(2,2) = 3.0f;
- MinMaxScaler minMaxScaler;
- EXPECT_TRUE(minMaxScaler.Fit(m));
- const AZStd::vector<float>& min = minMaxScaler.GetMin();
- const AZStd::vector<float>& max = minMaxScaler.GetMax();
- EXPECT_NEAR(min[0], 0.0f, s_testEpsilon); EXPECT_NEAR(max[0], 7.0f, s_testEpsilon);
- EXPECT_NEAR(min[1],-1.0f, s_testEpsilon); EXPECT_NEAR(max[1], 5.0f, s_testEpsilon);
- EXPECT_NEAR(min[2], 3.0f, s_testEpsilon); EXPECT_NEAR(max[2], 9.0f, s_testEpsilon);
- }
- TEST_F(MinMaxScalerFixture, Transform)
- {
- FeatureMatrix m;
- m.resize(3, 4);
- m(0,0) = 0.0f; m(0,1) =-1.0f; m(0,2) = 10.0f; m(0, 3) = 3.0f;
- m(1,0) = 0.5f; m(1,1) = 1.0f; m(1,2) =-10.0f; m(1, 3) = 3.0f;
- m(2,0) = 1.0f; m(2,1) = 0.5f; m(2,2) =-5.0f; m(2, 3) = 3.0f;
- MinMaxScaler minMaxScaler;
- EXPECT_TRUE(minMaxScaler.Fit(m, {/*featureMin=*/0.0f, /*featureMax=*/1.0f, /*clip=*/false }));
- FeatureMatrix t = minMaxScaler.Transform(m);
- EXPECT_NEAR(t(0,0), 0.0f, s_testEpsilon); EXPECT_NEAR(t(0, 1), 0.0f, s_testEpsilon); EXPECT_NEAR(t(0, 2), 1.0f, s_testEpsilon); EXPECT_NEAR(t(0, 3), 3.0f, s_testEpsilon);
- EXPECT_NEAR(t(1,0), 0.5f, s_testEpsilon); EXPECT_NEAR(t(1, 1), 1.0f, s_testEpsilon); EXPECT_NEAR(t(1, 2), 0.0f, s_testEpsilon); EXPECT_NEAR(t(1, 3), 3.0f, s_testEpsilon);
- EXPECT_NEAR(t(2,0), 1.0f, s_testEpsilon); EXPECT_NEAR(t(2, 1), 0.75f, s_testEpsilon);EXPECT_NEAR(t(2, 2), 0.25f, s_testEpsilon);EXPECT_NEAR(t(1, 3), 3.0f, s_testEpsilon);
- }
- TEST_F(MinMaxScalerFixture, TransformValueNoClipping)
- {
- FeatureMatrix m;
- m.resize(2, 1);
- m(0, 0) = -2.0f;
- m(1, 0) = 2.0f; // range = 4.0
- MinMaxScaler minMaxScaler;
- EXPECT_TRUE(minMaxScaler.Fit(m, {/*featureMin=*/0.0f, /*featureMax=*/1.0f, /*clip=*/false }));
- EXPECT_NEAR(minMaxScaler.Transform(-6.0f, 0), -1.0f, s_testEpsilon);
- EXPECT_NEAR(minMaxScaler.Transform(4.0f, 0), 1.5f, s_testEpsilon);
- }
- TEST_F(MinMaxScalerFixture, TransformValueClip)
- {
- FeatureMatrix m;
- m.resize(2, 1);
- m(0, 0) = -2.0f;
- m(1, 0) = 2.0f;
- MinMaxScaler minMaxScaler;
- EXPECT_TRUE(minMaxScaler.Fit(m, {/*featureMin=*/0.0f, /*featureMax=*/1.0f, /*clip=*/true}));
- EXPECT_NEAR(minMaxScaler.Transform(-6.0f, 0), 0.0f, s_testEpsilon);
- EXPECT_NEAR(minMaxScaler.Transform(8.0f, 0), 1.0f, s_testEpsilon);
- }
- TEST_F(MinMaxScalerFixture, FeatureRangeTest)
- {
- FeatureMatrix m;
- m.resize(2, 1);
- m(0, 0) = -2.0f;
- m(1, 0) = 2.0f;
- MinMaxScaler minMaxScaler;
- EXPECT_TRUE(minMaxScaler.Fit(m, {/*featureMin=*/6.0f, /*featureMax=*/10.0f, /*clip=*/true}));
- EXPECT_NEAR(minMaxScaler.Transform(-2.0f, 0), 6.0f, s_testEpsilon);
- EXPECT_NEAR(minMaxScaler.Transform(0.0f, 0), 8.0f, s_testEpsilon);
- EXPECT_NEAR(minMaxScaler.Transform(2.0f, 0), 10.0f, s_testEpsilon);
- //--
- m(0, 0) = 10.0f;
- m(1, 0) = 20.0f;
- FeatureMatrixTransformer::Settings fitSettings;
- fitSettings.m_featureMin = -5.0f;
- fitSettings.m_featureMax = 5.0f;
- EXPECT_TRUE(minMaxScaler.Fit(m, fitSettings));
- EXPECT_NEAR(minMaxScaler.Transform(10.0f, 0), -5.0f, s_testEpsilon);
- EXPECT_NEAR(minMaxScaler.Transform(15.0f, 0), 0.0f, s_testEpsilon);
- EXPECT_NEAR(minMaxScaler.Transform(20.0f, 0), 5.0f, s_testEpsilon);
- }
- TEST_F(MinMaxScalerFixture, SameValues)
- {
- FeatureMatrix m;
- m.resize(3, 1);
- m(0, 0) = 2.0f;
- m(1, 0) = 2.0f;
- m(2, 0) = 2.0f;
- MinMaxScaler minMaxScaler;
- EXPECT_TRUE(minMaxScaler.Fit(m));
- EXPECT_NEAR(minMaxScaler.GetMin()[0], 2.0f, s_testEpsilon);
- EXPECT_NEAR(minMaxScaler.GetMax()[0], 2.0f, s_testEpsilon);
- EXPECT_NEAR(minMaxScaler.Transform(2.0f, 0), 2.0f, s_testEpsilon);
- EXPECT_NEAR(minMaxScaler.InverseTransform(2.0f, 0), 2.0f, s_testEpsilon);
- // Test out of data range.
- // In case the feature was constant, it is expected to not transform the value.
- EXPECT_NEAR(minMaxScaler.Transform(0.0f, 0), 0.0f, s_testEpsilon);
- EXPECT_NEAR(minMaxScaler.Transform(10.0f, 0), 10.0f, s_testEpsilon);
- // Test out of feature range.
- // As the feature is constant, no matter what the input is, the constant feature should be returned.
- EXPECT_NEAR(minMaxScaler.InverseTransform(0.0f, 0), 2.0f, s_testEpsilon);
- EXPECT_NEAR(minMaxScaler.InverseTransform(10.0f, 0), 2.0f, s_testEpsilon);
- }
- TEST_F(MinMaxScalerFixture, CloseEpsilonValues)
- {
- FeatureMatrix m;
- m.resize(3, 1);
- m(0, 0) = 2.0f + MinMaxScaler::s_epsilon;
- m(1, 0) = 2.0f - MinMaxScaler::s_epsilon;
- m(2, 0) = 2.0f;
- MinMaxScaler minMaxScaler;
- EXPECT_TRUE(minMaxScaler.Fit(m));
- EXPECT_NEAR(minMaxScaler.GetMin()[0], 2.0f - MinMaxScaler::s_epsilon, s_testEpsilon);
- EXPECT_NEAR(minMaxScaler.GetMax()[0], 2.0f + MinMaxScaler::s_epsilon, s_testEpsilon);
- EXPECT_NEAR(minMaxScaler.Transform(2.0f, 0), 2.0f, s_testEpsilon);
- EXPECT_NEAR(minMaxScaler.InverseTransform(2.0f, 0), 2.0f, s_testEpsilon);
- EXPECT_NEAR(minMaxScaler.Transform(2.0f + MinMaxScaler::s_epsilon, 0), 2.0f + MinMaxScaler::s_epsilon, s_testEpsilon);
- EXPECT_NEAR(minMaxScaler.InverseTransform(2.0f + MinMaxScaler::s_epsilon, 0), 2.0f + MinMaxScaler::s_epsilon, s_testEpsilon);
- // Test out of data range.
- // In case the feature was constant, it is expected to not transform the value.
- EXPECT_NEAR(minMaxScaler.Transform(0.0f, 0), 0.0f, s_testEpsilon);
- EXPECT_NEAR(minMaxScaler.Transform(10.0f, 0), 10.0f, s_testEpsilon);
- // Test out of feature range.
- // As the feature is constant, no matter what the input is, the constant feature should be returned.
- EXPECT_FLOAT_EQ(minMaxScaler.InverseTransform(0.0f, 0), 2.0f - MinMaxScaler::s_epsilon);
- EXPECT_FLOAT_EQ(minMaxScaler.InverseTransform(10.0f, 0), 2.0f + MinMaxScaler::s_epsilon);
- }
- TEST_F(MinMaxScalerFixture, SimpleRoundTrip)
- {
- FeatureMatrix m;
- m.resize(2, 1);
- m(0, 0) = -2.0f;
- m(1, 0) = 2.0f; // range = 4.0
- MinMaxScaler minMaxScaler;
- FeatureMatrixTransformer::Settings fitSettings;
- fitSettings.m_featureMin = -10.0f;
- fitSettings.m_featureMax = 10.0f;
- EXPECT_TRUE(minMaxScaler.Fit(m, fitSettings));
- const float tVal = minMaxScaler.Transform(0.0f, 0);
- EXPECT_NEAR(tVal, 0.0f, s_testEpsilon);
- const float orgVal = minMaxScaler.InverseTransform(tVal, 0);
- EXPECT_NEAR(orgVal, 0.0f, s_testEpsilon);
- }
- TEST_F(MinMaxScalerFixture, RoundTripFeatureRange)
- {
- FeatureMatrix m;
- m.resize(3, 4);
- m(0, 0) = 0.0f; m(0, 1) = -1.0f; m(0, 2) = 10.0f; m(0, 3) = 3.0f;
- m(1, 0) = 0.5f; m(1, 1) = 1.0f; m(1, 2) = -10.0f; m(1, 3) = 3.0f + MinMaxScaler::s_epsilon;
- m(2, 0) = 1.0f; m(2, 1) = 0.5f; m(2, 2) = -5.0f; m(2, 3) = 3.0f;
- MinMaxScaler minMaxScaler;
- FeatureMatrixTransformer::Settings fitSettings;
- fitSettings.m_featureMin = -36.0f;
- fitSettings.m_featureMax = 250.0f;
- EXPECT_TRUE(minMaxScaler.Fit(m, fitSettings));
- const FeatureMatrix t = minMaxScaler.Transform(m);
- const FeatureMatrix inv = minMaxScaler.InverseTransform(t);
- const FeatureMatrix::Index numRows = m.rows();
- const FeatureMatrix::Index numColumns = m.cols();
- for (FeatureMatrix::Index row = 0; row < numRows; ++row)
- {
- for (FeatureMatrix::Index column = 0; column < numColumns; ++column)
- {
- EXPECT_NEAR(inv(row, column), m(row, column), s_testEpsilon);
- }
- }
- }
- } // EMotionFX::MotionMatching
|