<!-- (c) Electronic Arts. All Rights Reserved. -->
<TESTCLASS>

    <CLASS NAME="UnitTestSoa4Trig" HEADER="soa4_trigtest.h" SOURCE="soa4_trigtest.inc" RWGENERICHEADER="" RWHOSTHEADER="" GENERIC="false" HOST="false" RWCOMMONHEADER="rw/math/vpu/soa4_trig.h rw/math/fpu/constants.h" COMMON="true">


  <TYPE NAME="function">

    <TYPE NAME="correctness">

      <TEST NAME="degtorad">
      <![CDATA[

        SetFunctionName("DegToRad");
        Validate( IsEqualWithEpsilon(DegToRad(Soa4FloatFromFloat(180.0f)), Soa4FloatFromFloat(::rw::math::fpu::PI)) );
        Validate( IsEqualWithEpsilon(DegToRad(Soa4FloatFromFloat(360.0f)), Soa4FloatFromFloat(::rw::math::fpu::TWO_PI)) );
        Validate( IsEqualWithEpsilon(DegToRad(Soa4FloatFromFloat(0.0f)), Soa4FloatFromFloat(0.0f)) );

      ]]>
      </TEST>

      <TEST NAME="radtodeg">
      <![CDATA[

        SetFunctionName("RadToDeg");
        Validate(IsEqualWithEpsilon(RadToDeg(Soa4FloatFromFloat(0.0f)), Soa4FloatFromFloat(0.f), Soa4FloatFromFloat(::rw::math::fpu::SMALL_FLOAT)));
        
#if defined EA_PLATFORM_PS3_SPU        
        
        Validate(IsEqualWithinPercent(RadToDeg(Soa4FloatFromFloat(::rw::math::fpu::PI)), Soa4FloatFromFloat(180.f), Soa4FloatFromFloat(0.0001)));
        Validate(IsEqualWithinPercent(RadToDeg(Soa4FloatFromFloat(::rw::math::fpu::TWO_PI)), Soa4FloatFromFloat(360.f), Soa4FloatFromFloat(0.0001)));
#else
        Validate(IsEqualWithEpsilon(RadToDeg(Soa4FloatFromFloat(::rw::math::fpu::PI)), Soa4FloatFromFloat(180.f), Soa4FloatFromFloat(::rw::math::fpu::SMALL_FLOAT)));
        Validate(IsEqualWithEpsilon(RadToDeg(Soa4FloatFromFloat(::rw::math::fpu::TWO_PI)), Soa4FloatFromFloat(360.f), Soa4FloatFromFloat(::rw::math::fpu::SMALL_FLOAT)));
#endif        

      ]]>
      </TEST>

      <TEST NAME="sin">
      <![CDATA[

        SetFunctionName("Sin test");
        bool success = true;
        for (int i = 0; i < NUM_SINCOS_VALUES; ++i)
        {
            success &= IsEqualWithEpsilon(Sin(Soa4FloatFromFloat(sincos_values[i].input)),
                Soa4FloatFromFloat(sincos_values[i].output1), Soa4FloatFromFloat(FSIN_EPSILON));
        }
        Validate(success);

      ]]>
      </TEST>

      <TEST NAME="cos">
      <![CDATA[

        SetFunctionName("Cos test");
        bool success = true;
        for (int i = 0; i < NUM_SINCOS_VALUES; ++i)
        {
            success &= IsEqualWithEpsilon(Cos(Soa4FloatFromFloat(sincos_values[i].input)),
                Soa4FloatFromFloat(sincos_values[i].output2), Soa4FloatFromFloat(FCOS_EPSILON));
        }
        Validate(success);

      ]]>
      </TEST>

      <TEST NAME="tan">
      <![CDATA[

        SetFunctionName("Tan test");
        bool success = true;
        for (int i = 0; i < NUM_TAN_VALUES; ++i)
        {
            success &= IsEqualWithEpsilon(Tan(Soa4FloatFromFloat(tan_values[i].input)),
                Soa4FloatFromFloat(tan_values[i].output), Soa4FloatFromFloat(FTAN_EPSILON));
        }
        Validate(success);

      ]]>
      </TEST>

      <TEST NAME="asin">
      <![CDATA[

        SetFunctionName("ASin test");
        bool success = true;
        for (int i = 0; i < NUM_ASINCOS_VALUES; ++i)
        {
            success &= IsEqualWithEpsilon(ASin(Soa4FloatFromFloat(asincos_values[i].input)),
                Soa4FloatFromFloat(asincos_values[i].output1), Soa4FloatFromFloat(FASIN_EPSILON));
        }
        Validate(success);

      ]]>
      </TEST>

      <TEST NAME="acos">
      <![CDATA[

        SetFunctionName("ACos test");
        bool success = true;
        for (int i = 0; i < NUM_ASINCOS_VALUES; ++i)
        {
            success &= IsEqualWithEpsilon(ACos(Soa4FloatFromFloat(asincos_values[i].input)),
                Soa4FloatFromFloat(asincos_values[i].output2), Soa4FloatFromFloat(FACOS_EPSILON));
        }
        Validate(success);

      ]]>
      </TEST>

      <TEST NAME="atan">
      <![CDATA[

        SetFunctionName("ATan test");
        bool success = true;
        for (int i = 0; i < NUM_ATAN_VALUES; ++i)
        {
            success &= IsEqualWithEpsilon(ATan(Soa4FloatFromFloat(atan_values[i].input)),
                Soa4FloatFromFloat(atan_values[i].output), Soa4FloatFromFloat(FATAN_EPSILON));
        }
        Validate(success);

      ]]>
      </TEST>

      <TEST NAME="atan2">
      <![CDATA[

        SetFunctionName("ATan2 test");
        bool success = true;
        for (int i = 0; i < NUM_ATAN2_VALUES; ++i)
        {
            Soa4Float atan2Result = ATan2(Soa4FloatFromFloat(atan2_values[i].x), Soa4FloatFromFloat(atan2_values[i].y));
            bool result = IsEqualWithEpsilon(atan2Result, Soa4FloatFromFloat(atan2_values[i].output), Soa4FloatFromFloat(FATAN_EPSILON));
            // Special case:  PI and -PI should be considered equally valid.
            if( atan2_values[i].output == -3.141593f && !result )
            {
                result = IsEqualWithEpsilon(atan2Result, Soa4FloatFromFloat(3.141593f), Soa4FloatFromFloat(FATAN_EPSILON));
            }
            success &= result;
        }
        Validate(success);

      ]]>
      </TEST>

      <TEST NAME="normalizeangle">
      <![CDATA[

        SetFunctionName("NormalizeAngle");
        bool success = true;
        success &= IsEqualWithEpsilon(NormalizeAngle(Soa4FloatFromFloat(::rw::math::fpu::TWO_PI + 1.1f)), Soa4FloatFromFloat(1.1f));
	    success &= IsEqualWithEpsilon(NormalizeAngle( Soa4FloatFromFloat(::rw::math::fpu::QUARTER_PI)),  Soa4FloatFromFloat(::rw::math::fpu::QUARTER_PI));
	    success &= IsEqualWithEpsilon(NormalizeAngle(Soa4FloatFromFloat(-::rw::math::fpu::QUARTER_PI)), Soa4FloatFromFloat(-::rw::math::fpu::QUARTER_PI));
	    success &= IsEqualWithEpsilon(NormalizeAngle(Soa4FloatFromFloat(::rw::math::fpu::PI + 0.1f)), Soa4FloatFromFloat(-::rw::math::fpu::PI + 0.1f));
	    success &= IsEqualWithEpsilon(NormalizeAngle(Soa4FloatFromFloat(-::rw::math::fpu::PI + 0.1f)), Soa4FloatFromFloat(-::rw::math::fpu::PI + 0.1f));
	    success &= IsEqualWithEpsilon(NormalizeAngle(Soa4FloatFromFloat(0.f)), Soa4FloatFromFloat(0.f));
	    success &= IsEqualWithEpsilon(NormalizeAngle(Soa4FloatFromFloat(::rw::math::fpu::TWO_PI)), Soa4FloatFromFloat(0.f));
	    success &= IsEqualWithEpsilon(NormalizeAngle(Soa4FloatFromFloat(-::rw::math::fpu::PI - 0.1f)), Soa4FloatFromFloat(::rw::math::fpu::PI - 0.1f));
        Validate(success);

      ]]>
      </TEST>

      <TEST NAME="sincos">
      <![CDATA[

        Soa4Float fSin, fCos;

        bool success = true;
        for (int i = 0; i < NUM_SINCOS_VALUES; ++i)
        {
            SetFunctionName("SinCos(a, sin_out, cos_out)");
            SinCos(Soa4FloatFromFloat(sincos_values[i].input), fSin, fCos);

            success &= IsEqualWithEpsilon( fSin, Soa4FloatFromFloat(sincos_values[i].output1), Soa4FloatFromFloat(FSINCOS_EPSILON) );
            success &= IsEqualWithEpsilon( fCos, Soa4FloatFromFloat(sincos_values[i].output2), Soa4FloatFromFloat(FSINCOS_EPSILON) );
        }
        Validate(success);

      ]]>
      </TEST>

    </TYPE>

    <TYPE NAME="performance">

      <TEST NAME="sin_performance">
      <![CDATA[
        SetFunctionName("Sin");

        StartTimer(testing::RW_MATH_UNITTEST_TEST_VECTOR_ARRAY_SIZE * testing::RW_MATH_UNITTEST_TEST_LOOP_COUNT_LONG);

        for (int testloop = 0; testloop < testing::RW_MATH_UNITTEST_TEST_LOOP_COUNT_LONG; testloop++)
        {
            for (int i = 0; i < testing::RW_MATH_UNITTEST_TEST_VECTOR_ARRAY_SIZE; i++)
            {
                fOutArray[i] = Sin(xArray[i]);
            }
        }

        StopTimer();
      ]]>
      </TEST>

      <TEST NAME="cos_performance">
      <![CDATA[
        SetFunctionName("Cos");

        StartTimer(testing::RW_MATH_UNITTEST_TEST_VECTOR_ARRAY_SIZE * testing::RW_MATH_UNITTEST_TEST_LOOP_COUNT_LONG);

        for (int testloop = 0; testloop < testing::RW_MATH_UNITTEST_TEST_LOOP_COUNT_LONG; testloop++)
        {
            for (int i = 0; i < testing::RW_MATH_UNITTEST_TEST_VECTOR_ARRAY_SIZE; i++)
            {
                fOutArray[i] = Cos(xArray[i]);
            }
        }

        StopTimer();
      ]]>
      </TEST>

    </TYPE>

  </TYPE>


</CLASS>

</TESTCLASS>
