Racket can't plot a surface - plot

I want to plot this surface:
z = (3x - 8 + 11y) / (6y -11)
Here is the code
(plot3d (surface
(lambda (x y) (/ (+ (* 3 x) -8 (* 11 y)) (- (* 6 y) 11)) 0 1 0 1))
#:x-min 0 #:x-max 1 #:y-min 0 #:y-max 1)
However, Racket produces a strange (and wrong graph). I try this function on academo.org and it plots just fine.
https://academo.org/demos/3d-surface-plotter/?expression=(3x-8%2B11y)%2F(6y-11)&xRange=0%2C1&yRange=0%2C1&resolution=25
Does anybody knows why? Because I need to plot multiple surfaces in a same graph and I cannot do that on academo. I have only Racket as graphing tool on my laptop.
Thank you,

Use surface3d (not surface). Easy oversight.

Sorry, surface does not work but surface3d works.
(plot3d (surface3d
(lambda (x y) (/ (+ (* 3 x) -8 (* 11 y)) (- (* 6 y) 11))) 0 1 0 1))
Though I still do not know why.

Related

Is in Racket any function to draw a plot like "stem" plot in python?

"A stem plot plots vertical lines at each x location from the baseline to y, and places a marker there."
Like this:
The graph you use is generated by the following code in Python:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0.1, 2 * np.pi, 41)
y = np.exp(np.sin(x))
plt.stem(x, y, use_line_collection=True)
plt.show()
Trying to build a similar plot using Racket:
#lang racket
(require plot)
(define my-linspace
(λ (start stop [num 50])
(range start stop (/ stop num))))
(define x (my-linspace 0 (* 2 pi) 41))
(define y (map exp (map sin x)))
(define my-blue '(32 119 180))
(plot
#:x-min -0.3
#:x-max 6.5
#:y-min -0.2
#:y-max 2.9
#:x-label #f
#:y-label #f
(let ([data (map list x y)])
(list
(points data #:color my-blue #:sym 'fullcircle5)
; for each data point, draw a vertical line
; at its "x" ranging from height 0 to its "y"
(list (map (λ (d) (vrule (first d) 0 (second d) #:color my-blue #:width 2)) data))
(list (hrule 0 (first (first data)) (first (last data)) #:color "red" #:width 2)))))

Recursive Multiplication in Scheme (trouble with negatives)

I am trying to multiply in Scheme using recursion, and I am able to do so with positive numbers but not negatives (they get stuck in an infinite loop). I assume the problem comes in the 3rd and 4th lines, which I wrote in an attempt to be able to handle negatives. Any help would be appreciated :)
(define Multiply(lambda (x y)
(if (eq? x 0) 0 (if (eq? y 0) 0 ;if either x or y are zero, return 0
(if (> 0 x) (- 0 (+ x (Multiply x (- y 1))))
(if (> 0 y) (- 0 (+ x (Multiply x (- y 1))))
(+ x (Multiply x (- y 1)))))))))
Since multiplication is associative, you can have
x * (-1 * y) = (x * -1) * y
With this in mind, you can convert y to positive whenever it is less than zero, by multiplying both x and y with -1.
Consider the following:
(define (multiply x y)
(cond
((zero? x) 0)
((zero? y) 0)
((< y 0)
(multiply (- x) (- y)))
(else
(+ x (multiply x (sub1 y))))))

Why is the recursive function performing better than the iterative function in elisp?

As a test for one of my classes, our teacher asked us to test a recursive and non-recursive approach to the famous Euclidean Algorithm:
Iterative
(defun gcdi (a b)
(let ((x a) (y b) r)
(while (not (zerop y))
(setq r (mod x y) x y y r))
x))
Recursive
(defun gcdr (a b)
(if (zerop b)
a
(gcdr b (mod a b))))
And then I ran a test:
(defun test-iterative ()
(setq start (float-time))
(loop for x from 1 to 100000
do (gcdi 14472334024676221 8944394323791464)) ; Fibonacci Numbers close to 2^64 >:)
(- (float-time) start))
(defun test-recursive ()
(setq start (float-time))
(loop for x from 1 to 100000
do (gcdr 14472334024676221 8944394323791464)) ; Fibonacci Numbers close to 2^64 >:)
(- (float-time) start))
And then I ran the timers:
(test-recursive)
: 1.359128475189209
(test-iterative)
: 1.7059495449066162
So my question is this, why did the recursive test perform faster than the iterative test? Isn't iterative almost always better than recursion? Is elisp an exception to this?
The theoretical answer is that the recursive version is actually tail
recursive and thus should compile to iteration.
However, disassembling
the functions reveals the truth:
byte code for gcdi:
args: (a b)
0 varref a
1 varref b
2 constant nil
3 varbind r
4 varbind y
5 varbind x
6 varref y
7:1 constant 0
8 eqlsign
9 goto-if-not-nil 2
12 constant mod
13 varref x
14 varref y
15 call 2
16 varset r
17 varref y
18 varset x
19 varref r
20 dup
21 varset y
22 goto 1
25:2 varref x
26 unbind 3
27 return
vs
byte code for gcdr:
args: (a b)
0 varref b
1 constant 0
2 eqlsign
3 goto-if-nil 1
6 varref a
7 return
8:1 constant gcdr
9 varref b
10 constant mod
11 varref a
12 varref b
13 call 2
14 call 2
15 return
You can see that the gcdr has almost half as many instructions, but contains two call instructions, which means that ELisp does not, apparently, convert the tail recursive call to iteration.
However, function calls in ELisp are relatively cheap and
thus the recursive version executes faster.
PS. While the question makes sense, and the answer is actually generally applicable (e.g., the same approach is valid for Python and CLISP, inter alia), one should be aware that choosing the right algorithm (e.g., linearithmic merge-sort instead of quadratic bubble-sort) is much more important than "micro-optimizations" of the implementation.
Hmm... indeed that's weird, since Emacs's implementation of function calls (and hence recursion) is not very efficient.
I just evaluated the code below:
(defun sm-gcdi (a b)
(let ((x a) (y b) r)
(while (not (zerop y))
(setq r (mod x y) x y y r))
x))
(defun sm-gcdr (a b)
(if (zerop b)
a
(sm-gcdr b (mod a b))))
(defun sm-test-iterative ()
(let ((start (float-time)))
(dotimes (_ 100000)
(sm-gcdi 14472334024676221 8944394323791464))
(- (float-time) start)))
(defun sm-test-recursive ()
(let ((start (float-time)))
(dotimes (_ 100000)
(sm-gcdr 14472334024676221 8944394323791464))
(- (float-time) start)))
and then tried M-: (sm-test-recursive) and M-: (sm-test-iterative) and sure enough the iterative version is faster for me. I then did M-: (byte-compile 'sm-gcdi) and M-: (byte-compile 'sm-gcdr) and tried again, and the speed difference was even larger.
So your measurements come as a surprise to me: they don't match my expectations, and don't match my tests either.

How to write a function that raises a number to 10th power using Racket?

This is what I have:
(define (10th-power 10 y)
(if (= y 0)
1
(* 10 ((10th-power 10 (- y 1)))))
for example if I input 2 it should give out 1024.
There are a lot of errors in this short procedure. Here are the errors reported by racket:
read: expected a ')' to close '(' since you are missing ending parentheis
define: not an identifier... in 10 as 10 cannot be a variable name it cannot be in the argument list.
application: not a procedure. Double parentheses in the recursion part makes the result from 10th-power tried as a procedure as the result instead of just using the value as is.
If you fix those your procedure will work, but it will do the 10^y instead of y^10. Perhaps you need a helper where you keep how many times you have multiplied y that counts down instead of y which is the one that should be in 10's place.
You were close:
#lang racket
(define (10th-power y)
(if (= y 0)
1
(* 10 (10th-power (- y 1)))))
(10th-power 3)
Things to note: You can't insert an extra parenthesis around an expression. Example: (100) means call 100 with no arguments - and since 100 is not a function, you get the error "application: not a procedure:.
Second thing to note: You do not need the 10 as an argument.
you can write a recursion like this:
#lang racket
(define (10th-power y)
(if (= y 0 )
1
(* 10 (10th-power (- y 1)))))
by the way, if you want to improve you space efficiency from o(n) to o(1),you can write iteration:
#lang racket
(define (10th-power y)
(define (iter back times)
(if (= times 0)
back
(iter (* 10 back) (- times 1))))
(iter 1 y))
(10th-power 3)

Using Racket to Plot Points

After spending some time looking at the documentation, searching the web, and experimenting at the prompt, I haven't succeeded at plotting points using Racket. Could someone post an example of how I'd go about plotting (0 1 2 3 4 5) for my x coordinates and (0 1 4 9 16 25) for the y coordinates. I think 1 good example will clear the problem up.
Based on the first example of the doc, and given that the function you want to plot already exists in Racket, it's as simple as:
(require plot)
(plot (function sqr 0 5 #:label "y = x ^ 2"))
If you just want to see the individual points, this is also taken from the docs:
(require plot)
(define xs '(0 1 2 3 4 5))
(define ys '(0 1 4 9 16 25))
(plot (points (map vector xs ys) #:color 'red))
which is equivalent to
(require plot)
(plot (points '(#(0 0) #(1 1) #(2 4) #(3 9) #(4 16) #(5 25)) #:color 'red))

Resources