Skip to content

Commit ca289c3

Browse files
committed
Added routines to find cumulative integrals
1 parent fa1d59d commit ca289c3

File tree

3 files changed

+234
-4
lines changed

3 files changed

+234
-4
lines changed

Diff for: README

+4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ lib_array.f90 (no dependencies)
2828
- integral_linlog: trapezium integration with linear-log interpolation
2929
- integral_loglin: trapezium integration with log-linear interpolation
3030
- integral_loglog: trapezium integration with log-log interpolation
31+
- cumulative_integral: cumulative version of integral
32+
- cumulative_integral_linlog: cumulative version of integral_linlog
33+
- cumulative_integral_loglin: cumulative version of integral_loglin
34+
- cumulative_integral_loglog: cumulative version of integral_loglog
3135
- locate: search for a value in a sorted array
3236
- interp1d: 1-D linear interpolation
3337
- interp2d: 2-D linear interpolation

Diff for: src/lib_array.f90

+143-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
! MD5 of template: 712f522020dbe2eab390eba5980d46a1
1+
! MD5 of template: 0b9f273f3eb8d1227efa1e89e6732368
22
! Array related routines (Integration, Interpolation, etc.)
33
! Thomas Robitaille (c) 2009
44

@@ -41,6 +41,14 @@ module lib_array
4141
module procedure integral_subset_dp
4242
end interface integral
4343

44+
public :: cumulative_integral
45+
interface cumulative_integral
46+
module procedure cumulative_integral_sp
47+
module procedure cumulative_integral_dp
48+
! module procedure cumulative_integral_subset_sp
49+
! module procedure cumulative_integral_subset_dp
50+
end interface cumulative_integral
51+
4452
public :: integral_linlog
4553
interface integral_linlog
4654
module procedure integral_linlog_sp
@@ -49,6 +57,14 @@ module lib_array
4957
module procedure integral_linlog_subset_dp
5058
end interface integral_linlog
5159

60+
public :: cumulative_integral_linlog
61+
interface cumulative_integral_linlog
62+
module procedure cumulative_integral_linlog_sp
63+
module procedure cumulative_integral_linlog_dp
64+
! module procedure cumulative_integral_linlog_subset_sp
65+
! module procedure cumulative_integral_linlog_subset_dp
66+
end interface cumulative_integral_linlog
67+
5268
public :: integral_loglin
5369
interface integral_loglin
5470
module procedure integral_loglin_sp
@@ -57,6 +73,14 @@ module lib_array
5773
module procedure integral_loglin_subset_dp
5874
end interface integral_loglin
5975

76+
public :: cumulative_integral_loglin
77+
interface cumulative_integral_loglin
78+
module procedure cumulative_integral_loglin_sp
79+
module procedure cumulative_integral_loglin_dp
80+
! module procedure cumulative_integral_loglin_subset_sp
81+
! module procedure cumulative_integral_loglin_subset_dp
82+
end interface cumulative_integral_loglin
83+
6084
public :: integral_loglog
6185
interface integral_loglog
6286
module procedure integral_loglog_sp
@@ -65,6 +89,14 @@ module lib_array
6589
module procedure integral_loglog_subset_dp
6690
end interface integral_loglog
6791

92+
public :: cumulative_integral_loglog
93+
interface cumulative_integral_loglog
94+
module procedure cumulative_integral_loglog_sp
95+
module procedure cumulative_integral_loglog_dp
96+
! module procedure cumulative_integral_loglog_subset_sp
97+
! module procedure cumulative_integral_loglog_subset_dp
98+
end interface cumulative_integral_loglog
99+
68100
public :: locate
69101
interface locate
70102
module procedure locate_sp
@@ -317,6 +349,41 @@ real(dp) function integral_loglog_subset_dp(x,y,x1,x2)
317349
integral_loglog_subset_dp = integral_general_subset_dp(x, y, x1, x2, interp1d_loglog_dp, trapezium_loglog_dp)
318350
end function integral_loglog_subset_dp
319351

