* Predicted energy : e_model

*Compute the energy predicted by the Taylor series*

The energy is predicted using a Taylor expansion truncated at te 2nd
order :

\begin{align*}
E_{k+1} = E_{k} + \textbf{g}_k^{T} \cdot \textbf{x}_{k+1} + \frac{1}{2} \cdot \textbf{x}_{k+1}^T \cdot \textbf{H}_{k} \cdot \textbf{x}_{k+1} + \mathcal{O}(\textbf{x}_{k+1}^2)
\end{align*}

Input:
| n           | integer          | m*(m-1)/2                                 |
| n2          | integer          | m*(m-1)/2 or 1 if the hessian is diagonal |
| v_grad(n)   | double precision | gradient                                  |
| H(n,n)      | double precision | hessian                                   |
| x(n)        | double precision | Step in the trust region                  |
| prev_energy | double precision | previous energy                           |

Output:
| e_model | double precision | predicted energy after the rotation of the MOs |

Internal:
| part_1  | double precision | v_grad^T.x    |
| part_2  | double precision | 1/2 . x^T.H.x |
| part_2a | double precision | H.x           |
| i,j     | integer          | indexes       |

Function:
| ddot | double precision | dot product (Lapack) |

#+BEGIN_SRC f90 :comments org :tangle trust_region_expected_e.irp.f
subroutine trust_region_expected_e(n,n2,v_grad,H,x,prev_energy,e_model)
   
  include 'pi.h'

  !BEGIN_DOC
  ! Compute the expected criterion/energy after the application of the step x
  !END_DOC

  implicit none

  ! Variables

  ! in
  integer, intent(in)           :: n,n2
  double precision, intent(in)  :: v_grad(n),H(n,n2),x(n)
  double precision, intent(in)  :: prev_energy

  ! out
  double precision, intent(out) :: e_model

  ! internal
  double precision              :: part_1, part_2, t1,t2,t3
  double precision, allocatable :: part_2a(:)

  integer                       :: i,j

  !Function
  double precision              :: ddot

  print*,''
  print*,'---Trust_e_model---'

  call wall_time(t1)

  ! Allocation
  allocate(part_2a(n))
#+END_SRC

** Calculations

part_1 corresponds to the product g.x
part_2a corresponds to the product H.x
part_2 corresponds to the product 0.5*(x^T.H.x)

TODO: remove the dot products

#+BEGIN_SRC f90 :comments org :tangle trust_region_expected_e.irp.f
  ! Product v_grad.x
  part_1 = ddot(n,v_grad,1,x,1)
 
  !if (debug) then
  !  print*,'g.x : ', part_1
  !endif
    
  ! Product H.x
  if (n == n2) then
    call dgemv('N',n,n,1d0,H,size(H,1),x,1,0d0,part_2a,1)
  else
    ! If the hessian is diagonal
    do i = 1, n
      part_2a(i) = H(i,1) * x(i)
    enddo
  endif

  ! Product 1/2 . x^T.H.x
  part_2 = 0.5d0 * ddot(n,x,1,part_2a,1)

  !if (debug) then
  !  print*,'1/2*x^T.H.x : ', part_2 
  !endif


  ! Sum
  e_model = prev_energy + part_1 + part_2

  ! Writing the predicted energy
  print*, 'prev_energy:                        ', prev_energy
  print*, 'Predicted energy after the rotation:', e_model
  print*, 'Previous energy - predicted energy: ', prev_energy - e_model
  
  ! Can be deleted, already in another subroutine
  if (DABS(prev_energy - e_model) < 1d-12 ) then 
    print*,'WARNING: ABS(prev_energy - e_model) < 1d-12'
  endif

  ! Deallocation
  deallocate(part_2a)

  call wall_time(t2)
  t3 = t2 - t1
  print*,'Time in trust e model:', t3

  print*,'---End trust_e_model---'
 
end subroutine 
#+END_SRC 
