[ 
https://issues.apache.org/jira/browse/NUMBERS-155?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17361819#comment-17361819
 ] 

Alex Herbert commented on NUMBERS-155:
--------------------------------------

Re: Triangle array.

I have a class that implements an API as a helper to generate indices into an 
index of a upper triangular array. I wrote this to store all-vs-all comparison 
matrices. Thus it does not support i==j as the self-comparison score is known.

It suited my use case. But I think it could be modified to support the i==j 
index. I cannot remember if I worked out the indexing math or copied it. The 
methods are below. The reverse method has a sqrt so will not be fast.
{code:java}
/**
 * Convert from ij to linear index.  Index j must be greater than i.
 *
 * <p>Behaviour is undefined if i==j.
 *
 * @param n the size of the array in 1 dimension
 * @param i the index i
 * @param j the index j
 * @return the linear index
 */
public static int toIndex(int n, int i, int j) {
  return (n * (n - 1) / 2) - (n - i) * ((n - i) - 1) / 2 + j - i - 1;
}

/**
 * Convert from linear index to ij.
 *
 * @param n the size of the array in 1 dimension (total length = n*(n-1)/2) 
 * @param k the linear index (Must be with the bound 0:length-1)
 * @param ij the ij data (Must be size 2 or greater)
 */
public static void fromIndex(int n, int k, int[] ij) {
  final int i = n - 2 - (int) Math.floor(Math.sqrt(-8.0 * k + 4 * n * (n - 1) - 
7) / 2.0 - 0.5);
  ij[0] = i;
  ij[1] = k + i + 1 - (n * (n - 1) / 2) + (n - i) * ((n - i) - 1) / 2;
}
{code}
This was all in a class that could precompute some values and provided methods 
for fast iteration over rows or columns by initialising the row/column then 
outputting the indices in a separate call to be used in a loop.

What type of API do you want? A simple version is:
{code:java}
// Upper or lower triangle
TriangularArrayIndex index = TriangularArrayIndex.of(n, true);
double[] data = new double[index.size()];
for (int i = 0; i < n; i++) {
  // Upper
  for (int j = i; j < n; j++) {
    data[index.get(i, j)] = i * j;
  }
}

TriangularArrayIndex index = TriangularArrayIndex.of(n, false);
double[] data = new double[index.size()];
for (int i = 0; i < n; i++) {
  // Lower
  for (int j = 0; j <= i; j++) {
    data[index.get(i, j)] = i * j;
  }
}
{code}

> About modules "arrays" and "rootfinder"
> ---------------------------------------
>
>                 Key: NUMBERS-155
>                 URL: https://issues.apache.org/jira/browse/NUMBERS-155
>             Project: Commons Numbers
>          Issue Type: Task
>          Components: arrays, core
>    Affects Versions: 1.0-beta1
>            Reporter: Gilles Sadowski
>            Priority: Major
>              Labels: refactoring
>             Fix For: 1.0
>
>
> Shouldn't some functionality currently in module {{commons-numbers-arrays}} 
> be moved to {{commons-number-core}}?
> Rationale is that the utilities focus on extended precision of some 
> computations (on numbers that happen to be stored in an array).
> Wouldn't the Brent solver (in module {{commons-numbers-rootfinder}}) benefit 
> from a version based on the new {{ExtendedPrecision}} class?



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to