rng('default') for rand() function in MATLAB vs Octave - matlab

I have a matlab piece of code that generates same random numbers (rand(n,1)) when I initialize with rng('default');
Example:
>> rng('default');
>> rand(3,1)
ans =
0.8147
0.9058
0.1270
Now I need to generate the same output in Octave. Is there an equivalent function for rng('default') in Octave? Please advise on how to get the same set of random numbers as MATLAB in Octave.

From the rand documentation for Octave
By default, the generator is initialized from /dev/urandom if it is available, otherwise from CPU time, wall clock time, and the current fraction of a second. Note that this differs from MATLAB, which always initializes the state to the same state at startup. To obtain behavior comparable to MATLAB, initialize with a deterministic state vector in Octave’s startup files (see ‘Startup Files’).
To get around this difference, you will have to seed both the MATLAB and Octave random number generator, and specify the generation method, to try and ensure they're doing the same thing. Note I say "try" because fundamentally they're different languages and there is no equivalency guarantee.
However, it appears that MATLAB and Octave don't use equivalent seeds. User Markuman has provided an example on the Octave wiki to get around this
Octave
function ret = twister_seed(SEED=0)
ret = uint32(zeros(625,1));
ret(1) = SEED;
for N = 1:623
## initialize_generator
# bit-xor (right shift by 30 bits)
uint64(1812433253)*uint64(bitxor(ret(N),bitshift(ret(N),-30)))+N; # has to be uint64, otherwise in 4th iteration hit maximum of uint32!
ret(N+1) = uint32(bitand(ans,uint64(intmax('uint32')))); # untempered numbers
endfor
ret(end) = 1;
endfunction
octave:1> rand('twister',twister_seed) # notice: default seed is 0 in the function
octave:2> rand
ans = 0.548813503927325
octave:3> rand
ans = 0.715189366372419
octave:4> rand
ans = 0.602763376071644
MATLAB
>> rand('twister',0)
>> rand
ans =
0.548813503927325
>> rand
ans =
0.715189366372419
>> rand
ans =
0.602763376071644
So from the documentation quote at the top of this answer, you could set the random number generator seed during Octave startup if you want this behaviour by default.

Related

Find the optimum combination

