From 6a38ca47ce403094c0fea829e306e78831bfd440 Mon Sep 17 00:00:00 2001 From: Pim Nelissen Date: Fri, 17 Oct 2025 19:29:12 +0200 Subject: [PATCH] minimal code for part 1. --- Link.py | 11 +++++++++++ RubberBand.py | 35 +++++++++++++++++++++++++++++++++++ main.py | 23 +++++++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 Link.py create mode 100644 RubberBand.py create mode 100644 main.py diff --git a/Link.py b/Link.py new file mode 100644 index 0000000..f7f7274 --- /dev/null +++ b/Link.py @@ -0,0 +1,11 @@ +class Link: + def __init__(self, direction): + """ + An incompressible link of fixed length a and either a positive or + negative direction. + + Parameters: + direction (int) The direction. Must be 1 or -1. + """ + + self.direction = direction diff --git a/RubberBand.py b/RubberBand.py new file mode 100644 index 0000000..4fa61f6 --- /dev/null +++ b/RubberBand.py @@ -0,0 +1,35 @@ +import numpy as np + +from Link import Link + +class RubberBand: + def __init__(self, N, a=1.): + """ + RubberBand is a class that can simulate a rubber band with N + incompressible links of length a. + + Parameters: + N (int) The number of links. + a (float) The fixed length of links. + """ + + self.N = N + self.a = a + self.links = self.__sample_links() + + @property + def length(self): + return self.a * np.sum([l.direction for l in self.links]) + + def __sample_links(self): + """ + Sample N Link objects with a random direction. + """ + + samples = np.random.random_sample((self.N,)) + directions = np.ones(samples.shape) + directions[samples < 0.5] = -1. + directions = directions.astype(int) + return [Link(d) for d in directions] + + diff --git a/main.py b/main.py new file mode 100644 index 0000000..40be257 --- /dev/null +++ b/main.py @@ -0,0 +1,23 @@ +import numpy as np +import scipy as scp + +from matplotlib import pyplot as plt + +from RubberBand import RubberBand + +NUM_BANDS = int(1E5) +N = 100 + +length_dist = np.zeros((NUM_BANDS,)) +for i in range(NUM_BANDS): + band = RubberBand(N, a=1) + length_dist[i] = band.length/band.a + +P_true = lambda N, L: scp.special.binom(N, (L+N)/2) / 2**N +L_norm = np.linspace(-N, N, 100) # normalised (no Link length a) range + +plt.plot(L_norm, P_true(N, L_norm)) +plt.hist(length_dist, range=(-N, N), bins=N, density=True) +plt.xlabel("$L/a$") +plt.ylabel("P($L/a$)") +plt.show()