Solving Function Problem in Code Exchange

Click For Summary

Discussion Overview

The discussion revolves around converting a block of Fortran code into two functions for reuse in future programs. Participants are addressing issues related to function implementation, variable initialization, and array indexing, with a focus on debugging and improving code readability.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant shares a code snippet and requests assistance in converting it into two functions, lj and l, for further use.
  • Another participant points out that the original code does not specify why it is not working, suggesting that clearer descriptions of issues would help in troubleshooting.
  • A participant notes that the variable l is not initialized before being used, which could lead to errors.
  • Concerns are raised about array indexing, with one participant mentioning that their compiler uses 1-based indexing, which may cause issues if the code accesses x(0) or y(0).
  • Another participant acknowledges the issue with accessing out-of-bounds array elements and expresses gratitude for the correction.
  • Further commentary includes suggestions for improving variable naming for better code readability and the importance of adding comments and whitespace for clarity.
  • One participant questions the necessity of passing the loop control variable j as a parameter to the function, suggesting it is unnecessary.

Areas of Agreement / Disagreement

Participants generally agree on the need to address issues related to variable initialization and array indexing. However, there are differing opinions on variable naming conventions and the structure of the function parameters, indicating that some aspects of the discussion remain contested.

Contextual Notes

Limitations include potential confusion arising from different indexing conventions in various compilers, as well as the need for clearer variable names and comments in the code to enhance readability.

Galizius
Messages
14
Reaction score
0
Hello I am trying to exchange following code into two functions which I will need to use in further programs.
The code is as follows:

Code:
do i=0,k
  do j=0,k
  if (i/=j) then
    lj(i)=lj(i)*((xx-x(i))/(x(j)-x(i)))
  end if
  enddo
  l(i)=l(i)+y(i)*lj(i)
  write(2,*) x(i),y(i),l(i)
enddo

I would like to swap lj and l arrays for the functions. I have tried something like that:

Code:
real(8) function lj(j,xx,x,k)
  real(8) :: x(1000)
  real(8) :: xx
  integer :: i,j,k

  lj=1.d0
do i=0,k
  do j=0,k
  if (i/=j) then
    lj=lj*((xx-x(i))/(x(j)-x(i)))
  end if
  enddo
enddo

Code:
real(8) function l(xx,x,y,k)
real(8) :: x(1000),y(1000), xx
integer :: i,j,k
  do i=0,k
    l=l+y(i)*lj(i,xx,x,k)
  enddo

And then I am trying to call it in the main program
Code:
do i=0,k
  write(2,*) x(i),y(i),l(x(i),x,y,k)
enddo

But it does not seem to be working as before. What am I doing wrong?
 
Last edited:
Technology news on Phys.org
Galizius said:
But it does not seem to be working as before.
This is very vague. You'll get better help when you clearly describe why (you think) it is wrong.

Galizius said:
Code:
real(8) function l(xx,x,y,k)
real(8) :: x(1000),y(1000), xx
integer :: i,j,k
  do i=0,k
    l=l+y(i)*lj(i,xx,x,k)
  enddo
l is not initialized before being used in the loop.
 
Galizius said:
Hello I am trying to exchange following code into two functions which I will need to use in further programs.
What am I doing wrong?

Not sure. In my compiler arrays are 1-based and dividing by 0 is disastrous. From your snippets I can come to something that runs but I have no idea if it's what you intend:
Code:
real(8) function lj(j,xx,x,k)
  real(8) :: x(1000)
  real(8) :: xx
  integer :: i,j,k
 
  lj=1.d0
 do i=1,k
  do j=1,k
  if (x(i) /= x(j)) then
  if (i/=j) then
  lj=lj*((xx-x(i))/(x(j)-x(i)))
  end if
  end if
  enddo
 enddo
end
 real(8) function l(xx,x,y,k)
 real(8) :: x(*),y(*), xx,  lj
 external lj
 integer :: i,j,k
  do i=1,k
  l=l+y(i)*lj(i,xx,x,k)
  enddo
 end
 
Program test
real*8 l,x(1000),y(1000)
external l
k=4
do i=1,k
  write(2,*) x(i),y(i),l(x(i),x,y,k)
pause
enddo
end

with output

Code:
  0.000000000000000E+000  0.000000000000000E+000  6.790386531088871E-313

suspicious ! We should probably initialize a few things
 
I just noticed another problem:

Galizius said:
Code:
real(8) function lj(j,xx,x,k)
  real(8) :: x(1000)
  real(8) :: xx
  integer :: i,j,k

  lj=1.d0
do i=0,k
  do j=0,k
  if (i/=j) then
    lj=lj*((xx-x(i))/(x(j)-x(i)))
  end if
  enddo
enddo

Code:
real(8) function l(xx,x,y,k)
real(8) :: x(1000),y(1000), xx
integer :: i,j,k
  do i=0,k
    l=l+y(i)*lj(i,xx,x,k)
  enddo
The code is accessing x(0) and y(0), which are outside the array boundaries.
 
  • Like
Likes   Reactions: Galizius
BvU said:
Not sure. In my compiler arrays are 1-based and dividing by 0 is disastrous.
I guess you didn't mean dividing by 0, in which case you beat me to it!
 
DrClaude said:
I just noticed another problem:The code is accessing x(0) and y(0), which are outside the array boundaries.

That solved my problem! Thank You so much, I do not know how could I miss that...
 
Galizius said:
That solved my problem! Thank You so much, I do not know how could I miss that...
Be sure to also implement the fix to the problem I mentioned in post #2. It might work for now, but you never know when it might fail.
 
  • Like
Likes   Reactions: Galizius
Yes, I already did. Thank You again!
 
Galizius said:
Fortran:
real(8) function lj(j,xx,x,k)
  real(8) :: x(1000)
  real(8) :: xx
  integer :: i,j,k
  lj=1.d0
do i=0,k
  do j=0,k
  if (i/=j) then
    lj=lj*((xx-x(i))/(x(j)-x(i)))
  end if
  enddo
enddo
A few comments about your code:
  1. The names you have picked for most of your variables are terrible! Single letter names such as i and j are OK for loop control variables, but names like lj, x, xx, and k don't give any indication of what you're going to use them for. There is no reason not to choose a name that suggest what the variable represents. Many years ago there were limits on how long a name you could use for a variable, so having variable names like x, xx, and lj is completely unwarranted, and makes your code harder to read than it should be.
  2. Why are you passing j as a parameter of your function? This variable gets set to 0, 1, 2, ..., k. It is strictly a local loop control variable, so there is no point in passing it as a function parameter.
  3. There isn't a single comment in your code.
  4. There isn't a single whitespace character in your code. The compiler doesn't care, but it's much harder for humans to read this -- lj=lj*((xx-x(i))/(x(j)-x(i))) -- than this --
    lj = lj * ( (xx - x(i) ) / ( x(j) - x(i) ) )
 

Similar threads

  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 20 ·
Replies
20
Views
4K
  • · Replies 22 ·
Replies
22
Views
5K
  • · Replies 12 ·
Replies
12
Views
2K
Replies
1
Views
2K
  • · Replies 4 ·
Replies
4
Views
8K
  • · Replies 20 ·
Replies
20
Views
2K
  • · Replies 7 ·
Replies
7
Views
4K
  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K