How to write exponent in racket? - racket

Using (x^4) or (^ x 4) giving an error message. Is there some functions for exponent than simply using (* x x x x)?

Use the primitive function expt (see reference):
(expt x 4) ; = x⁴

If you forget expt, you can use:
(for/product ((i 4)) x)
It's easier than writing (* x x x x) for larger values.

Related

How to get the average of two floating point numbers

I want to get the average of a 2 floating point numbers. My function for the integer variant
let int_average x y = (x + y) / 2
works fine but when I try to write it for floats
let float_average x y = (x +. y) / 2.
it fails with the error
This expression has type float but an expression was expected of type
int
You forgot to "floatify" the division operator. / should be /., just as +. is the float variant of +:
let float_average x y = (x +. y) /. 2.

racket. Implement the Ackermann's function

I'm trying to understand, but so far I can not make myself. When I see the finished solution is easier to understand how to do it. This is my first exercise, the others want to do it myself, but need to understand how to implement it.
Please help me how to write a racket function.
Implement the Ackermann's function A. It takes two parameters, x and y, and works as follows:
if y = 0, then it returns 0;
if x = 0, then it returns 2*y;
if y = 1, then it returns 2;
else, it calls itself (function A) with x = x-1 and y = A ( x, (y - 1) )
The project is given
#lang racket/base
(require rackunit)
;; BEGIN
;; END
(check-equal? (A 1 10) 1024)
(check-equal? (A 2 4) 65536)
(check-equal? (A 3 3) 65536)
It's a straightforward translation, you just have to write the formula using Scheme's syntax:
(define (A x y)
(cond ((= y 0) 0) ; if y = 0, then it returns 0
((= x 0) (* 2 y)) ; if x = 0, then it returns 2*y
((= y 1) 2) ; if y = 1, then it returns 2
(else (A (- x 1) ; else it calls itself (function A) with x = x-1
(A x (- y 1)))))) ; and y = A ( x, (y - 1))
Here is one solution:
#lang racket
(define (ack x y)
(match* (x y)
[(_ 0) 0] ; if y = 0, then it returns 0
[(0 y) (* 2 y)] ; if x = 0, then it returns 2*y
[(_ 1) 2] ; if y = 1, then it returns 2
[(x y) (ack (- x 1) (ack x (- y 1)))]))

Matlab - define a general variable

