Topic: Debugging. Variables in the stack frame (activation record).
At first I thought this was a subtle bug in the debugger but now I think it is a feature which is possibly quite helpful (and might even be improved upon -- see later).
The following code uses adaptive trapezoidal rule to integrate sin(x) between 0 and pi/2 (of course the result should be 1.0). The main function integrate calls a recursive subroutine trapezium which calls itself to sub-divide the integral interval to achieve a specific tolerance on the result.
The trapezium subroutine is an internal subroutine to integrate. The function integrate is the host of subroutine trapezium. Variables declared in integrate are in scope (may be referenced) when trapezium is called (both initially and for subsequent recursive calls).
When stepping into trapezium in the debugger I note that:
- Host variables min_interval and integrate (the result variable) are listed in the variables panel.
- The other host variables, fnc_lower, fnc_upper, lower, upper, tolerance are not listed.
- Host variable tol is not listed but is, in any case, hidden by the local variable of the same name.
It seems then that host variables are only listed if they are in scope and are actually referenced in trapezium.
This is potentially useful I think.
module quad
implicit none
contains
function f(x)
real, intent(in) :: x
real :: f
f = sin(x)
end function f
function integrate(lower, upper, tolerance)
real, intent(in) :: lower, upper, tolerance
real :: integrate, fnc_lower, fnc_upper, min_interval, tol
min_interval = (upper - lower)/100.0
fnc_lower = f(lower)
fnc_upper = f(upper)
integrate = 0.0
tol = tolerance
call trapezium(lower, upper, fnc_lower, fnc_upper, tol)
contains
recursive subroutine trapezium(a, b, fna, fnb, tol)
real, intent(in) :: a, b, fna, fnb, tol
real :: c, fnc, area1, area2, error
c = 0.5*(a + b)
fnc = f(c)
area1 = 0.5*(fna + fnb)*(b - a)
area2 = 0.25*(fna + 2.0*fnc + fnb)*(b - a)
error = (area2 - area1)/3.0
if (abs(error) < tol .or. b - a < min_interval) then
integrate = integrate + area2 + error
else
call trapezium(a, c, fna, fnc, 0.5*tol)
call trapezium(c, b, fnc, fnb, 0.5*tol)
end if
end subroutine trapezium
end function integrate
end module quad
program main
use quad
real :: pi, area
pi = 4.0*atan(1.0)
area = integrate(0.0, pi/2.0, 1.0e-5)
print *,'Area under curve = ', area
end program main
Now, the missing host variables can be listed by switching to the stack list in the panels window, selecting integrate and then switching back to the variables list.
This is OK, but I wonder if it could be improved upon by allowing the variables from two or more stack frames to be seen at the same time? My simplest view of this is to give access to up to 4 left-hand panels (tiled on top of each other) which users can configure as they see fit.
Views on this are sought.
David