// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "main.h"

#include <Eigen/CXX11/Tensor>

using Eigen::Tensor;
using Eigen::RowMajor;


static void test_0d()
{
  TensorFixedSize<float, Sizes<> > scalar1;
  TensorFixedSize<float, Sizes<>, RowMajor> scalar2;
  VERIFY_IS_EQUAL(scalar1.rank(), 0);
  VERIFY_IS_EQUAL(scalar1.size(), 1);
  VERIFY_IS_EQUAL(internal::array_prod(scalar1.dimensions()), 1);

  scalar1() = 7.0;
  scalar2() = 13.0;

  // Test against shallow copy.
  TensorFixedSize<float, Sizes<> > copy = scalar1;
  VERIFY_IS_NOT_EQUAL(scalar1.data(), copy.data());
  VERIFY_IS_APPROX(scalar1(), copy());
  copy = scalar1;
  VERIFY_IS_NOT_EQUAL(scalar1.data(), copy.data());
  VERIFY_IS_APPROX(scalar1(), copy());

  TensorFixedSize<float, Sizes<> > scalar3 = scalar1.sqrt();
  TensorFixedSize<float, Sizes<>, RowMajor> scalar4 = scalar2.sqrt();
  VERIFY_IS_EQUAL(scalar3.rank(), 0);
  VERIFY_IS_APPROX(scalar3(), sqrtf(7.0));
  VERIFY_IS_APPROX(scalar4(), sqrtf(13.0));

  scalar3 = scalar1 + scalar2;
  VERIFY_IS_APPROX(scalar3(), 7.0f + 13.0f);
}

static void test_1d()
{
  TensorFixedSize<float, Sizes<6> > vec1;
  TensorFixedSize<float, Sizes<6>, RowMajor> vec2;

  VERIFY_IS_EQUAL((vec1.size()), 6);
  //  VERIFY_IS_EQUAL((vec1.dimensions()[0]), 6);
  //  VERIFY_IS_EQUAL((vec1.dimension(0)), 6);

  vec1(0) = 4.0;  vec2(0) = 0.0;
  vec1(1) = 8.0;  vec2(1) = 1.0;
  vec1(2) = 15.0; vec2(2) = 2.0;
  vec1(3) = 16.0; vec2(3) = 3.0;
  vec1(4) = 23.0; vec2(4) = 4.0;
  vec1(5) = 42.0; vec2(5) = 5.0;

  // Test against shallow copy.
  TensorFixedSize<float, Sizes<6> > copy = vec1;
  VERIFY_IS_NOT_EQUAL(vec1.data(), copy.data());
  for (int i = 0; i < 6; ++i) {
    VERIFY_IS_APPROX(vec1(i), copy(i));
  }
  copy = vec1;
  VERIFY_IS_NOT_EQUAL(vec1.data(), copy.data());
  for (int i = 0; i < 6; ++i) {
    VERIFY_IS_APPROX(vec1(i), copy(i));
  }

  TensorFixedSize<float, Sizes<6> > vec3 = vec1.sqrt();
  TensorFixedSize<float, Sizes<6>, RowMajor> vec4 = vec2.sqrt();

  VERIFY_IS_EQUAL((vec3.size()), 6);
  VERIFY_IS_EQUAL(vec3.rank(), 1);
  //  VERIFY_IS_EQUAL((vec3.dimensions()[0]), 6);
  //  VERIFY_IS_EQUAL((vec3.dimension(0)), 6);

  VERIFY_IS_APPROX(vec3(0), sqrtf(4.0));
  VERIFY_IS_APPROX(vec3(1), sqrtf(8.0));
  VERIFY_IS_APPROX(vec3(2), sqrtf(15.0));
  VERIFY_IS_APPROX(vec3(3), sqrtf(16.0));
  VERIFY_IS_APPROX(vec3(4), sqrtf(23.0));
  VERIFY_IS_APPROX(vec3(5), sqrtf(42.0));

  VERIFY_IS_APPROX(vec4(0), sqrtf(0.0));
  VERIFY_IS_APPROX(vec4(1), sqrtf(1.0));
  VERIFY_IS_APPROX(vec4(2), sqrtf(2.0));
  VERIFY_IS_APPROX(vec4(3), sqrtf(3.0));
  VERIFY_IS_APPROX(vec4(4), sqrtf(4.0));
  VERIFY_IS_APPROX(vec4(5), sqrtf(5.0));

  vec3 = vec1 + vec2;
  VERIFY_IS_APPROX(vec3(0), 4.0f + 0.0f);
  VERIFY_IS_APPROX(vec3(1), 8.0f + 1.0f);
  VERIFY_IS_APPROX(vec3(2), 15.0f + 2.0f);
  VERIFY_IS_APPROX(vec3(3), 16.0f + 3.0f);
  VERIFY_IS_APPROX(vec3(4), 23.0f + 4.0f);
  VERIFY_IS_APPROX(vec3(5), 42.0f + 5.0f);
}

static void test_tensor_map()
{
  TensorFixedSize<float, Sizes<6> > vec1;
  TensorFixedSize<float, Sizes<6>, RowMajor> vec2;

  vec1(0) = 4.0;  vec2(0) = 0.0;
  vec1(1) = 8.0;  vec2(1) = 1.0;
  vec1(2) = 15.0; vec2(2) = 2.0;
  vec1(3) = 16.0; vec2(3) = 3.0;
  vec1(4) = 23.0; vec2(4) = 4.0;
  vec1(5) = 42.0; vec2(5) = 5.0;

  float data3[6];
  TensorMap<TensorFixedSize<float, Sizes<6> > > vec3(data3, 6);
  vec3 = vec1.sqrt() + vec2;

  VERIFY_IS_APPROX(vec3(0), sqrtf(4.0));
  VERIFY_IS_APPROX(vec3(1), sqrtf(8.0) + 1.0f);
  VERIFY_IS_APPROX(vec3(2), sqrtf(15.0) + 2.0f);
  VERIFY_IS_APPROX(vec3(3), sqrtf(16.0) + 3.0f);
  VERIFY_IS_APPROX(vec3(4), sqrtf(23.0) + 4.0f);
  VERIFY_IS_APPROX(vec3(5), sqrtf(42.0) + 5.0f);
}

