diff --git a/doc/specs/stdlib_linalg.md b/doc/specs/stdlib_linalg.md index cab16279c..b99c11fad 100644 --- a/doc/specs/stdlib_linalg.md +++ b/doc/specs/stdlib_linalg.md @@ -206,3 +206,81 @@ program demo_outer_product !A = reshape([3., 6., 9., 4., 8., 12.], [3,2]) end program demo_outer_product ``` + +## `empty` + +### Description + +`empty` creates a new rank-1 or rank-2 `array` of `integer/real/complex` type and given shape, without initializing values. + +`empty`, unlike `zeros`, does not set the array values to zero, and may therefore be marginally faster. On the other hand, it requires the user to manually set all the values in the array, and should be used with caution. + +### Status + +Experimental + +### Class + +Pure function. + +### Syntax + +For rank-1 `array`: +`result = [[stdlib_linalg(module):empty(interface)]](dim)` + +For rank-2 `array`: +`result = [[stdlib_linalg(module):empty(interface)]](dim1, dim2)` + +### Arguments + +`dim/dim1`: Shall be an `integer` scalar. +This is an `intent(in)` argument. + +`dim2`: Shall be an `integer` scalar. +This is an `intent(in)` argument. + +### Return value + +Returns a new rank-1 or rank-2 `array` of `integer` type and given shape, without initializing values. + +#### Note +If the receiving `array` of the return value of the `empty` function is of a `real/complex` type, conversion from `integer` type to `real/complex` type will occur. + +### Example + +```fortran +program demo_linlag_empty_1 + + use stdlib_linlag, only: empty + implicit none + integer, allocatable :: i(:,:) + + print *, empty(2, 1) + print *, 0.0*empty(2) !! 0.00000000 0.00000000 + print *, 0.0*empty(2) + 1.0*empty(2) + print *, (0.1, 0.1)*empty(2) + (0.2, 0.2)*empty(2) + + i = empty(2,2) + print *, reshape(empty(2*3*4),[2,3,4]) + +end program demo_linalg_empty_1 +``` + +```fortran +program demo_linlag_empty_2 + + use stdlib_linlag, only: empty + implicit none + integer, allocatable :: i(:,:) + real, allocatable :: r(:,:) + complex, allocatable :: c(:,:) + integer :: j(2) + + i = empty(2,1) + r = empty(2,1) + c = empty(2,1) + j = empty(2) + print *, i, r, c, j + +end program demo_linalg_empty_2 +``` \ No newline at end of file diff --git a/src/stdlib_linalg.fypp b/src/stdlib_linalg.fypp index 5e0388c0b..fecea546b 100644 --- a/src/stdlib_linalg.fypp +++ b/src/stdlib_linalg.fypp @@ -9,6 +9,7 @@ module stdlib_linalg private public :: diag + public :: empty public :: eye public :: trace public :: outer_product @@ -53,6 +54,15 @@ module stdlib_linalg #:endfor end interface + !> Version: experimental + !> + !> `empty` creates a new rank-1 or rank-2 `array` of `integer` type and given shape, + !> without initializing values. + !> ([Specification](../page/specs/stdlib_linalg.html#empty)) + interface empty + procedure :: empty_1_default, empty_2_default + end interface empty + ! Matrix trace interface trace @@ -108,4 +118,23 @@ contains end do end function trace_${t1[0]}$${k1}$ #:endfor -end module + + !> `empty` creates an empty rank-1 `array` of `integer` type. + pure function empty_1_default(dim) result(result) + integer, intent(in) :: dim + integer, allocatable :: result(:) + + allocate(result(dim)) + + end function empty_1_default + + !> `empty` creates an empty rank-2 `array` of `integer` type. + pure function empty_2_default(dim1, dim2) result(result) + integer, intent(in) :: dim1, dim2 + integer, allocatable :: result(:, :) + + allocate(result(dim1, dim2)) + + end function empty_2_default + +end module stdlib_linalg diff --git a/src/tests/Makefile.manual b/src/tests/Makefile.manual index 7ab184016..c29170e24 100644 --- a/src/tests/Makefile.manual +++ b/src/tests/Makefile.manual @@ -11,3 +11,4 @@ all test clean: $(MAKE) -f Makefile.manual --directory=stats $@ $(MAKE) -f Makefile.manual --directory=string $@ $(MAKE) -f Makefile.manual --directory=math $@ + $(MAKE) -f Makefile.manual --directory=linalg $@ diff --git a/src/tests/linalg/CMakeLists.txt b/src/tests/linalg/CMakeLists.txt index f1098405b..89c4f98b4 100644 --- a/src/tests/linalg/CMakeLists.txt +++ b/src/tests/linalg/CMakeLists.txt @@ -1,2 +1,3 @@ ADDTEST(linalg) +ADDTEST(linalg_empty) diff --git a/src/tests/linalg/Makefile.manual b/src/tests/linalg/Makefile.manual new file mode 100644 index 000000000..b3311eca5 --- /dev/null +++ b/src/tests/linalg/Makefile.manual @@ -0,0 +1,4 @@ +PROGS_SRC = test_linalg_empty.f90 + + +include ../Makefile.manual.test.mk \ No newline at end of file diff --git a/src/tests/linalg/test_linalg_empty.f90 b/src/tests/linalg/test_linalg_empty.f90 new file mode 100644 index 000000000..177b91f9b --- /dev/null +++ b/src/tests/linalg/test_linalg_empty.f90 @@ -0,0 +1,44 @@ +! SPDX-Identifier: MIT +module test_linalg_empty + + use stdlib_error, only: check + use stdlib_linalg, only: empty + implicit none + logical :: warn = .false. + +contains + + subroutine test_linalg_empty_integer + call check(size(empty(2)) == 2, msg="size(empty(2)) == 2 failed", warn=warn) + call check(size(empty(1, 2)) == 2, msg="size(empty(1,2)) == 2 failed", warn=warn) + end subroutine test_linalg_empty_integer + + subroutine test_linalg_empty_real + real, allocatable :: rA(:), rB(:, :) + rA = empty(2) + call check(size(rA) == 2, msg="size(rA) == 2 failed.", warn=warn) + rB = empty(1, 2) + call check(size(rB) == 2, msg="size(rB) == 2 failed.", warn=warn) + end subroutine test_linalg_empty_real + + subroutine test_linalg_empty_cmplx + complex, allocatable :: cA(:), cB(:, :) + cA = empty(2) + call check(size(cA) == 2, msg="size(cA) == 2 failed.", warn=warn) + cB = empty(1, 2) + call check(size(cB) == 2, msg="size(cB) == 2 failed.", warn=warn) + end subroutine test_linalg_empty_cmplx + +end module test_linalg_empty + +program tester + + use test_linalg_empty + + call test_linalg_empty_integer + call test_linalg_empty_real + call test_linalg_empty_cmplx + + print *, "All tests in `test_linalg_empty` passed." + +end program tester