function [W,dActual] = perceptron(x,d)
    alpha = 0.75;
    N = 50000;
    W = rand(3,3);

    for counter = 1:N
        index = mod(counter-1,size(x,2))+1;
        
        [y,z] = evaluatePerceptron(W,x(:,index));
        
        gradientE = zeros(3,3);
        for i = 1:2
            for j = 1:3
                gradientE(j,i) = -(d(index)-y)*y*(1-y)*W(i,3)*z(i)*(1-z(i))*x(j,index);
            end
        end
    
        for j = 1:3
            gradientE(j,3) = -(d(index)-y)*y*(1-y)*z(j);
        end
        
        W = W-alpha*gradientE;
    end

    dactual = zeros(size(d));
    for counter = 1:size(x,2)
        dActual(counter) = evaluatePerceptron(W,x(:,counter));
    end
    
    X = 0:0.01:1;
    Y = X;
    Z = zeros(length(Y),length(X));
    for i = 1:length(X)
        for j = 1:length(Y)
            Z(j,i) = evaluatePerceptron(W,[X(i);Y(j);-1]);
        end
    end
    mesh(X,Y,Z);
    view(-10,35);

    return;
    
function f = sigmoid(v)
    f = 1/(1+exp(-v));
    
    return;
    
function [y,z] = evaluatePerceptron(W,x)
    z = [sigmoid(W(:,1)'*x);sigmoid(W(:,2)'*x);-1];
    y = sigmoid(W(:,3)'*z);
    
    return;