When does the rational predicate yield false in Scheme? - scheme

When is the rational? predicate useful if even (rational? (sqrt 2)) is true?
I understand that the matter of qualifying numbers rational/irrational is complicated by the fact that numbers are inexactly represented. The predicate is there, anyway.

In an implementation that uses floating point representation of mathematically irrational numbers, any number other than infinity or NaN will be be rational, since a floating point value is essentially a fraction with a power of 2 as the denominator. Basically, irrational numbers like π and (sqrt 2) are actually rational approximations in these systems.
The rational? predicate is provided for completeness to allow for other possible representations of irrational numbers, such as continued fractions. I don't think there are any real implementations like this, it's just theoretical.

The rational? predicate returns true if a number is a rational: a number of the form n/m where n and m are integers and m is not zero. That means that, as Barmar says, it must return true for floats (assuming the normal float representation), because floats are, in fact rationals.
But there's a really important case where rational? must return false: complex numbers. Complex numbers are not rational numbers. So for any implementation which has complex numbers, rational? will return false for those:
> (rational? 1+2i)
#f
> (number? 1+2i)
#t
> (complex? 1+2i)
#t
> (real? 1+2i)
#f
> (exact? 1+2i)
#t
> (complex? 1)
#t
> (rational? 1+0i)
#t

Related

sbcl keep as much precision as possible when converting rational to decimal notation

