void makeOLSAveragesTable( double[][] D, double[][] A )
	{
	  	edge e,f,g,h;
	  	edge exclude;
	  	e = f = null;
	  	e = depthFirstTraverse(e);
	  	while ( null != e )
	    {
	      	f = e;
	      	exclude = e.tail.parentEdge;
	      	/* we want to calculate A[e.head][f.head] for all edges
			except those edges which are ancestral to e.  For those
			edges, we will calculate A[e.head][f.head] to have a
			different meaning, later*/
	      if ( e.head.leaf() )
	      {
	    	  while ( null != f )
	    	  {
	    		  if ( exclude != f )	   
	    		  {
	    			  if ( f.head.leaf() )
	    				  A[e.head.index][f.head.index] = 
	    				     A[f.head.index][e.head.index] = 
	    					 D[e.head.index2][f.head.index2];
	    			  else
	    			  {
	    				  g = f.head.leftEdge;
	    				  h = f.head.rightEdge;
	    				  A[e.head.index][f.head.index] = 
	    					  A[f.head.index][e.head.index] = 
	    					  (g.bottomsize*A[e.head.index][g.head.index] 
	    					  + h.bottomsize*A[e.head.index][h.head.index])
	    					  /f.bottomsize; 
	    			  }
	    		  }
	    		  else //exclude == f
	    			  exclude = exclude.tail.parentEdge; 
	    		  f = depthFirstTraverse(f);
	    	  }
    	  }
    	  else 
	      //e.head is not a leaf, so we go recursively to 
	      //values calculated for the nodes below e
    	  while ( null !=f )
	      {
			  if ( exclude != f )	      
			  {
				  g = e.head.leftEdge;
				  h = e.head.rightEdge;
				  A[e.head.index][f.head.index] = 
					  A[f.head.index][e.head.index] = 
					  (g.bottomsize*A[f.head.index][g.head.index] 
					  + h.bottomsize*A[f.head.index][h.head.index])
					  /e.bottomsize;
			  }
			  else
				  exclude = exclude.tail.parentEdge;
			  f = depthFirstTraverse(f);
		  }
	      /*now we move to fill up the rest of the table: we want
	    	A[e.head.index][f.head.index] for those cases where e is an
	    	ancestor of f, or vice versa.  We'll do this by choosing e via a
	    	depth first-search, and the recursing for f up the path to the
	    	root*/
	      f = e.tail.parentEdge;
	      if (null != f)
	    	  fillTableUp(e,f,A,D);	   
	      e = depthFirstTraverse(e);
	    } 

	  	/*we are indexing this table by vertex indices, but really the
	    underlying object is the edge set.  Thus, the array is one element
	    too big in each direction, but we'll ignore the entries involving the root,
	    and instead refer to each edge by the head of that edge.  The head of
	    the root points to the edge ancestral to the rest of the tree, so
	    we'll keep track of up distances by pointing to that head*/

	  	/*10/13/2001: collapsed three depth-first searches into 1*/
	}