function ddEV = lyngby_nn_cddevds(X, Y, V, W, H12)

% lyngby_nn_cddevds    - 2nd order, entropic, input, diag. sym.
%
%       function ddEV = lyngby_nn_cddevds(X, Y, V, W, H12)
%
%       Input:  X      Neural network input
%               Y      Neural network output
%               W      Output weights
%               H12    One minus Hidden layer in 2nd power
%
%       Output: ddEV   Derivative, a vector
%
%       'Symmetric' diagonal approximation to the second order
%       derivative of the entropic error function with respect 
%       to the input weights.
%
%       H12 can be computed as (1-H.^2)
%
%       See also: lyngby_nn_cddewds, lyngby_nn_cdev

% cvs : $Id: lyngby_nn_cddevds.m,v 1.1 1998/03/20 14:30:15 fnielsen Exp $
%       $Revision: 1.1 $

    [Nii, Nh] = size(V);
    [Nhh, No] = size(W);
    [Np, Noo] = size(Y);

    H122  = H12(:,1:Nh) .* H12(:,1:Nh);    % Np x Nh
    X2t   = (X .* X)';                     % Nii x Np
    Y1    = Y(:,1:No) .* (1 - Y(:,1:No));  % Np x No
    W2t   = (W(1:Nh,:) .* W(1:Nh,:))';     % No x Nh
    
    ddEV  = X2t * ((Y1 * W2t) .* H122) / Np;
    
    % Numerical errors? 
    indices = find(V==0);
    if indices
      ddEV(indices) = zeros(1,length(indices));
    end

    % This is equivalent to the last computation:
    %ddEVtest = zeros(Nh, Nii);
    % for oo = 1:No
    %   for hh = 1:Nh
    %     for pp = 1:Np
    %	   ddEVtest(hh,:) = W2(oo,hh) * Y1(oo,pp) * H122(hh,pp) * ...
    %	       X2t(pp,:);
    %	  end
    %   end
    % end















