Re: Plotting an ELU function with GNU Octave
Juan Pablo Carbajal <[email protected]>
| Newsgroups | gmane.comp.gnu.octave.general |
|---|---|
| Message-ID | <CABDtPkSNXT1yD_n8xJ06gMLeiWh4crGwjkSthfU3pxgF-94ycw@mail.gmail.com> |
On Thu, Feb 4, 2021 at 8:53 PM Brett Green <[email protected]> wrote: > > > On Thu, Feb 4, 2021 at 2:27 PM Alexandru Munteanu <[email protected]> wrote: >> >> Hello, >> >> I am trying to create plots for an ELU (Exponential Liniear Unit) >> funciton. The function is defined as follows: >> >> function e = elu(z, alpha) >> if z >= 0 >> e = z >> else >> e = alpha * ((exp(z)) - 1) >> endif >> endfunction >> >> So this is pretty simple so far (alpha is a constant of values 0.01), >> and I can test to evaluate it in the interpreter and everything is >> working as expected. >> >> >> However, I want to plot the values of elu(x), where x belongs to the >> interval (-5, 5). >> >> function plot_elu >> x = -5:0.01:5 >> y = elu(x, 0.01) >> >> plot(x, y, "linewidth", 5) >> set(gca,"fontsize", 25) >> axis([-6, 6, -1.2, 1.2]) >> grid on; >> endfunction >> >> This is where the plot goes wrong: it creates the plot as if the values >> for elu are all going on the second branch of the if-then-else >> statement. >> >> I have attached what the plot looks like. Any help in this direction is appreciated. >> >> -- >> Alexandru Munteanu >> > > The if statement does not operate elementwise, which is the cause of your problem. The expression > > y = (x>=0).*x + (x<0).*alpha.*(exp(x)-1) > > is essentially an elementwise if-else statement. > > Try something more like this. > > x = -5:0.01:5 > alpha = 0.01 > y = (x>=0).*x + (x<0).*alpha.*(exp(x)-1) > plot(x, y, "linewidth", 5) > set(gca,"fontsize", 25) > axis([-6, 6, -1.2, 1.2]) > grid on > > - Brett Green That solution is perfectly acceptable for this case. However if the computational cost of the different branches of your function is not that low you could use a mask, e.g. y = zeros(size(x)); # allocate space for the answer (needed for the mask to work) x_ge_zero = (x >= 0); # this is the mask. Parenthesis are not needed y(x_ge_zero) = x(x_ge_zero); # y(x) = x if x >=0 y(!x_ge_zero) = alpha .* expm1 (x(!x_ge_zero)); # y(x) = exp(x) - 1 if x < 0. Use expm1 instead of exp(x) - 1 This approach also has the advantage that you can do boolean operations on the mask. x_abs_gt_one = abs(x) > 1 msk = x_abs_gt_one & x_ge_zero # x is non-negative and with absolute value bigger than 1