-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcram.f90
127 lines (88 loc) · 2.08 KB
/
cram.f90
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
! To solve a system of linear equations. Here I used the concept of crammer's rule
! For simplicity's sake, I've used the entries of the matrix you've given, professor
program crammer
implicit none
integer,parameter :: n=3
integer ::i,j
real,dimension(n,n,n+1) :: a
real,dimension(n,1) :: b,x
a(:,:,1) = reshape((/-1,3,-1,1,-1,3,2,1,4/),(/n,n/))
b = reshape((/2,6,4/),(/n,1/))
call cram(x,a,b,n)
write(*,*) 'Matrix A|b:'
do i=1,n
write(*, '("|")',advance='no')
do j=1,n
write(*,'(f8.2,t2)',advance='no'),a(i,j,1)
end do
write(*,'(" | ",f8.2)'),b(i,1)
end do
write(*,*)'Matrix Xa:'
do i=1,n
do j=1,n
write(*,'(f8.2,t2)',advance='no'),a(i,j,2)
end do
write(*,*)
end do
write(*,*)'Matrix Xb:'
do i=1,n
do j=1,n
write(*,'(f8.2,t2)',advance='no'),a(i,j,3)
end do
write(*,*)
end do
write(*,*)'Matrix Xc:'
do i=1,n
do j=1,n
write(*,'(f8.2,t2)',advance='no'),a(i,j,4)
end do
write(*,*)
end do
write(*,*) ' The solution is:'
do i=1,n
write(*,*) x(i,1)
end do
end program crammer
subroutine cram(x,a,b,n)
implicit none
integer,intent(in) :: n
real,dimension(n,n,n+1), intent(inout) :: a
real,intent(in),dimension(n) :: b
real,external :: detf
integer :: i
real,dimension(n,1),intent(out) :: x
do i=1,n
a(:,:,i+1) = a(:,:,1)
a(:,i,i+1) = b
x(i,1) = detf(a(:,:,i+1),n)/detf(a(:,:,1),n)
end do
end subroutine cram
recursive real function detf(mat,n) result(det)
implicit none
integer,intent(in) :: n
real,intent(in),dimension(n,n) :: mat
real,dimension(n-1,n-1) :: sl
integer :: i
det = 0
if(n==1) then
det = mat(1,1)
return
else
do i=1,n
call slicef(sl,mat,n,1,i)
det = det + ((-1.0)**(1+i))*mat(1,i)*detf(sl,n-1)
end do
return
end if
end function detf
subroutine slicef(sl,mat,n,row,column)
implicit none
integer,intent(in) :: n,row,column
real,dimension(n,n),intent(in) :: mat
real,dimension(n-1,n-1),intent(out) :: sl
logical,dimension(n,n) :: mask
mask = .true.
mask(row,:) = .false.
mask(:,column) = .false.
sl = reshape(pack(mat,mask),(/n-1,n-1/))
end subroutine slicef