// GenTensors - A simple tensor library
// Copyright (C) 2012-2026 Eric Bechet
//
// See the LICENSE file for license information and contributions.
// Please report all bugs and problems to <bechet@cadxfem.org>.

// check gentensor ops on complex
#include <complex>
#include "genTensors.h"

int main(int argc,char**argv)
{
  std::complex<double> mat0 (7.0,7.0);
  const std::complex<double> mat1[]=
  {
    std::complex<double>(+01.0,+01.0),std::complex<double>(+05.0,+05.0),std::complex<double>(+03.0,+03.0)
  };
  const std::complex<double> mat2[]=
  {
    std::complex<double>(+01.0,+01.0),std::complex<double>(+00.0,+00.0),std::complex<double>(-01.0,-01.0),
    std::complex<double>(+00.0,+00.0),std::complex<double>(+02.0,+02.0),std::complex<double>(+00.0,+00.0),
    std::complex<double>(-01.0,-01.0),std::complex<double>(+00.0,+00.0),std::complex<double>(+03.0,+03.0)
  };

  const std::complex<double> mat3[]=
  {
    std::complex<double>(+01.0,+01.0),std::complex<double>(+00.0,+00.0),std::complex<double>(-01.0,-01.0),
    std::complex<double>(+00.0,+00.0),std::complex<double>(+02.0,+02.0),std::complex<double>(+00.0,+00.0),
    std::complex<double>(-01.0,-01.0),std::complex<double>(+00.0,+00.0),std::complex<double>(+03.0,+03.0),

    std::complex<double>(+00.0,+00.0),std::complex<double>(+00.0,+00.0),std::complex<double>(+00.0,+00.0),
    std::complex<double>(+00.0,+00.0),std::complex<double>(+02.0,+02.0),std::complex<double>(+00.0,+00.0),
    std::complex<double>(+00.0,+00.0),std::complex<double>(+00.0,+00.0),std::complex<double>(+00.0,+00.0),

    std::complex<double>(+03.0,+03.0),std::complex<double>(+00.0,+00.0),std::complex<double>(-10.0,-10.0),
    std::complex<double>(+00.0,+00.0),std::complex<double>(+04.0,+04.0),std::complex<double>(+00.0,+00.0),
    std::complex<double>(-10.0,-10.0),std::complex<double>(+00.0,+00.0),std::complex<double>(+05.0,+05.0)
  };

  const std::complex<double> mat4[]=
  {
    std::complex<double>(+01.0,+01.0),std::complex<double>(+00.0,+00.0),std::complex<double>(-01.0,-01.0),
    std::complex<double>(+00.0,+00.0),std::complex<double>(+02.0,+02.0),std::complex<double>(+00.0,+00.0),
    std::complex<double>(-01.0,-01.0),std::complex<double>(+00.0,+00.0),std::complex<double>(+03.0,+03.0),

    std::complex<double>(+00.0,+00.0),std::complex<double>(+00.0,+00.0),std::complex<double>(+00.0,+00.0),
    std::complex<double>(+00.0,+00.0),std::complex<double>(+02.0,+02.0),std::complex<double>(+00.0,+00.0),
    std::complex<double>(+00.0,+00.0),std::complex<double>(+00.0,+00.0),std::complex<double>(+00.0,+00.0),

    std::complex<double>(+03.0,+03.0),std::complex<double>(+00.0,+00.0),std::complex<double>(-10.0,-10.0),
    std::complex<double>(+00.0,+00.0),std::complex<double>(+04.0,+04.0),std::complex<double>(+00.0,+00.0),
    std::complex<double>(-10.0,-10.0),std::complex<double>(+00.0,+00.0),std::complex<double>(+05.0,+05.0),


    std::complex<double>(+01.0,+01.0),std::complex<double>(+00.0,+00.0),std::complex<double>(-01.0,-01.0),
    std::complex<double>(+00.0,+00.0),std::complex<double>(+02.0,+02.0),std::complex<double>(+00.0,+00.0),
    std::complex<double>(-01.0,-01.0),std::complex<double>(+00.0,+00.0),std::complex<double>(+03.0,+03.0),

    std::complex<double>(+00.0,+00.0),std::complex<double>(+00.0,+00.0),std::complex<double>(+00.0,+00.0),
    std::complex<double>(+00.0,+00.0),std::complex<double>(+02.0,+02.0),std::complex<double>(+00.0,+00.0),
    std::complex<double>(+00.0,+00.0),std::complex<double>(+00.0,+00.0),std::complex<double>(+00.0,+00.0),

    std::complex<double>(+03.0,+03.0),std::complex<double>(+00.0,+00.0),std::complex<double>(-10.0,-10.0),
    std::complex<double>(+00.0,+00.0),std::complex<double>(+04.0,+04.0),std::complex<double>(+00.0,+00.0),
    std::complex<double>(-10.0,-10.0),std::complex<double>(+00.0,+00.0),std::complex<double>(+05.0,+05.0),


    std::complex<double>(+01.0,+01.0),std::complex<double>(+00.0,+00.0),std::complex<double>(-01.0,-01.0),
    std::complex<double>(+00.0,+00.0),std::complex<double>(+02.0,+02.0),std::complex<double>(+00.0,+00.0),
    std::complex<double>(-01.0,-01.0),std::complex<double>(+00.0,+00.0),std::complex<double>(+03.0,+03.0),

    std::complex<double>(+00.0,+00.0),std::complex<double>(+00.0,+00.0),std::complex<double>(+00.0,+00.0),
    std::complex<double>(+00.0,+00.0),std::complex<double>(+02.0,+02.0),std::complex<double>(+00.0,+00.0),
    std::complex<double>(+00.0,+00.0),std::complex<double>(+00.0,+00.0),std::complex<double>(+00.0,+00.0),

    std::complex<double>(+03.0,+03.0),std::complex<double>(+00.0,+00.0),std::complex<double>(-10.0,-10.0),
    std::complex<double>(+00.0,+00.0),std::complex<double>(+04.0,+04.0),std::complex<double>(+00.0,+00.0),
    std::complex<double>(-10.0,-10.0),std::complex<double>(+00.0,+00.0),std::complex<double>(+05.0,+05.0)
  };


  genTensor0<std::complex<double> > t0(mat0);
  genTensor1<std::complex<double> > t1(mat1);
  genTensor2<std::complex<double> > t2(mat2);
  genTensor3<std::complex<double> > t3(mat3);
  genTensor4<std::complex<double> > t4(mat4);

  genTensor0<std::complex<double> > t00=t0*t0;
  genTensor0<std::complex<double> > t11=t1*t1;
  genTensor0<std::complex<double> > t22=t2*t2;
  genTensor0<std::complex<double> > t33=t3*t3;
  genTensor0<std::complex<double> > t44=t4*t4;

  genTensor1<std::complex<double> > t10=t1*t0;
  genTensor1<std::complex<double> > t01=t0*t1;
  genTensor1<std::complex<double> > t12=t1*t2;
  genTensor1<std::complex<double> > t21=t2*t1;
  genTensor1<std::complex<double> > t23=t2*t3;
  genTensor1<std::complex<double> > t32=t3*t2;
  genTensor1<std::complex<double> > t34=t3*t4;
  genTensor1<std::complex<double> > t43=t4*t3;

  genTensor2<std::complex<double> > t20=t2*t0;
  genTensor2<std::complex<double> > t02=t0*t2;
  genTensor2<std::complex<double> > t31=t3*t1;
  genTensor2<std::complex<double> > t13=t1*t3;
  genTensor2<std::complex<double> > t42=t4*t2;
  genTensor2<std::complex<double> > t24=t2*t4;

  genTensor3<std::complex<double> > t30=t3*t0;
  genTensor3<std::complex<double> > t03=t0*t3;
  genTensor3<std::complex<double> > t41=t4*t1;
  genTensor3<std::complex<double> > t14=t1*t4;

  genTensor4<std::complex<double> > t40=t4*t0;
  genTensor4<std::complex<double> > t04=t0*t4;


  std::cout.precision(17);
  std::cout << std::showpos;
  std::cout << std::scientific;

  std::cout << norm(t0) << " " << norm(t1) << " " << norm(t2) << " " << norm(t3) << " " << norm(t4) << std::endl;
  std::cout << norm(t00) << " " << norm(t11) << " " << norm(t22) << " " << norm(t33) << " " << norm(t44) << std::endl;
  std::cout << norm(t10) << " " << norm(t01) << " " << norm(t21) << " " << norm(t12) << " " << norm(t32) <<  " " << norm(t23) << " " << norm(t43) <<  " " << norm(t34) << std::endl;
  std::cout << norm(t20) << " " << norm(t02) << " " << norm(t31) << " " << norm(t13) << " " << norm(t42) << " " << norm(t24) << std::endl;
  std::cout << norm(t30) << " " << norm(t03) << " " << norm(t41) << " " << norm(t14) << std::endl;
  std::cout << norm(t40) << " " << norm(t04)  << std::endl;

  if (std::abs(norm(t0) - std::complex<double>(7.00000000000000000e+00,7.00000000000000000e+00))> 1e-12) return 1;
  if (std::abs(norm(t1) - std::complex<double>(5.91607978309961613e+00,5.91607978309961613e+00))> 1e-12) return 2;
  if (std::abs(norm(t2) - std::complex<double>(4.00000000000000000e+00,4.00000000000000000e+00))> 1e-12) return 3;
  if (std::abs(norm(t3) - std::complex<double>(1.64316767251549827e+01,1.64316767251549827e+01))> 1e-12) return 4;
  if (std::abs(norm(t4) - std::complex<double>(2.84604989415154144e+01,2.84604989415154144e+01))> 1e-12) return 5;

  if (std::abs(norm(t00) - std::complex<double>(+0.00000000000000000e+00,+9.80000000000000000e+01)) >1e-12) return 6;
  if (std::abs(norm(t11) - std::complex<double>(+0.00000000000000000e+00,+7.00000000000000000e+01)) >1e-12) return 7;
  if (std::abs(norm(t22) - std::complex<double>(+0.00000000000000000e+00,+3.20000000000000000e+01)) >1e-12) return 8;
  if (std::abs(norm(t33) - std::complex<double>(+0.00000000000000000e+00,+1.30000000000000000e+02)) >1e-12) return 9;
  if (std::abs(norm(t44) - std::complex<double>(+0.00000000000000000e+00,+2.00000000000000000e+00)) >1e-12) return 10;

  if (std::abs(norm(t10) - std::complex<double>(+0.00000000000000000e+00,+8.28251169633946205e+01))> 1e-12) return 11;
  if (std::abs(norm(t01) - std::complex<double>(+0.00000000000000000e+00,+8.28251169633946205e+01))> 1e-12) return 12;
  if (std::abs(norm(t21) - std::complex<double>(+0.00000000000000000e+00,+2.59229627936314415e+01))> 1e-12) return 13;
  if (std::abs(norm(t12) - std::complex<double>(+0.00000000000000000e+00,+2.59229627936314415e+01))> 1e-12) return 14;
  if (std::abs(norm(t32) - std::complex<double>(+0.00000000000000000e+00,+9.77343337829649244e+01))> 1e-12) return 15;
  if (std::abs(norm(t23) - std::complex<double>(+0.00000000000000000e+00,+7.53126815350509276e+01))> 1e-12) return 16;
  if (std::abs(norm(t43) - std::complex<double>(+0.00000000000000000e+00,+2.25166604983954045e+02))> 1e-12) return 17;
  if (std::abs(norm(t34) - std::complex<double>(+0.00000000000000000e+00,+1.82658150653071061e+02))> 1e-12) return 18;

  if (std::abs(norm(t20) - std::complex<double>(+0.00000000000000000e+00,+5.60000000000000000e+01))> 1e-12) return 19;
  if (std::abs(norm(t02) - std::complex<double>(+0.00000000000000000e+00,+5.60000000000000000e+01))> 1e-12) return 20;
  if (std::abs(norm(t31) - std::complex<double>(+0.00000000000000000e+00,+7.54188305398592149e+01))> 1e-12) return 21;
  if (std::abs(norm(t13) - std::complex<double>(+0.00000000000000000e+00,+1.08111054013916629e+02))> 1e-12) return 22;
  if (std::abs(norm(t42) - std::complex<double>(+0.00000000000000000e+00,+1.69280831755990619e+02))> 1e-12) return 23;
  if (std::abs(norm(t24) - std::complex<double>(+0.00000000000000000e+00,+6.57267069006199307e+01))> 1e-12) return 24;

  if (std::abs(norm(t30) - std::complex<double>(+0.00000000000000000e+00,+2.30043474152169779e+02))> 1e-12) return 25;
  if (std::abs(norm(t03) - std::complex<double>(+0.00000000000000000e+00,+2.30043474152169779e+02))> 1e-12) return 26;
  if (std::abs(norm(t41) - std::complex<double>(+0.00000000000000000e+00,+1.30629246342463460e+02))> 1e-12) return 27;
  if (std::abs(norm(t14) - std::complex<double>(+0.00000000000000000e+00,+2.95770181052789724e+02))> 1e-12) return 28;

  if (std::abs(norm(t40) - std::complex<double>(+0.00000000000000000e+00,+3.98446985181215780e+02))> 1e-12) return 29;
  if (std::abs(norm(t04) - std::complex<double>(+0.00000000000000000e+00,+3.98446985181215780e+02))> 1e-12) return 30;

  return 0; 
}