I want to calculate Fourier series for some function func.
I build this method:
function y = CalcFourier(accurate, func, a, b, val_x)
f = #(x) eval(func);
% calculate coefficients
a0 = (2 / (b - a)) * calcArea(func, a , b);
an = (2 / (b - a)) * calcArea(strcat(func, '*cos(2*n*pi*x / (b - a))'), a , b);
an = (2 / (b - a)) * calcArea(strcat(func, '*sin(2*n*pi*x / (b - a))'), a , b);
partial = 0;
an_f = #(n) an;
bn_f = #(n) bn;
for n = 1:accurate
partial = partial + an_f(n)* cos(2*n*pi*val_x / (b - a)) + bn_f(n) * sin(2*n*pi*val_x / (b - a));
end
y = (a0 / 2) + partial;
end
And this - to approximate the coefficient's:
function area = calcArea(func, a, b)
f = #(x) eval(func);
area = (a - b) * (f(a) - f(b)) / 2;
end
On line an = (2 / (b - a)) * calcArea(strcat(func, '*cos(2*n*pi*x / (b - a))'), a , b); I'm getting error:
??? Error using ==> eval
Undefined function or variable 'n'.
Error in ==> calcArea>#(x)eval(func) at 2
f = #(x) eval(func);
Error in ==> calcArea at 3
area = (a - b) * (f(a) - f(b)) / 2;
Error in ==> CalcFourier at 5
an = (2 / (b - a)) * calcArea(strcat(func,
'*cos(2*n*pi*x / (b - a))'), a , b);
>>
Is there any option to declate n as "some constant"? Thanks!
You try to use a variable called n in line 4 of your code. However at that time n is not defined yet, that only happens in the for loop. (Tip: Use dbstop if error at all times, that way you can spot the problem more easily).
Though I don't fully grasp what you are doing I believe you need something like this:
n=1 at the start of your CalcFourier function. Of course you can also choose to input n as a variable, or to move the corresponding line to a place where n is actually defined.
Furthermore you seem to use n in calcArea, but you don't try to pass it to the function at all.
All of this would be easier to find if you avoided the use of eval, perhaps you can try creating the function without it, and then matlab will more easily guide you to the problems in your code.
if the symbolic toolbox is available it can be used to declare symbolic variables , which can be treated as 'some variable' and substituted with a value later.
however a few changes should be made for it to be implemented, generally converting anonymous functions to symbolic functions and any function of n to symbolic functions. And finally the answer produced will need to be converted from a symbolic value to some more easy to handle value e.g. double
quickly implementing this to your code as follows;
function y = test(accurate, func, a, b, val_x)
syms n x % declare symbolic variables
%f = symfun(eval(func),x); commented out as not used
The two lines above show the declaration of symbolic variables and the syntax for creating a symbolic function
% calculate coefficients
a0 = symfun((2 / (b - a)) * calcArea(func, a , b),x);
an = symfun((2 / (b - a)) * calcArea(strcat(func, '*cos(2*n*pi*x / (b - a))'),...
... a , b),[x n]);
bn = symfun((2 / (b - a)) * calcArea(strcat(func, '*sin(2*n*pi*x / (b - a))'),...
... a , b),[x n]);
partial = 0;
the function definitions in in your code are combined into the lines above, note they functions are of x and n, the substitution of x_val is done later here...
for n = 1:accurate
partial = partial + an(val_x,n)* cos(2*n*pi*val_x / (b - a)) +...
... bn(val_x,n) * sin(2*n*pi*val_x / (b - a));
end
The for loop which now replaces the symbolic n with values and calls the symbolic functions with x_val and each n value
y = (a0 / 2) + partial;
y = double(y);
end
Finally the solution is calculated and then converted to double;
Disclaimer: I have not checked if this code generates the correct solution, however I hope it gives you enough information to understand what has been changed and why to carry out the process given in your code above, using the symbolic toolbox to address the issue...

Isabelle: degree of polynomial multiplied with constant

I am working with the library HOL/Library/Polynomial.thy.
A simple property didn't work. E.g., the degree of 2x *2 is equal to the degree of 2x-
How can I prove the lemmas (i.e., remove "sorry"):
lemma mylemma:
fixes y :: "('a::comm_ring_1 poly)" and x :: "('a::comm_ring_1)"
shows "1 = 1" (* dummy *)
proof-
have "⋀ x. degree [: x :] = 0" by simp
from this have "⋀ x y. degree (y * [: x :] ) = degree y" sorry
(* different notation: *)
from this have "⋀ x y. degree (y * (CONST pCons x 0)) = degree y" sorry
.
From Manuel's answer, the solution I was looking for:
have 1: "⋀ x. degree [: x :] = 0" by simp
{
fix y :: "('a::comm_ring_1 poly)" and x :: "('a::comm_ring_1)"
from 1 have "degree (y * [: x :]) ≤ degree y"
by (metis Nat.add_0_right degree_mult_le)
}
There are a number of issues here.
First of all, the statement you are trying to show simply does not hold for all x. If x = 0 and y is nonconstant, e.g. y = [:0,1:], you have
degree (y * [: x :]) = degree 0 = 0 ≠ 1 = degree y
The obvious way to fix this is to assume x ≠ 0.
However, this is not sufficient either, since you only assumed 'a to be a commutative ring. However, in a commutative ring, in general, you can have zero divisors. Consider the commutative ring ℤ/4ℤ. Let x = 2 and y = [:0,2:].
Then y * [:x:] = [:0,4:], but 4 = 0 in ℤ/4ℤ. Therefore y * [:x:] = 0, and therefore, again,
degree (y * [: x :]) = degree 0 = 0 ≠ 1 = degree y
So, what you really need is one of the following two:
the assumption x ≠ 0 and 'a::idom instead of 'a::comm_ring. idom stands for “integral domain” and, that is simply a commutative ring with a 1 and without zero divisors
more generally, the assumption that x is not a zero divisor
even more generally, the assumption that x * y ≠ 0 or, equivalently, x times the leading coefficient of y is not 0
Also, the usage of ⋀ in Isar proofs is somewhat problematic at times. The “proper“ Isar way of doing this would be:
fix x :: "'a::idom" and y :: "'a poly"
assume "x ≠ 0"
hence "degree (y * [:x:]) = degree y" by simp
The relevant lemmas are degree_mult_eq and degree_smult_eq, you will see that they require the coefficient type to be an idom. This works for the first case I described above, the other two will require some more manual reasoning, I think.
EDIT: just a small hint: you can find theorems like this by typing
find_theorems "degree (_ * _)"
If you try to apply the degree_mult_eq it shows to your situation (with comm_ring), you will find that it fails, even though the terms seem to match. If that is the case, it is usually a type issue, so you can write something like
from [[show_sorts]] degree_mult_eq
to see what the types and sorts required by the lemma are, and it says idom.

