# Functions defined on rational numbers?

benice shared this question 8 years ago

Hi All,

How to plot functions defined on rational numbers and irrational numbers?

For example, consider the Thomae function:

f(x) =

1/q if x=p/q is rational, gcd(p,q)=1 and q>0,

0 if x is irrational.

How to define f as a GeoGebra function such that we can plot y = f(sin(x)) directly?

benice

https://ggbm.at/558123

1

The Thomae function cannot be done at present. There are two problems that I can see. First you could try to define it in Python in GG5 but there is currently no way for GeoGebra to access "programmed functions" from Python. I believe it is on the wish list though.

Secondly, when graphing a function you have no control of which x-values to plot. In a sense, all plotted values are rational for the have limited presicion.

What you could do is devise a numbering scheme for the rational numbers (i.e. something like for i, for j, x = j/i etc) and use Python (GG5 Beta) or JavaScript to directly plot the function by creating a larbe number of points.

As for the other question, this is possible in version 4.2 which will be released soonish (1 month?). There you can define f(x) = e^x and then define g(x) = f(sin(x)).

1

Secondly, when graphing a function you have no control of which x-values to plot.
Is it possible to increase the sample size of a GeoGebra function?

If this is possible, then we can define f approximately and plot y = f(sin(x)) directly.

benice

1

Nice examples - those should be possibel to reproduce in either Python or maybe with sequence commands. You cannot as far as I know increase the plot resolution for normal plots but using sequence you can produce the points directly. Unfortunately I cannot get the sequence command to work at all right now :imp: but try something like

Sequence[ Sequence[ (a/b, b/a), a, 1, 10], b, 1, a]

1

OK - so I tried and this seems to work:

Sequence[Sequence[If[GCD[a, b] ≟ 1, (a / b, 1 / b), 0], a, 1, b - 1], b, 1, 100]

The last number 100 can be changed for resolution and you can set the point sizes all at once by right clicking on the list and selecting Object Properties.

It might be wise to select Options - Labelling - No new objects from the menu before doning this or you'll get 5000 new labels to be drawn on screen :-D

1

Hi all,

so with asin, reflect and translate.

How to define f as a GeoGebra function such that we can plot y = f(sin(x)) directly?

some points of y=f(sin(x))

n=70

list1=Sequence[Sequence[If[GCD[a, b] ≟ 1, (asin(a / b), 1 / b), 0], a, 1, b - 1], b, 1, n]

list1'=Reflect[list1,yaxis]

list1'_1 = Translate[list1, (-pi, 0)]

list1'' = Translate[list1', (π, 0)]

or

n=70

Sequence[Sequence[If[GCD[a, b] ≟ 1, {(asin(a / b), 1 / b), (-asin(a / b), 1 / b), (asin(a / b) - π, 1 / b), (-asin(a / b) + π, 1 / b)}, 0], a, 1, b - 1], b, 1, n]

Michel

https://ggbm.at/558165

1

Hi, I add with Python with 5.0 but very hard for my computer when n is more then few tens.

with

inport math

in the (global) script.

See the next post.

1

I tried the Python file and I get a result with n=20 in about 0.4s. Timing should be quadratic on this so n=200 should give 40s (did not try this though..)

However, I have noticed when working with Python that the Python-GeoGebra bridge is slow. For one project I simply discarded the GeoGebra links and write the output to an image file instead.

I'm on the bus now but here is a file with a basic script that can probably be modified to do something nice. I imagine that one would first make all points in the image white, then in a separate loop produce black pixels for the function. White is FFFFFFh in decimal and black is 0. You need to make sure the target directory exists or Python will exit quietly without saving.

http://tube.geogebra.org/ma...

1

ouppssss : I've made a mistake in 50f1.ggb : not tested if num^den==1

n=30

def pgcd(a,b) :

r=a%b

if r==0 :

return b

else :

return pgcd(b,r)

for den in range(1,n):

for num in range(1,den):

if (pgcd(num,den)==1):

A=Point(math.asin(num/den),1/den,label_visible=False,point_size=1)

B=Point(-math.asin(num/den),1/den,label_visible=False,point_size=1)

C=Point(-math.asin(num/den)+math.pi,1/den,label_visible=False,point_size=1)

D=Point(math.asin(num/den)-math.pi,1/den,label_visible=False,point_size=1)

https://ggbm.at/558167

1

Too with 5.0, I've tried to "translate" one script of the first link

import math

d = 0.001

m = 250

def f(k,x):

if (k>m):

return 0.0

else:

if (math.fabs(k*x-math.floor(k*x))<d):

return 1.0/k

else:

return f(k+1,x)

precision=500

for k in range(precision):

x=-math.pi+2*k*math.pi/precision

A=Point(x,f(1,math.sin(x)),label_visible=False,point_size=1)

but too a problem of the power of calc.

Michel

1

Ok, I forgot about the gcd bit but this works :-)