352+
function cumulative_integral_dp(x,y)
353+
! Total cumulative_integral of a function
354+
implicit none
355+
real(dp),intent(in) :: x(:),y(:)
356+
real(dp), dimension(size(y)) :: cumulative_integral_dp
357+
cumulative_integral_dp = cumulative_integral_general_dp(x, y, trapezium_dp)
358+
end function cumulative_integral_dp
359+
360+
function cumulative_integral_linlog_dp(x,y)
361+
! Total cumulative_integral of a function
362+
! (uses linlog interpolation)
363+
implicit none
364+
real(dp),intent(in) :: x(:),y(:)
365+
real(dp), dimension(size(y)) :: cumulative_integral_linlog_dp
366+
cumulative_integral_linlog_dp = cumulative_integral_general_dp(x, y, trapezium_linlog_dp)
367+
end function cumulative_integral_linlog_dp
368+
369+
function cumulative_integral_loglin_dp(x,y)
370+
! Total cumulative_integral of a function
371+
! (uses loglin interpolation)
372+
implicit none
373+
real(dp),intent(in) :: x(:),y(:)
374+
real(dp), dimension(size(y)) :: cumulative_integral_loglin_dp
375+
cumulative_integral_loglin_dp = cumulative_integral_general_dp(x, y, trapezium_loglin_dp)
376+
end function cumulative_integral_loglin_dp
377+
378+
function cumulative_integral_loglog_dp(x,y)
379+
! Total cumulative_integral of a function
380+
! (uses log10 interpolation)
381+
implicit none
382+
real(dp),intent(in) :: x(:),y(:)
383+
real(dp), dimension(size(y)) :: cumulative_integral_loglog_dp
384+
cumulative_integral_loglog_dp = cumulative_integral_general_dp(x, y, trapezium_loglog_dp)
385+
end function cumulative_integral_loglog_dp
386+
320387
real(dp) function integral_general_dp(x,y,f_chunk) result(sum)
321388
! Total integral of a function
322389
implicit none
@@ -335,6 +402,25 @@ end function f_chunk
335402
end do
336403
end function integral_general_dp
337404

405+
function cumulative_integral_general_dp(x,y,f_chunk) result(c)
406+
! Total integral of a function
407+
implicit none
408+
real(dp),intent(in) :: x(:),y(:)
409+
integer :: j
410+
interface
411+
real(dp) function f_chunk(x1,y1,x2,y2)
412+
import :: dp
413+
implicit none
414+
real(dp),intent(in) :: x1,y1,x2,y2
415+
end function f_chunk
416+
end interface
417+
real(dp), dimension(size(y)) :: c
418+
c(1) = 0._dp
419+
do j=1,size(x)-1
420+
c(j+1)=c(j)+f_chunk(x(j),y(j),x(j+1),y(j+1))
421+
end do
422+
end function cumulative_integral_general_dp
423+
338424
real(dp) function integral_general_subset_dp(x,y,x1,x2,f_interp,f_chunk) result(sum)
339425
! Integral of a function between two limits
340426

@@ -371,7 +457,7 @@ end function f_chunk
371457
if(x1.gt.x(1)) then
372458
i1 = locate(x,x1)
373459
f1 = f_interp(x,y,x1)
374-
else
460+
else
375461
i1 = 0
376462
f1 = 0._dp
377463
end if
@@ -1269,6 +1355,41 @@ real(sp) function integral_loglog_subset_sp(x,y,x1,x2)
12691355
integral_loglog_subset_sp = integral_general_subset_sp(x, y, x1, x2, interp1d_loglog_sp, trapezium_loglog_sp)
12701356
end function integral_loglog_subset_sp
12711357

