samples = model.sample_real(randint(n_min, n_max))
    
    # only sample once per undirected edge
    inverse_edge=(edge[1], edge[0])
    if (edge not in data and inverse_edge not in data):
        data1=samples[edge[0]]
        data2=samples[edge[1]]
        
        data[edge]=(data1,data2)
        data[inverse_edge]=(data2,data1)
        
# compute all (here Gaussian) kernels of node data at edges with themselves
kernel=GaussianKernel(sigma=1)

# collect lines for Graphlab graph definition file for full rank case
graphlab_lines=GraphlabLines(output_filename="graph_definition.txt", \
                             caller_filename=os.path.basename(__file__))


# regulariser for matrix inversions
reg_lambda=0.1

# incomplete cholesky cutoff parameter
eta=0.1

# store index sets at source and target of every edge
index_sets={}

print "precomputing systems for messages from observed nodes"
graphlab_lines.lines.append(os.linesep + "# edges with observed targets")
for node, observation in observations.items():
    for out_message in graph[node]:
 def precompute(self):
     # collect lines for Graphlab graph definition file for full rank case
     graphlab_lines=GraphlabLines(output_filename=self.output_filename)
                                         
     # compute all non-symmetric kernels for incoming messages at a node
     print "precomputing (non-symmetric) kernels for incoming messages at a node"
     graphlab_lines.lines.append("# non-observed nodes")
     for node in self.graph:
         added_node=False
         
         for in_message in self.graph[node]:
             for out_message in self.graph[node]:
                 if in_message==out_message:
                     continue
                 
                 # dont add nodes which have no kernels, and only do once if they have
                 if not added_node:
                     graphlab_lines.new_non_observed_node(node)
                     added_node=True
                     
                 edge_in_message=(node, in_message)
                 edge_out_message=(out_message, node)
                 
                 lhs=self.data[edge_in_message][0]
                 rhs=self.data[edge_out_message][1]
                 lhs=reshape(lhs, (len(lhs),1))
                 rhs=reshape(rhs, (len(rhs),1))
                 K=self.kernel.kernel(lhs,rhs)
                 graphlab_lines.add_non_observed_node(node, out_message, in_message, K)
         
     print "precomputing kernel (vectors) at observed nodes"
     graphlab_lines.lines.append(os.linesep + "# observed nodes")
     for node, observation in self.observations.items():
         graphlab_lines.new_observed_node(node)
         
         for out_message in self.graph[node]:
             edge=(out_message, node)
             lhs=self.data[edge][1]
             lhs=reshape(lhs, (len(lhs), 1))
             rhs=[[observation]]
             K=self.kernel.kernel(lhs, rhs)
             graphlab_lines.add_observed_node(node, out_message, K)
             
     
     # now precompute systems for inference
     
     print "precomputing systems for messages from observed nodes"
     graphlab_lines.lines.append(os.linesep + "# edges with observed targets")
     for node, observation in self.observations.items():
         for out_message in self.graph[node]:
             edge=(out_message, node)
             graphlab_lines.new_edge_observed_target(node, out_message)
             
             data_source=self.data[edge][0]
             data_source=reshape(data_source, (len(data_source), 1))
             data_target=self.data[edge][1]
             data_target=reshape(data_target, (len(data_target), 1))
     
             Ks=self.kernel.kernel(data_source)
             Kt=self.kernel.kernel(data_target)
             
             Ls=cholesky(Ks+eye(shape(Ks)[0])*self.reg_lambda)
             Lt=cholesky(Kt+eye(shape(Kt)[0])*self.reg_lambda)
             
             graphlab_lines.add_edge(node, out_message,"L_s", Ls)
             graphlab_lines.add_edge(node, out_message,"L_t", Lt)
     
     print "precomputing systems for messages from non-observed nodes"
     graphlab_lines.lines.append(os.linesep + "# edges with non-observed targets")
     for edge in self.edges:
         # exclude edges which involve observed nodes
         is_edge_target_observed=len(Set(self.observations.keys()).intersection(Set(edge)))>0
         if not is_edge_target_observed:
             graphlab_lines.new_edge_observed_target(edge[1], edge[0])
             
             data_source=self.data[edge][0]
             data_source=reshape(data_source, (len(data_source), 1))
             Ks=self.kernel.kernel(data_source)
             Ls=cholesky(Ks+eye(shape(Ks)[0])*self.reg_lambda)
             graphlab_lines.add_edge(edge[1], edge[0],"L_s", Ls)
             
     # write graph definition file to disc
     graphlab_lines.flush()