I am trying to optimise this: function [ LPS, LCE ] = runProject( Nw, Np, Nb) which calls some other functions I have written before. The idea is to find the optimum combination of Nw, Np, Nb AND keep the LPS=0, while LCE is minimum. Nw, Np, Nb should be positive integers. LCE will also be positive.
function [ LPS, LCE ] = runProject( Nw, Np, Nb)
%
% Detailed explanation goes here
[Pg, Pw, Pp] = Pgener();
[Pb, LPS] = Bat( Pg );
[LCE] = Constr(Pw, Pp, Nb)
end
However, I tried the gamultiobj solver from the Global Optimization Toolbox of matlab2015 (trial version) for a different approach with pareto front, but I got the error:
"Optimization running.
Error running optimization.
Not enough input arguments."
You should write your objective function like the following example:
function scores = rastriginsfcn(pop)
%RASTRIGINSFCN Compute the "Rastrigin" function.
% pop = max(-5.12,min(5.12,pop));
scores = 10.0 * size(pop,2) + sum(pop .^2 - 10.0 * cos(2 * pi .* pop),2);
As you can see, the function accepts all the inputs as a single vector pop.
With such representation I can evaluate the function as follows:
rastriginsfcn([2 3])
>> ans
13
Still for running the optimization from the toolbox you have to mention the number of variables, for instance, in my example it is equal to 2:
[x fval exitflag] = ga(#rastriginsfcn, 2)
It is the same for the multi-objective optimization. Check the following image from MATHWORKS:

Insanely huge numbers in symbolic variables after assigning double

I first define some differential equations:
%% Definitions
% Constants
syms L R J Ke p
% Input
syms ud uq m
% Output
syms id iq ome theta
% Derivations
syms did diq dome dtheta
%% Equations
did=(ud/L)-(R/L)*id+ome*iq;
diq=(uq/L)-(R/L)*iq-ome*id-(Ke/L)*ome;
dome = (p/J)*((3/2)*p*Ke*iq-m);
dtheta = ome;
I'm trying to calculate R and L now. The input and output variables come from simulink:
idvalues = DQ_OUT.signals.values(:,1);
iqvalues = DQ_OUT.signals.values(:,2);
udvalues = UIdq.signals.values(:,1);
uqvalues = UIdq.signals.values(:,2);
% ... define some position in these arrays ...
% Define values for symbolic variables
id=idvalues(position);
ud=udvalues(position);
iq=iqvalues(position);
ome=iqvalues(position);
These are double. I then eval the first equation:
eval(did)
And I get this crap:
ans =
6002386699416615/(18014398509481984*L) - (846927175344863*R)/(1125899906842624*L) + 4168268387464377/9007199254740992
I was thinking that mathematics calculator like matlab won't bother you with variable types, but what I see here is definitely variable type problem - the actual values are less than 1:
Specifically:
id = 0.7522
ud = 0.3332
iq = 0.6803
ome = 0.6803
When doing symbolic calculations, Matlab uses rational numbers for small decimals. This prevents floating point numerical issues and keeps the results exact. However as you found, it makes the results harder to read.
Matlab also has a vpa (variable precision arithmetic) function, which is capable of keeping up to 2^(29)+1 digits (apparently) in calculations, which means Matlab doesn't need to stick to rational functions in order to maintain exact results.
Before viewing the output of a symbolic calculation, use vpa to convert rational numbers with large numerators/denominators to decimal expansions, by using, in your case, vpa(eval(did)).
For example, defining
syms a
b=0.75221
then a*b gives
>> a*b
ans =
(75221*a)/100000
but vpa(a*b) gives
>> vpa(a*b)
ans =
0.75221*a

Matlab nchoosek got difference answer using int64 and sym

This is a question about the function nchoosek in Matlab.
I want to find nchoosek(54,25), which is the same as 54C25. Since the answer is about 10^15, I originally use int64. However the answer is wrong with respect to the symbolic one.
Input:
nchoosek(int64(54),int64(25))
nchoosek(sym(54),sym(25))
Output:
1683191473897753
1683191473897752
You can see that they differ by one. This is not really an urgent problem since I now use sym. However can someone tell me why this happens?
EDIT:
I am using R2013a.
I take a look at the nchoosek.m, and find that if the input are in int64, the code can be simplified into
function c = nchoosek2(v,k)
n = v; % rename v to be n. the algorithm is more readable this way.
classOut = 'int64';
nd = double(n);
kd = double(k);
nums = (nd-kd+1):nd;
dens = 1:kd;
nums = nums./dens; %%
c = round(prod(nums));
c = cast(c,classOut);
end
However, the outcome of int64(prod(nums./dens)) is different from prod(sym(nums)./sym(dens)) for me. Is this the same for everyone?
I don't have this problem on R2014a:
Numeric
>> n = int64(54);
>> k = int64(25);
>> nchoosek(n,k)
ans =
1683191473897752 % class(ans) == int64
Symbolic
>> nn = sym(n);
>> kk = sym(k);
>> nchoosek(nn,kk)
ans =
1683191473897752 % class(ans) == sym
% N!/((N-K)! K!)
>> factorial(nn) / (factorial(nn-kk) * factorial(kk))
ans =
1683191473897752 % class(ans) == sym
If you check the source code of the function edit nchoosek.m, you'll see it specifically handles the case of 64-bit integers using a separate algorithm. I won't reproduce the code here, but here are the highlights:
function c = nchoosek(v,k)
...
if int64type
% For 64-bit integers, use an algorithm that avoids
% converting to doubles
c = binCoef(n,k,classOut);
else
% Do the computation in doubles.
...
end
....
end
function c = binCoef(n,k,classOut)
% For integers, compute N!/((N-K)! K!) using prime factor cancellations
...
end
In 2013a this can be reproduced...
There is as #Amro shows a special case in nchoosek for classOut of int64 or unit64,
however in 2013a this is only applied when the answer is between
flintmax (with no argument) and
double(intmax(classOut)) + 2*eps(double(intmax(classOut)))
which for int64 gives 9007199254740992 & 9223372036854775808, which the solution does not lie between...
If the solution had fallen between these values it would be recalculated using the subfunction binCoef
for which the help states: For integers, compute N!/((N-K)! M!) using prime factor cancellations
The binCoef function would have produced the right answer for the given int64 inputs
In 2013a with these inputs binCoef is not called
Instead the "default" pascals triangle method is used in which:
Inputs are cast to double
The product of the vector ((n-k+1):n)./(1:k) is taken
this vector contains k double representations of fractions.
So what we have is almost certainly floating point error.
What can be done?
Two options I can see;
Make your own function based on the code in binCoef,
Modify nchoosek and remove && c >= flintmax from line 81
Removing this expression will force Matlab to use the more accurate integer based calculation for inputs of int64 and uint64 for any values within their precision. This will be slightly slower but will avoid floating point errors, which are rightfully unexpected when working with integer types.
Option one - should be fairly straight forward...
Option two - I recommend keeping an unchanged backup of the original function, or makeing a copy of the function with the modification and use that instead.

Error with recursive function in m-file

I'm working on chapter 8 of A Course in Mathematical Biology. The textbook uses Maple, but includes this link, Computer course of Chapter 8 in Matlab. I'm told to put the following in an m-file:
% defining a recursive function in an m-file
function y = plot_traj(a)
RM = inline('a*x.*exp(-x)', 'a', 'x')
% Note that we are using an inline function. Sometimes it’s easier to do this.
% collecting list of x-coordinates
for i = 1:31,
X(i) = i - 1
end
% collecting list of y-coordinates
for i = 1:30,
Y(i+1)=RM(a,iter(i));
iter(i+1) = Y(i+1);
end
y = plot(X, Y, '*');
Now, save your m-file (as plot traj.m) and close it. Type the following into the command window:
>> plot traj(0.8)
>> plot traj(1.0)
>> plot traj(5.0)
>> plot traj(8.0)
>> plot traj(13.0)
>> plot traj(14.5)
>> plot traj(20.0)
However, when I type plot traj(0.8) into the command window I get this:
>> plot_traj(0.8)
Undefined function or variable "iter".
Error in plot_traj (line 13)
Y(i)=RM(a,iter(i));
I don't see anything wrong with line 13, and I've made sure that my code is exactly what is in the chapter. I've been doing fine with the codes up until this point. I'd appreciate it if anyone could provide some assistance. Thank you.
The problem at line 13 is that the iter local variable array has not been defined. So on the first iteration, the code tries to access iter(1) and fails. I looked at the link you provided and they missed it too. Based on previous examples in the Matlab_Course.pdf (and figure 8.6), the iter array should be initialized as
iter(1) = 1.0;
Just add this line prior to the for loop and you should be good to continue. I suspect also that this line should be added too (again based on the document)
Y(1)=iter(1);
to make sure that both iter and Y have the same length.
Note that it is a good habit to pre-allocate memory to arrays to avoid the internal resizing of matrices/arrays on each iteration of the loop (which can have a negative impact on performance). For this loop
for i = 1:30,
Y(i+1)=RM(a,iter(i));
iter(i+1) = Y(i+1);
end
you can observe that i iterates over 1 through 30, and we always populate Y(i+1) and iter(i+1). So both Y and iter are 31x1 vectors. We can allocate memory to each prior to entering the for loop as
iter = zeros(31,1);
Y = zeros(31,1);
iter(1) = 1;
Y(1) = iter(1);
The same should be done for X as well.

MATLAB how do I access a specific coefficient in a symbolic equation system solution?

I need to run a simple Monte Carlo varying coefficients on a system of equations. I need to record the solved coefficient of one of the variables each time.
The following gets me results from a single run:
syms alpha gamma Ps Pc beta lambda Pp Sp Ss Dp Ds;
eq1 = -Ss + alpha + 0.17*Ps - 1*Pc;
eq2 = -Sp + beta + 0.2*Pp;
eq3 = -Ds + gamma - 0.2*Ps + 1*Pp;
eq4 = -Dp + lambda - 0.17*Pp + 1*Ps;
eq5 = Ss - Ds;
eq6 = Sp - Dp;
ans1 = solve(eq1,eq2,eq3,eq4,eq5,eq6,'Ps','Pp','Ss','Ds','Sp','Dp');
disp('Ps')
vpa(ans1.Ps,3)
disp('Pp')
vpa(ans1.Pp,3)
disp('Ss')
vpa(ans1.Ss,3)
disp('Ds')
vpa(ans1.Ds,3)
disp('Sp')
vpa(ans1.Sp,3)
disp('Dp')
vpa(ans1.Dp,3)
I will be varying several of the variables (on Ps, Pp, and Pc), and recording the coefficient on Pc in each of the reduced form equations (i.e. the coefficient on Pc that shows up after vpa(ans1.xx)--so in the case above, it would be a 1x6 vector [-0.429,-1.16,-1.07,-1.07,-0.232,-0.429,-1.16]).
I'm very new to MATLAB, but I'm sure I can figure out how to implement the loop code to do the model iterations. What I can't figure out is how to record the vector of coefficients after each iteration. Is there some "accessor" that will give me just the one coefficient for each equation each time?
Something like vpa(ans1.ps.coef(pc)) (which is a total shot in the dark, and it's wrong, but hopefully you get the idea).
There's probably a better way to do this, but this is all I could come up to at this moment.
Step 1:
In order to obtain the coefficient of Pc as a double from ans1.Ps, you can use the subs function, as follows:
subs(ans1.Ps,{alpha,Pc,beta,gamma,lambda},{0,1,0,0,0});
Step 2a:
To get a vector of all coefficients per ans1 expression (say ans1.Ps) you can use something like this:
N=numel(symvar(ans1.Ps)); % obtain number of coefs
cp=num2cell(eye(N)); % create a cell array using unit matrix, so each iteration a different coef will be selected
for n=1:N;
coefs(n)=subs(ans1.Ps,{alpha,Pc,beta,gamma,lambda},cp(n,:));
end
Step 2b:
Alternatively, you want to get just Pc, but from all the ans1 expressions. If so then you can do the following:
SNames = fieldnames(ans1); % get names of ans1 expressions
for n = 1:numel(SNames)
expr = ans1.(SNames{n}); % get the expression itself
pc(n)=subs(expr,{alpha,Pc,beta,gamma,lambda},{0,1,0,0,0}); % obtain just pc
end
You can now combine the two if you want all info about the coefficients.
Edit:
To store the retrieved Pc per iteration you can do the following:
alpha=[3 1 4 6 7] % just a vector of values
beta = [6 7 8 5 2]
SNames = fieldnames(ans1); % get names of ans1 expressions
for n = 1:numel(SNames)
expr = ans1.(SNames{n}); % get the expression itself
for n1=1:numel(alpha)
for n2=1:numel(beta)
pc(n,n1,n2)=subs(expr,{alpha,Pc,beta,gamma,lambda},{alpha(n1),1,beta(n2),0,0})
end
end
end