content: /*
   * Copyright (c) 2017-present, Workday, Inc.
   * All rights reserved.
   *
   * This source code is licensed under the MIT license found in the LICENSE file in the root repository.
   */
  
  package com.workday.insights.matrix;
  
  import java.io.Serializable;
  
  /**
   * InsightsVector
   *
   * <p> Vector of double entries </p>
   */
  public class InsightsVector implements Serializable {
  
    private static final long serialVersionUID = 43L;
  
    protected int _m = -1;
    protected double[] _data = null;
    protected boolean _valid = false;
  
    //=====================================================================
    // Constructors
    //=====================================================================
  
    /**
     * Constructor for InsightVector
     *
     * @param m     size of the vector
     * @param value initial value for all entries
     */
    public InsightsVector(int m,
                          double value) {
      if (m <= 0) {
        throw new RuntimeException("[InsightsVector] invalid size");
      } else {
        _data = new double[m];
        for (int j = 0; j < m; ++j) {
          _data[j] = value;
        }
        _m = m;
        _valid = true;
      }
    }
  
    /**
     * Constructor for InsightVector
     *
     * @param data     1-dimensional double array with pre-populated values
     * @param deepCopy if TRUE, allocated new memory space and copy data over if FALSE, re-use the given memory space and
     *                 overwrites on it
     */
    public InsightsVector(double[] data,
                          boolean deepCopy) {
      if (data == null || data.length == 0) {
        throw new RuntimeException("[InsightsVector] invalid data");
      } else {
        _m = data.length;
        if (deepCopy) {
          _data = new double[_m];
          System.arraycopy(data, 0, _data, 0, _m);
        } else {
          _data = data;
        }
        _valid = true;
      }
    }
    //=====================================================================
    // END of Constructors
    //=====================================================================
    //=====================================================================
    // Helper Methods
    //=====================================================================
  
    /**
     * Create and allocate memory for a new copy of double array of current elements in the vector
     *
     * @return the new copy
     */
    public double[] deepCopy() {
      double[] dataDeepCopy = new double[_m];
      System.arraycopy(_data, 0, dataDeepCopy, 0, _m);
      return dataDeepCopy;
    }
    //=====================================================================
    // END of Helper Methods
    //=====================================================================
    //=====================================================================
    // Getters & Setters
    //=====================================================================
  
    /**
     * Getter for the i-th element in the vector
     *
     * @param i element index
     * @return the i-th element
     */
    public double get(int i) {
      if (!_valid) {
        throw new RuntimeException("[InsightsVector] invalid Vector");
      } else if (i >= _m) {
        throw new IndexOutOfBoundsException(
            String.format("[InsightsVector] Index: %d, Size: %d", i, _m));
      }
      return _data[i];
    }
  
    /**
     * Getter for the size of the vector
     *
     * @return size of the vector
     */
    public int size() {
      if (!_valid) {
        throw new RuntimeException("[InsightsVector] invalid Vector");
      }
  
      return _m;
    }
  
    /**
     * Setter to modify a element in the vector
     *
     * @param i   element index
     * @param val new value
     */
    public void set(int i,
                    double val) {
      if (!_valid) {
        throw new RuntimeException("[InsightsVector] invalid Vector");
      } else if (i >= _m) {
        throw new IndexOutOfBoundsException(
            String.format("[InsightsVector] Index: %d, Size: %d", i, _m));
      }
      _data[i] = val;
    }
  
    //=====================================================================
    // END of Getters & Setters
    //=====================================================================
    //=====================================================================
    // Basic Linear Algebra operations
    //=====================================================================
  
    /**
     * Perform dot product operation with another vector of the same size
     *
     * @param vector vector of the same size
     * @return dot product of the two vector
     */
    public double dot(InsightsVector vector) {
      if (!_valid || !vector._valid) {
        throw new RuntimeException("[InsightsVector] invalid Vector");
      } else if (_m != vector.size()) {
        throw new RuntimeException("[InsightsVector][dot] invalid vector size.");
      }
  
      double sumOfProducts = 0;
      for (int i = 0; i < _m; i++) {
        sumOfProducts += _data[i] * vector.get(i);
      }
      return sumOfProducts;
    }
    //=====================================================================
    // END of Basic Linear Algebra operations
    //=====================================================================
  }
  