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

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

Related

Write a function that takes as input `n` and returns the matrix C, Cij= 0 if i/j<2 , Cij =ij^2 otherwise in MATLAB

Consider the nxn matrix C with elements
Cij = 0 if i/j < 2
Cij = ij^2 otherwise
with 1 <= i,j <= n
Write a Matlab function matSetup that takes as input n and returns the matrix C. Use your function to create C for n = 6. function [Cij]= matSetup(n)
I have written this but it seems not to be correct
function Cij=matSetup(n)
for n=1:n
% whatever you write here is done with i=1, then i=2, then i=3, etc.
Cij(3,j)=i+7;
if (i/j)<2
Cij=0
else
Cij=i*(j)^2
end
end
end
Unfortunately, you can't just write something math-like and have a computer understand it. Things like 1<=i<=n have to be written instead with something like an explicit loop. For Matlab, here's one way to write a loop:
for i=1:n
% whatever you write here is done with i=1, then i=2, then i=3, etc.
end
To assign a value to an element of an array in Matlab, do something like this:
Cij(3,j)=i+7;
To test for a condition in Matlab, do this:
if i+3>2*j
% What you write here is done if the condition is true
else
% What you write here is done if the condition is false
end
If you put all of those things together correctly, you should be able to write your desired function.
Like the other answer, you should first learn to use loops to write a naive program to achieve your goal. When you are comfortable enough, you can try vectorizing your program with functions like meshgrid. Below is an example:
n = 20;
eps = 1/(n+1);
[x, y] = meshgrid(1:n, 1:n);
r = y./x;
z = heaviside(r - 2 + eps) .* y .* x.^2;

Vectorized function as output of matlabFunction

I am trying to automatize a process in MATLAB. I have a symbolic function that has to be converted into an anonymous function.
Basically, I have something like this:
syms x y z t
var = [x y z t];
f = x.^2+y;
gf = gradient(f, var);
gf_fun = matlabFunction(gf, 'vars', {var});
giving as output
gf_fun =
function_handle with value:
#(in1)[in1(:,1).*2.0;1.0;0.0;0.0]
Now, I'd like to evaluate this gf_fun in several points at a time, but, of course, I got strange results, due to how gf_fun is written. For example, if I want to evaluate gf_fun in 6 (different) points simultaneously, what I get is
rng('deafult')
vv = ones(6,4);
gf_fun(vv)
ans =
1.3575
1.5155
1.4863
0.7845
1.3110
0.3424
1.0000
0
0
instead of a matrix with dimensions 4x6, with each colomn being the evaluation of a single point.
I know that a workaround will be the use of a for loop, that is
results = zeros(4,6);
for i = 1:6
results(:,i) = gf_fun(vv(i,:));
end
but I must avoid it due to code performances reasons.
Is there a way to automatize all the process, having a matrix as output of gf_fun while evaluating different point at a time? So, basically, there is a simple way to replace the 0.0 and 1.0 in gf_fun with a more general zeros(size(in1)) and ones(size(in1)) automatically?
Thank you for you help!

How to resolve MATLAB trapz function error?

I am working on an assignment that requires me to use the trapz function in MATLAB in order to evaluate an integral. I believe I have written the code correctly, but the program returns answers that are wildly incorrect. I am attempting to find the integral of e^(-x^2) from 0 to 1.
x = linspace(0,1,2000);
y = zeros(1,2000);
for iCnt = 1:2000
y(iCnt) = e.^(-(x(iCnt)^2));
end
a = trapz(y);
disp(a);
This code currently returns
1.4929e+03
What am I doing incorrectly?
You need to just specify also the x values:
x = linspace(0,1,2000);
y = exp(-x.^2);
a = trapz(x,y)
a =
0.7468
More details:
First of all, in MATLAB you can use vectors to avoid for-loops for performing operation on arrays (vectors). So the whole four lines of code
y = zeros(1,2000);
for iCnt = 1:2000
y(iCnt) = exp(-(x(iCnt)^2));
end
will be translated to one line:
y = exp(-x.^2)
You defined x = linspace(0,1,2000) it means that you need to calculate the integral of the given function in range [0 1]. So there is a mistake in the way you calculate y which returns it to be in range [1 2000] and that is why you got the big number as the result.
In addition, in MATLAB you should use exp there is not function as e in MATLAB.
Also, if you plot the function in the range, you will see that the result makes sense because the whole page has an area of 1x1.

