!-*-f90-*- ! ! API: Array support !> \page "Comments on vectors and matrices" !> Please go to api/array.finc for the API documentation. !> Since array processing is one of the strengths of Fortran, FGSL focuses on !> leveraging Fortran-style array processing for those GSL routines which !> require arguments of type fgsl_vector* or fgsl_matrix*. ! ! vectors (extended precision real) ! !> Initialize a GSL vector object. This is invoked via the generic !> fgsl_vector_init. !> \param[in] array. The result variable's block is aliased to this !! contiguous array or a section of it. The actual argument must be !! a CONTIGUOUS array with the TARGET attribute. It can be of type !! integer(fgsl_int) or real(fgsl_double). !> \param[in] stride. If present, the stride between subsequent array !! elements of the function result. Otherwise, the value one is assumed. !> \param[inout] status. If present, the exit status. function fgsl_vector_init(array, stride, stat) real(fgsl_double), target, contiguous, intent(in) :: array(:) integer(fgsl_size_t), intent(in), optional :: stride integer(fgsl_int), intent(inout), optional :: stat type(fgsl_vector) :: fgsl_vector_init integer(fgsl_size_t) :: stride_local, array_size, section_size integer(fgsl_int) :: stat_local try : block if (present(stride)) then stride_local = stride else stride_local = 1_fgsl_size_t end if if (stride_local <= 0) then stat_local = fgsl_einval exit try end if array_size = size(array,dim=1,kind=fgsl_size_t) section_size = (array_size - 1) / stride_local + 1 fgsl_vector_init%gsl_vector = fgsl_aux_vector_double_init() stat_local = fgsl_aux_vector_double_align(c_loc(array), & array_size, fgsl_vector_init%gsl_vector, & section_size, 0_fgsl_size_t, stride_local) end block try if ( present(stat) ) stat = stat_local if ( .not. present(stat) .and. stat_local /= fgsl_success ) & call fgsl_error("aligning failed", __FILE__, __LINE__, stat_local) end function fgsl_vector_init function fgsl_vector_int_init(array, stride, stat) integer(fgsl_int), target, contiguous, intent(in) :: array(:) integer(fgsl_size_t), intent(in), optional :: stride integer(fgsl_int), intent(inout), optional :: stat type(fgsl_vector_int) :: fgsl_vector_int_init integer(fgsl_size_t) :: stride_local, array_size, section_size integer(fgsl_int) :: stat_local try : block if (present(stride)) then stride_local = stride else stride_local = 1_fgsl_size_t end if if (stride_local <= 0) then stat_local = fgsl_einval exit try end if array_size = size(array,dim=1,kind=fgsl_size_t) section_size = (array_size - 1) / stride_local + 1 fgsl_vector_int_init%gsl_vector_int = fgsl_aux_vector_int_init() stat_local = fgsl_aux_vector_int_align(c_loc(array), & array_size, fgsl_vector_int_init%gsl_vector_int, & section_size, 0_fgsl_size_t, stride_local) end block try if ( present(stat) ) stat = stat_local if ( .not. present(stat) .and. stat_local /= fgsl_success ) & call fgsl_error("aligning failed", __FILE__, __LINE__, stat_local) end function fgsl_vector_int_init !> Legacy specific fgsl_vector_init of for GSL vector initialization !> \param type - determine intrinsic type of vector object !> \return new object of type fgsl_vector function fgsl_vector_init_legacy(type) real(fgsl_double), intent(in) :: type type(fgsl_vector) :: fgsl_vector_init_legacy fgsl_vector_init_legacy%gsl_vector = fgsl_aux_vector_double_init() end function fgsl_vector_init_legacy !> Legacy function to wrap a rank 1 Fortran array slice inside a double !! precision real GSL vector object. This is invoked via the generic !! fgsl_vector_align. !! It is recommended to update codes using this to use the !! new fgsl_vector_init specific instead !> \param array - requires the actual argument to have the !! TARGET attribute. Otherwise being passed by reference is !! not guaranteed by the Fortran standard. !> \param len - number of elements of the rank 1 array !> \param fvec - previously initialized GSL vector object !> \param size - number of elements from array wrapped inside fvec !> \param offset - index of first element of array to be mapped to fvec !> \param stride - stride in array for successive elements of fvec !> \return Status function fgsl_vector_align(array, len, fvec, size, offset, stride) integer(fgsl_size_t), intent(in) :: len, size, offset, stride real(fgsl_double), dimension(len), target, intent(in) :: array type(fgsl_vector), intent(inout) :: fvec integer(fgsl_int) :: fgsl_vector_align ! fgsl_vector_align = fgsl_aux_vector_double_align(c_loc(array), len, & fvec%gsl_vector, size, offset, stride) end function fgsl_vector_align !> Function to associate a Fortran pointer with a GSL vector object. !> \param[in] fvec. double precision real GSL vector !> The function result is a null pointer if the object is invalid, !! otherwise it points to the data described by the fvec object function fgsl_vector_to_fptr(fvec) type(fgsl_vector), intent(in) :: fvec real(fgsl_double), pointer :: fgsl_vector_to_fptr(:) real(fgsl_double), pointer, contiguous :: fptr_local(:) integer(fgsl_size_t) :: size, stride type(c_ptr) :: cp if ( fgsl_vector_status(fvec) ) then size = fgsl_aux_vector_double_size(fvec%gsl_vector) stride = fgsl_aux_vector_double_stride(fvec%gsl_vector) if (stride == 0) then fgsl_vector_to_fptr => null() else cp = gsl_vector_ptr(fvec%gsl_vector,0_fgsl_size_t) call c_f_pointer(cp, fptr_local, [ size*stride ]) fgsl_vector_to_fptr => fptr_local(1:size*stride:stride) end if else fgsl_vector_to_fptr => null() end if end function fgsl_vector_to_fptr function fgsl_vector_int_to_fptr(fvec) type(fgsl_vector_int), intent(in) :: fvec integer(fgsl_int), pointer :: fgsl_vector_int_to_fptr(:) integer(fgsl_int), pointer, contiguous :: fptr_local(:) integer(fgsl_size_t) :: size, stride type(c_ptr) :: cp if ( fgsl_vector_int_status(fvec) ) then size = fgsl_aux_vector_int_size(fvec%gsl_vector_int) stride = fgsl_aux_vector_int_stride(fvec%gsl_vector_int) if (stride == 0) then fgsl_vector_int_to_fptr => null() else cp = gsl_vector_int_ptr(fvec%gsl_vector_int,0_fgsl_size_t) call c_f_pointer(cp, fptr_local, [ size*stride ]) fgsl_vector_int_to_fptr => fptr_local(1:size*stride:stride) end if else fgsl_vector_int_to_fptr => null() end if end function fgsl_vector_int_to_fptr !> Legacy function to associate a Fortran pointer with the data stored inside !> a GSL vector object. Codes should be updated to use fgsl_vector_ptr. !> This is invoked via the generic fgsl_vector_align. Objects of type !> gsl_vector which are returned by GSL routines often are !> persistent subobjects of other GSL objects. A Fortran pointer aligned with !> a subobject hence will remain up-to-date throughout the lifetime of the !> object; it may become undefined once the object ceases to exist. !> \param ptr - rank 1 Fortran pointer !> \param fvec - double precision real GSL vector !> \return Status function fgsl_vector_pointer_align(ptr, fvec) real(fgsl_double), pointer, intent(out) :: ptr(:) type(fgsl_vector), intent(in) :: fvec integer(fgsl_int) :: fgsl_vector_pointer_align ! real(fgsl_double), pointer :: fp_local(:) type(c_ptr) :: cp integer(fgsl_size_t) :: size, stride ! tests ! real(fgsl_double) :: cc(3) size = fgsl_aux_vector_double_size(fvec%gsl_vector) stride = fgsl_aux_vector_double_stride(fvec%gsl_vector) if (stride == 0) then fgsl_vector_pointer_align = fgsl_einval else cp = gsl_vector_ptr(fvec%gsl_vector,0_fgsl_size_t) ! cc(1) = gsl_vector_get(fvec%gsl_vector,0_c_size_t) ! cc(2) = gsl_vector_get(fvec%gsl_vector,1_c_size_t) ! cc(3) = gsl_vector_get(fvec%gsl_vector,2_c_size_t) call c_f_pointer(cp, fp_local, (/ size*stride /)) ! write(6, *) 'size, stride, fp_local: ',size,stride,fp_local(1:3),cc(1:3) ptr => fp_local(1:size*stride:stride) fgsl_vector_pointer_align = fgsl_success end if end function fgsl_vector_pointer_align !> The assignment operator (see interface/generics.finc) is overloaded to enable !> copying of the content of a GSL vector into a Fortran array. subroutine fgsl_vector_to_array(result, source) real(fgsl_double), intent(inout) :: result(:) type(fgsl_vector), intent(in) :: source ! integer(fgsl_size_t) :: i, n, k k = size(result) n = min(k,fgsl_aux_vector_double_size(source%gsl_vector)) ! write(6,*) 'result length: ',size(result) ! write(6,*) 'vector length: ', & ! fgsl_aux_vector_double_size(source%gsl_vector) do i=1,n result(i) = gsl_vector_get(source%gsl_vector,i-1) end do do i=n+1,size(result) result(i) = 0.0_fgsl_double end do end subroutine fgsl_vector_to_array !> Free the resources inside a GSL vector object previously established !> by a call to fgsl_vector_init(). This is invoked via the generic !> fgsl_vector_free. subroutine fgsl_vector_free(fvec) type(fgsl_vector), intent(inout) :: fvec ! call gsl_vector_free(fvec%gsl_vector) call fgsl_aux_vector_double_free(fvec%gsl_vector) end subroutine fgsl_vector_free subroutine fgsl_vector_int_free(fvec) type(fgsl_vector_int), intent(inout) :: fvec call fgsl_aux_vector_int_free(fvec%gsl_vector_int) end subroutine fgsl_vector_int_free subroutine fgsl_vector_c_ptr(res, src) type(c_ptr), intent(in) :: src type(fgsl_vector), intent(out) :: res res%gsl_vector = src end subroutine fgsl_vector_c_ptr function fgsl_vector_status(vector) type(fgsl_vector), intent(in) :: vector logical :: fgsl_vector_status fgsl_vector_status = .true. if (.not. c_associated(vector%gsl_vector)) fgsl_vector_status = .false. end function fgsl_vector_status !> Inquire the size of a double precision real GSL vector object. function fgsl_vector_int_status(vector) type(fgsl_vector_int), intent(in) :: vector logical :: fgsl_vector_int_status fgsl_vector_int_status = .true. if (.not. c_associated(vector%gsl_vector_int)) fgsl_vector_int_status = .false. end function fgsl_vector_int_status function fgsl_sizeof_vector(w) type(fgsl_vector), intent(in) :: w integer(fgsl_size_t) :: fgsl_sizeof_vector fgsl_sizeof_vector = gsl_aux_sizeof_vector() end function fgsl_sizeof_vector ! ! vectors (complex) ! !> Initialize a complex GSL vector object. This is invoked via the generic !> fgsl_vector_init. !> \param type - determine intrinsic type of vector object !> \return new object of type fgsl_vector function fgsl_vector_complex_init_legacy(type) complex(fgsl_double_complex), intent(in) :: type type(fgsl_vector_complex) :: fgsl_vector_complex_init_legacy fgsl_vector_complex_init_legacy%gsl_vector_complex = fgsl_aux_vector_complex_init() end function fgsl_vector_complex_init_legacy function fgsl_vector_complex_init(array, stride, stat) complex(fgsl_double), target, contiguous, intent(in) :: array(:) integer(fgsl_size_t), intent(in), optional :: stride integer(fgsl_int), intent(inout), optional :: stat type(fgsl_vector_complex) :: fgsl_vector_complex_init integer(fgsl_size_t) :: stride_local, array_size, section_size integer(fgsl_int) :: stat_local try : block if (present(stride)) then stride_local = stride else stride_local = 1_fgsl_size_t end if if (stride_local <= 0) then stat_local = fgsl_einval exit try end if array_size = size(array,dim=1,kind=fgsl_size_t) section_size = (array_size - 1) / stride_local + 1 fgsl_vector_complex_init%gsl_vector_complex = fgsl_aux_vector_complex_init() stat_local = fgsl_aux_vector_complex_align(c_loc(array), & array_size, fgsl_vector_complex_init%gsl_vector_complex, & section_size, 0_fgsl_size_t, stride_local) end block try if ( present(stat) ) stat = stat_local if ( .not. present(stat) .and. stat_local /= fgsl_success ) & call fgsl_error("aligning failed", __FILE__, __LINE__, stat_local) end function fgsl_vector_complex_init !> Wrap a rank 1 Fortran array slice inside a double precision complex !> real GSL vector object. This is invoked via the generic !> fgsl_vector_align. !> \param array - requires the actual argument to have the !> TARGET attribute. Otherwise being passed by reference is !> not guaranteed by the Fortran standard. !> \param len - number of elements of the rank 1 array !> \param fvec - previously initialized complex GSL vector object !> \param size - number of elements from array wrapped inside fvec !> \param offset - index of first element of array to be mapped to fvec !> \param stride - stride in array for successive elements of fvec !> \return Status function fgsl_vector_complex_align(array, len, fvec, size, offset, stride) integer(fgsl_size_t), intent(in) :: len, size, offset, stride complex(fgsl_double_complex), dimension(len), target, intent(in) :: array type(fgsl_vector_complex), intent(inout) :: fvec integer(fgsl_int) :: fgsl_vector_complex_align ! fgsl_vector_complex_align = & fgsl_aux_vector_complex_align(c_loc(array), len, & fvec%gsl_vector_complex, size, offset, stride) end function fgsl_vector_complex_align !> Associate a Fortran pointer with the data stored inside a GSL vector object. !> This is invoked via the generic fgsl_vector_align. Objects of type !> gsl_vector_complex which are returned by GSL routines often are !> persistent subobjects of other GSL objects. A Fortran pointer aligned with !> a subobject hence will remain up-to-date throughout the lifetime of the !> object; it may become undefined once the object ceases to exist. !> \param ptr - rank 1 Fortran pointer !> \param fvec - double precision complex GSL vector !> \return Status function fgsl_vector_complex_pointer_align(ptr, fvec) complex(fgsl_double_complex), pointer, intent(out) :: ptr(:) type(fgsl_vector_complex), intent(in) :: fvec integer(fgsl_int) :: fgsl_vector_complex_pointer_align ! complex(fgsl_double_complex), pointer :: fp_local(:) type(c_ptr) :: cp integer(fgsl_size_t) :: size, stride ! tests ! real(fgsl_double) :: cc(3) size = fgsl_aux_vector_complex_size(fvec%gsl_vector_complex) stride = fgsl_aux_vector_complex_stride(fvec%gsl_vector_complex) if (stride == 0) then fgsl_vector_complex_pointer_align = fgsl_einval else cp = gsl_vector_complex_ptr(fvec%gsl_vector_complex,0_fgsl_size_t) ! cc(1) = gsl_vector_complex_get(fvec%gsl_vector_complex,0_c_size_t) ! cc(2) = gsl_vector_complex_get(fvec%gsl_vector_complex,1_c_size_t) ! cc(3) = gsl_vector_complex_get(fvec%gsl_vector_complex,2_c_size_t) call c_f_pointer(cp, fp_local, (/ size*stride /)) ! write(6, *) 'size, stride, fp_local: ',size,stride,fp_local(1:3),cc(1:3) ptr => fp_local(1:size*stride:stride) fgsl_vector_complex_pointer_align = fgsl_success end if end function fgsl_vector_complex_pointer_align function fgsl_vector_complex_to_fptr(fvec) type(fgsl_vector_complex), intent(in) :: fvec complex(fgsl_double), pointer :: fgsl_vector_complex_to_fptr(:) complex(fgsl_double), pointer, contiguous :: fptr_local(:) integer(fgsl_size_t) :: size, stride type(c_ptr) :: cp if ( fgsl_vector_complex_status(fvec) ) then size = fgsl_aux_vector_complex_size(fvec%gsl_vector_complex) stride = fgsl_aux_vector_complex_stride(fvec%gsl_vector_complex) if (stride == 0) then fgsl_vector_complex_to_fptr => null() else cp = gsl_vector_complex_ptr(fvec%gsl_vector_complex,0_fgsl_size_t) call c_f_pointer(cp, fptr_local, [ size*stride ]) fgsl_vector_complex_to_fptr => fptr_local(1:size*stride:stride) end if else fgsl_vector_complex_to_fptr => null() end if end function fgsl_vector_complex_to_fptr !> The assignment operator (see interface/generics.finc) is overloaded to enable !> copying of the content of a complex GSL vector into a Fortran array. subroutine fgsl_vector_complex_to_array(result, source) complex(fgsl_double_complex), intent(inout) :: result(:) type(fgsl_vector_complex), intent(in) :: source ! type(gsl_complex) :: aux ! integer(fgsl_size_t) :: i, n, k k = size(result) n = min(k,fgsl_aux_vector_complex_size(source%gsl_vector_complex)) ! write(6,*) 'result length: ',size(result) ! write(6,*) 'vector_complex length: ', & ! fgsl_aux_vector_complex_size(source%gsl_vector_complex) do i=1,n result(i) = gsl_vector_complex_get(source%gsl_vector_complex,i-1) ! aux = gsl_vector_complex_get(source%gsl_vector_complex,i-1) ! result(i) = aux ! write(6, *) 'i=',i,' res = ',result(i) end do do i=n+1,size(result) result(i) = 0.0_fgsl_double end do end subroutine fgsl_vector_complex_to_array !> Free the resources inside a complex GSL vector object previously established !> by a call to fgsl_vector_complex_init(). This is invoked via the generic !> fgsl_vector_free. subroutine fgsl_vector_complex_free(fvec) type(fgsl_vector_complex), intent(inout) :: fvec call fgsl_aux_vector_complex_free(fvec%gsl_vector_complex) end subroutine fgsl_vector_complex_free subroutine fgsl_vector_complex_c_ptr(res, src) type(c_ptr), intent(in) :: src type(fgsl_vector_complex), intent(out) :: res res%gsl_vector_complex = src end subroutine fgsl_vector_complex_c_ptr function fgsl_vector_complex_status(vector_complex) type(fgsl_vector_complex), intent(in) :: vector_complex logical :: fgsl_vector_complex_status fgsl_vector_complex_status = .true. if (.not. c_associated(vector_complex%gsl_vector_complex)) fgsl_vector_complex_status = .false. end function fgsl_vector_complex_status !> Inquire the size of a double precision complex GSL vector object. function fgsl_sizeof_vector_complex(w) type(fgsl_vector_complex), intent(in) :: w integer(fgsl_size_t) :: fgsl_sizeof_vector_complex fgsl_sizeof_vector_complex = gsl_aux_sizeof_vector_complex() end function fgsl_sizeof_vector_complex ! ! matrices (real) ! !> Legacy function to initialize a GSL matrix object. This is invoked via the generic !> fgsl_matrix_init. !> \param type - determine intrinsic type of vector object !> \return new object of type fgsl_matrix. function fgsl_matrix_init_legacy(type) real(fgsl_double), intent(in) :: type type(fgsl_matrix) :: fgsl_matrix_init_legacy fgsl_matrix_init_legacy%gsl_matrix = fgsl_aux_matrix_double_init() end function fgsl_matrix_init_legacy !> Initialize a rank 2 Fortran array to become associated with a double precision !> GSL matrix object. This is invoked via the generic fgsl_matrix_init. !> \param array - requires the actual argument to have the !> TARGET and CONTIGUOUS attributes. !> \param n - number of rows in array !> \param m - number of columns in array !> \param fmat - double precision GSL matrix object, which is allocated !> \return Status function fgsl_matrix_init(array, n, m, stat) integer(fgsl_size_t), intent(in), optional :: n, m real(fgsl_double), dimension(:,:), target, contiguous, intent(in) :: array type(fgsl_matrix) :: fgsl_matrix_init integer(fgsl_int), optional :: stat integer :: stat_local integer(fgsl_size_t) :: mloc, nloc ! fgsl_matrix_init%gsl_matrix = fgsl_aux_matrix_double_init() if ( present(n) ) then nloc = n else nloc = size(array,1,KIND=c_size_t) end if if ( present(m) ) then mloc = m else mloc = size(array,2,KIND=c_size_t) end if stat_local = & fgsl_aux_matrix_double_align(c_loc(array), size(array,1,KIND=c_size_t), & nloc, mloc, fgsl_matrix_init%gsl_matrix) if ( present(stat) ) stat = stat_local if ( .not. present(stat) .and. stat_local /= fgsl_success ) & call fgsl_error("aligning failed", __FILE__, __LINE__, stat_local) end function fgsl_matrix_init !> Legacy specific to wrap a rank 2 Fortran array inside a double precision !> real GSL matrix object. This is invoked via the generic !> fgsl_matrix_align. !> \param array - requires the actual argument to have the !> TARGET attribute. Otherwise being passed by reference is !> not guaranteed by the Fortran standard. !> \param lda - leading dimension of the rank 2 array !> \param n - number of rows in array !> \param m - number of columns in array !> \param fmat - previously initialized double precision GSL matrix object !> \return Status function fgsl_matrix_align(array, lda, n, m, fmat) integer(fgsl_size_t), intent(in) :: lda, n, m real(fgsl_double), dimension(lda, m), target, intent(in) :: array type(fgsl_matrix), intent(inout) :: fmat integer(fgsl_int) :: fgsl_matrix_align ! fgsl_matrix_align = fgsl_aux_matrix_double_align(c_loc(array), lda, & n, m, fmat%gsl_matrix) end function fgsl_matrix_align !> Associate a Fortran pointer with the data stored inside a GSL matrix object. !> This is invoked via the generic fgsl_matrix_align. Objects of type !> gsl_matrix which are returned by GSL routines often are !> persistent subobjects of other GSL objects. A Fortran pointer aligned with !> a subobject hence will remain up-to-date throughout the lifetime of the !> object; it may become undefined once the object ceases to exist. !> \param ptr - rank 2 Fortran pointer !> \param fmat - double precision real GSL matrix !> \return Status function fgsl_matrix_pointer_align(ptr, fmat) real(fgsl_double), pointer, intent(out) :: ptr(:,:) type(fgsl_matrix), intent(in) :: fmat integer(fgsl_int) :: fgsl_matrix_pointer_align ! real(fgsl_double), pointer :: fp_local(:,:) type(c_ptr) :: cp integer(fgsl_size_t) :: m, n, lda call fgsl_aux_matrix_double_size(fmat%gsl_matrix, lda, n, m) cp = gsl_matrix_ptr(fmat%gsl_matrix,0_fgsl_size_t,0_fgsl_size_t) call c_f_pointer(cp, fp_local, (/ lda , m /)) ptr => fp_local(1:n,1:m) fgsl_matrix_pointer_align = fgsl_success end function fgsl_matrix_pointer_align !> Associate a Fortran pointer with the data stored inside a GSL matrix object. !> This is invoked via the generic fgsl_matrix_to_fptr. Objects of type !> gsl_matrix which are returned by GSL routines often are !> persistent subobjects of other GSL objects. A Fortran pointer aligned with !> a subobject hence will remain up-to-date throughout the lifetime of the !> object; it may become undefined once the object ceases to exist. !> \param fmat - GSL matrix !> \return rank 2 Fortran pointer function fgsl_matrix_to_fptr(fmat) real(fgsl_double), pointer :: fgsl_matrix_to_fptr(:,:) type(fgsl_matrix), intent(in) :: fmat ! real(fgsl_double), pointer :: fp_local(:,:) type(c_ptr) :: cp integer(fgsl_size_t) :: m, n, lda if ( fgsl_matrix_status(fmat) ) then call fgsl_aux_matrix_double_size(fmat%gsl_matrix, lda, n, m) cp = gsl_matrix_ptr(fmat%gsl_matrix,0_fgsl_size_t,0_fgsl_size_t) call c_f_pointer(cp, fp_local, (/ lda , m /)) fgsl_matrix_to_fptr => fp_local(1:n,1:m) else fgsl_matrix_to_fptr => null() end if end function fgsl_matrix_to_fptr !> The assignment operator (see interface/generics.finc) is overloaded to enable !> copying of the content of a GSL matrix into a rank 2 Fortran array. subroutine fgsl_matrix_to_array(result, source) real(fgsl_double), intent(inout) :: result(:,:) type(fgsl_matrix), intent(in) :: source ! integer(fgsl_size_t) :: i, j, kl, m, n, ml, nl, lda call fgsl_aux_matrix_double_size(source%gsl_matrix, lda, n, m) kl = size(result,1) nl = min(kl,n) kl = size(result,2) ml = min(kl,m) ! write(6, *) 'Number of rows: ', nl, n ! write(6, *) 'Number of cols: ', ml, m do j=1,ml do i=1,nl result(i,j) = gsl_matrix_get(source%gsl_matrix,j-1,i-1) end do end do do j=1,ml do i=nl+1,size(result,1) result(i,j) = 0.0_fgsl_double end do end do do j=ml+1,size(result,2) do i=1,size(result,1) result(i,j) = 0.0_fgsl_double end do end do end subroutine fgsl_matrix_to_array !> Free the resources inside a GSL matrix object previously established !> by a call to fgsl_matrix_init(). This is invoked via the generic !> fgsl_matrix_free. subroutine fgsl_matrix_free(fvec) type(fgsl_matrix), intent(inout) :: fvec call fgsl_aux_matrix_double_free(fvec%gsl_matrix) end subroutine fgsl_matrix_free subroutine fgsl_matrix_c_ptr(res, src) type(c_ptr), intent(in) :: src type(fgsl_matrix), intent(out) :: res res%gsl_matrix = src end subroutine fgsl_matrix_c_ptr function fgsl_matrix_status(matrix) type(fgsl_matrix), intent(in) :: matrix logical :: fgsl_matrix_status fgsl_matrix_status = .true. if (.not. c_associated(matrix%gsl_matrix)) fgsl_matrix_status = .false. end function fgsl_matrix_status !> Inquire the number of elements in a double precision real GSL matrix object. function fgsl_sizeof_matrix(w) type(fgsl_matrix), intent(in) :: w integer(fgsl_size_t) :: fgsl_sizeof_matrix fgsl_sizeof_matrix = gsl_aux_sizeof_matrix() end function fgsl_sizeof_matrix ! ! matrices (complex) ! !> Legacy specifit to initialize a GSL matrix object. This is invoked via the generic !> fgsl_matrix_init. !> \param type - determine intrinsic type of vector object !> \return new object of type fgsl_matrix. function fgsl_matrix_complex_init_legacy(type) complex(fgsl_double_complex), intent(in) :: type type(fgsl_matrix_complex) :: fgsl_matrix_complex_init_legacy fgsl_matrix_complex_init_legacy%gsl_matrix_complex = fgsl_aux_matrix_complex_init() end function fgsl_matrix_complex_init_legacy !> Initialize a rank 2 Fortran array to become associated with a double precision !> complex GSL matrix object. This is invoked via the generic !> fgsl_matrix_init. !> \param array - requires the actual argument to have the !> TARGET and CONTIGUOUS attributes. !> \param n - number of rows in array !> \param m - number of columns in array !> \param fmat - double precision complex GSL matrix object, which is allocated !> \return Status function fgsl_matrix_complex_init(array, n, m, stat) integer(fgsl_size_t), intent(in), optional :: n, m complex(fgsl_double_complex), dimension(:,:), target, contiguous, intent(in) :: array type(fgsl_matrix_complex) :: fgsl_matrix_complex_init integer(fgsl_int), optional :: stat integer(fgsl_int) :: stat_local integer(fgsl_size_t) :: mloc, nloc ! fgsl_matrix_complex_init%gsl_matrix_complex = fgsl_aux_matrix_complex_init() if ( present(n) ) then nloc = n else nloc = size(array,1,KIND=c_size_t) end if if ( present(m) ) then mloc = m else mloc = size(array,2,KIND=c_size_t) end if stat_local = fgsl_aux_matrix_complex_align(c_loc(array), size(array,1,KIND=c_size_t), & nloc, mloc, fgsl_matrix_complex_init%gsl_matrix_complex) if ( present(stat) ) stat = stat_local if ( .not. present(stat) .and. stat_local /= fgsl_success ) & call fgsl_error("aligning failed", __FILE__, __LINE__, stat_local) end function fgsl_matrix_complex_init !> Legacy function to wrap a rank 2 Fortran array inside a double precision !> complex GSL matrix object. This is invoked via the generic !> fgsl_matrix_align. !> \param array - requires the actual argument to have the !> TARGET attribute. Otherwise being passed by reference is !> not guaranteed by the Fortran standard. !> \param lda - leading dimension of the rank 2 array !> \param n - number of rows in array !> \param m - number of columns in array !> \param fmat - previously initialized double precision complex GSL matrix object !> \return Status function fgsl_matrix_complex_align(array, lda, n, m, fmat) integer(fgsl_size_t), intent(in) :: lda, n, m complex(fgsl_double_complex), dimension(lda, m), target, intent(in) :: array type(fgsl_matrix_complex), intent(inout) :: fmat integer(fgsl_int) :: fgsl_matrix_complex_align ! fgsl_matrix_complex_align = & fgsl_aux_matrix_complex_align(c_loc(array), lda, & n, m, fmat%gsl_matrix_complex) end function fgsl_matrix_complex_align !> Associate a Fortran pointer with the data stored inside a complex GSL matrix object. !> This is invoked via the generic fgsl_matrix_align. Objects of type !> gsl_matrix_complex which are returned by GSL routines often are !> persistent subobjects of other GSL objects. A Fortran pointer aligned with !> a subobject hence will remain up-to-date throughout the lifetime of the !> object; it may become undefined once the object ceases to exist. !> \param ptr - rank 2 Fortran pointer !> \param fmat - double precision complex GSL matrix !> \return Status function fgsl_matrix_complex_pointer_align(ptr, fmat) complex(fgsl_double_complex), pointer, intent(out) :: ptr(:,:) type(fgsl_matrix_complex), intent(in) :: fmat integer(fgsl_int) :: fgsl_matrix_complex_pointer_align ! complex(fgsl_double_complex), pointer :: fp_local(:,:) type(c_ptr) :: cp integer(fgsl_size_t) :: m, n, lda call fgsl_aux_matrix_complex_size(fmat%gsl_matrix_complex, lda, n, m) cp = gsl_matrix_complex_ptr(fmat%gsl_matrix_complex,0_fgsl_size_t,0_fgsl_size_t) call c_f_pointer(cp, fp_local, (/ lda , m /)) ptr => fp_local(1:n,1:m) fgsl_matrix_complex_pointer_align = fgsl_success end function fgsl_matrix_complex_pointer_align function fgsl_matrix_complex_to_fptr(fmat) complex(fgsl_double), pointer :: fgsl_matrix_complex_to_fptr(:,:) type(fgsl_matrix_complex), intent(in) :: fmat ! complex(fgsl_double), pointer :: fp_local(:,:) type(c_ptr) :: cp integer(fgsl_size_t) :: m, n, lda if ( fgsl_matrix_complex_status(fmat) ) then call fgsl_aux_matrix_complex_size(fmat%gsl_matrix_complex, lda, n, m) cp = gsl_matrix_complex_ptr(fmat%gsl_matrix_complex,0_fgsl_size_t,0_fgsl_size_t) call c_f_pointer(cp, fp_local, (/ lda , m /)) fgsl_matrix_complex_to_fptr => fp_local(1:n,1:m) else fgsl_matrix_complex_to_fptr => null() end if end function fgsl_matrix_complex_to_fptr !> The assignment operator (see interface/generics.finc) is overloaded to enable !> copying of the content of a complex GSL matrix into a rank 2 Fortran array. subroutine fgsl_matrix_complex_to_array(result, source) complex(fgsl_double_complex), intent(inout) :: result(:,:) type(fgsl_matrix_complex), intent(in) :: source ! integer(fgsl_size_t) :: i, j, kl, m, n, ml, nl, lda call fgsl_aux_matrix_complex_size(source%gsl_matrix_complex, lda, n, m) kl = size(result,1) nl = min(kl,n) kl = size(result,2) ml = min(kl,m) ! write(6, *) 'Number of rows: ', nl, n ! write(6, *) 'Number of cols: ', ml, m do j=1,ml do i=1,nl result(i,j) = gsl_matrix_complex_get(source%gsl_matrix_complex,j-1,i-1) end do end do do j=1,ml do i=nl+1,size(result,1) result(i,j) = 0.0_fgsl_double_complex end do end do do j=ml+1,size(result,2) do i=1,size(result,1) result(i,j) = 0.0_fgsl_double_complex end do end do end subroutine fgsl_matrix_complex_to_array !> Free the resources inside a complex GSL matrix object previously established !> by a call to fgsl_matrix_complex_init(). This is invoked via the generic !> fgsl_matrix_free. subroutine fgsl_matrix_complex_free(fvec) type(fgsl_matrix_complex), intent(inout) :: fvec call fgsl_aux_matrix_complex_free(fvec%gsl_matrix_complex) end subroutine fgsl_matrix_complex_free subroutine fgsl_matrix_complex_c_ptr(res, src) type(c_ptr), intent(in) :: src type(fgsl_matrix_complex), intent(out) :: res res%gsl_matrix_complex = src end subroutine fgsl_matrix_complex_c_ptr function fgsl_matrix_complex_status(matrix_complex) type(fgsl_matrix_complex), intent(in) :: matrix_complex logical :: fgsl_matrix_complex_status fgsl_matrix_complex_status = .true. if (.not. c_associated(matrix_complex%gsl_matrix_complex)) fgsl_matrix_complex_status = .false. end function fgsl_matrix_complex_status !> Inquire the number of elements in a double precision complex GSL matrix object. function fgsl_sizeof_matrix_complex(w) type(fgsl_matrix_complex), intent(in) :: w integer(fgsl_size_t) :: fgsl_sizeof_matrix_complex fgsl_sizeof_matrix_complex = gsl_aux_sizeof_matrix_complex() end function fgsl_sizeof_matrix_complex function fgsl_vector_get_size(vec) type(fgsl_vector), intent(in) :: vec integer(fgsl_size_t) :: fgsl_vector_get_size fgsl_vector_get_size = fgsl_aux_vector_double_size(vec%gsl_vector) end function fgsl_vector_get_size function fgsl_vector_get_stride(vec) type(fgsl_vector), intent(in) :: vec integer(fgsl_size_t) :: fgsl_vector_get_stride fgsl_vector_get_stride = fgsl_aux_vector_double_stride(vec%gsl_vector) end function fgsl_vector_get_stride function fgsl_matrix_get_size1(matr) type(fgsl_matrix), intent(in) :: matr integer(fgsl_size_t) :: tda, size1, size2 integer(fgsl_size_t) :: fgsl_matrix_get_size1 call fgsl_aux_matrix_double_size(matr%gsl_matrix, tda, size2,& size1) fgsl_matrix_get_size1 = size1 end function fgsl_matrix_get_size1 function fgsl_matrix_get_size2(matr) type(fgsl_matrix), intent(in) :: matr integer(fgsl_size_t) :: tda, size1, size2 integer(fgsl_size_t) :: fgsl_matrix_get_size2 call fgsl_aux_matrix_double_size(matr%gsl_matrix, tda, size2,& size1) fgsl_matrix_get_size2 = size2 end function fgsl_matrix_get_size2 function fgsl_matrix_get_tda(matr) type(fgsl_matrix), intent(in) :: matr integer(fgsl_size_t) :: tda, size1, size2 integer(fgsl_size_t) :: fgsl_matrix_get_tda call fgsl_aux_matrix_double_size(matr%gsl_matrix, tda, size2,& size1) fgsl_matrix_get_tda = tda end function fgsl_matrix_get_tda