1358+
function cumulative_integral_sp(x,y)
1359+
! Total cumulative_integral of a function
1360+
implicit none
1361+
real(sp),intent(in) :: x(:),y(:)
1362+
real(sp), dimension(size(y)) :: cumulative_integral_sp
1363+
cumulative_integral_sp = cumulative_integral_general_sp(x, y, trapezium_sp)
1364+
end function cumulative_integral_sp
1365+
1366+
function cumulative_integral_linlog_sp(x,y)
1367+
! Total cumulative_integral of a function
1368+
! (uses linlog interpolation)
1369+
implicit none
1370+
real(sp),intent(in) :: x(:),y(:)
1371+
real(sp), dimension(size(y)) :: cumulative_integral_linlog_sp
1372+
cumulative_integral_linlog_sp = cumulative_integral_general_sp(x, y, trapezium_linlog_sp)
1373+
end function cumulative_integral_linlog_sp
1374+
1375+
function cumulative_integral_loglin_sp(x,y)
1376+
! Total cumulative_integral of a function
1377+
! (uses loglin interpolation)
1378+
implicit none
1379+
real(sp),intent(in) :: x(:),y(:)
1380+
real(sp), dimension(size(y)) :: cumulative_integral_loglin_sp
1381+
cumulative_integral_loglin_sp = cumulative_integral_general_sp(x, y, trapezium_loglin_sp)
1382+
end function cumulative_integral_loglin_sp
1383+
1384+
function cumulative_integral_loglog_sp(x,y)
1385+
! Total cumulative_integral of a function
1386+
! (uses log10 interpolation)
1387+
implicit none
1388+
real(sp),intent(in) :: x(:),y(:)
1389+
real(sp), dimension(size(y)) :: cumulative_integral_loglog_sp
1390+
cumulative_integral_loglog_sp = cumulative_integral_general_sp(x, y, trapezium_loglog_sp)
1391+
end function cumulative_integral_loglog_sp
1392+
12721393
real(sp) function integral_general_sp(x,y,f_chunk) result(sum)
12731394
! Total integral of a function
12741395
implicit none
@@ -1287,6 +1408,25 @@ end function f_chunk
12871408
end do
12881409
end function integral_general_sp
12891410

1411+
function cumulative_integral_general_sp(x,y,f_chunk) result(c)
1412+
! Total integral of a function
1413+
implicit none
1414+
real(sp),intent(in) :: x(:),y(:)
1415+
integer :: j
1416+
interface
1417+
real(sp) function f_chunk(x1,y1,x2,y2)
1418+
import :: sp
1419+
implicit none
1420+
real(sp),intent(in) :: x1,y1,x2,y2
1421+
end function f_chunk
1422+
end interface
1423+
real(sp), dimension(size(y)) :: c
1424+
c(1) = 0._sp
1425+
do j=1,size(x)-1
1426+
c(j+1)=c(j)+f_chunk(x(j),y(j),x(j+1),y(j+1))
1427+
end do
1428+
end function cumulative_integral_general_sp
1429+
12901430
real(sp) function integral_general_subset_sp(x,y,x1,x2,f_interp,f_chunk) result(sum)
12911431
! Integral of a function between two limits
12921432

@@ -1323,7 +1463,7 @@ end function f_chunk
13231463
if(x1.gt.x(1)) then
13241464
i1 = locate(x,x1)
13251465
f1 = f_interp(x,y,x1)
1326-
else
1466+
else
13271467
i1 = 0
13281468
f1 = 0._sp
13291469
end if

Diff for: templates/lib_array_template.f90

+87-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@ module lib_array
4040
module procedure integral_subset_dp
4141
end interface integral
4242

43+
public :: cumulative_integral
44+
interface cumulative_integral
45+
module procedure cumulative_integral_sp
46+
module procedure cumulative_integral_dp
47+
! module procedure cumulative_integral_subset_sp
48+
! module procedure cumulative_integral_subset_dp
49+
end interface cumulative_integral
50+
4351
public :: integral_linlog
4452
interface integral_linlog
4553
module procedure integral_linlog_sp
@@ -48,6 +56,14 @@ module lib_array
4856
module procedure integral_linlog_subset_dp
4957
end interface integral_linlog
5058

59+
public :: cumulative_integral_linlog
60+
interface cumulative_integral_linlog
61+
module procedure cumulative_integral_linlog_sp
62+
module procedure cumulative_integral_linlog_dp
63+
! module procedure cumulative_integral_linlog_subset_sp
64+
! module procedure cumulative_integral_linlog_subset_dp
65+
end interface cumulative_integral_linlog
66+
5167
public :: integral_loglin
5268
interface integral_loglin
5369
module procedure integral_loglin_sp
@@ -56,6 +72,14 @@ module lib_array
5672
module procedure integral_loglin_subset_dp
5773
end interface integral_loglin
5874

75+
public :: cumulative_integral_loglin
76+
interface cumulative_integral_loglin
77+
module procedure cumulative_integral_loglin_sp
78+
module procedure cumulative_integral_loglin_dp
79+
! module procedure cumulative_integral_loglin_subset_sp
80+
! module procedure cumulative_integral_loglin_subset_dp
81+
end interface cumulative_integral_loglin
82+
5983
public :: integral_loglog
6084
interface integral_loglog
6185
module procedure integral_loglog_sp
@@ -64,6 +88,14 @@ module lib_array
6488
module procedure integral_loglog_subset_dp
6589
end interface integral_loglog
6690

