Showing posts with label Numpy. Show all posts
Showing posts with label Numpy. Show all posts

Saturday, 29 March 2025

Smooth Versus Jagged

I need to make more use of AI in my blog posts and to this end I wanted to replace the jagged lines in Figure 3 of my previous post with one continuous smooth line. The graph in question looked as shown in Figure 1 below:


Figure 1

The data being plotted were the numbers from 395 to 425 and their corresponing sigma values:

[(395, 480), (396, 1092), (397, 398), (398, 600), (399, 640), (400, 961), (401, 402), (402, 816), (403, 448), (404, 714), (405, 726), (406, 720), (407, 456), (408, 1080), (409, 410), (410, 756), (411, 552), (412, 728), (413, 480), (414, 936), (415, 504), (416, 882), (417, 560), (418, 720), (419, 420), (420, 1344), (421, 422), (422, 636), (423, 624), (424, 810), (425, 558)]

I asked Google Gemini to put a smooth curve through these points and Figure 2 shows what it came up with when I pasted the code into SageMathCell.


Figure 2: permalink

This is a satisfying output and is just an alternative way to display the data. There may well be a way to implement this using SageMath code alone but this approach using Python was quick and easy. It also creates a title and legends for the point and curve. I can use this code in future when needed. Here is the code that Gemini created:

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import CubicSpline

data = [(395, 480), (396, 1092), (397, 398), (398, 600), (399, 640), (400, 961), (401, 402), (402, 816), (403, 448), (404, 714), (405, 726), (406, 720), (407, 456), (408, 1080), (409, 410), (410, 756), (411, 552), (412, 728), (413, 480), (414, 936), (415, 504), (416, 882), (417, 560), (418, 720), (419, 420), (420, 1344), (421, 422), (422, 636), (423, 624), (424, 810), (425, 558)]

# Extract x and y values
x = [point[0] for point in data]
y = [point[1] for point in data]

# Create a cubic spline interpolation
cs = CubicSpline(x, y)

# Generate smoother x values for plotting the curve
x_smooth = np.linspace(min(x), max(x), 500)  # Adjust 500 for more/less smoothness
y_smooth = cs(x_smooth)

# Plot the original points and the smooth curve
plt.figure(figsize=(10, 6))
plt.plot(x, y, 'o', label='Original Points')
plt.plot(x_smooth, y_smooth, '-', label='Smooth Curve (Cubic Spline)')
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Smooth Curve Through Points')
plt.legend()
plt.grid(True)
plt.show()

Of course, Gemini provides a full explanation of the code that it created:

Explanation:

  1. Import Libraries:
    • numpy for numerical operations (especially for generating smoother x-values).
    • matplotlib.pyplot for plotting the graph.
    • scipy.interpolate.CubicSpline for creating the smooth curve.

  2. Extract Data: The x and y values are extracted from the data list into separate lists.

  3. Cubic Spline Interpolation:
    • CubicSpline(x, y) creates a cubic spline object that represents the smooth curve passing through the given data points. Cubic splines are chosen as they offer a good balance between smoothness and accuracy.

  4. Generate Smooth x-Values:
    • np.linspace(min(x), max(x), 500) creates an array of 500 evenly spaced x-values between the minimum and maximum x-values of the original data. This is used to generate a smoother curve for plotting. Adjust the 500 for a curve with more or less detail.

  5. Calculate Smooth y-Values:
    • cs(x_smooth) calculates the corresponding y-values for the smoother x-values using the cubic spline interpolation.

  6. Plotting:
    • plt.plot(x, y, 'o', label='Original Points') plots the original data points as circles.
    • plt.plot(x_smooth, y_smooth, '-', label='Smooth Curve (Cubic Spline)') plots the smooth curve.
    • The rest of the code sets up the plot's labels, title, legend, and grid.
    • plt.show() displays the plot.

  7. How to Run:
    • Make sure you have numpy, matplotlib, and scipy installed (pip install numpy matplotlib scipy).
    • Save the code as a Python file (e.g., smooth_curve.py).
    • Run the file from your terminal: python smooth_curve.py.

Wednesday, 10 April 2024

Dartboard Totals


I've only made one post about darts and dartboards and that was Measuring Dartsmanship on Wednesday 24th of January 2024. In this post, I want to quantify the number the of ways in which a certain total can be achieved using one, two or three darts. To this end, I developed a program in SageMath to do the job and at first glance it worked fine. Figure 1 shows the code using 75 as sample input (permalink).

Figure 1

The output is shown below (there are 194 possible ways of achieving a total of 75):

