- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm trying to allocate array value but encountered a catastrophic error while compiling. Here's the function :
function poisson_pressure(P, B, dx, dy) result(P_n)
real, intent(in) :: B(:,:), dx, dy
real :: P(:,:), norm=1, P_n(nx,ny), norm_t=1e-6
P_n = P
do while (norm > norm_t)
P(2:nx-1, 2:ny-1) = ((dy**2 * (P_n(3:,2:ny-1)+P_n(1:nx-2,2:ny-1))) &
+ (dx**2 * (P_n(2:nx-1,3:)+P_n(2:nx-1,1:ny-2))) &
- (dx**2 * dy**2 * B(2:nx-1,2:ny-1))) / (2*(dx**2 + dy**2))
P(:, ny-1) = 0
P(1, = P(2, :)
P(nx-1, = P(nx-2, !!! Line that throws compilation error
P(:, 1) = P(:, 2)
norm = l1norm(P, P_n)
P_n = P
end do
return
end function poisson_pressure
The program compiles well if I remove the problematic line. I don't understand why this is happening. I've checked declarations, type, shape etc but nothing bad came up. I'm using
ifort -c foo.F90
as compile command.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The code that you showed is not a proper external function. No compiler will accept it without corrections and without code in a containing scope.
For instance, the variables nx and ny appear to be from a containing outer scope. The line before the "problematic line" is also problematic. It is wrong for l1norm to be implicitly declared with the wrong type. Check the subscript expressions.
If the function is invoked several times, the value of norm at entry will not be 1, and the conditional expression in the DO WHILE statement will probably be evaluated incorrectly.
Your description does not match the code that you posted. Please show the actual code.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
mecej4,
In the posted text (program), it appears that the text formatting replace colon, right paren with a non-printing smiley face.
.OR.
the OP copied the file from this forum, and missed the colon, right paren to hidden smiley face.
I am not sure if Past with Fortran formatting still has this problem. Let's see if it does
array(1,:) = 2 ! left side has array(1,: ) without space following :
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have reported already the tendency of this forum to replace certain common Fortran syntax with invisible emoji (you can see it only in a brief instant of the display of raw HTML when you edit a post.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
From me.rice.edu Professor Akin --
program vector_norm
! A simple vector norm program, Fortran 90 version
implicit none
integer, parameter :: dp = selected_real_kind(14) ! 14 digits
integer, parameter :: MAX = 1000; ! Maximum vector size
integer n; ! Actual vector size
integer i; ! Loop controls
real (kind=dp) :: x(MAX) ! The vector
real (kind=dp) :: L1_norm, L2_norm; ! Work results
print *,"Enter the vector length: ";
read *, n; ! User size input
print *, n ! Echo size
if ( n > MAX ) then ! Check validity
stop "Vector size exceeds dimension, ERROR"; ! Abort run
end if
! Input vector contents
print *,"Enter the vector: ";
read *, (x(i), i=1,n) ! Read values
L2_norm = sqrt ( sum ( x(:n)*x(:n) )) ! L2 norm
L1_norm = sum ( abs(x(:n)) )/n ! L1 norm
write (6,'(" The L2 norm of [")',advance='no') ! Print header
! Loop over vector contents, (except last)
do i = 1, n-1
write (6, '(f10.4, ",")', advance = 'no') x(i) ! List values
end do
! Now last term
write (6, '(f10.4, " ] is: ")', advance = 'no') x(n) ! Last value
print *, L2_norm, "." ; ! Print L2
print *, "The L1 norm is: ", L1_norm, "." ; ! Print L1
end program vector_norm
! Running with file lab_1.dat;
! 4
! 3.14159265358979 5 12e1 .645
! gives
! Enter the vector length:
! 4
! Enter the vector:
! The L2 norm of [ 3.1416, 5.0000, 120.0000, 0.6450 ] is: 120.146933499.
! The L1 norm is: 32.196648163397448.
- a nice little program
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Akin's program give the same results in the latest Fortran classic compiler: which is nice to know.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
L1 norm is just the average length on the positive number line for the independent elements of the vector.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Is the L1 norm invariant under a transformation of the base
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- L1 Norm is the sum of the magnitudes of the vectors in a space
Is the Fortran code in error? Because Akins has divided the sum by the number of vectors
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It is an internal function. The line before the problematic line had correct closed parentheses but idk why when I posted got removed in formatting. The norm value changes every time `l1norm` is invoked. May I know why repeated calling changes the value of a variable?
The posted code is the actual part of the code!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
because nx and ny will have strange value if they exist at all.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
function poisson_pressure(P, B, dx, dy) result(P_n)
real, intent(in) :: B(:,:), dx, dy
integer :: nx = 100
integer :: ny = 100
real :: P(:,:), norm=1, P_n(100,100), norm_t=1e-6
P_n = P
do while (norm > norm_t)
P(2:nx-1, 2:ny-1) = ((dy**2 * (P_n(3:,2:ny-1)+P_n(1:nx-2,2:ny-1))) &
+ (dx**2 * (P_n(2:nx-1,3:)+P_n(2:nx-1,1:ny-2))) &
- (dx**2 * dy**2 * B(2:nx-1,2:ny-1))) / (2*(dx**2 + dy**2))
P(:, ny-1) = 0
P(1,:) = P(2, :)
P(nx-1,:) = P(nx-2,:) !!! Line that throws compilation error
P(:, 1) = P(:, 2)
!norm = l1norm(P, P_n)
P_n = P
end do
return
end function poisson_pressure
It compiles now - but I need a calling routine, you cannot expect people to do a lot of work. PS it will not compile until nx and ny are defined and P_n should probably be allocatable.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
function l1norm(matA, matB) result(norm_r)
real, intent(in) :: matA(:,:), matB(:,:)
real :: norm_r
norm_r = (sum(abs(matA) - abs(matB)))/(sum(abs(matB)))
return
end function l1norm
This was my 'l1norm' function.
Thanks for the help! I also want to know whether repeated allocation to any array will write garbage values to it?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you wish norm=1 to be set every time this is called you need it to be set by a runtime statement. Not by a compile time initialisation.
I don't see an allocatables in the sample BTW.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ok -- I am more than a little confused.
Where did you get your L1 Norm from -- it is a single number returned from a vector of lengths. The Manhattan Taxi.
And we need a driving program - something that can be tested in a Fortran compiler.
I am not trying to be difficult but you are dealing with busy folk who have a much higher level of knowledge of Fortran than I , but my Pure Maths says -- this is just a little weird without some background.
If you are using the L1 Norm to determine a delta error there are better ways to calculate it I would think.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page