Avoiding for-loops in Matlab

I have a function as follows:
My optimized matlab code is:
function gamma = calcGamma(H, d, delta, f)
s= size(H);
Nv = s(1);
Ne = s(2);
gamma = zeros(Ne,1);
for e =1:Ne
hue = H(:,e);
sdu=f./sqrt(d);
mHUE = repmat(hue',Nv,1);
mHVE = repmat(hue,1,Nv);
mSDU = repmat(sdu',Nv,1);
mSd = repmat(sdu,1,Nv);
ss1 = mHUE .* mHVE/delta(e) .* (mSDU-mSd).^2;
gamma(e) = sum(ss1(:));
end
However, since Ne is very big, it takes quite a long time to calculate the function.
I see an similar question with a good solution, but I do not understand how it is derived.
Any solution to avoid the for-loop? Thanks
I am not sure if this will be faster, but instead of your trick with repmat, you can use bsxfun. This trick is pretty similar to the array broadcasting that is standard in numpy and saves the creation of the large intermediate matrices like mHUE.
Another thing you should always do is to move everything out of the loop that does not depend on e. It seems to me that the calculation of sdu is totally constant, so do that once before the loop. And I guess that delta(e) is a scalar, so instead of dividing the big matrices by that, do it once afterwards:
s= size(H);
Nv = s(1);
Ne = s(2);
gamma = zeros(Ne,1);
sdu = f./sqrt(d);
M = bsxfun(#minus, sdu', sdu).^2;
for e =1:Ne
hue = H(:,e);
ss1 = bsxfun(#times, hue', hue) .* M;
gamma(e) = sum(ss1(:));
end
gamma = gamma ./ delta;
It might be possible to remove the for-loop, but it is doubtful that that will increase speed, since you have just a single loop and your calculation time is anyhow dominated by the multiplication of the big matrices. Moreover, removing the for-loop will just make your function very hard to understand, so just leave it as is.

Implementing iterative solution of integral equation in Matlab

We have an equation similar to the Fredholm integral equation of second kind.
To solve this equation we have been given an iterative solution that is guaranteed to converge for our specific equation. Now our only problem consists in implementing this iterative prodedure in MATLAB.
For now, the problematic part of our code looks like this:
function delta = delta(x,a,P,H,E,c,c0,w)
delt = #(x)delta_a(x,a,P,H,E,c0,w);
for i=1:500
delt = #(x)delt(x) - 1/E.*integral(#(xi)((c(1)-c(2)*delt(xi))*ms(xi,x,a,P,H,w)),0,a-0.001);
end
delta=delt;
end
delta_a is a function of x, and represent the initial value of the iteration. ms is a function of x and xi.
As you might see we want delt to depend on both x (before the integral) and xi (inside of the integral) in the iteration. Unfortunately this way of writing the code (with the function handle) does not give us a numerical value, as we wish. We can't either write delt as two different functions, one of x and one of xi, since xi is not defined (until integral defines it). So, how can we make sure that delt depends on xi inside of the integral, and still get a numerical value out of the iteration?
Do any of you have any suggestions to how we might solve this?
Using numerical integration
Explanation of the input parameters: x is a vector of numerical values, all the rest are constants. A problem with my code is that the input parameter x is not being used (I guess this means that x is being treated as a symbol).
It looks like you can do a nesting of anonymous functions in MATLAB:
f =
#(x)2*x
>> ff = #(x) f(f(x))
ff =
#(x)f(f(x))
>> ff(2)
ans =
8
>> f = ff;
>> f(2)
ans =
8
Also it is possible to rebind the pointers to the functions.
Thus, you can set up your iteration like
delta_old = #(x) delta_a(x)
for i=1:500
delta_new = #(x) delta_old(x) - integral(#(xi),delta_old(xi))
delta_old = delta_new
end
plus the inclusion of your parameters...
You may want to consider to solve a discretized version of your problem.
Let K be the matrix which discretizes your Fredholm kernel k(t,s), e.g.
K(i,j) = int_a^b K(x_i, s) l_j(s) ds
where l_j(s) is, for instance, the j-th lagrange interpolant associated to the interpolation nodes (x_i) = x_1,x_2,...,x_n.
Then, solving your Picard iterations is as simple as doing
phi_n+1 = f + K*phi_n
i.e.
for i = 1:N
phi = f + K*phi
end
where phi_n and f are the nodal values of phi and f on the (x_i).