[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Plotting an ELU function with GNU Octave
From: |
Juan Pablo Carbajal |
Subject: |
Re: Plotting an ELU function with GNU Octave |
Date: |
Fri, 5 Feb 2021 12:16:46 +0100 |
On Thu, Feb 4, 2021 at 8:53 PM Brett Green <green.brett.r@gmail.com> wrote:
>
>
> On Thu, Feb 4, 2021 at 2:27 PM Alexandru Munteanu
> <alexandru.munteanu@e-uvt.ro> 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