主要内容

雅可比函数与线性最小二乘

使用雅可比乘函数,你可以解决这种形式的最小二乘问题

最小值 x 1 2 C x - d 2 2

这样Lb≤x≤ub,用于下列问题C是非常大的,可能大到无法存储。对于这个技巧,使用“trust-region-reflective”算法。

例如,考虑这样一个问题C是一个基于循环矩阵的2n × n矩阵。的行C是行向量的移位吗v.这个例子有行向量v与表单的元素 - - - - - - 1 k + 1 / k

v 1 - 1 / 2 1 / 3. - 1 / 4 ... - 1 / n

元素循环移动。

C 1 - 1 / 2 1 / 3. - 1 / n - 1 / n 1 - 1 / 2 1 / n - 1 1 / n - 1 - 1 / n 1 - 1 / n - 2 - 1 / 2 1 / 3. - 1 / 4 1 1 - 1 / 2 1 / 3. - 1 / n - 1 / n 1 - 1 / 2 1 / n - 1 1 / n - 1 - 1 / n 1 - 1 / n - 2 - 1 / 2 1 / 3. - 1 / 4 1

这个最小二乘例子考虑的问题是

d n - 1 n - 2 ... - n

约束条件是 - 5 x 5 1 ... n

足够大的 n ,密集矩阵C不能装入计算机内存( n 1 0 0 0 0 在一个测试系统上太大)。

雅可比乘函数的语法如下。

w = jmfcn(动力系统,Y,标志)

动力系统矩阵的大小和C,用作预调词。如果C太大,无法放入内存,动力系统应该是稀疏的。Y一个向量或矩阵的大小是这样的吗C * YC ' * Y作为矩阵乘法。国旗告诉jmfcn形成哪种产品:

  • 国旗> 0⇒w = C * Y

  • 国旗< 0⇒w = C ' * Y

  • 国旗= 0⇒w C = C的* * Y

因为C是这样一个结构简单的矩阵,你可以很容易地用向量写出雅可比矩阵乘法函数v,没有形成C.每一行的C * Y是循环移位的产物吗vY.使用circshift圆转变v

来计算C * Y,计算v * Y找到第一行,然后移位v然后计算第二行,以此类推。

来计算C ' * Y,执行相同的计算,但使用移位的临时的第一行构成的向量C '

temp = [fliplr (v), fliplr (v)];

temp = [circshift (temp, 1 2) circshift (temp, 1, 2)];% Now temp = C'(1,:)

来计算C ' * C * Y简单的计算C * Y使用变化v,然后计算C '乘以平移的结果fliplr (v)

辅助函数lsqcirculant3是实现这个过程的雅可比乘函数;它出现在这个例子到此结束

dolsqJac3的辅助函数这个例子到此结束建立向量v调用求解器lsqlin使用lsqcirculant3雅可比矩阵乘法函数。

n= 3000,C是一个1800万元素的密集矩阵。确定结果dolsqJac3函数n= 3000在选定的值x,并显示输出结构。

[x, resnorm残留,exitflag,输出]= dolsqJac3 (3000);
局部最小值。Lsqlin停止是因为函数值的相对变化小于函数的容限。
disp (x (1))
5.0000
disp (x (1500))
-0.5201
disp (x (3000))
-5.0000
disp(输出)
cgiterations: 16 algorithm: 'trust-region-reflective' firstorderopt: 5.9351e-05 cgiterations: 36 construct: [] linearsolver: [] message: `局部最小可能。↵↵lsqlin停止,因为功能值的相对变化小于功能容限。

辅助函数

此代码创建lsqcirculant3helper函数。

函数w = lsqcirculant3(动力系统,Y,国旗,v)这个函数计算雅可比矩阵乘法函数%是一个2n × n循环矩阵的例子。如果flag > 0 w = Jpositive(Y);elseifflag < 0 w = Jnegative(Y);其他的w = Jnegative (Jpositive (Y));结束函数一个= Jpositive(问)%计算C * qtemp = v;一个= 0(大小(q));分配矩阵aa = [;];结果是输入的两倍高。R = 1:size(a,1) a(R,:) = temp*q;%计算第r行temp = circshift (temp, 1 2);%移动循环结束结束函数一个= Jnegative(问)%计算C ' * qtemp = fliplr (v);temp = circshift (temp, 1 2);%替换C'的循环len (q, 1) / 2 =大小;%返回的向量长度是原来的一半%作为输入向量。= 0 (len大小(q, 2));分配矩阵aR = 1:len a(R,:) = [temp,temp]*q;%计算第r行temp = circshift (temp, 1 2);%移动循环结束结束结束

此代码创建dolsqJac3helper函数。

函数[x, resnorm残留,exitflag,输出]= dolsqJac3 (n)r = 1: n - 1;表示向量的索引v (n) = (1) ^ (n + 1) / n;%分配向量vv (r) = (1) ^ (r + 1) / r;现在C应该是一个基于v的2n × n循环矩阵,%,但它可能太大而无法放入内存。r = 1:2 * n;d (r) = n-r;动力系统= [speye (n); speye (n));%用于预处理的稀疏矩阵这个矩阵是求解器必须的输入;本例中没有使用%预处理。%传递向量v以便它不需要是%在雅可比乘函数中计算。选择= optimoptions (“lsqlin”“算法”“trust-region-reflective”...“JacobianMultiplyFcn”@(动力系统,Y,国旗)lsqcirculant3(动力系统,Y,国旗,v));磅= 5 * 1 (1,n);乌兰巴托= 5 * 1 (1,n);[x, resnorm残留,exitflag,输出]=...lsqlin(动力系统,d ,[],[],[],[], 磅,乌兰巴托,[]选项);结束

另请参阅

|

相关的话题