Got Questions? Get Answers.
Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Computation precision on command line and in scripts

Subject: Computation precision on command line and in scripts

From: Pierre

Date: 7 Feb, 2013 12:16:08

Message: 1 of 10

Hi All,
I am seeing different behavior between computations on the command line and computations in .m scripts. (R2011a) Here is an example

a = zeros(1);
a(:) = single(1) + 1e-9 - 1

On the command line this gives: 1.000000082740371e-009
When done in a .m function: 0
When in a debugger: 0
Is this to be expected?

The underlying question was: Are computations with singles performed in double or in single precision??
It seems, on the command line in double precision. And in a function in single precision. Is this the right conclusion?

Subject: Computation precision on command line and in scripts

From: Bruno Luong

Date: 7 Feb, 2013 14:39:09

Message: 2 of 10

"Pierre" wrote in message <kf05u8$9n3$1@newscl01ah.mathworks.com>...

>
> The underlying question was: Are computations with singles performed in double or in single precision??

This question is interesting but actually is not a right question to ask.

The documentation states that

1) an arithmetic expression is mixed with two numerical type, the result is cast in lower type, then the operation is carried out.

2) The expression is evaluated from left to right

That explains the result like:

>> uint8(1)+(0.4+0.1+0.1+0.1)

ans =

    2

>> 0.4+0.1+0.1+0.1+uint8(1)

ans =

    2

>>

IMO the observation in your example is not due to casting, but due to JIT accelerator might detect (single(1) - 1) is 0. The JIT is activated or not in different mode (command line, function, or debug mode). It also depends on which MATLAB version you are running.

Bruno

Subject: Computation precision on command line and in scripts

From: Bruno Luong

Date: 7 Feb, 2013 14:42:08

Message: 3 of 10

Should read:

>> 0.4+0.1+0.1+0.1+uint8(1)

ans =

    2

>> uint8(1)+0.4+0.1+0.1+0.1

ans =

    1

% Bruno

Subject: Computation precision on command line and in scripts

From: Pierre

Date: 7 Feb, 2013 15:39:08

Message: 4 of 10

"Bruno Luong" <b.luong@fogale.findmycountry> wrote in message <kf0eac$cch$1@newscl01ah.mathworks.com>...
> "Pierre" wrote in message <kf05u8$9n3$1@newscl01ah.mathworks.com>...
>
> >
> > The underlying question was: Are computations with singles performed in double or in single precision??
>
> This question is interesting but actually is not a right question to ask.

You got me smiling :)

I've read (parts of) the documentation and thus I indeed expect the arithmetic to be done in singles. But if done in singles, I would expect 0 as outcome.
Blaming JIT settings does not really satisfy me (and it is not documented, as far as I can search).

I've not been able to reverse engineer how Matlab does the computation, other variants give other numbers. E.g.
a(:) = single(1) + (1e-9 - 1) results in: 9.999999717180685e-010
(Which I would expect btw.)

Help appreciated!
Regards,
Pierre

Subject: Computation precision on command line and in scripts

From: Pierre

Date: 7 Feb, 2013 15:50:11

Message: 5 of 10

"Pierre" wrote in message <kf0hqs$r3e$1@newscl01ah.mathworks.com>...

> I've not been able to reverse engineer how Matlab does the computation, other variants give other numbers. E.g.
> a(:) = single(1) + (1e-9 - 1) results in: 9.999999717180685e-010
> (Which I would expect btw.)

Err, on second thought, no I did not expect this if evaluated in single precision.
 a(:) = single(1) + single(1e-9 - 1) results in: 0

Subject: Computation precision on command line and in scripts

From: Bruno Luong

Date: 7 Feb, 2013 17:30:13

Message: 6 of 10

"Pierre" wrote in message <kf0hqs$r3e$1@newscl01ah.mathworks.com>...

> Blaming JIT settings does not really satisfy me (and it is not documented, as far as I can search).

They are unfortunately not documented. Understandable decision because users should not rely on those optimizations, they can change quickly from version to version. I bellieve Loren must write few useful things on her blog on the subject.

The best is user should make the code robust to JIT or order of evaluation.

Bruno

Subject: Computation precision on command line and in scripts

From: Bruno Luong

Date: 7 Feb, 2013 21:12:08

Message: 7 of 10

"Bruno Luong" <b.luong@fogale.findmycountry> wrote in message >
> The documentation states that
>
> 1) an arithmetic expression is mixed with two numerical type, the result is cast in lower type, then the operation is carried out.
>
> 2) The expression is evaluated from left to right
>

It seems that this rule does not applied for scalar expression affected with colon operator on the lhs. To avoid JIT, I put the argument as parameters of foo function.

function [a rd rs] = foo(b, c, d)

a = zeros(1,2,'double');
bar = b + c -d;
a(1) = b + c -d;
a(2) = bar;

rd = 0;
rd(:) = b + c -d;

rs = single(0);
rs(:) = b + c -d;

end % foo

% and here is the result

>> [a rd rs] = foo(single(1),1e-9,1)

a =

     0 0


rd =

   1.0000e-09


rs =

  1.0000e-09

>>

Subject: Computation precision on command line and in scripts

From: Bruno Luong

Date: 9 Feb, 2013 10:10:10

Message: 8 of 10

Update. I'm now pretty sure the JIT accelerator does something when the lhs is a scalar (:).

What I did is force calling the built-in function by a wrap functions, so JIT is not kicked in, and the result is different only when the scalar LHS is indexed by (:).

Here is the code that shows what is going on:

function [a rd_colon rd] = foo(b, c, d, bsxflag)

if nargin >= 4 && bsxflag
    % http://www.mathworks.com/matlabcentral/fileexchange/23821-bsxops
    bsxops(1);
end

a = zeros(1,2,'double');
bar = b + c - d;
a(1) = b + c - d; % always 0
a(2) = bar; % always 0

rd_colon = double(0); % <= zeros(1,1,'double');
rd_colon(:) = b + c - d; % 1.0000e-09 when bsxflag is FALSE

rd = b + c - d; % always 0

bsxops(0);

end % foo

% Test on command line (2012B, WIN7-64):

>> [a rd_colon rd] = foo(single(1),double(1e-9),double(1), 0)

a =

     0 0


rd_colon =

   1.0000e-09


rd =

     0

>> [a rd_colon rd] = foo(single(1),double(1e-9),double(1), 1)

a =

     0 0


rd_colon =

     0


rd =

     0

% Bruno

Subject: Computation precision on command line and in scripts

From: Pierre

Date: 11 Feb, 2013 09:45:11

Message: 9 of 10

Bruno, thanks for your investigations!
I have to admit though I need to dig into bsxops to fully understand your reasoning.

Can one assume now JIT changes the order of execution? And it is applied on command line input only?

Subject: Computation precision on command line and in scripts

From: Bruno Luong

Date: 11 Feb, 2013 11:59:09

Message: 10 of 10

"Pierre" wrote in message <kfaej7$caq$1@newscl01ah.mathworks.com>...

> Can one assume now JIT changes the order of execution?

Or casting. I don't know exactly what the JIT does really.

You might submit your observation to the TMW support. It would be nice to get a comment from them on the lack of consistency of the results (stricly speaking I'm not sure they own an explanation though).

> And it is applied on command line input only?

No, in my tests (2012A and B), the command line gives the same result as with function.

Bruno

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us