General remarks first, applicable to all assignments. Please include your thoroughly documented/commented code and description of methods and results in a Jupyter notebook submitted via Quercus to TA Fergus H. Every important line needs to be commented to show that you correctly understand the algorithm (do not comment "z gets multiplied by y". We can read that. We what to know why. Most assignments have analytical solutions. You are not required to find them, but if you do, then the benefits of finding an alternative to numerical method are fairly obvious, so we do encourage looking for independent corroboration for your numerical results. DEADLINE: 8 OCTOBER 2019 in the evening Problem 1 - Ancient Egypt _________________________ You are the tax collector in ancient Egypt The villages under your control house 12000 taxpaying persons. In a given year, the earnings are uniformly distributed between x = 1200 cups of grain per year and x=2400 c.o.g./yr. (Those two numbers are smallest and largest earnings, and all values inbetween are present, as if generated by numpy.linspace() function that did not yet exist then :] The taxpayers are progressively taxed but have some tax breaks. Everybody pays (6%)*(1+x/1000) tax to Pharaoh, unless he/she is employed at the building of the Pyramid (one quarter of them are). Pharaoh does not tax public workers. You, the tax collector can pocket additional tax of 1.5% of the villager's earnings (after-Pharaoh tax has been deducted), but if their birthday falls within one lunar month, before or after, your birthday (there are 13 lunar months per year), then they get a tax break of 0.8% and pay only 0.7% to you. Everybody's taxes are rounded down to the nearest 1 c.o.g. How much revenue did you pocket, and how much tax did the Pharaoh's Treasury get from the villagers, last year? REMARK: Do not use random number generation in this problem - if you need to skip some taxpayers, use some simpler approach to skip the correct fraction of them. The scheme may not be unique! You can see how much the result changes when you do a somewhat different prescription of which people are designated as Pyramid builders or which have cetain birthdays. In this problem, high precision is not the aim, coding of an algorithm is! Problem 2 - Student loan ________________________ Your student loan is $36000 and the bank is currently applying a fixed +4.2% annual interest rate at the end of every month, i.e. +(4.2/12)% each month. For two full years, you'll pay $300 a month, but expect that afterwards you will be able to pay $380 per month. Payments cover monthly interest on loan, and the rest goes toward repaying your principal amount. After how many years and months will you repay the loan? Plot the amount of loan as a function of time (in months). For comparison, compute and overplot one alternative history, obtaind under a cautious assumption that the bank interest rate will go up to 5.2%/yr after 2 years, to 5.7%/yr after full 4 years from the present, and will later remain constant. Problem 3 - Scan of the grid ____________________________ On a uniform grid of 1000 x 1000 (x,y) values, find the minimum of function f(x,y) = 1 + 0.1*D*x - 4*sqrt(2)*x*y*exp(-x-y*y) over domain x=[0,3], y=[0.,3]. Print that minimum's location in (x,y) plane. D is the last digit of your UofT student number, which should be stated in the solution. Please time the execution of the program and print the time in seconds. Problem 4 - Random event processing ___________________________________ At completely random times, cosmic muons strike a muon counter in a physical experiment. Only those time intervals of unit length, in which two muons were recorded at t1 and t2, are analyzed. Q1: What is the probability that the two analyzed events are spaced by less than 1/2 of the unit time interval? Solve the problem by generating with NumPy a very large number 2N of pseudorandom times, uniformly covering interval [0,1). [It is more efficient to generate one or two large arrays of random numbers, for instance with: t1_and_t2 = np.random.rand(2*N) or with t1=np.random.random(N) etc., than to call these generating function 2N times with size of data equal 1. Function calls in this case take too much time.] Q2: Display the mean and the standard deviation of |t1-t2| in the format: <|t1-t2|> +- sigma_of_<|t2-t1|>; sigma_of |t2-t1|. Standard deviation of the mean is smaller by a factor sqrt(N) from the standard deviation of data items, read wiki on that subject if you forget what we discussed during lectures. Hint: Variance = square of std (standard deviation, or sigma**2). Let brackets denote averaging of y (in our case y = |t1-t2|). From the definition of standard deviation Variance = sigma**2 = <(y-)**2> = -<2y> +**2 = = -2**2 +**2 = - **2, which allows you to avoid two passes through data set, one to find and second to find sigma = <(y-)**2>. One can evaluate both and in the same, one pass, by introducing 2 partial sums (variables), to which contributions from consequtive data items are added in a loop. If you decide to use NumPy to get the sigma, think avbout which sigma is it, standard deviation of values around their mean, or the standard deviation of the mean value. They're different by a factor sqrt(N-1), as explained in exercise simple_stat.py on our code page.