ArrayRealVector.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      https://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. /*
  18.  * This is not the original file distributed by the Apache Software Foundation
  19.  * It has been modified by the Hipparchus project
  20.  */
  21. package org.hipparchus.linear;

  22. import java.io.Serializable;
  23. import java.util.Arrays;
  24. import java.util.Iterator;

  25. import org.hipparchus.analysis.UnivariateFunction;
  26. import org.hipparchus.exception.LocalizedCoreFormats;
  27. import org.hipparchus.exception.MathIllegalArgumentException;
  28. import org.hipparchus.exception.NullArgumentException;
  29. import org.hipparchus.util.FastMath;
  30. import org.hipparchus.util.MathUtils;

  31. /**
  32.  * This class implements the {@link RealVector} interface with a double array.
  33.  */
  34. public class ArrayRealVector extends RealVector implements Serializable {
  35.     /** Serializable version identifier. */
  36.     private static final long serialVersionUID = -1097961340710804027L;
  37.     /** Default format. */
  38.     private static final RealVectorFormat DEFAULT_FORMAT = RealVectorFormat.getRealVectorFormat();

  39.     /** Entries of the vector. */
  40.     private double[] data;

  41.     /**
  42.      * Build a 0-length vector.
  43.      * Zero-length vectors may be used to initialized construction of vectors
  44.      * by data gathering. We start with zero-length and use either the {@link
  45.      * #ArrayRealVector(ArrayRealVector, ArrayRealVector)} constructor
  46.      * or one of the {@code append} method ({@link #append(double)},
  47.      * {@link #append(ArrayRealVector)}) to gather data into this vector.
  48.      */
  49.     public ArrayRealVector() {
  50.         data = new double[0];
  51.     }

  52.     /**
  53.      * Construct a vector of zeroes.
  54.      *
  55.      * @param size Size of the vector.
  56.      */
  57.     public ArrayRealVector(int size) {
  58.         data = new double[size];
  59.     }

  60.     /**
  61.      * Construct a vector with preset values.
  62.      *
  63.      * @param size Size of the vector
  64.      * @param preset All entries will be set with this value.
  65.      */
  66.     public ArrayRealVector(int size, double preset) {
  67.         data = new double[size];
  68.         Arrays.fill(data, preset);
  69.     }

  70.     /**
  71.      * Construct a vector from an array, copying the input array.
  72.      *
  73.      * @param d Array.
  74.      */
  75.     public ArrayRealVector(double[] d) {
  76.         data = d.clone();
  77.     }

  78.     /**
  79.      * Create a new ArrayRealVector using the input array as the underlying
  80.      * data array.
  81.      * If an array is built specially in order to be embedded in a
  82.      * ArrayRealVector and not used directly, the {@code copyArray} may be
  83.      * set to {@code false}. This will prevent the copying and improve
  84.      * performance as no new array will be built and no data will be copied.
  85.      *
  86.      * @param d Data for the new vector.
  87.      * @param copyArray if {@code true}, the input array will be copied,
  88.      * otherwise it will be referenced.
  89.      * @throws NullArgumentException if {@code d} is {@code null}.
  90.      * @see #ArrayRealVector(double[])
  91.      */
  92.     public ArrayRealVector(double[] d, boolean copyArray)
  93.         throws NullArgumentException {
  94.         if (d == null) {
  95.             throw new NullArgumentException();
  96.         }
  97.         data = copyArray ? d.clone() :  d;
  98.     }

  99.     /**
  100.      * Construct a vector from part of a array.
  101.      *
  102.      * @param d Array.
  103.      * @param pos Position of first entry.
  104.      * @param size Number of entries to copy.
  105.      * @throws NullArgumentException if {@code d} is {@code null}.
  106.      * @throws MathIllegalArgumentException if the size of {@code d} is less
  107.      * than {@code pos + size}.
  108.      */
  109.     public ArrayRealVector(double[] d, int pos, int size)
  110.         throws MathIllegalArgumentException, NullArgumentException {
  111.         if (d == null) {
  112.             throw new NullArgumentException();
  113.         }
  114.         if (d.length < pos + size) {
  115.             throw new MathIllegalArgumentException(LocalizedCoreFormats.NUMBER_TOO_LARGE,
  116.                                                    pos + size, d.length);
  117.         }
  118.         data = new double[size];
  119.         System.arraycopy(d, pos, data, 0, size);
  120.     }

  121.     /**
  122.      * Construct a vector from an array.
  123.      *
  124.      * @param d Array of {@code Double}s.
  125.      */
  126.     public ArrayRealVector(Double[] d) {
  127.         data = new double[d.length];
  128.         for (int i = 0; i < d.length; i++) {
  129.             data[i] = d[i];
  130.         }
  131.     }

  132.     /**
  133.      * Construct a vector from part of an array.
  134.      *
  135.      * @param d Array.
  136.      * @param pos Position of first entry.
  137.      * @param size Number of entries to copy.
  138.      * @throws NullArgumentException if {@code d} is {@code null}.
  139.      * @throws MathIllegalArgumentException if the size of {@code d} is less
  140.      * than {@code pos + size}.
  141.      */
  142.     public ArrayRealVector(Double[] d, int pos, int size)
  143.         throws MathIllegalArgumentException, NullArgumentException {
  144.         if (d == null) {
  145.             throw new NullArgumentException();
  146.         }
  147.         if (d.length < pos + size) {
  148.             throw new MathIllegalArgumentException(LocalizedCoreFormats.NUMBER_TOO_LARGE,
  149.                                                    pos + size, d.length);
  150.         }
  151.         data = new double[size];
  152.         for (int i = pos; i < pos + size; i++) {
  153.             data[i - pos] = d[i];
  154.         }
  155.     }

  156.     /**
  157.      * Construct a vector from another vector, using a deep copy.
  158.      *
  159.      * @param v vector to copy.
  160.      * @throws NullArgumentException if {@code v} is {@code null}.
  161.      */
  162.     public ArrayRealVector(RealVector v) throws NullArgumentException {
  163.         if (v == null) {
  164.             throw new NullArgumentException();
  165.         }
  166.         data = new double[v.getDimension()];
  167.         for (int i = 0; i < data.length; ++i) {
  168.             data[i] = v.getEntry(i);
  169.         }
  170.     }

  171.     /**
  172.      * Construct a vector from another vector, using a deep copy.
  173.      *
  174.      * @param v Vector to copy.
  175.      * @throws NullArgumentException if {@code v} is {@code null}.
  176.      */
  177.     public ArrayRealVector(ArrayRealVector v) throws NullArgumentException {
  178.         this(v, true);
  179.     }

  180.     /**
  181.      * Construct a vector from another vector.
  182.      *
  183.      * @param v Vector to copy.
  184.      * @param deep If {@code true} perform a deep copy, otherwise perform a
  185.      * shallow copy.
  186.      */
  187.     public ArrayRealVector(ArrayRealVector v, boolean deep) {
  188.         data = deep ? v.data.clone() : v.data;
  189.     }

  190.     /**
  191.      * Construct a vector by appending one vector to another vector.
  192.      * @param v1 First vector (will be put in front of the new vector).
  193.      * @param v2 Second vector (will be put at back of the new vector).
  194.      */
  195.     public ArrayRealVector(ArrayRealVector v1, ArrayRealVector v2) {
  196.         data = new double[v1.data.length + v2.data.length];
  197.         System.arraycopy(v1.data, 0, data, 0, v1.data.length);
  198.         System.arraycopy(v2.data, 0, data, v1.data.length, v2.data.length);
  199.     }

  200.     /**
  201.      * Construct a vector by appending one vector to another vector.
  202.      * @param v1 First vector (will be put in front of the new vector).
  203.      * @param v2 Second vector (will be put at back of the new vector).
  204.      */
  205.     public ArrayRealVector(ArrayRealVector v1, RealVector v2) {
  206.         final int l1 = v1.data.length;
  207.         final int l2 = v2.getDimension();
  208.         data = new double[l1 + l2];
  209.         System.arraycopy(v1.data, 0, data, 0, l1);
  210.         for (int i = 0; i < l2; ++i) {
  211.             data[l1 + i] = v2.getEntry(i);
  212.         }
  213.     }

  214.     /**
  215.      * Construct a vector by appending one vector to another vector.
  216.      * @param v1 First vector (will be put in front of the new vector).
  217.      * @param v2 Second vector (will be put at back of the new vector).
  218.      */
  219.     public ArrayRealVector(RealVector v1, ArrayRealVector v2) {
  220.         final int l1 = v1.getDimension();
  221.         final int l2 = v2.data.length;
  222.         data = new double[l1 + l2];
  223.         for (int i = 0; i < l1; ++i) {
  224.             data[i] = v1.getEntry(i);
  225.         }
  226.         System.arraycopy(v2.data, 0, data, l1, l2);
  227.     }

  228.     /**
  229.      * Construct a vector by appending one vector to another vector.
  230.      * @param v1 First vector (will be put in front of the new vector).
  231.      * @param v2 Second vector (will be put at back of the new vector).
  232.      */
  233.     public ArrayRealVector(ArrayRealVector v1, double[] v2) {
  234.         final int l1 = v1.getDimension();
  235.         final int l2 = v2.length;
  236.         data = new double[l1 + l2];
  237.         System.arraycopy(v1.data, 0, data, 0, l1);
  238.         System.arraycopy(v2, 0, data, l1, l2);
  239.     }

  240.     /**
  241.      * Construct a vector by appending one vector to another vector.
  242.      * @param v1 First vector (will be put in front of the new vector).
  243.      * @param v2 Second vector (will be put at back of the new vector).
  244.      */
  245.     public ArrayRealVector(double[] v1, ArrayRealVector v2) {
  246.         final int l1 = v1.length;
  247.         final int l2 = v2.getDimension();
  248.         data = new double[l1 + l2];
  249.         System.arraycopy(v1, 0, data, 0, l1);
  250.         System.arraycopy(v2.data, 0, data, l1, l2);
  251.     }

  252.     /**
  253.      * Construct a vector by appending one vector to another vector.
  254.      * @param v1 first vector (will be put in front of the new vector)
  255.      * @param v2 second vector (will be put at back of the new vector)
  256.      */
  257.     public ArrayRealVector(double[] v1, double[] v2) {
  258.         final int l1 = v1.length;
  259.         final int l2 = v2.length;
  260.         data = new double[l1 + l2];
  261.         System.arraycopy(v1, 0, data, 0, l1);
  262.         System.arraycopy(v2, 0, data, l1, l2);
  263.     }

  264.     /** {@inheritDoc} */
  265.     @Override
  266.     public ArrayRealVector copy() {
  267.         return new ArrayRealVector(this, true);
  268.     }

  269.     /** {@inheritDoc} */
  270.     @Override
  271.     public ArrayRealVector add(RealVector v)
  272.         throws MathIllegalArgumentException {
  273.         if (v instanceof ArrayRealVector) {
  274.             final double[] vData = ((ArrayRealVector) v).data;
  275.             final int dim = vData.length;
  276.             checkVectorDimensions(dim);
  277.             ArrayRealVector result = new ArrayRealVector(dim);
  278.             double[] resultData = result.data;
  279.             for (int i = 0; i < dim; i++) {
  280.                 resultData[i] = data[i] + vData[i];
  281.             }
  282.             return result;
  283.         } else {
  284.             checkVectorDimensions(v);
  285.             double[] out = data.clone();
  286.             Iterator<Entry> it = v.iterator();
  287.             while (it.hasNext()) {
  288.                 final Entry e = it.next();
  289.                 out[e.getIndex()] += e.getValue();
  290.             }
  291.             return new ArrayRealVector(out, false);
  292.         }
  293.     }

  294.     /** {@inheritDoc} */
  295.     @Override
  296.     public ArrayRealVector subtract(RealVector v)
  297.         throws MathIllegalArgumentException {
  298.         if (v instanceof ArrayRealVector) {
  299.             final double[] vData = ((ArrayRealVector) v).data;
  300.             final int dim = vData.length;
  301.             checkVectorDimensions(dim);
  302.             ArrayRealVector result = new ArrayRealVector(dim);
  303.             double[] resultData = result.data;
  304.             for (int i = 0; i < dim; i++) {
  305.                 resultData[i] = data[i] - vData[i];
  306.             }
  307.             return result;
  308.         } else {
  309.             checkVectorDimensions(v);
  310.             double[] out = data.clone();
  311.             Iterator<Entry> it = v.iterator();
  312.             while (it.hasNext()) {
  313.                 final Entry e = it.next();
  314.                 out[e.getIndex()] -= e.getValue();
  315.             }
  316.             return new ArrayRealVector(out, false);
  317.         }
  318.     }

  319.     /** {@inheritDoc} */
  320.     @Override
  321.     public ArrayRealVector map(UnivariateFunction function) {
  322.         return copy().mapToSelf(function);
  323.     }

  324.     /** {@inheritDoc} */
  325.     @Override
  326.     public ArrayRealVector mapToSelf(UnivariateFunction function) {
  327.         for (int i = 0; i < data.length; i++) {
  328.             data[i] = function.value(data[i]);
  329.         }
  330.         return this;
  331.     }

  332.     /** {@inheritDoc} */
  333.     @Override
  334.     public RealVector mapAddToSelf(double d) {
  335.         for (int i = 0; i < data.length; i++) {
  336.             data[i] += d;
  337.         }
  338.         return this;
  339.     }

  340.     /** {@inheritDoc} */
  341.     @Override
  342.     public RealVector mapSubtractToSelf(double d) {
  343.         for (int i = 0; i < data.length; i++) {
  344.             data[i] -= d;
  345.         }
  346.         return this;
  347.     }

  348.     /** {@inheritDoc} */
  349.     @Override
  350.     public RealVector mapMultiplyToSelf(double d) {
  351.         for (int i = 0; i < data.length; i++) {
  352.             data[i] *= d;
  353.         }
  354.         return this;
  355.     }

  356.     /** {@inheritDoc} */
  357.     @Override
  358.     public RealVector mapDivideToSelf(double d) {
  359.         for (int i = 0; i < data.length; i++) {
  360.             data[i] /= d;
  361.         }
  362.         return this;
  363.     }

  364.     /** {@inheritDoc} */
  365.     @Override
  366.     public ArrayRealVector ebeMultiply(RealVector v)
  367.         throws MathIllegalArgumentException {
  368.         if (v instanceof ArrayRealVector) {
  369.             final double[] vData = ((ArrayRealVector) v).data;
  370.             final int dim = vData.length;
  371.             checkVectorDimensions(dim);
  372.             ArrayRealVector result = new ArrayRealVector(dim);
  373.             double[] resultData = result.data;
  374.             for (int i = 0; i < dim; i++) {
  375.                 resultData[i] = data[i] * vData[i];
  376.             }
  377.             return result;
  378.         } else {
  379.             checkVectorDimensions(v);
  380.             double[] out = data.clone();
  381.             for (int i = 0; i < data.length; i++) {
  382.                 out[i] *= v.getEntry(i);
  383.             }
  384.             return new ArrayRealVector(out, false);
  385.         }
  386.     }

  387.     /** {@inheritDoc} */
  388.     @Override
  389.     public ArrayRealVector ebeDivide(RealVector v)
  390.         throws MathIllegalArgumentException {
  391.         if (v instanceof ArrayRealVector) {
  392.             final double[] vData = ((ArrayRealVector) v).data;
  393.             final int dim = vData.length;
  394.             checkVectorDimensions(dim);
  395.             ArrayRealVector result = new ArrayRealVector(dim);
  396.             double[] resultData = result.data;
  397.             for (int i = 0; i < dim; i++) {
  398.                 resultData[i] = data[i] / vData[i];
  399.             }
  400.             return result;
  401.         } else {
  402.             checkVectorDimensions(v);
  403.             double[] out = data.clone();
  404.             for (int i = 0; i < data.length; i++) {
  405.                 out[i] /= v.getEntry(i);
  406.             }
  407.             return new ArrayRealVector(out, false);
  408.         }
  409.     }

  410.     /**
  411.      * Get a reference to the underlying data array.
  412.      * This method does not make a fresh copy of the underlying data.
  413.      *
  414.      * @return the array of entries.
  415.      */
  416.     public double[] getDataRef() {
  417.         return data; // NOPMD - returning an internal array is intentional and documented here
  418.     }

  419.     /** {@inheritDoc} */
  420.     @Override
  421.     public double dotProduct(RealVector v) throws MathIllegalArgumentException {
  422.         if (v instanceof ArrayRealVector) {
  423.             final double[] vData = ((ArrayRealVector) v).data;
  424.             checkVectorDimensions(vData.length);
  425.             double dot = 0;
  426.             for (int i = 0; i < data.length; i++) {
  427.                 dot += data[i] * vData[i];
  428.             }
  429.             return dot;
  430.         }
  431.         return super.dotProduct(v);
  432.     }

  433.     /** {@inheritDoc} */
  434.     @Override
  435.     public double getNorm() {
  436.         double sum = 0;
  437.         for (double a : data) {
  438.             sum += a * a;
  439.         }
  440.         return FastMath.sqrt(sum);
  441.     }

  442.     /** {@inheritDoc} */
  443.     @Override
  444.     public double getL1Norm() {
  445.         double sum = 0;
  446.         for (double a : data) {
  447.             sum += FastMath.abs(a);
  448.         }
  449.         return sum;
  450.     }

  451.     /** {@inheritDoc} */
  452.     @Override
  453.     public double getLInfNorm() {
  454.         double max = 0;
  455.         for (double a : data) {
  456.             max = FastMath.max(max, FastMath.abs(a));
  457.         }
  458.         return max;
  459.     }

  460.     /** {@inheritDoc} */
  461.     @Override
  462.     public double getDistance(RealVector v) throws MathIllegalArgumentException {
  463.         if (v instanceof ArrayRealVector) {
  464.             final double[] vData = ((ArrayRealVector) v).data;
  465.             checkVectorDimensions(vData.length);
  466.             double sum = 0;
  467.             for (int i = 0; i < data.length; ++i) {
  468.                 final double delta = data[i] - vData[i];
  469.                 sum += delta * delta;
  470.             }
  471.             return FastMath.sqrt(sum);
  472.         } else {
  473.             checkVectorDimensions(v);
  474.             double sum = 0;
  475.             for (int i = 0; i < data.length; ++i) {
  476.                 final double delta = data[i] - v.getEntry(i);
  477.                 sum += delta * delta;
  478.             }
  479.             return FastMath.sqrt(sum);
  480.         }
  481.     }

  482.     /** {@inheritDoc} */
  483.     @Override
  484.     public double getL1Distance(RealVector v)
  485.         throws MathIllegalArgumentException {
  486.         if (v instanceof ArrayRealVector) {
  487.             final double[] vData = ((ArrayRealVector) v).data;
  488.             checkVectorDimensions(vData.length);
  489.             double sum = 0;
  490.             for (int i = 0; i < data.length; ++i) {
  491.                 final double delta = data[i] - vData[i];
  492.                 sum += FastMath.abs(delta);
  493.             }
  494.             return sum;
  495.         } else {
  496.             checkVectorDimensions(v);
  497.             double sum = 0;
  498.             for (int i = 0; i < data.length; ++i) {
  499.                 final double delta = data[i] - v.getEntry(i);
  500.                 sum += FastMath.abs(delta);
  501.             }
  502.             return sum;
  503.         }
  504.     }

  505.     /** {@inheritDoc} */
  506.     @Override
  507.     public double getLInfDistance(RealVector v)
  508.         throws MathIllegalArgumentException {
  509.         if (v instanceof ArrayRealVector) {
  510.             final double[] vData = ((ArrayRealVector) v).data;
  511.             checkVectorDimensions(vData.length);
  512.             double max = 0;
  513.             for (int i = 0; i < data.length; ++i) {
  514.                 final double delta = data[i] - vData[i];
  515.                 max = FastMath.max(max, FastMath.abs(delta));
  516.             }
  517.             return max;
  518.         } else {
  519.             checkVectorDimensions(v);
  520.             double max = 0;
  521.             for (int i = 0; i < data.length; ++i) {
  522.                 final double delta = data[i] - v.getEntry(i);
  523.                 max = FastMath.max(max, FastMath.abs(delta));
  524.             }
  525.             return max;
  526.         }
  527.     }

  528.     /** {@inheritDoc} */
  529.     @Override
  530.     public RealMatrix outerProduct(RealVector v) {
  531.         if (v instanceof ArrayRealVector) {
  532.             final double[] vData = ((ArrayRealVector) v).data;
  533.             final int m = data.length;
  534.             final int n = vData.length;
  535.             final RealMatrix out = MatrixUtils.createRealMatrix(m, n);
  536.             for (int i = 0; i < m; i++) {
  537.                 for (int j = 0; j < n; j++) {
  538.                     out.setEntry(i, j, data[i] * vData[j]);
  539.                 }
  540.             }
  541.             return out;
  542.         } else {
  543.             final int m = data.length;
  544.             final int n = v.getDimension();
  545.             final RealMatrix out = MatrixUtils.createRealMatrix(m, n);
  546.             for (int i = 0; i < m; i++) {
  547.                 for (int j = 0; j < n; j++) {
  548.                     out.setEntry(i, j, data[i] * v.getEntry(j));
  549.                 }
  550.             }
  551.             return out;
  552.         }
  553.     }

  554.     /** {@inheritDoc} */
  555.     @Override
  556.     public double getEntry(int index) throws MathIllegalArgumentException {
  557.         try {
  558.             return data[index];
  559.         } catch (IndexOutOfBoundsException e) {
  560.             throw new MathIllegalArgumentException(e, LocalizedCoreFormats.INDEX, index, 0, getDimension() - 1);
  561.         }
  562.     }

  563.     /** {@inheritDoc} */
  564.     @Override
  565.     public int getDimension() {
  566.         return data.length;
  567.     }

  568.     /** {@inheritDoc} */
  569.     @Override
  570.     public RealVector append(RealVector v) {
  571.         if (v instanceof ArrayRealVector) {
  572.             return new ArrayRealVector(this, (ArrayRealVector) v);
  573.         } else {
  574.             return new ArrayRealVector(this, v);
  575.         }
  576.     }

  577.     /**
  578.      * Construct a vector by appending a vector to this vector.
  579.      *
  580.      * @param v Vector to append to this one.
  581.      * @return a new vector.
  582.      */
  583.     public ArrayRealVector append(ArrayRealVector v) {
  584.         return new ArrayRealVector(this, v);
  585.     }

  586.     /** {@inheritDoc} */
  587.     @Override
  588.     public RealVector append(double in) {
  589.         final double[] out = new double[data.length + 1];
  590.         System.arraycopy(data, 0, out, 0, data.length);
  591.         out[data.length] = in;
  592.         return new ArrayRealVector(out, false);
  593.     }

  594.     /** {@inheritDoc} */
  595.     @Override
  596.     public RealVector getSubVector(int index, int n)
  597.         throws MathIllegalArgumentException {
  598.         if (n < 0) {
  599.             throw new MathIllegalArgumentException(LocalizedCoreFormats.NUMBER_OF_ELEMENTS_SHOULD_BE_POSITIVE, n);
  600.         }
  601.         ArrayRealVector out = new ArrayRealVector(n);
  602.         try {
  603.             System.arraycopy(data, index, out.data, 0, n);
  604.         } catch (IndexOutOfBoundsException e) {
  605.             checkIndex(index);
  606.             checkIndex(index + n - 1);
  607.         }
  608.         return out;
  609.     }

  610.     /** {@inheritDoc} */
  611.     @Override
  612.     public void setEntry(int index, double value) throws MathIllegalArgumentException {
  613.         try {
  614.             data[index] = value;
  615.         } catch (IndexOutOfBoundsException e) {
  616.             checkIndex(index);
  617.         }
  618.     }

  619.     /** {@inheritDoc} */
  620.     @Override
  621.     public void addToEntry(int index, double increment)
  622.         throws MathIllegalArgumentException {
  623.         try {
  624.         data[index] += increment;
  625.         } catch(IndexOutOfBoundsException e){
  626.             throw new MathIllegalArgumentException(e, LocalizedCoreFormats.INDEX, index, 0, data.length - 1);
  627.         }
  628.     }

  629.     /** {@inheritDoc} */
  630.     @Override
  631.     public void setSubVector(int index, RealVector v)
  632.         throws MathIllegalArgumentException {
  633.         if (v instanceof ArrayRealVector) {
  634.             setSubVector(index, ((ArrayRealVector) v).data);
  635.         } else {
  636.             try {
  637.                 for (int i = index; i < index + v.getDimension(); ++i) {
  638.                     data[i] = v.getEntry(i - index);
  639.                 }
  640.             } catch (IndexOutOfBoundsException e) {
  641.                 checkIndex(index);
  642.                 checkIndex(index + v.getDimension() - 1);
  643.             }
  644.         }
  645.     }

  646.     /**
  647.      * Set a set of consecutive elements.
  648.      *
  649.      * @param index Index of first element to be set.
  650.      * @param v Vector containing the values to set.
  651.      * @throws MathIllegalArgumentException if the index is inconsistent with the vector
  652.      * size.
  653.      */
  654.     public void setSubVector(int index, double[] v)
  655.         throws MathIllegalArgumentException {
  656.         try {
  657.             System.arraycopy(v, 0, data, index, v.length);
  658.         } catch (IndexOutOfBoundsException e) {
  659.             checkIndex(index);
  660.             checkIndex(index + v.length - 1);
  661.         }
  662.     }

  663.     /** {@inheritDoc} */
  664.     @Override
  665.     public void set(double value) {
  666.         Arrays.fill(data, value);
  667.     }

  668.     /** {@inheritDoc} */
  669.     @Override
  670.     public double[] toArray(){
  671.         return data.clone();
  672.     }

  673.     /** {@inheritDoc} */
  674.     @Override
  675.     public String toString(){
  676.         return DEFAULT_FORMAT.format(this);
  677.     }

  678.     /**
  679.      * Check if instance and specified vectors have the same dimension.
  680.      *
  681.      * @param v Vector to compare instance with.
  682.      * @throws MathIllegalArgumentException if the vectors do not
  683.      * have the same dimension.
  684.      */
  685.     @Override
  686.     protected void checkVectorDimensions(RealVector v)
  687.         throws MathIllegalArgumentException {
  688.         checkVectorDimensions(v.getDimension());
  689.     }

  690.     /**
  691.      * Check if instance dimension is equal to some expected value.
  692.      *
  693.      * @param n Expected dimension.
  694.      * @throws MathIllegalArgumentException if the dimension is
  695.      * inconsistent with vector size.
  696.      */
  697.     @Override
  698.     protected void checkVectorDimensions(int n)
  699.         throws MathIllegalArgumentException {
  700.         if (data.length != n) {
  701.             throw new MathIllegalArgumentException(LocalizedCoreFormats.DIMENSIONS_MISMATCH,
  702.                                                    data.length, n);
  703.         }
  704.     }

  705.     /**
  706.      * Check if any coordinate of this vector is {@code NaN}.
  707.      *
  708.      * @return {@code true} if any coordinate of this vector is {@code NaN},
  709.      * {@code false} otherwise.
  710.      */
  711.     @Override
  712.     public boolean isNaN() {
  713.         for (double v : data) {
  714.             if (Double.isNaN(v)) {
  715.                 return true;
  716.             }
  717.         }
  718.         return false;
  719.     }

  720.     /**
  721.      * Check whether any coordinate of this vector is infinite and none
  722.      * are {@code NaN}.
  723.      *
  724.      * @return {@code true} if any coordinate of this vector is infinite and
  725.      * none are {@code NaN}, {@code false} otherwise.
  726.      */
  727.     @Override
  728.     public boolean isInfinite() {
  729.         if (isNaN()) {
  730.             return false;
  731.         }

  732.         for (double v : data) {
  733.             if (Double.isInfinite(v)) {
  734.                 return true;
  735.             }
  736.         }

  737.         return false;
  738.     }

  739.     /** {@inheritDoc} */
  740.     @Override
  741.     public boolean equals(Object other) {
  742.         if (this == other) {
  743.             return true;
  744.         }

  745.         if (!(other instanceof RealVector)) {
  746.             return false;
  747.         }

  748.         RealVector rhs = (RealVector) other;
  749.         if (data.length != rhs.getDimension()) {
  750.             return false;
  751.         }

  752.         if (rhs.isNaN()) {
  753.             return this.isNaN();
  754.         }

  755.         for (int i = 0; i < data.length; ++i) {
  756.             if (data[i] != rhs.getEntry(i)) {
  757.                 return false;
  758.             }
  759.         }
  760.         return true;
  761.     }

  762.     /**
  763.      * {@inheritDoc} All {@code NaN} values have the same hash code.
  764.      */
  765.     @Override
  766.     public int hashCode() {
  767.         if (isNaN()) {
  768.             return 9;
  769.         }
  770.         return MathUtils.hash(data);
  771.     }

  772.     /** {@inheritDoc} */
  773.     @Override
  774.     public ArrayRealVector combine(double a, double b, RealVector y)
  775.         throws MathIllegalArgumentException {
  776.         return copy().combineToSelf(a, b, y);
  777.     }

  778.     /** {@inheritDoc} */
  779.     @Override
  780.     public ArrayRealVector combineToSelf(double a, double b, RealVector y)
  781.         throws MathIllegalArgumentException {
  782.         if (y instanceof ArrayRealVector) {
  783.             final double[] yData = ((ArrayRealVector) y).data;
  784.             checkVectorDimensions(yData.length);
  785.             for (int i = 0; i < this.data.length; i++) {
  786.                 data[i] = a * data[i] + b * yData[i];
  787.             }
  788.         } else {
  789.             checkVectorDimensions(y);
  790.             for (int i = 0; i < this.data.length; i++) {
  791.                 data[i] = a * data[i] + b * y.getEntry(i);
  792.             }
  793.         }
  794.         return this;
  795.     }

  796.     /** {@inheritDoc} */
  797.     @Override
  798.     public double walkInDefaultOrder(final RealVectorPreservingVisitor visitor) {
  799.         visitor.start(data.length, 0, data.length - 1);
  800.         for (int i = 0; i < data.length; i++) {
  801.             visitor.visit(i, data[i]);
  802.         }
  803.         return visitor.end();
  804.     }

  805.     /** {@inheritDoc} */
  806.     @Override
  807.     public double walkInDefaultOrder(final RealVectorPreservingVisitor visitor,
  808.         final int start, final int end) throws MathIllegalArgumentException {
  809.         checkIndices(start, end);
  810.         visitor.start(data.length, start, end);
  811.         for (int i = start; i <= end; i++) {
  812.             visitor.visit(i, data[i]);
  813.         }
  814.         return visitor.end();
  815.     }

  816.     /**
  817.      * {@inheritDoc}
  818.      *
  819.      * In this implementation, the optimized order is the default order.
  820.      */
  821.     @Override
  822.     public double walkInOptimizedOrder(final RealVectorPreservingVisitor visitor) {
  823.         return walkInDefaultOrder(visitor);
  824.     }

  825.     /**
  826.      * {@inheritDoc}
  827.      *
  828.      * In this implementation, the optimized order is the default order.
  829.      */
  830.     @Override
  831.     public double walkInOptimizedOrder(final RealVectorPreservingVisitor visitor,
  832.         final int start, final int end) throws MathIllegalArgumentException {
  833.         return walkInDefaultOrder(visitor, start, end);
  834.     }

  835.     /** {@inheritDoc} */
  836.     @Override
  837.     public double walkInDefaultOrder(final RealVectorChangingVisitor visitor) {
  838.         visitor.start(data.length, 0, data.length - 1);
  839.         for (int i = 0; i < data.length; i++) {
  840.             data[i] = visitor.visit(i, data[i]);
  841.         }
  842.         return visitor.end();
  843.     }

  844.     /** {@inheritDoc} */
  845.     @Override
  846.     public double walkInDefaultOrder(final RealVectorChangingVisitor visitor,
  847.         final int start, final int end) throws MathIllegalArgumentException {
  848.         checkIndices(start, end);
  849.         visitor.start(data.length, start, end);
  850.         for (int i = start; i <= end; i++) {
  851.             data[i] = visitor.visit(i, data[i]);
  852.         }
  853.         return visitor.end();
  854.     }

  855.     /**
  856.      * {@inheritDoc}
  857.      *
  858.      * In this implementation, the optimized order is the default order.
  859.      */
  860.     @Override
  861.     public double walkInOptimizedOrder(final RealVectorChangingVisitor visitor) {
  862.         return walkInDefaultOrder(visitor);
  863.     }

  864.     /**
  865.      * {@inheritDoc}
  866.      *
  867.      * In this implementation, the optimized order is the default order.
  868.      */
  869.     @Override
  870.     public double walkInOptimizedOrder(final RealVectorChangingVisitor visitor,
  871.         final int start, final int end) throws MathIllegalArgumentException {
  872.         return walkInDefaultOrder(visitor, start, end);
  873.     }
  874. }