There exists no equation for the perimeter of an ellipse (excluding infinite series). This project uses gradient descent to find an approximate equation of the form area = pi * (wa + vb - sqrt(xa^2 + yab + zb^2))
where w,v,x,y,z
are the weights generated in this project.
A full example of running and finding an equation can be seen in main.cpp
, although most of the necessary code is repeated in the instructions below.
To simply run the equation using the default equation, use the method ellipse_perimeter
:
std::cout << "Perimeter of ellipse with radii 3 and 2 using default equation: " << ellipse_perimeter(3, 2);
To run the gradient descent algorithm in order to try and find a better equation, use the gradient_descent
method. You will need to pass in a std::vector<long double>
object to write the results to.
For example,
//initialise all weights to a random integer between 1 and 100 inclusive
std::vector<long double> weights;
srand(0);
for (int i = 0; i < 5; i++) {
long double r = rand() % 100 + 1;
weights.push_back(r);
}
//run gradient descent
gradient_descent(&weights);
There are also a number of optional arguments to gradient_descent
.
In this order, they are:
bool show_results
- Whether to print the results of the algorithm, defaults tofalse
int iterations
- The number of iterations to run through, defaults to1000
double learning_rate
- The learning rate to use (affects how far to adjust the weights each iteration), defaults to0.01
double learning_rate_modifier
- How much to decreaselearning_rate
by after each iteration, e.g0.99
decreaseslearning_rate
by 1% each iteration. Can help to avoid local minima, defaults to1
double min_learning_rate
- The minimum value forlearning_rate
, used to stoplearning_rate_modifier
from decreasinglearning_rate
too far, defaults to0
For example, the parameters used to generate the default are as follows:
gradient_descent(&weights, true, 1000000, 0.023, 0.9995, 0.001);
Once you have generated new weights with gradient_descent
, you can run the equation using them as follows:
std::cout << "Perimeter of ellipse with radii 3 and 2 using default equation: " << ellipse_perimeter(3, 2, &weights);
- More accurate approximations exist than the one found in this project, and can be found here.
ellipse_lengths.csv
is a slightly modified version of an list of true perimeter lengths by radii ratios created by Matt Parker. You can find the original version here.