# Simple implementation of a multi-part ratio data structure

A multi-part ratio would be an expression of the form:

$e_1:e_2:e_3:\cdots:e_n$

It would have the following properties:

1. When the expressions are natural nos, they can be evaluated to be $$\frac{e_1}{gcd(e_1,e_2,...,e_n)}:\frac{e_2}{gcd(e_1,e_2,...,e_n)}:\cdots:\frac{e_n}{gcd(e_1,e_2,...,e_n)}$$
2. Two ratios (say, $e_1:e_2:e_3$ and $u_1:u_2:u_3$) will be equal iff $e_i=k*u_i \;\forall i$ for some fixed k.

There is no direct implementation of this type available in Mathematica to my knowledge, but I think it would be nice to have one (perhaps in terms of lists).

• Is continued ratio just simply one ratio repeated several times? Why would you need to express it explicitly? – swish Mar 5 '18 at 19:41
• If e and u are lists of real numbers like {e1,e2,e3} and {u1,u2,u3} you can check the equality of ratios e1:e2:e3 and u1:u2:u3 with the test Abs@Dot[e,u]==Norm[e]*Norm[u]. This will avoid potential divide-by-zero errors to which existing answers are prone. – LLlAMnYP Mar 6 '18 at 11:51
• No. It is something like 20:30:60:100:1000 such that one doesn't care about the explicit values of the elements as long as a new set of values is a common multiple of the old set. – Subho Mar 6 '18 at 11:53
• I am looking for a an implementation that will allow one to store a set of expressions in this continued fraction form so that one can have equations like f(x):g(x):h(x)==5:6:j(x) which would mean f(x)/g(x)==5/6, g(x)/h(x)=6/j(x). This sort of information can be thus nicely packaged into continued ratio notation. – Subho Mar 6 '18 at 11:58

Updated to work in M10.1

One idea is to use FactorList to generate the factors of the expressions, and then remove common factors. The nice thing about this approach is that the output will be normalized, so that one can use Equal to compare the ratio lists. One refinement is to post-process the output of FactorList so that integers get factored as well. Here is some code to do this:

factor[p_] := Association @* Map[Apply[Rule]] @ Replace[
FactorList[p],
{
{1,1} -> Sequence[],
{n_Integer, 1} :> Sequence @@ FactorInteger[n],
{n_Integer, -1} :> Sequence @@ FactorInteger[1/n]
},
{1}
]

Clear[Colon]
Colon[p__] := Module[{ku, res, diff},
ku = KeyUnion[factor /@ {p}, 0&];
res = Merge[ku, Min];
diff = # - res& /@ ku;
Apply[Colon] @ Map[Apply[Times] @* KeyValueMap[Power]] @ diff /;
MinMax[res] != {0, 0}
]


A couple examples:

Colon[20, 30, 60, 100, 1000] //TeXForm


$2:3:6:10:100$

Colon[24 x (2y+y^2+1), 36/z (y+1)] //TeXForm


$2 x (y+1) z:3$

• Sorry, when I execute this code, I am getting errors, saying that the arguments of the association are incompatible – Subho Mar 7 '18 at 4:39
• @SubhobrataChatterjee You probably are using an older M build. I updated things to work in M10.1. – Carl Woll Mar 7 '18 at 5:12
• Thanks. It worked this time. This is really nice! – Subho Mar 7 '18 at 7:54
mytest[a_List, b_List] := Equal @@ MapThread[Divide, {a, b}];

a = {3, 4, 5};
b = {6, 8, 10};

mytest[a,b]


True

b = {6, 9, 10};

mytest[a,b]


False

You might find this useful:

myratiomaker[start_, factor_, numberofelements_Integer] :=
StringJoin @@
Riffle[ToString /@
FixedPointList[factor # &, start, numberofelements], ":"]


So:

myratiomaker[6, .5, 4]


(*

"6:3.:1.5:0.75:0.375"

*)

• I think OP askes for data structure for continued proportions, which is something like 1:3:9:27:81, i.e. all ratios are the same. – swish Mar 5 '18 at 19:40
• "...but I think it would be nice to have one(perhaps in terms of lists)." – David G. Stork Mar 5 '18 at 21:02
• What I mean is that neither {3,4,5} or {6,8,10} in your example is a continued ratio. – swish Mar 5 '18 at 22:00

I imagine it would be useful for providing equality between ratios to Solve or FindInstance maybe. You can define \[Colon] operator to construct such equality for you:

Colon[a___] := Equal @@ Divide @@@ Partition[{a}, 2, 1]


And then

FindInstance[(a \[Colon] b \[Colon] c) && (0 < a < b < c), {a, b, c}, Integers, 2]