It produces an image of the function. Change the script to change resolution or maximum denominator or other things. There is a global Python script to import libraries and en event script that does the work. Output is set initially to c:\geogebraoutput but this can be changed.

Have fun, I did :-D

https://ggbm.at/558171

1

I've added gcd and f(sin). Thank you very much

https://ggbm.at/558175

1

Hi, I don't see why this one does not work :

# Bring in Java.

from java.awt.image import BufferedImage

from javax.imageio import ImageIO

from java.io import File

import math

# Useful constants

dir = "/home/usr/"# Directory to save files

name = "Trial004" # Prefix to filenames

sizeX = 1000 # Number of pixels in x

xmin = -math.pi

xmax =math.pi # x-coordinates of canvas

ymin = -0.1

ymax = 0.5 # y-coordinates of canvas

# Initialize step sizes and SizeY

deltaX = (xmax - xmin)

deltaY = (ymax - ymin)

aspect = deltaX/deltaY

sizeY = int(sizeX/aspect + 0.001)

stepX = deltaX/sizeX

stepY = deltaY/sizeY

d = 0.001 # max error

m = 250 # den max

# Create the image object.

img = BufferedImage(sizeX, sizeY, BufferedImage.TYPE_INT_RGB)

g = img.getGraphics()

# Step through every pixel

for x in range(sizeX):

for y in range(sizeY):

img.setRGB(x, y, 256*256*255 + 256*255 + 255) # Set the colourvalue to white

# Do the Thomae function(sin(x))

def f(k,x):

if (k>m):

return 0.0

else:

if (math.fabs(k*x-math.floor(k*x))<d):

return 1.0/k

else:

return f(k+1,x)

# Draw the Thomae function(sin(x))

for k in range(sizeX):

a=xmin+k*stepX

b=f(1,math.sin(a))

y=int((ymax-b)/stepY)

img.setRGB(k, y , 0) # Set the colourvalue to black

# Save to file.

if not ImageIO.write(img, "png", File(dir + name + ".png" )): print "Save failed!"

1

Not sure... but I've had problems with the "abs" function not working before. Is math.fabs something similar?

If a program doesn't work, then debug it by feeding it to the interactive pane, one bit at a time. That way you at least get some error messages and can identify what part of the script that is causing the problem.

1

Thanks, i've tried as you say but I haven't any error message.

I've found :

we need to have x>0 and y>0 within

img.setRGB(x, y , 0)

and if not, there is no error message but the script does not work.

My mistake was to have ymax<max :flushed:

With ymax=1.5 (as in the script of your link) all is ok.

Michel

1

OK - so I tried and this seems to work:

Sequence[Sequence[If[GCD[a, b] ≟ 1, (a / b, 1 / b), 0], a, 1, b - 1], b, 1, 100]

It's great! Thank you.

or

n=70

Sequence[Sequence[If[GCD[a, b] ≟ 1, {(asin(a / b), 1 / b), (-asin(a / b), 1 / b), (asin(a / b) - π, 1 / b), (-asin(a / b) + π, 1 / b)}, 0], a, 1, b - 1], b, 1, n]

Hi miir,

Thank you for the codes.

1

Thank you very much for the discussions on GeoGebra 5.

Unfortunately, GeoGebra 5 can't be installed on my system. :cry:

I tried to modify the Thomae function and got the following animation.

It reminds me the old arcade games like Space Invaders and Galaxian. I hope you like it.

benice

1

GeoGebraEd :)

https://ggbm.at/558223

1

I tried to modify the Thomae function and got the following animation.

benice

Really nice - Good work!