package basics.utl;

import basics.testing.Test;

public class VectorSpaceUtl
{
private VectorSpaceUtl()
{
}

/*
 * ------------------------------------ 
 * A = {x1,x2,x3...} 
 * B = {y1,y2,y3...} 
 * x1*y2 + x2*y2 + x3*y3 +...
 * ------------------------------------
 */
public static double cosine(double [] d, double dMagnit, double [] q, double qMagnit)
{
   double sum = 0D;
   for(int k = 0; k < d.length; k++)
      sum = sum + (d[k] * q[k]);
   double M = dMagnit * qMagnit;
   double result = M == 0 ? sum : sum / M;
   return result > 0D ? NumUtl.round(result, 12) : result;
}

public static double magnitude(double [] vector)
{
   double M = 0D;
   for(int i = 0; i < vector.length; i++)
   {
      double e = vector[i];
      M = (e > 0) ? M + (e * e) : M;
   }
   return NumUtl.round(Math.sqrt(M), 12);
}

public static void unittest()
{
   double [] v0 = new double [] { 0, 0, 0, 0, 0 };
   double [] v1 = new double [] { 1, 0, 1, 1, 0 };
   double [] v2 = new double [] { 0, 0, 1, 1, 0 };
   double [] v3 = new double [] { 0, 1, 0, 0, 1 };
   double [] v4 = new double [] { 0, 10, 0, 0, 10 };
   double m0 = magnitude(v0);
   double m1 = magnitude(v1);
   double m2 = magnitude(v2);
   double m3 = magnitude(v3);
   double m4 = magnitude(v4);
   Test.assertTrue(m0 == 0, "magnitude of m0 should be 0");
   Test.assertTrue(m2 == m3, "magnitude of m2 != m3");
   Test.assertTrue(m4 > 10, "magnitude of m4 should be > 10");
   //   Test.printout("m0 " + m0 + " v: " + SUtl.join(v0, " "));
   //   Test.printout("m1 " + m1 + " v: " + SUtl.join(v1, " "));
   //   Test.printout("m2 " + m2 + " v: " + SUtl.join(v2, " "));
   //   Test.printout("m3 " + m3 + " v: " + SUtl.join(v3, " "));
   //   Test.printout("m4 " + m4 + " v: " + SUtl.join(v4, " "));
   double cos_0_1 = cosine(v0, magnitude(v0), v1, magnitude(v1));
   double cos_1_2 = cosine(v1, magnitude(v1), v2, magnitude(v2));
   double cos_2_3 = cosine(v2, magnitude(v2), v3, magnitude(v3));
   double cos_3_4 = cosine(v3, magnitude(v3), v4, magnitude(v4));
   double cos_0_4 = cosine(v0, magnitude(v0), v4, magnitude(v4));
   //   Test.printout("cos_0_1 " + cos_0_1);
   //   Test.printout("cos_1_2 " + cos_1_2);
   //   Test.printout("cos_2_2 " + cos_2_3);
   //   Test.printout("cos_3_4 " + cos_3_4);
   //   Test.printout("cos_0_4 " + cos_0_4);
   Test.assertTrue(cos_0_1 == 0, "cos_0_1 should be 0");
   Test.assertTrue(cos_2_3 == 0, "cos_2_3 should be 0");
   Test.assertTrue(cos_0_4 == 0, "cos_0_4 should be 0");
}
}