91+
public :: cumulative_integral_loglog
92+
interface cumulative_integral_loglog
93+
module procedure cumulative_integral_loglog_sp
94+
module procedure cumulative_integral_loglog_dp
95+
! module procedure cumulative_integral_loglog_subset_sp
96+
! module procedure cumulative_integral_loglog_subset_dp
97+
end interface cumulative_integral_loglog
98+
6799
public :: locate
68100
interface locate
69101
module procedure locate_sp
@@ -298,6 +330,41 @@ real(<T>) function integral_loglog_subset_<T>(x,y,x1,x2)
298330
integral_loglog_subset_<T> = integral_general_subset_<T>(x, y, x1, x2, interp1d_loglog_<T>, trapezium_loglog_<T>)
299331
end function integral_loglog_subset_<T>
300332

333+
function cumulative_integral_<T>(x,y)
334+
! Total cumulative_integral of a function
335+
implicit none
336+
real(<T>),intent(in) :: x(:),y(:)
337+
real(<T>), dimension(size(y)) :: cumulative_integral_<T>
338+
cumulative_integral_<T> = cumulative_integral_general_<T>(x, y, trapezium_<T>)
339+
end function cumulative_integral_<T>
340+
341+
function cumulative_integral_linlog_<T>(x,y)
342+
! Total cumulative_integral of a function
343+
! (uses linlog interpolation)
344+
implicit none
345+
real(<T>),intent(in) :: x(:),y(:)
346+
real(<T>), dimension(size(y)) :: cumulative_integral_linlog_<T>
347+
cumulative_integral_linlog_<T> = cumulative_integral_general_<T>(x, y, trapezium_linlog_<T>)
348+
end function cumulative_integral_linlog_<T>
349+
350+
function cumulative_integral_loglin_<T>(x,y)
351+
! Total cumulative_integral of a function
352+
! (uses loglin interpolation)
353+
implicit none
354+
real(<T>),intent(in) :: x(:),y(:)
355+
real(<T>), dimension(size(y)) :: cumulative_integral_loglin_<T>
356+
cumulative_integral_loglin_<T> = cumulative_integral_general_<T>(x, y, trapezium_loglin_<T>)
357+
end function cumulative_integral_loglin_<T>
358+
359+
function cumulative_integral_loglog_<T>(x,y)
360+
! Total cumulative_integral of a function
361+
! (uses log10 interpolation)
362+
implicit none
363+
real(<T>),intent(in) :: x(:),y(:)
364+
real(<T>), dimension(size(y)) :: cumulative_integral_loglog_<T>
365+
cumulative_integral_loglog_<T> = cumulative_integral_general_<T>(x, y, trapezium_loglog_<T>)
366+
end function cumulative_integral_loglog_<T>
367+
301368
real(<T>) function integral_general_<T>(x,y,f_chunk) result(sum)
302369
! Total integral of a function
303370
implicit none
@@ -316,6 +383,25 @@ end function f_chunk
316383
end do
317384
end function integral_general_<T>
318385

386+
function cumulative_integral_general_<T>(x,y,f_chunk) result(c)
387+
! Total integral of a function
388+
implicit none
389+
real(<T>),intent(in) :: x(:),y(:)
390+
integer :: j
391+
interface
392+
real(<T>) function f_chunk(x1,y1,x2,y2)
393+
import :: <T>
394+
implicit none
395+
real(<T>),intent(in) :: x1,y1,x2,y2
396+
end function f_chunk
397+
end interface
398+
real(<T>), dimension(size(y)) :: c
399+
c(1) = 0._<T>
400+
do j=1,size(x)-1
401+
c(j+1)=c(j)+f_chunk(x(j),y(j),x(j+1),y(j+1))
402+
end do
403+
end function cumulative_integral_general_<T>
404+
319405
real(<T>) function integral_general_subset_<T>(x,y,x1,x2,f_interp,f_chunk) result(sum)
320406
! Integral of a function between two limits
321407

@@ -352,7 +438,7 @@ end function f_chunk
352438
if(x1.gt.x(1)) then
353439
i1 = locate(x,x1)
354440
f1 = f_interp(x,y,x1)
355-
else
441+
else
356442
i1 = 0
357443
f1 = 0._<T>
358444
end if

0 commit comments

Comments
 (0)