I have a simple lisp program here that computes an approximation of the average length between two points chosen uniformly at random on the unit interval. If I run the program, I get a rational number 16666671666667/50000000000000, but when I (naively) try to format the rational number to 20 places, some of the precision is thrown away 0.33333343000000000000. I think that, under the hood, SBCL is casting the rational to a floating point number before formatting it, but I'm not really sure how to tell. I'm just using the expression (format t "~20$~%" (scale-all-line-contributions 10000000 1). Is there a way to convert a rational number to decimal notation keeping as much precision as possible? I understand the format system is powerful and expansive, but I'm having trouble finding documentation about it specifically related to rational numbers.
Here's the code below for completeness' sake, since it isn't very long.
(defun number-of-pairs (n i)
"get the number of pairs with distance x
for non-zero distances we have to consider two cases"
(cond
((= i 0) n)
((> i 0) (* 2 (- n i)))
((> i n) 0)))
(defun line-contribution (n i power)
"get the number of segments of length i in a line of n segments and their weight combined"
(let
((number-of-pairs (number-of-pairs n i))
(weight-of-pair (expt i power)))
(* number-of-pairs weight-of-pair)))
(defun all-line-contributions (n power)
"get the line contributions for reach [0 .. n]"
(loop for i from 1 upto (- n 1) summing (line-contribution n i power)))
(defun normalized-all-line-contributions (n power)
"normalize line contributions by number of pairs"
(let ((pair-count (expt n 2)))
(/ (all-line-contributions n power) pair-count)))
(defun scale-all-line-contributions (n power)
"scale the line contributions by the distance n
this will guarantee convergence"
(/ (normalized-all-line-contributions n power) (expt n power)))
(print (scale-all-line-contributions 10000000 1))
(format t "~20$~%" (scale-all-line-contributions 10000000 1))
edit: fixed logic error in code. new rational number, float pair is 33333333333333/100000000000000 0.33333334000000000000
You can use either coerce or float. For instance:
(format t "~20$" (coerce 16666671666667/50000000000000 'long-float))
; prints 0.33333343333334000000
(format t "~a" (float 16666671666667/50000000000000 1.0l0))
; prints 0.33333343333334d0
Note that a coercion to long-float can produce different results in different implementations of Common Lisp (in particular in CLISP).
The second parameter to float is a prototype: you should provide any float literal and the first parameter will be converted to the same kind of float.

Creating and solving a recurrence relation for sine approximation

In SICP, there is a problem (exercise 1.15) that says
Exercise 1.15. The sine of an angle (specified in radians) can be
computed by making use of the approximation sin x x if x is
sufficiently small, and the trigonometric identity
sin(r) = 3sin(r/3) - 4sin^3(r/3)
to reduce the size of the argument of sin. (For purposes of this
exercise an angle is considered ``sufficiently small'' if its
magnitude is not greater than 0.1 radians.) These ideas are incorporated
in the following procedures:
(define (cube x) (* x x x))
(define (p x) (- (* 3 x) (* 4 (cube x))))
(define (sine angle)
(if (not (> (abs angle) 0.1))
angle
(p (sine (/ angle 3.0)))))
a. How many times is the procedure p applied when (sine 12.15) is evaluated?
b. What is the order of growth in space and number of steps
(as a function of a) used by the process generated by the
sine procedure when (sine a) is evaluated?
You can analyze it by running it, and see that it becomes O(loga) where a is the input angle in radians.
However, this isn't sufficient. This should be provable via recurrence relation. I can set up a recurrence relation as such:
T(a) = 3T(a/3) - 4T(a/3)^3
Which is homogenous:
3T(a/3) - 4T(a/3)^3 - T(a) = 0
However, it is non-linear. I am unsure how to get the characteristic equation for this so that I can solve it and prove to myself O(loga) is more than just "intuitively true". No tutorial on the internet seems to cover this analysis, and the only thing I saw conclusively said that non-linear recurrences are pretty much impossible to solve.
Can anyone help?
Thank you!
You're confusing the computation with the amount of time the computation takes.
If θ≤0.1, then T(θ) is 1. Otherwise, it is T(θ/3)+k, where k is the time it takes to do four multiplications, a subtraction, and some miscellaneous bookkeeping.
It is evident that the argument for the ith recursion will be θ/3i, and therefore that the recursion will continue until θ/3i≤0.1. Since the smallest value of i for which that inequality is true is ⌈log3(θ/0.1)⌉, we can see that T(θ) = k*⌈log3(θ/0.1)⌉, which is O(logθ). (I left out the small constant factor which differentiates the last recursion from the other ones, since it makes no difference.)

DrRacket procedure body help (boolean-odd? x)

An iterative version of odd? for non-negative integer arguments can be written using and, or, and not. To do so, you have to take advantage of the fact that and and or are special forms that evaluate their arguments in order from left to right, exiting as soon as the value is determined. Write (boolean-odd? x) without using if or cond, but using and, or, not (boolean) instead. You may use + and -, but do not use quotient, remainder, /, etc.
A number is even if two divides it evenly, and odd if there if there is a remainder of one. In general, when you divide a number k by a number n, the remainder is one element of the set {0,1,…n-1}. You can generalize your question by asking whether, when k is divided by n, the remainder is in some privileged set of remainder values. Since this is almost certainly homework, I do not want to provide a direct answer to your question, but I'll answer this more general version, without sticking to the constraints of using only and and or.
(define (special-remainder? k n special-remainders)
(if (< k n)
(member k special-remainders)
(special-remainder? (- k n) special-remainders)))
This special-remainder? recursively divides k by n until a remainder less than n is found. Then n is tested for its specialness. In the case that you're considering, you'll be able to eliminate special-remainders, because you don't need (member k special-remainders). Since you only have one special remainder, you can just check whether k is that special remainder.
A positive odd number can be defined as 1 + 2n. Thus an odd number is:
If x is 1
If x is greater than 1 and x-2 is odd.
Thus one* solution that is tail recursive/iterative looks like this:
(define (odd? x)
(or (= ...) ; #t if 1
(and ... ; #f if less than 1
(odd? ...))); recurse with 2 less
*having played around with it it's many ways to do do this and still have it iterative and without if/cond.

time complexity of the acc function in scheme?

I have been trying to find a tight bound time complexity for this function with respect to just one of the arguments. I thought it was O(p^2) (or rather big theta) but I am not sure anymore.
(define (acc p n)
(define (iter p n result)
(if (< p 1)
result
(iter (/ p 2) (- n 1) (+ result n))))
(iter p n 1))
#sarahamedani, why would this be O(p^2)? It looks like O(log p) to me. The runtime should be insensitive to the value of n.
You are summing a series of numbers, counting down from n. The number of times iter will iterate depends on how many times p can be halved without becoming less than 1. In other words, the position of the leftmost '1' bit in p, minus one, is the number of times iter will iterate. That means the number of times iter runs is proportional to log p.
You might try to eyeball it, or go from it more systematically. Assuming we're doing this from scratch, we should try build a recurrence relation from the function definition.
We can assume, for the moment, a very simple machine model where arithmetic operations and variable lookups are constant time.
Let iter-cost be the name of the function that counts how many steps it takes to compute iter, and let it be a function of p, since iter's termination depends only on p. Then you should be able to write expressions for iter-cost(0). Can you do that for iter-cost(1), iter-cost(2), iter-cost(3), and iter-cost(4)?
More generally, given an p greater than zero, can you express iter-cost(p)? It will be in terms of constants and a recurrent call to iter-cost. If you can express it as a recurrence, then you're in a better position to express it in a closed form.

Solving quadratic congruence equation in Mathematica

In order to solve
x^2 == 123456 mod 1299709
in Mathematica I have used:
Reduce[x^2 == 123456 + 1299709 k, {x, k}, Integers]
which yields the correct answer.
Question: Is Reduce the best way ( performance, elegance or otherwise ) to solve quadratic congruence equations?
Apparently you are seeking the Modulus option.
Reduce[x^2 == 123456, x, Modulus -> 1299709]
(*Out[]= x == 427784 || x == 871925 *)
Quoting the documentation:
Modulus -> n
is an option that can be given in certain algebraic functions to specify that integers should be treated modulo n.
Equations for Modulus can be given in Solve and related functions.
Modulus appears as an option in Factor, PolynomialGCD and PolynomialLCM, as well as in linear algebra functions such as Inverse,
LinearSolve and Det.
Arithmetic is usually done over the full ring ℤ of integers; setting the option Modulus specifies that arithmetic should instead be
done in the finite ring ℤn.
The setting Modulus->0 specifies the full ring ℤ of integers.
Some functions require that Modulus be set to a prime, or a power of a prime. ℤn is a finite field when n is prime.
In[1]:= PowerModList[123456, 1/2, 1299709]
Out[1]= {427784, 871925}
Daniel Lichtblau

Resources