Runninghigh
Programmer
- Jun 20, 2015
- 5
I have a problem.
I can only a little bit fortran. So I write a program first in Java, then I try to translate it in Fortran.
First my Java-Prgram:
This program calculates the determinant of a nxn matrix by Laplace. This program works.
The methode public static double determinante(double [][] array, int matrix_groesse) is the recursive methode, the heart of the program.
Termination condition is the Size of Matrix -> 2x2.
This program solve all testing problems. For example the test you see in the program. Determinante=6
Now my Fortran-Program
The recursive function is double precision recursive function determinante_laplace(array, groesse_matrix)result(det).
In my opinion this function is equal to the methode in java.
But it isn't so. The Fortran-program solve only 3x3 Matrix. Is the matrix higher, the result is wrong. Why?
I'am sorry for my bad english. I hope, you can understand my problem and can help to solve it.
I can only a little bit fortran. So I write a program first in Java, then I try to translate it in Fortran.
First my Java-Prgram:
Java:
public static void main(String[] args)
{
int matrix_groesse=4;
double [][] array=new double[matrix_groesse][matrix_groesse];
array[0][0]=4;
array[0][1]=1;
array[0][2]=0;
array[0][3]=1;
//array[0][4]=-3;
//array[0][5]=-4;
//array[0][6]=-5;
array[1][0]=-2;
array[1][1]=0;
array[1][2]=-2;
array[1][3]=2;
//array[1][4]=-4;
//array[1][5]=-0;
//array[1][6]=-1;
array[2][0]=-1;
array[2][1]=1;
array[2][2]=-4;
array[2][3]=4;
//array[4][4]=4;
//array[4][5]=1;
//array[4][6]=-3;
array[3][0]=-5;
array[3][1]=-4;
array[3][2]=5;
array[3][3]=0;
//array[2][4]=0;
//array[2][5]=1;
//array[2][6]=-4;
/*array[3][0]=-2;
array[3][1]=-4;
array[3][2]=2;
array[3][3]=-5;
array[3][4]=-1;
array[3][5]=2;
array[3][6]=0;
array[5][0]=3;
array[5][1]=-3;
array[5][2]=-3;
array[5][3]=4;
array[5][4]=-2;
array[5][5]=-5;
array[5][6]=1;
array[6][0]=-2;
array[6][1]=-5;
array[6][2]=3;
array[6][3]=-2;
array[6][4]=3;
array[6][5]=1;
array[6][6]=-5;*/
Zeitmesser.startMessung(1);
System.out.println("Determinante = "+Double.toString(Formelsammlung.determinante(array,matrix_groesse)));
Zeitmesser.stopMessung(1);
System.out.println("Zeit: "+Double.toString(Zeitmesser.getErgebnis(1)/1000)+" Sekunde");
}
public static double determinante(double [][] array) //2x2 Matrix => det = 0/0*1/1-0/1*1/0
{
return (array[0][0]*array[1][1])-(array[0][1]*array[1][0]);
}
public static double[][] laplace(double [][] array,int groesse_matrix, int spalte) //reduce matrix nxn into a matrix n-1*n-1
{
double [][] array_=new double[groesse_matrix-1][groesse_matrix-1];
int k,l;
k=0;
l=0;
for (int i=1;i<groesse_matrix;i++)//beginn mit zeile 1, da zeile 0 immer die ausgewählte Zeile ist
{
{
for(int j=0;j<groesse_matrix;j++)
{
if(j!=spalte) //aktuelle spalte wird nicht berücksichtigt
array_[k][l++]=array[i][j];
}
}
k++;
l=0;
}
return array_;
}
public static double determinante(double [][] array, int matrix_groesse)
{
int vorzeichen=1;
double [][] array2;
double faktor;
double zwischensumme=0;
double endsumme=0;
if (matrix_groesse==2) //terminated by 2x2 matrix, liefert determinante einer 2x2-matrix
{
return Formelsammlung.determinante(array);
}
else
{
for (int i=0;i<matrix_groesse;i++)
{
zwischensumme=0;
array2=laplace(array, matrix_groesse,i);
faktor=array[0][i]*vorzeichen;
vorzeichen*=-1;
if(faktor!=0)
{
zwischensumme=faktor*determinante(array2,matrix_groesse-1);
}
endsumme+=zwischensumme;
}
return endsumme;
}
}
This program calculates the determinant of a nxn matrix by Laplace. This program works.
The methode public static double determinante(double [][] array, int matrix_groesse) is the recursive methode, the heart of the program.
Termination condition is the Size of Matrix -> 2x2.
This program solve all testing problems. For example the test you see in the program. Determinante=6
Now my Fortran-Program
Code:
program determinante
double precision, dimension(:,:),allocatable::array !Startmatrix mit groesse matrix_groesse
integer::groesse_matrix !Groesse der Startmatrix
integer ::i,j !schleifenvariablen
double precision ::ergebnis=0 !Ergebnis der Determinante für die Startmatrix
character(len=10)::hilf !Wird nur für die sichtbare Lösung aus Start der Exe-Datei benötigt
! Öffnen der Eingabedatei, Einlesen
!**************************************************************************!
open(10,file='vierer.txt')
read(10,*) groesse_matrix
! Zuweisung der Matrixgrößen, Einlesen der Matrix und Schließen der Eingabedatei
allocate(array(groesse_matrix,groesse_matrix))
do i=1,groesse_matrix
read(10,*) (array(i,j),j=1,groesse_matrix)
end do
close(10)
!Darstellung der zu berechnenden Matrix
print*, 'Berechnung der Determinanten von zweier bis siebener Matrix'
print*, '==========================================================='
print*
print*, 'gewaehlte Matrixgroesse = ', groesse_matrix
print*
print*,'Matrix ='
do i=1,groesse_matrix
do j=1,groesse_matrix
write(*,'(F7.1)',advance="no") array(i,j)
end do
print*
end do
print*
ergebnis=determinante_laplace(array,groesse_matrix)
!Freigeben des Speichers array
deallocate(array)
!Ergebnisausgabe
print*
print*,'Determinante = ', ergebnis
!Unterbrechung damit das Programm mit sichtbaren Ergebnis auch bei Start der Exe-Datei angezeigt bleibt. Weiter mit beliebiger Eingabe und Return
read *, hilf
contains
!Liefert die Determinante einer 2er Matrix zurück
function determinante_matrix_2(array)result(d)
double precision, dimension(2,2) :: array
double precision ::d
d= (array(1,1)*array(2,2))-(array(1,2)*array(2,1))
end function determinante_matrix_2
!Reduziert eine quadratische Matrix nach dem laplaceschem Verfahren um 1 (5er Matrix zu einer 4er Matrix, 4er zu einer 3er Matrix, usw.
function laplace(array, groesse_matrix, spalte)result(array_)
integer :: groesse_matrix,spalte
double precision, dimension(groesse_matrix,groesse_matrix), intent(in) :: array
double precision, dimension(groesse_matrix-1,groesse_matrix-1) :: array_
integer:: k,l
integer:: i,j
k=1
l=1
do i=2,groesse_matrix!beginn mit zeile 2, da zeile 1 immer die ausgewählte Zeile ist (Kann man optimieren, in dem man die Zeile oder Spalte raussucht mit den meisten Nullen)
do j=1,groesse_matrix
if(j/=spalte) then!aktuelle spalte wird nicht berücksichtigt
array_(k,l)=array(i,j)
l=l+1
end if
end do
k=k+1
l=1
end do
end function laplace
double precision recursive function determinante_laplace(array, groesse_matrix)result(det)
integer, intent(in) :: groesse_matrix
double precision, dimension (groesse_matrix,groesse_matrix) :: array
double precision, dimension (groesse_matrix-1,groesse_matrix-1) :: array2
double precision :: det
integer,save :: vorzeichen=1
double precision :: faktor
double precision :: zwischensumme
double precision :: ergebnis=0
double precision :: hilf=0
integer::i !schleifenvariable
if (groesse_matrix==2) then
hilf=determinante_matrix_2(array)
det=hilf
else
do i=1,groesse_matrix
zwischensumme=0
array2=laplace(array, groesse_matrix,i)
faktor=array(1,i)*vorzeichen
vorzeichen=vorzeichen*(-1)
if(array(1,i)/=0) then
zwischensumme=faktor*determinante_laplace(array2,groesse_matrix-1)
end if
ergebnis=ergebnis+zwischensumme
end do
det=ergebnis
end if
end function determinante_laplace
end program determinante
The recursive function is double precision recursive function determinante_laplace(array, groesse_matrix)result(det).
In my opinion this function is equal to the methode in java.
But it isn't so. The Fortran-program solve only 3x3 Matrix. Is the matrix higher, the result is wrong. Why?
I'am sorry for my bad english. I hope, you can understand my problem and can help to solve it.