[[1, 14, 60], [1, 17, 57], [1, 20, 54], [1, 26, 48], [1, 34, 40], [1, 36, 38], [1, 42, 32], [2, 13, 60], [2, 16, 57], [2, 22, 51], [2, 28, 45], [2, 33, 40], [2, 39, 34], [2, 54, 19], [3, 12, 60], [3, 15, 57], [3, 18, 54], [3, 21, 51], [3, 24, 48], [3, 27, 45], [3, 30, 42], [3, 32, 40], [3, 33, 39], [3, 34, 38], [3, 36, 36], [4, 11, 60], [4, 14, 57], [4, 17, 54], [4, 20, 51], [4, 26, 45], [4, 33, 38], [4, 39, 32], [5, 10, 60], [5, 13, 57], [5, 16, 54], [5, 22, 48], [5, 28, 42], [5, 30, 40], [5, 32, 38], [5, 36, 34], [5, 51, 19], [6, 9, 60], [6, 12, 57], [6, 15, 54], [6, 18, 51], [6, 21, 48], [6, 24, 45], [6, 27, 42], [6, 30, 39], [6, 33, 36], [7, 11, 57], [7, 14, 54], [7, 17, 51], [7, 20, 48], [7, 26, 42], [7, 28, 40], [7, 30, 38], [7, 34, 34], [7, 36, 32], [8, 7, 60], [8, 10, 57], [8, 13, 54], [8, 16, 51], [8, 22, 45], [8, 27, 40], [8, 33, 34], [8, 39, 28], [8, 48, 19], [9, 9, 57], [9, 12, 54], [9, 15, 51], [9, 18, 48], [9, 21, 45], [9, 24, 42], [9, 26, 40], [9, 27, 39], [9, 28, 38], [9, 30, 36], [9, 32, 34], [9, 33, 33], [10, 11, 54], [10, 14, 51], [10, 20, 45], [10, 26, 39], [10, 27, 38], [10, 33, 32], [10, 48, 17], [11, 13, 51], [11, 22, 42], [11, 26, 38], [11, 32, 32], [11, 36, 28], [11, 45, 19], [12, 12, 51], [12, 15, 48], [12, 18, 45], [12, 21, 42], [12, 24, 39], [12, 27, 36], [12, 30, 33], [13, 28, 34], [13, 45, 17], [14, 13, 48], [14, 16, 45], [14, 21, 40], [14, 22, 39], [14, 27, 34], [14, 33, 28], [14, 42, 19], [15, 15, 45], [15, 18, 42], [15, 20, 40], [15, 21, 39], [15, 22, 38], [15, 24, 36], [15, 26, 34], [15, 27, 33], [15, 28, 32], [15, 30, 30], [15, 60], [16, 11, 48], [16, 19, 40], [16, 20, 39], [16, 27, 32], [16, 33, 26], [16, 42, 17], [18, 17, 40], [18, 18, 39], [18, 19, 38], [18, 21, 36], [18, 24, 33], [18, 27, 30], [18, 57], [20, 13, 42], [20, 17, 38], [20, 22, 33], [20, 36, 19], [21, 16, 38], [21, 20, 34], [21, 21, 33], [21, 22, 32], [21, 24, 30], [21, 26, 28], [21, 27, 27], [21, 54], [22, 13, 40], [22, 34, 19], [22, 36, 17], [24, 11, 40], [24, 13, 38], [24, 17, 34], [24, 24, 27], [24, 32, 19], [24, 51], [25, 2, 48], [25, 5, 45], [25, 8, 42], [25, 10, 40], [25, 11, 39], [25, 12, 38], [25, 14, 36], [25, 16, 34], [25, 18, 32], [25, 20, 30], [25, 22, 28], [25, 24, 26], [25, 25, 25], [25, 33, 17], [25, 50], [26, 32, 17], [27, 20, 28], [27, 22, 26], [27, 48], [28, 28, 19], [30, 11, 34], [30, 13, 32], [30, 26, 19], [30, 28, 17], [30, 45], [33, 42], [36, 13, 26], [36, 39], [39, 17, 19], [50, 1, 24], [50, 3, 22], [50, 4, 21], [50, 5, 20], [50, 6, 19], [50, 8, 17], [50, 9, 16], [50, 10, 15], [50, 12, 13], [50, 14, 11], [50, 18, 7]]

194

However, using 48 as a total produces an error message as shown in Figure 2.


Figure 2

I don't understand why sum(c) works when the target is 75 but it doesn't work when the target is 48. However, I found that it would work if I made the total 49 and altered the code from "if target = sum(c)" to "if target - 1 = sum(c)". Weird, right. The program works for 23, 29, 31, 35, 37, 41, 43, 44, 46, 47, 49, 52 and does better as the totals get larger. I can't see any obvious pattern to the misfires.

I imported Numpy and used its sum() function but that didn't work either. The same with Pandas. I put Google's Gemini to work on the problem using this prompt:

This SageMath code works for some numbers e.g. 49 but not for other numbers such as 48. When I use 48 as input, I get the following error message: unsupported operand parent(s) for +: 'Integer Ring' and '<class 'list'>'. The error location is sum(c) but I can't determine what the problem is as I don't understand the error message. 

Gemini was confident that it had identified the problem and even proposed a solution but that proved to be nonsense even though appearing plausible at first glance. I'll have to leave it there and if I do discover the source of the problem I'll discuss it here. Link to Airtable record.