init commit
This commit is contained in:
336
output/Libraries/AForge.Math/AForge/Math/svd.cs
Normal file
336
output/Libraries/AForge.Math/AForge/Math/svd.cs
Normal file
@@ -0,0 +1,336 @@
|
||||
using System;
|
||||
|
||||
namespace AForge.Math;
|
||||
|
||||
internal class svd
|
||||
{
|
||||
public static void svdcmp(double[,] a, out double[] w, out double[,] v)
|
||||
{
|
||||
int length = a.GetLength(0);
|
||||
int length2 = a.GetLength(1);
|
||||
if (length < length2)
|
||||
{
|
||||
throw new ArgumentException("Number of rows in A must be greater or equal to number of columns");
|
||||
}
|
||||
w = new double[length2];
|
||||
v = new double[length2, length2];
|
||||
int num = 0;
|
||||
int num2 = 0;
|
||||
double[] array = new double[length2];
|
||||
double num5;
|
||||
double num4;
|
||||
double num3 = (num4 = (num5 = 0.0));
|
||||
for (int i = 0; i < length2; i++)
|
||||
{
|
||||
num = i + 1;
|
||||
array[i] = num4 * num3;
|
||||
double num6;
|
||||
num3 = (num6 = (num4 = 0.0));
|
||||
if (i < length)
|
||||
{
|
||||
for (int j = i; j < length; j++)
|
||||
{
|
||||
num4 += System.Math.Abs(a[j, i]);
|
||||
}
|
||||
if (num4 != 0.0)
|
||||
{
|
||||
for (int j = i; j < length; j++)
|
||||
{
|
||||
a[j, i] /= num4;
|
||||
num6 += a[j, i] * a[j, i];
|
||||
}
|
||||
double num7 = a[i, i];
|
||||
num3 = 0.0 - Sign(System.Math.Sqrt(num6), num7);
|
||||
double num8 = num7 * num3 - num6;
|
||||
a[i, i] = num7 - num3;
|
||||
if (i != length2 - 1)
|
||||
{
|
||||
for (int k = num; k < length2; k++)
|
||||
{
|
||||
num6 = 0.0;
|
||||
for (int j = i; j < length; j++)
|
||||
{
|
||||
num6 += a[j, i] * a[j, k];
|
||||
}
|
||||
num7 = num6 / num8;
|
||||
for (int j = i; j < length; j++)
|
||||
{
|
||||
a[j, k] += num7 * a[j, i];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int j = i; j < length; j++)
|
||||
{
|
||||
a[j, i] *= num4;
|
||||
}
|
||||
}
|
||||
}
|
||||
w[i] = num4 * num3;
|
||||
num3 = (num6 = (num4 = 0.0));
|
||||
if (i < length && i != length2 - 1)
|
||||
{
|
||||
for (int j = num; j < length2; j++)
|
||||
{
|
||||
num4 += System.Math.Abs(a[i, j]);
|
||||
}
|
||||
if (num4 != 0.0)
|
||||
{
|
||||
for (int j = num; j < length2; j++)
|
||||
{
|
||||
a[i, j] /= num4;
|
||||
num6 += a[i, j] * a[i, j];
|
||||
}
|
||||
double num7 = a[i, num];
|
||||
num3 = 0.0 - Sign(System.Math.Sqrt(num6), num7);
|
||||
double num8 = num7 * num3 - num6;
|
||||
a[i, num] = num7 - num3;
|
||||
for (int j = num; j < length2; j++)
|
||||
{
|
||||
array[j] = a[i, j] / num8;
|
||||
}
|
||||
if (i != length - 1)
|
||||
{
|
||||
for (int k = num; k < length; k++)
|
||||
{
|
||||
num6 = 0.0;
|
||||
for (int j = num; j < length2; j++)
|
||||
{
|
||||
num6 += a[k, j] * a[i, j];
|
||||
}
|
||||
for (int j = num; j < length2; j++)
|
||||
{
|
||||
a[k, j] += num6 * array[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int j = num; j < length2; j++)
|
||||
{
|
||||
a[i, j] *= num4;
|
||||
}
|
||||
}
|
||||
}
|
||||
num5 = System.Math.Max(num5, System.Math.Abs(w[i]) + System.Math.Abs(array[i]));
|
||||
}
|
||||
for (int i = length2 - 1; i >= 0; i--)
|
||||
{
|
||||
if (i < length2 - 1)
|
||||
{
|
||||
if (num3 != 0.0)
|
||||
{
|
||||
for (int k = num; k < length2; k++)
|
||||
{
|
||||
v[k, i] = a[i, k] / a[i, num] / num3;
|
||||
}
|
||||
for (int k = num; k < length2; k++)
|
||||
{
|
||||
double num6 = 0.0;
|
||||
for (int j = num; j < length2; j++)
|
||||
{
|
||||
num6 += a[i, j] * v[j, k];
|
||||
}
|
||||
for (int j = num; j < length2; j++)
|
||||
{
|
||||
v[j, k] += num6 * v[j, i];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int k = num; k < length2; k++)
|
||||
{
|
||||
v[i, k] = (v[k, i] = 0.0);
|
||||
}
|
||||
}
|
||||
v[i, i] = 1.0;
|
||||
num3 = array[i];
|
||||
num = i;
|
||||
}
|
||||
for (int i = length2 - 1; i >= 0; i--)
|
||||
{
|
||||
num = i + 1;
|
||||
num3 = w[i];
|
||||
if (i < length2 - 1)
|
||||
{
|
||||
for (int k = num; k < length2; k++)
|
||||
{
|
||||
a[i, k] = 0.0;
|
||||
}
|
||||
}
|
||||
if (num3 != 0.0)
|
||||
{
|
||||
num3 = 1.0 / num3;
|
||||
if (i != length2 - 1)
|
||||
{
|
||||
for (int k = num; k < length2; k++)
|
||||
{
|
||||
double num6 = 0.0;
|
||||
for (int j = num; j < length; j++)
|
||||
{
|
||||
num6 += a[j, i] * a[j, k];
|
||||
}
|
||||
double num7 = num6 / a[i, i] * num3;
|
||||
for (int j = i; j < length; j++)
|
||||
{
|
||||
a[j, k] += num7 * a[j, i];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int k = i; k < length; k++)
|
||||
{
|
||||
a[k, i] *= num3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int k = i; k < length; k++)
|
||||
{
|
||||
a[k, i] = 0.0;
|
||||
}
|
||||
}
|
||||
a[i, i] += 1.0;
|
||||
}
|
||||
for (int j = length2 - 1; j >= 0; j--)
|
||||
{
|
||||
for (int l = 1; l <= 30; l++)
|
||||
{
|
||||
int num9 = 1;
|
||||
for (num = j; num >= 0; num--)
|
||||
{
|
||||
num2 = num - 1;
|
||||
if (System.Math.Abs(array[num]) + num5 == num5)
|
||||
{
|
||||
num9 = 0;
|
||||
break;
|
||||
}
|
||||
if (System.Math.Abs(w[num2]) + num5 == num5)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
double num10;
|
||||
double num6;
|
||||
double num7;
|
||||
double num8;
|
||||
double num11;
|
||||
double num12;
|
||||
if (num9 != 0)
|
||||
{
|
||||
num10 = 0.0;
|
||||
num6 = 1.0;
|
||||
for (int i = num; i <= j; i++)
|
||||
{
|
||||
num7 = num6 * array[i];
|
||||
if (System.Math.Abs(num7) + num5 != num5)
|
||||
{
|
||||
num3 = w[i];
|
||||
num8 = Pythag(num7, num3);
|
||||
w[i] = num8;
|
||||
num8 = 1.0 / num8;
|
||||
num10 = num3 * num8;
|
||||
num6 = (0.0 - num7) * num8;
|
||||
for (int k = 1; k <= length; k++)
|
||||
{
|
||||
num11 = a[k, num2];
|
||||
num12 = a[k, i];
|
||||
a[k, num2] = num11 * num10 + num12 * num6;
|
||||
a[k, i] = num12 * num10 - num11 * num6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
num12 = w[j];
|
||||
if (num == j)
|
||||
{
|
||||
if (num12 < 0.0)
|
||||
{
|
||||
w[j] = 0.0 - num12;
|
||||
for (int k = 0; k < length2; k++)
|
||||
{
|
||||
v[k, j] = 0.0 - v[k, j];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (l == 30)
|
||||
{
|
||||
throw new ApplicationException("No convergence in 30 svdcmp iterations");
|
||||
}
|
||||
double num13 = w[num];
|
||||
num2 = j - 1;
|
||||
num11 = w[num2];
|
||||
num3 = array[num2];
|
||||
num8 = array[j];
|
||||
num7 = ((num11 - num12) * (num11 + num12) + (num3 - num8) * (num3 + num8)) / (2.0 * num8 * num11);
|
||||
num3 = Pythag(num7, 1.0);
|
||||
num7 = ((num13 - num12) * (num13 + num12) + num8 * (num11 / (num7 + Sign(num3, num7)) - num8)) / num13;
|
||||
num10 = (num6 = 1.0);
|
||||
for (int k = num; k <= num2; k++)
|
||||
{
|
||||
int i = k + 1;
|
||||
num3 = array[i];
|
||||
num11 = w[i];
|
||||
num8 = num6 * num3;
|
||||
num3 = num10 * num3;
|
||||
num12 = (array[k] = Pythag(num7, num8));
|
||||
num10 = num7 / num12;
|
||||
num6 = num8 / num12;
|
||||
num7 = num13 * num10 + num3 * num6;
|
||||
num3 = num3 * num10 - num13 * num6;
|
||||
num8 = num11 * num6;
|
||||
num11 *= num10;
|
||||
for (int m = 0; m < length2; m++)
|
||||
{
|
||||
num13 = v[m, k];
|
||||
num12 = v[m, i];
|
||||
v[m, k] = num13 * num10 + num12 * num6;
|
||||
v[m, i] = num12 * num10 - num13 * num6;
|
||||
}
|
||||
num12 = Pythag(num7, num8);
|
||||
w[k] = num12;
|
||||
if (num12 != 0.0)
|
||||
{
|
||||
num12 = 1.0 / num12;
|
||||
num10 = num7 * num12;
|
||||
num6 = num8 * num12;
|
||||
}
|
||||
num7 = num10 * num3 + num6 * num11;
|
||||
num13 = num10 * num11 - num6 * num3;
|
||||
for (int m = 0; m < length; m++)
|
||||
{
|
||||
num11 = a[m, k];
|
||||
num12 = a[m, i];
|
||||
a[m, k] = num11 * num10 + num12 * num6;
|
||||
a[m, i] = num12 * num10 - num11 * num6;
|
||||
}
|
||||
}
|
||||
array[num] = 0.0;
|
||||
array[j] = num7;
|
||||
w[j] = num13;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static double Sign(double a, double b)
|
||||
{
|
||||
if (!(b >= 0.0))
|
||||
{
|
||||
return 0.0 - System.Math.Abs(a);
|
||||
}
|
||||
return System.Math.Abs(a);
|
||||
}
|
||||
|
||||
private static double Pythag(double a, double b)
|
||||
{
|
||||
double num = System.Math.Abs(a);
|
||||
double num2 = System.Math.Abs(b);
|
||||
if (num > num2)
|
||||
{
|
||||
double num3 = num2 / num;
|
||||
return num * System.Math.Sqrt(1.0 + num3 * num3);
|
||||
}
|
||||
if (num2 > 0.0)
|
||||
{
|
||||
double num3 = num / num2;
|
||||
return num2 * System.Math.Sqrt(1.0 + num3 * num3);
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user