5 integer,
parameter :: dp = kind(0.0d0)
6 integer,
parameter :: table_size = 99
7 integer,
parameter :: test_size = 100*1000
10 call test_linear_extrapolation(table_size, test_size)
11 call test_valid_location(table_size, test_size)
16 integer,
intent(in) :: table_size, n_samples
18 real(dp) :: x(2) = [-1.0_dp, 1.0_dp]
19 real(dp) :: x_sample(2) = [-2.0_dp, 2.0_dp]
20 real(dp),
allocatable :: x_test(:), y(:)
21 real(dp) :: max_deviation
22 real(dp),
parameter :: tolerance = 5e-14_dp
24 print *,
"test_linear_data"
26 my_lt =
lt_create(x(1), x(2), n_points=table_size, n_cols=1, &
31 allocate(x_test(n_samples))
32 allocate(y(n_samples))
34 call random_number(x_test)
35 x_test = x_sample(1) + (x_sample(2) - x_sample(1)) * x_test
39 elsewhere (x_test > x(2))
45 max_deviation = maxval(abs(
lt_get_col(my_lt, 1, x_test) - y))
47 if (max_deviation > tolerance)
then
48 print *,
"FAILED: too large deviation from solution", max_deviation
55 subroutine test_linear_extrapolation(table_size, n_samples)
56 integer,
intent(in) :: table_size, n_samples
58 real(dp) :: x(2) = [-1.0_dp, 1.0_dp]
59 real(dp) :: x_sample(2) = [-2.0_dp, 2.0_dp]
60 real(dp),
allocatable :: x_test(:), y(:)
61 real(dp) :: max_deviation
62 real(dp),
parameter :: tolerance = 5e-14_dp
64 print *,
"test_linear_extrapolation"
66 my_lt =
lt_create(x(1), x(2), n_points=table_size, n_cols=1, &
71 allocate(x_test(n_samples))
72 allocate(y(n_samples))
74 call random_number(x_test)
75 x_test = x_sample(1) + (x_sample(2) - x_sample(1)) * x_test
83 max_deviation = maxval(abs(
lt_get_col(my_lt, 1, x_test) - y))
85 if (max_deviation > tolerance)
then
86 print *,
"FAILED: too large deviation from solution", max_deviation
91 end subroutine test_linear_extrapolation
93 subroutine test_valid_location(table_size, n_samples)
94 integer,
intent(in) :: table_size, n_samples
96 real(dp) :: x(2) = [-1.0_dp, 1.0_dp]
97 real(dp) :: x_sample(2) = [-2.0_dp, 2.0_dp]
98 real(dp),
allocatable :: x_test(:)
99 type(
lt_loc_t),
allocatable :: locs(:)
103 print *,
"test_valid_location"
105 my_lt =
lt_create(x(1), x(2), n_points=table_size, n_cols=0, &
108 allocate(x_test(n_samples))
109 call random_number(x_test)
110 x_test = x_sample(1) + (x_sample(2) - x_sample(1)) * x_test
112 allocate(locs(n_samples))
116 if (maxval(locs(:)%low_ix) > table_size - 1)
then
117 print *,
"FAILED: too high low_ix in location"
121 if (minval(locs(:)%low_ix) < 1)
then
122 print *,
"FAILED: too low low_ix in location"
127 if (x_test(n) < x(1))
then
128 if (locs(n)%low_ix /= 1)
then
129 print *,
"FAILED: low_ix /= 1 for x < x_min"
132 else if (x_test(n) > x(2))
then
133 if (locs(n)%low_ix /= table_size-1)
then
134 print *,
"FAILED: low_ix /= table_size-1 for x > x_max"
137 else if (my_lt%x(locs(n)%low_ix) > x_test(n) .or. &
138 my_lt%x(locs(n)%low_ix+1) < x_test(n))
then
139 print *,
"FAILED: x not between x(low_ix) and x(low_ix+1)"
144 if (n /= n_samples + 1) success = .false.
145 if (success) print *,
"PASSED"
147 end subroutine test_valid_location
149 real(dp)
elemental function f_linear(x)
150 real(dp),
intent(in) :: x
151 f_linear = -1.5_dp * x + 0.5_dp
152 end function f_linear
A Fortran 90 module for creating lookup tables. These tables can be used to efficiently interpolate o...
subroutine, public lt_set_col(my_lt, col_ix, x, y)
Fill the column with index col_ix after linearly interpolating.
type(lt_t) function, public lt_create(x_min, x_max, n_points, n_cols, xspacing, extrapolate_above)
This function returns a new lookup table.
elemental real(dp) function, public lt_get_col(my_lt, col_ix, x)
Get the value of a single column at x.
integer, parameter, public lt_xspacing_linear
elemental type(lt_loc_t) function, public lt_get_loc(my_lt, x)
Get a location in the lookup table.
Type to indicate a location in the lookup table, which can be used to speed up multiple lookups of di...
The lookup table type. There can be one or more columns, for which values can be looked up for a give...
subroutine test_linear_data(table_size, n_samples)