MATLAB中矩阵方程求解的实现

MATLAB中矩阵方程求解的实现

一、矩阵方程

1、定义:

MATLAB中矩阵方程求解的实现_第1张图片

 

 

2、分类

http://naotu.baidu.com/file/14d36860667d356a54490320cdab2950?token=56a299fe0e0815fe

二、M代码实现

1、M代码

  1 function d=CDBH_for_sov_JZFC(a,b)
  2 [m1,n1]=size(a);
  3 [m2,n2]=size(b);
  4 c=[a,b];
  5 ra=rank(a);             %矩阵a的秩
  6 rb=rank(b);             %矩阵b的秩
  7 rc=rank(c);             %矩阵[a,b]的秩
  8 zero=zeros(m2,n2);      %构造与b规格相同的零矩阵
  9 pj=zero~=b;             %确定b中非零元素的个数
 10 pj=sum(pj);
 11 pj=sum(abs(b));         %更新,把判据改为b中所有值的绝对值之和
 12 global i1;              %用于阶梯型的计算
 13 global i0;              %用于阶梯型的计算,其值为当前列于当前行的差值
 14 global cx;              %用于记录阶梯型的首个元素的位置
 15 i1=0;
 16 i0=0;
 17 x_fqc=[];                  %非齐次计算中,用于记录阶梯型的首个元素的位置
 18 x_qc=[];                  %在齐次计算中,用于记录阶梯型的首个元素的位置
 19 cx=[];
 20 if m1~=m2
 21     error('输入有误,无法计算');
 22     return;
 23 end
 24 switch pj
 25     %这种情况为其次方程组
 26     case 0
 27         switch rc
 28             %这种情况只有零解
 29             case n1
 30                 
 31                 d=zeros(n1,1);
 32                 %disp(d);
 33                 
 34                 %这种情况有基础解系
 35             case num2cell([0:n1-1])
 36                 %求解思路:
 37                 %一.矩阵变换
 38                 %1)化为行阶梯型
 39                 %2)化为标准型
 40                 %二.求基础解系
 41                 %1)分别取非线性向量
 42                 %2)则线性向量的值为,上述向量对应元素的相反数
 43                 %三.输出结果
 44                 
 45                 %一、矩阵变换
 46                 for i=1:m1-1;    %需要对行数-1行进行行变换
 47                     %选中了第i行
 48                     %如果都为非线性相关的向量,则阶梯的行列数相等,若存在线性相
 49                     %的向量,则需要构造一个i0来表示阶梯对应的列,并用i1表示列于
 50                     %行数的差值。
 51                     i0=i1+i;
 52                     %因为i1的值根据本行元素具体情况确定,因此需要注意,应当在这
 53                     %个for循环内完成下三角、化为1、上三角的所有操作。
 54                     %Step01 检查阶梯元素是否等于零
 55                     %       若等于零,则需要与第一个不为零的行对调,若全为零,
 56                     %       则i1+1,并再次循环。
 57                     pj_01=0;%初始化以下循环的判据
 58                     while pj_01==0 %利用判据pj_01来判断是否需要再次循环,在循环中,通过修改pj的值来跳出循环。
 59                         pj_01=1;    %没有特殊情况执行完跳出循环
 60                         i0=i+i1;
 61                         if c(i,i0)==0
 62                             %01 找到第i0列,i行及以下第一个非零元素的位置k
 63                             k=find(c([i+1:end],i0));
 64                             %k=k(1);
 65                             %02 将k行与i行对调(若k为空集,应当i1+1并再循环)
 66                             if k~=[];           %k不为空集时,将k行与i行对调
 67                                 k=k(1);
 68                                 e=c(i,:);
 69                                 c(i,:)=c(k,:);
 70                                 c(k,:)=e;
 71                                 pj_01=1;
 72                             elseif isempty(k)==1;       %k为空集时,i1+1并再循环
 73                                 i1=+1;
 74                                 i0=i1+i;
 75                                 pj_01=0;        %将判据设为0,再次循环
 76                             end
 77                         end
 78                     end
 79                     i0=i1+i;        
 80                     x_qc=[x_qc,i0];     %将此时的列位置进行记录
 81                     %Step2 检查阶梯元素是否为1,若不为1,则将其化为1
 82                     if c(i,i0)~=0&&c(i,i0)~=0;
 83                         c(i,:)=c(i,:)/c(i,i0);
 84                     end
 85                     %Step3 将i0列,第i行一下的元素消减为0
 86                     for j=i+1:m1
 87                         if c(j,i0)~=0
 88                             c(j,:)=c(j,:)-c(j,i0)*c(i,:);
 89                         end
 90                     end
 91                     %Step4 将i0列,第i行一上的元素消减为0
 92                     for j=1:i-1
 93                         if c(j,i0)~=0
 94                             c(j,:)=c(j,:)-c(j,i0)*c(i,:);
 95                         end
 96                     end
 97                 end
 98                 %更新!检查最后一行
 99                 if sum(abs(c(m1,[1:n1])))~=0