Evaluating arguments in Clojure macro

I'd like to build a function, which, given a 2D matrix and some element from that matrix, will return the indexes of the element's position:
(get-indices [[1 2 3] [4 5 6] [7 8 9]] 6)
;=> [1 2]
which, given back to get-in, will return the element itself:
(get-in [[1 2 3] [4 5 6] [7 8 9]] [1 2])
;=> 6
I wanted the function (get-indices) to be fast, so I was thinking about doing a macro which will expand to something similar to the (cond ...) part of this function (but generic for every 2D matrix of size NxN):
(defn get-indices
[matrix el]
(let [[[a b c] [d e f] [g h i]] matrix]
(cond
(= a el) [0 0]
(= b el) [0 1]
(= c el) [0 2]
(= d el) [1 0]
(= e el) [1 1]
(= f el) [1 2]
(= g el) [2 0]
(= h el) [2 1]
(= i el) [2 2])))
I came up with this macro:
(defmacro get-indices
[matrix el]
(let [size (count matrix)
flat (flatten matrix)
compare-parts (map #(list '= % el) flat)
indices (for [x (range size) y (range size)] [x y])]
(cons 'cond (interleave compare-parts indices))))
It seemed just nice... But when called with var, not a direct value, it throws an exception:
(def my-matrix [[1 2 3] [4 5 6] [7 8 9]])
(get-indices my-matrix 6)
;=> java.lang.UnsupportedOperationException: count not supported on this
; type: Symbol (NO_SOURCE_FILE:0)
To me it seems like the symbol "matrix" isn't resolved to value at macro expansion time or something like that, but I'm absolute beginner in macros...
How can I make this macro to work also with vars as arguments?
I was also thinking about using syntax-quote etc., but I'd like to avoid having (let ...) as a part of the macro output and also didn't know how to implement (interleave compare-parts indices) within the syntax-quote....
Writing this as a macro is a disastrous choice. As a function it's pretty simple, and more efficient than what you wanted your macro to expand to anyway:
(defn get-indices [matrix el]
(let [h (count matrix), w (count (first matrix))]
(loop [y 0, x 0, row (first matrix), remaining (rest matrix)]
(cond (= x w) (recur (inc y) 0 (first remaining), (rest remaining))
(= y h) nil
(= (first row) el) [y x]
:else (recur y (inc x) (rest row) remaining)))))
Conversely, as a macro it is simply impossible. Macros are for writing code at compile-time - how could you generate the cond-based code for 2D matrices at compile time, if you don't know the matrix's size until runtime?