Created
May 5, 2020 05:39
-
-
Save DSCF-1224/0463fc73c05cd356b30a1fd5c0fa6953 to your computer and use it in GitHub Desktop.
ガウス過程と機械学習 第1章 lm.py version 01 (Fortran)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
! ================================================================================================================================== | |
! ISBN 978-4-06-152926-7 | |
! ガウス過程と機械学習 | |
! | |
! [reference] | |
! http://chasen.org/~daiti-m/gpbook/python/lm.py | |
! http://chasen.org/~daiti-m/gpbook/data/nonlinear.dat | |
! https://nbviewer.jupyter.org/gist/genkuroki/a37894d5669ad13b4cd27da16096bfd2 | |
! https://gihyo.jp/book/2015/978-4-7741-7506-5 | |
! ================================================================================================================================== | |
module mod_ISBN9784061529267 | |
! <module>s to import | |
use, intrinsic :: iso_fortran_env | |
use, non_intrinsic :: ISBN9784774175065 | |
! require all variables to be explicitly declared | |
implicit none | |
! accessibility of the <subroutine>s and <function>s in this <module> | |
public :: type_data_estimated ! type | |
public :: type_data_observed ! type | |
public :: type_data_regression ! type | |
public :: type_data_regression_degree ! type | |
public :: type_data_regression_weight ! type | |
public :: compute_weight ! subroutine | |
public :: estimate_output ! subroutine | |
public :: read_data ! subroutine | |
public :: save_result ! subroutine | |
private :: compute_estimated_output ! function | |
! <type>s for this <module> | |
type type_data_observed | |
integer(INT32), public :: size | |
real(REAL64), allocatable, public :: inpt(:) | |
real(REAL64), allocatable, public :: otpt(:) | |
end type type_data_observed | |
type type_data_regression_degree | |
integer(INT32), public :: poly | |
integer(INT32), public :: trig | |
end type type_data_regression_degree | |
type type_data_regression_weight | |
real(REAL64), allocatable, public :: poly(:) | |
real(REAL64), allocatable, public :: trig(:) | |
end type type_data_regression_weight | |
type type_data_regression | |
type(type_data_regression_degree), public :: degree | |
type(type_data_regression_weight), public :: weight | |
end type type_data_regression | |
type type_data_estimated | |
integer(INT32), public :: size | |
real(REAL64), allocatable, public :: inpt(:) | |
real(REAL64), allocatable, public :: otpt(:) | |
end type type_data_estimated | |
! contained <subroutine>s and <function>s are below | |
contains | |
pure function compute_estimated_output (data_regression, input) result(output) | |
! arguments for this <function> | |
type(type_data_regression), intent(in) :: data_regression | |
real(REAL64), intent(in) :: input | |
! return value of this <function> | |
real(REAL64) :: output | |
! variables for this <function> | |
integer(INT32) :: itr_dgr | |
itr_dgr = data_regression%degree%poly | |
output = data_regression%weight%poly(itr_dgr - 1) + data_regression%weight%poly(itr_dgr) * input | |
itr_dgr = itr_dgr - 2_INT32 | |
do while (itr_dgr .ge. 0_INT32) | |
output = data_regression%weight%poly(itr_dgr) + input * output | |
itr_dgr = itr_dgr - 1_INT32 | |
end do | |
do itr_dgr = 1_INT32, data_regression%degree%trig, 1_INT32 | |
output = &! | |
output + &! | |
data_regression%weight%trig(2 * itr_dgr - 1) * cos(itr_dgr * input) + &! | |
data_regression%weight%trig(2 * itr_dgr ) * sin(itr_dgr * input) | |
end do | |
end function compute_estimated_output | |
subroutine compute_weight (data_degree, data_observed, data_regression) | |
! arguments for this <subroutine> | |
type(type_data_regression_degree), intent(in) :: data_degree | |
type(type_data_observed), intent(in) :: data_observed | |
type(type_data_regression), intent(inout) :: data_regression | |
! variables for this <subroutine> | |
integer(INT32) :: bffr_dgr | |
integer(INT32) :: bffr_stat | |
integer(INT32) :: itr_cl, itr_rw | |
integer(INT32), allocatable :: pivot(:) | |
real(REAL64), allocatable :: bffr_vector(:) | |
real(REAL64), allocatable :: bffr_matrix(:,:) | |
real(REAL64), allocatable :: matrix_design_unit(:,:) | |
real(REAL64), allocatable :: matrix_design_prod(:,:) | |
! STEP.01 | |
! store the given degree of regression | |
! allocate the array to store the weight of regression | |
data_regression%degree = data_degree | |
allocate(data_regression%weight%poly(0:data_degree%poly), stat= bffr_stat) | |
if (bffr_stat .gt. 0_INT32) stop 'Failed to allocate `data_regression%weight%poly(:)` !' | |
allocate(data_regression%weight%trig(1:2*data_degree%trig), stat= bffr_stat) | |
if (bffr_stat .gt. 0_INT32) stop 'Failed to allocate `data_regression%weight%trig(:)` !' | |
! STEP.02 | |
! allocate the arrays to store the design matrix | |
bffr_dgr = data_degree%poly + 2 * data_degree%trig | |
allocate(matrix_design_unit(1:data_observed%size, 0:bffr_dgr), stat= bffr_stat) | |
if (bffr_stat .gt. 0_INT32) stop 'Failed to allocate `matrix_design_unit(:,:)` !' | |
allocate(matrix_design_prod(0:bffr_dgr, 0:bffr_dgr), stat= bffr_stat) | |
if (bffr_stat .gt. 0_INT32) stop 'Failed to allocate `matrix_design_prod(:,:)` !' | |
allocate(pivot(0:bffr_dgr), stat= bffr_stat) | |
if (bffr_stat .gt. 0_INT32) stop 'Failed to allocate `pivot(:)` !' | |
allocate(bffr_vector(0:bffr_dgr), stat= bffr_stat) | |
if (bffr_stat .gt. 0_INT32) stop 'Failed to allocate `bffr_vector(:,:)` !' | |
allocate(bffr_matrix(0:bffr_dgr, 0:bffr_dgr), stat= bffr_stat) | |
if (bffr_stat .gt. 0_INT32) stop 'Failed to allocate `bffr_matrix(:,:)` !' | |
! STEP.03 | |
! compute the design matrix | |
matrix_design_unit(1:data_observed%size, 0) = 1 | |
do itr_cl = 1_INT32, data_degree%poly, 1_INT32 | |
do concurrent (itr_rw = 1:data_observed%size:1) | |
matrix_design_unit(itr_rw, itr_cl ) = &! | |
matrix_design_unit(itr_rw, itr_cl - 1) * data_observed%inpt(itr_rw) | |
end do | |
end do | |
do itr_cl = 1_INT32, data_degree%trig, 1_INT32 | |
do concurrent (itr_rw = 1:data_observed%size:1) | |
matrix_design_unit(itr_rw, data_degree%poly + 2 * itr_cl - 1) = cos( itr_cl * data_observed%inpt(itr_rw) ) | |
matrix_design_unit(itr_rw, data_degree%poly + 2 * itr_cl ) = sin( itr_cl * data_observed%inpt(itr_rw) ) | |
end do | |
end do | |
! STEP.04 | |
! compute the weight | |
matrix_design_prod = matmul( transpose(matrix_design_unit), matrix_design_unit ) | |
call lu_decomposition_pivot(&! | |
dim = bffr_dgr + 1_INT32, &! | |
matrix = matrix_design_prod(0:bffr_dgr, 0:bffr_dgr), &! | |
pivot = pivot(0:bffr_dgr) &! | |
) | |
call lu_inverse_pivot(&! | |
dim = bffr_dgr + 1_INT32, &! | |
mtrx_trg = matrix_design_prod(0:bffr_dgr, 0:bffr_dgr), &! | |
pivot = pivot(0:bffr_dgr), &! | |
mtrx_tmp = bffr_matrix(0:bffr_dgr, 0:bffr_dgr), &! | |
vctr_tmp = bffr_vector(0:bffr_dgr) &! | |
) | |
bffr_vector(0:bffr_dgr) = matmul( matrix_design_prod, matmul( transpose(matrix_design_unit), data_observed%otpt ) ) | |
data_regression%weight%poly(0: data_degree%poly) = bffr_vector(0:data_degree%poly) | |
data_regression%weight%trig(1:2*data_degree%trig) = bffr_vector(data_degree%poly + 1:bffr_dgr) | |
! STEP.04 | |
! deallocate arrays used in this subroutine | |
deallocate(bffr_vector) | |
deallocate(bffr_matrix) | |
deallocate(matrix_design_prod) | |
deallocate(matrix_design_unit) | |
deallocate(pivot) | |
end subroutine compute_weight | |
subroutine estimate_output (size, data_observed, data_regression, data_estimated) | |
! arguments for this <subroutine> | |
integer(INT32), intent(in) :: size | |
type(type_data_observed), intent(in) :: data_observed | |
type(type_data_regression), intent(in) :: data_regression | |
type(type_data_estimated), intent(inout) :: data_estimated | |
! variables for this <subroutine> | |
integer(INT32) :: itr_pnt | |
integer(INT32) :: bffr_stat | |
real(REAL64) :: interval_inpt | |
real(REAL64) :: maxval_inpt | |
real(REAL64) :: minval_inpt | |
! STEP.01 | |
! store the given number of points | |
data_estimated%size = size | |
! STEP.02 | |
! allocate the arrays to store the estimated output | |
allocate( data_estimated%inpt(1:size), stat= bffr_stat ) | |
if (bffr_stat .gt. 0_INT32) stop 'Failed to allocate `data_estimated%inpt` !' | |
allocate( data_estimated%otpt(1:size), stat= bffr_stat ) | |
if (bffr_stat .gt. 0_INT32) stop 'Failed to allocate `data_estimated%otpt` !' | |
! STEP.03 | |
! prepare the values to compute input | |
minval_inpt = minval(array= data_observed%inpt(:)) | |
maxval_inpt = maxval(array= data_observed%inpt(:)) | |
interval_inpt = maxval_inpt - minval_inpt | |
minval_inpt = minval_inpt - 0.1_REAL64 * interval_inpt | |
maxval_inpt = maxval_inpt + 0.1_REAL64 * interval_inpt | |
interval_inpt = (maxval_inpt - minval_inpt) / ( size - 1_INT32 ) | |
! STEP.04 | |
! compute the input and estimated output | |
do concurrent (itr_pnt = 1_INT32 : size : 1_INT32) | |
data_estimated%inpt(itr_pnt) = minval_inpt + (itr_pnt - 1_INT32) * interval_inpt | |
data_estimated%otpt(itr_pnt) = compute_estimated_output( data_regression, data_estimated%inpt(itr_pnt) ) | |
end do | |
end subroutine estimate_output | |
subroutine read_data (file, data_observed) | |
! arguments for this <subroutine> | |
character(len=*), intent(in) :: file ! file path to read | |
type(type_data_observed), intent(inout) :: data_observed ! object to store the read data | |
! variables for this <subroutine> | |
integer(INT32) :: bffr_size | |
integer(INT32) :: bffr_stat | |
integer(INT32) :: unit_read | |
integer(INT32) :: itr_line | |
! STEP.01 | |
! open the target file | |
open(&! | |
action = 'read', &! | |
file = file, &! | |
form = 'formatted', &! | |
iostat = bffr_stat, &! | |
newunit = unit_read, &! | |
status = 'old' &! | |
) | |
if (bffr_stat .gt. 0_INT32) then | |
write(unit=OUTPUT_UNIT, fmt='(2(A,/),A,I0)') &! | |
'Failed to open file !', &! | |
'PATH > ' // file, &! | |
'IOSTAT > ', bffr_stat | |
stop | |
end if | |
! STEP.02 | |
! check the given data size | |
bffr_size = 0_INT32 | |
do | |
read(unit=unit_read, fmt='()', iostat=bffr_stat) | |
if ( IS_IOSTAT_END(bffr_stat) ) exit | |
bffr_size = bffr_size + 1_INT32 | |
end do | |
data_observed%size = bffr_size | |
! STEP.03 | |
! allocate the array to store the data | |
allocate( data_observed%inpt(1:bffr_size), stat= bffr_stat ) | |
if (bffr_stat .gt. 0_INT32) stop 'Failed to allocate an array `data_observed%inpt` !' | |
allocate( data_observed%otpt(1:bffr_size), stat= bffr_stat ) | |
if (bffr_stat .gt. 0_INT32) stop 'Failed to allocate an array `data_observed%otpt` !' | |
! STEP.04 | |
! store the read data | |
rewind(unit= unit_read, iostat= bffr_stat) | |
if (bffr_stat .gt. 0_INT32) stop 'Failed to rewind !' | |
! STEP.05 | |
! read out the data | |
do itr_line = 1_INT32, bffr_size, 1_INT32 | |
read(unit=unit_read, fmt=*) &! | |
data_observed%inpt(itr_line), &! | |
data_observed%otpt(itr_line) | |
end do | |
! STEP.06 | |
! close the file | |
close(unit= unit_read, status='keep') | |
end subroutine read_data | |
subroutine save_result (data_observed, data_regression, data_estimated) | |
! arguments for this <subroutine> | |
type(type_data_observed), intent(in) :: data_observed | |
type(type_data_regression), intent(in) :: data_regression | |
type(type_data_estimated), intent(in) :: data_estimated | |
! variables for this <subroutine> | |
integer(INT32) :: itr | |
integer(INT32) :: bffr_stat | |
integer(INT32) :: unit_save | |
open(&! | |
action = 'write', &! | |
file = 'fortran2008/chap01/result.csv', &! | |
form = 'formatted', &! | |
iostat = bffr_stat, &! | |
newunit = unit_save, &! | |
status = 'replace' &! | |
) | |
write(unit= unit_save, fmt='(A,",",A)', advance='yes') &! | |
'input', &! | |
'output (observed)' | |
do itr = 1_INT32, data_observed%size, 1_INT32 | |
write(unit= unit_save, fmt='(ES24.16E3,",",ES24.16E3)', advance='yes') &! | |
data_observed%inpt(itr), &! | |
data_observed%otpt(itr) | |
end do | |
write(unit= unit_save, fmt='(/,A,",",A)', advance='yes') &! | |
'degree', &! | |
'weight (poly)' | |
do itr = 0_INT32, data_regression%degree%poly, 1_INT32 | |
write(unit= unit_save, fmt='(I2,",",ES24.16E3)', advance='yes') &! | |
itr, data_regression%weight%poly(itr) | |
end do | |
write(unit= unit_save, fmt='(/,A,",",A)', advance='yes') &! | |
'degree', &! | |
'weight (trig)' | |
do itr = 1_INT32, 2 * data_regression%degree%trig, 1_INT32 | |
write(unit= unit_save, fmt='(I2,",",ES24.16E3)', advance='yes') &! | |
itr, data_regression%weight%trig(itr) | |
end do | |
write(unit= unit_save, fmt='(/,A,",",A)', advance='yes') &! | |
'input', &! | |
'output (estimated)' | |
do itr = 1_INT32, data_estimated%size, 1_INT32 | |
write(unit= unit_save, fmt='(ES24.16E3,",",ES24.16E3)', advance='yes') &! | |
data_estimated%inpt(itr), &! | |
data_estimated%otpt(itr) | |
end do | |
close(unit= unit_save, status='keep') | |
end subroutine save_result | |
end module mod_ISBN9784061529267 | |
! ================================================================================================================================== | |
program linear | |
! <module>s to import | |
use, intrinsic :: iso_fortran_env | |
use, non_intrinsic :: mod_ISBN9784061529267 | |
! require all variables to be explicitly declared | |
implicit none | |
! variables for this <program> | |
type(type_data_estimated) :: obj_data_estimated | |
type(type_data_observed) :: obj_data_observed | |
type(type_data_regression) :: obj_data_regression | |
type(type_data_regression_degree) :: obj_data_degree | |
obj_data_degree%poly = 2 | |
obj_data_degree%trig = 1 | |
call read_data('downloaded/chap01/nonlinear.dat', obj_data_observed) | |
call compute_weight(obj_data_degree, obj_data_observed, obj_data_regression) | |
call estimate_output(101, obj_data_observed, obj_data_regression, obj_data_estimated) | |
call save_result(obj_data_observed, obj_data_regression, obj_data_estimated) | |
end program linear | |
! ================================================================================================================================== | |
! EOF | |
! ================================================================================================================================== |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ================================================================================================================================== | |
# ISBN 978-4-06-152926-7 | |
# ガウス過程と機械学習 | |
# | |
# [reference] | |
# http://chasen.org/~daiti-m/gpbook/python/lm.py | |
# http://chasen.org/~daiti-m/gpbook/data/nonlinear.dat | |
# https://nbviewer.jupyter.org/gist/genkuroki/a37894d5669ad13b4cd27da16096bfd2 | |
# https://gihyo.jp/book/2015/978-4-7741-7506-5 | |
# ================================================================================================================================== | |
set datafile separator comma | |
set key on outside right center vertical Left reverse | |
set format x '%3.1f' | |
set format y '%3.1f' | |
set grid x | |
set grid y | |
set xlabel 'input' | |
set ylabel 'output' | |
set xzeroaxis linetype -1 | |
set yzeroaxis linetype -1 | |
plot 'result.csv' using 1:2 every ::1:0::0 with points title 'observed' , \ | |
'result.csv' using 1:2 every ::1:3::3 with lines title 'regression' | |
# ================================================================================================================================== | |
# EOF | |
# ================================================================================================================================== |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# GNU Fortran (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0 | |
gfortran -c -O2 -std=f2008 -Wall -fcheck=all -pedantic-errors -ffree-line-length-none ../ISBN9784774175065/Module/ISBN9784774175065.f08 | |
gfortran -c -O2 -std=f2008 -Wall -fcheck=all -pedantic-errors -ffree-line-length-none fortran2008/chap01/20200505_1430.f08 | |
gfortran -o 20200505_1430.exe 20200505_1430.o ISBN9784774175065.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
input | output (observed) | |
---|---|---|
2.7613622000000002E+000 | 7.8126940000000000E-001 | |
-2.5020370999999999E+000 | 5.7840239999999998E-001 | |
-6.5341980000000000E-001 | -8.3648389999999995E-001 | |
-5.0937080000000001E-001 | -1.0659939000000000E+000 | |
1.0698122999999999E+000 | -5.0531780000000004E-001 | |
1.2444854000000001E+000 | 6.5693199999999993E-002 | |
-1.5838630000000001E-001 | -1.7132896000000000E+000 | |
-1.8188962000000000E+000 | 1.5392700000000001E-001 | |
-3.6129367000000001E+000 | 1.0440645000000000E+000 | |
-2.8263055000000001E+000 | 7.7416410000000002E-001 | |
-1.0204458000000001E+000 | -8.3045159999999996E-001 | |
2.6113039999999998E-001 | -1.3202885000000000E+000 | |
-9.6677950000000001E-001 | -1.0839772000000001E+000 | |
4.7017170000000003E-001 | -4.5600799999999997E-002 | |
-7.2799290000000005E-001 | -3.6915999999999997E-002 | |
3.0501329999999999E-001 | -1.1703207000000000E+000 | |
3.9014330000000003E-001 | -7.7879779999999998E-001 | |
3.0430492000000000E+000 | 1.2799982999999999E+000 | |
-1.6307559000000000E+000 | -2.2101540000000000E-001 | |
-3.5160841999999999E+000 | 5.7242400000000004E-001 | |
-6.4898370999999999E+000 | -4.1269260000000002E-001 | |
1.8201852000000001E+000 | 9.1200530000000002E-001 | |
-7.7676290000000003E-001 | -8.3715919999999999E-001 | |
-3.4106993999999999E+000 | 6.3177320000000003E-001 | |
-9.1959919999999995E-001 | -1.2476601000000000E+000 | |
-1.1248267000000001E+000 | -4.3716270000000002E-001 | |
-1.5116411999999999E+000 | -7.7745160000000002E-001 | |
1.8203301999999999E+000 | 1.2516906999999999E+000 | |
-1.1185539000000000E+000 | -1.6227400999999999E+000 | |
degree | weight (poly) | |
0 | -9.5426604458734299E-002 | |
1 | 7.2322955596856808E-002 | |
2 | 2.4200714833955781E-002 | |
degree | weight (trig) | |
1 | -9.0875410400920353E-001 | |
2 | 2.9939963775084627E-001 | |
input | output (estimated) | |
-7.4431257300000002E+000 | 6.9552597830008667E-002 | |
-7.2143364588000001E+000 | -1.4027833846537097E-001 | |
-6.9855471875999999E+000 | -3.0678636857615749E-001 | |
-6.7567579163999998E+000 | -4.2452885579149924E-001 | |
-6.5279686452000005E+000 | -4.9047261765132050E-001 | |
-6.2991793740000004E+000 | -5.0415200510174263E-001 | |
-6.0703901028000002E+000 | -4.6769317054032072E-001 | |
-5.8416008316000001E+000 | -3.8570325998311028E-001 | |
-5.6128115604000000E+000 | -2.6503030428100305E-001 | |
-5.3840222892000007E+000 | -1.1440632303864626E-001 | |
-5.1552330180000006E+000 | 5.6007758553942744E-002 | |
-4.9264437468000004E+000 | 2.3515166258984493E-001 | |
-4.6976544756000003E+000 | 4.1164218251905055E-001 | |
-4.4688652044000001E+000 | 5.7436643716501989E-001 | |
-4.2400759332000000E+000 | 7.1306103630202688E-001 | |
-4.0112866619999998E+000 | 8.1884697365285619E-001 | |
-3.7824973908000001E+000 | 8.8469237050273142E-001 | |
-3.5537081196000000E+000 | 9.0577895330588232E-001 | |
-3.3249188484000003E+000 | 8.7975316571811313E-001 | |
-3.0961295772000001E+000 | 8.0684882795014645E-001 | |
-2.8673403060000000E+000 | 6.8987495085335016E-001 | |
-2.6385510347999999E+000 | 5.3406933982626303E-001 | |
-2.4097617635999997E+000 | 3.4682561820848634E-001 | |
-2.1809724924000005E+000 | 1.3730789677439117E-001 | |
-1.9521832212000003E+000 | -8.4026828557700384E-002 | |
-1.7233939500000002E+000 | -3.0597365979354668E-001 | |
-1.4946046788000000E+000 | -5.1716375804396542E-001 | |
-1.2658154075999999E+000 | -7.0665684874777057E-001 | |
-1.0370261363999997E+000 | -8.6451139157927481E-001 | |
-8.0823686520000049E-001 | -9.8230269972365425E-001 | |
-5.7944759400000034E-001 | -1.0535620059054203E+000 | |
-3.5065832280000020E-001 | -1.0741135925416412E+000 | |
-1.2186905160000006E-001 | -1.0422924159427531E+000 | |
1.0692021960000009E-001 | -9.5903088272764547E-001 | |
3.3570949080000023E-001 | -8.2781025596135172E-001 | |
5.6449876199999949E-001 | -6.5447922356220645E-001 | |
7.9328803319999963E-001 | -4.4694908457612104E-001 | |
1.0220773043999998E+000 | -2.1478143917284798E-001 | |
1.2508665755999999E+000 | 3.1310129440453860E-002 | |
1.4796558468000001E+000 | 2.8001841054421850E-001 | |
1.7084451180000002E+000 | 5.2003185927877627E-001 | |
1.9372343892000004E+000 | 7.4062411589730281E-001 | |
2.1660236604000005E+000 | 9.3221302716061816E-001 | |
2.3948129316000006E+000 | 1.0868600355797073E+000 | |
2.6236022028000008E+000 | 1.1986839100368205E+000 | |
2.8523914739999991E+000 | 1.2641672555520851E+000 | |
3.0811807451999993E+000 | 1.2823398279488851E+000 | |
3.3099700163999994E+000 | 1.2548290996810072E+000 | |
3.5387592875999996E+000 | 1.1857754415026061E+000 | |
3.7675485587999997E+000 | 1.0816163404239116E+000 | |
3.9963378299999999E+000 | 9.5075089977906180E-001 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment