code: package dotnet54.util.math.doubles;
  
  public class Vectors {
      public static final double threshold = 1e-10;
  
      public static double l1Norm(double[] vector) {
          double total = 0;
          for (double element : vector) {
              total += (element <= 0.0D) ? 0.0D - element : element;  //Math.abs()
          }
          return total;
      }
  
      public static double l2Norm(double[] vector) {
          double total = 0;
          for (double element : vector) {
              total += element * element;
          }
          return Math.sqrt(total);
      }
  
      public static double l2NormSquared(double[] vector) {
          double total = 0;
          for (double element : vector) {
              total += element * element;
          }
          return total;
      }
  
      public static double lpNorm(double[] vector, int p) {
          double total = 0;
          for (double element : vector) {
              total += Math.pow(element, p);
          }
          return  Math.pow(total, (double) 1/p);
      }
  
      public static double l1Distance(double[] vector1, double[] vector2) {
          double total = 0;
          int minLength = Math.min(vector1.length, vector2.length);
          double diff;
          for (int i = 0; i < minLength; i++) {
              diff = vector1[i] - vector2[i];
              total += (diff <= 0.0D) ? 0.0D - diff : diff;  //Math.abs()
          }
          return total;
      }
  
      public static double l2Distance(double[] vector1, double[] vector2) {
          double total = 0;
          int minLength = Math.min(vector1.length, vector2.length);
          double diff;
          for (int i = 0; i < minLength; i++) {
              diff = vector1[i] - vector2[i];
              total +=  diff * diff;
          }
          return Math.sqrt(total);
      }
  
      public static double l2DistanceSquared(double[] vector1, double[] vector2) {
          double total = 0;
          int minLength = Math.min(vector1.length, vector2.length);
          double diff;
          for (int i = 0; i < minLength; i++) {
              diff = vector1[i] - vector1[i];
              total += (diff <= 0.0D) ? 0.0D - diff : diff;  //Math.abs()
          }
          return total;
      }
  
      public static double lpDistance(double[] vector1, double[] vector2, int p) {
          double total = 0;
          int minLength = Math.min(vector1.length, vector2.length);
          double pow;
          for (int i = 0; i < minLength; i++) {
              pow =  Math.pow(vector1[i] - vector2[i], p);
              total += (pow <= 0.0D) ? 0.0D - pow : pow;  //Math.abs()
          }
          return Math.pow(total,  1.0D /p);
      }
  
  //    //TODO CHECK
  //    public static int l1Similarity(double[] vector1, double[] vector2, double epsilon) {
  //        double total = 0;
  //        int minLength = Math.min(vector1.length, vector2.length);
  //        double diff;
  //        for (int i = 0; i < minLength; i++) {
  //            diff = vector1[i] - vector2[i];
  //            total += (diff <= 0.0D) ? 0.0D - diff : diff;  //Math.abs()
  //        }
  //        return total <= minLength * epsilon ? 1: 0;
  //    }
  
  //    //TODO CHECK
  //    public static int l2Similarity(double[] vector1, double[] vector2, double epsilon) {
  //        double total = 0;
  //        int minLength = Math.min(vector1.length, vector2.length);
  //        double diff;
  //        for (int i = 0; i < minLength; i++) {
  //            diff = vector1[i] - vector2[i];
  //            total +=  diff * diff;
  //        }
  //        // if epsilon < 1?
  //        return total <= minLength * epsilon * epsilon ? 1: 0;
  //    }
  
  //    //TODO CHECK
  //    public static int lpSimilarity(double[] vector1, double[] vector2, int p, double epsilon) {
  //        double total = 0;
  //        int minLength = Math.min(vector1.length, vector2.length);
  //        double pow;
  //        for (int i = 0; i < minLength; i++) {
  //            pow =  Math.pow(vector1[i] - vector2[i], p);
  //            total += (pow <= 0.0D) ? 0.0D - pow : pow;  //Math.abs()
  //        }
  //        return Math.pow(total,  1.0D /p);
  //    }
  
      public static double dot(double[] vector1, double[] vector2) {
          double total = 0;
          int minLength = Math.min(vector1.length, vector2.length);
          for (int i = 0; i < minLength; i++) {
              total +=  vector1[i] * vector2[i];
          }
          return total;
      }
  
      public static double[] add(double[] vector1, double[] vector2) {
          double[] result = new double[vector1.length];
          for (int i = 0; i < vector1.length; i++) {
              result[i] =  vector1[i] + vector2[i];
          }
          return result;
      }
  
      public static double[] subtract(double[] vector1, double[] vector2) {
          double[] result = new double[vector1.length];
          for (int i = 0; i < vector1.length; i++) {
              result[i] =  vector1[i] - vector2[i];
          }
          return result;
      }
  
      public static double[] div(double[] vector1, double[] vector2) {
          double[] result = new double[vector1.length];
          for (int i = 0; i < vector1.length; i++) {
              result[i] =  vector1[i] / vector2[i];
          }
          return result;
      }
  
      public static double[] mul(double[] vector1, double[] vector2) {
          double[] result = new double[vector1.length];
          for (int i = 0; i < vector1.length; i++) {
              result[i] =  vector1[i] * vector2[i];
          }
          return result;
      }
  
      public static double[] add(double[] vector1, double scalar) {
          double[] result = new double[vector1.length];
          for (int i = 0; i < vector1.length; i++) {
              result[i] =  vector1[i] + scalar;
          }
          return result;
      }
  
      public static double[] subtract(double[] vector1, double scalar) {
          double[] result = new double[vector1.length];
          for (int i = 0; i < vector1.length; i++) {
              result[i] =  vector1[i] - scalar;
          }
          return result;
      }
  
      public static double[] div(double[] vector1, double scalar) {
          double[] result = new double[vector1.length];
          for (int i = 0; i < vector1.length; i++) {
              result[i] =  vector1[i] / scalar;
          }
          return result;
      }
  
      public static double[] mul(double[] vector1, double scalar) {
          double[] result = new double[vector1.length];
          for (int i = 0; i < vector1.length; i++) {
              result[i] =  vector1[i] * scalar;
          }
          return result;
      }
  
      public static double[] addInPlace(double[] vector1, double[] vector2) {
          for (int i = 0; i < vector1.length; i++) {
              vector1[i] =  vector1[i] + vector2[i];
          }
          return vector1;
      }
  
      public static double[] subtractInPlace(double[] vector1, double[] vector2) {
          for (int i = 0; i < vector1.length; i++) {
              vector1[i] =  vector1[i] - vector2[i];
          }
          return vector1;
      }
  
      public static double[] divInPlace(double[] vector1, double[] vector2) {
          for (int i = 0; i < vector1.length; i++) {
              vector1[i] =  vector1[i] / vector2[i];
          }
          return vector1;
      }
  
      public static double[] mulInPlace(double[] vector1, double[] vector2) {
          for (int i = 0; i < vector1.length; i++) {
              vector1[i] =  vector1[i] * vector2[i];
          }
          return vector1;
      }
  
      public static double[] addInPlace(double[] vector1, double scalar) {
          for (int i = 0; i < vector1.length; i++) {
              vector1[i] =  vector1[i] + scalar;
          }
          return vector1;
      }
  
      public static double[] subtractInPlace(double[] vector1, double scalar) {
          for (int i = 0; i < vector1.length; i++) {
              vector1[i] =  vector1[i] - scalar;
          }
          return vector1;
      }
  
      public static double[] divInPlace(double[] vector1, double scalar) {
          for (int i = 0; i < vector1.length; i++) {
              vector1[i] =  vector1[i] / scalar;
          }
          return vector1;
      }
  
      public static double[] mulInPlace(double[] vector1, double scalar) {
          for (int i = 0; i < vector1.length; i++) {
              vector1[i] =  vector1[i] * scalar;
          }
          return vector1;
      }
  }
  