static void test_2d()
{
  float data1[6];
  TensorMap<TensorFixedSize<float, Sizes<2, 3> > > mat1(data1,2,3);
  float data2[6];
  TensorMap<TensorFixedSize<float, Sizes<2, 3>, RowMajor> > mat2(data2,2,3);

  VERIFY_IS_EQUAL((mat1.size()), 2*3);
  VERIFY_IS_EQUAL(mat1.rank(), 2);
  //  VERIFY_IS_EQUAL((mat1.dimension(0)), 2);
  //  VERIFY_IS_EQUAL((mat1.dimension(1)), 3);

  mat1(0,0) = 0.0;
  mat1(0,1) = 1.0;
  mat1(0,2) = 2.0;
  mat1(1,0) = 3.0;
  mat1(1,1) = 4.0;
  mat1(1,2) = 5.0;

  mat2(0,0) = -0.0;
  mat2(0,1) = -1.0;
  mat2(0,2) = -2.0;
  mat2(1,0) = -3.0;
  mat2(1,1) = -4.0;
  mat2(1,2) = -5.0;

  TensorFixedSize<float, Sizes<2, 3> > mat3;
  TensorFixedSize<float, Sizes<2, 3>, RowMajor> mat4;
  mat3 = mat1.abs();
  mat4 = mat2.abs();

  VERIFY_IS_EQUAL((mat3.size()), 2*3);
    //  VERIFY_IS_EQUAL((mat3.dimension(0)), 2);
    //  VERIFY_IS_EQUAL((mat3.dimension(1)), 3);

  VERIFY_IS_APPROX(mat3(0,0), 0.0f);
  VERIFY_IS_APPROX(mat3(0,1), 1.0f);
  VERIFY_IS_APPROX(mat3(0,2), 2.0f);
  VERIFY_IS_APPROX(mat3(1,0), 3.0f);
  VERIFY_IS_APPROX(mat3(1,1), 4.0f);
  VERIFY_IS_APPROX(mat3(1,2), 5.0f);

  VERIFY_IS_APPROX(mat4(0,0), 0.0f);
  VERIFY_IS_APPROX(mat4(0,1), 1.0f);
  VERIFY_IS_APPROX(mat4(0,2), 2.0f);
  VERIFY_IS_APPROX(mat4(1,0), 3.0f);
  VERIFY_IS_APPROX(mat4(1,1), 4.0f);
  VERIFY_IS_APPROX(mat4(1,2), 5.0f);
}

static void test_3d()
{
  TensorFixedSize<float, Sizes<2, 3, 7> > mat1;
  TensorFixedSize<float, Sizes<2, 3, 7>, RowMajor> mat2;

  VERIFY_IS_EQUAL((mat1.size()), 2*3*7);
  VERIFY_IS_EQUAL(mat1.rank(), 3);
  //  VERIFY_IS_EQUAL((mat1.dimension(0)), 2);
  //  VERIFY_IS_EQUAL((mat1.dimension(1)), 3);
  //  VERIFY_IS_EQUAL((mat1.dimension(2)), 7);

  float val = 0.0f;
  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < 3; ++j) {
      for (int k = 0; k < 7; ++k) {
        mat1(i,j,k) = val;
        mat2(i,j,k) = val;
        val += 1.0f;
      }
    }
  }

  TensorFixedSize<float, Sizes<2, 3, 7> > mat3;
  mat3 = mat1.sqrt();
  TensorFixedSize<float, Sizes<2, 3, 7>, RowMajor> mat4;
  mat4 = mat2.sqrt();

  VERIFY_IS_EQUAL((mat3.size()), 2*3*7);
  //  VERIFY_IS_EQUAL((mat3.dimension(0)), 2);
  //  VERIFY_IS_EQUAL((mat3.dimension(1)), 3);
  //  VERIFY_IS_EQUAL((mat3.dimension(2)), 7);


  val = 0.0f;
  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < 3; ++j) {
      for (int k = 0; k < 7; ++k) {
        VERIFY_IS_APPROX(mat3(i,j,k), sqrtf(val));
        VERIFY_IS_APPROX(mat4(i,j,k), sqrtf(val));
        val += 1.0f;
      }
    }
  }
}


static void test_array()
{
  TensorFixedSize<float, Sizes<2, 3, 7> > mat1;
  float val = 0.0f;
  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < 3; ++j) {
      for (int k = 0; k < 7; ++k) {
        mat1(i,j,k) = val;
        val += 1.0f;
      }
    }
  }

  TensorFixedSize<float, Sizes<2, 3, 7> > mat3;
  mat3 = mat1.pow(3.5f);

  val = 0.0f;
  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < 3; ++j) {
      for (int k = 0; k < 7; ++k) {
        VERIFY_IS_APPROX(mat3(i,j,k), powf(val, 3.5f));
        val += 1.0f;
      }
    }
  }
}

EIGEN_DECLARE_TEST(cxx11_tensor_fixed_size)
{
  CALL_SUBTEST(test_0d());
  CALL_SUBTEST(test_1d());
  CALL_SUBTEST(test_tensor_map());
  CALL_SUBTEST(test_2d());
  CALL_SUBTEST(test_3d());
  CALL_SUBTEST(test_array());
}
