1) Write Python functions that return a list of N i.i.d. pseudo- random variates for the following distributions: - the t-distribution with parameter p: def student(N,p): - the F-distribution with parameters p and q: def F_distr(N,p): - the Poisson distribution with parameter lambda: def poisson(N,lambda): Find a relation between the Poisson variates and other variates that are implemented in Python, such as the uniform, exponential, Gaussian, Gamma,..., and use it to implement the Poisson function. Inside the functions say import random You can then use calls to the following functions that produce one pseudo-random variate at a time: random.uniform(left, right) random.gauss(mean,stdev) random.expovariate(par) # par = 1/scale random.gammavariate(par1,par2) 2) Construct a random binary tree that tiles the unit square (0,1)x(0,1) as follows. - A tile is defined as a rectangle (al,ar)x(bl,br), where 0 <= al < ar <= 1 and 0 <= bl < br <= 1 - A random subdivision of a rectangle is obtained as follows: . If (al,ar) is wider than (bl,br), pick a uniform random number c between al and ar. Let (al,c)x(bl,br) and (c,ar)x(bl,br) be the daughter rectangles of (al,ar)x(bl,br). . If (bl,br) is wider, proceed similarly. - The width of a rectangle is defined as max(ar-al,br-bl). Keep dividing till the rectangles in all leafs of the tree are of of width < epsilon (a given number >0). Some guidance: - Use recursion and write some auxiliary function. - Use the following data structures: . for rectangles use lists of the form [al, ar, bl, br] . for nodes in the tree use lists of the form [rectangle, left_node, right_node] where left_node and right_node are nodes again, or empty lists. For nodes that are leafs, use [rectangle, [], []] . Put another way: if 'node' is a node, then node[0] is a rectangle, i.e., of the form [al, ar, bl, br] node[1] is a node or [] node[2] is a node or [] - Auxiliary functions: def width(rect): # Returns the larger of the two widths of the rectangle. def divide(rect): # Returns a list containing two rectangles that subdivide "rect"; # the subdivision is on the larger of the two sides; # the function should import "uniform" from "random". def descend_recursively(node, eps): # This is a recursive function that returns doing nothing # if the rectangle "node[0]" has width < eps. # Oherwise the function calls "divide(node[0])" # to obtain two subdividing rectangles. # The function then sticks leaf nodes in "node[1]" and "node[2]" # with left and right subdividing rectangle, respectively. # Finally, the function calls itself on "node[1]" and "node[2]". # This function relies heavily on passing "node" by reference. # Intended use: tree = [[0.,1.,0.,1.], [], []] # Initialize a tree with a root node; rectangle = unit square. descend_recursively(tree, 0.5) # Keep "eps" large for starters. tree # This is not very readable, but it is good enough to check whether # the rectangles have indeed sides shorter than 0.5 # Now check whether the following function works on your tree: def descend_point(node, coord): def is_in_rect(rect, coord): return(rect[0] <= coord[0] < rect[1] and rect[2] <= coord[1] < rect[3]) rect = node[0] if not is_in_rect(rect, coord): return("not in rectangle") elif node[1] == []: # need to check only one daughter node return(rect) else: node_left = node[1] node_right = node[2] rect_left = node_left[0] rect_right = node_right[0] if is_in_rect(rect_left, coord): rect_leaf = descend_point(node[1], coord) if is_in_rect(rect_right, coord): rect_leaf = descend_point(node[2], coord) return(rect_leaf) # Figure out what the function "descend_point" does. # Add detailed comments to its code. # Here are two examples of its intended use: descend_point(tree, [.2,.1]) descend_point(tree, [-.2,.1])