function [solucion, distancia, distabs] = condicionesvn(k, X, Y, F, signoX, signoXF, cero)
%condicionesvn
%   solucion = condicionesvn(k, X, Y, F, signoX, signoXF)
%
%   Comprueba si se cumplen las condiciones de primer orden para VN
%      X ~ 0        <->    F(k) Y ~ 0              X .* F(k) Y = 0
%      X F(k) ~ 0   <->    -Y ~ 0                  X F(k) .* Y = 0
%      k > 0               1 + X F'(k) Y = 0
%
%   [solucion, distancia, distabs] = condicionesvn(k,X,Y,F,signoX,signoXF,cero)
%   Devuelve la tabla con las distancias al cumplimiento de las condiciones
%   [X~0, dL/dX~0, X·dL/dX; -Y~0, dL/dY~0, dL/dY·Y; k>0, dL/dk, k·dL/dk]
%      k, X, Y     factor, intensidades y valores solución
%      F           recetas en tiempo discreto o continuo
%      signoX      signo de las intensidades; por defecto X >= 0
%      signoXF     signo de los balances materiales; por defecto X F(k) = 0
%      cero        precisión del cero (1e-10 por defecto)
%      solucion    es 1 si se cumplen las condiciones y 0 si no se cumplen
%      distancia   tabla con las distancias a las condiciones
%      distabs     suma de la magnitud absoluta de las distancias

%necesita forma0.m, forma1.m

if nargin < 5, signoX = []; end
if nargin < 6, signoXF = []; end
if nargin < 7, cero = []; end

if isempty(cero), cero = 1e-10; end      %define la precisión del cero
Fn = forma0(F, k);                       %calcula F(k)
[filas, columnas] = size(Fn);            %establece el tamaño del problema
if isempty(signoX), signoX = 1; end      %si no esta definido supone que X >= 0
if size(signoX, 2) == 1, signoX = signoX*ones(1,filas); end
if isempty(signoXF), signoXF = 0; end    %si no esta definido supone que X F(k) = 0
if size(signoXF, 2) == 1, signoXF = signoXF*ones(1,columnas); end
signoY = signodual(signoXF, [3,1,2,0]);  %establece los signos de Y
signoFY = signodual(signoX, [3,2,1,0]);  %establece los signos de F(k) Y

if nargout == 1                          %si sólo hay un argumento de salida
    solucion = 0;                            %de entrada se supone que no hay solución
    if and(abs(imag(k)) < cero, real(k) > cero)  %pero si k es real y positivo
        if res(X, signoX, cero)                      %si X ~ 0
            if res(Y, signoY, cero)                      %si Y ~ 0
                if res(Fn*Y, signoFY, cero)                  %si dL/dX = F(k) Y ~ 0
                    if res(X*Fn, signoXF, cero)                  %si dL/dY = X F(k) ~ 0
                        if abs(X'.*(Fn*Y)) < cero                    %si X' · dL/dX = X' .* F(k) Y = 0
                            if abs((X*Fn)'.*Y) < cero                    %si dL/dY · Y' = X F(k) .* Y' = 0
                                if abs(1+X*forma1(F,k)*Y) < cero             %si dL/dk = 1 + X F'(k) Y = 0
                                    solucion = 1;                                  %entonces existe solución
                                end
                            end
                        end
                    end
                end
            end
        end
    end
else                                      %si hay varios argumentos de salida
    XF = X * Fn;                                                    %calcula X * F(k)
    FY = Fn * Y;                                                    %calcula F(k) * Y
    XdFY = X * forma1(F, k) * Y;                                    %calcula X * F'(k) * Y
    distancia = [res2(X, signoX)  , res2(FY, signoFY), X' .* FY   ; %X ~ 0        F(k) Y ~ 0          X' · F(k) Y = 0
                 res2(XF, signoXF), res2(Y, signoY)  , XF' .* Y   ; %X F(k) ~ 0   -Y ~ 0              X F(k) · Y' = 0
                 res2(k, 1)       , 1 + XdFY         , k*(1+XdFY)]; %k > 0        1 + X F'(k) Y = 0   k · (1+X F'(k) Y) = 0
    solucion = sum(sum(abs(distancia)<cero)) == ((filas+columnas+1)*3);
    distabs = sum(sum(abs(distancia)));
end




function solucion = res(X, signoX, cero)
solucion = 1;
for c1 = 1:size(signoX, 2)
    switch signoX(c1)
        case 0, if abs(X(c1)) > cero, solucion = 0; break; end
        case 1, if X(c1) < -cero, solucion = 0; break; end
        case 2, if X(c1) > cero, solucion = 0; break; end
        case 3,
    end
end


function distancia = res2(X, signoX)
n = size(signoX, 2);
distancia = zeros(n, 1);
for c1 = 1:n
    switch signoX(c1)
        case 0, distancia(c1) = X(c1);
        case 1, if X(c1) < 0, distancia(c1) = X(c1); end
        case 2, if X(c1) > 0, distancia(c1) = X(c1); end
        case 3,
    end
end


function y = signodual(x, distancia)
y = distancia(x(:) + 1);
