Wolfram Cloud – functions, do iteration, if and lists

Iwas reading about group theory recently, for basic cryptography, and wanted a function for computing the set \mathbb{Z}^*_n   , i.e. the set of integers with greatest common divisor (gcd) with n equal to 1 , formally \mathbb{Z}^*_n = \{a \in \mathbb{Z}_n | gcd(a,n)=1\}  .

And I wanted to do it “quickly”, in a math engine, so what better place than on Wolfram’s Development Platform!

It’s not rocket science how to compute the set, but I thought this’d serve as a nice reference, with examples, to basic operations in the Wolfram Language on the Wolfram Cloud.

I needed to be able to check the gcd between numbers, this is built in as GCD, example

in: GCD[4,6];
out: 2

Checking from 1..n-1 is tedious however, where Do comes in handy. Do[ expr, { var, limit } ], loops var from 1 to limit (inclusive), example

In: Do[GCD[n,6], {n,6}];
Out: // nothing's output as Do just performs the calculation.

Time for Print[expr]! Example

In: Do[Print[GCD[n,6]], {n,6}];
Out: 1
  2
  3
  2
  1
  6

But this is badly formatted, and also it includes the check of gcd(6,6), and it has a hardcoded variable. First, into a function, example

In: f[x_] := 42 + x;
  f[2];
Out: 44

Calculates the answer to life, the universe and everything, plus x, i.e. 2. Our function looks like, (variable factored out, removed gcd(n,n) check with g-1)

In: CalcSet[g_]:= Do[Print[GCD[n,g]], {n,g-1}]; 
  CalcSet[6];
Out: 1
    2
    3
    2
    1
    6

Still badly formatted, and actually it doesn’t output the set, just a list of tests where it prints the restult of GCD; enter If. If[ expr, t, f], where t is evaluated if expr is true, and f is an optional expression, evaluated if expr evaluates to false. (If no f is provided, and the If is used in something bigger, say a list, it’ll return null). Start small:

In: If[ 1==1, Print["true"], Print["false"]]; (* prints "true" *)
  If[ 1==2, Print["true"], Print["false"]]; (* prints "false" *)
  If[ 1==2, Print["true"]];(* does nothing *)
  If[ 1==1, Print["true"]];  (* prints "true" *)
Out: "true"
  "false"
  "true"

Redefine function with the If-condition

In: CalcSet[g_]:= Do[If[GCD[n,g] == 1, Print[n]], {n,g}];
  CalcSet[6];
Out: 1
    5

I love it, I can compute the set! Still it isn’t very nicely formatted; I want it in a list. So I need a list, and the AppendTo function,

In: l = {1, 2};
  AppendTo[l, 3];
  Print[l];
out: {1, 2, 3}

Putting it all together in a ()-clause, extracting the Print I get the final code:

In: GenSet[g_]:= (
  l={};
  Do[If[GCD[n,g] == 1, AppendTo[l,n]], {n,g-1}];
  Return[l];
);
  Print[GenSet[6]];
Out: {1, 5}
  Print[GenSet[5]];
Out: {1, 2, 3, 4}
  Print[GenSet[10]];
Out:  {1, 3. 7, 9}

This could probably be optimized further by adding 1 to the initial set, and skip the first check, like below (Do with a { var, start, end }-constraint),

In: GenSetOptimized[g_]:= (
  l={1};
  Do[If[GCD[n,g] == 1, AppendTo[l,n]], {n,2,g-1}];
  Return[l];
);
  Print[GenSetOptimized[6]];
Out: {1, 5}

But it’s not a race!!.. I wonder if this can be done with a map somehow, in a sane way. In my head it doesn’t seem faster(, or less involved!)

Also, I totally know that I’m cheating by not calculating gcd(n,n), but I made the clever observation that it’ll never be 1 unless n is 1 (I’ll leave it up to the reader to prove this.) The function doesn’t work for generating \mathbb{Z}^*_1  either; suppose we’ll have to wonder for eternity what the result of this is.

Edit: lol wait, it actually does work in the optimized version, since it adds 1 to the set initially and just skips the Do-loop. I totally knew this; which is why I made the optimized version, I promise.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.