How to construct `g` such that `g(x0)(x1)(x2) == f(f(x0, x1), x2)` - functional-programming

Given arbitrary function f, how to construct function g such that for every x0, x1, ..., xn, g(x0)(x1)...(xn) equals f(...f(f(x0, x1), x2), ...), xn)?
EDIT
This is very similar to the question how to implement a function like sum(2)(3)(4)...(n) in python

At every point gn has to return both a function that can accept xn+1 and the value given by applying f to gn-1 and xn. Unless you are using a language that allows the return value to be or act as both types, this is impossible.

Related

Julia: Plugging Matrix Values into a Function

I have a given matrix PC1, which is a 3xn matrix. I would like to write a loop that calculates the magnitude (vector magnitude) of each line of our given matrix and rewrite it into a 1xn matrix. For magnitude I made the function:
function magnitude(x,y,z)
sqrt((x^2)+(y^2)+(z^2))
end
I want to be able to use this function if possible to again calculate the magnitude of each line of my matrix. I have tried the following:
for j in size(pc1[:,1])
B[j] = magnitude(pc1[1,j],a[2,j],a[3,j])
end
When I try this, I get an error reading:
"ArgumentError: Invalid index: 0.0 of type Float64"
Any suggestions on how to get rid of this error as well as make my for loop work would be wonderful.
Thanks!
Then you can do this:
#Suppose that my_mat is:
julia> my_mat
3×5 Matrix{Float64}:
0.146247 0.309755 0.0802212 0.810787 0.459134
0.810021 0.876092 0.89679 0.238271 0.852003
0.124778 0.590032 0.613531 0.0857502 0.524727
julia> function magnitude(x...)
x1, x2, x3 = x
#show x1, x2, x3
sqrt((x1^2)+(x2^2)+(x3^2))
end
magnitude (generic function with 1 method)
julia> magnitude.(eachrow(my_mat)...)
(x1, x2, x3) = (0.14624718982068596, 0.8100214466524703, 0.1247777052693978)
(x1, x2, x3) = (0.30975515637837503, 0.8760918202600901, 0.5900319505173406)
(x1, x2, x3) = (0.08022117017277575, 0.8967900297662494, 0.6135309351302954)
(x1, x2, x3) = (0.8107874182293756, 0.23827052138513005, 0.08575020171498149)
(x1, x2, x3) = (0.45913420665189597, 0.852002514985355, 0.5247268441565018)
5-element Vector{Float64}:
0.8325217476436908
1.1007374060423891
1.0895356818360262
0.8494128419174967
1.1009317718358742
As you can see, you don't need a for loop for this, and broadcasting can do what you need through the dot (.) operator.
But maybe you ask why I used eachrow and how I'm accessing each column through the eachrow function. Well, let's see an example to understand what's happening inside magnitude.(eachrow(my_mat)...):
The eachrow function returns a generator that iterates over the first dimension of the vector or matrix. Let's say I have a matrix named mat:
julia> mat = rand(2,2)
2×2 Matrix{Float64}:
0.541733 0.0644034
0.451938 0.612991
Now some_func.(eachrow(mat)...) is equivalent to these:
julia> some_func.([0.541733, 0.0644034], [0.451938, 0.612991])
# Which is equivalent to
julia> [some_func(0.541733, 0.451938),
some_func(0.0644034, 0.612991)
]
And this is how I managed to broadcast your function on each column using broadcasting.
Additional Notes
But I suggest you make your function robust and not limit it to specific dimensions (your function accepts three elements, which is usable only when you have a 3xn matrix). Let's make it better:
julia> function magnitude(x...)
sqrt(sum(x->x^2, x))
end
magnitude (generic function with 1 method)
One of the beautiful features of the sum function is that it can accept a function as its first positional argument and an iterable as its second positional argument; In this way, sum applies the given function on each element of the given iterable and then sum the results up. And now I apply it on my_mat through broadcasting:
julia> magnitude.(eachrow(my_mat)...)
5-element Vector{Float64}:
0.8325217476436908
1.1007374060423891
1.0895356818360262
0.8494128419174967
1.1009317718358742
The result is similar to before but not limited to a specific dimension!

Problems with Gaussian Quadrature in R

I'm using the the gaussquad package to evaluate some integrals numerically.
I thought the ghermite.h.quadrature command worked by evaluating a function f(x) at points x1, ..., xn and then constructing the sum w1*f(x1) + ... + wn*f(xn), where x1, ..., xn and w1, ..., wn are nodes and weights supplied by the user.
Thus I thought the commands
ghermite.h.quadrature(f,rule)
sum(sapply(rule$x,f)*rule$w)
would yield the same output for any function f, where ''rule'' is a dataframe which stores the nodes in a column labelled ''x'' and the weights in a column labelled "w". For many functions the output is indeed the same, but for some functions I get very different results. Can someone please help me understand this discrepancy?
Thanks!
Code:
n.quad = 50
rule = hermite.h.quadrature.rules(n.quad)[[n.quad]]
f <- function(z){
f1 <- function(x,y) pnorm(x+y)
f2 <- function(y) ghermite.h.quadrature(f1,rule,y = y)
g <- function(x,y) x/(1+y) / f2(y)*pnorm(x+y)
h <- function(y) ghermite.h.quadrature(g,rule,y=y)
h(z)
}
ghermite.h.quadrature(f,rule)
sum(sapply(rule$x,f)*rule$w)
Ok, that problem got me interested.
I've looked into gaussquad sources, and clearly author is not running sapply internally, because all integrands/function shall return vector on vector argument.
It is clearly stated in documentation:
functn an R function which should take a numeric argument x and possibly some parameters.
The function returns a numerical vector value for the given argument x
In case where you're using some internal functions, they're written that way, so everything works.
You have to rewrite your function to work with vector argument and return back a vector
UPDATE
Vectorize() works for me to rectify the problem, as well as simple wrapper with sapply
vf <- function(z) {
sapply(z, f)
}
After either of those changes, results are identical: 0.2029512

