Section: BLAS/LAPACK - SCAL#
Adapted from: gjbex/Fortran-MOOC
This program demonstrates using the SCAL BLAS/LAPACK subroutine to scale a vector by a constant in Fortran.#
In file section_blas_lapack_scal.f90
program scal
use, intrinsic :: iso_fortran_env, only : error_unit, DP => REAL64
implicit none
integer, parameter :: rows = 3, cols = 4
real(kind=DP), dimension(rows, cols) :: matrix
real(kind=DP), dimension(rows) :: norm
integer :: row
! Define the explicit interface for the BLAS subroutine dscal
interface
subroutine dscal(n, da, dx, incx)
import :: DP
integer :: n, incx
real(kind=DP) :: da
real(kind=DP), dimension(*) :: dx
end subroutine dscal
end interface
! Initialize matrix with random numbers
call random_number(matrix)
! Print original matrix
print '(A)', 'original:'
! Print matrix
call print_matrix(matrix)
! Normalize along each column
norm = sum(matrix, dim=2)
print '(A, *(F12.7))', 'norm:', norm
! Loop over rows
do row = 1, rows
print '(A, I0)', 'row: ', row
print '(A, F12.7)', '1/norm(row): ', 1.0_DP/norm(row)
! In Fortran, the function call for dscal is:
! call dscal(n, da, dx, incx)
! where:
! n is the number of elements in the vector
! da is the scalar
! dx is the vector
! incx is the increment between elements of the vector
call dscal(cols, 1.0_DP/norm(row), matrix(row, :), 1)
! Print the matrix
call print_matrix(matrix)
end do
print '(A)', 'row-normalized::'
! Print matrix
call print_matrix(matrix)
! Normalize along each column
norm = sum(matrix, dim=2)
print '(A, *(F12.7))', 'norm:', norm
contains
subroutine print_matrix(matrix)
implicit none
real(kind=DP), dimension(:, :), intent(in) :: matrix
integer :: row
do row = 1, size(matrix, 1)
print '(*(F12.7))', matrix(row, :)
end do
end subroutine print_matrix
end program scal
The above program is compiled and run using Fortran Package Manager (fpm):
Build the Program using FPM (Fortran Package Manager)#
import os
root_dir = ""
root_dir = os.getcwd()
Since the code makes use of the LAPACK library, the following FPM configuration file (fpm.toml) was used:
name = "Section_BLAS_LAPACK_Scal"
[build]
auto-executables = true
auto-tests = true
auto-examples = true
link = ["blas", "lapack"]
[install]
library = false
[[executable]]
name="Section_BLAS_LAPACK_Scal"
source-dir="app"
main="section_blas_lapack_scal.f90"
code_dir = root_dir + "/" + "Fortran_Code/Section_BLAS_LAPACK_Scal"
os.chdir(code_dir)
build_status = os.system("fpm build 2>/dev/null")
Run the Program using FPM (Fortran Package Manager)#
exec_status = \
os.system("fpm run 2>/dev/null")
original:
0.6484231 0.7699479 0.0408001 0.9845512
0.8282905 0.2951749 0.0316558 0.7883060
0.0588210 0.1357320 0.8372485 0.4022821
norm: 2.4437222 1.9434273 1.4340835
row: 1
1/norm(row): 0.4092118
0.2653424 0.3150718 0.0166959 0.4028900
0.8282905 0.2951749 0.0316558 0.7883060
0.0588210 0.1357320 0.8372485 0.4022821
row: 2
1/norm(row): 0.5145549
0.2653424 0.3150718 0.0166959 0.4028900
0.4262009 0.1518837 0.0162886 0.4056267
0.0588210 0.1357320 0.8372485 0.4022821
row: 3
1/norm(row): 0.6973095
0.2653424 0.3150718 0.0166959 0.4028900
0.4262009 0.1518837 0.0162886 0.4056267
0.0410164 0.0946472 0.5838213 0.2805151
row-normalized::
0.2653424 0.3150718 0.0166959 0.4028900
0.4262009 0.1518837 0.0162886 0.4056267
0.0410164 0.0946472 0.5838213 0.2805151
norm: 1.0000000 1.0000000 1.0000000