<commit_before>package hex.psvm.psvm;

import water.MRTask;
import water.fvec.*;
import water.util.ArrayUtils;

/**
 * Utils class for matrix operations. See also {code DMatrix.java}
 * 
 */
public class MatrixUtils {

  /**
   * Calculates matrix product M'DM
   * @param m Frame representing the M matrix (m x n), M' is expected to be lower triangular
   * @param diagonal Vec representation of a diagonal matrix (m x m)
   * @return lower triangular portion of the product (the product is a symmetrical matrix, only the lower portion is represented)
   */
  public static LLMatrix productMtDM(Frame m, Vec diagonal) {
    Vec[] vecs = ArrayUtils.append(m.vecs(), diagonal);
    double result[] = new ProductMMTask().doAll(vecs)._result;
    
    LLMatrix product = new LLMatrix(m.numCols());
    int pos = 0;
    for (int i = 0; i < m.numCols(); i++) {
      for (int j = 0; j <= i; j++) {
        product.set(i, j, result[pos++]);
      }
    }
    return product;
  }

  /**
   * Calculates matrix-vector product M'v
   *
   * @param m Frame representing matrix M (m x n)
   * @param v Vec representing vector v (m x 1)
   * @return m-element array representing the result of the product
   */
  public static double[] productMtv(Frame m, Vec v) {
    Vec[] vecs = ArrayUtils.append(m.vecs(), v);
    return new ProductMtvTask().doAll(vecs)._result;
  }

  /**
   * Previous Mtv method is for v of dimension (m x 1) here it is for (n x 1)
   * <p>
   * Calculates matrix-vector product M'v
   *
   * @param m Frame representing matrix M (m x n)
   * @param v Vec representing vector v (n x 1)
   * @return m-element array representing the result of the product
   */
  public static Vec productMtv2(Frame m, Vec v) {
    if (v.length() != m.numCols()) {
      throw new UnsupportedOperationException("Vector elements number must be the same as matrix column number");
    }
    Vec result = new ProductMtvTask2(v).doAll(Vec.T_NUM, m).outputFrame().vecs()[0];
    return result;
  }

  /**
   * Same as productMtv2 but here is array.
   * <p>
   * Calculates matrix-vector product M'v
   *
   * @param m     Frame representing matrix M (m x n)
   * @param array Array representing vector v (n x 1). Size of array here is significantly smaller. Vector would be
   *              too much.
   * @return m-element array representing the result of the product
   */
  public static Vec productMtv2Array(Frame m, double[] array) {
    if (array.length != m.numCols()) {
      throw new UnsupportedOperationException("Array elements number must be the same as matrix column number");
    }
    Vec result = new ProductMtv2Array(array).doAll(Vec.T_NUM, m).outputFrame().vecs()[0];
    return result;
  }

  /**
   * Calculates vector-vector product v1*v2
   *
   * @param v1 vec representing first element (1 x n)
   * @param v2 Vec representing second element (n x 1)
   * @return double value (vector 1 x 1)
   */
  public static double productVtV(Vec v1, Vec v2) {
    if (v2.length() != v1.length()) {
      throw new UnsupportedOperationException("Vector elements number must be the same");
    }
    return new ProductMtvTask().doAll(v1, v2)._result[0];
  }

  /**
   * Calculates matrix-array subtraction M'array
   *
   * @param m     Frame representing matrix M (m x n)
   * @param array Array representing vector v (n x 1). Size of array here is significantly smaller. Vector would be
   *              too much.
   * @return (m x n)-element array representing the result of the subtraction
   */
  public static Frame subtractionMtArray(Frame m, double[] array) {
    if (array.length != m.numCols()) {
      throw new UnsupportedOperationException("Array elements number must be the same as matrix column number");
    }
    Frame result = new SubtractionMtArrayTask(array).doAll(m.types(), m).outputFrame();
    return result;
  }

  /**
   * Calculates matrix-vector subtraction M'v
   *
   * @param m Frame representing matrix M (m x n)
   * @param v Vec representing vector v (n x 1)
   * @return (m x n)-element array representing the result of the subtraction
   */
  public static Frame subtractionMtv(Frame m, Vec v) {
    if (v.length() != m.numCols()) {
      throw new UnsupportedOperationException("Vector elements number must be the same as matrix column number");
    }
    Frame result = new SubtractionMtvTask(v).doAll(m.types(), m).outputFrame();
    return result;
  }

  /**
   * Calculates vector-vector subtraction v'v
   *
   * @param v1 Vec representing vector v (n x 1)
   * @param v2 Vec representing vector v (n x 1)
   * @return n-element vec representing the result of the subtraction
   */
  public static Vec subtractionVtv(Vec v1, Vec v2) {
    if (v2.length() != v1.length()) {
      throw new UnsupportedOperationException("Vector elements number must be the same");
    }
    Vec result = new SubtractionVtvTask().doAll(Vec.T_NUM, v1, v2).outputFrame().vec(0);
    return result;
  }

  private static class ProductMMTask extends MRTask<ProductMMTask> {
    // OUT
    private double[] _result;

