faint….高斯算法有问题.以至求出的秩经常不是正确值,我倒.据说还是java算浮点数的问题.算了.
要不改用C++写好了.明天再试试.换个方法重写高斯消元函数.奇怪的是计算行列式值的时候又没错.
/**
* 求矩阵的秩
* @return 秩
*/
public int matrixOrder(){
//高斯消元化为上三角
guass();
this.displayMatrix(a);
int r=a.length-1;
//初始值为矩阵的行数
int count=r+1;
int c=a[0].length-1;
boolean flag=true;
//自底向上循环查找非零,非无穷,非NaN的值.发现则跳出循环
for(int i=r;i>=0&&flag;i–){
flag=true;
for(int j=c;j>=0;j–){
//高斯消元后的结果可能为无穷和非数字,加上判断
if(a[i][j]!=0&&!Double.isNaN(a[i][j])&&!Double.isInfinite(a[i][j]))flag=false;
}
//每一个满足条件的行则count减一
if(flag==true)count–;
}
return count;
}
update: 确实是java浮点数运算的问题.
Math.sqrt(-1.0) -> NaN
0.0 / 0.0 -> NaN
1.0 / 0.0 -> 无穷大
-1.0 / 0.0 -> 负无穷大
NaN + 1.0 -> NaN
无穷大 + 1.0 -> 无穷大
无穷大 + 无穷大 -> 无穷大
NaN > 1.0 -> false
NaN == 1.0 -> false
NaN < 1.0 -> false
NaN == NaN -> false
0.0 == -0.01 -> true
http://www-128.ibm.com/developerworks/cn/java/j-jtp0114/
NaN(Not a Number)
在运行高斯消元函数是结果中多次出现了NaN.而不是正常的数字.这是由于运算时使用了数学上未定义的方法..我没看出来哪个方法数学上没有定义.但这给后面的求秩和求线性方程通解带来麻烦.判断的时候不能用是否为零来判断.还必须用 Double.isNaN()和 Double.isInfinite()来判断是否非数字和是否为无穷大,判断条件就判断无效条件是否成立而不是通常的有效条件.刚写了一个矩阵乘法.很简单东西竟然还出错.郁闷ing..调试半天才看出来 原来时运算符打错了.把 R[i][j]+=aa[i][k]*ma[k][j];的乘号写成家.汗..
public int[][] matrixMultiply(int[][] ma)throws IllegalArgumentException{
//this.displayMatrix(ma);
if(aa[0].length!=ma.length)throw new IllegalArgumentException(“被乘矩阵的列数应等于要乘的矩阵的行数”);
int[][] R=new int[aa.length][ma[0].length];
for(int i=0;i
this.displayMatrix(R);
return R;
}
这两天偷懒了..后面是写线性方程通解.和使用Strassen的矩阵乘法.还有矩阵连乘.明天继续吧.
圣经感想 (一)
今天又开始读圣经.忍不住想写点东西.
第一章
And Jehovah God commanded the man, saying, Of every tree of the garden thou mayest freely eat:
but of the tree of the knowledge of good and evil, thou shalt not eat of it: for in the day that thou eatest thereof thou shalt surely die
?为什么god不让人知道善恶?还骗他们说吃了果子就会死.
Now the serpent was more subtle than any beast of the field which Jehovah God had made. And he said unto the woman, Yea, hath God said, Ye shall not eat of any tree of the garden?
蛇真的很狡猾?它并没有骗Adam and Eve
And the serpent said unto the woman, Ye shall not surely die:
for God doth know that in the day ye eat thereof, then your eyes shall be opened, and ye shall be as God, knowing good and evil.
确实.吃了果子并不会死,我觉得人类有现在应该感谢蛇.不然还是笨笨的和小白鼠没什么区别
God said, Behold, the man is become as one of us, to know good and evil; and now, lest he put forth his hand, and take also of the tree of life, and eat, and live for ever- therefore Jehovah God sent him forth from the garden of Eden, to till the ground from whence he was taken.
原来神把亚当和夏娃赶出来是怕他们吃了生命树的果子.然后就会和神一样永生.赶出去以后还派人守树.
Cain and Abel 亚当和夏娃的两个儿子,Cain把Abel杀了.因为Jehovah had respect unto Abel and to his offering:
亚当竟然活了这么久Adam lived were nine hundred and thirty years: and he died.
Adam(130)->Seth(105)-> Enosh(90)-> Kenan(70)-> Mahalalel(65)-> Jared (162)-> Enoch(65)-> Methuselah(187)-> Lamech(182)->Noah
诺亚竟然是亚当第九代.而且他们的父辈都是几十上百岁的时候才生的下一代.最大的187有下一代.最小的也65.呵.晚育的代表嘛.
诺亚更夸张Noah was five hundred years old: And Noah begat Shem, Ham, and Japheth,500岁的时候才3个儿子
上帝的儿子们好像也是很”色”的?喜欢哪个人类女子就要哪个老婆
the sons of God saw the daughters of men that they were fair; and they took them wives of all that they chose.
上帝看着不行呀.生出来的是神?那不就一大堆小神了噢.就决定这样的生出来只能活120岁,但是生出来后来都是有名的人物嘛.
And Jehovah said, My spirit shall not strive with man for ever, for that he also is flesh: yet shall his days be a hundred and twenty years,The Nephilim were in the earth in those days, and also after that, when the sons of God came unto the daughters of men, and they bare children to them: the same were the mighty men that were of old, the men of renown.
上帝为什么要用洪水毁灭人类和其他动物?
上帝看来下面人天天想的很邪恶的事情
And Jehovah saw that the wickedness of man was great in the earth, and that every imagination of the thoughts of his heart was only evil continually
于是就感觉很失败
And it repented Jehovah that he had made man on the earth, and it grieved him at his heart.
就决定要毁灭一切.开始”屠杀”
And Jehovah said, I will destroy man whom I have created from the face of the ground; both man, and beast, and creeping things, and birds of the heavens; for it repenteth me that I have made them.
但是上帝也不好如此不留后路嘛所以还留了一手,找到一个听话的,放他一条生路,不知道那些神的儿子们是不是也 被淹死?
These are the generations of Noah. Noah was a righteous man, [and] perfect in his generations: Noah walked with God.
下面该建方舟了.
Make thee an ark of gopher wood; rooms shalt thou make in the ark, and shalt pitch it within and without with pitch. And this is how thou shalt make it: the length of the ark three hundred cubits, the breadth of it fifty cubits, and the height of it thirty cubits.A light shalt thou make to the ark, and to a cubit shalt thou finish it upward; and the door of the ark shalt thou set in the side thereof; with lower, second, and third stories shalt thou make it.
船造好了就该洪水了嘛.
先是rain was upon the earth forty days and forty nights. 然后And the flood was forty days upon the earth;
水这样深Fifteen cubits upward did the waters prevail; and the mountains were covered.这样的深度还持续了这么多天And the waters prevailed upon the earth a hundred and fifty days. 然后开始退水了,水是在
In the six hundredth year of Noah’s life, in the second month, on the seventeenth day of the month,开始的.
然后10月1号山顶才露出来in the tenth month, on the first day of the month, were the tops of the mountains seen. 又过了40天.Noah才打开窗户And it came to pass at the end of forty days, that Noah opened the window of the ark which he had made,放了一只乌鸦出去.然后乌鸦没地方降落就飞了飞去he sent forth a raven, and it went forth to and fro,然后又放了一只鸽子.And he sent forth a dove from him, 当然结果只能是the dove found no rest for the sole of her foot,七天以后又放出鸽子.鸽子给他叼回来一个橄榄枝.橄榄枝代表和平什么的应该就是出自这里吧.And he stayed yet other seven days; and again he sent forth the dove out of the ark,and the dove came in to him at eventide; and, lo, in her mouth an olive-leaf plucked off: so Noah knew that the waters were abated from off the earth.
呵.有意思的时候再过了7天.又放了一只鸽子.鸽子就不回来了.
And he stayed yet other seven days, and sent forth the dove; and she returned not again unto him any more. 到第二年的1月1号.地上水才干And it came to pass in the six hundred and first year, in the first month, the first day of the month, the waters were dried up from off the earth:
System.arraycopy
运行以下两段代码:
代码1:
String[][] sa1 = new String[][]{{“a11”, “a12”},{“a21”, “a22”}};
String[][] sa2 = new String[sa1.length][sa1[0].length];
System.arraycopy(sa1,0, sa2, 0, sa1.length);
System.out.println(“sa1[0][0] : ” + sa1[0][0]);
System.out.println(“sa2[0][0] : ” + sa2[0][0]);
sa1[0][0] = “XXXXX”;
System.out.println(“———————“);
System.out.println(“sa1[0][0] : ” + sa1[0][0]);
System.out.println(“sa2[0][0] : ” + sa2[0][0])
输出:
sa1[0][0] : a11
sa2[0][0] : a11
———————
sa1[0][0] : XXXXX
sa2[0][0] : XXXXX
代码2:
String[] sa1 = new String[]{“a11”, “a12”};
String[] sa2 = new String[sa1.length];
System.arraycopy(sa1,0, sa2, 0, sa1.length);
System.out.println(“sa1[0] : ” + sa1[0]);
System.out.println(“sa2[0] : ” + sa2[0]);
sa1[0] = “XXXXX”;
System.out.println(“———————“);
System.out.println(“sa1[0] : ” + sa1[0]);
System.out.println(“sa2[0] : ” + sa2[0]);
输出:
sa1[0] : a11
sa2[0] : a11
———————
sa1[0] : XXXXX
sa2[0] : a11
可见,当数组是两维时,对源数组的改变也影响到了目标数组,但一维数组却不会有问题。要当心的。。。
行列式,矩阵,线性方程组,逆阵 java算法
行列式,矩阵,线性方程组,逆阵
package org.dean;
import javax.swing.*;
public class fun {
private double[][]a;
private int[][]aa;
public fun(double[][] aa){
a=new double[aa.length][aa[0].length];
System.arraycopy(aa,0,a,0,aa.length);
}
public fun(int[][] a){
aa=new int[a.length][a[0].length];
System.arraycopy(a,0,aa,0,a.length);
}
public void displayMatrix(int aa[][]){
for(int[] df:aa){
System.out.println();
for(int d:df)
System.out.print(d+” “);}
}
public void displayMatrix(double aa[][]){
for(double[] df:aa){
System.out.println();
for(double d:df)
System.out.print(d+” “);}
}
/**
* 使用高斯消元解行列式
* @param aa 二维double数组
*/
public double guass(){
double arrangerResult=1.0;
double k=0;
if(a[0].length!=a.length)throw new IllegalArgumentException(“行列式的行列数必须相等”);
for (int p = 0; p for (int r =p+1; r
a[r][p]=0;
for (int c = p+1; c a[r][c]=a[r][c]-k*a[p][c];
}
}
}
for (int i = 0; i
}
return arrangerResult;
}
public int arra(){
int c,l,sum;
int A[];
c=aa[0].length;
l=aa.length;
//第一行的代数余子式
A=new int[c];
sum=0;
//若行列数不相等
if(c!=l) throw new IllegalArgumentException(“行列式的行数和列数必须相等”);
//到达最小单位2*2,计算出值
if(c==2)return aa[0][0]*aa[1][1]-aa[0][1]*aa[1][0];
//按第一行展开,计算代数余子式
for(int i=0;i
//求第一行第i个元素的代数余子式
A[i]=solveA(aa,0,i);}
else{
A[i]=solveA(aa,0,i)*(-1);}
sum+=aa[0][i]*A[i];
}
return sum;
}
public int arra(int aa[][]){
int c,l,sum;
int A[][];
c=aa[0].length;
l=aa.length;
A=new int[c][l];
sum=0;
if(c!=l) throw new IllegalArgumentException(“行列式的行数和列数必须相等”);
if(c==2)return aa[0][0]*aa[1][1]-aa[0][1]*aa[1][0];
for(int i=0;i
A[0][i]=solveA(aa,0,i);}
else{
A[0][i]=solveA(aa,0,i)*(-1);}
sum+=aa[0][i]*A[0][i];
}
return sum;
}
/**
* 计算aa[][]第i行的j列元素的代数余子式
* @param aa 整形数组
* @param ii 元素的行号
* @param jj 元素的列号
* @return 代数余子式的行列式的值
*/
public int solveA(int aa[][],int ii,int jj){
//余子式元素
int a[][];
int c,l,m;
int x=-1,y=0;
c=aa[0].length-1;
l=aa.length-1;
//每次都按第一 行展开的余子式的行列式的值
int A[];
int sum=0;
A=new int[c];
a=new int[c][l];
for(int i=0;i<=c;i++){
//如果元素的行号等于要求余子式的行号则跳过
if(i==ii){continue;}
y=0;x++;
for(int j=0;j<=c;j++){
//如果元素的列号等于要求余子式的列号则跳过
if(j==jj){continue;
}else{
a[x][y]=aa[i][j];
y++;}
}}
if(c==2)return a[0][0]*a[1][1]-a[0][1]*a[1][0];
// 递归调用.每次都按第一行展开
for(int i=0;i
A[i]=solveA(a,0,i);
else
A[i]=solveA(a,0,i)*(-1);
sum+=a[0][i]*A[i];
}
return sum;
}
/**
* 输入增广矩阵求解线性方程组解
* @return 包含解的double数组
*/
public double[] formula(){
int c=aa[0].length-1;
int r=aa.length;
if(r!=(c)) throw new IllegalArgumentException(“必须是增广矩阵.且行数比列数少1 “);
int D[]=new int[c];
//A矩阵存放解
double A[]=new double[c];
int a[][]=new int[r][c];
for(int i=0;i
//求出系数矩阵行列式的值
int DD=arra(a);
for(int k=0;k
}
//第k列用最后一列替换
a[i][k]=aa[i][c];
}
//求出第k列用最后一列替换以后的 行列式的值
D[k]=arra(a);
//求出解
A[k]=D[k]/(double)DD;
}
return A;
}
/**
* 求方阵的逆阵
*
*
* @return 逆阵
*/
public double[][] nizhen()
{
int c,l,sum;
double A[][];
c=aa[0].length;
l=aa.length;
A=new double[c][l];
double he=arra(aa);
//如果只有2*2 则主对角线交换,副对角线取负即为A*
if(c==2){
A[0][0]=aa[1][1];
A[1][1]=aa[0][0];
A[1][0]=aa[0][1]*(-1);
A[0][1]=aa[1][0]*(-1);
//displayMatrix(A);
return A;
}
for(int i=0;i
A[j][i]=solveA(aa,i,j)/he;}
else{
A[j][i]=(solveA(aa,i,j)*(-1))/he;}
}
//displayMatrix(A);
return A;
}
}
今天重写了一次..使用了jdk5.0 的for while功能.不错.十分好用.只是递归的效率太低.高阶的几乎就是解不出来了.在想办法..