Matlab牛顿迭代函数xHist存储格式调整求助
解决牛顿法迭代历史xHist的存储格式问题
首先,针对你提到的将纵向堆叠的x向量转为每行存储一个完整x向量的需求,最通用的方法是利用Matlab的reshape函数,完全不需要依赖循环索引(不管方程组是几阶都适用)。同时,我注意到你的牛顿法函数存在逻辑问题,导致迭代过程和结果可能不符合预期,也会一并修正。
核心解决方案:重塑xHist的形状
假设你已经得到了原始的xHist(纵向堆叠的列向量,比如n维方程组迭代m次后,xHist是n×m行的列向量),只需要一行代码就能转成每行一个x向量的矩阵:
% 假设x0是n维列向量,先获取维度 n = length(x0); % 重塑为m行n列的矩阵,每行对应一次迭代的x向量 xHist_reshaped = reshape(xHist, n, [])';
原理:Matlab的reshape是按列优先排列的,原始xHist是把每个x的n个元素依次纵向堆叠,所以reshape(xHist, n, [])会得到一个n行m列的矩阵(每列是一个x向量),再转置就得到m行n列,每行是一个完整的x向量。
从根源优化:迭代时直接存储行向量
如果你想在迭代过程中就直接生成每行一个x向量的xHist,可以修改迭代中xHist的赋值语句,把列向量x转成行向量后再添加:
xHist = [xHist; x'];
这样每次迭代都会把当前的x向量作为一行添加到xHist中,最后直接得到符合要求的格式。
修正你的牛顿法函数逻辑
你的原始函数中,for k = 1:1:size(f)这个循环是错误的——牛顿法求解向量值方程组时,应该一次性求解整个方程组(把f作为一个向量值函数,返回列向量,df返回Jacobian矩阵),而不是循环每个单独的函数。这个循环会导致你重复求解两次,得到错误的结果。
下面是修正后的完整牛顿法函数:
% INPUT % f 向量值根函数(返回列向量) % df 返回f的Jacobian矩阵的函数(n×n矩阵,n是方程组维度) % x0 初始猜测值(列向量) % tol 期望容差 % maxIt 最大迭代次数 % % OUTPUT % x 近似解 % success 收敛标志(true表示收敛) % errEst 每次迭代的误差估计(列向量) % xHist 存储中间解的数组(每行一个x向量) function [x, success, errEst, xHist] = newton(f, df, x0, tol, maxIt) errEst = []; xHist = []; iter = 0; err = inf; x = x0; success = false; n = length(x0); % 获取方程组维度 while err > tol && iter < maxIt % 修正循环条件:err > tol而不是err>0 Fun = f(x); % f是向量值函数,返回列向量 Jac = df(x); % df返回Jacobian矩阵 delta = -Jac\Fun; err = norm(delta); x = x + delta; errEst = [errEst; err]; xHist = [xHist; x']; % 存储行向量 iter = iter + 1; end if err < tol success = true; end end
修正后的调用代码
注意要把f改成向量值函数,df返回正确的Jacobian矩阵:
x0 = 1/sqrt(2) * [2;1]; grad = [sqrt(2)/2;sqrt(2)]; n_vec = grad/norm(grad); % 避免和维度变量n重名,改名为n_vec t = [n_vec(2),-n_vec(1)]; p = 0.5; x0 = x0 + 2 * (n_vec + t); %x0 = x0 - 2 * (n_vec + t); % 定义向量值函数f,返回列向量 f = @(x) [ (x(1)/2)^2 + x(2)^2 - 1; n_vec .* (x - x0) - p - 0.5 .* (t .* (x - x0)) .^ 2 ]; % 定义返回Jacobian矩阵的df函数 df = @(x) [ x(1)/2, 2*x(2); n_vec(1) - t(1)*t*(x - x0), n_vec(2) - t(2)*t*(x - x0) ]; [x, success, errEst, xHist] = newton(f, df, x0, 1e-12, 20);
这样运行后,xHist就是每行存储一个完整的x向量,完全适用于任意维度的方程组。
内容的提问来源于stack exchange,提问作者Pee Late
相关产品推荐
相关产品推荐

