Defining recursive relation in Maple by "for loop" - recursion

I'm trying to make a recursive relation by "for loop" in Maple. Suppose we have two sequences M[i](x) and N[i](x) which N[0](x)=x^2 and M[i](x)=N[i-1](x)+1 and N[i](x)=M[i](x)+2. So I tried this code:
N[0] := proc (x) options operator, arrow; x^2 end proc;
for i to 3 do M[i] := proc (x) options operator, arrow; N[i-1](x)+1 end proc; N[i] := proc (x) options operator, arrow; M[i](x)+2 end proc end do;
But it doesn't give the correct answer (e.g. N[1](x) must be x^2+3). By the way, for some reasons I have to define my functions by mapping x. Is there anyway to modify this code?

The rsolve command can easily handle this example, except that it expects functions of the independent variable i.
And what you have is equations involving functions of x (which doesn't bear on the recursion), with i only appearing as an index.
You can rewrite the equations as functions of i, call rsolve, and then resubstitute back for the original functions.
It would be little effort to construct the substituion set S below by simply entering it in by hand. But for fun I construct it programmatically.
restart;
R1 := N[0](x) = x^2;
2
R1 := N[0](x) = x
R2 := M[i](x) = N[i-1](x)+1;
R2 := M[i](x) = N[i - 1](x) + 1
R3 := N[i](x) = M[i](x)+2;
R3 := N[i](x) = M[i](x) + 2
S := map( u->u=op([0,0],u)(op([0,1],u)),
indets({R1,R2,R3},
specfunc(anything,{N,M})) );
S := {M[i](x) = M(i), N[0](x) = N(0), N[i](x) = N(i),
N[i - 1](x) = N(i - 1)}
newEqs := eval( {R1,R2,R3}, S );
2
newEqs := { M(i) = N(i - 1) + 1, N(0) = x , N(i) = M(i) + 2 }
newV := eval( {N[i](x),M[i](x)}, S );
newV := {M(i), N(i)}
tempans := rsolve( newEqs, newV );
2 2
tempans := { M(i) = x + 3 i - 2, N(i) = x + 3 i }
ans := eval( tempans, map(rhs=lhs,S) );
2 2
ans := { M[i](x) = x + 3 i - 2, N[i](x) = x + 3 i }
Having constructed equations for the general forms of M[i](x) and N[i](x) you can evaluate either of those at specific cals of i. You can also create procedures from those results, and assign them. Eg,
for k from 1 to 3 do
N[k] := unapply(subs(i=k,eval(N[i](x),ans)), [x]);
end do:
N[3](11);
130
It seems inefficient to create all those operators (procedures separately). Why not create just on for N and one for M, that admits two arguments for i and x?
Nfunc := unapply(eval(N[i](x),ans), [i,x]);
2
Nfunc := (i, x) -> x + 3 i
Nfunc(3,x);
2
x + 9
Nfunc(3, 11);
130
[edited] I should tell you why your original attempt failed.
When you try your original attempt the i that appears within both of the procedure bodies is not simplified to the current value of the loop index i. And when you subsequently try and run any of the constructed procedures then it would just pick up whatever value the global i still had. There is no link between the index value of the name N[2] say and the i in its assigned procedure, whenever you subsequently call N[2](x).
restart;
N[0] := x -> x^2:
for i to 2 do
M[i] := x -> N[i-1](x)+1;
N[i] := x -> M[i](x)+2;
end do;
M[1] := x -> N[i - 1](x) + 1
N[1] := x -> M[i](x) + 2
M[2] := x -> N[i - 1](x) + 1
N[2] := x -> M[i](x) + 2
N[2](11); # why this result, you might asK
M[3](11) + 2
i; # still the value coming out of that do-loop
3
unassign('i');
N[2](11); # no relation between the 2 and the `i`
M[i](11) + 2
You could fix up your original by constructing a recursive sequence of procedures. The following "works". But it is incredibly inefficient at run-time because every call to any of the N[..] or M[..] procedures will recursively call into the others in the chain. And that whole recursive set of calls will happen every time you call it. That is to say, here the recursion occurs at run-time of each of the procedures.
restart;
N[0] := x -> x^2:
for i to 3 do
M[i] := subs(ii=i, x -> N[ii-1](x)+1);
N[i] := subs(ii=i,x -> M[ii](x)+2);
end do;
M[1] := x -> N[0](x) + 1
N[1] := x -> M[1](x) + 2
M[2] := x -> N[1](x) + 1
N[2] := x -> M[2](x) + 2
M[3] := x -> N[2](x) + 1
N[3] := x -> M[3](x) + 2
N[3](11);
130
The overall performance of running such a scheme would be very poor.
Much better would be to utilize the unapply command so that each of the N[i] and M[i] (for explicit i values) is a procedure that contains its explicit formula. When using unapply in the following way we pass it the function call which recursively evalutes to the respective formula. Here the recursion occurs only at construction time of each of the procedures.
restart;
N[0] := x -> x^2:
for i to 3 do
M[i] := unapply( N[i-1](x)+1, x);
N[i] := unapply( M[i](x)+2, x);
end do;
2
M[1] := x -> x + 1
2
N[1] := x -> x + 3
2
M[2] := x -> x + 4
2
N[2] := x -> x + 6
2
M[3] := x -> x + 7
2
N[3] := x -> x + 9
N[3](11);
130
But as I noted in my Answer above, there is no need to construct all those procedures at all. By utilizing the rsolve command we can solve the recurrence relation for the general formula (closed in terms of both i and x). And then from that closed formula we can utilize the unapply command to construct only one 2-argument procedure for N and one for M.

Related

Why two styles of executing Juilia programs are giving different results?

If a run a program written in julia as
sachin#localhost:$ julia mettis.jl then it runs sucessfully, without printing anything, though one print statement is in it.
And Secondly If run it as by going in julia:
sachin#localhost:$ julia
julia> include("mettis.jl")
main (generic function with 1 method)`
julia> main()
Then It gives some error.
I am puzzled why two style of executing is giving different result ?
Here is my code:
using ITensors
using Printf
function ITensors.op(::OpName"expτSS", ::SiteType"S=1/2", s1::Index, s2::Index; τ)
h =
1 / 2 * op("S+", s1) * op("S-", s2) +
1 / 2 * op("S-", s1) * op("S+", s2) +
op("Sz", s1) * op("Sz", s2)
return exp(τ * h)
end
function main(; N=10, cutoff=1E-8, δτ=0.1, beta_max=2.0)
# Make an array of 'site' indices
s = siteinds("S=1/2", N; conserve_qns=true)
# #show s
# Make gates (1,2),(2,3),(3,4),...
gates = ops([("expτSS", (n, n + 1), (τ=-δτ / 2,)) for n in 1:(N - 1)], s)
# Include gates in reverse order to complete Trotter formula
append!(gates, reverse(gates))
# Initial state is infinite-temperature mixed state
rho = MPO(s, "Id") ./ √2
#show inner(rho, H)
# Make H for measuring the energy
terms = OpSum()
for j in 1:(N - 1)
terms += 1 / 2, "S+", j, "S-", j + 1
terms += 1 / 2, "S-", j, "S+", j + 1
terms += "Sz", j, "Sz", j + 1
end
H = MPO(terms, s)
# Do the time evolution by applying the gates
# for Nsteps steps
for β in 0:δτ:beta_max
energy = inner(rho, H)
#printf("β = %.2f energy = %.8f\n", β, energy)
rho = apply(gates, rho; cutoff)main
rho = rho / tr(rho)
end
# #show energy
return nothing
end
There is nothing special about a function called main in Julia and defining a function is different from calling it. Consequently a file mettis.jl with the following code:
function main()
println("Hello, World!")
end
will not "do" anything when run (julia mettis.jl). However if you actually call the function at the end:
function main()
println("Hello, World!")
end
main()
you get the expected result
$ julia mettis.jl
Hello, World!

several questions about this sml recursion function

When f(x-1) is called, is it calling f(x) = x+10 or f(x) = if ...
Is this a tail recursion?
How should I rewrite it using static / dynamic allocation?
let fun f(x) = x + 10
in
let fun f(x) = if x < 1 then 0 else f(x-1)
in f(3)
end
end
Before addressing your questions, here are some observations about your code:
There are two functions f, one inside the other. They're different from one another.
To lessen this confusion you can rename the inner function to g:
let fun f(x) = x + 10
in
let fun g(x) = if x < 1 then 0 else g(x-1)
in g(3)
end
end
This clears up which function calls which by the following rules: The outer f is defined inside the outer in-end, but is immediately shadowed by the inner f. So any reference to f on the right-hand side of the inner fun f(x) = if ... is shadowed because fun enables self-recursion. And any reference to f within the inner in-end is shadowed
In the following tangential example the right-hand side of an inner declaration f does not shadow the outer f if we were using val rather than fun:
let fun f(x) = if (x mod 2 = 0) then x - 10 else x + 10
in
let val f = fn x => f(x + 2) * 2
in f(3)
end
end
If the inner f is renamed to g in this second piece of code, it'd look like:
let fun f(x) = if (x mod 2 = 0) then x - 10 else x + 10
in
let val g = fn x => f(x + 2) * 2
in g(3)
end
end
The important bit is that the f(x + 2) part was not rewritten into g(x + 2) because val means that references to f are outer fs, not the f being defined, because a val is not a self-recursive definition. So any reference to an f within that definition would have to depend on it being available in the outer scope.
But the g(3) bit is rewritten because between in-end, the inner f (now g) is shadowing. So whether it's a fun or a val does not matter with respect to the shadowing of let-in-end.
(There are some more details wrt. val rec and the exact scope of a let val f = ... that I haven't elaborated on.)
As for your questions,
You should be able to answer this now. A nice way to provide the answer is 1) rename the inner function for clarity, 2) evaluate the code by hand using substitution (one rewrite per line, ~> denoting a rewrite, so I don't mean an SML operator here).
Here's an example of how it'd look with my second example (not your code):
g(3)
~> (fn x => f(x + 2) * 2)(3)
~> f(3 + 2) * 2
~> f(5) * 2
~> (if (5 mod 2 = 0) then 5 - 10 else 5 + 10) * 2
~> (if (1 = 0) then 5 - 10 else 5 + 10) * 2
~> (5 + 10) * 2
~> 15 * 2
~> 30
Your evaluation by hand would look different and possibly conclude differently.
What is tail recursion? Provide a definition and ask if your code satisfies that definition.
I'm not sure what you mean by rewriting it using static / dynamic allocation. You'll have to elaborate.

Value Bindings in SML? [duplicate]

This question already has answers here:
Value of bindings in SML?
(2 answers)
Closed 6 years ago.
Could someone please help. I don't get the sequence of evaluation here and how we got values of "ans". e.g. in the first example there's no value of y and I'm not sure whether this returns a pair or calls x ! (fn y => y x). It would be very helpful if you can Trace each expression.
val x = 1
val f = (fn y => y x)
val x = 7
val g = (fn y => x - y)
val ans = f g
val ans = 6 : int
=====================================
fun f p =
let
val x = 3
val y = 4
val (z,w) = p
in
(z (w y)) + x
end
val x = 1
val y = 2
val ans = f((fn z => x + z), (fn x => x + x + 0))
val ans = 12 : int
There are a few things which help make problems like this much clearer
when trying understand an alien function Lexical scoping works.
add in types to the parameters and return values without modifying the program, the compiler will tell you if you get it wrong...
replace anonymous functions with named ones.
rename variable bindings that have the same names but refer to different lexical scope.
remove variable bindings that only get used once.
binding a value to a name does not actually perform any computation,
so is merely for the benefit of the reader, if it is not doing that job
it merely serves to obfuscate, then by all means remove it.
fun f (y1 : int -> 'a) = y1 1 : 'a;
fun g (y2 : int) = 7 - y2 : int;
val ans : int = f g;
so g is given as a parameter to f, f calls g giving it the parameter x having the value 1 making y2 = 1, which g subtracts 7 - 1 returning 6.
the return value of g is an int, thus f's 'a type when g is applied to it is an int.
for the 2nd one clean it up a bit, I pulled the anonymous fn's out into their own and named values and call f (foo, bar) to make it more readable...
fun f p =
let val x = 3
val y = 4
val (z, w) = p
in (z (w y)) + x end
fun foo z = z + 1;
fun bar x = x * 2;
val ans = f(foo, bar);
Finally, we can get rid of the let values which are only used once
and replace the (z,w) = p with just (z, w) as a parameter to the function which should be much easier to follow
fun f (z, w) = (z (w 4)) + 3
fun foo z = z + 1;
fun bar x = x * 2;
val ans = f(foo, bar);
val ans = ((4 * 2) + 1) + 3

Log likelihood implementation in Delphi

I am trying to compute a Log Likelihood score for occurrence of pairs of words in text and am getting the same anomalous results in my Delphi implementation which I've derived from Java and Python sources found online. Ted Dunning who published on this source in 1993 gives these results for one particular pair:
K11 (AB, ie joint frequency) = 110,
K12 (word A without B nearby) = 2442,
K21 (B without A nearby) = 111
K22 (number of words other than A or B in the text) = 29114
and gives the desired result as 270.72
Dunning also gives an implementation in R at
http://tdunning.blogspot.co.uk/2008/03/surprise-and-coincidence.html
Computing the log-likelihood ratio score (also known as G2) is very
simple, LLR = 2 sum(k) (H(k) - H(rowSums(k)) - H(colSums(k)))
where H is Shannon's entropy, computed as the sum of (k_ij / sum(k)) log (k_ij / sum(k)) . In R, this function is defined as
H = function(k) {N = sum(k) ; return (sum(k/N * log(k/N + (k==0)))}
but I do not know R and am unsure how to translate that to Pascal.
My translation attempts include these functions
function LnOK(x : integer): extended;
begin
if x<=0 then Result :=0
else Result := Ln(x);
end;
function Entropy2(a, b: Integer): extended;
begin
Result := LnOK(a + b) - LnOK(a) - LnOK(b);
end;
function Entropy4(a, b, c, d: Integer): extended;
begin
Result := LnOK(a + b + c + d) - LnOK(a) - LnOK(b) - LnOK(c) - LnOK(d);
end;
function Log_likelihood_from_Java(f1, f2, joint, total_tokens: Integer):
single;
var
k11, k12, k21, k22: Integer;
matrixEntropy, rowEntropy, colEntropy: extended;
begin
k11 := joint;
k12 := f2 - joint;
k21 := f1 - joint;
k22 := total_tokens - f1 - f2 + joint;
rowEntropy := Entropy2(k11 + k12, k21 + k22);
colEntropy := Entropy2(k11 + k21, k12 + k22);
matrixEntropy := Entropy4(k11, k12, k21, k22);
if (rowEntropy + colEntropy < matrixEntropy) then
Result := 0.0 // round off error
else
Result := 2.0 * (rowEntropy + colEntropy - matrixEntropy);
end;
The above returns 7.9419 instead of the desired 270.72 when it's called like this:
Log_likelihood_from_Java(2552, 221, 110, 31777);
Grateful for help!
I've found the issue in the translation of the LnOk function which should be as follows:
function LnOK(x: Integer): Extended;
begin
if x = 0 then
Result := 0
else
Result := x * Ln(x);
end;
Off topic
As a side note if I'm allowed, just to improve the coding style, you might prefer to overload the Entropy functions instead of calling them with different names:
function Entropy(a, b: Integer): Extended; overload;
begin
Result := LnOK(a + b) - LnOK(a) - LnOK(b);
end;
function Entropy(a, b, c, d: Integer): Extended; overload;
begin
Result := LnOK(a + b + c + d) - LnOK(a) - LnOK(b) - LnOK(c) - LnOK(d);
end;
I can't make any sense of the code that you wrote which bears no obvious relationship to the R code to which you linked. I did not make any attempt to reconcile these differences.
Here's a literal translation of the R code. The algorithm is much simpler written this way as I am sure you will agree.
{$APPTYPE CONSOLE}
uses
SysUtils, Math;
type
TVector2 = array [1..2] of Double;
TMatrix2 = array [1..2] of TVector2;
function rowSums(const M: TMatrix2): TVector2;
begin
Result[1] := M[1,1] + M[1,2];
Result[2] := M[2,1] + M[2,2];
end;
function colSums(const M: TMatrix2): TVector2;
begin
Result[1] := M[1,1] + M[2,1];
Result[2] := M[1,2] + M[2,2];
end;
function H(const k: array of Double): Double;
var
i: Integer;
N, kOverN: Double;
begin
N := Sum(k);
Result := 0.0;
for i := low(k) to high(k) do begin
kOverN := k[i]/N;
if kOverN>0.0 then begin
Result := Result + kOverN*Ln(kOverN);
end;
end;
end;
function LLR(const M: TMatrix2): Double;
var
k: array [1..4] of Double absolute M; // this is a little sneaky I admit
rs, cs: TVector2;
begin
rs := rowSums(M);
cs := colSums(M);
Result := 2.0*Sum(k)*(H(k) - H(rs) - H(cs));
end;
var
M: TMatrix2;
begin
M[1,1] := 110;
M[1,2] := 2442;
M[2,1] := 111;
M[2,2] := 29114;
Writeln(LLR(M));
end.
Output
2.70721876936232E+0002

Maxima: Recursively taking derivatives

I am trying to write some code that recursively finds Taylor coefficients by taking derivatives of a function and then once at the base case evaluates the derivatives at x=0. Here's the code I have so far:
test(f, n) := block([df],
define(df(x), diff(f(x), x)),
print(n, "|", df(x), "|", f(x)),
if n = 0
then f(0)
else test(df, n-1)
);
test_func(x) := x^2;
test(test_func, 2);
The trouble is that this is what I get:
(%i4) test(test_func,2)
2
2 | 2 x | x
1 | 2 | 2
0 | 0 | 0
(%o4) 0
As you can see, the first time through everything looks good, f(x) is x^2, df(x) is 2x. However, the second time through f(x) is 2, even though df(x) was 2x the last time through the function. I'm somewhat new to Maxima so it's quite possible that I'm simply missing something obvious (i.e. don't assume I'm not making a stupid mistake).
My advice is to work with expressions instead of named functions. Something like this:
test(e, n) := block([e1 : diff(e, x)],
print(n, "|", e, "|", e1),
if n = 0
then ev(e, x = 0)
else test(e1, n - 1));

Resources