using System;
namespace Legalsoft.Truffer
{
public class Indexx
{
public int n { get; set; } = 0;
public int[] indx;
public Indexx()
{
}
public Indexx(double[] arr)
{
index(arr, arr.Length);
}
public void sort(double[] brr)
{
if (brr.Length != n)
{
throw new Exception("bad size in Index sort");
}
double[] tmp = Globals.CopyFrom(brr);
for (int j = 0; j < n; j++)
{
brr[j] = tmp[indx[j]];
}
}
public void sort(int[] brr)
{
if (brr.Length != n)
{
throw new Exception("bad size in Index sort");
}
int[] tmp = Globals.CopyFrom(brr);
for (int j = 0; j < n; j++)
{
brr[j] = tmp[indx[j]];
}
}
public double el(double[] brr, int j)
{
return brr[indx[j]];
}
public int el(int[] brr, int j)
{
return brr[indx[j]];
}
public void setEl(int[] brr, int j, int v)
{
brr[indx[j]] = v;
}
public void setEl(double[] brr, int j, double v)
{
brr[indx[j]] = v;
}
public void rank(int[] irank)
{
irank = new int[n];
for (int j = 0; j < n; j++)
{
irank[indx[j]] = j;
}
}
public void index(double[] arr, int nn)
{
const int M = 7;
const int NSTACK = 64;
int jstack = -1;
int[] istack = new int[NSTACK];
n = nn;
indx = new int[n];
int ir = n - 1;
for (int j = 0; j < n; j++)
{
indx[j] = j;
}
int l = 0;
for (; ; )
{
if (ir - l < M)
{
for (int j = l + 1; j <= ir; j++)
{
int indxt = indx[j];
double a = arr[indxt];
int i = j - 1;
for (; i >= l; i--)
{
if (arr[indx[i]] <= a)
{
break;
}
indx[i + 1] = indx[i];
}
indx[i + 1] = indxt;
}
if (jstack < 0)
{
break;
}
ir = istack[jstack--];
l = istack[jstack--];
}
else
{
int k = (l + ir) >> 1;
Globals.SWAP(ref indx[k], ref indx[l + 1]);
if (arr[indx[l]] > arr[indx[ir]])
{
Globals.SWAP(ref indx[l], ref indx[ir]);
}
if (arr[indx[l + 1]] > arr[indx[ir]])
{
Globals.SWAP(ref indx[l + 1], ref indx[ir]);
}
if (arr[indx[l]] > arr[indx[l + 1]])
{
Globals.SWAP(ref indx[l], ref indx[l + 1]);
}
int i = l + 1;
int j = ir;
int indxt = indx[l + 1];
double a = arr[indxt];
for (; ; )
{
do
{
i++;
} while (arr[indx[i]] < a);
do
{
j--;
} while (arr[indx[j]] > a);
if (j < i)
{
break;
}
Globals.SWAP(ref indx[i], ref indx[j]);
}
indx[l + 1] = indx[j];
indx[j] = indxt;
jstack += 2;
if (jstack >= NSTACK)
{
throw new Exception("NSTACK too small in index.");
}
if (ir - i + 1 >= j - l)
{
istack[jstack] = ir;
istack[jstack - 1] = i;
ir = j - 1;
}
else
{
istack[jstack] = j - 1;
istack[jstack - 1] = l;
l = i;
}
}
}
}
}
}