Class MutableDoubleRealVector

All Implemented Interfaces:
RealVector

public class MutableDoubleRealVector extends DoubleRealVector
Mutable double-precision vector. Extends DoubleRealVector with a set of explicit in-place mutation methods suffixed *This (addToThis(RealVector), subtractFromThis(RealVector), multiplyThisBy(double), normalizeThis(), zeroThis(), setData(double[])). Each writes through the receiver's existing storage and returns this, so they compose into chains without allocating.

The non-*This arithmetic methods inherited from DoubleRealVector (add, subtract, multiply, normalize, withData) are deliberately not overridden here — they continue to allocate fresh DoubleRealVector results and leave the receiver untouched. This split keeps the choice of mutation visible at every call site: v.add(w) always produces a new value; v.addToThis(w) always mutates v. A caller can therefore use the same MutableDoubleRealVector reference under both idioms without surprise.

Typical use is short-lived hot loops that reuse a single storage buffer — most prominently the centroid update in k-means, which zeros and then accumulates assigned vectors into the same instance once per Lloyd iteration. For values that must remain stable after construction, hand out toImmutable() (which copies into a fresh immutable DoubleRealVector) rather than the mutable reference itself.

Implementation notes worth knowing:

  • The parent class memoizes the hash code and the converted representations (DoubleRealVector.toHalfRealVector(), DoubleRealVector.toFloatRealVector(), AbstractRealVector.getRawData()). Mutation would invalidate those caches, so this class overrides each to recompute on every call.
  • toMutable() returns this (no copy) since the receiver is already mutable. Callers who need an independent buffer must explicitly construct a new instance over getData().clone().
  • toDoubleRealVector() also returns this, typed as MutableDoubleRealVector. Code that captures the result under a DoubleRealVector reference is still pointing at this mutable buffer; subsequent mutations will be visible through that reference.
  • Underlying storage is the same double[] held by AbstractRealVector.data; the double[] constructor stores the array by reference, and AbstractRealVector.getData() returns the live array. Mutation methods write directly through it, so any external alias of that array sees the changes.
  • Constructor Details

    • MutableDoubleRealVector

      public MutableDoubleRealVector(@Nonnull Double[] doubleData)
      Constructs a mutable vector from a boxed Double[]. The input is defensively copied into a fresh primitive array, so subsequent changes to doubleData do not affect the returned vector.
      Parameters:
      doubleData - the components of the new vector
    • MutableDoubleRealVector

      public MutableDoubleRealVector(@Nonnull double[] data)
      Constructs a mutable vector over the given primitive array. The array is stored by reference — the new vector reads and writes through it, and any external alias of data will see every subsequent mutation. Use data.clone() at the call site if you need an independent backing store.
      Parameters:
      data - the components of the new vector; ownership is shared with the caller per the aliasing contract above
    • MutableDoubleRealVector

      public MutableDoubleRealVector(@Nonnull int[] intData)
      Constructs a mutable vector by widening each int component to a double. The new vector owns its backing array — the input is read but not retained.
      Parameters:
      intData - the components of the new vector
    • MutableDoubleRealVector

      public MutableDoubleRealVector(@Nonnull long[] longData)
      Constructs a mutable vector by widening each long component to a double. The new vector owns its backing array — the input is read but not retained.
      Parameters:
      longData - the components of the new vector
  • Method Details

    • toHalfRealVector

      @Nonnull public HalfRealVector toHalfRealVector()
      Returns the memoized half-precision projection of this vector.

      Override note: the parent memoizes the half-precision projection because immutable vectors never change. This class's contents can change, so memoization would return stale values — every call recomputes from the current data.

      Specified by:
      toHalfRealVector in interface RealVector
      Overrides:
      toHalfRealVector in class DoubleRealVector
      Returns:
      a non-null HalfRealVector containing the Half precision floating-point representation of this object.
    • toFloatRealVector

      @Nonnull public FloatRealVector toFloatRealVector()
      Returns the memoized single-precision projection of this vector.

      Override note: same reasoning as toHalfRealVector() — recomputed on every call because the underlying data may have changed since the last invocation.

      Specified by:
      toFloatRealVector in interface RealVector
      Overrides:
      toFloatRealVector in class DoubleRealVector
      Returns:
      a non-null FloatRealVector containing the single precision floating-point representation of this object.
    • toDoubleRealVector

      @Nonnull public MutableDoubleRealVector toDoubleRealVector()
      Returns this, typed as MutableDoubleRealVector. No copy is made; the result shares storage with the receiver, so any subsequent mutation is visible through both references.
      Specified by:
      toDoubleRealVector in interface RealVector
      Overrides:
      toDoubleRealVector in class DoubleRealVector
      Returns:
      a non-null DoubleRealVector representation of this vector.
    • toMutable

      @Nonnull public MutableDoubleRealVector toMutable()
      Returns this — the receiver is already mutable, so no copy is made. Callers that need an independent mutable buffer should explicitly construct one over getData().clone().
      Returns:
      a fresh (or in the case of MutableDoubleRealVector, the same) mutable double-precision vector
    • toImmutable

      @Nonnull public DoubleRealVector toImmutable()
      Returns a snapshot of the current contents as a fresh immutable DoubleRealVector. The underlying double[] is cloned, so subsequent mutations of the receiver do not affect the returned value.
      Specified by:
      toImmutable in interface RealVector
      Overrides:
      toImmutable in class DoubleRealVector
      Returns:
      a non-null immutable vector with the same components as this vector
    • setData

      @Nonnull public MutableDoubleRealVector setData(@Nonnull double[] data)
      Replaces this vector's components with those of data (element-wise copy through the existing backing array). The receiver's storage is reused — no allocation — and data is read but not retained.
      Parameters:
      data - the new component values; must have the same length as this vector
      Returns:
      this for chaining
      Throws:
      IllegalArgumentException - if data.length does not match this vector's dimensionality
    • getRawData

      @Nonnull public byte[] getRawData()
      Gets the raw byte data representation of this object.

      This method provides a direct, unprocessed view of the object's underlying data. The format of the byte array is implementation-specific and should be documented by the concrete class that implements this method.

      Override note: the parent's memoized raw-bytes representation would be stale once any mutation happens; this override recomputes on every call.

      Specified by:
      getRawData in interface RealVector
      Overrides:
      getRawData in class AbstractRealVector
      Returns:
      a non-null byte array containing the raw data.
    • hashCode

      public int hashCode()
      Returns a hash code value for this object. The hash code is computed once and memoized.

      Override note: hash codes are intentionally not memoized for mutable vectors — mutation changes equality and therefore the hash. Treat mutable instances as unsuitable keys for hash-based collections while they might still be mutated; snapshot via toImmutable() before keying.

      Overrides:
      hashCode in class AbstractRealVector
      Returns:
      a hash code value for this object.
    • l2SquaredNorm

      public double l2SquaredNorm()
      Description copied from class: AbstractRealVector
      Returns the squared L2 norm Σ_i this[i]^2. Implementations typically memoize this since the value is reused by RealVector.l2Norm() and several distance helpers.

      Memoized via the l2SquaredNormSupplier so repeated calls — including the ones driving RealVector.l2Norm() — share a single computation.

      Specified by:
      l2SquaredNorm in interface RealVector
      Overrides:
      l2SquaredNorm in class AbstractRealVector
      Returns:
      the squared L2 norm of this vector
    • normalizeThis

      @Nonnull public MutableDoubleRealVector normalizeThis()
      Normalizes this vector to unit L2 norm in place.
      Returns:
      this for chaining
      Throws:
      IllegalArgumentException - if this vector's L2 norm is zero, infinite, or NaN
    • addToThis

      @Nonnull public MutableDoubleRealVector addToThis(@Nonnull RealVector other)
      Adds other to this vector component-wise, in place.
      Parameters:
      other - the vector to add; must have the same dimensionality as this vector
      Returns:
      this for chaining
    • addToThis

      @Nonnull public MutableDoubleRealVector addToThis(double scalar)
      Adds scalar to every component of this vector, in place.
      Parameters:
      scalar - the value to add to each component
      Returns:
      this for chaining
    • subtractFromThis

      @Nonnull public MutableDoubleRealVector subtractFromThis(@Nonnull RealVector other)
      Subtracts other from this vector component-wise, in place.
      Parameters:
      other - the vector to subtract; must have the same dimensionality as this vector
      Returns:
      this for chaining
    • subtractFromThis

      @Nonnull public MutableDoubleRealVector subtractFromThis(double scalar)
      Subtracts scalar from every component of this vector, in place.
      Parameters:
      scalar - the value to subtract from each component
      Returns:
      this for chaining
    • multiplyThisBy

      @Nonnull public MutableDoubleRealVector multiplyThisBy(double scalar)
      Multiplies every component of this vector by scalar, in place.
      Parameters:
      scalar - the factor to scale each component by
      Returns:
      this for chaining
    • zeroThis

      @CanIgnoreReturnValue @Nonnull public MutableDoubleRealVector zeroThis()
      Sets every component of this vector to zero, in place. The dimensionality is unchanged.
      Returns:
      this for chaining; the return is annotated CanIgnoreReturnValue because callers commonly reset state without consuming the result
    • zeroVector

      @Nonnull public static MutableDoubleRealVector zeroVector(int numDimensions)
      Returns a new mutable vector of the given dimensionality with all components set to zero.
      Parameters:
      numDimensions - number of dimensions; must be non-negative
      Returns:
      a freshly allocated zero vector
    • fromBytes

      @Nonnull public static MutableDoubleRealVector fromBytes(@Nonnull byte[] vectorBytes)
      Creates a MutableDoubleRealVector from the serialized form produced by AbstractRealVector.getRawData().

      The input is interpreted as a leading type byte followed by a sequence of 64-bit big-endian IEEE-754 doubles; each 8-byte run becomes one component of the resulting vector. The returned instance owns a fresh backing array; the byte array is read but not retained.

      Parameters:
      vectorBytes - the serialized form
      Returns:
      a new mutable vector with the decoded components