Forcing MATLAB to use `single` precision as default? - matlab

Is there a way to force MATLAB to use single precision as default precision?
I have a MATLAB code, whose output I need to compare to C code output, and C code is written exclusively using floats, no doubles allowed.

Short answer: You can't.
Longer answer: In most cases, you can get around this by setting your initial variables to single. Once that's done, that type will (almost always) propagate down through your code. (cf. this and this thread on MathWorks).
So, for instance, if you do something like:
>> x = single(magic(4));
>> y = double(6);
>> x * y
ans =
4×4 single matrix
96 12 18 78
30 66 60 48
54 42 36 72
24 84 90 6
MATLAB keeps the answer in the lower precision. I have occasionally encountered functions, both built-in and from the FileExchange, that recast the output to be a double, so you will want to sprinkle in the occasional assert statement to keep things honest during your initial debugging (or better yet put the assertion as the first lines of any sub-functions you write to check the critical inputs), but this should get you 99% of the way there.

You can convert any object A to single precision using A=single(A);
The Mathworks forums show that
in your case: system-specific('precision','8'); should do it. Try this in the console or add at the top of your script.

Related

What is the link between randi and rand?

I'm running on R2012a version. I tried to write a function that imitates randi using rand (only rand), producing the same output when the same arguments are passed and the same seed is provided. I tried something with the command window and here's what I got:
>> s = rng;
>> R1 = randi([2 20], 3, 5)
R1 =
2 16 11 15 14
10 17 10 16 14
9 5 14 7 5
>> rng(s)
>> R2 = 2+18*rand(3, 5)
R2 =
2.6200 15.7793 10.8158 14.7686 14.2346
9.8974 16.3136 10.0206 15.5844 13.7918
8.8681 5.3637 13.6336 6.9685 4.9270
>>
A swift comparison led me to believe that there's some link between the two: each integer in R1 is within plus or minus unity from the corresponding element in R2. Nonetheless, I failed to go any further: I checked for ceiling, flooring, fixing and rounding but neither of them seems to work.
randi([2 20]) generates integers between 2 and 20, both included. That is, it can generate 19 different values, not 18.
19 * rand
generates values uniformly distributed within the half-open interval [0,19), flooring it gives you uniformly distributed integers in the range [0,18].
Thus, in general,
x = randi([a,b]]);
y = rand * (b-a+1) + a;
should yield numbers with the same property. From OP’s experiment it looks like they might generate the same sequence, but this cannot be guaranteed, and it likely doesn't.
Why? It is likely that randi is not implemented in terms of rand, but it’s underlying random generator, which produces integers. To go from a random integer x in a large range ([0,N-1]) to one in a small range ([0,n-1]), you would normally use the modulo operator (mod(x,N)) or a floored division like above, but remove a small subset of the values that skew the distribution. This other anser gives a detailed explanation. I like to think of it in terms of examples:
Say random values are in the range [0,2^16-1] (N=2^16) and you want values in the range [0,18] (n=19). mod(19,2^16)=5. That is, the largest 5 values that can be generated by the random number generator are mapped to the lowest 5 values of the output range (assuming the modulo method), leaving those numbers slightly more likely to be generated than the rest of the output range. These lowest 5 values have a chance floor(N/n)+1, whereas the rest has a chance floor(N/n). This is bad. [Using floored division instead of modulo yields a different distribution of the unevenness, but the end result is the same: some numbers are slightly more likely than others.]
To solve this issue, a correct implementation does as follows: if you get one of the values in the random generator that are floor(N/n)*n or higher, you need to throw it away and try again. This is a very small chance, of course, with a typical random number generator that uses N=2^64.
Though we don't know how randi is implemented, we can be fairly certain that it follows the correct implementation described here. So your sequence based on rand might be right for millions of numbers, but then start deviating.
Interestingly enough, Octave's randi is implemented as an M-file, so we can see how they do it. And it turns out it uses the wrong algorithm shown at the top of this answer, based on rand:
ri = imin + floor ( (imax-imin+1)*rand (varargin{:}) );
Thus, Octave's randi is biased!

Get matlab to show square roots (i.e. 2^(1/2) instead of 1.414)

I have a few simple equations that I want to pipe through matlab. But I would like to get exact answers, because these values are expected to be used and simplified later on.
Right now Matlab shows sqrt(2.0) as 1.1414 instead of something like 2^(1/2) as I would like.
I tried turning on format rat but this is dangerous becasue it shows sqrt(2) as 1393/985 without any sort of warning.
There is "symbolic math" but it seems like overkill.
All I want is that 2 + sqrt(50) would return something like 2 + 5 * (2)^(1/2) and even my 5 years old CASIO calculator can do this!
So what can I do to get 2 + sqrt(50) evaluate to 2 + 5 * (2)^(1/2) in matlab?
As per #Oleg's comment use symbolic math.
x=sym('2')+sqrt(sym('50'))
x =
5*2^(1/2) + 2
The average time on ten thousand iterations through this expression is 1.2 milliseconds, whilst the time for the numeric expression (x=2+sqrt(50)) is only 0.4 micro seconds, i.e. a factor of ten thousand faster.
I did pre-run the symbolic expression 50 times, because, as Oleg points out in his second comment the symbolic engine needs some warming up. The first run through your expression took my pc almost 2 seconds.
I would therefore recommend using numeric equations due to the huge difference in calculation time. Only use symbolic expressions when you are forced to (e.g. simplifying expressions for a paper) and then use a symbolic computation engine like Maple or Wolfram Alpha.
Matlab main engine is not symbolic but numeric.
Symbolic toolbox. Create expression in x and subs x = 50
syms x
f = 2+sqrt(x)
subs(f,50)
ans =
50^(1/2) + 2

