      module chain_weight
      use sparse_matmult_fly_sym
      use scaled_identity
      implicit none
      logical, parameter, private :: T = .true., F = .false.
      contains

      !---------------------------------------------------------------------------------
      integer function chain_w( adj, add, model, data) 
      logical            :: adj,add
      real, dimension(:) :: model, data
      real, pointer      :: temp(:)


      allocate( temp(size(model)))
      
      call chain20(scaled_identity_wto_lop,smatmult_lop, adj, add, model, data, temp)

      deallocate( temp)

      chain_w= 0

      end function


      !---------------------------------------------------------------------------------
      subroutine chain20(op1,op2, adj,add, m,d,t1)
        interface  
          integer function op1(adj,add,m,d)
            real::m(:),d(:)
            logical,intent(in)::adj,add
          end function 
          integer function op2(adj,add,m,d)
            real::m(:),d(:)
            logical,intent(in)::adj,add
          end function
        end interface 
        logical, intent(in) :: adj, add
        real, dimension(:)  :: m,d, t1
        integer             :: st
        if (adj) then
          st = op1( T,   F, t1,d )         !        t =    H' d
          st = op2( T, add, m, t1)         ! m = B' t = B' A' d
        else
          st = op2( F,   F, m, t1)         !        t =    B  m
          st = op1( F, add, t1,d )         ! d = A  t = A  B  m
        end if
      end subroutine
     !---------------------------------------------------------------------------------

      end module
