How can I calculate all possible combinations between a specific ratio range?

341 Views Asked by At

Not sure this is the right wording for this sort of problem, but let me explain by context.

Instagram displays specific image ratios when posted to a feed. These ratios are:

1:1 (square)

1.91:1 (landscape/horizontal)

4:5 (portrait/vertical)

On the company's help forum, they also state:

[...] the photo's aspect ratio is between 1.91:1 and 4:5 [...]

This specific wording makes it seem like there are other acceptable image proportions in their platform. What I want to do is test this hypothesis by posting other aspect rations that lie between 1.91:1 and 4:5. I know for a fact that 3:2-sized images works.

Is there a formula, trick or correct way to calculate or generate all possible whole values between these two ratios?

1

There are 1 best solutions below

0
On

You can produce the desired sequence of ratios using a Farey sequence:

the Farey sequence of order $n$ is the sequence of completely reduced fractions, either between 0 and 1, or without this restriction, which when in lowest terms have denominators less than or equal to $n$, arranged in order of increasing size.

That article shows a simple algorithm to produce the next term of the Farey sequence of order $n$ from the previous two terms. That algorithm starts at $0/1$, but we can adapt it to start from $4/5$.

One important property of any Farey sequence is that given two adjacent terms $a/b, c/d$ (with $a/b < c/d$), then $c/d - a/b = 1 / bd$. We can use that to find the next term after $4/5$.

Let $a/b = 4/5$. Thus $$c/d - 4/5 = 1/5d$$ $$5c - 4d = 1$$

Now, for any $t$, $$5(1+4t) - 4(1+5t) = 1$$ So we can set $$c=1+4t$$ $$d=1+5t$$ for some suitable $t$. It can be shown that the resulting $c, d$ are coprime, so $c/d$ is a fraction in lowest terms.

We choose $t$ such that the resulting $d$ is as large as possible with $d\le n$. That is, $$d = 1+5t \le n$$ So $$t=\lfloor(n-1)/5\rfloor$$


Here's some Python code (derived from the Wikipedia example) which implements this algorithm. It uses a Sage feature to read the input parameter $n$, but it can be easily adapted to use the standard Python procedures for getting input data.

# Partial Farey sequence. PM 2Ring 2021.09.15
# See https://math.stackexchange.com/q/4250558/207316
@interact
def main(n=12):
    n = int(n)

    # Minimum aspect ratio
    a, b = 4, 5

    # Second term
    t = (n - 1) // 5
    c, d = 4 * t + 1, 5 * t + 1

    while True:
        r = c / d
        print(f"{c:2} / {d:2} = {r:.4}")
        if r >= 1.91:
            break
        # Next term
        k = (n + b) // d
        a, b, c, d = c, d, k * c - a, k * d - b

Here's the output for $n=12$:

 9 / 11 = 0.8182
 5 /  6 = 0.8333
 6 /  7 = 0.8571
 7 /  8 = 0.875
 8 /  9 = 0.8889
 9 / 10 = 0.9
10 / 11 = 0.9091
11 / 12 = 0.9167
 1 /  1 = 1.0
13 / 12 = 1.083
12 / 11 = 1.091
11 / 10 = 1.1
10 /  9 = 1.111
 9 /  8 = 1.125
 8 /  7 = 1.143
 7 /  6 = 1.167
13 / 11 = 1.182
 6 /  5 = 1.2
11 /  9 = 1.222
 5 /  4 = 1.25
14 / 11 = 1.273
 9 /  7 = 1.286
13 / 10 = 1.3
 4 /  3 = 1.333
15 / 11 = 1.364
11 /  8 = 1.375
 7 /  5 = 1.4
17 / 12 = 1.417
10 /  7 = 1.429
13 /  9 = 1.444
16 / 11 = 1.455
 3 /  2 = 1.5
17 / 11 = 1.545
14 /  9 = 1.556
11 /  7 = 1.571
19 / 12 = 1.583
 8 /  5 = 1.6
13 /  8 = 1.625
18 / 11 = 1.636
 5 /  3 = 1.667
17 / 10 = 1.7
12 /  7 = 1.714
19 / 11 = 1.727
 7 /  4 = 1.75
16 /  9 = 1.778
 9 /  5 = 1.8
20 / 11 = 1.818
11 /  6 = 1.833
13 /  7 = 1.857
15 /  8 = 1.875
17 /  9 = 1.889
19 / 10 = 1.9
21 / 11 = 1.909
23 / 12 = 1.917

And here's a link to a live version of the script, which runs on the SageMathCell server.