Is there a way to convert a function to expressions in Julia? - macros

I am trying to create a macro which is capable of (probably recursively) turn a function into expressions so as to reach the operations applied within that function.
As a visualization:
function sampleFunc(x)
println(x)
y = 2x
return 2y* x
end
#macroIcannotImplement sampleFunc(x)
Desired Output:
quote
println(x)
y = 2x
return 2y* x
end
Does Julia support such an extraction or should I start searching for other ways?

Yes, use CodeTracking:
julia> using Revise, CodeTracking
julia> function sampleFunc(x)
println(x)
y = 2x
return 2y* x
end
sampleFunc (generic function with 1 method)
julia> #code_expr sampleFunc(3)
:(function sampleFunc(x)
#= REPL[2]:1 =#
#= REPL[2]:2 =#
println(x)
#= REPL[2]:3 =#
y = 2x
#= REPL[2]:4 =#
return (2y) * x
end)

Related

put argument inside mathematical function in matlab [duplicate]

I want to write a function that returns the value of f(y) for any value of y:
f(y) =tan( sin(y) - sin(tan(y)) )
How can I write this as a function in MATLAB?
Here is an example function for your purpose
function y = f(x)
y = tan(sin(x)-sin(tan(x)));
end
You could use an anonymous function, as elluded to in the comments by
obchardon:
f = #(y) tan(sin(y) - sin(tan(y)))
% usage like any other function:
f(1)
Note that you do not include the (y) on the left hand side of the =, this syntax is reserved for indexing into variables, or symbolic math.

Evaluate integral limits using the antiderivatives expression, with a calculator

THE QUESTION IS
Is there a compact way to evaluate an antidevivative expression: x**3 / 2 | x = a; x = b
When we have an indefinite integral of the form:
# Pseudocode as I cannot write it in math mode
expr = x**2; a = 1; b = 5;
F = integral(expr, x); # integral of expr
Definite_integral = F.subs(x, b) - F.subs(x, a);
We can also do this by just using the built-in integrate function
# Pseudocode
expr = x**2;
a = 1; b = 5;
Definite_integra = integrate(expr, x, a, b) # integrate expr from a to b
However, the problem is that I start with an expression for the antiderivative
x**3 / 3
Ideally, I'd just want to express it with itegration brackets, example:
I don't want to repeat myself and write the expression twice and I don't really want to declare the expression as a (unnecessary; only used unce) function just to express it as: f(b) - f(a) or more in line with Ti Nspire notation: f(x)|x=b - f(x)|x=a
You can define bracket using a little helper function.
The screenshot below is from the Notes area.

Why wont this softmax function I have written in Julia change the input data?

I have written the softmax function in Julia. It performs softmax on a matrix row by row and changes the matrix. However, when I call the function in the REPL, it has no effect on the matrix. I do not understand why this is happening and I would really like an explanation.
"""
the following function performs softmax on a design matrix row by row
inputs: X:mxn matrix
output: none
"""
function softmax!(X::Array{Float64,2})
X = exp.(X)
for i = 1:size(X,1)
rowsum = sum(X[i,:])
X[i,:] /= rowsum
end
end
And here is an example call in the REPL:
julia> a = rand(2,5)
2×5 Array{Float64,2}:
0.069014 0.265159 0.489641 0.455672 0.0489479
0.274386 0.935308 0.41976 0.509558 0.234294
julia> softmax!(a)
julia> a
2×5 Array{Float64,2}:
0.069014 0.265159 0.489641 0.455672 0.0489479
0.274386 0.935308 0.41976 0.509558 0.234294
As you can see, there is no change in the matrix. What is extremely strange is if I hardcode what is inside the function in the REPL, I get the intended effect.
julia> a = exp.(a)
2×5 Array{Float64,2}:
1.07145 1.30364 1.63173 1.57723 1.05017
1.31572 2.548 1.5216 1.66456 1.26402
julia> for i = 1:size(a,1)
rowsum = sum(a[i,:])
a[i,:] /= rowsum
end
julia> a
2×5 Array{Float64,2}:
0.161504 0.196502 0.245957 0.237742 0.158295
0.158256 0.306475 0.183019 0.200214 0.152037
I know there is something I am not understanding but I am at a loss for what that might be. Any help will be much appreciated :)
you need to replace X = exp.(X) with X .= exp.(X). Julia is pass by sharing, so when you say X = exp.(X) from that point forward, the X in your function and the X you passed in refer to different memory.
Note also that this method is fairly inefficient since julia uses column major matrices. If you transpose your problem and write,
function softmax!(X::Array{Float64,2})
X .= exp.(X)
for j = 1:size(X,2)
#views rowsum = sum(X[:,j])
X[:,j] .*= 1/rowsum
end
end
it will be about 2x faster

How to fix nan in anonymous function?

Suppose I have a function f(x) defined, which gives nan when it is very large, say x>100. Fortunately, when x>100, I can replace f by another function g. So I would like to define:
h = #(x)isnan(f(x)).*f(x)+isnan(f(x)).*g(x)
However, when I substitute h(1001), it gives nan. Is it possible to define h so that it gives g(1001) instead of nan? The only restriction is that I need to have anonymous function h for later use, say I would like to use it in integration, i.e., integral(h,0,inf).
Example: Suppose I have a function:
f = #(x)x.*1./x
This function is very easy and must be 1. I construct a function:
g = #(x)isnan(f(x)).*0+isnan(f(x)).*1
How to make g to be well defined so that I can still evaluate integral(g,-1,1)? For this example, I know I can evaluate it easily, but my restriction is that I need to define anonymous function g and use integral to do it.
You would need to make a regular function and wrap it with the anonymous function.
i.e.
function r = ternary(a, b, c)
if (a)
r = b;
else
r = c;
end
end
h = #(x)ternary(isnan(f(x)), g(x), f(x));
Note that this will evaluate your function twice. A less generalized solution for your particular case that won't evaluate the function twice.
function r = avoidNAN(a, b)
if (isnan(a))
r = b;
else
r = a;
end
end
There is a solution without any additional functions:
f = #(x)x.*1./x;
g = #(x)100+x;
h= #(x)getfield(struct('a',f(x),'b',g(x)),char(isnan(f(x))+'a'))

creating function using matlab

I wrote the following function
% e is n×1 and y is n×1 vectors
function z=e_rand(e,y)
b_LS=regress(e,y)
z=b_LS*5
I saved the function in MATLAB toolbox.
But when I run the function I get the following error:
input argument "e" is undefined
How can I create the function correctly?
You DON'T RUN a function. You use it in an expression. You call your function at the command line. But you don't use the run command on a function. Run is only for scripts, not functions.
At the command line, just type this:
z = e_rand(e,y);
If you want to leave your function as-is, and encapsulate your function within another function, then you need to give e and y values in a parent function.
Try this:
function parent()
clear all, close all
n = randi(10, 1)
e = rand(n, 1)
y = rand(n, 1)
z = e_rand(e, y)
% e is [n×1] and y is [n×1] vectors
function z = e_rand(e, y)
b_LS = regress(e, y)
z = b_LS * 5
end
end
Works cited: http://www.mathworks.com/help/matlab/matlab_prog/nested-functions.html