function [cost,grad]=costgrad_TICA(W,X,H,op)
%
% This function computes the cost and gradient of a obj function for TICA.
% topographies on one and two dimensional lattice are possible. But, the
% size of topography is restricted. 
% 
% W: filter matrix
% X: whitened data 
% p: parameters
% op: options
% H: topography matrix
%

if(nargin~=4)
    error('Check the number of arguments.\n');
end

if(size(W,2)<2)
    W=reshape(W,[op.components,size(X,1)]);
end

N=size(X,2);

S=W*X;

H=abs(H);
epsi=0.1;

hnum=round(op.toponum/2);

Hb=sum(H(:,:,1:hnum),3)-(hnum-1)*eye(op.components);
Hf=sum(H(:,:,hnum+1:end),3)-(hnum-1)*eye(op.components);

sqSf=(epsi+Hf*S.^2).^(0.5);
    
grad=(S.*(Hb*(sqSf.^(-1))))*X'/N-inv(W');
    
cost=mean(sum(sqSf))-log(abs(det(W)));

grad=grad(:);