Wednesday, November 11, 2020

How I used Java to Calculate Riemann Sums

I was looking through my Github projects from last year and I stumbled across a program I started writing when I was first learning Java. It’s goal was to approximate the area under the quadratic equation f(x) =x^2 by summing the area of an arbitrary number of rectangles that fit under the curve between two points; this method for calculating the area is called a Riemann Sum. 


I was taking a Calculus 1 at the time and wanted to try my hand at simulating it in Java. 


Just doing some basic testing on my original file I got these results:




For these parameters it seems like my code is working well. 


However when I try different ranges the answer became wildly wrong



This cannot be the case since there is less area between [2,10] than between [0,10].


I started looking at the code and boy was it a mess. There was only one class file that had all the methods. I think I was trying to express it as a combination of negative areas and positive areas. 



I think I was trying to create an array of the base of each of the rectangles.  



I ran into some problems since this was overly complicated and I was pretty sure there was a simpler way to do it. 


In the year since I started this project I’ve learned a lot more about how to get rid of code smells and generally write cleaner code. So I gave myself a couple of goals and branched the repository on GitHub. You can see the repository here.


  1. Make sure that the answers are correct

  2. Refactor the code into more methods so that each method does one thing and that one thing well. 

  3. Use an organizational structure to make the code more modular 

    1. Right now all of the methods are in a single java file that also has main() in it.

    2. I can move several of the different methods to other classes so that it is easier to understand. 

  4. Add a feature that uses the simplified integral to determine the true area and compare it to my approximation.


Remember that the area under a curve is:


If you want a more visual appreciation for Riemann Sums Wolfram Alpha has a nice demonstration of the concept. 


You can solve the integral to get:



Where a is the starting point and b is the end point.


As a roadmap I planned on breaking up the code into the following classes:


  1. A class to do the math.

    1. This would need to calculate the xValues, yValues, width, area approximation and true area. 

  2. A class to get the parameters from the user.

  3. A Main() to stitch everything together.


I first started working on a class to do the math. 


Instead of trying to calculate how many rectangles should be on the negative side of the x axis and expressing it as a sum of those products it seemed easier to code (and more intuitive) to 

create an array of X values and an array of Y values. 



I decided that each rectangle would have its top left corner be on the line. 


That would make the array look like:

 [start, start +1* width, start + 2*width ... start + numberOfRectangles*width]


From this I can take each of those X values and plug them into f(X) to get the associated Y value, which is the height of each rectangle. 



Now I have an array of Y Values where each is the height of a different rectangle. .  


The width of each rectangle is the total distance between the start and end divided by the number of rectangles. 

 

Now to find the area simply add up the area of all those rectangles. 


I stitched it all together in the main like so



In the end I got a some sample run that looks like this:



Just like is expected as you use more rectangles the sum of their areas approaches the area under the curve. In practice, there is a limit to the preciseness since java is not built to handle an infinite number of anything, let alone infinite rectangles. 



It now works for negative values. Important to note here is that when you are summing areas of negative X values the area approaches from the positive side while on the right hand side they are approaching from the negative side. 


When part of the range is negative and part is positive it will approach from the positive side if more rectangles are on the left and from the negative side if more rectangles are on the right. 



To improve the organizational structure I separated the math functions, the user input functions and the main into different files.



You can see the whole project here under “RienmannSumCalculator”.






Saturday, November 7, 2020

How I Used Google Sheets to Build A Rotisserie Draft Simulator

Magic the Gathering is a popular collectible card game with a variety of different ways to play. "Drafting" is where players take turns picking cards to put in their deck from a common card pool. One popular variant is called a Rotisserie Draft. Unfortunately, I could not find any ways to Rotisserie Draft online with friends so I decided to create a tool to do that in google sheets.

Players Rotisserie Draft by taking turns publicly choosing a card from a cube. Cubes are carefully selected subsets of cards of similar power levels that are made to be drafted together. Typically cubes have 360, 450, or 540 cards.


The stipulation is that once a card has been chosen no other players can choose that card. You can read more about Rotisserie Drafting here.


The problem is that since each player ends up picking 45 cards it is hard to remember the cards that are still available to be picked and what cards have been picked already. Lucky for us, Google Sheets makes it easy to build a tool that keeps track of this automatically. Check out that tool here.


Here is how I built that tool.


First I downloaded the names of all the 540 cards from the Summer Vintage Cube. That is saved in a tab called “List” and a named range called “List”. Named ranges are useful here since I will be checking against the list of cards many times.


Next I made a tab called Two_Person_Draft where two players could track the cards they pick.

I used data validation to make sure that people are only picking cards in the list and are using the full name of the cards.




There also needs to be a check if the card has already been picked. 



By creating the “AlreadyPicked_TwoPerson” that is the range of  B:B and C:C I used the countif() function to see if that card exists. The countif(range, value) function returns an integer of the number of occurrences of a value in a range. For my purposes I only want to be notified if there are 2 or more occurrences since there is no problem if a card has been picked once or not at all. 



Some simple conditional formatting to make it clear that a card has been picked already. I used these rules. 


Now, when a card is being picked twice it will say FALSE



Once I had the 2 player draft set up it was simple to duplicate the system for 4 and 8 player drafts. 


 



This is a convenient way to Rotisserie draft with friends online since you both don't need to be in the same room. After you finish drafting you can export the list to a deck editor to finalize your deck and add basic lands. 


Data Viz and Analysis of the Numerai Leaderboard

There is a protocol built on Ethereum called Numerai. They explain it in more detail on their website but in essence it is a way for anyone...