For anyone interested in learning more about user-defined â€śconstructorsâ€ť via a generic interface that has the same name as the derived type, see below a simple example to experiment with using gfortran , Intel oneAPI IFORT, etc.

The example uses the topic at hand of linear regression. Note also with the question in the original post with derived type components being `PRIVATE`

, that notion has been extended to the basic OO concept of `information hiding`

and `data encapsulation`

in this example.

Iâ€™ll leave it to critics of OO to give commentary on how such a style can be unwieldy in some circumstances!

```
module linear_reg_m
private
type, public :: linear_reg_t
private ! All components private by default
real :: m_n = 0.0
real :: m_R_squared = 0.0 ! note default initialized to zero
real :: m_slope = 0.0
real :: m_intercept = 0.0
real :: m_Sx = 0.0
real :: m_Sy = 0.0
real :: m_Sxx = 0.0
real :: m_Syy = 0.0
real :: m_Sxy = 0.0
real, allocatable :: m_residuals(:)
contains
private
procedure, pass(this), public :: intercept => get_intercept
procedure, pass(this), public :: residuals => get_residuals
procedure, pass(this), public :: slope => get_slope
procedure, pass(this), public :: y => calc_y
end type
interface linear_reg_t ! Generic interface
module procedure construct_linear_reg_basic
module procedure construct_linear_reg_data
end interface
contains
function construct_linear_reg_basic( slope, intercept ) result(r)
real, intent(in) :: slope
real, intent(in) :: intercept
! Function result
type(linear_reg_t) :: r
r%m_slope = slope
r%m_intercept = intercept
end function
function construct_linear_reg_data( x, y ) result(r)
real, intent(in) :: x(:)
real, intent(in) :: y(:)
! Function result
type(linear_reg_t) :: r
! Elided are checks on data
r%m_n = real( size(x) )
r%m_Sx = sum( x )
r%m_Sy = sum( y )
r%m_Sxx = dot_product( x, x )
r%m_Syy = dot_product( y, y )
r%m_Sxy = dot_product( x, y )
r%m_slope = ( r%m_n*r%m_Sxy - r%m_Sx*r%m_Sy) / (r%m_n*r%m_Sxx - r%m_Sx**2)
r%m_intercept = ( r%m_Sy - r%m_slope*r%m_Sx ) / r%m_n
allocate( r%m_residuals(size(x)) )
r%m_residuals = calc_y( r, x ) - y
end function
elemental function get_intercept( this ) result(intercept)
class(linear_reg_t), intent(in) :: this
! Function result
real :: intercept
intercept = this%m_intercept
end function
elemental function get_slope( this ) result(slope)
class(linear_reg_t), intent(in) :: this
! Function result
real :: slope
slope = this%m_slope
end function
elemental function calc_y( this, x ) result(y)
class(linear_reg_t), intent(in) :: this
real, intent(in) :: x
! Function result
real :: y
y = this%m_slope*x + this%m_intercept
end function
function get_residuals(this) result(residuals)
class(linear_reg_t), intent(in) :: this
! Function result
real, allocatable :: residuals(:)
! Elided are checks on state
if ( allocated(this%m_residuals) ) then
residuals = this%m_residuals
else
! Return a zero-sized vector?
residuals = [ real :: ]
end if
end function
end module
use linear_reg_m, only : linear_reg_t
blk1: block
real, allocatable :: height(:)
real, allocatable :: weight(:)
type(linear_reg_t) :: model
print *, "Block 1: Linear Regression of some data"
! Arbitrary data
height = [ 1.47, 1.50, 1.52, 1.55, 1.57, 1.60 ]
weight = [ 52.21, 53.12, 54.48, 55.84, 57.20, 58.57 ]
model = linear_reg_t( x=height, y=weight ) !<< Construct model using raw data
print *, "Slope: ", model%slope()
print *, "Intercept: ", model%intercept()
print *, "Residuals: ", new_line(""), model%residuals()
end block blk1
print *
blk2: block
type(linear_reg_t) :: model
print *, "Block 2: Calculation using an arbitrary model"
model = linear_reg_t( slope=61.272, intercept=-39.062 ) !<< Construct model using reduced data
print *, "y(x) at x=1.5: ", model%y( x=1.5 )
end block blk2
end
```

Upon execution with gfortran, the output is as I expect:

Block 1: Linear Regression of some data

Slope: 50.7999115

Intercept: -22.7411957

Residuals:

-0.275321960 0.338672638 -5.32913208E-03 0.158664703 -0.185329437 -3.13339233E-02

Block 2: Calculation using an arbitrary model

y(x) at x=1.5: 52.8459969