5

I am interested in a function which would stop Mathematica reducing fraction.

If my input is 50/100, Mathematica outputs 1/2, I want it to output 50/100. Any nice function which does this?

I need this because I want to define a recursive function with this behavior:

f[0]=50/100
f[n_]:=(Numerator[f[n-1]]+1)/(Denominator[f[n-1]]+1)

I want to obtain f[1]=51/101, not f[1]=2/3, which I get.

A more complicated example:

f[0]=50/100
f[n_]:=If[Mod[n,2]==0,(Numerator[f[n-1]+1])/n,Numerator[f[n-1]/(Denominator[f[n-1]‌​]+1)

This gets really annoying if I store 50/100 as {50,100}.

ybeltukov
  • 43,673
  • 5
  • 108
  • 212
matti0006
  • 87
  • 1
  • 6
  • I need it because I am defining a recursive function, where I need the denominator and nominator of the previous element of the function. i.e. let's say my function is this:

    f[0]=50/100 f[n_]=Nominator[f[n-1]]+1/Denominator[f[n-1]]+1

    Then this is useless if mathematica reduces the fractions...

    EDIT: First time here, no clue how to make enters:P

    – matti0006 Sep 25 '13 at 19:53
  • 5
    How about storing f[0]={50,100}? (and there is an "edit" button right below your question, I think it would be nice to include the example) – Pinguin Dirk Sep 25 '13 at 19:55
  • That's a possibility, but it is slower than just not reducing the fraction I would say. It will probably work for what I am doing, but I would still like to know if there is a generic function to achieve this. – matti0006 Sep 25 '13 at 19:57
  • Did that! (10 characters) – matti0006 Sep 25 '13 at 20:00
  • Well yeah, this is just a quick thing I typed up, the thing I really want to do is a bit more complicated. Also HoldForm just keeps "Numerator" as a string. I'll edit my orginal post with brackets. – matti0006 Sep 25 '13 at 20:02
  • Sorry, I am in a bit of a hurry, but perhaps you can find the answer to your question in the notebook Basic Overriding.nb you find here http://library.wolfram.com/infocenter/MathSource/3336/ – Peltio Sep 25 '13 at 20:12
  • Man, already five minutes have passed? So, here's the rest: Basically, you should redefine the basic functions behind "/" (Times, Power, Rational) to execute custom code that won't simplify but will display like a fraction. But you'll probably be better off by defining a new function to use instead of any division. – Peltio Sep 25 '13 at 20:18

2 Answers2

3

Try this one

f[0] = HoldForm[50]/HoldForm[100];

f[n_] := HoldForm[#] &[ReleaseHold@Numerator[f[n - 1]] + 1]/
    HoldForm[#] &[ReleaseHold@Denominator[f[n - 1]] + 1];

f[5]

55/105

The second example

f2[0] = HoldForm[50]/HoldForm[100];

f2[n_] := 
 If[Mod[n, 2] == 0, 
  HoldForm[#] &[ReleaseHold@Numerator[f[n - 1]] + 1]/HoldForm[#] &[n],
   Numerator[f[n - 1]]/HoldForm[#] &[ReleaseHold@Denominator[f2[n - 1]] + 1]]

f2[1]

50/101


More elegant approach consists in the definition of your own irreducible Fraction

Fraction /: MakeBoxes[Fraction[n1_, n2_], StandardForm] := MakeBoxes@HoldForm[n1/n2]

f[0] = Fraction[50, 100];
f[n_] := Fraction[#1 + 1, #2 + 1] & @@ f[n - 1];
f[5]

55/105

f2[0] = Fraction[50, 100];
f2[n_] := If[Mod[n, 2] == 0, Fraction[#1 + 1, n], Fraction[#1, #2 + 1]] & @@ f2[n - 1];
f2[1]

50/101

ybeltukov
  • 43,673
  • 5
  • 108
  • 212
1

As mentionend in the comments, as a kind of "workaround", you could use:

f[0] = {50, 100}; f[x_] := f[x - 1] + 1

(using that Plus is Listable) which yields for f[1]:

{51,101}

or using memoization:

f[0] = {50, 100}; f[x_] := f[x] = f[x - 1] + 1

On another note (or reading the comments, thanks @Kuba), you won't even need recurisivity here:

f[x_]:= f[0] + n

EDIT

For the extended example (I guess there might be a typo in your comment below), you could do:

ff[0] = {50, 100};
ff[x_] := If[EvenQ[x], {#1 + 1, x}, {#1, #2 + 1}] & @@ ff[x - 1];
ff /@ Range[10]

{{50, 101}, {51, 2}, {51, 3}, {52, 4}, {52, 5}, {53, 6}, {53, 7}, {54, 8}, {54, 9}, {55, 10}}

I leave it to you to judge what's nicer to look at (and faster...)

Pinguin Dirk
  • 6,519
  • 1
  • 26
  • 36
  • 2
    I believe the real case would be interesting since here f[n_]:=(50+n)/(100+n) :) – Kuba Sep 25 '13 at 20:05
  • uhm... I must be tired – Pinguin Dirk Sep 25 '13 at 20:06
  • This works in this simple case, as I said in the comments above, but as things get more complicated, this is less and less effective, say I want instead to do this: f[0]=50/100 f[n]=If[Mod[n,2]==0,(Numerator[f[n-1]+1])/n,Numerator[f[n-1]/(Denominator[f[n-1]]+1)

    Using suggested notation, this gets very unreadable with all the brackets, since you'll have to use f[n-1][[1]] and f[n-1][[2]]

    – matti0006 Sep 25 '13 at 20:06
  • I will add this to original question for better notation... – matti0006 Sep 25 '13 at 20:07
  • Edited my original post to show how problems can arise if you do something a bit more difficult, it is still possible to store it as a list (obviously), but it won't be very pretty code. – matti0006 Sep 25 '13 at 20:10
  • Hm, your solution is pretty elegant as well, I like this! – matti0006 Sep 25 '13 at 20:37