[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/xtensor-stack/xtensor/master/test/test_xcomplex.cpp [Back]  [Original]

/***************************************************************************
 * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht          *
 * Copyright (c) QuantStack                                                 *
 *                                                                          *
 * Distributed under the terms of the BSD 3-Clause License.                 *
 *                                                                          *
 * The full license is in the file LICENSE, distributed with this software. *
 ****************************************************************************/

#include 

#include 

#include "xtensor/containers/xarray.hpp"
#include "xtensor/generators/xbuilder.hpp"
#include "xtensor/io/xio.hpp"
#include "xtensor/misc/xcomplex.hpp"
#include "xtensor/reducers/xnorm.hpp"
#include "xtensor/views/xview.hpp"

#include "test_common_macros.hpp"

namespace xt
{
    using namespace std::complex_literals;

    TEST(xcomplex, expression)
    {
        xarray e = {{1.0, 1.0 + 1.0i}, {1.0 - 1.0i, 1.0}};

        // Test real expression
        auto r = real(e);
        auto i = imag(e);

        ASSERT_EQ(r.dimension(), size_t(2));
        ASSERT_EQ(i.dimension(), size_t(2));

        ASSERT_EQ(r.shape()[0], size_t(2));
        ASSERT_EQ(r.shape()[1], size_t(2));
        ASSERT_EQ(i.shape()[0], size_t(2));
        ASSERT_EQ(i.shape()[1], size_t(2));

        ASSERT_EQ(i(0, 0), 0);
        ASSERT_EQ(i(0, 1), 1);
        ASSERT_EQ(i(1, 0), -1);
        ASSERT_EQ(i(1, 1), 0);

        // Test assignment to an array
        xarray ar = r;
        EXPECT_TRUE(all(equal(ar, ones({2, 2}))));
    }

    TEST(xcomplex, lvalue)
    {
        xarray e = {{1.0, 1.0 + 1.0i}, {1.0 - 1.0i, 1.0}};

        // Test assigning an expression to the complex view
        real(e) = zeros({2, 2});
        xarray expect1 = {{0.0, 0.0 + 1.0i}, {0.0 - 1.0i, 0.0}};
        EXPECT_TRUE(all(equal(e, expect1)));

        imag(e) = zeros({2, 2});
        EXPECT_TRUE(all(equal(e, zeros({2, 2}))));
    }

    TEST(xcomplex, scalar_assignmnent)
    {
        xarray e = {{1.0, 1.0 + 1.0i}, {1.0 - 1.0i, 1.0}};

        // Test assigning an expression to the complex view
        real(e) = 0.0;
        xarray expect1 = {{0.0, 0.0 + 1.0i}, {0.0 - 1.0i, 0.0}};
        EXPECT_TRUE(all(equal(e, expect1)));
    }

    TEST(xcomplex, noncomplex)
    {
        xarray e = ones({2, 2});
        auto r = real(e);
        auto i = imag(e);
        EXPECT_TRUE(all(equal(r, e)));
        EXPECT_TRUE(all(equal(i, zeros({2, 2}))));
    }

    TEST(xcomplex, scalar)
    {
        double d = 1.0;
        ASSERT_EQ(1.0, real(d));
        ASSERT_EQ(0.0, imag(d));
        real(d) = 2.0;
        ASSERT_EQ(2.0, d);
    }

    TEST(xcomplex, pointer)
    {
        xarray e = {{1.0, 1.0 + 1.0i}, {1.0 - 1.0i, 1.0}};
        auto r = real(e);
        auto it = r.begin();
        EXPECT_EQ(*(it.operator->()), 1.0);
    }

    TEST(xcomplex, arg)
    {
        xarray cmplarg_0 = {
            {0.40101756 + 0.71233018i, 0.62731701 + 0.42786349i, 0.32415089 + 0.2977805i},
            {0.24475928 + 0.49208478i, 0.69475518 + 0.74029639i, 0.59390240 + 0.35772892i},
            {0.63179202 + 0.41720995i, 0.44025718 + 0.65472131i, 0.08372648 + 0.37380143i}
        };
        xarray res = xt::arg(cmplarg_0);
    }

    TEST(xcomplex, abs_angle_conj)
    {
        xarray cmplarg_0 = {
            {0.40101756 + 0.71233018i, 0.62731701 + 0.42786349i, 0.32415089 + 0.2977805i},
            {0.24475928 + 0.49208478i, 0.69475518 + 0.74029639i, 0.59390240 + 0.35772892i},
            {0.63179202 + 0.41720995i, 0.44025718 + 0.65472131i, 0.08372648 + 0.37380143i}
        };
        auto cmplres = xt::abs(cmplarg_0);
        xarray cmplexpected = {
            {0.81745298, 0.75933774, 0.44016704},
            {0.54959488, 1.01524554, 0.69331814},
            {0.75711643, 0.78897806, 0.38306348}
        };

        EXPECT_TRUE(allclose(cmplexpected, cmplres));

        auto cmplres_angle = xt::angle(cmplarg_0);
        xarray cmplexpected_angle = {
            {1.05805307, 0.59857922, 0.74302273},
            {1.10923689, 0.81712241, 0.54213553},
            {0.58362348, 0.97881125, 1.35044673}
        };
        EXPECT_TRUE(allclose(cmplexpected_angle, cmplres_angle));

        using assign_t_angle = xassign_traits;

#if XTENSOR_USE_XSIMD
        EXPECT_TRUE(assign_t_angle::simd_linear_assign());
#endif

        auto cmplres_conj = xt::conj(cmplarg_0);
        xarray cmplexpected_conj = {
            {0.40101756 - 0.71233018i, 0.62731701 - 0.42786349i, 0.32415089 - 0.2977805i},
            {0.24475928 - 0.49208478i, 0.69475518 - 0.74029639i, 0.59390240 - 0.35772892i},
            {0.63179202 - 0.41720995i, 0.44025718 - 0.65472131i, 0.08372648 - 0.37380143i}
        };
        EXPECT_TRUE(allclose(cmplexpected_conj, cmplres_conj));

        using assign_t_conj = xassign_traits;

#if XTENSOR_USE_XSIMD
        auto b1 = cmplres_angle.template load_simd(0);
        auto b2 = cmplres_conj.template load_simd(0);
        static_cast(b1);
        static_cast(b2);
        EXPECT_TRUE(assign_t_conj::simd_linear_assign());
#endif

        auto cmplres_norm = xt::norm(cmplarg_0);
        xarray fieldnorm = {
            {0.66822937, 0.5765938, 0.19374703},
            {0.30205453, 1.0307235, 0.48069004},
            {0.57322529, 0.62248637, 0.14673763}
        };

        using assign_t_norm = xassign_traits;

#if XTENSOR_USE_XSIMD
        EXPECT_TRUE(assign_t_norm::simd_linear_assign());
#endif

        EXPECT_TRUE(allclose(fieldnorm, cmplres_norm));
    }

    TEST(xcomplex, arg)
    {
        xarray cmplarg_0 = {
            {0.40101756 + 0.71233018i, 0.62731701 + 0.42786349i, 0.32415089 + 0.2977805i},
            {0.24475928 + 0.49208478i, 0.69475518 + 0.74029639i, 0.59390240 + 0.35772892i},
            {0.63179202 + 0.41720995i, 0.44025718 + 0.65472131i, 0.08372648 + 0.37380143i}
        };
        auto cmplres = xt::arg(cmplarg_0);

        auto evc = xt::eval(cmplres);
        auto it = cmplarg_0.begin();

        for (auto el : evc)
        {
            auto exp = std::arg(*it);
            EXPECT_DOUBLE_EQ(el, exp);
            ++it;
        }

        using assign_t_arg = xassign_traits;

#if XTENSOR_USE_XSIMD
        EXPECT_TRUE(assign_t_arg::simd_linear_assign());
#endif
    }

    TEST(xcomplex, conj_real)
    {
        xarray A = {
            {0.81745298, 0.75933774, 0.44016704},
            {0.54959488, 1.01524554, 0.69331814},
            {0.75711643, 0.78897806, 0.38306348}
        };
        xarray B = xt::real(xt::conj(A));
        EXPECT_EQ(A, B);
    }

    TEST(xcomplex, isnan)
    {
        using c_t = std::complex;
        double nan = std::numeric_limits::quiet_NaN();

        xarray e = {c_t(0, 1), c_t(0, nan), c_t(-nan, 2), c_t(nan, -nan)};
        xarray expected = {false, true, true, true};
        // Full qualification required by Windows
        EXPECT_TRUE(all(equal(expected, xt::isnan(e))));
    }

    TEST(xcomplex, isinf)
    {
        using c_t = std::complex;
        double inf = std::numeric_limits::infinity();

        xarray e = {c_t(0, 1), c_t(0, inf), c_t(-inf, 2), c_t(inf, -inf), c_t(0, -inf)};
        xarray expected = {false, true, true, true, true};

        EXPECT_TRUE(all(equal(expected, xt::isinf(e))));
    }

    TEST(xcomplex, isclose)
    {
        xarray arg = {
            {0.40101756 + 0.71233018i, 0.62731701 + 0.42786349i, 0.32415089 + 0.2977805i},
            {0.24475928 + 0.49208478i, 0.69475518 + 0.74029639i, 0.59390240 + 0.35772892i},
            {0.63179202 + 0.41720995i, 0.44025718 + 0.65472131i, 0.08372648 + 0.37380143i}
        };

        xarray compare = {
            {0.401 + 0.712i, 0.627 + 0.427i, 0.324 + 0.297i},
            {0.244 + 0.492i, 0.694 + 0.740i, 0.593 + 0.357i},
            {0.631 + 0.417i, 0.440 + 0.654i, 0.083 + 0.373i}
        };

        auto veryclose = isclose(arg, compare, 1e-5);
        auto looselyclose = isclose(arg, compare, 1e-1);

        EXPECT_TRUE(all(equal(false, veryclose)));
        EXPECT_TRUE(all(equal(true, looselyclose)));

        double inf = std::numeric_limits::infinity();
        double nan = std::numeric_limits::quiet_NaN();
        using c_t = std::complex;

        EXPECT_TRUE(isclose(c_t(0, nan), c_t(0, nan))() == false);
        EXPECT_TRUE(isclose(c_t(0, nan), c_t(0, nan), 1e-5, 1e-3, true)() == true);
        EXPECT_TRUE(isclose(c_t(0, inf), c_t(0, inf))() == true);
        EXPECT_TRUE(isclose(c_t(0, -inf), c_t(0, inf))() == false);

        EXPECT_TRUE(isclose(c_t(inf, -inf), c_t(0, inf))() == false);
        EXPECT_TRUE(isclose(c_t(5, 5), c_t(5, -5))() == false);
    }

    TEST(xcomplex, real_expression)
    {
        using cpx = std::complex;
        xtensor a = {{cpx(1, 1), cpx(-1, 1), cpx(-2, -2)}, {cpx(-1, 0), cpx(0, 1), cpx(2, 2)}};

        xtensor exp = {{2, -2, -4}, {-2, 0, 4}};
        xtensor res = real(a + a);
        EXPECT_EQ(res, exp);
    }

    TEST(xcomplex, conj)
    {
        using cpx = std::complex;
        xtensor a = {{cpx(1, 1), cpx(-1, 1), cpx(-2, -2)}, {cpx(-1, 0), cpx(0, 1), cpx(2, 2)}};
        xtensor res = conj(a);
        xtensor exp = {{cpx(1, -1), cpx(-1, -1), cpx(-2, 2)}, {cpx(-1, 0), cpx(0, -1), cpx(2, -2)}};

        EXPECT_EQ(res, exp);
    }

    TEST(xcomplex, exp)
    {
        xt::xarray ph =
            {274.7323f, 276.3974f, 274.7323f, 276.3974f, 274.7323f, 276.3974f, 274.7323f, 276.3974f};
        xt::xarray input = ph * std::complex(0, 1.f);
        xt::xarray res = xt::exp(input);
        auto expected = xt::xarray::from_shape({size_t(8)});
        std::transform(
            input.cbegin(),
            input.cend(),
            expected.begin(),
            [](const std::complex& arg)
            {
                return std::exp(arg);
            }
        );
        EXPECT_EQ(expected, res);
    }

    TEST(xcomplex, longdouble)
    {
        using cmplx = std::complex;
        xt::xtensor a = xt::empty({5, 5});
        xt::real(a) = 123.321L;
        xt::imag(a) = -123.321L;

        EXPECT_EQ(a(4, 4), cmplx(123.321L, -123.321L));

        xt::real(a) = xt::imag(a);

        EXPECT_EQ(a(0, 0), cmplx(-123.321L, -123.321L));
        EXPECT_EQ(a(4, 4), cmplx(-123.321L, -123.321L));
    }

    TEST(xcomplex, build_from_double)
    {
        xt::xarray r = {1., 2., 3.};
        xt::xarray rc(r);
        EXPECT_EQ(rc(0).real(), r(0));
        EXPECT_EQ(rc(1).real(), r(1));
        EXPECT_EQ(rc(2).real(), r(2));
    }

    TEST(xcomplex, xcomplex)
    {
        using complex_type = xtl::xcomplex;
        xt::xarray a = xt::ones(std::vector(3, 7));

        auto simd_loaded = a.template load_simd(
            0
        );
        (void) simd_loaded;
    }

    TEST(xcomplex, view)
    {
        using cpx = std::complex;
        xt::xtensor a = {{cpx(1, 1), cpx(-1, 1), cpx(-2, -2)}, {cpx(-1, 0), cpx(0, 1), cpx(2, 2)}};

        xtensor c = conj(view(a, 0, xt::all()));
        xtensor exp_conj = {cpx(1, -1), cpx(-1, -1), cpx(-2, 2)};
        EXPECT_EQ(c, exp_conj);

        xtensor r = real(view(a, 0, xt::all()));
        xtensor exp_real = {double(1), double(-1), double(-2)};
        EXPECT_EQ(r, exp_real);

        xtensor im = imag(view(a, 0, xt::all()));
        xtensor exp_im = {double(1), double(1), double(-2)};
        EXPECT_EQ(im, exp_im);
    }
}

Web Proxy Viewer  |  New URL  |  Original Page