From a4d2cc66b28861983c683dea84ac44625fffe844 Mon Sep 17 00:00:00 2001 From: zoziha13 <1325686572@qq.com> Date: Fri, 30 Jul 2021 18:32:29 +0800 Subject: [PATCH 1/5] Add zeros, ones, ex function. --- doc/specs/stdlib_linalg.md | 104 +++++++++++++++++++++++++++ src/CMakeLists.txt | 1 + src/Makefile.manual | 8 ++- src/stdlib_linalg.fypp | 55 +++++++++++++- src/stdlib_linalg_exs.fypp | 76 ++++++++++++++++++++ src/tests/Makefile.manual | 1 + src/tests/linalg/CMakeLists.txt | 1 + src/tests/linalg/Makefile.manual | 4 ++ src/tests/linalg/test_linalg_exs.f90 | 75 +++++++++++++++++++ 9 files changed, 323 insertions(+), 2 deletions(-) create mode 100644 src/stdlib_linalg_exs.fypp create mode 100644 src/tests/linalg/Makefile.manual create mode 100644 src/tests/linalg/test_linalg_exs.f90 diff --git a/doc/specs/stdlib_linalg.md b/doc/specs/stdlib_linalg.md index cab16279c..00a75470c 100644 --- a/doc/specs/stdlib_linalg.md +++ b/doc/specs/stdlib_linalg.md @@ -206,3 +206,107 @@ program demo_outer_product !A = reshape([3., 6., 9., 4., 8., 12.], [3,2]) end program demo_outer_product ``` + +## `zeros/ones` - creates an vector or matrix of `integer` type, given shape and `0/1` value. + +### Status + +Experimental + +### Class + +Pure function. + +### Description + +`zeros/ones` creates an vector or matrix of `integer` type, given shape and `0/1` value. + +### Syntax + +For vector: +`result = [[stdlib_linalg(module):zeros(interface)]](dim)` +`result = [[stdlib_linalg(module):ones(interface)]](dim)` + +For matrix: +`result = [[stdlib_linalg(module):zeros(interface)]](dim1, dim2)` +`result = [[stdlib_linalg(module):ones(interface)]](dim1, dim2)` + + +### Arguments + +`dim/dim1`: Shall be an `integer` type. + +`dim2`: Shall be an `integer` type. + +### Return value + +Returns an vector or matrix of `integer` type, given shape and `0/1` value. + +### Example + +```fortran +program demo + use stdlib_linalg, only: zeros, ones + implicit none + real, allocatable :: A(:,:) + + A = zeros(2,2) !! 0 0 0 0 + A = ones(4,4) !! 1 1 1 1; 1 1 1 1; 1 1 1 1; 1 1 1 1 + A = 2.0*ones(2,2) !! 2.00000000 2.00000000 2.00000000 2.00000000 + +end program demo +``` + +## `ex` - creates an vector or matrix of `integer/logical/real/complex/string_type` type, given shape and `value` value. + +### Status + +Experimental + +### Class + +Pure function. + +### Description + +`ex` creates an vector or matrix of `integer/logical/real/complex/string_type` type, given shape and `value` value. + +### Syntax + +For vector: +`result = [[stdlib_linalg(module):ex(interface)]](value, dim)` + +For matrix: +`result = [[stdlib_linalg(module):ex(interface)]](value, dim1, dim2)` + + +### Arguments + +`value`: Shall be an `integer/logical/real/complex/string_type` scalar. +This is an `intent(in)` argument. + +`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 an vector or matrix of `integer/logical/real/complex/string_type` type, given shape and `value` value. + +### Example + +```fortran +program demo_linalg_ex + use stdlib_linalg, only: zeros, ones + implicit none + real, allocatable :: A(:,:) + + A = ex(0,2,2) !! Same as zeros(2,2) + A = ex(1,4,4) !! Same as ones(4,4) + A = 2.0*ex(1, 2,2) !! 2.00000000 2.00000000 2.00000000 2.00000000 + A = ex(1.0, 2) !! 1.00000000 1.00000000 + +end program demo_linalg_ex +``` \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c4f6d76e7..d6b484ba0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,6 +9,7 @@ set(fppFiles stdlib_io.fypp stdlib_linalg.fypp stdlib_linalg_diag.fypp + stdlib_linalg_exs.fypp stdlib_linalg_outer_product.fypp stdlib_optval.fypp stdlib_sorting.fypp diff --git a/src/Makefile.manual b/src/Makefile.manual index a12f81255..63281fbbb 100644 --- a/src/Makefile.manual +++ b/src/Makefile.manual @@ -6,6 +6,7 @@ SRCFYPP =\ stdlib_io.fypp \ stdlib_linalg.fypp \ stdlib_linalg_diag.fypp \ + stdlib_linalg_exs.fypp \ stdlib_linalg_outer_product.fypp \ stdlib_optval.fypp \ stdlib_quadrature.fypp \ @@ -81,10 +82,15 @@ stdlib_io.o: \ stdlib_optval.o \ stdlib_kinds.o stdlib_linalg.o: \ - stdlib_kinds.o + stdlib_kinds.o \ + stdlib_string_type.o stdlib_linalg_diag.o: \ stdlib_linalg.o \ stdlib_kinds.o +stdlib_linalg_exs.o: \ + stdlib_linalg.o \ + stdlib_kinds.o \ + stdlib_string_type.o stdlib_logger.o: stdlib_ascii.o stdlib_optval.o stdlib_optval.o: stdlib_kinds.o stdlib_quadrature.o: stdlib_kinds.o diff --git a/src/stdlib_linalg.fypp b/src/stdlib_linalg.fypp index 5e0388c0b..b8267be61 100644 --- a/src/stdlib_linalg.fypp +++ b/src/stdlib_linalg.fypp @@ -4,7 +4,8 @@ module stdlib_linalg !!Provides a support for various linear algebra procedures !! ([Specification](../page/specs/stdlib_linalg.html)) use stdlib_kinds, only: sp, dp, qp, & - int8, int16, int32, int64 + int8, int16, int32, int64, lk, c_bool + use stdlib_string_type, only: string_type implicit none private @@ -12,6 +13,7 @@ module stdlib_linalg public :: eye public :: trace public :: outer_product + public :: zeros, ones, ex interface diag !! version: experimental @@ -80,6 +82,57 @@ module stdlib_linalg #:endfor end interface outer_product + !> Version: experimental + !> + !> `ones` creates an vector or matrix of `integer` type and given shape, + !> with a `1` value. + interface ones + pure module function ones_1_default(dim) result(result) + integer, intent(in) :: dim + integer :: result(dim) + end function ones_1_default + pure module function ones_2_default(dim1, dim2) result(result) + integer, intent(in) :: dim1, dim2 + integer :: result(dim1, dim2) + end function ones_2_default + end interface ones + + !> Version: experimental + !> + !> `zeros` creates an vector or matrix of `integer` type and given shape, + !> with a `0` value. + interface zeros + pure module function zeros_1_default(dim) result(result) + integer, intent(in) :: dim + integer :: result(dim) + end function zeros_1_default + pure module function zeros_2_default(dim1, dim2) result(result) + integer, intent(in) :: dim1, dim2 + integer :: result(dim1, dim2) + end function zeros_2_default + end interface zeros + + !> Version: experimental + !> + !> `ex` creates an vector or matrix of `integer/logical/real/complex/string_type` type and given shape, + !> with an `value` value. + interface ex + #:set ALL_KINDS_TYPES = REAL_KINDS_TYPES + INT_KINDS_TYPES + CMPLX_KINDS_TYPES & + & + LOG_KINDS_TYPES + STRING_KINDS_TYPES + #:for k1, t1 in ALL_KINDS_TYPES + pure module function ex_1_${t1[0]}$_${k1}$(value, dim) result(result) + ${t1}$, intent(in) :: value + integer, intent(in) :: dim + ${t1}$ :: result(dim) + end function ex_1_${t1[0]}$_${k1}$ + pure module function ex_2_${t1[0]}$_${k1}$(value, dim1, dim2) result(result) + ${t1}$, intent(in) :: value + integer, intent(in) :: dim1, dim2 + ${t1}$ :: result(dim1, dim2) + end function ex_2_${t1[0]}$_${k1}$ + #:endfor + end interface ex + contains function eye(n) result(res) diff --git a/src/stdlib_linalg_exs.fypp b/src/stdlib_linalg_exs.fypp new file mode 100644 index 000000000..ad64e65c8 --- /dev/null +++ b/src/stdlib_linalg_exs.fypp @@ -0,0 +1,76 @@ +#:include "common.fypp" +#:set ALL_KINDS_TYPES = REAL_KINDS_TYPES + INT_KINDS_TYPES + CMPLX_KINDS_TYPES & + & + LOG_KINDS_TYPES + STRING_KINDS_TYPES +submodule(stdlib_linalg) stdlib_linalg_exs + + implicit none + +contains + + !> `ones` creates an vector of `integer` type and `1` value. + pure module function ones_1_default(dim) result(result) + implicit none + integer, intent(in) :: dim + integer :: result(dim) + + result = 1 + + end function ones_1_default + + !> `ones` creates a matrix of `integer` type and `1` value. + pure module function ones_2_default(dim1, dim2) result(result) + implicit none + integer, intent(in) :: dim1, dim2 + integer :: result(dim1, dim2) + + result = 1 + + end function ones_2_default + + !> `zeros` creates an vector of `integer` type and `0` value. + pure module function zeros_1_default(dim) result(result) + implicit none + integer, intent(in) :: dim + integer :: result(dim) + + result = 0 + + end function zeros_1_default + + !> `zeros` creates a matrix of `integer` type and `0` value. + pure module function zeros_2_default(dim1, dim2) result(result) + implicit none + integer, intent(in) :: dim1, dim2 + integer :: result(dim1, dim2) + + result = 0 + + end function zeros_2_default + + #:for k1, t1 in ALL_KINDS_TYPES + !> `ex` creates an vector of `${t1}$` type and `value` value. + pure module function ex_1_${t1[0]}$_${k1}$(value, dim) result(result) + + implicit none + ${t1}$, intent(in) :: value + integer, intent(in) :: dim + ${t1}$ :: result(dim) + + result = value + + end function ex_1_${t1[0]}$_${k1}$ + + !> `ex` creates a matrix of `${t1}$` type and `value` value. + pure module function ex_2_${t1[0]}$_${k1}$(value, dim1, dim2) result(result) + + implicit none + ${t1}$, intent(in) :: value + integer, intent(in) :: dim1, dim2 + ${t1}$ :: result(dim1, dim2) + + result = value + + end function ex_2_${t1[0]}$_${k1}$ + #:endfor + +end submodule stdlib_linalg_exs 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..6a2be9f45 100644 --- a/src/tests/linalg/CMakeLists.txt +++ b/src/tests/linalg/CMakeLists.txt @@ -1,2 +1,3 @@ ADDTEST(linalg) +ADDTEST(linalg_exs) diff --git a/src/tests/linalg/Makefile.manual b/src/tests/linalg/Makefile.manual new file mode 100644 index 000000000..9f426bf3b --- /dev/null +++ b/src/tests/linalg/Makefile.manual @@ -0,0 +1,4 @@ +PROGS_SRC = test_linalg_exs.f90 + + +include ../Makefile.manual.test.mk diff --git a/src/tests/linalg/test_linalg_exs.f90 b/src/tests/linalg/test_linalg_exs.f90 new file mode 100644 index 000000000..6a2fee115 --- /dev/null +++ b/src/tests/linalg/test_linalg_exs.f90 @@ -0,0 +1,75 @@ +!> SPDX-Identifier: MIT +module test_linalg_exs + + use stdlib_linalg, only: zeros, ones, ex + use stdlib_error, only: check + use stdlib_string_type + implicit none + + logical, parameter :: warn = .false. + +contains + + subroutine test_linalg_zeros + call check(all(zeros(2) == [0, 0]), msg="all(zeros(2)==[0, 0] failed", warn=warn) + call check(all(zeros(2, 2) == reshape([0, 0, 0, 0], [2, 2])), & + msg="all(zeros(2,2)==reshape([0, 0, 0, 0],[2,2]) failed", warn=warn) + end subroutine test_linalg_zeros + + subroutine test_linalg_ones + call check(all(ones(2) == [1, 1]), msg="all(ones(2)==[1, 1] failed", warn=warn) + call check(all(ones(2, 2) == reshape([1, 1, 1, 1], [2, 2])), & + msg="all(ones(2,2)==reshape([1, 1, 1, 1],[2,2]) failed", warn=warn) + end subroutine test_linalg_ones + + subroutine test_linalg_ex_integer + call check(all(ex(1, 2) == ones(2)), msg="all(ex(1, 2) == ones(2)) failed", warn=warn) + call check(all(ex(1, 2, 2) == ones(2, 2)), & + msg="all(ex(1, 2, 2) == ones(2,2)) failed", warn=warn) + end subroutine test_linalg_ex_integer + + subroutine test_linalg_ex_real + call check(all(ex(1.0, 2) == 1.0*ones(2)), msg="all(ex(1.0, 2) == 1.0*ones(2)) failed", warn=warn) + call check(all(ex(1.0, 2, 2) == 1.0*ones(2, 2)), & + msg="all(ex(1.0, 2, 2) == 1.0*ones(2,2)) failed", warn=warn) + end subroutine test_linalg_ex_real + + subroutine test_linalg_ex_complex + call check(all(ex((1.0, 1.0), 2) == (1.0, 1.0)*ones(2)), & + msg="all(ex((1.0,1.0), 2) == (1.0,1.0)*ones(2)) failed", warn=warn) + call check(all(ex((1.0, 1.0), 2, 2) == (1.0, 1.0)*ones(2, 2)), & + msg="all(ex((1.0,1.0), 2, 2) == (1.0,1.0)*ones(2,2)) failed", warn=warn) + end subroutine test_linalg_ex_complex + + subroutine test_linalg_ex_logical + call check(all(ex(.true., 2) .eqv. [.true., .true.]), & + msg="all(ex(.true., 2) .eqv. [.true., .true.]) failed", warn=warn) + call check(all(ex(.true., 1, 2) .eqv. reshape([.true., .true.], [1, 2])), & + msg="all(ex(.true., 1, 2) .eqv. reshape([.true., .true.],[1,2])) failed", warn=warn) + end subroutine test_linalg_ex_logical + + subroutine test_linalg_ex_string_type + call check(all(ex(string_type("A"), 2) == [string_type("A"), string_type("A")]), & + msg='all(ex(string_type("A"), 2) == [string_type("A"), & + &string_type("A")]) failed', warn=warn) + call check(all(ex(string_type("A"), 1, 2) == reshape([string_type("A"), string_type("A")], [1, 2])), & + msg='all(ex(string_type("A"), 1, 2) == reshape([string_type("A"), & + &string_type("A")],[1,2])) failed', warn=warn) + end subroutine test_linalg_ex_string_type + +end module test_linalg_exs + +program tester + + use test_linalg_exs + + call test_linalg_zeros + call test_linalg_ones + call test_linalg_ex_integer + call test_linalg_ex_real + call test_linalg_ex_complex + call test_linalg_ex_logical + call test_linalg_ex_string_type + print *, "All tests in `test_linalg_exs` passed" + +end program tester From d88a88da6827b1a228a1fab733e45095e2ba3c72 Mon Sep 17 00:00:00 2001 From: zoziha13 <1325686572@qq.com> Date: Fri, 30 Jul 2021 19:44:17 +0800 Subject: [PATCH 2/5] fix test_linalg_exs.f90: `reshape` function is not compatible with `string_type` type in some compilers --- src/tests/linalg/test_linalg_exs.f90 | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/tests/linalg/test_linalg_exs.f90 b/src/tests/linalg/test_linalg_exs.f90 index 6a2fee115..c4e89ff43 100644 --- a/src/tests/linalg/test_linalg_exs.f90 +++ b/src/tests/linalg/test_linalg_exs.f90 @@ -49,12 +49,17 @@ subroutine test_linalg_ex_logical end subroutine test_linalg_ex_logical subroutine test_linalg_ex_string_type + + type(string_type) :: string_list(1,2) + string_list = string_type("A") + call check(all(ex(string_type("A"), 2) == [string_type("A"), string_type("A")]), & msg='all(ex(string_type("A"), 2) == [string_type("A"), & &string_type("A")]) failed', warn=warn) - call check(all(ex(string_type("A"), 1, 2) == reshape([string_type("A"), string_type("A")], [1, 2])), & + call check(all(ex(string_type("A"), 1, 2) == string_list), & msg='all(ex(string_type("A"), 1, 2) == reshape([string_type("A"), & &string_type("A")],[1,2])) failed', warn=warn) + end subroutine test_linalg_ex_string_type end module test_linalg_exs @@ -70,6 +75,7 @@ program tester call test_linalg_ex_complex call test_linalg_ex_logical call test_linalg_ex_string_type + print *, "All tests in `test_linalg_exs` passed" end program tester From c6eaa283a8c3e8663b24a2c87ffd7f530c5b46e3 Mon Sep 17 00:00:00 2001 From: zoziha13 <1325686572@qq.com> Date: Mon, 2 Aug 2021 21:22:20 +0800 Subject: [PATCH 3/5] Update `zeros/ones/expand` function: 1. automatic array -> allocatable array. 2. the name: `ex` -> `expand`. 3. update stdlib_linalg.md related docs. --- doc/specs/stdlib_linalg.md | 79 ++++++++--- src/CMakeLists.txt | 2 +- src/Makefile.manual | 6 +- src/stdlib_linalg.fypp | 28 ++-- ...alg_exs.fypp => stdlib_linalg_expand.fypp} | 42 +++--- src/tests/linalg/CMakeLists.txt | 2 +- src/tests/linalg/Makefile.manual | 2 +- src/tests/linalg/test_linalg_expand.f90 | 132 ++++++++++++++++++ src/tests/linalg/test_linalg_exs.f90 | 81 ----------- 9 files changed, 228 insertions(+), 146 deletions(-) rename src/{stdlib_linalg_exs.fypp => stdlib_linalg_expand.fypp} (58%) create mode 100644 src/tests/linalg/test_linalg_expand.f90 delete mode 100644 src/tests/linalg/test_linalg_exs.f90 diff --git a/doc/specs/stdlib_linalg.md b/doc/specs/stdlib_linalg.md index 00a75470c..b64011d57 100644 --- a/doc/specs/stdlib_linalg.md +++ b/doc/specs/stdlib_linalg.md @@ -207,7 +207,7 @@ program demo_outer_product end program demo_outer_product ``` -## `zeros/ones` - creates an vector or matrix of `integer` type, given shape and `0/1` value. +## `zeros/ones` - Create an vector or matrix of `integer/real/complex` type, given shape and `0/1` value. ### Status @@ -219,15 +219,15 @@ Pure function. ### Description -`zeros/ones` creates an vector or matrix of `integer` type, given shape and `0/1` value. +`zeros/ones` creates an vector or matrix of `integer/real/complex` type, given shape and `0/1` value. ### Syntax -For vector: +For vector: `result = [[stdlib_linalg(module):zeros(interface)]](dim)` `result = [[stdlib_linalg(module):ones(interface)]](dim)` -For matrix: +For matrix: `result = [[stdlib_linalg(module):zeros(interface)]](dim1, dim2)` `result = [[stdlib_linalg(module):ones(interface)]](dim1, dim2)` @@ -235,12 +235,22 @@ For matrix: ### Arguments `dim/dim1`: Shall be an `integer` type. +This is an `intent(in)` argument. `dim2`: Shall be an `integer` type. +This is an `intent(in)` argument. + +#### Note + +Because of `huge(integer :: i) == 2147483647`, the dimensional maximum length of array created by the `zeros/ones` function is `2147483647`. ### Return value -Returns an vector or matrix of `integer` type, given shape and `0/1` value. +Returns an `vector` or `matrix` of `integer` type, given shape and `0/1` value. + +#### Note + +If the array that receives the return value of the `zeros/ones` function is of `real/complex` type, conversion from `integer` type to `real/complex` type will occur. ### Example @@ -249,15 +259,20 @@ program demo use stdlib_linalg, only: zeros, ones implicit none real, allocatable :: A(:,:) + integer :: iA(2) + compelx :: cA(2) - A = zeros(2,2) !! 0 0 0 0 - A = ones(4,4) !! 1 1 1 1; 1 1 1 1; 1 1 1 1; 1 1 1 1 - A = 2.0*ones(2,2) !! 2.00000000 2.00000000 2.00000000 2.00000000 + A = zeros(2,2) !! [0.0,0.0; 0.0,0.0] + A = ones(4,4) !! [1.0,1.0,1.0,1.0; 1.0,1.0,1.0,1.0; 1.0,1.0,1.0,1.0; 1.0,1.0,1.0 1.0] + A = 2.0*ones(2,2) !! [2.0,2.0; 2.0,2.0] + iA = ones(2) !! [1,1] + cA = ones(2) !! [(1.0,0.0),(1.0,0.0)] + cA = (1.0,1.0)*ones(2) !! [(1.0,1.0),(1.0,1.0)] end program demo ``` -## `ex` - creates an vector or matrix of `integer/logical/real/complex/string_type` type, given shape and `value` value. +## `expand` - Create an vector or matrix of `integer/logical/real/complex/string_type` type, given shape and given `value` value. ### Status @@ -269,16 +284,15 @@ Pure function. ### Description -`ex` creates an vector or matrix of `integer/logical/real/complex/string_type` type, given shape and `value` value. +`expand` creates an vector or matrix of `integer/logical/real/complex/string_type` type, given shape and given `value` value. ### Syntax -For vector: -`result = [[stdlib_linalg(module):ex(interface)]](value, dim)` - -For matrix: -`result = [[stdlib_linalg(module):ex(interface)]](value, dim1, dim2)` +For vector: +`result = [[stdlib_linalg(module):expand(interface)]](value, dim)` +For matrix: +`result = [[stdlib_linalg(module):expand(interface)]](value, dim1, dim2)` ### Arguments @@ -291,22 +305,41 @@ This is an `intent(in)` argument. `dim2`: Shall be an `integer` scalar. This is an `intent(in)` argument. +#### Note + +Because of `huge(integer :: i) == 2147483647`, the dimensional maximum length of array created by the `expand` function is `2147483647`. + ### Return value -Returns an vector or matrix of `integer/logical/real/complex/string_type` type, given shape and `value` value. +Returns an vector or matrix of `integer/logical/real/complex/string_type` type, given shape and given `value` value. ### Example ```fortran -program demo_linalg_ex - use stdlib_linalg, only: zeros, ones +program demo_linalg_expand_1 + use stdlib_linalg, only: expand implicit none real, allocatable :: A(:,:) - A = ex(0,2,2) !! Same as zeros(2,2) - A = ex(1,4,4) !! Same as ones(4,4) - A = 2.0*ex(1, 2,2) !! 2.00000000 2.00000000 2.00000000 2.00000000 - A = ex(1.0, 2) !! 1.00000000 1.00000000 + A = expand(0,2,2) !! Same as zeros(2,2) + A = expand(1,2,1) !! Same as ones(4,4) + A = 2.0*expand(1, 2,2) !! 2.00000000 2.00000000 2.00000000 2.00000000 + A = expand(1.0, 2) !! 1.00000000 1.00000000 + +end program demo_linalg_expand_1 +``` + +```fortran +program demo_linalg_expand_2 + use stdlib_linalg, only: expand + use stdlib_string_type + implicit none + + print *, expand(1, 2) !! [1,1] + print *, expand(1.0, 2) !! [1.0,1.0] + print *, expand((1.0,1.0), 2) !! [(1.0,1.0),(1.0,1.0)] + print *, expand(.false., 2) !! [F,F] + print *, expand(string_type("A"), 2) !! ["A","A"] -end program demo_linalg_ex +end program demo_linalg_expand_2 ``` \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d6b484ba0..a3454e7df 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,7 +9,7 @@ set(fppFiles stdlib_io.fypp stdlib_linalg.fypp stdlib_linalg_diag.fypp - stdlib_linalg_exs.fypp + stdlib_linalg_expand.fypp stdlib_linalg_outer_product.fypp stdlib_optval.fypp stdlib_sorting.fypp diff --git a/src/Makefile.manual b/src/Makefile.manual index 63281fbbb..2e261d66b 100644 --- a/src/Makefile.manual +++ b/src/Makefile.manual @@ -6,7 +6,7 @@ SRCFYPP =\ stdlib_io.fypp \ stdlib_linalg.fypp \ stdlib_linalg_diag.fypp \ - stdlib_linalg_exs.fypp \ + stdlib_linalg_expand.fypp \ stdlib_linalg_outer_product.fypp \ stdlib_optval.fypp \ stdlib_quadrature.fypp \ @@ -87,10 +87,10 @@ stdlib_linalg.o: \ stdlib_linalg_diag.o: \ stdlib_linalg.o \ stdlib_kinds.o -stdlib_linalg_exs.o: \ +stdlib_linalg_expand.o: \ stdlib_linalg.o \ stdlib_kinds.o \ - stdlib_string_type.o + stdlib_string_type.o stdlib_logger.o: stdlib_ascii.o stdlib_optval.o stdlib_optval.o: stdlib_kinds.o stdlib_quadrature.o: stdlib_kinds.o diff --git a/src/stdlib_linalg.fypp b/src/stdlib_linalg.fypp index b8267be61..effec9afa 100644 --- a/src/stdlib_linalg.fypp +++ b/src/stdlib_linalg.fypp @@ -13,7 +13,7 @@ module stdlib_linalg public :: eye public :: trace public :: outer_product - public :: zeros, ones, ex + public :: zeros, ones, expand interface diag !! version: experimental @@ -89,11 +89,11 @@ module stdlib_linalg interface ones pure module function ones_1_default(dim) result(result) integer, intent(in) :: dim - integer :: result(dim) + integer, allocatable :: result(:) end function ones_1_default pure module function ones_2_default(dim1, dim2) result(result) integer, intent(in) :: dim1, dim2 - integer :: result(dim1, dim2) + integer, allocatable :: result(:, :) end function ones_2_default end interface ones @@ -104,34 +104,34 @@ module stdlib_linalg interface zeros pure module function zeros_1_default(dim) result(result) integer, intent(in) :: dim - integer :: result(dim) + integer, allocatable :: result(:) end function zeros_1_default pure module function zeros_2_default(dim1, dim2) result(result) integer, intent(in) :: dim1, dim2 - integer :: result(dim1, dim2) + integer, allocatable :: result(:, :) end function zeros_2_default end interface zeros !> Version: experimental !> - !> `ex` creates an vector or matrix of `integer/logical/real/complex/string_type` type and given shape, + !> `expand` creates an vector or matrix of `integer/logical/real/complex/string_type` type and given shape, !> with an `value` value. - interface ex + interface expand #:set ALL_KINDS_TYPES = REAL_KINDS_TYPES + INT_KINDS_TYPES + CMPLX_KINDS_TYPES & & + LOG_KINDS_TYPES + STRING_KINDS_TYPES #:for k1, t1 in ALL_KINDS_TYPES - pure module function ex_1_${t1[0]}$_${k1}$(value, dim) result(result) + pure module function expand_1_${t1[0]}$_${k1}$(value, dim) result(result) ${t1}$, intent(in) :: value integer, intent(in) :: dim - ${t1}$ :: result(dim) - end function ex_1_${t1[0]}$_${k1}$ - pure module function ex_2_${t1[0]}$_${k1}$(value, dim1, dim2) result(result) + ${t1}$, allocatable :: result(:) + end function expand_1_${t1[0]}$_${k1}$ + pure module function expand_2_${t1[0]}$_${k1}$(value, dim1, dim2) result(result) ${t1}$, intent(in) :: value integer, intent(in) :: dim1, dim2 - ${t1}$ :: result(dim1, dim2) - end function ex_2_${t1[0]}$_${k1}$ + ${t1}$, allocatable :: result(:, :) + end function expand_2_${t1[0]}$_${k1}$ #:endfor - end interface ex + end interface expand contains diff --git a/src/stdlib_linalg_exs.fypp b/src/stdlib_linalg_expand.fypp similarity index 58% rename from src/stdlib_linalg_exs.fypp rename to src/stdlib_linalg_expand.fypp index ad64e65c8..e8e8f305c 100644 --- a/src/stdlib_linalg_exs.fypp +++ b/src/stdlib_linalg_expand.fypp @@ -1,76 +1,74 @@ #:include "common.fypp" #:set ALL_KINDS_TYPES = REAL_KINDS_TYPES + INT_KINDS_TYPES + CMPLX_KINDS_TYPES & & + LOG_KINDS_TYPES + STRING_KINDS_TYPES -submodule(stdlib_linalg) stdlib_linalg_exs - - implicit none +submodule(stdlib_linalg) stdlib_linalg_expand contains !> `ones` creates an vector of `integer` type and `1` value. pure module function ones_1_default(dim) result(result) - implicit none integer, intent(in) :: dim - integer :: result(dim) + integer, allocatable :: result(:) + allocate(result(dim)) result = 1 end function ones_1_default !> `ones` creates a matrix of `integer` type and `1` value. pure module function ones_2_default(dim1, dim2) result(result) - implicit none integer, intent(in) :: dim1, dim2 - integer :: result(dim1, dim2) + integer, allocatable :: result(:, :) + allocate(result(dim1, dim2)) result = 1 end function ones_2_default !> `zeros` creates an vector of `integer` type and `0` value. pure module function zeros_1_default(dim) result(result) - implicit none integer, intent(in) :: dim - integer :: result(dim) + integer, allocatable :: result(:) + allocate(result(dim)) result = 0 end function zeros_1_default !> `zeros` creates a matrix of `integer` type and `0` value. pure module function zeros_2_default(dim1, dim2) result(result) - implicit none integer, intent(in) :: dim1, dim2 - integer :: result(dim1, dim2) + integer, allocatable :: result(:, :) + allocate(result(dim1, dim2)) result = 0 end function zeros_2_default #:for k1, t1 in ALL_KINDS_TYPES - !> `ex` creates an vector of `${t1}$` type and `value` value. - pure module function ex_1_${t1[0]}$_${k1}$(value, dim) result(result) + !> `expand` creates an vector of `${t1}$` type and `value` value. + pure module function expand_1_${t1[0]}$_${k1}$(value, dim) result(result) - implicit none ${t1}$, intent(in) :: value integer, intent(in) :: dim - ${t1}$ :: result(dim) + ${t1}$, allocatable :: result(:) + allocate(result(dim)) result = value - end function ex_1_${t1[0]}$_${k1}$ + end function expand_1_${t1[0]}$_${k1}$ - !> `ex` creates a matrix of `${t1}$` type and `value` value. - pure module function ex_2_${t1[0]}$_${k1}$(value, dim1, dim2) result(result) + !> `expand` creates a matrix of `${t1}$` type and `value` value. + pure module function expand_2_${t1[0]}$_${k1}$(value, dim1, dim2) result(result) - implicit none ${t1}$, intent(in) :: value integer, intent(in) :: dim1, dim2 - ${t1}$ :: result(dim1, dim2) + ${t1}$, allocatable :: result(:, :) + allocate(result(dim1, dim2)) result = value - end function ex_2_${t1[0]}$_${k1}$ + end function expand_2_${t1[0]}$_${k1}$ #:endfor -end submodule stdlib_linalg_exs +end submodule stdlib_linalg_expand diff --git a/src/tests/linalg/CMakeLists.txt b/src/tests/linalg/CMakeLists.txt index 6a2be9f45..5a33d8f17 100644 --- a/src/tests/linalg/CMakeLists.txt +++ b/src/tests/linalg/CMakeLists.txt @@ -1,3 +1,3 @@ ADDTEST(linalg) -ADDTEST(linalg_exs) +ADDTEST(linalg_expand) diff --git a/src/tests/linalg/Makefile.manual b/src/tests/linalg/Makefile.manual index 9f426bf3b..e8a1725ea 100644 --- a/src/tests/linalg/Makefile.manual +++ b/src/tests/linalg/Makefile.manual @@ -1,4 +1,4 @@ -PROGS_SRC = test_linalg_exs.f90 +PROGS_SRC = test_linalg_expand.f90 include ../Makefile.manual.test.mk diff --git a/src/tests/linalg/test_linalg_expand.f90 b/src/tests/linalg/test_linalg_expand.f90 new file mode 100644 index 000000000..932cb4a97 --- /dev/null +++ b/src/tests/linalg/test_linalg_expand.f90 @@ -0,0 +1,132 @@ +!> SPDX-Identifier: MIT +module test_linalg_expand + + use stdlib_linalg, only: zeros, ones, expand + use stdlib_error, only: check + use stdlib_string_type + implicit none + + logical, parameter :: warn = .false. + +contains + + !> `zeros` tests + + subroutine test_linalg_zeros_integer + call check(all(zeros(2) == [0, 0]), msg="all(zeros(2)==[0, 0] failed", warn=warn) + call check(all(zeros(2, 2) == reshape([0, 0, 0, 0], [2, 2])), & + msg="all(zeros(2,2)==reshape([0, 0, 0, 0],[2,2]) failed", warn=warn) + end subroutine test_linalg_zeros_integer + + subroutine test_linalg_zeros_real + real, allocatable :: rA(:), rB(:,:) + rA = zeros(2) + call check(all(rA == expand(0.0_4, 2)), msg="all(rA == expand(1.0_4, 2)) failed", warn=warn) + rB = zeros(2,2) + call check(all(rB == expand(0.0_4, 2,2)), & + msg="all(rB == expand(1.0_4, 2,2)) failed", warn=warn) + end subroutine test_linalg_zeros_real + + subroutine test_linalg_zeros_complex + complex, allocatable :: cA(:), cB(:,:) + cA = zeros(2) + call check(all(cA == expand((0.0_4,0.0_4), 2)), msg="all(cA == expand((1.0_4,0.0_4), 2)) failed", warn=warn) + cB = zeros(2,2) + call check(all(cB == expand((0.0_4,0.0_4), 2,2)), & + msg="all(cB == expand((1.0_4,0.0_4), 2,2)) failed", warn=warn) + end subroutine test_linalg_zeros_complex + + !> `ones` tests + + subroutine test_linalg_ones_integer + call check(all(ones(2) == [1, 1]), msg="all(ones(2)==[1, 1] failed", warn=warn) + call check(all(ones(2, 2) == reshape([1, 1, 1, 1], [2, 2])), & + msg="all(ones(2,2)==reshape([1, 1, 1, 1],[2,2]) failed", warn=warn) + end subroutine test_linalg_ones_integer + + subroutine test_linalg_ones_real + real, allocatable :: rA(:), rB(:,:) + rA = ones(2) + call check(all(rA == expand(1.0_4, 2)), msg="all(rA == expand(1.0_4, 2)) failed", warn=warn) + rB = ones(2,2) + call check(all(rB == expand(1.0_4, 2,2)), & + msg="all(rB == expand(1.0_4, 2,2)) failed", warn=warn) + end subroutine test_linalg_ones_real + + subroutine test_linalg_ones_complex + complex, allocatable :: cA(:), cB(:,:) + cA = ones(2) + call check(all(cA == expand((1.0_4,0.0_4), 2)), msg="all(cA == expand((1.0_4,0.0_4), 2)) failed", warn=warn) + cB = ones(2,2) + call check(all(cB == expand((1.0_4,0.0_4), 2,2)), & + msg="all(cB == expand((1.0_4,0.0_4), 2,2)) failed", warn=warn) + end subroutine test_linalg_ones_complex + + !> `expand` tests + + subroutine test_linalg_expand_integer + call check(all(expand(1, 2) == ones(2)), msg="all(expand(1, 2) == ones(2)) failed", warn=warn) + call check(all(expand(1, 2, 2) == ones(2, 2)), & + msg="all(expand(1, 2, 2) == ones(2,2)) failed", warn=warn) + end subroutine test_linalg_expand_integer + + subroutine test_linalg_expand_real + call check(all(expand(1.0, 2) == 1.0*ones(2)), msg="all(expand(1.0, 2) == 1.0*ones(2)) failed", warn=warn) + call check(all(expand(1.0, 2, 2) == 1.0*ones(2, 2)), & + msg="all(expand(1.0, 2, 2) == 1.0*ones(2,2)) failed", warn=warn) + end subroutine test_linalg_expand_real + + subroutine test_linalg_expand_complex + call check(all(expand((1.0, 1.0), 2) == (1.0, 1.0)*ones(2)), & + msg="all(expand((1.0,1.0), 2) == (1.0,1.0)*ones(2)) failed", warn=warn) + call check(all(expand((1.0, 1.0), 2, 2) == (1.0, 1.0)*ones(2, 2)), & + msg="all(expand((1.0,1.0), 2, 2) == (1.0,1.0)*ones(2,2)) failed", warn=warn) + end subroutine test_linalg_expand_complex + + subroutine test_linalg_expand_logical + call check(all(expand(.true., 2) .eqv. [.true., .true.]), & + msg="all(expand(.true., 2) .eqv. [.true., .true.]) failed", warn=warn) + call check(all(expand(.true., 1, 2) .eqv. reshape([.true., .true.], [1, 2])), & + msg="all(expand(.true., 1, 2) .eqv. reshape([.true., .true.],[1,2])) failed", warn=warn) + end subroutine test_linalg_expand_logical + + subroutine test_linalg_expand_string_type + + type(string_type) :: string_list(1,2) + string_list = string_type("A") + + call check(all(expand(string_type("A"), 2) == [string_type("A"), string_type("A")]), & + msg='all(expand(string_type("A"), 2) == [string_type("A"), & + &string_type("A")]) failed', warn=warn) + call check(all(expand(string_type("A"), 1, 2) == string_list), & + msg='all(expand(string_type("A"), 1, 2) == reshape([string_type("A"), & + &string_type("A")],[1,2])) failed', warn=warn) + + end subroutine test_linalg_expand_string_type + +end module test_linalg_expand + +program tester + + use test_linalg_expand + + print *, "`zeros` tests" + call test_linalg_zeros_integer + call test_linalg_zeros_real + call test_linalg_zeros_complex + + print *, "`ones` tests" + call test_linalg_ones_integer + call test_linalg_ones_real + call test_linalg_ones_complex + + print *, "`expand` tests" + call test_linalg_expand_integer + call test_linalg_expand_real + call test_linalg_expand_complex + call test_linalg_expand_logical + call test_linalg_expand_string_type + + print *, "All tests in `test_linalg_expand` passed" + +end program tester diff --git a/src/tests/linalg/test_linalg_exs.f90 b/src/tests/linalg/test_linalg_exs.f90 deleted file mode 100644 index c4e89ff43..000000000 --- a/src/tests/linalg/test_linalg_exs.f90 +++ /dev/null @@ -1,81 +0,0 @@ -!> SPDX-Identifier: MIT -module test_linalg_exs - - use stdlib_linalg, only: zeros, ones, ex - use stdlib_error, only: check - use stdlib_string_type - implicit none - - logical, parameter :: warn = .false. - -contains - - subroutine test_linalg_zeros - call check(all(zeros(2) == [0, 0]), msg="all(zeros(2)==[0, 0] failed", warn=warn) - call check(all(zeros(2, 2) == reshape([0, 0, 0, 0], [2, 2])), & - msg="all(zeros(2,2)==reshape([0, 0, 0, 0],[2,2]) failed", warn=warn) - end subroutine test_linalg_zeros - - subroutine test_linalg_ones - call check(all(ones(2) == [1, 1]), msg="all(ones(2)==[1, 1] failed", warn=warn) - call check(all(ones(2, 2) == reshape([1, 1, 1, 1], [2, 2])), & - msg="all(ones(2,2)==reshape([1, 1, 1, 1],[2,2]) failed", warn=warn) - end subroutine test_linalg_ones - - subroutine test_linalg_ex_integer - call check(all(ex(1, 2) == ones(2)), msg="all(ex(1, 2) == ones(2)) failed", warn=warn) - call check(all(ex(1, 2, 2) == ones(2, 2)), & - msg="all(ex(1, 2, 2) == ones(2,2)) failed", warn=warn) - end subroutine test_linalg_ex_integer - - subroutine test_linalg_ex_real - call check(all(ex(1.0, 2) == 1.0*ones(2)), msg="all(ex(1.0, 2) == 1.0*ones(2)) failed", warn=warn) - call check(all(ex(1.0, 2, 2) == 1.0*ones(2, 2)), & - msg="all(ex(1.0, 2, 2) == 1.0*ones(2,2)) failed", warn=warn) - end subroutine test_linalg_ex_real - - subroutine test_linalg_ex_complex - call check(all(ex((1.0, 1.0), 2) == (1.0, 1.0)*ones(2)), & - msg="all(ex((1.0,1.0), 2) == (1.0,1.0)*ones(2)) failed", warn=warn) - call check(all(ex((1.0, 1.0), 2, 2) == (1.0, 1.0)*ones(2, 2)), & - msg="all(ex((1.0,1.0), 2, 2) == (1.0,1.0)*ones(2,2)) failed", warn=warn) - end subroutine test_linalg_ex_complex - - subroutine test_linalg_ex_logical - call check(all(ex(.true., 2) .eqv. [.true., .true.]), & - msg="all(ex(.true., 2) .eqv. [.true., .true.]) failed", warn=warn) - call check(all(ex(.true., 1, 2) .eqv. reshape([.true., .true.], [1, 2])), & - msg="all(ex(.true., 1, 2) .eqv. reshape([.true., .true.],[1,2])) failed", warn=warn) - end subroutine test_linalg_ex_logical - - subroutine test_linalg_ex_string_type - - type(string_type) :: string_list(1,2) - string_list = string_type("A") - - call check(all(ex(string_type("A"), 2) == [string_type("A"), string_type("A")]), & - msg='all(ex(string_type("A"), 2) == [string_type("A"), & - &string_type("A")]) failed', warn=warn) - call check(all(ex(string_type("A"), 1, 2) == string_list), & - msg='all(ex(string_type("A"), 1, 2) == reshape([string_type("A"), & - &string_type("A")],[1,2])) failed', warn=warn) - - end subroutine test_linalg_ex_string_type - -end module test_linalg_exs - -program tester - - use test_linalg_exs - - call test_linalg_zeros - call test_linalg_ones - call test_linalg_ex_integer - call test_linalg_ex_real - call test_linalg_ex_complex - call test_linalg_ex_logical - call test_linalg_ex_string_type - - print *, "All tests in `test_linalg_exs` passed" - -end program tester From baa12a9d59da1eb2c5ccfcfe343aee6a282c298c Mon Sep 17 00:00:00 2001 From: zoziha13 <1325686572@qq.com> Date: Tue, 3 Aug 2021 10:48:41 +0800 Subject: [PATCH 4/5] Improve the help documentation and comments of the `zeros/ones/expand` function. --- doc/specs/stdlib_linalg.md | 37 ++++++++++++++++++++++++----------- src/stdlib_linalg.fypp | 24 ++++++++++++++++------- src/stdlib_linalg_expand.fypp | 12 ++++++------ 3 files changed, 49 insertions(+), 24 deletions(-) diff --git a/doc/specs/stdlib_linalg.md b/doc/specs/stdlib_linalg.md index b64011d57..cbc86a726 100644 --- a/doc/specs/stdlib_linalg.md +++ b/doc/specs/stdlib_linalg.md @@ -207,7 +207,7 @@ program demo_outer_product end program demo_outer_product ``` -## `zeros/ones` - Create an vector or matrix of `integer/real/complex` type, given shape and `0/1` value. +## `zeros/ones` - Create a `vector` or `matrix` of the given shape, filled completely with either `0` or `1` `integer [/real/complex]` type values ### Status @@ -219,7 +219,8 @@ Pure function. ### Description -`zeros/ones` creates an vector or matrix of `integer/real/complex` type, given shape and `0/1` value. +`zeros` creates a `vector` or `matrix` of the given shape, filled completely with `0` `integer [/real/complex]` type values. +`ones` creates a `vector` or `matrix` of the given shape, filled completely with `1` `integer [/real/complex]` type values. ### Syntax @@ -246,11 +247,23 @@ Because of `huge(integer :: i) == 2147483647`, the dimensional maximum length of ### Return value -Returns an `vector` or `matrix` of `integer` type, given shape and `0/1` value. +Return a `vector` or `matrix` of the given shape, filled completely with either `0` or `1` `integer [/real/complex]` type values. -#### Note +#### Warning + +If the array that receives the return value of the `zeros/ones` function is of `real/complex` type, conversion from `integer` type to `real/complex` type will occur. + +Just as `Fortran` is a strongly typed statically compiled language, be careful with the following statements: +```fortran +real :: A(:,:) -If the array that receives the return value of the `zeros/ones` function is of `real/complex` type, conversion from `integer` type to `real/complex` type will occur. +!> Be careful +A = ones(2,2)/2 !! A = 1/2 = 0.0 + +!> Recommend +A = ones(2,2)/2.0 !! A = 1/2.0 = 0.5 +A = expand(0.5, 2,2) +``` ### Example @@ -260,7 +273,7 @@ program demo implicit none real, allocatable :: A(:,:) integer :: iA(2) - compelx :: cA(2) + compelx :: cA(2), cB(2,3) A = zeros(2,2) !! [0.0,0.0; 0.0,0.0] A = ones(4,4) !! [1.0,1.0,1.0,1.0; 1.0,1.0,1.0,1.0; 1.0,1.0,1.0,1.0; 1.0,1.0,1.0 1.0] @@ -269,10 +282,12 @@ program demo iA = ones(2) !! [1,1] cA = ones(2) !! [(1.0,0.0),(1.0,0.0)] cA = (1.0,1.0)*ones(2) !! [(1.0,1.0),(1.0,1.0)] + cB = ones(2,3) !! [(1.0,0.0),(1.0,0.0),(1.0,0.0); (1.0,0.0),(1.0,0.0),(1.0,0.0)] + end program demo ``` -## `expand` - Create an vector or matrix of `integer/logical/real/complex/string_type` type, given shape and given `value` value. +## `expand` - Create a `vector` or `matrix` of the given shape, filled completely with `value` `integer/logical/real/complex/string_type` type values ### Status @@ -284,7 +299,7 @@ Pure function. ### Description -`expand` creates an vector or matrix of `integer/logical/real/complex/string_type` type, given shape and given `value` value. +`expand` creates a `vector` or `matrix` of the given shape, filled completely with `value` `integer/logical/real/complex/string_type` type values. ### Syntax @@ -311,7 +326,7 @@ Because of `huge(integer :: i) == 2147483647`, the dimensional maximum length of ### Return value -Returns an vector or matrix of `integer/logical/real/complex/string_type` type, given shape and given `value` value. +Return a `vector` or `matrix` of the given shape, filled completely with `value` `integer/logical/real/complex/string_type` type values. ### Example @@ -323,8 +338,8 @@ program demo_linalg_expand_1 A = expand(0,2,2) !! Same as zeros(2,2) A = expand(1,2,1) !! Same as ones(4,4) - A = 2.0*expand(1, 2,2) !! 2.00000000 2.00000000 2.00000000 2.00000000 - A = expand(1.0, 2) !! 1.00000000 1.00000000 + A = 2.0*expand(1, 2,2) !! [2.0,2.0; 2.0,2.0] + A = expand(1.0, 2) !! [1.0,1.0] end program demo_linalg_expand_1 ``` diff --git a/src/stdlib_linalg.fypp b/src/stdlib_linalg.fypp index effec9afa..fc4a45fff 100644 --- a/src/stdlib_linalg.fypp +++ b/src/stdlib_linalg.fypp @@ -84,8 +84,11 @@ module stdlib_linalg !> Version: experimental !> - !> `ones` creates an vector or matrix of `integer` type and given shape, - !> with a `1` value. + !> `ones` creates a vector or matrix of the given shape, + !> filled completely with `1` `integer` type values. + !> ([Specification](../page/specs/stdlib_linalg.html# + !>zerosones-create-a-vector-or-matrix-of-the-given-shape + !>-filled-completely-with-either-0-or-1-integer-realcomplex-type-values)) interface ones pure module function ones_1_default(dim) result(result) integer, intent(in) :: dim @@ -99,8 +102,11 @@ module stdlib_linalg !> Version: experimental !> - !> `zeros` creates an vector or matrix of `integer` type and given shape, - !> with a `0` value. + !> `zeros` creates a vector or matrix of the given shape, + !> filled completely with `0` `integer` type values. + !> ([Specification](../page/specs/stdlib_linalg.html# + !>zerosones-create-a-vector-or-matrix-of-the-given-shape + !>-filled-completely-with-either-0-or-1-integer-realcomplex-type-values)) interface zeros pure module function zeros_1_default(dim) result(result) integer, intent(in) :: dim @@ -114,8 +120,11 @@ module stdlib_linalg !> Version: experimental !> - !> `expand` creates an vector or matrix of `integer/logical/real/complex/string_type` type and given shape, - !> with an `value` value. + !> `expand` creates a vector or matrix of the given shape, + !> filled with `value` `integer/logical/real/complex/string_type` type values. + !> ([Specification](../page/specs/stdlib_linalg.html# + !>expand-create-a-vector-or-matrix-of-the-given-shape- + !>filled-completely-with-value-integerlogicalrealcomplexstring_type-type-values)) interface expand #:set ALL_KINDS_TYPES = REAL_KINDS_TYPES + INT_KINDS_TYPES + CMPLX_KINDS_TYPES & & + LOG_KINDS_TYPES + STRING_KINDS_TYPES @@ -161,4 +170,5 @@ contains end do end function trace_${t1[0]}$${k1}$ #:endfor -end module + +end module stdlib_linalg diff --git a/src/stdlib_linalg_expand.fypp b/src/stdlib_linalg_expand.fypp index e8e8f305c..a716cd569 100644 --- a/src/stdlib_linalg_expand.fypp +++ b/src/stdlib_linalg_expand.fypp @@ -5,7 +5,7 @@ submodule(stdlib_linalg) stdlib_linalg_expand contains - !> `ones` creates an vector of `integer` type and `1` value. + !> `ones` creates a vector, filled completely with `1` `integer` type values. pure module function ones_1_default(dim) result(result) integer, intent(in) :: dim integer, allocatable :: result(:) @@ -15,7 +15,7 @@ contains end function ones_1_default - !> `ones` creates a matrix of `integer` type and `1` value. + !> `ones` creates a matrix, filled completely with `1` `integer` type values. pure module function ones_2_default(dim1, dim2) result(result) integer, intent(in) :: dim1, dim2 integer, allocatable :: result(:, :) @@ -25,7 +25,7 @@ contains end function ones_2_default - !> `zeros` creates an vector of `integer` type and `0` value. + !> `zeros` creates a vector, filled completely with `0` `integer` type values. pure module function zeros_1_default(dim) result(result) integer, intent(in) :: dim integer, allocatable :: result(:) @@ -35,7 +35,7 @@ contains end function zeros_1_default - !> `zeros` creates a matrix of `integer` type and `0` value. + !> `zeros` creates a matrix, filled completely with `0` `integer` type values. pure module function zeros_2_default(dim1, dim2) result(result) integer, intent(in) :: dim1, dim2 integer, allocatable :: result(:, :) @@ -46,7 +46,7 @@ contains end function zeros_2_default #:for k1, t1 in ALL_KINDS_TYPES - !> `expand` creates an vector of `${t1}$` type and `value` value. + !> `expand` creates a vector, filled completely with `value` `${t1}$` type values. pure module function expand_1_${t1[0]}$_${k1}$(value, dim) result(result) ${t1}$, intent(in) :: value @@ -58,7 +58,7 @@ contains end function expand_1_${t1[0]}$_${k1}$ - !> `expand` creates a matrix of `${t1}$` type and `value` value. + !> `expand` creates a matrix, filled completely with `value` `${t1}$` type values. pure module function expand_2_${t1[0]}$_${k1}$(value, dim1, dim2) result(result) ${t1}$, intent(in) :: value From d80955e3fb5324e933e091c206fbe669494f3f2e Mon Sep 17 00:00:00 2001 From: zoziha13 <1325686572@qq.com> Date: Wed, 11 Aug 2021 09:44:35 +0800 Subject: [PATCH 5/5] Remove `expand` func, focus on `ones/zeros` func. --- doc/specs/stdlib_linalg.md | 107 +++------------- src/CMakeLists.txt | 1 - src/Makefile.manual | 5 - src/stdlib_linalg.fypp | 94 +++++++------- src/stdlib_linalg_expand.fypp | 74 ----------- src/tests/linalg/CMakeLists.txt | 2 +- src/tests/linalg/Makefile.manual | 2 +- src/tests/linalg/test_linalg_expand.f90 | 132 -------------------- src/tests/linalg/test_linalg_ones_zeros.f90 | 81 ++++++++++++ 9 files changed, 143 insertions(+), 355 deletions(-) delete mode 100644 src/stdlib_linalg_expand.fypp delete mode 100644 src/tests/linalg/test_linalg_expand.f90 create mode 100644 src/tests/linalg/test_linalg_ones_zeros.f90 diff --git a/doc/specs/stdlib_linalg.md b/doc/specs/stdlib_linalg.md index cbc86a726..bbff70a68 100644 --- a/doc/specs/stdlib_linalg.md +++ b/doc/specs/stdlib_linalg.md @@ -207,7 +207,12 @@ program demo_outer_product end program demo_outer_product ``` -## `zeros/ones` - Create a `vector` or `matrix` of the given shape, filled completely with either `0` or `1` `integer [/real/complex]` type values +## `zeros/ones` + +### Description + +`zeros` creates a rank-1 or rank-2 `array` of the given shape, filled completely with `0` `integer` type values. +`ones` creates a rank-1 or rank-2 `array` of the given shape, filled completely with `1` `integer` type values. ### Status @@ -217,18 +222,13 @@ Experimental Pure function. -### Description - -`zeros` creates a `vector` or `matrix` of the given shape, filled completely with `0` `integer [/real/complex]` type values. -`ones` creates a `vector` or `matrix` of the given shape, filled completely with `1` `integer [/real/complex]` type values. - ### Syntax -For vector: +For rank-1 array: `result = [[stdlib_linalg(module):zeros(interface)]](dim)` `result = [[stdlib_linalg(module):ones(interface)]](dim)` -For matrix: +For rank-2 array: `result = [[stdlib_linalg(module):zeros(interface)]](dim1, dim2)` `result = [[stdlib_linalg(module):ones(interface)]](dim1, dim2)` @@ -241,19 +241,13 @@ This is an `intent(in)` argument. `dim2`: Shall be an `integer` type. This is an `intent(in)` argument. -#### Note - -Because of `huge(integer :: i) == 2147483647`, the dimensional maximum length of array created by the `zeros/ones` function is `2147483647`. - ### Return value -Return a `vector` or `matrix` of the given shape, filled completely with either `0` or `1` `integer [/real/complex]` type values. +Returns a rank-1 or rank-2 `array` of the given shape, filled completely with either `0` or `1` `integer` type values. #### Warning -If the array that receives the return value of the `zeros/ones` function is of `real/complex` type, conversion from `integer` type to `real/complex` type will occur. - -Just as `Fortran` is a strongly typed statically compiled language, be careful with the following statements: +Since the result of `ones` is of `integer` type, one should be careful about using it in arithmetic expressions. For example: ```fortran real :: A(:,:) @@ -262,7 +256,6 @@ A = ones(2,2)/2 !! A = 1/2 = 0.0 !> Recommend A = ones(2,2)/2.0 !! A = 1/2.0 = 0.5 -A = expand(0.5, 2,2) ``` ### Example @@ -273,88 +266,18 @@ program demo implicit none real, allocatable :: A(:,:) integer :: iA(2) - compelx :: cA(2), cB(2,3) + complex :: cA(2), cB(2,3) - A = zeros(2,2) !! [0.0,0.0; 0.0,0.0] + A = zeros(2,2) !! [0.0,0.0; 0.0,0.0] (Same as `reshape(spread(0,1,2*2),[2,2])`) A = ones(4,4) !! [1.0,1.0,1.0,1.0; 1.0,1.0,1.0,1.0; 1.0,1.0,1.0,1.0; 1.0,1.0,1.0 1.0] A = 2.0*ones(2,2) !! [2.0,2.0; 2.0,2.0] - iA = ones(2) !! [1,1] + print *, reshape(ones(2*3*4),[2,3,4]) !! Same as `reshape(spread(1,1,2*3*4),[2,3,4])` + + iA = ones(2) !! [1,1] (Same as `spread(1,1,2)`) cA = ones(2) !! [(1.0,0.0),(1.0,0.0)] cA = (1.0,1.0)*ones(2) !! [(1.0,1.0),(1.0,1.0)] cB = ones(2,3) !! [(1.0,0.0),(1.0,0.0),(1.0,0.0); (1.0,0.0),(1.0,0.0),(1.0,0.0)] end program demo ``` - -## `expand` - Create a `vector` or `matrix` of the given shape, filled completely with `value` `integer/logical/real/complex/string_type` type values - -### Status - -Experimental - -### Class - -Pure function. - -### Description - -`expand` creates a `vector` or `matrix` of the given shape, filled completely with `value` `integer/logical/real/complex/string_type` type values. - -### Syntax - -For vector: -`result = [[stdlib_linalg(module):expand(interface)]](value, dim)` - -For matrix: -`result = [[stdlib_linalg(module):expand(interface)]](value, dim1, dim2)` - -### Arguments - -`value`: Shall be an `integer/logical/real/complex/string_type` scalar. -This is an `intent(in)` argument. - -`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. - -#### Note - -Because of `huge(integer :: i) == 2147483647`, the dimensional maximum length of array created by the `expand` function is `2147483647`. - -### Return value - -Return a `vector` or `matrix` of the given shape, filled completely with `value` `integer/logical/real/complex/string_type` type values. - -### Example - -```fortran -program demo_linalg_expand_1 - use stdlib_linalg, only: expand - implicit none - real, allocatable :: A(:,:) - - A = expand(0,2,2) !! Same as zeros(2,2) - A = expand(1,2,1) !! Same as ones(4,4) - A = 2.0*expand(1, 2,2) !! [2.0,2.0; 2.0,2.0] - A = expand(1.0, 2) !! [1.0,1.0] - -end program demo_linalg_expand_1 -``` - -```fortran -program demo_linalg_expand_2 - use stdlib_linalg, only: expand - use stdlib_string_type - implicit none - - print *, expand(1, 2) !! [1,1] - print *, expand(1.0, 2) !! [1.0,1.0] - print *, expand((1.0,1.0), 2) !! [(1.0,1.0),(1.0,1.0)] - print *, expand(.false., 2) !! [F,F] - print *, expand(string_type("A"), 2) !! ["A","A"] - -end program demo_linalg_expand_2 -``` \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a3454e7df..c4f6d76e7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,7 +9,6 @@ set(fppFiles stdlib_io.fypp stdlib_linalg.fypp stdlib_linalg_diag.fypp - stdlib_linalg_expand.fypp stdlib_linalg_outer_product.fypp stdlib_optval.fypp stdlib_sorting.fypp diff --git a/src/Makefile.manual b/src/Makefile.manual index 2e261d66b..2d036d409 100644 --- a/src/Makefile.manual +++ b/src/Makefile.manual @@ -6,7 +6,6 @@ SRCFYPP =\ stdlib_io.fypp \ stdlib_linalg.fypp \ stdlib_linalg_diag.fypp \ - stdlib_linalg_expand.fypp \ stdlib_linalg_outer_product.fypp \ stdlib_optval.fypp \ stdlib_quadrature.fypp \ @@ -87,10 +86,6 @@ stdlib_linalg.o: \ stdlib_linalg_diag.o: \ stdlib_linalg.o \ stdlib_kinds.o -stdlib_linalg_expand.o: \ - stdlib_linalg.o \ - stdlib_kinds.o \ - stdlib_string_type.o stdlib_logger.o: stdlib_ascii.o stdlib_optval.o stdlib_optval.o: stdlib_kinds.o stdlib_quadrature.o: stdlib_kinds.o diff --git a/src/stdlib_linalg.fypp b/src/stdlib_linalg.fypp index fc4a45fff..c9e021231 100644 --- a/src/stdlib_linalg.fypp +++ b/src/stdlib_linalg.fypp @@ -13,7 +13,7 @@ module stdlib_linalg public :: eye public :: trace public :: outer_product - public :: zeros, ones, expand + public :: zeros, ones interface diag !! version: experimental @@ -84,64 +84,24 @@ module stdlib_linalg !> Version: experimental !> - !> `ones` creates a vector or matrix of the given shape, + !> `ones` creates a rank-1 or rank-2 array of the given shape, !> filled completely with `1` `integer` type values. - !> ([Specification](../page/specs/stdlib_linalg.html# - !>zerosones-create-a-vector-or-matrix-of-the-given-shape - !>-filled-completely-with-either-0-or-1-integer-realcomplex-type-values)) + !> ([Specification](../page/specs/stdlib_linalg.html#zerosones)) interface ones - pure module function ones_1_default(dim) result(result) - integer, intent(in) :: dim - integer, allocatable :: result(:) - end function ones_1_default - pure module function ones_2_default(dim1, dim2) result(result) - integer, intent(in) :: dim1, dim2 - integer, allocatable :: result(:, :) - end function ones_2_default + procedure :: ones_1_default + procedure :: ones_2_default end interface ones !> Version: experimental !> - !> `zeros` creates a vector or matrix of the given shape, + !> `zeros` creates a rank-1 or rank-2 array of the given shape, !> filled completely with `0` `integer` type values. - !> ([Specification](../page/specs/stdlib_linalg.html# - !>zerosones-create-a-vector-or-matrix-of-the-given-shape - !>-filled-completely-with-either-0-or-1-integer-realcomplex-type-values)) + !> ([Specification](../page/specs/stdlib_linalg.html#zerosones)) interface zeros - pure module function zeros_1_default(dim) result(result) - integer, intent(in) :: dim - integer, allocatable :: result(:) - end function zeros_1_default - pure module function zeros_2_default(dim1, dim2) result(result) - integer, intent(in) :: dim1, dim2 - integer, allocatable :: result(:, :) - end function zeros_2_default + procedure :: zeros_1_default + procedure :: zeros_2_default end interface zeros - !> Version: experimental - !> - !> `expand` creates a vector or matrix of the given shape, - !> filled with `value` `integer/logical/real/complex/string_type` type values. - !> ([Specification](../page/specs/stdlib_linalg.html# - !>expand-create-a-vector-or-matrix-of-the-given-shape- - !>filled-completely-with-value-integerlogicalrealcomplexstring_type-type-values)) - interface expand - #:set ALL_KINDS_TYPES = REAL_KINDS_TYPES + INT_KINDS_TYPES + CMPLX_KINDS_TYPES & - & + LOG_KINDS_TYPES + STRING_KINDS_TYPES - #:for k1, t1 in ALL_KINDS_TYPES - pure module function expand_1_${t1[0]}$_${k1}$(value, dim) result(result) - ${t1}$, intent(in) :: value - integer, intent(in) :: dim - ${t1}$, allocatable :: result(:) - end function expand_1_${t1[0]}$_${k1}$ - pure module function expand_2_${t1[0]}$_${k1}$(value, dim1, dim2) result(result) - ${t1}$, intent(in) :: value - integer, intent(in) :: dim1, dim2 - ${t1}$, allocatable :: result(:, :) - end function expand_2_${t1[0]}$_${k1}$ - #:endfor - end interface expand - contains function eye(n) result(res) @@ -171,4 +131,40 @@ contains end function trace_${t1[0]}$${k1}$ #:endfor + !> `ones` creates a rank-1 array, filled completely with `1` `integer` type values. + pure function ones_1_default(dim) result(result) + integer, intent(in) :: dim + integer, allocatable :: result(:) + + allocate(result(dim), source=1) + + end function ones_1_default + + !> `ones` creates a rank-2 array, filled completely with `1` `integer` type values. + pure function ones_2_default(dim1, dim2) result(result) + integer, intent(in) :: dim1, dim2 + integer, allocatable :: result(:, :) + + allocate(result(dim1, dim2), source=1) + + end function ones_2_default + + !> `zeros` creates a rank-1 array, filled completely with `0` `integer` type values. + pure function zeros_1_default(dim) result(result) + integer, intent(in) :: dim + integer, allocatable :: result(:) + + allocate(result(dim), source=0) + + end function zeros_1_default + + !> `zeros` creates a rank-2 array, filled completely with `0` `integer` type values. + pure function zeros_2_default(dim1, dim2) result(result) + integer, intent(in) :: dim1, dim2 + integer, allocatable :: result(:, :) + + allocate(result(dim1, dim2), source=0) + + end function zeros_2_default + end module stdlib_linalg diff --git a/src/stdlib_linalg_expand.fypp b/src/stdlib_linalg_expand.fypp deleted file mode 100644 index a716cd569..000000000 --- a/src/stdlib_linalg_expand.fypp +++ /dev/null @@ -1,74 +0,0 @@ -#:include "common.fypp" -#:set ALL_KINDS_TYPES = REAL_KINDS_TYPES + INT_KINDS_TYPES + CMPLX_KINDS_TYPES & - & + LOG_KINDS_TYPES + STRING_KINDS_TYPES -submodule(stdlib_linalg) stdlib_linalg_expand - -contains - - !> `ones` creates a vector, filled completely with `1` `integer` type values. - pure module function ones_1_default(dim) result(result) - integer, intent(in) :: dim - integer, allocatable :: result(:) - - allocate(result(dim)) - result = 1 - - end function ones_1_default - - !> `ones` creates a matrix, filled completely with `1` `integer` type values. - pure module function ones_2_default(dim1, dim2) result(result) - integer, intent(in) :: dim1, dim2 - integer, allocatable :: result(:, :) - - allocate(result(dim1, dim2)) - result = 1 - - end function ones_2_default - - !> `zeros` creates a vector, filled completely with `0` `integer` type values. - pure module function zeros_1_default(dim) result(result) - integer, intent(in) :: dim - integer, allocatable :: result(:) - - allocate(result(dim)) - result = 0 - - end function zeros_1_default - - !> `zeros` creates a matrix, filled completely with `0` `integer` type values. - pure module function zeros_2_default(dim1, dim2) result(result) - integer, intent(in) :: dim1, dim2 - integer, allocatable :: result(:, :) - - allocate(result(dim1, dim2)) - result = 0 - - end function zeros_2_default - - #:for k1, t1 in ALL_KINDS_TYPES - !> `expand` creates a vector, filled completely with `value` `${t1}$` type values. - pure module function expand_1_${t1[0]}$_${k1}$(value, dim) result(result) - - ${t1}$, intent(in) :: value - integer, intent(in) :: dim - ${t1}$, allocatable :: result(:) - - allocate(result(dim)) - result = value - - end function expand_1_${t1[0]}$_${k1}$ - - !> `expand` creates a matrix, filled completely with `value` `${t1}$` type values. - pure module function expand_2_${t1[0]}$_${k1}$(value, dim1, dim2) result(result) - - ${t1}$, intent(in) :: value - integer, intent(in) :: dim1, dim2 - ${t1}$, allocatable :: result(:, :) - - allocate(result(dim1, dim2)) - result = value - - end function expand_2_${t1[0]}$_${k1}$ - #:endfor - -end submodule stdlib_linalg_expand diff --git a/src/tests/linalg/CMakeLists.txt b/src/tests/linalg/CMakeLists.txt index 5a33d8f17..4ddd4b5cf 100644 --- a/src/tests/linalg/CMakeLists.txt +++ b/src/tests/linalg/CMakeLists.txt @@ -1,3 +1,3 @@ ADDTEST(linalg) -ADDTEST(linalg_expand) +ADDTEST(linalg_ones_zeros) diff --git a/src/tests/linalg/Makefile.manual b/src/tests/linalg/Makefile.manual index e8a1725ea..616db4875 100644 --- a/src/tests/linalg/Makefile.manual +++ b/src/tests/linalg/Makefile.manual @@ -1,4 +1,4 @@ -PROGS_SRC = test_linalg_expand.f90 +PROGS_SRC = test_linalg_ones_zeros.f90 include ../Makefile.manual.test.mk diff --git a/src/tests/linalg/test_linalg_expand.f90 b/src/tests/linalg/test_linalg_expand.f90 deleted file mode 100644 index 932cb4a97..000000000 --- a/src/tests/linalg/test_linalg_expand.f90 +++ /dev/null @@ -1,132 +0,0 @@ -!> SPDX-Identifier: MIT -module test_linalg_expand - - use stdlib_linalg, only: zeros, ones, expand - use stdlib_error, only: check - use stdlib_string_type - implicit none - - logical, parameter :: warn = .false. - -contains - - !> `zeros` tests - - subroutine test_linalg_zeros_integer - call check(all(zeros(2) == [0, 0]), msg="all(zeros(2)==[0, 0] failed", warn=warn) - call check(all(zeros(2, 2) == reshape([0, 0, 0, 0], [2, 2])), & - msg="all(zeros(2,2)==reshape([0, 0, 0, 0],[2,2]) failed", warn=warn) - end subroutine test_linalg_zeros_integer - - subroutine test_linalg_zeros_real - real, allocatable :: rA(:), rB(:,:) - rA = zeros(2) - call check(all(rA == expand(0.0_4, 2)), msg="all(rA == expand(1.0_4, 2)) failed", warn=warn) - rB = zeros(2,2) - call check(all(rB == expand(0.0_4, 2,2)), & - msg="all(rB == expand(1.0_4, 2,2)) failed", warn=warn) - end subroutine test_linalg_zeros_real - - subroutine test_linalg_zeros_complex - complex, allocatable :: cA(:), cB(:,:) - cA = zeros(2) - call check(all(cA == expand((0.0_4,0.0_4), 2)), msg="all(cA == expand((1.0_4,0.0_4), 2)) failed", warn=warn) - cB = zeros(2,2) - call check(all(cB == expand((0.0_4,0.0_4), 2,2)), & - msg="all(cB == expand((1.0_4,0.0_4), 2,2)) failed", warn=warn) - end subroutine test_linalg_zeros_complex - - !> `ones` tests - - subroutine test_linalg_ones_integer - call check(all(ones(2) == [1, 1]), msg="all(ones(2)==[1, 1] failed", warn=warn) - call check(all(ones(2, 2) == reshape([1, 1, 1, 1], [2, 2])), & - msg="all(ones(2,2)==reshape([1, 1, 1, 1],[2,2]) failed", warn=warn) - end subroutine test_linalg_ones_integer - - subroutine test_linalg_ones_real - real, allocatable :: rA(:), rB(:,:) - rA = ones(2) - call check(all(rA == expand(1.0_4, 2)), msg="all(rA == expand(1.0_4, 2)) failed", warn=warn) - rB = ones(2,2) - call check(all(rB == expand(1.0_4, 2,2)), & - msg="all(rB == expand(1.0_4, 2,2)) failed", warn=warn) - end subroutine test_linalg_ones_real - - subroutine test_linalg_ones_complex - complex, allocatable :: cA(:), cB(:,:) - cA = ones(2) - call check(all(cA == expand((1.0_4,0.0_4), 2)), msg="all(cA == expand((1.0_4,0.0_4), 2)) failed", warn=warn) - cB = ones(2,2) - call check(all(cB == expand((1.0_4,0.0_4), 2,2)), & - msg="all(cB == expand((1.0_4,0.0_4), 2,2)) failed", warn=warn) - end subroutine test_linalg_ones_complex - - !> `expand` tests - - subroutine test_linalg_expand_integer - call check(all(expand(1, 2) == ones(2)), msg="all(expand(1, 2) == ones(2)) failed", warn=warn) - call check(all(expand(1, 2, 2) == ones(2, 2)), & - msg="all(expand(1, 2, 2) == ones(2,2)) failed", warn=warn) - end subroutine test_linalg_expand_integer - - subroutine test_linalg_expand_real - call check(all(expand(1.0, 2) == 1.0*ones(2)), msg="all(expand(1.0, 2) == 1.0*ones(2)) failed", warn=warn) - call check(all(expand(1.0, 2, 2) == 1.0*ones(2, 2)), & - msg="all(expand(1.0, 2, 2) == 1.0*ones(2,2)) failed", warn=warn) - end subroutine test_linalg_expand_real - - subroutine test_linalg_expand_complex - call check(all(expand((1.0, 1.0), 2) == (1.0, 1.0)*ones(2)), & - msg="all(expand((1.0,1.0), 2) == (1.0,1.0)*ones(2)) failed", warn=warn) - call check(all(expand((1.0, 1.0), 2, 2) == (1.0, 1.0)*ones(2, 2)), & - msg="all(expand((1.0,1.0), 2, 2) == (1.0,1.0)*ones(2,2)) failed", warn=warn) - end subroutine test_linalg_expand_complex - - subroutine test_linalg_expand_logical - call check(all(expand(.true., 2) .eqv. [.true., .true.]), & - msg="all(expand(.true., 2) .eqv. [.true., .true.]) failed", warn=warn) - call check(all(expand(.true., 1, 2) .eqv. reshape([.true., .true.], [1, 2])), & - msg="all(expand(.true., 1, 2) .eqv. reshape([.true., .true.],[1,2])) failed", warn=warn) - end subroutine test_linalg_expand_logical - - subroutine test_linalg_expand_string_type - - type(string_type) :: string_list(1,2) - string_list = string_type("A") - - call check(all(expand(string_type("A"), 2) == [string_type("A"), string_type("A")]), & - msg='all(expand(string_type("A"), 2) == [string_type("A"), & - &string_type("A")]) failed', warn=warn) - call check(all(expand(string_type("A"), 1, 2) == string_list), & - msg='all(expand(string_type("A"), 1, 2) == reshape([string_type("A"), & - &string_type("A")],[1,2])) failed', warn=warn) - - end subroutine test_linalg_expand_string_type - -end module test_linalg_expand - -program tester - - use test_linalg_expand - - print *, "`zeros` tests" - call test_linalg_zeros_integer - call test_linalg_zeros_real - call test_linalg_zeros_complex - - print *, "`ones` tests" - call test_linalg_ones_integer - call test_linalg_ones_real - call test_linalg_ones_complex - - print *, "`expand` tests" - call test_linalg_expand_integer - call test_linalg_expand_real - call test_linalg_expand_complex - call test_linalg_expand_logical - call test_linalg_expand_string_type - - print *, "All tests in `test_linalg_expand` passed" - -end program tester diff --git a/src/tests/linalg/test_linalg_ones_zeros.f90 b/src/tests/linalg/test_linalg_ones_zeros.f90 new file mode 100644 index 000000000..57e82b9a1 --- /dev/null +++ b/src/tests/linalg/test_linalg_ones_zeros.f90 @@ -0,0 +1,81 @@ +!> SPDX-Identifier: MIT +module test_linalg_ones_zeros + + use stdlib_linalg, only: zeros, ones + use stdlib_error, only: check + use stdlib_string_type + implicit none + + logical, parameter :: warn = .false. + +contains + + !> `zeros` tests + subroutine test_linalg_zeros_integer + call check(all(zeros(2) == [0, 0]), msg="all(zeros(2)==[0, 0] failed", warn=warn) + call check(all(zeros(2, 2) == reshape([0, 0, 0, 0], [2, 2])), & + msg="all(zeros(2,2)==reshape([0, 0, 0, 0],[2,2]) failed", warn=warn) + end subroutine test_linalg_zeros_integer + + subroutine test_linalg_zeros_real + real, allocatable :: rA(:), rB(:, :) + rA = zeros(2) + call check(all(rA == spread(0.0_4, 1, 2)), msg="all(rA == spread(0.0_4,1,2)) failed", warn=warn) + rB = zeros(2, 2) + call check(all(rB == reshape(spread(0.0_4, 1, 2*2), [2, 2])), & + msg="all(rB == reshape(spread(0.0_4, 1,2*2),[2,2])) failed", warn=warn) + end subroutine test_linalg_zeros_real + + subroutine test_linalg_zeros_complex + complex, allocatable :: cA(:), cB(:, :) + cA = zeros(2) + call check(all(cA == spread((0.0_4, 0.0_4), 1, 2)), msg="all(cA == spread((0.0_4,0.0_4),1,2)) failed", warn=warn) + cB = zeros(2, 2) + call check(all(cB == reshape(spread((0.0_4, 0.0_4), 1, 2*2), [2, 2])), & + msg="all(cB == reshape(spread((0.0_4,0.0_4), 1, 2*2), [2, 2])) failed", warn=warn) + end subroutine test_linalg_zeros_complex + + !> `ones` tests + subroutine test_linalg_ones_integer + call check(all(ones(2) == [1, 1]), msg="all(ones(2)==[1, 1] failed", warn=warn) + call check(all(ones(2, 2) == reshape([1, 1, 1, 1], [2, 2])), & + msg="all(ones(2,2)==reshape([1, 1, 1, 1],[2,2])) failed", warn=warn) + end subroutine test_linalg_ones_integer + + subroutine test_linalg_ones_real + real, allocatable :: rA(:), rB(:, :) + rA = ones(2) + call check(all(rA == spread(1.0_4, 1, 2)), msg="all(rA == spread(1.0_4,1,2)) failed", warn=warn) + rB = ones(2, 2) + call check(all(rB == reshape(spread(1.0_4, 1, 2*2), [2, 2])), & + msg="all(rB == reshape(spread(1.0_4, 1, 2*2), [2, 2])) failed", warn=warn) + end subroutine test_linalg_ones_real + + subroutine test_linalg_ones_complex + complex, allocatable :: cA(:), cB(:, :) + cA = ones(2) + call check(all(cA == spread((1.0_4, 0.0_4), 1, 2)), msg="all(cA == spread((1.0_4,0.0_4),1,2)) failed", warn=warn) + cB = ones(2, 2) + call check(all(cB == reshape(spread((1.0_4, 0.0_4), 1, 2*2), [2, 2])), & + msg="all(cB == reshape(spread((1.0_4, 0.0_4), 1, 2*2), [2, 2])) failed", warn=warn) + end subroutine test_linalg_ones_complex + +end module test_linalg_ones_zeros + +program tester + + use test_linalg_ones_zeros + + print *, "`zeros` tests" + call test_linalg_zeros_integer + call test_linalg_zeros_real + call test_linalg_zeros_complex + + print *, "`ones` tests" + call test_linalg_ones_integer + call test_linalg_ones_real + call test_linalg_ones_complex + + print *, "All tests in `test_linalg_ones_zeros` passed" + +end program tester