How to produce a vectorized function and take a double integral of each?

I have a function and I want to take a double integral of it. The problem is that there are some vectors inside the function. I don't know how to vectorize the function and then integrate of each function over the variables which are not vectors.
beta=c(1,2,3)
sigmay=0.1
sigmax1=0.1
sigmay1=0.1
# each of stt, sezz and smm is an identified n element vector
func1 = function(smtheo, sttheo) {
Xtheo=c(1, log(smtheo), log(sezz))
mu <- beta %*% Xtheo
ypri=dnorm(log(sttheo), mu, sigmay)
joipri=dnorm(log(stt), log(sttheo), sigmay1)*dnorm(log(smm),log(smtheo), sigmax1)
return(ypri*joipri)}
int=integral2(func1(smtheo, sttheo), a1, a2, b1, b2)
Actually I have n numbers of func1 of each should be integrated over smtheo and stttheo limits. Does anyone know about it?

Calculate the n-th derivative in any point using Scilab

I am trying to evaluate a function in Scilab using the following steps:
x=poly(0,'x')
y=(x^18+x^11)^3 // function (the function is variable)
y1=derivat(y) // first derivate
y2=derivat(y) //second derivate
y3=derivat(y) //third derivate
I need evaluate the 3 derivatives in any point.
I know the function: evstr(expression) but it does not work with the return value of the derivative.
I try to use: string(y) but it returns something strange.
How can to do it, to cast the return of derivat to string to evaluate with evstr or how can I evaluate the n-th derivative in any point using Scilab.
To evaluate numerical derivatives of almost any kind of function (of one or sereval variables) up to machine precision (you won't get better results if you evaluate symbolic expressions obtained by hand), you can use the complex step method (google these terms you will have a bunch of references). For example:
function y = f(x)
s = poly(0,'s');
p = (s-s^2)^3;
y = horner(p,x).*exp(-x.^2);
end
x=linspace(-1,1,100);
d = imag(f(x+complex(0,1e-100)))/1e-100;
true_d = exp(-x.^2).*(-1+x).^2.*x^2.*(3-6*x-2*x.^2+2.*x^3)
disp(max(abs(d-true_d)))
--> disp(max(abs(d-true_d)))
1.776D-15
To evaluate a symbolic polynomial at a particular point or points, use the horner command. Example:
t = 0:0.1:1
v1 = horner(y1, t)
plot(t, v1)
This is the closest I got to a solution to this problem.
He proposes using:
old = 'f';
for i=1:n
new = 'd'+string(i)+'f';
deff('y='+new+'(x)','y=numderivative('+old+',x)');
old=new;
end
I know, it's horrible, but I think there is no better solution, at least in Scilab.
I found a way:
function y = deriva(f, v, n, h)
deff("y = DF0(x)", "y="+f)
if n == 0 then
y = DF0(v);
else
for i=1:(n-1)
deff("y=DF"+string(i)+"(x)", "y=numderivative(DF"+string(i-1)+",x,"+string(h)+",4)");
end
deff("y=DFN(x)", "y=numderivative(DF"+string(n-1)+",x,"+string(h)+",4)");
y = DFN(v);
end
endfunction
disp(deriva("x.*x", 3, 2, 0.0001));
This correctly calculates numerical derivatives of nth order. But it needs to have the function passed as a string. Errors can get pretty large, and time to compute tends to go up fast as a function of n.

Trouble with Curry functions (SML/NJ)

Often we are interested in computing f(i) i=m n∑ , the sum of function
values f(i) for i = m through n. Define ‘sigma f m n’ which computes
f(i) i=m n∑ . This is different from defining ‘sigma (f, m, n)’
I'm required to write a Curried version of this function. I'm have a bit of trouble understanding how this would actually work. I understand that a Curry function is something that takes in a function and produces a function. Would this be an example of a curry function?
fun myCurry f x = f(x)
As far as setting up my problem, would this be an acceptable start?
fun sigma f m n =
I haven't gotten any further, because I can't really grasp what i'm being asked to do.
A curried function is not, in fact, a function that takes in a function and produces another function. That is a higher order function.
A curried function is simply one that takes more than one argument and can be partially applied by only giving it one of its arguments.
For example, with your sigma question,
fun sigma (f,m,n) = ...
is not a curried function, as it takes only one argument (the tuple (f,m,n).)
fun sigma f m n = ...
, however, is a curried function, as it takes three arguments, and it is valid to say something like
val sigmasquare = sigma (fn x => x * x)
, partially applying sigma by giving it its first argument.
A simpler example would be
fun add (x,y) = x + y
This is a noncurried function. To evaluate it, you must give it its argument, which includes both x and y. add (3,5) will evaluate to 8, in this case.
fun add x y = x + y
is the curried version of this same function. This can be partially evaluated by just giving it x. For example, add 3 will evaluate to a function which will add three to its argument.
This is more clearly seen by looking at the previous examples as anonymous or lambda functions.
The first is equivalent to fn (x,y) => x + y, which clearly takes two ints and evaluates to an int.
The second is equivalent to fn x => fn y => x + y, which takes an int and evaluates to a function taking another int and evaluating to an int.
Thus, the type of the first is (int * int) -> int, while the type of the second is int -> int -> int.
Hopefully, this clears currying up somewhat.

Resources