我写了这段代码,应该做出这里描述的内容:
Conjugate Gradient from wikipedia
但经过一些迭代后,变量denomAlpha
变为零,因此我在alpha
上获得了一个NAN。那我的算法有什么问题呢?
import Jama.Matrix;
public class ConjugateGrad {
private static final int MAX_IT = 20;
private static final int MAX_SIZE = 50;
public static void main(String[] args) {
Matrix A = Matrix.random(MAX_SIZE, MAX_SIZE);
Matrix b = Matrix.random(MAX_SIZE, 1);
double[][] d = new double[MAX_SIZE][1];
for(int ii=0;ii<MAX_SIZE;ii++) {
d[ii][0] =0;
}
Matrix x = Matrix.constructWithCopy(d);
Matrix r = b.minus(A.times(x));
Matrix p = r;
Matrix rTrasp_r = r.transpose().times(p);
for (int i = 0; i < MAX_IT; i++) {
Matrix denomAlpha = p.transpose().times(A.times(p));
double numeratorAlpha = rTrasp_r.getArray()[0][0];
double Alpha = numeratorAlpha / denomAlpha.getArray()[0][0];
x = x.plus(p.times(Alpha));
r = r.minus(A.times(p));
Matrix rNew = r.transpose().times(r);
if (Math.sqrt(rNew.getArray()[0][0]) <1.0e-6) {
break;
}
double Beta = rNew.getArray()[0][0] / rTrasp_r.getArray()[0][0];
p = r.plus(p.times(Beta));
rTrasp_r = rNew;
}
}
}
与那些参数相同:
double[][] matrixA = {{4,1},{1,3}};
Matrix A = Matrix.constructWithCopy(matrixA);
double[][] vectorb = {{1},{2}};
Matrix b = Matrix.constructWithCopy(vectorb);
double[][] d = {{2},{1}};
Matrix x = Matrix.constructWithCopy(d);
在算法的第一步,事情是好的 但第二步不是......
r: -8.0, -3.0
Alpha: 0.22054380664652568
Beta: 12.67123287671233
x: 0.2356495468277946, 0.33836858006042303,
第二步:
Alpha: 0.0337280177221555
Beta: 159.11259655226627
x: -2.2726985108925097, -0.47156587291133856,
好的,我发现了一个错误:
r = r.minus(A.times(p).times(Alpha));
现在可行:
r: -8.0, -3.0,
Alpha: 0.22054380664652568
rNew: 0.6403099643121183,
Beta: 0.008771369374138607
p: -0.3511377223647101, 0.7229306048685207,
x: 0.2356495468277946, 0.33836858006042303,
答案 0 :(得分:0)
对于黑客的答案感到抱歉,但是...使用维基百科文章中的数字示例参数并在每个步骤将矩阵输出到终端可能会发现差异。