
%  Solve the Dirichlet problem on a graph and display the results.
%  Usage:
%
%    dirichlet(G, XY, bndryValues)
%
%  runs on the graph G having (x,y) coordinates XY, with
%  boundary values bndryValues = [[n1,v1];[n2,v2];...;[nk,vk]]
%  which specify that node n1 has value v1, etc.

function dirichlet(G, XY, bndry)

     n = length(G);
     f = zeros(n,1);
     g = zeros(n,1);
     ind = zeros(n,1);
     pos = zeros(n,1);
     isboundary = zeros(n,1);
     p = zeros(n,n);
     d = size(bndry);
     labeled = d(1);
     unlabeled = n-labeled;

     % assign indices, with the labeled vertices first, and
     % fix the values on the boundary

     for i = 1:labeled
       x = bndry(i,1);
       v =  bndry(i,2);
       ind(x) = i;
       pos(i) = x;
       isboundary(x) = 1;
       f(i) = bndry(i,2);
     end;

     % now index the unlabeled data
     i = labeled+1;
     for x = 1:n
       if (not(isboundary(x))) 
	 ind(x) = i;
	 pos(i) = x;
	 i = i+1;
       end
     end
     if (not(i-1==n)) 
        error('Error indexing unlabeled data: %d != %d', i-1, n)
     end

     for i = 1:labeled
        p(i,i) = 1;
     end

     % Now construct the transition matrix
     for i = (labeled+1):n
        x = pos(i);
        numNeighbors = 0;
	for y = 1:n
	  if (G(x,y)) 
	    numNeighbors = numNeighbors+1;
	  end
	end
        % normalize
	for y = 1:n
	  if (G(x,y))
	    j = ind(y);
	    p(i,j) = 1/numNeighbors;
	  end
	end
     end

     % Finally, do the algebra that computes the sol'n
     % to the Dirichlet problem
     R = p(labeled+1:n,1:labeled);
     Q = p(labeled+1:n,labeled+1:n);
     Id = eye(unlabeled,unlabeled);
     B = inv(Id-Q)*R;
     f(1+labeled:n) = B*f(1:labeled);

     % Now map f to a vector of 'colors'
     C = zeros(n,1);
     for i = 1:n
       x = pos(i);
       C(x) = f(i);
     end
     
     % plot it!
     gcplot(G, XY, bndry, C);