    @Override
    public void map(Chunk[] cs) {
      final int column = cs.length - 1;
      final Chunk diagonal = cs[column];
      _result = new double[(column + 1) * column / 2];
      double[] buff = new double[cs[0]._len];
      int offset = 0;
      for (int i = 0; i < column; i++) {
        offset += i;<commit_msg>PUBDEV-7138 - better exception messages in MatrixUtils methods<commit_after>package hex.psvm.psvm;

import water.MRTask;
import water.fvec.*;
import water.util.ArrayUtils;

/**
 * Utils class for matrix operations. See also {code DMatrix.java}
 * 
 */
public class MatrixUtils {

  /**
   * Calculates matrix product M'DM
   * @param m Frame representing the M matrix (m x n), M' is expected to be lower triangular
   * @param diagonal Vec representation of a diagonal matrix (m x m)
   * @return lower triangular portion of the product (the product is a symmetrical matrix, only the lower portion is represented)
   */
  public static LLMatrix productMtDM(Frame m, Vec diagonal) {
    Vec[] vecs = ArrayUtils.append(m.vecs(), diagonal);
    double result[] = new ProductMMTask().doAll(vecs)._result;
    
    LLMatrix product = new LLMatrix(m.numCols());
    int pos = 0;
    for (int i = 0; i < m.numCols(); i++) {
      for (int j = 0; j <= i; j++) {
        product.set(i, j, result[pos++]);
      }
    }
    return product;
  }

  /**
   * Calculates matrix-vector product M'v
   *
   * @param m Frame representing matrix M (m x n)
   * @param v Vec representing vector v (m x 1)
   * @return m-element array representing the result of the product
   */
  public static double[] productMtv(Frame m, Vec v) {
    Vec[] vecs = ArrayUtils.append(m.vecs(), v);
    return new ProductMtvTask().doAll(vecs)._result;
  }

  /**
   * Previous Mtv method is for v of dimension (m x 1) here it is for (n x 1)
   * <p>
   * Calculates matrix-vector product M'v
   *
   * @param m Frame representing matrix M (m x n)
   * @param v Vec representing vector v (n x 1)
   * @return m-element array representing the result of the product
   */
  public static Vec productMtv2(Frame m, Vec v) {
    if (v.length() != m.numCols()) {
      throw new UnsupportedOperationException("Vector elements number must be the same as matrix column number");
    }
    Vec result = new ProductMtvTask2(v).doAll(Vec.T_NUM, m).outputFrame().vecs()[0];
    return result;
  }

  /**
   * Same as productMtv2 but here is array.
   * <p>
   * Calculates matrix-vector product M'v
   *
   * @param m     Frame representing matrix M (m x n)
   * @param array Array representing vector v (n x 1). Size of array here is significantly smaller. Vector would be
   *              too much.
   * @return m-element array representing the result of the product
   */
  public static Vec productMtv2Array(Frame m, double[] array) {
    if (array.length != m.numCols()) {
      throw new UnsupportedOperationException("Array elements number must be the same size as matrix column number");
    }
    Vec result = new ProductMtv2Array(array).doAll(Vec.T_NUM, m).outputFrame().vecs()[0];
    return result;
  }

  /**
   * Calculates vector-vector product v1*v2
   *
   * @param v1 vec representing first element (1 x n)
   * @param v2 Vec representing second element (n x 1)
   * @return double value (vector 1 x 1)
   */
  public static double productVtV(Vec v1, Vec v2) {
    if (v2.length() != v1.length()) {
      throw new UnsupportedOperationException("Vector elements number must be the same size.");
    }
    return new ProductMtvTask().doAll(v1, v2)._result[0];
  }

  /**
   * Calculates matrix-array subtraction M'array
   *
   * @param m     Frame representing matrix M (m x n)
   * @param array Array representing vector v (n x 1). Size of array here is significantly smaller. Vector would be
   *              too much.
   * @return (m x n)-element array representing the result of the subtraction
   */
  public static Frame subtractionMtArray(Frame m, double[] array) {
    if (array.length != m.numCols()) {
      throw new UnsupportedOperationException("Array elements number must be the same size as matrix column number.");
    }
    Frame result = new SubtractionMtArrayTask(array).doAll(m.types(), m).outputFrame();
    return result;
  }

  /**
   * Calculates matrix-vector subtraction M'v
   *
   * @param m Frame representing matrix M (m x n)
   * @param v Vec representing vector v (n x 1)
   * @return (m x n)-element array representing the result of the subtraction
   */
  public static Frame subtractionMtv(Frame m, Vec v) {
    if (v.length() != m.numCols()) {
      throw new UnsupportedOperationException("Vector elements number must be the same size as matrix column number.");
    }
    Frame result = new SubtractionMtvTask(v).doAll(m.types(), m).outputFrame();
    return result;
  }

  /**
   * Calculates vector-vector subtraction v'v
   *
   * @param v1 Vec representing vector v (n x 1)
   * @param v2 Vec representing vector v (n x 1)
   * @return n-element vec representing the result of the subtraction
   */
  public static Vec subtractionVtv(Vec v1, Vec v2) {
    if (v2.length() != v1.length()) {
      throw new UnsupportedOperationException("Vector elements number must be the same size.");
    }
    Vec result = new SubtractionVtvTask().doAll(Vec.T_NUM, v1, v2).outputFrame().vec(0);
    return result;
  }

  private static class ProductMMTask extends MRTask<ProductMMTask> {
    // OUT
    private double[] _result;

    @Override
    public void map(Chunk[] cs) {
      final int column = cs.length - 1;
      final Chunk diagonal = cs[column];
      _result = new double[(column + 1) * column / 2];
      double[] buff = new double[cs[0]._len];
      int offset = 0;
      for (int i = 0; i < column; i++) {
        offset += i;
{'fraction_non_alphanumeric': 0.10956875809735332, 'fraction_numerical': 0.009439200444197668, 'mean_word_length': 2.9775487670224514, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5559269', 'n_tokens_mistral': 3361, 'n_tokens_neox': 3261, 'n_words': 1234}