Computation Contest #3 Results and Solution

in #programming3 years ago

Solution

The problem of this contest was to solve the differential equation for the pendulum numerically:
Screenshot from 2019-10-27 20-41-05.png

I implemented an example solution in java which also plots a graph of the angle of the pendulum for the both solutions:

import javax.swing.JFrame;
import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;

public class main extends JFrame {
    ArrayList<Double> valuesToGraph = new ArrayList<>();
    public static int num = 0;
    public main(double c, boolean visible) {
        this.c = c;
        num = 0;
        setSize(1600, 800);
        setUndecorated(true);
        setVisible(visible);
        
        long t0 = System.currentTimeMillis() + 20;
        while(running) {
            try{Thread.sleep(t0 - System.currentTimeMillis());} catch(Exception e) {e.printStackTrace();}
            t0 += 20;
            update();
        }
        // Make sure not to waste resources on not visible frames.
        if(!visible)
            dispose();
        else {
            for(int i = valuesToGraph.size(); i < 1600; i++) {
                update(); // Make sure to draw the full image.
            }
            repaint();
        }
    }
    double dt = 0.0001;
    double phi = 0;
    double omega = 2*Math.PI;
    double c;
    double g = 9.80665;
    double l = 1;
    boolean running = true;
    public void update() {
        for(int i = 0; i < 100; i++) {
            // Perform one iteration of the Differential Equation
            double alpha = -c*omega - g/l*Math.sin(phi);
            omega += alpha*dt;
            phi += omega*dt;
            // Make sure phi stays within ±π to make the graph look better:
            if(phi > Math.PI) {
                phi -= Math.PI*2;
                num++;
            }
            if(phi < -Math.PI) {
                phi += Math.PI*2;
                num++;
            }
            
            // Stop the program when the pendulum changes direction:
            if(omega < 0) {
                running = false;
            }
        }
        valuesToGraph.add(phi); // Only add every 100th value to the output.
    }
    public void paint(Graphics gr) {
        // Paint it:
        gr.fillRect(0, 0, 1600, 800);
        gr.setColor(Color.WHITE);
        for(int i = 1; i < valuesToGraph.size(); i++) {
            gr.drawLine(i-1, 400-(int)(valuesToGraph.get(i-1)*400/Math.PI), i, 400-(int)(valuesToGraph.get(i)*400/Math.PI));
        }
    }

    public static void main(String[] args) {
        double c0 = 0.01;
        new main(c0, true);
        System.out.println("Number of swings around = " + num);
        if(num == 3)
            System.out.println("c₁ = " + c0); // A solution is already found.
        if(num < 3) { // Slowly reduce c:
            while(num != 3) {
                c0 *= 0.9;
                new main(c0, false);
            }
            new main(c0, true);
            System.out.println("c₁ = " + c0);
        }
        if(num > 3) { // Slowly increase c:
            while(num != 3) {
                c0 *= 1.1;
                new main(c0, false);
            }
            new main(c0, true);
            System.out.println("c₁ = " + c0);
        }
    }
}

This prints out:

Number of swings around = 3
c₁ = 0.0018530201888518425

And plots the graph of the angle mod 2π, so a straight line means it swings once around the top(top → c = c₀, bottom → c = c₁):
Screenshot from 2019-11-08 22-30-41.pngScreenshot from 2019-11-08 22-30-55.png

This code prints the result 14.1332 which is not perfectly accurate even though I used 1000000 iterations in the final run.

↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓

List of participants with their entries:

NameSolution found
@kaeserotor0 and 0.00146484375Both are correct assuming g = 9.81 ms⁻² instead of the value I used above.

↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓

Winners:

Congratulations @kaeserotor. You won 6 SBI due to lack of competition!

↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓↑↓

The next contest starts in 2 days. Don't miss it!