Related
I have the following code
import sympy as sp
x, y = sp.symbols('x y', real=True, positive=True)
expr = sp.sqrt(1/(x-y))/sp.sqrt(x+y)
the expression created should be equal to sqrt(1/(x^2 - y^2)) and I would like to rewrite it in that form but I cannot figure out how. I tried .rewrite(sp.sqrt), .rewrite(x**2 - y**2) and similar stuff but it did not help.
Ty for any tips on this,
Franz
The expression that you want is not equivalent to the one that you have:
In [53]: expr1 = sqrt(1/x - y)/sqrt(x + y)
In [54]: expr2 = 1/sqrt(x**2 - y**2)
In [55]: expr1
Out[55]:
________
╱ 1
╱ -y + ─
╲╱ x
────────────
_______
╲╱ x + y
In [56]: expr2
Out[56]:
1
────────────
_________
╱ 2 2
╲╱ x - y
In [58]: expr1.subs({x:1, y:2})
Out[58]:
√3⋅ⅈ
────
3
In [59]: expr2.subs({x:1, y:2})
Out[59]:
-√3⋅ⅈ
──────
3
That being said it should still be possible to do what you want using powsimp(expr1, force=True) but that doesn't seem to work in this case. I recommend opening a bug report about powsimp:
https://github.com/sympy/sympy/issues
I'm trying to solve a system of equations using LAPACK's dgesv subroutine in Fortran. I use the system matrix B:
B(1,:) = [1.0000000000000000, 0.0000000000000000, 0.0000000000000000, 0.0000000000000000]
B(2,:) = [0.11111111111111113, 0.66666666666666674, 0.22222222222222221, 0.0000000000000000]
B(3,:) = [0.0000000000000000, 0.22222222222222227, 0.66666666666666674, 0.11111111111111106]
B(4,:) = [0.0000000000000000, 0.0000000000000000, 0.0000000000000000, 1.0000000000000000]
and multiple rhs's P:
P(1,:) = [0.0000000000000000, 1.0000000000000000, 2.0000000000000000, 3.0000000000000000]
P(2,:) = [0.0000000000000000, 0.0000000000000000, 0.0000000000000000, 0.0000000000000000]
P(3,:) = [0.0000000000000000, 1.0000000000000000, 2.0000000000000000, 3.0000000000000000]
Then I'm solving the system using call dgesv(4, 3, B, 4, pivot, P, 4, info). The result is this matrix
0.0000000000000000 1.0000000000000000 2.8124999130377573 4.8749998218845638
6.2499996856786456E-002 0.0000000000000000 0.0000000000000000 -2.1249998931307394
-0.18749999476131071 0.56250000523868871 2.0000000000000000 3.0000000000000000
which is incorrect in every row. I also tried to solve the system for only one rhs at once, like that:
call dgesv(4, 1, B, 4, pivot, P(1,:), 4, info)
call dgesv(4, 1, B, 4, pivot, P(2,:), 4, info)
call dgesv(4, 1, B, 4, pivot, P(3,:), 4, info)
but only the first row (P(1,:)) gives the correct solution:
0.0000000000000000 0.74999999580904786 2.2499999287538253 3.0000000000000000
0.0000000000000000 0.0000000000000000 0.0000000000000000 0.0000000000000000
0.0000000000000000 0.52941179749874301 2.9117645384763313 3.0000000000000000
In fact, I can reorder the dgesv calls and only the first dgesv call produces a correct solution for the system and all following ones are just incorrect (with exception of the zero rhs).
Does anyone know that I am doing incorrectly?
Edit:
The code I'm running
program main
integer :: pivot(4) = 0
integer :: info = 0
doubleprecision :: B(4,4)
doubleprecision :: P(3,4)
B(1,:) = [1.0000000000000000, 0.0000000000000000, 0.0000000000000000, 0.0000000000000000]
B(2,:) = [0.11111111111111113, 0.66666666666666674, 0.22222222222222221, 0.0000000000000000]
B(3,:) = [0.0000000000000000, 0.22222222222222227, 0.66666666666666674, 0.11111111111111106]
B(4,:) = [0.0000000000000000, 0.0000000000000000, 0.0000000000000000, 1.0000000000000000]
P(1,:) = [0.0000000000000000, 1.0000000000000000, 2.0000000000000000, 3.0000000000000000]
P(2,:) = [0.0000000000000000, 0.0000000000000000, 0.0000000000000000, 0.0000000000000000]
P(3,:) = [0.0000000000000000, 1.0000000000000000, 2.0000000000000000, 3.0000000000000000]
! call dgesv(4, 1, B, 4, pivot, P(1,:), 4, info)
! call dgesv(4, 1, B, 4, pivot, P(2,:), 4, info)
! call dgesv(4, 1, B, 4, pivot, P(3,:), 4, info)
call dgesv(4, 3, B, 4, pivot, P, 4, info)
end program main
I am trying to understand mpi_gatherv through a simple example:
each rank has an array called x_local of size "id+1" thus rank 1 has x_local(1), rank 2 has x_local(2) and so on. In total I am using 4 procs.
For simplicity x_local = real(id+1)
On output I would like to have an array x (only for the root processor) like this:
x=(1,2,2,3,3,3,4,4,4,4)
Here is my code:
subroutine testGatherV
! Global variables
use mpi
use mpivar
! Local variables
implicit none
integer i, ierr, displs(nid), rcounts(nid)
real, dimension(:), allocatable:: x_local
real, dimension(:), allocatable:: x
allocate(x_local(id+1))
allocate(x(10))
!
x=-1.0
displs(1) = 0
displs(2) = 1
displs(3) = 3
displs(4) = 6
rcounts(1) = 1
rcounts(2) = 2
rcounts(3) = 3
rcounts(4) = 4
x_local = real(id+1)
call mpi_gatherv(x_local, id+1, MPI_REAL, x, rcounts, displs, &
MPI_REAL, 0, MPI_COMM_WORLD, ierr)
if(id.eq.0) write(*,*) 'x = ', x
end
The output is:
x = 0.0000000000000000 0.0000000000000000 0.0000000000000000 4.0000000000000000 4.0000000000000000 -1.0000000000000000 -1.0000000000000000 -1.0000000000000000 -1.0000000000000000 -1.0000000000000000
Where am I wrong? Any help will be much appreciated. Thank you.
I am calculating first and second derivatives of a function a(x,y,z) stored in a 3d array a(n1,n2,n3) using Finite Difference. Here the functional value at boundaries is zero. here is the code in Fortran:
implicit none
integer i1,i2,i3
integer, parameter :: n1 = 33
integer, parameter :: n2 = 33
integer, parameter :: n3 = 32
real*8 pi, a(n1,n2,n3), a2(n1,n2,n3), z(n3),x(n1),y(n2),h,a1(n1,n2,n3)
real*8 num(n1,n2,n3),deno(n1,n2,n3),diff(n1,n2,1),A0,dx,dy
pi=3.14159265358979323846d0
dx=2.0d0*pi/(n1-1)
dy=4.0d0*pi/(n2-1)
do i1=1,n1
x(i1)=-pi+(i1-1)*dx
do i2=1,n2
y(i2)=-2.0d0*pi+(i2-1)*dy
do i3=1,n3
z(i3)=(i3-1)*2.0d0*pi/n3
a(i1,i2,1)= dcos(x(i1)/2.0d0) * dcos(y(i2)/4.0d0) !input array
a1(i1,i2,1)= - 0.25d0*dcos(x(i1)/2.0d0) * dsin(y(i2)/4.0d0) !analytical expression of first order y-derivative
enddo
enddo
enddo
do i1=1,n1
do i2=1,n2
write(20,*)x(i1),y(i2),a(i1,i2,1)
enddo
enddo
call d1y(n1,n2,n3,a,a2)
do i1=1,n1
do i2=1,n2
num(i1,i2,1)=(a2(i1,i2,1)-a1(i1,i2,1)) !numerator of error calculation
deno(i1,i2,1)=a2(i1,i2,1) !denomenator of error calculation
if (dabs(deno(i1,i2,1)) .lt. 1e-10)deno(i1,i2,1)=1.0d0
diff(i1,i2,1)=dabs(num(i1,i2,1))/dabs(deno(i1,i2,1)) !relative error in 1st order derivative calculation
write(21,*)x(i1),y(i2),a(i1,i2,1),a2(i1,i2,1),diff(i1,i2,1),a1(i1,i2,1)
write(21,*)
enddo
enddo
end
subroutine d1y(n1,n2,n3,a,a2)
implicit none
integer n1, n2, n3, i1, i2, i3
real*8 pi, a(n1,n2,n3), a2(n1,n2,n3), z(n3),x(n1),y(n2),h,a1(n1,n2,n3)
pi=3.14159265358979323846d0
h=4.0d0*pi/(n2-1)
do i1=1,n1
do i3=1,n3
do i2=1,n2
if(i2 .eq. 1)then
a2(i1,i2,i3)=( -3.0d0*a(i1,i2,i3) + 4.0d0*a(i1,i2+1,i3) - a(i1,i2+2,i3) )/ (2.0d0*h)
else if(i2 .eq. n2)then
a2(i1,i2,i3)=( 3.0d0*a(i1,i2,i3) - 4.0d0*a(i1,i2-1,i3) + a(i1,i2-2,i3) )/ (2.0d0*h)
else
a2(i1,i2,i3)=( a(i1,i2+1,i3) - a(i1,i2-1,i3) )/ (2.0d0*h)
endif
enddo
enddo
enddo
end subroutine
My input function a(i1,i2,1)= dcos(x(i1)/2.0d0) * dcos(y(i2)/4.0d0), so the sample input data (for grid no 17*17*16)
-3.1415926535897931 -6.2831853071795862 3.7493994566546440E-033
-3.1415926535897931 -5.4977871437821380 1.1945836920083898E-017
-3.1415926535897931 -4.7123889803846897 2.3432602026631496E-017
-3.1415926535897931 -3.9269908169872414 3.4018865378450254E-017
-3.1415926535897931 -3.1415926535897931 4.3297802811774670E-017
-3.1415926535897931 -2.3561944901923448 5.0912829964730140E-017
-3.1415926535897931 -1.5707963267948966 5.6571305614385013E-017
-3.1415926535897931 -0.78539816339744828 6.0055777714832775E-017
-3.1415926535897931 0.0000000000000000 6.1232339957367660E-017
-3.1415926535897931 0.78539816339744828 6.0055777714832775E-017
-3.1415926535897931 1.5707963267948966 5.6571305614385013E-017
-3.1415926535897931 2.3561944901923439 5.0912829964730146E-017
-3.1415926535897931 3.1415926535897931 4.3297802811774670E-017
-3.1415926535897931 3.9269908169872423 3.4018865378450242E-017
-3.1415926535897931 4.7123889803846897 2.3432602026631496E-017
-3.1415926535897931 5.4977871437821371 1.1945836920083910E-017
-3.1415926535897931 6.2831853071795862 3.7493994566546440E-033
-2.7488935718910690 -6.2831853071795862 1.1945836920083898E-017
-2.7488935718910690 -5.4977871437821380 3.8060233744356645E-002
-2.7488935718910690 -4.7123889803846897 7.4657834050342639E-002
-2.7488935718910690 -3.9269908169872414 0.10838637566236967
-2.7488935718910690 -3.1415926535897931 0.13794968964147156
-2.7488935718910690 -2.3561944901923448 0.16221167441072892
-2.7488935718910690 -1.5707963267948966 0.18023995550173702
-2.7488935718910690 -0.78539816339744828 0.19134171618254495
-2.7488935718910690 0.0000000000000000 0.19509032201612833
-2.7488935718910690 0.78539816339744828 0.19134171618254495
-2.7488935718910690 1.5707963267948966 0.18023995550173702
-2.7488935718910690 2.3561944901923439 0.16221167441072895
-2.7488935718910690 3.1415926535897931 0.13794968964147156
-2.7488935718910690 3.9269908169872423 0.10838637566236962
-2.7488935718910690 4.7123889803846897 7.4657834050342639E-002
-2.7488935718910690 5.4977871437821371 3.8060233744356686E-002
-2.7488935718910690 6.2831853071795862 1.1945836920083898E-017
-2.3561944901923448 -6.2831853071795862 2.3432602026631496E-017
-2.3561944901923448 -5.4977871437821380 7.4657834050342639E-002
-2.3561944901923448 -4.7123889803846897 0.14644660940672630
-2.3561944901923448 -3.9269908169872414 0.21260752369181418
-2.3561944901923448 -3.1415926535897931 0.27059805007309856
-2.3561944901923448 -2.3561944901923448 0.31818964514320852
-2.3561944901923448 -1.5707963267948966 0.35355339059327384
-2.3561944901923448 -0.78539816339744828 0.37533027751786530
-2.3561944901923448 0.0000000000000000 0.38268343236508984
-2.3561944901923448 0.78539816339744828 0.37533027751786530
-2.3561944901923448 1.5707963267948966 0.35355339059327384
-2.3561944901923448 2.3561944901923439 0.31818964514320858
-2.3561944901923448 3.1415926535897931 0.27059805007309856
-2.3561944901923448 3.9269908169872423 0.21260752369181410
-2.3561944901923448 4.7123889803846897 0.14644660940672630
-2.3561944901923448 5.4977871437821371 7.4657834050342722E-002
-2.3561944901923448 6.2831853071795862 2.3432602026631496E-017
-1.9634954084936207 -6.2831853071795862 3.4018865378450254E-017
-1.9634954084936207 -5.4977871437821380 0.10838637566236967
-1.9634954084936207 -4.7123889803846897 0.21260752369181418
-1.9634954084936207 -3.9269908169872414 0.30865828381745519
-1.9634954084936207 -3.1415926535897931 0.39284747919355117
-1.9634954084936207 -2.3561944901923448 0.46193976625564342
-1.9634954084936207 -1.5707963267948966 0.51327996715933677
-1.9634954084936207 -0.78539816339744828 0.54489510677581865
-1.9634954084936207 0.0000000000000000 0.55557023301960229
-1.9634954084936207 0.78539816339744828 0.54489510677581865
-1.9634954084936207 1.5707963267948966 0.51327996715933677
-1.9634954084936207 2.3561944901923439 0.46193976625564348
-1.9634954084936207 3.1415926535897931 0.39284747919355117
-1.9634954084936207 3.9269908169872423 0.30865828381745508
-1.9634954084936207 4.7123889803846897 0.21260752369181418
-1.9634954084936207 5.4977871437821371 0.10838637566236978
-1.9634954084936207 6.2831853071795862 3.4018865378450254E-017
-1.5707963267948966 -6.2831853071795862 4.3297802811774670E-017
-1.5707963267948966 -5.4977871437821380 0.13794968964147156
-1.5707963267948966 -4.7123889803846897 0.27059805007309856
-1.5707963267948966 -3.9269908169872414 0.39284747919355117
-1.5707963267948966 -3.1415926535897931 0.50000000000000011
-1.5707963267948966 -2.3561944901923448 0.58793780120967942
-1.5707963267948966 -1.5707963267948966 0.65328148243818829
-1.5707963267948966 -0.78539816339744828 0.69351992266107376
-1.5707963267948966 0.0000000000000000 0.70710678118654757
-1.5707963267948966 0.78539816339744828 0.69351992266107376
-1.5707963267948966 1.5707963267948966 0.65328148243818829
-1.5707963267948966 2.3561944901923439 0.58793780120967942
-1.5707963267948966 3.1415926535897931 0.50000000000000011
-1.5707963267948966 3.9269908169872423 0.39284747919355101
-1.5707963267948966 4.7123889803846897 0.27059805007309856
-1.5707963267948966 5.4977871437821371 0.13794968964147170
-1.5707963267948966 6.2831853071795862 4.3297802811774670E-017
-1.1780972450961724 -6.2831853071795862 5.0912829964730140E-017
-1.1780972450961724 -5.4977871437821380 0.16221167441072892
-1.1780972450961724 -4.7123889803846897 0.31818964514320852
-1.1780972450961724 -3.9269908169872414 0.46193976625564342
-1.1780972450961724 -3.1415926535897931 0.58793780120967942
-1.1780972450961724 -2.3561944901923448 0.69134171618254492
-1.1780972450961724 -1.5707963267948966 0.76817775671141630
-1.1780972450961724 -0.78539816339744828 0.81549315684891710
-1.1780972450961724 0.0000000000000000 0.83146961230254524
-1.1780972450961724 0.78539816339744828 0.81549315684891710
-1.1780972450961724 1.5707963267948966 0.76817775671141630
-1.1780972450961724 2.3561944901923439 0.69134171618254503
-1.1780972450961724 3.1415926535897931 0.58793780120967942
-1.1780972450961724 3.9269908169872423 0.46193976625564326
-1.1780972450961724 4.7123889803846897 0.31818964514320852
-1.1780972450961724 5.4977871437821371 0.16221167441072909
-1.1780972450961724 6.2831853071795862 5.0912829964730140E-017
-0.78539816339744828 -6.2831853071795862 5.6571305614385013E-017
-0.78539816339744828 -5.4977871437821380 0.18023995550173702
-0.78539816339744828 -4.7123889803846897 0.35355339059327384
-0.78539816339744828 -3.9269908169872414 0.51327996715933677
-0.78539816339744828 -3.1415926535897931 0.65328148243818829
-0.78539816339744828 -2.3561944901923448 0.76817775671141630
-0.78539816339744828 -1.5707963267948966 0.85355339059327373
-0.78539816339744828 -0.78539816339744828 0.90612744635288778
-0.78539816339744828 0.0000000000000000 0.92387953251128674
-0.78539816339744828 0.78539816339744828 0.90612744635288778
-0.78539816339744828 1.5707963267948966 0.85355339059327373
-0.78539816339744828 2.3561944901923439 0.76817775671141642
-0.78539816339744828 3.1415926535897931 0.65328148243818829
-0.78539816339744828 3.9269908169872423 0.51327996715933655
-0.78539816339744828 4.7123889803846897 0.35355339059327384
-0.78539816339744828 5.4977871437821371 0.18023995550173721
-0.78539816339744828 6.2831853071795862 5.6571305614385013E-017
-0.39269908169872414 -6.2831853071795862 6.0055777714832775E-017
-0.39269908169872414 -5.4977871437821380 0.19134171618254495
-0.39269908169872414 -4.7123889803846897 0.37533027751786530
-0.39269908169872414 -3.9269908169872414 0.54489510677581865
-0.39269908169872414 -3.1415926535897931 0.69351992266107376
-0.39269908169872414 -2.3561944901923448 0.81549315684891710
-0.39269908169872414 -1.5707963267948966 0.90612744635288778
-0.39269908169872414 -0.78539816339744828 0.96193976625564337
-0.39269908169872414 0.0000000000000000 0.98078528040323043
-0.39269908169872414 0.78539816339744828 0.96193976625564337
-0.39269908169872414 1.5707963267948966 0.90612744635288778
-0.39269908169872414 2.3561944901923439 0.81549315684891721
-0.39269908169872414 3.1415926535897931 0.69351992266107376
-0.39269908169872414 3.9269908169872423 0.54489510677581843
-0.39269908169872414 4.7123889803846897 0.37533027751786530
-0.39269908169872414 5.4977871437821371 0.19134171618254514
-0.39269908169872414 6.2831853071795862 6.0055777714832775E-017
0.0000000000000000 -6.2831853071795862 6.1232339957367660E-017
0.0000000000000000 -5.4977871437821380 0.19509032201612833
0.0000000000000000 -4.7123889803846897 0.38268343236508984
0.0000000000000000 -3.9269908169872414 0.55557023301960229
0.0000000000000000 -3.1415926535897931 0.70710678118654757
0.0000000000000000 -2.3561944901923448 0.83146961230254524
0.0000000000000000 -1.5707963267948966 0.92387953251128674
0.0000000000000000 -0.78539816339744828 0.98078528040323043
0.0000000000000000 0.0000000000000000 1.0000000000000000
0.0000000000000000 0.78539816339744828 0.98078528040323043
0.0000000000000000 1.5707963267948966 0.92387953251128674
0.0000000000000000 2.3561944901923439 0.83146961230254535
0.0000000000000000 3.1415926535897931 0.70710678118654757
0.0000000000000000 3.9269908169872423 0.55557023301960207
0.0000000000000000 4.7123889803846897 0.38268343236508984
0.0000000000000000 5.4977871437821371 0.19509032201612853
0.0000000000000000 6.2831853071795862 6.1232339957367660E-017
0.39269908169872414 -6.2831853071795862 6.0055777714832775E-017
0.39269908169872414 -5.4977871437821380 0.19134171618254495
0.39269908169872414 -4.7123889803846897 0.37533027751786530
0.39269908169872414 -3.9269908169872414 0.54489510677581865
0.39269908169872414 -3.1415926535897931 0.69351992266107376
0.39269908169872414 -2.3561944901923448 0.81549315684891710
0.39269908169872414 -1.5707963267948966 0.90612744635288778
0.39269908169872414 -0.78539816339744828 0.96193976625564337
0.39269908169872414 0.0000000000000000 0.98078528040323043
0.39269908169872414 0.78539816339744828 0.96193976625564337
0.39269908169872414 1.5707963267948966 0.90612744635288778
0.39269908169872414 2.3561944901923439 0.81549315684891721
0.39269908169872414 3.1415926535897931 0.69351992266107376
0.39269908169872414 3.9269908169872423 0.54489510677581843
0.39269908169872414 4.7123889803846897 0.37533027751786530
0.39269908169872414 5.4977871437821371 0.19134171618254514
0.39269908169872414 6.2831853071795862 6.0055777714832775E-017
0.78539816339744828 -6.2831853071795862 5.6571305614385013E-017
0.78539816339744828 -5.4977871437821380 0.18023995550173702
0.78539816339744828 -4.7123889803846897 0.35355339059327384
0.78539816339744828 -3.9269908169872414 0.51327996715933677
0.78539816339744828 -3.1415926535897931 0.65328148243818829
0.78539816339744828 -2.3561944901923448 0.76817775671141630
0.78539816339744828 -1.5707963267948966 0.85355339059327373
0.78539816339744828 -0.78539816339744828 0.90612744635288778
0.78539816339744828 0.0000000000000000 0.92387953251128674
0.78539816339744828 0.78539816339744828 0.90612744635288778
0.78539816339744828 1.5707963267948966 0.85355339059327373
0.78539816339744828 2.3561944901923439 0.76817775671141642
0.78539816339744828 3.1415926535897931 0.65328148243818829
0.78539816339744828 3.9269908169872423 0.51327996715933655
0.78539816339744828 4.7123889803846897 0.35355339059327384
0.78539816339744828 5.4977871437821371 0.18023995550173721
0.78539816339744828 6.2831853071795862 5.6571305614385013E-017
1.1780972450961720 -6.2831853071795862 5.0912829964730146E-017
1.1780972450961720 -5.4977871437821380 0.16221167441072895
1.1780972450961720 -4.7123889803846897 0.31818964514320858
1.1780972450961720 -3.9269908169872414 0.46193976625564348
1.1780972450961720 -3.1415926535897931 0.58793780120967942
1.1780972450961720 -2.3561944901923448 0.69134171618254503
1.1780972450961720 -1.5707963267948966 0.76817775671141642
1.1780972450961720 -0.78539816339744828 0.81549315684891721
1.1780972450961720 0.0000000000000000 0.83146961230254535
1.1780972450961720 0.78539816339744828 0.81549315684891721
1.1780972450961720 1.5707963267948966 0.76817775671141642
1.1780972450961720 2.3561944901923439 0.69134171618254503
1.1780972450961720 3.1415926535897931 0.58793780120967942
1.1780972450961720 3.9269908169872423 0.46193976625564331
1.1780972450961720 4.7123889803846897 0.31818964514320858
1.1780972450961720 5.4977871437821371 0.16221167441072912
1.1780972450961720 6.2831853071795862 5.0912829964730146E-017
1.5707963267948966 -6.2831853071795862 4.3297802811774670E-017
1.5707963267948966 -5.4977871437821380 0.13794968964147156
1.5707963267948966 -4.7123889803846897 0.27059805007309856
1.5707963267948966 -3.9269908169872414 0.39284747919355117
1.5707963267948966 -3.1415926535897931 0.50000000000000011
1.5707963267948966 -2.3561944901923448 0.58793780120967942
1.5707963267948966 -1.5707963267948966 0.65328148243818829
1.5707963267948966 -0.78539816339744828 0.69351992266107376
1.5707963267948966 0.0000000000000000 0.70710678118654757
1.5707963267948966 0.78539816339744828 0.69351992266107376
1.5707963267948966 1.5707963267948966 0.65328148243818829
1.5707963267948966 2.3561944901923439 0.58793780120967942
1.5707963267948966 3.1415926535897931 0.50000000000000011
1.5707963267948966 3.9269908169872423 0.39284747919355101
1.5707963267948966 4.7123889803846897 0.27059805007309856
1.5707963267948966 5.4977871437821371 0.13794968964147170
1.5707963267948966 6.2831853071795862 4.3297802811774670E-017
1.9634954084936211 -6.2831853071795862 3.4018865378450242E-017
1.9634954084936211 -5.4977871437821380 0.10838637566236962
1.9634954084936211 -4.7123889803846897 0.21260752369181410
1.9634954084936211 -3.9269908169872414 0.30865828381745508
1.9634954084936211 -3.1415926535897931 0.39284747919355101
1.9634954084936211 -2.3561944901923448 0.46193976625564326
1.9634954084936211 -1.5707963267948966 0.51327996715933655
1.9634954084936211 -0.78539816339744828 0.54489510677581843
1.9634954084936211 0.0000000000000000 0.55557023301960207
1.9634954084936211 0.78539816339744828 0.54489510677581843
1.9634954084936211 1.5707963267948966 0.51327996715933655
1.9634954084936211 2.3561944901923439 0.46193976625564331
1.9634954084936211 3.1415926535897931 0.39284747919355101
1.9634954084936211 3.9269908169872423 0.30865828381745491
1.9634954084936211 4.7123889803846897 0.21260752369181410
1.9634954084936211 5.4977871437821371 0.10838637566236972
1.9634954084936211 6.2831853071795862 3.4018865378450242E-017
2.3561944901923448 -6.2831853071795862 2.3432602026631496E-017
2.3561944901923448 -5.4977871437821380 7.4657834050342639E-002
2.3561944901923448 -4.7123889803846897 0.14644660940672630
2.3561944901923448 -3.9269908169872414 0.21260752369181418
2.3561944901923448 -3.1415926535897931 0.27059805007309856
2.3561944901923448 -2.3561944901923448 0.31818964514320852
2.3561944901923448 -1.5707963267948966 0.35355339059327384
2.3561944901923448 -0.78539816339744828 0.37533027751786530
2.3561944901923448 0.0000000000000000 0.38268343236508984
2.3561944901923448 0.78539816339744828 0.37533027751786530
2.3561944901923448 1.5707963267948966 0.35355339059327384
2.3561944901923448 2.3561944901923439 0.31818964514320858
2.3561944901923448 3.1415926535897931 0.27059805007309856
2.3561944901923448 3.9269908169872423 0.21260752369181410
2.3561944901923448 4.7123889803846897 0.14644660940672630
2.3561944901923448 5.4977871437821371 7.4657834050342722E-002
2.3561944901923448 6.2831853071795862 2.3432602026631496E-017
2.7488935718910685 -6.2831853071795862 1.1945836920083910E-017
2.7488935718910685 -5.4977871437821380 3.8060233744356686E-002
2.7488935718910685 -4.7123889803846897 7.4657834050342722E-002
2.7488935718910685 -3.9269908169872414 0.10838637566236978
2.7488935718910685 -3.1415926535897931 0.13794968964147170
2.7488935718910685 -2.3561944901923448 0.16221167441072909
2.7488935718910685 -1.5707963267948966 0.18023995550173721
2.7488935718910685 -0.78539816339744828 0.19134171618254514
2.7488935718910685 0.0000000000000000 0.19509032201612853
2.7488935718910685 0.78539816339744828 0.19134171618254514
2.7488935718910685 1.5707963267948966 0.18023995550173721
2.7488935718910685 2.3561944901923439 0.16221167441072912
2.7488935718910685 3.1415926535897931 0.13794968964147170
2.7488935718910685 3.9269908169872423 0.10838637566236972
2.7488935718910685 4.7123889803846897 7.4657834050342722E-002
2.7488935718910685 5.4977871437821371 3.8060233744356721E-002
2.7488935718910685 6.2831853071795862 1.1945836920083910E-017
3.1415926535897931 -6.2831853071795862 3.7493994566546440E-033
3.1415926535897931 -5.4977871437821380 1.1945836920083898E-017
3.1415926535897931 -4.7123889803846897 2.3432602026631496E-017
3.1415926535897931 -3.9269908169872414 3.4018865378450254E-017
3.1415926535897931 -3.1415926535897931 4.3297802811774670E-017
3.1415926535897931 -2.3561944901923448 5.0912829964730140E-017
3.1415926535897931 -1.5707963267948966 5.6571305614385013E-017
3.1415926535897931 -0.78539816339744828 6.0055777714832775E-017
3.1415926535897931 0.0000000000000000 6.1232339957367660E-017
3.1415926535897931 0.78539816339744828 6.0055777714832775E-017
3.1415926535897931 1.5707963267948966 5.6571305614385013E-017
3.1415926535897931 2.3561944901923439 5.0912829964730146E-017
3.1415926535897931 3.1415926535897931 4.3297802811774670E-017
3.1415926535897931 3.9269908169872423 3.4018865378450242E-017
3.1415926535897931 4.7123889803846897 2.3432602026631496E-017
3.1415926535897931 5.4977871437821371 1.1945836920083910E-017
3.1415926535897931 6.2831853071795862 3.7493994566546440E-033
Input and output functions are as shown in the figure below.
As the output function is the same as - 0.25d0*dcos(x(i1)/2.0d0) * dsin(y(i2)/4.0d0), this shows derivative calculation is correct. Here in subroutine 'd1y', I have used forward and backward finite difference formula for calculation of derivative at boundaries and the central difference for points lying between two boundaries. Then I have calculated the relative error. I got an error of 0.003 at the boundary of y axis and 0.0015 at the points in between boundaries as shown in fig below.
I calculated 2nd derivative using same technique. The subroutine is given below:
`subroutine d2y(n1,n2,n3,a,a2)
implicit none
integer n1, n2, n3, i1, i2, i3
real*8 pi, a(n1,n2,n3), a2(n1,n2,n3), z(n3),x(n1),y(n2),h
pi=3.14159265358979323846d0
h=4.0d0*pi/(n2-1)
a2=0.0d0
i3 =1
do i1=1,n1
do i2=1,n2
if(i2 == 1)then
a2(i1,i2,i3)=( 2.0d0*a(i1,i2,i3) - 5.0d0*a(i1,i2+1,i3) + 4.0d0*a(i1,i2+2,i3) - a(i1,i2+3,i3))/(h*h)
else if( i2 == n2)then
a2(i1,i2,i3)=( 2.0d0*a(i1,i2,i3) - 5.0d0*a(i1,i2-1,i3) + 4.0d0*a(i1,i2-2,i3) - a(i1,i2-3,i3))/(h*h)
else
a2(i1,i2,i3)= ( a(i1,i2+1,i3) - 2.0d0*a(i1,i2,i3) + a(i1,i2-1,i3) )/(h*h)
endif
enddo
enddo
! enddo
end subroutine
Here also the error is large at boundaries, in fact, the error is very large compared to first order derivative as shown in figure:.
Why this large error in boundary? Please explain.
`
First, I stand corrected. The names 'Forward Difference' and 'Backward Difference' usually refer to the standard 1st order formulas. You do have correct 2nd order, One-sided 1st derivative formulas.
The 2nd order, 1st derivative, Forward difference formula is derived with a Taylor series expression at x+h and at x+2h as follows:
f(x+h) = f(x) + h*f'(x) + h^2*f''(x)/2! + h^3*f'''(x)/3! ....
f(x+2h) = f(x) + 2h*f'(x) + 4h^2*f''(x)/2! + 8h^3*f'''(x)/3! ....
Now, take 4 times the 1st series and subtract the 2nd series and solve for f'(x). Note that the second derivative term disappears.
f'(x) = 3h/2 * f(x) - 2/h *f(x+h) + 1/(2h) * f(x+2h) + 0 - 4h^2*f'''(x)/3!
This is the formula you are using and it is 2nd order accurate. This does not mean that the accuracy is identical to the central difference accuracy, only that the order of the accuracy is the same.
If you look at the derivation of central difference while keeping the error term, you will find that the error term looks like:
-h^2*f'''(x)/6
Did you note that the error term in the forward difference formula has a constant in front of it. In general, the error will always be larger. But that is not what it means to be 2nd order accurate. The order of accuracy tells you how the error changes when you change h.
For example, if you halve h, you should get about 4 times the accuracy. That means in your example above, the central difference error will go from about 0.0015 to about 0.0004 and the boundary error will go from about 0.003 to about 0.0008
Final Takeaway: Your program is correct and your errors are correct!
I am performing an SVD of a matrix using the LAPACK library and then multiplying the matrices to double check that they are correct. See the code below
subroutine svd_and_dgemm() ! -- Matrix decomp: A = USV^t
implicit none
integer,parameter :: m = 2
integer,parameter :: n = 3
integer i,info,lda,ldu,ldv,lwork,l,lds,ldc,ldvt,ldd
real*8 :: a(m,n),a_copy(m,n),sdiag(min(m,n)),s(m,n),u(m,m),vt(n,n),alpha,beta,c(m,n),d(m,n)
character jobu, jobv, transu, transs
real*8, allocatable, dimension ( : ) :: work
lwork = max(1,3*min(m,n) + max(m,n), 5*min(m,n))
allocate (work(lwork))
a = reshape((/3,1,1,-1,3,1/),shape(a),order=(/2, 1/)) !column-wise
print*,'A'
print*, a(1,1), a(1,2), a(1,3)
print*, a(2,1), a(2,2), a(2,3)
jobu = 'A'
jobv = 'A'
lda = m
ldu = m
ldv = n
a_copy = a
call dgesvd (jobu, jobv, m, n, a_copy, lda, sdiag, u, ldu, vt, ldv, work, lwork, info)
if ( info /= 0 ) then
write ( *, '(a)' ) ' '
write ( *, '(a)' ) 'R8MAT_SVD_LAPACK - Failure!'
write ( *, '(a)' ) ' The SVD could not be calculated.'
write ( *, '(a)' ) ' LAPACK routine DGESVD returned a nonzero'
write ( *, '(a,i8)' ) ' value of the error flag, INFO = ', info
return
end if
!
! Make the MxN matrix S from the diagonal values in SDIAG.
s(1:m,1:n) = 0.0D+00
do i = 1, min ( m, n )
s(i,i) = sdiag(i)
end do
print*,'U'
print*, u(1,1), u(1,2)
print*, u(2,1), u(2,2)
print*,'S'
print*, s(1,1), s(1,2), s(1,3)
print*, s(2,1), s(2,2), s(2,3)
print*,'Vt'
print*, vt(1,1), vt(1,2), vt(1,3)
print*, vt(2,1), vt(2,2), vt(2,3)
print*, vt(3,1), vt(3,2), vt(3,3)
deallocate (work)
! -- Verify SVD: A = USV^t
! -- Compute C = US
transu = 'N'
transs = 'N'
ldu = m; lds = m; ldc = m
alpha = 1.; beta = 1.
call dgemm(transu,transs,m,n,m,alpha,u,ldu,s,lds,beta,c,ldc)
! -- Compute A = D = CV^t
l = m ! nrows C
ldvt = n; ldd = m
call dgemm(transu,transs,m,n,n,alpha,c,ldc,vt,ldvt,beta,d,ldd)
print*,'C'
print*, c(1,1), c(1,2), c(1,3)
print*, c(2,1), c(2,2), c(2,3)
print*,'D'
print*, d(1,1), d(1,2), d(1,3)
print*, d(2,1), d(2,2), d(2,3)
end subroutine svd_and_dgemm
The output I get is
A
3.0000000000000000 1.0000000000000000 1.0000000000000000
-1.0000000000000000 3.0000000000000000 1.0000000000000000
U
-0.70710678118654835 -0.70710678118654657
-0.70710678118654668 0.70710678118654846
S
3.4641016151377553 0.0000000000000000 0.0000000000000000
0.0000000000000000 3.1622776601683795 0.0000000000000000
Vt
-0.40824829046386402 -0.81649658092772526 -0.40824829046386291
-0.89442719099991508 0.44721359549995882 5.2735593669694936E-016
-0.18257418583505536 -0.36514837167011066 0.91287092917527679
C
-2.4494897427831814 -2.2360679774997867 0.0000000000000000
-2.4494897427831757 2.2360679774997929 0.0000000000000000
D
2.9999999999999991 1.0000000000000002 0.99999999999999989
NaN 2.9999999999999991 1.0000000000000000
So I am not sure where is this NaN coming from. The odd thing is that if before printing D in such way I print it as follows:
print*,'D'
print*, d
Then I don't get the NaN anymore, so the output for D is
D
2.9999999999999991 -0.99999999999999933 1.0000000000000002 2.9999999999999991 0.99999999999999989 1.0000000000000000
D
2.9999999999999991 1.0000000000000002 0.99999999999999989
-0.99999999999999933 2.9999999999999991 1.0000000000000000
Any idea why is this happening?
PS: Information for the dgesvd (LAPACK) and dgemm (BLAS) subroutines.
So from our comments dialogue it seems like you have a problem that stems from not initializing an array. It is always good practice to do this, and in situations where you do operations like var = var +1 it is required. If you are unlucky your program will work fine anyway. But then strange things happen once in a while when some garbage happened to reside in memory where the array gets allocated.
A double should be initialized like this
array = 0.0d0 ! for double precision
or
array = 0 ! ok for single,double and integer
Initialize single precision but not double precision like this:
array = 0.0 ! single (not double) precision.
or this
array = 0.0e0 ! single (not double) precision.
I recommend the page fortran90.org.