矩子編程
A. MATLAB編程與應用系列-第3章 矩陣運算(4)
矩陣的分解是矩陣相關運算中的重要內容,MATLAB提供了用於矩陣分解運算的多種函數。本節將集中介紹MATLAB所提供的矩陣分解運算函數的功能及使用。
矩陣的三角分解又稱高斯消去法分解,它的目的是將一個矩陣分解成一個下三角矩陣L和一個上三角矩陣U的乘積,即A=LU。MATLAB提供了專門的函數lu來計算矩陣的LU分解。該函數的調用格式如下:
其中,返回矩陣U為上三角陣,矩陣L為下三角陣或其變換形式,且滿足LU=X。返回矩陣P為單位矩陣的行變換矩陣,滿足LU=PX。
奇異值分解在矩陣分析中佔有極其重要的作用。MATLAB提供了用於矩陣奇異值分解的函數svd,該函數是利用LINPACK程序庫中的ZSVDC編制而成的。在計算的過程中假如經過75步QR分解仍得不到一個奇異值,那麼系統會給出「不收斂」的提示。奇異值分解函數svd的幾種調用格式如下:
其中,命令①返迴向量s包含矩陣X分解所得到的全部奇異值向量。命令② 返回一個與X同大小的對角矩陣S和兩個酉矩陣U與V,且滿足= U S V'。命令③ 得到一個「有效大小」的分解,如果m×n維矩陣X中m>n則只計算出矩陣U的前n列,矩陣S的大小為n×n。
MATLAB提供了eig函數來對矩陣進行特徵值分解,該函數的幾種調用格式如下:
其中,①計算矩陣A的特徵值d,返回結果以向量形式存放。②計算方陣A和B的廣義特徵值d,返回結果以向量形式存放。③計算矩陣A的特徵值對角陣D和特徵向量陣V,使AV=VD成立。④計算矩陣A的特徵值對角陣D和特徵向量陣V,使AV=VD成立。當矩陣A中有與截斷誤差數量級相差不遠的值時,該指令可能更精確。'nobalance'起誤差調節作用。⑤計算矩陣A和B的廣義特徵值向量陣V和廣義特徵值陣D,滿足AV=BVD。最後一條命令⑥由flag指定演算法計算矩陣A和B的特徵值D和特徵向量V。其中,flag的可能值為:'chol' 和'qz' 。當flag值為'chol'時表示對B使用Cholesky分解演算法,其中A為對稱Hermitian矩陣,B為正定陣。當flag值為'qz'時表示使用QZ演算法,其中A、B為非對稱或非Hermitian矩陣。
MATLAB提供了chol函數來對矩陣進行Cholesky分解,該函數的調用格式為:
函數調用格式①如果X為n階對稱正定矩陣,則存在一個實的非奇異上三角陣R,滿足R'*R = X;若X非正定,則產生錯誤信息。②不產生任何錯誤信息,若X為正定陣,則p=0,R與上相同;若X非正定,則p為正整數,R是有序的上三角陣。
正交矩陣是指矩陣的列向量相互正交,且各個列向量的長度相等。QR分解就是將矩陣A分解成一個正交矩陣與一個上三角矩陣的乘積。MATLAB提供了用於矩陣QR分解的函數,表3.7中介紹用於矩陣QR分解的函數調用格式和功能。
表3.7 矩陣QR分解
Schur分解將使用schur函數,該函數的調用格式為:
命令行①-③返回正交矩陣U和schur矩陣T,滿足A = U T U'。其中,若A有復特徵根,則flag='complex',否則flag='real'。
即使是實陣,在其特徵值中也可能出現復數。實際使用中常需要把這一對對共軛復數特徵值轉化為一個(2x2)的實數塊。函數調用格式為:
MATLAB提供了gsvd函數對矩陣進行廣義奇異值分解,其具體調用格式為:
其中,函數調用格式①返回酉矩陣U和V、一個普通方陣X、非負對角矩陣C和S,滿足A = U C X',B = V S X',C' C + S' S = I (I為單位矩陣)。A和B的列數必須相同,行數可以不同。函數調用格式②和①基本相同,而③則返回廣義奇異值sigma值。
MATLAB提供了qz函數對矩陣進行特徵值問題的QZ分解,該函數的調用格式為:
其中函數調用格式①中A、B為方陣,返回結果AA和BB為上三角陣,Q、Z為正交矩陣或其列變換形式,V為特徵向量陣,且滿足Q A Z= AA 和Q B Z = BB。命令行②產生由flag決定的分解結果,flag取值為'complex'表示復數分解(默認);取值為'real'表示實數分解。
如果矩陣H的第一子對角線下元素都是0,則H為海森伯格(Hessenberg)矩陣。如果矩陣是對稱矩陣,則它的海森伯格形式是對角三角陣。MATLAB可以通過相似變換將矩陣變換成這種形式,具體調用格式為:
B. Matlab 矩陣程序求解
先建立一個M文件:
function y=t(x)
y=[1 x x.^2 x.^3];
然後在MATLAB內執行:
>> Y=[t(1);t(2);t(3)]
Y =
1 1 1 1
1 2 4 8
1 3 9 27
這樣子便可以得到你想要的矩陣了。如果要是想在一個M文件內完成全部計算的話,你在M文件內再加上x的取值就可以了。
C. matlab 矩陣編程問題
y
=
[1:30];
%給出y
x
=
[0:2]';
%給出x
yTanspose
=
zeros(3,
10);
%定義劃分並轉置後的存儲矩陣
for
i
=
1
:
10
yTranspos(:,
i)
=
(y(3*i-2,
3i))';
%將y按每3個一組進行劃分,並進行轉置
end
xcord
=
[1:10];
%用於畫圖的x坐標
yNorm
=
xcord;
%用於畫圖的矩陣模
for
i
=
1
:
10
yNorm(i)
=
norm(yTranspos(:,
i)
-
x);
%求劃分後的子向量與x的差的模
end
plot(xcord,
yNorm);
D. C語言編程求矩陣乘積
#defineMAX50
#defineMMAX
#defineNMAX
#defineTMAX
#defineSMAX
intMult(doublea[][N],intm,intn,doubleb[][T]ints,intt,doublec[][T]){
inti,j,k;
if(n!=s){
printf("兩矩陣相乘,左矩陣的列數與右矩陣的行數必須相等。 ");
return0;
}
intc;
tmp.m_Mat=newdouble*[tmp.m_Rows];
for(inti=0;i<tmp.m_Rows;i++)tmp.m_Mat[i]=newdouble[tmp.m_Cols];
for(i=0;i<m;++i){
for(j=0;j<n;++j){
c[i][j]=0;
for(k=0;k<t;++k)
c[i][j]+=c[i][k]*c[k][j];
}
}
return1;
}
E. 如何用C++編程求矩陣的逆
#define N 5 /*[注]:修改6為你所要的矩陣階數*/
#include "stdio.h"
#include "conio.h"
/*js()函數用於計算行列式,通過遞歸演算法實現*/
int js(s,n)
int s[][N],n;
{int z,j,k,r,total=0;
int b[N][N];/*b[N][N]用於存放,在矩陣s[N][N]中元素s[0]的餘子式*/
if(n>2) {for(z=0;z<n;z++)
{for(j=0;j<n-1;j++)
for(k=0;k<n-1;k++)
if(k>=z) b[j][k]=s[j+1][k+1];
else b[j][k]=s[j+1][k];
if(z%2==0) r=s[0][z]*js(b,n-1); /*遞歸調用*/
else r=(-1)*s[0][z]*js(b,n-1);
total=total+r;
}
}
else if(n==2) total=s[0][0]*s[1][1]-s[0][1]*s[1][0];
return total;
}
/*n_1()函數用於求原矩陣各元素對應的餘子式,存放在數組b[N][N]中,定義為float型*/
void n_1(s,b,n)
int s[][N],n;
float b[][N];
{int z,j,k,l,m,g,a[N][N];
for(z=0;z<n;z++)
{l=z;
for(j=0;j<n;j++)
{ m=j;
for (k=0;k<n-1;k++)
for(g=0;g<n-1;g++)
{ if(g>=m&&k<l) a[k][g]=s[k][g+1];
else if(k>=l&&g<m) a[k][g]=s[k+1][g];
else if(k>=l&&g>=m) a[k][g]=s[k+1][g+1];
else a[k][g]=s[k][g];
}
b[z][j]=js(a,n-1);
}
}
}
main()
{int a[N][N];
float b[N][N];
int r,z,j;
float temp;
//clrscr();
printf("Input original data:\n");
for(z=0;z<N;z++) /*輸入所需要的數據,為整型數據*/
for(j=0;j<N;j++)
scanf("%d",&a[z][j]);
printf("\nPress Enter continue......");
getchar();
//gotoxy(1,1);
printf("The original matrix is:\n");
for(z=0;z<N;z++)/*列印原矩陣*/
{for(j=0;j<N;j++)
printf("%5d",a[z][j]);
printf("\n");
}
r=js(a,N); /*調用js()函數計算原矩陣的行列式值*/
printf("\nThe original matrix hanglieshi is:|A|==%d\n",r);
if (r==0) printf("Because |A|==0,the original matrix have no nijuzhen!"); /*判斷條件:若|A|==0,則原矩陣無逆矩陣,反之則存在逆矩陣*/
else
{n_1(a,b,N); /*調用n_1()函數,得到原矩陣各元素對應的"餘子式",存放在數組b[N][N]中*/
for(z=0;z<N;z++) /*求代數餘子式,此時b[N][N]中存放的為原矩陣各元素對應的"代數餘子式"*/
for(j=0;j<N;j++)
if((z+j)%2!=0 && b[z][j]!=0) b[z][j]=-b[z][j];
for(z=0;z<N;z++) /*對b[N][N]轉置,此時b[N][N]中存放的為原矩陣的伴隨矩陣*/
for(j=z+2;j<N;j++)
{temp=b[z][j];
b[z][j]=b[j][z];
b[j][z]=temp;
}
printf("Because |A|!=0,the original matrix have nijuzhen!\n");
printf("The bansuijuzhen A* is:\n");
for(z=0;z<N;z++)/* 列印伴隨矩陣A* */
{for(j=0;j<N;j++)
printf("%4.0f\t",b[z][j]);
printf("\n");
}
for(z=0;z<N;z++) /*求逆矩陣,此時b[N][N]中存放的是原矩陣的逆矩陣*/
for(j=0;j<N;j++)
b[z][j]=b[z][j]/r;
printf("\nThe nijuzhen is:(A*)/|A|(|A|=%d)\n",r); /*列印逆矩陣*/
for(z=0;z<N;z++)
{for(j=0;j<N;j++)
printf("%8.3f",b[z][j]);
printf("\n");
}
}
}
F. 編程問題:輸入一個N,輸出一個矩陣
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
printf("%s","輸入N:");
int flag=0;
int n=0; //保存矩陣階數
scanf("%d",&n);
int length=((1+n)*n)/2; //計算矩陣元素個數
int m[length]; //按照矩陣元素的個數初始化一個數組存儲所有的數據
/*
*
*初始化數組,全部清0;
*/
for(int i=0;i<length;i++)
{
m[i]=0;
}
/*
*
*觀察矩陣每行最後一個數,並且往左增長的步長有一定規律。
*/
for(int i=n;i>0;i--)
{
m[flag]=i; //每一行最後一個數
for(int j=1;j<i;j++) //每一行按n-1,n-2,n-3....的步長規律增長
{
m[flag+1]=m[flag]+ n-j;
flag=flag+1;
}
flag+=1;
}
//printf("%d\n",flag);
// for(int i=0;i<length;i++){
// printf("%d ",m[i]);
// }
for(int i=0;i<n;i++)
{
for(int j=0;j<=i;j++)
{
printf("%d ",m[--flag]);
}
printf("\n");
}
system("PAUSE");
return EXIT_SUCCESS;
}
G. 用java語言編程.有一個5×4的矩陣,要求編程序求出其中值最大的那個元素的值,以及其所在的行號和列號.
importjava.util.Random;
publicclassTest2{
publicstaticvoidmain(String[]args){
//初始化出一個5X4的矩陣
int[][]a=newint[5][4];
Randomr=newRandom();
for(inti=0;i<a.length;i++){
for(intj=0;j<a[i].length;j++){
a[i][j]=r.nextInt(100);
System.out.print(a[i][j]+"");
}
System.out.println();
}
//找最大值
intmax=a[0][0];
intmaxi=0;
intmaxj=0;
for(inti=0;i<a.length;i++){
for(intj=0;j<a[i].length;j++){
if(a[i][j]>max){
max=a[i][j];
maxi=i;
maxj=j;
}
}
}
System.out.println("maxvalue:"+max+"maxindex:["+maxi+"]["+maxj+"]");
}
}