100                     c(m1,:)=c(m1,:)/c(m1,n1);
101                     for j=1:m1-1
102                         if c(j,n1)~=0
103                             c(j,:)=c(j,:)-c(j,n1)*c(m1,:);
104                         end
105                     end
106                 end
107                 
108                 %成功化为标准型
109                 %disp(c)    
110                 %二、求基础解系
111                 %依次选定线性相关向量所在列,查找对应非线性相关的元素的值,并将其取负,放入解系矩阵。
112                 %Step1 根据x_qc构造线性相关向量位置向量,构造基础解系矩阵
113                 no_x_qc=ones(1,n1);     %初始化与a列咧数相等的1向量
114                 no_x_qc(x_qc)=0;        %其中线性无关向量位置设为0
115                 no_x_qc=find(no_x_qc);  %找到非零元素位置,命名为no_x_qc
116                 jcjx=zeros(n1,rc);      %初始化基础解系(行:A的列,列:C的秩)
117                 %Step2 选定线性相关所在列(使用for循环)
118                 for i=1:length(no_x_qc)
119                     
120                     %Step3 查找该列中,线性无关向量对应的元素的值
121                     for j=1:length(x_qc)
122                         Psi=c(j,no_x_qc(i));
123                         %Step4 将查找到的值取负,并放入基础解系的第i列的相应位置
124                         Psi=Psi*-1;
125                         jcjx(x_qc(j),i)=Psi;
126                     end
127                     %Step5 将基础解系中,当前列对应的位置的元素赋值为1
128                     jcjx(no_x_qc(i),i)=1;
129                 end
130                 %disp(jcjx)
131                 %三、输出结果
132                 disp '齐次型,结果为基础解系'
133                 d=jcjx;
134                 disp 'x1'
135                 disp '... = k1*psi1+...+kr*psir'
136                 disp 'xn'
137                     otherwise
138                         error('输入有误,无法计算');
139                         return;
140                 end
141                 %这种话情况为非齐次方程
142     otherwise
143         %这种情况无解
144         if ra<rc
145             error('非齐次方程组无解');
146             return;
147             %这种情况唯一解
148         elseif ra==rc&&rc==n1   %这时,a必然为方阵,但是可以使用上述齐次方程的解法
149             %思路:
150             %一、矩阵变换
151             %二、求解
152             %三、输出结果
153             
154             %一、矩阵变换
155             for i=1:m1-1;    %需要对行数-1行进行行变换
156                 %选中了第i行
157                 %如果都为非线性相关的向量,则阶梯的行列数相等,若存在线性相
158                 %的向量,则需要构造一个i0来表示阶梯对应的列,并用i1表示列于
159                 %行数的差值。
160                 i0=i1+i;
161                 %因为i1的值根据本行元素具体情况确定,因此需要注意,应当在这
162                 %个for循环内完成下三角、化为1、上三角的所有操作。
163                 %Step01 检查阶梯元素是否等于零
164                 %       若等于零,则需要与第一个不为零的行对调,若全为零,
165                 %       则i1+1,并再次循环。
166                 pj_01=0;%初始化以下循环的判据
167                 while pj_01==0 %利用判据pj_01来判断是否需要再次循环,在循环中,通过修改pj的值来跳出循环。
168                     pj_01=1;    %没有特殊情况执行完跳出循环
169                     i0=i+i1;
170                     if c(i,i0)==0
171                         %01 找到第i0列,i行及以下第一个非零元素的位置k
172                         k=find(c([i+1:end],i0));
173                         %k=k(1);
174                         %02 将k行与i行对调(若k为空集,应当i1+1并再循环)
175                         if k~=[];           %k不为空集时,将k行与i行对调
176                             k=k(1);
177                             e=c(i,:);
178                             c(i,:)=c(k,:);
179                             c(k,:)=e;
180                             pj_01=1;
181                         elseif isempty(k)==1;       %k为空集时,i1+1并再循环
182                             i1=+1;
183                             i0=i1+i;
184                             pj_01=0;        %将判据设为0,再次循环
185                         end
186                     end
187                 end
188                 i0=i1+i;
189                 x_qc=[x_qc,i0];     %将此时的列位置进行记录
190                 %Step2 检查阶梯元素是否为1,若不为1,则将其化为1
191                 if c(i,i0)~=0&&c(i,i0)~=0;
192                     c(i,:)=c(i,:)/c(i,i0);
193                 end
194                 %Step3 将i0列,第i行一下的元素消减为0
195                 for j=i+1:m1
196                     if c(j,i0)~=0
197                         c(j,:)=c(j,:)-c(j,i0)*c(i,:);
198                     end
199                 end
200                 %Step4 将i0列,第i行一上的元素消减为0
201                 for j=1:i-1
202                     if c(j,i0)~=0
203                         c(j,:)=c(j,:)-c(j,i0)*c(i,:);
204                     end
205                 end
206             end
207             %更新!检查最后一行
208             if sum(abs(c(m1,[1:n1])))~=0
209                 c(m1,:)=c(m1,:)/c(m1,n1);
210                 for j=1:m1-1
211                     if c(j,n1)~=0
212                         c(j,:)=c(j,:)-c(j,n1)*c(m1,:);
213                     end
214                 end
215             end
216             
217             %成功化为标准型
218             %disp(c)
219             %二、求解
220             %c变换后,其b的位置的数据即为解
221             jx=c(:,[n1+1:end]);
222             %三、输出结果
223             d=jx;
224             disp '非齐次型,唯一解'
225             
226             %无穷多解
227         elseif ra==rc&&rc<n1
228             %思路:
229             %一、矩阵变换(利用齐次方程的代码)
230             for i=1:m1-1;    %需要对行数-1行进行行变换
231                 %选中了第i行
232                 %如果都为非线性相关的向量,则阶梯的行列数相等,若存在线性相
233                 %的向量,则需要构造一个i0来表示阶梯对应的列,并用i1表示列于
234                 %行数的差值。
235                 i0=i1+i;
236                 %因为i1的值根据本行元素具体情况确定,因此需要注意,应当在这
237                 %个for循环内完成下三角、化为1、上三角的所有操作。
238                 %Step01 检查阶梯元素是否等于零
239                 %       若等于零,则需要与第一个不为零的行对调,若全为零,
240                 %       则i1+1,并再次循环。
241                 pj_01=0;%初始化以下循环的判据
242                 while pj_01==0 %利用判据pj_01来判断是否需要再次循环,在循环中,通过修改pj的值来跳出循环。
243                     pj_01=1;    %没有特殊情况执行完跳出循环
244                     i0=i+i1;
245                     if c(i,i0)==0
246                         %01 找到第i0列,i行及以下第一个非零元素的位置k
247                         k=find(c([i+1:end],i0));
248                         %k=k(1);
249                         %02 将k行与i行对调(若k为空集,应当i1+1并再循环)
250                         if k~=[];           %k不为空集时,将k行与i行对调
251                             k=k(1);
252                             e=c(i,:);
253                             c(i,:)=c(k,:);
254                             c(k,:)=e;
255                             pj_01=1;
256                         elseif isempty(k)==1;       %k为空集时,i1+1并再循环
257                             i1=+1;
258                             i0=i1+i;
259                             pj_01=0;        %将判据设为0,再次循环
260                         end
261                     end
262                 end
263                 i0=i1+i;
264                 x_qc=[x_qc,i0];     %将此时的列位置进行记录
265                 %Step2 检查阶梯元素是否为1,若不为1,则将其化为1
266                 if c(i,i0)~=0&&c(i,i0)~=0;
267                     c(i,:)=c(i,:)/c(i,i0);
268                 end
269                 %Step3 将i0列,第i行一下的元素消减为0
270                 for j=i+1:m1
271                     if c(j,i0)~=0
272                         c(j,:)=c(j,:)-c(j,i0)*c(i,:);
273                     end
274                 end
275                 %Step4 将i0列,第i行一上的元素消减为0
276                 for j=1:i-1
277                     if c(j,i0)~=0
278                         c(j,:)=c(j,:)-c(j,i0)*c(i,:);
279                     end
280                 end
281             end
282             %更新!检查最后一行
283             if sum(abs(c(m1,[1:n1])))~=0
284                 c(m1,:)=c(m1,:)/c(m1,n1);
285                 for j=1:m1-1
286                     if c(j,n1)~=0
287                         c(j,:)=c(j,:)-c(j,n1)*c(m1,:);
288                     end
289                 end
290             end
291             
292             %成功化为标准型
293             %disp(c)
294             %二、求特解Psit
295             x_fqc=x_qc;                 %为了便于阅读,使用x_fqc代替x_qc
296             Psit=zeros(1,n1);           %初始化特解(长度:a的列数)
297             nx=length(x_fqc);           %nx为线性无关向量的数量
298             for i=1:nx
299                 ip=x_fqc(i);
300                 Psit1=c(:,[n1+1:end]);
301                 Psit(ip)=Psit1(i);
302                 disp(Psit);
303             end
304             Psit=Psit';
305             %三、构造对应齐次方程,并解出基础解系
306             b1=zeros(size(b));
307             
308             px=ones(1,n1);
309             px(x_fqc)=0;
310             px=find(px);
311             npx=length(x_fqc);
312             a1=a;
313             %for i=1:npx
314             %    ipx=px(i);
315             %    a1(:,ipx)=a1(:,ipx)*-1;
316             %    disp(a1);
317             %end
318             
319             d1=CDBH_for_sov_JZFC(a1,b1);
320             %四、构造通解
321             tj=[d1,Psit];
322             %五、输出结果
323             d=tj;
324             disp '非齐次,一般解:'
325             disp 'x=k1*psi1+...+kn*psin+psit'
326         else
327             error('输入有误,无法计算');
328             return;
329         end
330 end       

 

2、例子(用于验证)

(1)齐次方程(无限解):

1 a=[1,1,-1,-1;2,-5,3,2;7,-7,3,1];
2 b=[0,0,0]';

结果:

MATLAB中矩阵方程求解的实现_第2张图片

 

(2)非齐次方程(唯一解):

1 a=[89,14,81,19;95,25,24,25;54,84,92,61;13,25,34,47];
2 b=[436,317,742,353]';

结果:

>>x =
       1       
       2       
       3       
       4 

 

(3)非齐次方程(无限解):

1 a=[1,-1,-1,1;1,-1,1,-3;1,-1,-2,3];
2 b=[0,1,-1/2]';

结果:

MATLAB中矩阵方程求解的实现_第3张图片

转载于:https://www.cnblogs.com/Martin-Soaring/p/9737125.html

你可能感兴趣的:(MATLAB中矩阵方程求解的实现)