시스템 사용;
namespace Zhou.CSharp.Algorithm
{ public delegate double delFunction_x(double x); 공개 대리자 double delFunction_xa(double[] x); 공개 대리자 double delFunction_x_y(double x, double y); 공개 대리자 double delFunction_x_ya(double x, double[] y); 공개 대리자 double delFunction_xa_ya(double[] x, double[] y);
/// <summary>
/// 비선형 방정식을 풀기 위한 NLEquations 클래스
/// Zhou Changfa
/// 깊은 혼란에 적응
/// </summary>
public static partial class NLEquations
{
/// <summary>
/// 비선형 방정식 시스템의 최소 제곱해의 일반화된 역 방법 찾기
/// 1. 방정식의 왼쪽 끝에서 함수 f(x)의 값과 그 편도함수를 계산합니다. value
/// double Func(double[] x, double[] y)
/// 2. 야코비 행렬 함수 계산
/// double FuncMJ(double[] x, double[] y)
/// </summary>
/// <param name="Func" >방정식의 왼쪽 끝 함수 계산</param>
/// <param name="FuncMJ">야코비 행렬 함수 계산</param>
/// <param name= "m">방정식의 수</param>
// / <param name="n">미지의 수</param>
/// <param name="x">길이가 n인 1차원 배열, 일련의 초기 값 x0, x1, … 저장,xn-1, 모두 0이 필요하지 않음, 반환 시 방정식 시스템의 최소 제곱해가 저장됨, m=n일 때, 비선형 방정식 시스템의 솔루션</param>
/// <param name="eps1 ">최소 제곱 곱셈 솔루션의 정밀도가 정밀도를 제어합니다</param>
/// <param name="eps2">특이 값 분해의 정밀도가 정밀도를 제어합니다</param>
/// <return>bool 유형, 솔루션의 성공 여부</return>
public static bool GetRootsetGinv(delFunction_xa_ya Func, delFunction_xa_ya FuncMJ, int m, int n, double[] x, double eps1, double eps2) { int i,
j , k, r, kk, jt 이중 알파, z = 0, h2, y1, y2, y3, y0, h1 이중[] p, d, dx;
더블[] y = 새로운 더블[10];
더블[] b = 새로운 더블[10];
// 제어 매개변수
int ka = Math.Max(m, n) + 1;
double[] w = new double[ka];
// 반복 횟수를 60으로 설정, 반복 솔루션
r = 60;
alpha = 1.0;
while (r > 0)
{ Matrix mtxP = new Matrix(m, n); Matrix mtxD = new Matrix(m, 1); p = mtxP.GetData(); d = mtxD.GetData();
Func(x, d);
FuncMJ(x,p);
//선형 방정식 시스템 구성
//LEquations leqs = new LEquations(mtxP, mtxD);
//임시 행렬
행렬 mtxAP = new Matrix();
행렬 mtxU = new Matrix();
행렬 mtxV = new Matrix();
/ /솔루션 행렬
행렬 mtxDX = new Matrix();
// 일반화된 역에 기반한 최소 제곱 솔루션
if (!LEquations.GetRootsetGinv(mtxP, mtxD, mtxDX, mtxAP, mtxU, mtxV, eps2))
{ return false; }
dx = mtxDX.GetData();
j = 0;
jt = 1;
h2 = 0.0;
동안 (jt == 1)
{ jt = 0; if (j <= 2) { z = 알파 + 0.01 * j; } 그렇지 않으면 { z = h2; } for (i = 0; i <= n - 1; i++) { w[i] = x[i] - z * dx[i]; } Func(w, d);
y1 = 0.0;
for (i = 0; i <= m - 1; i++)
{ y1 = y1 + d[i] * d[i]; } for (i = 0; i <= n - 1; i++) { w[i] = x[i] - (z + 0.00001) * dx[i]; } Func(w, d);
y2 = 0.0;
for (i = 0; i <= m - 1; i++)
{ y2 = y2 + d[i] * d[i]; } y0 = (y2 - y1) / 0.00001;
if (Math.Abs(y0) > 1.0e-10)
{ h1 = y0; h2=z; if (j == 0) { y[0] = h1; b[0] = h2; } else { y[j] = h1; kk = 0; k = 0; 동안 ((kk == 0) && (k <= j - 1)) { y3 = h2 - b[k];
if (Math.Abs(y3) + 1.0 == 1.0)
{ kk = 1; } 그렇지 않으면 { h2 = (h1 - y[k]) / y3; } k = k + 1; }
b[j] = h2;
if (kk != 0)
{ b[j] = 1.0e+35; } h2 = 0.0; for (k = j - 1; k >= 0; k--) { h2 = -y[k] / (b[k + 1] + h2); } h2 = h2 + b[0]; }
j = j + 1;
if (j <= 7)
{ jt = 1; } 그렇지 않으면 { z = h2; } } }
알파 = z;
y1 = 0.0;
y2 = 0.0;
for (i = 0; i <= n - 1; i++)
{ dx[i] = -alpha * dx[i]; x[i] = x[i] + dx[i]; y1 = y1 + Math.Abs(dx[i]); y2 = y2 + Math.Abs(x[i]); }
// 성공적으로 해결
if (y1 < eps1 * y2)
{ return true; }
r = r - 1;
}
// 솔루션 실패
return false;
}
}
}