Why Euler's number e = 2.71828... is not a built-in constant in MATLAB?

494 ビュー (過去 30 日間)
Kareem Elgindy
Kareem Elgindy 2020 年 6 月 17 日
編集済み: David Goodmanson 2020 年 6 月 27 日
I understand that we can produce that number in MATLAB by evaluating exp(1), or possibly using exp(sym(1)) for the exact representation. But e is a very common constant in mathematics and it is as important as pi to some scholars, so after all these many versions of MATLAB, why haven't they recognize this valuable constant yet and show some appreciation by defining it as an individual constant rather than having to use the exp function for that?
  13 件のコメント
Kareem Elgindy
Kareem Elgindy 2020 年 6 月 18 日
I did John. Thank you brother.

サインインしてコメントする。

回答 (2 件)

John D'Errico
John D'Errico 2020 年 6 月 18 日
編集済み: John D'Errico 2020 年 6 月 18 日
Let me add this as an answer, because there are very good reasons to leave e as not a named constant, instead of naming it. Yes, they could have given you e, as well as pi and i. To be honest, there is just as good of an argument to have created many such named constants. For example, phi, the golden ratio. phi appears in zillions of places in mathematics. Luckily, phi is easy to compute, as
phi = (1 + sqrt(5))/2
phi =
1.61803398874989
in case you ever need it. Or you could compute it in this form equally useful form:
phi = (sqrt(5) - 1)/2
phi =
0.618033988749895
which happens to be just the inverse of the first.
But then there is the Euler-Mascheroni constant, often called the Euler gamma, or just gamma by some. And we already have a hugely valuable function named gamma, which computes the gamma function. I use gamma a LOT as a function. But some people would want to see the Euler gamma as a constant too.
You can actually find this in the symbolic toolbox as eulergamma.
vpa(eulergamma)
ans =
0.5772156649015328606065120900824
Note that it exists as a function with a long name, but it is there if you need it. And some people would have great arguments to include Avogadro's number, the Planck constant, or the speed of light. So there are some named constants. But really only the two of them. If it bothers you, you could theoretically write a function for e, but in fact, I strongly recommend that you do not do so in the case of e!
It would not have cost a lot, or so it would seem. It would have created some possible places for confusion as the comments suggest, because e is used by itself as an indicator of scientific notation.
If for some reason, you wanted the number, you can always compute it directly as exp(1). So this is even easier than computing the golden ratio constant. But let me ask you this: Why do you think you want it? Why do you think you want the number e in MATLAB?
Really, there is only one reason why you might want to have e laying around. That is to use it in the form e^x. There is a fundamental problem in that idea though, because it is both more efficient and more accurate to use the exp function directly. And exp(x) is used a LOT in mathematics. If the creators of MATLAB wanted to encourage people to compute e^x, they would have provided you with the constant e. But they really don't want to do that.
So you have the function exp. In fact, this is a commonly provided function in almost every computer language you will ever learn. Everything from spreadsheets to fortran to languages like MATLAB and Python. They will have a function probably called exp. It does exactly what you expect. It computes exp(x), and is highly optimized to compute exactly that function to within machine precision.
If you were to start writing it in the form of e^x, then this would put more load on less efficient libraries, that are set up to raise some arbitrary number to a power. In fact, we can even test this out:
E = exp(1)
E =
2.71828182845905
>> exp(2.5)
ans =
12.1824939607035
>> exp(2.5) - E^2.5
ans =
-3.5527136788005e-15
Interesting, no? It looks like exp(2.5) and E^2.5 produce slightly different results. Which is closer to the true value? Remember that E is a number pretty much as close as we can produce in MATLAB, to double precision accuracy. It won't help if you provided 20 significant digits for e, as MATLAB can store only 52 binary bits in the end anyway.
% What MATLAB produces using exp:
sprintf('%0.55f',exp(2.5))
ans =
'12.1824939607034732347301542176865041255950927734375000000'
% If you use E^2.5,
sprintf('%0.55f',E^2.5)
ans =
'12.1824939607034767874438330181874334812164306640625000000'
As you can see, they differ down in the digits where one goes ...034732, and the alternative goes ...034767. But which is closer to the truth? We can test that out using VPA and the symbolic toolbox.
vpa(exp(sym(2.5)))
ans =
12.182493960703473438070175951168
Here we see the correct value of exp(2.5) goes ...034734.
Essentially, we got an extra decimal digit of accuracy, by using the function exp. And it would not have helped if we defined E differently. We still get the wrong answer. Here, for example, I might use the symbolic toolbox to create E. In the end, it will be a double precision number, stored internally using an IEEE arithmetic floating point format.
E = double(exp(sym(1)))
E =
2.71828182845905
>> exp(2.5) - E^2.5
ans =
1.77635683940025e-15
>> sprintf('%0.55f',E^2.5)
ans =
'12.1824939607034714583733148174360394477844238281250000000'
Again, we get a result that is not as accurate as just using exp(2.5).
Thus in terms of accuracy, you want to use the function exp. But there are always two things we care about in computing, accuracy and speed. So how about speed? Here, remember that E is the constant we have created. It is a double precision number.
X = rand(1000);
>> timeit(@() exp(X))
ans =
0.0015833418125
>> timeit(@() E.^X)
ans =
0.0068411758125
Interesting, no? It is actually more than 4 times as fast to compute exp(X) as it was to compute E.^X. What are the odds someone who was doing some truly heavy duty computing would be upset if they saw such a differential in time? Honestly, they would have a fit.
Finally, how about consistency? Suppose The MathWorks decided to do as you wish, and they provided a named constant for e? I don't totally care what short name they chose. Think about what will happen. Now, every time someone tries to compute exp(x) versus e.^x, they might get subtly different results. Different down in the least significant bits, but DIFFERENT! Can you imagine the number of headaches they would have, trying to deal with this? The number of bug reports they would get?
So let me ask you to NOT define your own constant for E. You could do so, as some have suggested. But you will be happier in the end if you don't. You think you want it, but sometimes, what you think you want is an illusion. Just use the function exp, as people all around the world have happily done for many years. There are even several good reasons to do so.
  25 件のコメント
David Goodmanson
David Goodmanson 2020 年 6 月 27 日
編集済み: David Goodmanson 2020 年 6 月 27 日
Hi Kareem,
you are correct. I rather expected that vpa(exp(1),25) would give the right result and was going with that, but
vpa(exp(1),25)
ans = 2.718281828459045534884808
^
whereas
vpa(exp(sym(1)),25)
ans = 2.718281828459045235360287
is correct.

サインインしてコメントする。


Kareem Elgindy
Kareem Elgindy 2020 年 6 月 20 日
編集済み: Kareem Elgindy 2020 年 6 月 20 日
Great feedback @Rik. Could you tell us more about JIT compiler or perhaps pointing out to a simple reference to learn about it quickly? I'm a mathematician not an expert programmer in MATLAB, but trying to improve my skillls and understanding of its features and capabilities. It's good to have you with us today. The example you gave about a=zeros(200) is just stunning. I tested this example in my personal laptop-- I'm using MATLAB 2019b:
>> tic, a=[];a(200,200)=0; toc, tic, a=zeros(200); toc
Elapsed time is 0.000520 seconds.
Elapsed time is 0.000381 seconds.
I was so delighted to learn that common sense wins in this case :-).
  2 件のコメント
Kareem Elgindy
Kareem Elgindy 2020 年 6 月 20 日
Thanks @Rik.

サインインしてコメントする。

製品

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by