private static void FindBestUnbalancedHaarDecomposition(double[] x, List<List<double>> tree, double smooth)
{
ulong n = (ulong)x.Length;
tree.Clear();
List<double> branch = new List<double>();
branch.Add(0);
branch.Add(0);
branch.Add(0);
branch.Add(0);
branch.Add(0);
branch[0] = 1;
double[] ipi = new double[x.Length - 1];
GetInnerProdIter(x, ipi);
int ind_max = GetInnerProdMax(x);
branch[2] = 1;
branch[3] = ind_max;
branch[4] = n;
branch[1] = ipi[ind_max - 1];
tree.Add(new List<double>());
for (int i = 0; i < (int)branch.Count(); i++)
{
tree[0].Add(branch[i]);
}
int j = 0;
double bpSum = 0;
for (int i = 0; i < (int)Math.Floor((double)tree[j].Count() / 5); i++)
{
bpSum += tree[j][5 + i * 5 - 1] - tree[j][3 + i * 5 - 1] - 1.0;
}
while (bpSum != 0)
{
int no_parent_coeffs = (int)Math.Floor((double)tree[j].Count() / 5);
int no_child_coeffs = 0;
for (int i = 0; i < no_parent_coeffs; i++)
{
if (tree[j][4 + 5 * i - 1] - tree[j][3 + 5 * i - 1] >= 1)
{
no_child_coeffs++;
if (tree.Count() == j + 1)
{
tree.Add(new List<double>() { 0, 0, 0, 0, 0 });
}
else
{
for (uint k = 0; k < 5; k++) tree[j + 1].Add(0);
}
tree[j + 1][1 + 5 * (no_child_coeffs - 1) - 1] = 2 * tree[j][1 + 5 * i - 1] - 1;
int skip = (int)tree[j][i * 5 + 3 - 1] - 1;
int take = (int)tree[j][i * 5 + 4 - 1] - skip;
double[] subX = new double[take];
Array.Copy(x, skip, subX, 0, take);
Array.Clear(ipi, 0, ipi.Length);
Array.Resize(ref ipi, subX.Length - 1);
GetInnerProdIter(subX, ipi);
ind_max = GetInnerProdMax(subX);
tree[j + 1][(no_child_coeffs - 1) * 5 + 2 - 1] = ipi[ind_max - 1];
tree[j + 1][(no_child_coeffs - 1) * 5 + 3 - 1] = tree[j][i * 5 + 3 - 1];
tree[j + 1][(no_child_coeffs - 1) * 5 + 5 - 1] = tree[j][i * 5 + 4 - 1];
tree[j + 1][(no_child_coeffs - 1) * 5 + 4 - 1] = ind_max + tree[j][i * 5 + 3 - 1] - 1;
} //end if (tree.at(j)[4+5*(i-1)-1]-tree.at(j)[3+5*(i-1)-1]>=1) {
if (tree[j][i * 5 + 5 - 1] - tree[j][i * 5 + 4 - 1] >= 2)
{
no_child_coeffs++;
if (tree.Count() == j + 1)
{
tree.Add(new List<double>() { 0, 0, 0, 0, 0 });
}
else
{
for (uint k = 0; k < 5; k++) tree[j + 1].Add(0);
}
tree[j + 1][1 + 5 * (no_child_coeffs - 1) - 1] = 2 * tree[j][1 + 5 * i - 1];
int skip = (int)tree[j][i * 5 + 4 - 1];
int take = (int)tree[j][i * 5 + 5 - 1] - skip;
double[] subX = new double[take];
Array.Copy(x, skip, subX, 0, take);
Array.Clear(ipi, 0, ipi.Length);
Array.Resize(ref ipi, subX.Length - 1);
GetInnerProdIter(subX, ipi);
ind_max = GetInnerProdMax(subX);
tree[j + 1][(no_child_coeffs - 1) * 5 + 2 - 1] = ipi[ind_max - 1];
tree[j + 1][(no_child_coeffs - 1) * 5 + 3 - 1] = tree[j][i * 5 + 4 - 1] + 1;
tree[j + 1][(no_child_coeffs - 1) * 5 + 5 - 1] = tree[j][i * 5 + 5 - 1];
tree[j + 1][(no_child_coeffs - 1) * 5 + 4 - 1] = ind_max + tree[j][i * 5 + 4 - 1];
}
}
j++;
bpSum = 0;
for (int k = 0; k < (int)Math.Floor((double)tree[j].Count() / 5); k++)
{
bpSum += tree[j][5 + k * 5 - 1] - tree[j][3 + k * 5 - 1] - 1;
}
} //while 1
smooth = 0;
for (uint i = 0; i < n; i++) smooth += x[i];
smooth = smooth / Math.Sqrt(n);
}