void updateSubTree(double[][] A, edge nearEdge, node v, node root,
			node newNode, double dcoeff, direction d )
	{
		edge sib;
	  	switch( d )
	    {
	    	case UP: //newNode is above the edge nearEdge
	    		A[v.index][nearEdge.head.index] = A[nearEdge.head.index][v.index];
	    		A[newNode.index][nearEdge.head.index] = 
	    			A[nearEdge.head.index][newNode.index] =
	    			A[nearEdge.head.index][root.index];	
	    		if (null != nearEdge.head.leftEdge)
	    			updateSubTree(A, nearEdge.head.leftEdge, v, root, newNode, 
	    				0.5*dcoeff, direction.UP);
	    		if (null != nearEdge.head.rightEdge)
	    			updateSubTree(A, nearEdge.head.rightEdge, v, root, newNode, 
	    				0.5*dcoeff, direction.UP);
	    		updatePair(A, nearEdge, nearEdge, v, root, dcoeff, direction.UP);
	    		break;
	    	case DOWN: //newNode is below the edge nearEdge
	    		A[nearEdge.head.index][v.index] = A[v.index][nearEdge.head.index];
	    		A[newNode.index][nearEdge.head.index] = 
	    			A[nearEdge.head.index][newNode.index] =
	    			0.5*(A[nearEdge.head.index][root.index] 
	    			+ A[v.index][nearEdge.head.index]);
	    		sib = nearEdge.siblingEdge();
	    		if (null != sib)
	    			updateSubTree(A, sib, v, root, newNode, 0.5*dcoeff, 
	    				direction.SKEW);
	    		if (null != nearEdge.tail.parentEdge)
	    			updateSubTree(A, nearEdge.tail.parentEdge, v, root, 
	    				newNode, 0.5*dcoeff, direction.DOWN);
	    		updatePair(A, nearEdge, nearEdge, v, root, dcoeff, direction.DOWN);
	    		break;
	    	case SKEW: //newNode is neither above nor below nearEdge
	    		A[v.index][nearEdge.head.index] = A[nearEdge.head.index][v.index];
	    		A[newNode.index][nearEdge.head.index] = 
	    			A[nearEdge.head.index][newNode.index] =
	    			0.5*(A[nearEdge.head.index][root.index] + 
	    			A[nearEdge.head.index][v.index]);	
	    		if (null != nearEdge.head.leftEdge)
	    			updateSubTree(A, nearEdge.head.leftEdge, v, root, 
	    				newNode, 0.5*dcoeff,direction.SKEW);
	    		if (null != nearEdge.head.rightEdge)
	    			updateSubTree(A, nearEdge.head.rightEdge, v, root, 
	    				newNode, 0.5*dcoeff,direction.SKEW);
	    		updatePair(A, nearEdge, nearEdge, v, root, dcoeff, direction.UP);
	    }
	}