All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.barrybecker4.math.multiarray.MultiDimensionalIndexer.scala Maven / Gradle / Ivy

The newest version!
/* Copyright by Barry G. Becker, 2000-2018. Licensed under MIT License: http://www.opensource.org/licenses/MIT */
package com.barrybecker4.math.multiarray

import java.util


/**
  * Provide support for indexing into high dimensional arrays.
  * It does not actually allocate memory for the large dimensional array. That is up to the client app to manage.
  * Can be used to create an arbitrarily sized array of > 1 dimension.
  *
  * @author Barry Becker
  */
class MultiDimensionalIndexer(val dimensions: Array[Int]) {

  /** the size of each dimension in the multi-dim array. */
  final private val dims: Array[Int] = dimensions.clone
  /** the number of dimensions. May be any number  >= 0. */
  final private val numDims: Int = this.dims.length

  /** product of number of dimensions. All dimensions multiplied together. */
  final private val numVals: Long = getDimensionProduct
  if (numDims <= 0)
    throw new IllegalArgumentException("You must have > 0 dimension to use this class")
  if (numVals <= 0)
    throw new IllegalArgumentException("The product of the dimension lengths must be greater than 0. It was " + numVals)

  def getNumDims: Int = numDims

  /** @return the total number of values in the hypothetical array*/
  def getNumValues: Long = numVals

  /** @return the product of the first n dimensions. returns 1 if n is 0 */
  private def getDimensionProduct: Int = dims.product

  /** @param index n dimensional array of indices.
    * @return raw integer index from a integer array of indices.
    */
  def getRawIndex(index: Array[Int]): Int = {
    assert(index.length == numDims,
      "the index you specified has " + index.length + " values, when you need to specify " + numDims)
    var rawIndex: Int = index(numDims - 1)
    var offset: Int = dims(numDims - 1)
    for (i <- numDims - 2 to 0 by -1) {
      rawIndex += offset * index(i)
      offset *= dims(i)
    }
    rawIndex
  }

  /** @param rawIndex the raw integer index to convert to an array of int indices.
    * @return an integer array of indices from a raw integer index.
    */
  def getIndexFromRaw(rawIndex: Int): Array[Int] = {
    val index: Array[Int] = new Array[Int](numDims)
    var prod: Int = 1
    for (i <- numDims - 1 to 0 by -1) {
      index(i) = rawIndex / prod % dims(i)
      if (i > 0) prod *= dims(i)
    }
    index
  }

  /** @param rawIndex raw index
    * @return a string representation of the tuple. e.g. "3,5,9,3"
    */
  def getIndexKey(rawIndex: Int): String = {
    val index: Array[Int] = getIndexFromRaw(rawIndex)
    util.Arrays.toString(index)
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy