之前发过一篇文章BMP格式,主要是为了说明,在你用第三方软件,或API对图片进行操作时,其实首先要对图片的文件头进行解析,只是第三方软件或API已经帮你处理好了,你只需要关注图像处理的算法本身就行了!
Matlab是个不错的工具,可以快速有效的测试算法,但其本身只是个工具,真正重要的还是算法。本文主要是对参考文献做的笔记,方便自己查看。
a=3+2.3i
ceil--向正无穷取整、fix--向零取整、floor--向负无穷取整、round--四舍五入
函数名 | 说明 | 函数名 | 说明 |
chol | 矩阵的cholesky分解 | lu | 矩阵的LU分解 |
cholinc | 矩阵的不完全cholesky分解 | luinc | 矩阵的不完全LU分解 |
diag | 提取矩阵对角元素 | norm | 矩阵或矢量的范数 |
eig | 求本征值和本征向量 | normest | 求矩阵的最大范数矢量 |
eye | 生成单位矩阵 | pinv | 求伪逆矩阵 |
fliplr | 左右翻转矩阵 | qr | QR分解 |
flipud | 上下翻转矩阵 | rank | 求矩阵的秩 |
inv | 求逆矩阵 | trace | 矩阵对角元素的和(迹) |
线性方程组wiki
ex1:AX=B,A和B有相同的行数,则解为X=A\B;X=X';
ex2:消元法--rref(A)--rref可以得到矩阵的最简阶梯矩阵;列主元Gauss消去法解方程组A=[4,2,-6,4;3,1,5,2;2,3,2,-1;2,4,1,2];B=[2;0;0;8];X=CMGelim(A,B);
function X = CMGelim(A,B) % 列主元Gauss消元法 % A是方矩阵 % b是列向量 % X是线性方程组AX=B的解。 if size(A,1)~=size(A,2); % 判断A是否为方矩阵 error('Matrix U must be square.'); end N = size(A,1); % 返回未知数个数 Ap = [A,B]; % 生成增广矩阵 for n = 1:N-1; [Y,Ind] = max(abs(Ap(n:N,n))); % 找出列主元的位置Ind C = Ap(n,:); % 交换当前行和列主元对应的行 Ap(n,:) = Ap(Ind+n-1,:); % 交换当前行和列主元对应的行 Ap(Ind+n-1,:) = C; % 交换当前行和列主元对应的行 if Ap(n,n)==0; % 判断矩阵A是否奇异 error('Matrix is close to singular'); end for k = n+1:N; sc=Ap(k,n)/Ap(n,n); % 消元系数 Ap(k,n:N+1)=Ap(k,n:N+1)-sc*Ap(n,n:N+1); % 消元 end end X=uelim(Ap(:,1:N),Ap(:,N+1)); % 调用程序uelim.m进行回代过程
ex3:LU分解-A=[3,2,2,5;2,2,3,5;2,3,4,2;2,-3,3,2];B=[2;0;0;9];[L,U]=lu(A);B1=L\B;X=uelim(U,B1);Delta=[A*X'-B]';
function X = uelim(U,B); % U是上三角方矩阵。 % b是列向量。 % X是方程组AX=b的解。 if prod(diag(U))==0; % 判断矩阵U是否奇异 error('Matrix is close to singular or badly scaled.'); end if size(U,1)~=size(U,2); % 判断U是否为方矩阵 error('Matrix U must be square.') end D = triu(U)-U; if sum(abs(D(:)))>eps; % 判断U是否为上三角矩阵 error('Matrix U must be upper triangular.') end n = length(B); % 返回未知数个数 X(n) = B(n)/U(n,n); % 获得最后一个未知数的值 for k = n-1:-1:1; X(k) = (B(k)-sum(X(k+1:n).*U(k,k+1:n)))/U(k,k); % 依次求解其它未知数 end
ex4:迭代法:1、雅可比迭代法:A=[9,4,2;3,8,2;2,3,7];B=[1,2,3];X0=[0,0,0];Y=Jacobi_iteration(A,B,X0);
function X = Jacobi_iteration(A,B,X0,kmax,tol); % 雅可比(Jacobi)迭代法解线性方程组AX=B if nargin == 4; tol = 1e-6; % 设置默认精度 elseif nargin ==3; tol = 1e-6; kmax = 500;% 设置默认迭代次数 elseif nargin == 2; tol = 1e-6; kmax = 500; X0 = zeros(size(B)); % 设置默认初值 end n = length(B); % 获得未知数个数 if size(X0,1)<size(X0,2); % 把默认初值改为列向量 X0 = X0'; end DA = diag(A); %提取A的对角元素 Ap = [diag(DA)-A]./repmat(DA,1,n); % 生成式(7-28)中的矩阵Ap Bp = B./DA; % 生成式(7-28)中的向量Bp for k = 1:kmax X = Ap*X0+Bp; % 雅可比(Jacobi)迭代公式 if norm(X-X0)/(norm(X0)+eps)<tol;% 达到精度将终止循环 break; end X0 = X; end X=X';
2、高斯-赛德尔迭代1法:A=[9,2,2-4;2,8,2,-3;2,2,7,2;3,2,-2,9];B=[1;-1;2;1];X0=[0,0,0,];X=gauseid(A,B,X0);
function X = gauseid(A,B,X0,kmax,tol); %This function is to find x = A^(-1)*B by Gauss–Seidel iteration. % A是系数矩阵 % B是列向量 % X0是迭代初值 % kmax是最大迭代次数 % tol是预定的精度 if nargin == 4; tol = 1e-6; % 设置默认精度 elseif nargin ==3; tol = 1e-6; kmax = 500; elseif nargin == 2; tol = 1e-6; kmax = 500; X0 = zeros(size(B)); end n = length(B); % 获得未知数个数 if size(X0,1)<size(X0,2); X0 = X0'; end X = X0; for k = 1: kmax X(1) = (B(1)-A(1,2:n)*X(2:n))/A(1,1); for m = 2:n-1; tmp = B(m)-A(m,1:m-1)*X(1:m-1)-A(m,m+1:n)*X(m+1:n); X(m) = tmp/A(m,m); %Eq.(2.5.4) end X(n) = (B(n)-A(n,1:n-1)*X(1:n-1))/A(n,n); if nargout == 0, % 无输出时显示过程结果 X, end if norm(X - X0)/(norm(X0) + eps)<tol;% 达到精度将终止循环 break; end X0 = X; end X = X';
函数解法:
ex1: solve求解
f = sym('a*x^2+b*x+c=0'); % f = 'a*x^2+b*x+c=0'; x = solve(f) pretty(x) xL = latex(x) x = -(b + (b^2 - 4*a*c)^(1/2))/(2*a) -(b - (b^2 - 4*a*c)^(1/2))/(2*a)ex2:分别求解 和 其中a为未知数;将p,x和b作为常数看待
E1 = 'exp(-p*x)+b*sin(a)'; % 定义方程 E2 = '3*a+4*cos(a+pi)=0'; % 定义方程 a1 = solve(E1,'a') % 求解方程,并指定a为未知数 a2 = solve(E2,'a') % 求解方程,并指定a为未知数 a2d = double(a2) % 转化为双精度数据
ex3:求非线性4元方程组的解
分析:第一个方程是线性的,而其他3个是非线性的
E1 = 'a+b+x=y*3'; % 定义方程 E2 = 'a*x-b*y=1'; % 定义方程 E3 = 'a*b+x*y=2'; % 定义方程 E4 = 'a+b=(x+y)^2'; % 定义方程 [a,b,x,y]=solve(E1,E2,E3,E4); % 解方程组 Solution = [a, b, x, y] % 合为一个矩阵ex4:求非线性方程组的解
syms x y; % 定义符号变量 E1 = 'x*y=1'; % 定义方程 E2 = 'x^y=4'; % 定义方程 J = solve(E1,E2,x,y); % 求解方程,J是结构体 x=J.x % 显示x y=J.y % 显示y xd=double(x) yd=[y] figure; x = linspace(-2,8,200); y = lambertw(x); plot(x,real(y),'k',x,imag(y),'k:'); set(gca,'Fontsize',12); xlabel('\itx','Fontname','Times','Fontsize',18); ylabel('lambertw({\itx})','Fontname','Times','Fontsize',18); set(gca,'Position',[0.13 0.31 0.775 0.615]); legend('Re','Im',0); set(gcf,'Color','w');ex5:求y=0,x的解
syms x a b; % 定义符号变量 fx = x.^2-a*sin(x)+b; % 定义符号函数 fx = subs(fx,{a,b},{1,-2}); % 对a和b赋值 fx = char(fx); % 把fx转换为字符串 fx = strrep(fx,'^','.^'); % 把乘方运算转换为点运算 fx = inline(fx); % 定义内联函数 x1 = fzero(fx,0) % 求函数第1的零点 x2 = fzero(fx,2) % 求函数第2的零点 xt = -6:.1:6; % 产生[-6, 6]区间内等间距采样点 plot(xt,fx(xt)); % 绘制fx的曲线图 hold on; plot(xlim,[0,0],'k:') % 绘制0刻度线 set(gca,'Position',[0.13 0.31 0.775 0.615]); set(gcf,'color','w');
xx = linspace(1,4,200); yy = [xx.^2-4*sin(5*xx)]./[xx.^2+cos(xx)]; plot(xx,yy,'k'); fun = inline('abs([x^2-4*sin(5*x)]/[x^2+cos(x)])'); % % 转化为函数f(x)的绝对值 x01 = fminbnd(fun,1,1.5) % 计算最小值 x02 = fminbnd(fun,1.5,2) % 计算最小值 x03 = fminbnd(fun,1,4) [x03, fval] = fminbnd(fun,1,4) % 计算最小值 hold on plot(xx,abs(yy),'k:'); L=legend('{\itf}({\itx})','|{\itf}({\itx})|',0); set(L,'Fontsize',18); plot(x01,0,'r*','markersize',14); % 把解画到图上 plot(x02,0,'r*','markersize',14); % 把解画到图上 plot(x03,fval,'ro','markersize',14); % 把解画到图上 plot(x03,0,'ro','markersize',14); set(gca,'Fontsize',18); set(gcf,'Color','w');ex7:二分法,求解两个方程在区间【1,4】内的解
其中,初始条件为
xx = linspace(1,4,200); % 对自变量采样 for k=1:length(xx); x=xx(k); Ix=quad('sqrt(t).*sin(t).*exp(-t)',0,sin(6*x)); % 计算离散积分 y(k)=-2+x+Ix^2; % 得到方程1中函数的数值 end subplot(121); plot(xx,y); % 绘制曲线 hold on; plot(xlim,[0,0],'r:') % 绘制0刻度线 [x01, f1] = dichotomy('fund1',1,4) % 解方程1 plot(x01,f1,'k*','markersize',12) % 用符号"*"标出方程1的解 set(gca,'Position',[0.13 0.41 0.327023 0.515]); % 重置坐标轴位置 set(gca,'Fontsize',12); % 重置字体大小 subplot(122); [t,y]=ode45(@vdp1,[0 4],[2 0]); % 得到方程2中函数的数值 plot(t,y(:,1)); % 绘制曲线 hold on; plot(xlim,[0,0],'r:') % 绘制0刻度线 [x02, f2] = dichotomy('fund2',1,4) % 解方程2 plot(x02,f2,'k*','markersize',12) % 用符号"*"标出方程2的解 set(gca,'Position',[0.577977 0.41 0.327023 0.515]); % 重置坐标轴位置 set(gca,'Fontsize',12); % 重置字体大小 set(gcf,'Color','w'); % 重置图形背景色ex8:抛物线法,求解方程在区间【1,3】内的解
xx = linspace(1,3,200); % 对自变量采样 y = fund3(xx); % 计算个点的函数值 plot(xx,y); % 绘制函数f(x)曲线 hold on; plot(xlim,[0,0],'r:'); % 绘制零刻度线 xr = parabola('fund3',1,2,3) % 抛物线法解方程 plot(xr,fund3(xr),'k*','markersize',12); % 绘制解对应的点 set(gca,'Fontsize',12) set(gcf,'Color','w');ex9:牛顿法,求解方程在区间【3,5】内的解
xx = linspace(0,6,200); % 对自变量采样 y = fund4(xx); % 计算个点的函数值 plot(xx,y); % 绘制函数f(x)曲线 hold on; plot(xlim,[0,0],'r:'); % 绘制零刻度线 xr1 = Newtonm('fund4',1.5) %牛顿法求根,初始点是1.5 plot(xr1,fund4(xr1),'ks','markersize',12); % 绘制解对应的点 plot(1.5,fund4(1.5),'ks','markersize',12); % 绘制解对应的点 xr2 = Newtonm('fund4',3.5) %牛顿法求根,初始点是3.5 plot(xr2,fund4(xr2),'k*','markersize',12); % 绘制解对应的点 plot(3.5,fund4(3.5),'k*','markersize',12); % 绘制解对应的点 xr3 = Newtonm('fund4',5.5) %牛顿法求根,初始点是5.5 plot(xr3,fund4(xr3),'ko','markersize',12); % 绘制解对应的点 plot(5.5,fund4(5.5),'ko','markersize',12); % 绘制解对应的点 set(gca,'Fontsize',12) set(gcf,'Color','w');ex10:正割法,求解方程
fun = inline('exp(x)-x-5'); % 定义方程中的函数f(x) x0 = 3.5; % 第一初始值 x1 = 3; % 第二初始值 xr = secant(fun,x0,x1) % 用正割法解方程 xs = secant(fun,x1,x0) % 用正割法解方程 xq = fzero(fun,2) % 利用fzero函数作比较 x0 = 1; % 第一初始值 x1 = 3; % 第二初始值 xw = secant(fun,x0,x1) % 用正割法解方程 xa = steffenson(fun,x1) % 用steffenson法解方程 x0 = 1:.4:3.5; for k = 1:length(x0); % 测试不同初始值对求解的影响 xt = x0(k); xa = steffenson(fun,xt); T(k,:)=[xt,xa]; end T
ex1:线性拟合
xk = 0:9;
yk = [2 3.4 5.6 8 11 12.3 13.8 16 18.8 19.9];
xk = 0:9; yk = [2 3.4 5.6 8 11 12.3 13.8 16 18.8 19.9]; plot(xk,yk,'r+') h=lsline xd = get(h, 'XData'); yd = get(h, 'YData'); a = [yd(1)-yd(2)]/[xd(1)-xd(2)] b = yd(1)-a*xd(1) set(gcf,'Color','w') set(gca,'Fontsize',16) P = polyfit(xk,yk,1)ex2:二元线性拟合
M=[x',y',ones(9,1)]; d=z; [X, resnorm, residual] = lsqlin(M,d) X=X', resnorm, residual=residual'ex3:多项式拟合
利用从2到5次多项式分别显示多项式系数和次数
x = 0:5; % 输入拟合x数据 y = [1 22 61 69 76 111]; % 输入拟合y数据 xp = 0:0.02:5; % 产生更密集的x轴数据 for N=2:5 P = polyfit(x,y,N); % N次多项式拟合 yp = polyval(P,xp); % 计算xp出的多项式值 plot(x,y,'r+',xp,yp,'k'); % 绘制数据点与拟合曲线 title(['n=',int2str(N)],'Fontsize',16); % 显示次数 for k=1:length(P); text(1+k*0.4,k*10,['P(',num2str(k),... ')=',char(vpa(P(k),4))],... 'FOntsize',16); %显示所有多项式系数 end set(gca,'Fontsize',14); %设置字体大小 set(gcf,'Color','w'); % 重置背景色 pause % 停顿 endex4:非线性数据拟合
xd =1 2 3 4 5 6 7 8 9 10
yd =3.5000 3.0000 2.6000 2.3000 2.1000 1.9000 1.7000 1.6000 1.50001.4000
load P0528 % 读入数据 c0 = [0,1,1]; % 初始值 c = lsqcurvefit('fit_model_a',c0,xd,yd) % 进行非线性拟合 plot(xd,yd,'r+','Markersize',10); % 利用原始数据绘图 hold on; xp = linspace(min(xd),max(xd),200); % 生成原始数据范围内的等间距采样点 yp = fit_model_a(c,xp); % 利用拟合系数计算因变量数值 plot(xp,yp); % 绘制拟合曲线 set(gcf,'Color','w'); set(gca,'Fontsize',16); c0 = [0,1,1]; % 初始值 c = lsqnonlin('fit_model_b',c0) % 进行非线性拟合
ex5:拉格朗日插值
function y=lag_interp(x,xd,yd); %Example: % x=1:.1:4; % 待求点数据 % xd=1:4; % 插值点自变量数据 % yd=[2,1,3,4]; % 插值点因变量数据 % y=lag_interp(x,xd,yd); % 计算拉格朗日插值 % plot(x,y,'k',xd,yd,'ko','markersize',10);%绘制曲线 N = length(xd); % 插值点自变量数据长度 L = length(x); % 待求点数据长度 W = repmat(xd',1,L); % 生成矩阵W X = repmat(x,N,1)-repmat(xd',1,L); % 矩阵Xt y = 0; % 初始化y for k = 1:N; Xk = X; Xk(k,:) = yd(k)*ones(1,L); % 生成矩阵Xk Wk = xd(k)-W; Wk(k,:) = 1;% 生成矩阵Wk y = y+prod(Xk./Wk); % 累积求和 endex6:Hermite插值
x=1:.1:4; % 待求点数据 xd=1:4; % 插值点自变量数据 yd=[2,1,3,4]; % 插值点因变量数据 rand('state',0); % 设置随机数状态 dy = rand(1,4)-0.5; % 产生随机的dy值 y=hermite_interp(x,xd,yd,dy); % 插值计算 plot(x,y,'k',xd,yd,'ko','markersize',10); % 绘图 set(gca,'Fontsize',16) set(gcf,'Color','w'); function y=hermite_interp(x,xd,yd,dy); % Hermite插值 N = length(xd);% 计算插值点数据长度 L = length(x);% 计算待求点数据长度 X = repmat(x,N-1,1); % 扩展为矩阵X y = 0; % 初始化y for k = 1:N; xt = xd; xt(k) = []; % 去掉不满足条件的求和求积项 h=prod(1./[xd(k)-xt]); h=h*prod([X-repmat(xt',1,L)]); h = h.^2; % 计算h乘积因子 a = sum(1./[xd(k)-xt]); % 计算a乘积因子 y = y+h.*[(xd(k)-x)*(2*a*yd(k)-dy(k))+yd(k)];% 对y累加 endex6:样条插值
N = 5; % 设定采样点数 xd = linspace(-1,1,N); % 产生插值点 yd = 1./(1+25*xd.^2); % 产生插值点 x = linspace(-1,1,200); % 获得待求点坐标 y = 1./(1+25*x.^2); % 正确的结果 yL = lag_interp(x,xd,yd); % 拉格朗日插值 rand('state',0); % 设定随机数状态 dy = rand(1,N)-0.5; % 产生随机的一阶导数 yH=hermite_interp(x,xd,yd,dy); % 进行厄尔米特插值 subplot(221); plot(x,yL,'k:',xd,yd,'kx','markersize',8); hold on; plot(x,y,'k','linewidth',1); set(gca,'Fontsize',16); text(-0.8,0.5,'{\itN} = 5','Fontsize',16); xlabel('(a)'); subplot(222); plot(x,yH,'k:',xd,yd,'kx','markersize',8); hold on; plot(x,y,'k','linewidth',1); set(gca,'Fontsize',16); text(-0.8,1,'{\itN} = 5','Fontsize',16); xlabel('(b)'); %% N=10; N = 13; xd = linspace(-1,1,N); yd = 1./(1+25*xd.^2); x = linspace(-1,1,200); y = 1./(1+25*x.^2); yL = lag_interp(x,xd,yd); rand('state',0); dy = rand(1,N)-0.5; yH=hermite_interp(x,xd,yd,dy); subplot(223); plot(x,yL,'k:',xd,yd,'kx','markersize',6); hold on; plot(x,y,'k','linewidth',1); set(gca,'Fontsize',16); text(-0.7,-2,'{\itN} = 13','Fontsize',16); xlabel('(c)'); subplot(224); plot(x,yH,'k:',xd,yd,'kx','markersize',8); hold on; plot(x,y,'k','linewidth',1); set(gca,'Fontsize',16); text(-0.7,150,'{\itN} = 13','Fontsize',16); xlabel('(d)'); set(gcf,'Color','w');
x = 0:.5:5; % 生成插值点自变量数据 % N=length(x); % 获得插值数据长度 % Ik=randperm(N); % 产生一个随机排序序列 % x = x(Ik); % 对x随机排序 y = x.^2.*cos(x); % 计算插值点因变量数值 xi = 0:.02:5; % 计算待求点自变量数据 % xi=fliplr(xi); % 左右翻转向量xi method = {'nearest','linear','spline','pchip','cubic','v5cubic'}; % 插值方法名数组 for k=1:6; subplot(3,2,k); % 分布子图顺序 yi = interp1(x,y,xi,char(method(k))); % 用不同方法分段插值 yg = xi.^2.*cos(xi); % 计算理论值 plot(x,y,'ko',xi,yi,'k:',xi,yg,'k'); % 画数据点及绘制曲线 text(2,5,char(method(k)),'Fontsize',16); % 输出插值方法 set(gca,'Fontsize',14); % 重置坐标轴字体 xlim([min(x),max(x)]); % 设定横轴范围 end set(gcf,'Color','w');
未完待续!