Matlab: Chi-squared fit (chi2gof) to test if data is exponentially distributed

I guess this is a simple question, but I can't sort it out. I have a vector, the first elements of which look like:
V = [31 52 38 29 29 34 29 24 25 25 32 28 24 28 29 ...];
and I want to perform a chi2gof test in Matlab to test if V is exponentially distributed. I did:
[h,p] = chi2gof(V,'cdf',#expcdf);
but I get a warning message saying:
Warning: After pooling, some bins still have low expected counts.
The chi-square approximation may not be accurate
Have I defined the chi2gof call incorrectly?
At 36 values, you have a very small sample set. From the second sentence of Wikipedia's article on the chi-squared test (emphasis added):
It is suitable for unpaired data from large samples.
Large in this case usually means around at least 100. Read about more assumptions of this test here.
Alternatives
You might try kstest in Matlab, which is based on the Kolmogorov-Smirnov test:
[h,p] = kstest(V,'cdf',[V(:) expcdf(V(:),expfit(V))])
Or try lillietest, which is based on the Lilliefors test and has an option specifically for exponential distributed data:
[h,p] = lillietest(V,'Distribution','exp')
In case you can increase your sample size, you are doing one thing wrong with chi2gof. From the help for the 'cdf' option:
A fully specified cumulative distribution function. This
can be a ProbabilityDistribution object, a function
handle, or a function. name. The function must take X
values as its only argument. Alternately, you may provide
a cell array whose first element is a function name or
handle, and whose later elements are parameter values,
one per cell. The function must take X values as its
first argument, and other parameters as later arguments.
You're not supplying any additional parameters, so expcdf is using the default mean parameter of mu = 1. Your data values are very large and don't correspond at all an exponential distribution with this mean. You need to estimate parameters as well. You the expfit function, which is basted on maximum likelihood expectation, you might try something like this:
[h,p] = chi2gof(V,'cdf',#(x)expcdf(x,expfit(x)),'nparams',1)
However, with only 36 samples you may not get a very good estimate for a distribution like this and still may not get expected results even for data sampled from a known distribution, e.g.:
V = exprnd(10,1,36);
[h,p] = chi2gof(V,'cdf',#(x)expcdf(x,expfit(x)),'nparams',1)

What is wrong with my simple matlab code

(X^2)(1,2)
X is a square matrix, I just want to get the element from position (1,2) from (X^2) why it does not work?
Indexing is syntactically not allowed in this case. The simplest workaround is to use getfield
X=magic(5)
X =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
>> getfield(X^2,{1,3})
ans =
725
That's not how Matlab works. You need to assign the result of the matrix multiplication to another matrix, then use it:
A = X^2;
disp(A(1,2));
This is assuming that you really did mean to do matrix multiplication, and not multiply element by element. In the latter case you could have done
disp(X(1,2)^2)
And if you are interested in matrix multiplied result, then
disp(X(1,:)*X(:,2))
will do it, since that is how element (1,2) is calculated. This last solution has the advantage of being very efficient since you only calculate the element you need, instead of computing the entire matrix and throwing N^2-1 elements away just to keep the one. For bigger matrices that will make a difference. Of course it makes the code slightly less readable so I would always recommend writing a comment in your code when you do that - your future self will thank you...
edit take a look at http://www.mathworks.com/matlabcentral/newsreader/view_thread/235798 - that thread broadly agrees with my first statement, although it hints that the syntax you desire might be "part of a future release". But that was said 6 years ago, and it's still not here... It also shows some pretty obscure workarounds; I recommend not going that route (because all the workarounds do is hide the fact that you compute the matrix, then pick just one element. So the workload on the computer is no smaller.)

What does 8.309618000000001D-02 mean in QBASIC

I have a QBASIC program that basically consists of formulas and constants, and I want to translate the formulas and constants into a C++ programm. Since the formulas are not rocket science and the program is well documented, I have no problem translating the program, although I have not used or seen QBASIC before.
However, there is an initialization of a variable that reads abc(15) = 9.207134000000001D-02, and I am not sure how to interpret the D-02. I guess I should translate it like abc[15] =0.09207134...., but I'd like to verify if this is correct.
If I recall correctly D-02 means times ten raised to the power minus 2.
So 8.309618000000001D-02 = 8.30961800000000 x 10^(-2)
which is roughly 0.08309618
I also think the D means the type of the number is a double.
EDIT: It's been ages since I wrote any QBASIC code
Yes he is right the D means that the number is a double and the -2 after the D means it is multiplied by 10 to the power of negative 2 which means it is 0.08309618 to the precision of qbasics double precision numbers which is 52 or 54 bits If I remember corectly