Matlab: efficienting portion of code, random start - matlab

I have the following code that generates a matrix of 15 blocks that will then be used in a Montecarlo approach as multiple starting points. How can I get the same exact result in a smarter way?
assume that J=15*100 are the total simulation and paramNum the number of parameters
[10^-10*ones(paramNum,round(J/15)) 10^-9*ones(paramNum,round(J/15)) 10^-8*ones(paramNum,round(J/15)) 10^-7*ones(paramNum,round(J/15)) 10^-6*ones(paramNum,round(J/15)) 10^-5*ones(paramNum,round(J/15)) rand*10^-5*ones(paramNum,round(J/15)) 10^-4*ones(paramNum,round(J/15)) rand*10^-4*ones(paramNum,round(J/15)) 10^-3*ones(paramNum,round(J/15)) 10^-2*ones(paramNum,round(J/15)) 10^-1*ones(paramNum,round(J/15)) 10^-abs(randn/2)*ones(paramNum,round(J/15))];

you could do
v = 10.^[-10:-5 rand*10^-5 -4:-1 10^-abs(randn/2)];
repmat(repelem(v, 1, round(J/15)), paramNum) .* ...
repmat(ones(paramNum,round(J/15)), numel(v))
Or mimic the repmat/repelem functionality with a for loop. The first is shorter, the later is more understandable.
By the way... it's less than 15 blocks...

Related

limit random complex number to a given range

I can get the real part of a random number to stay withing a given range but the complex part of the number doesn't stay within the range I set. see matlab / octave code below.
xmin=-.5
xmax=1
n=3
x=xmin+rand(1,n)*(xmax-xmin)+(rand(1,n)-(xmax-xmin))*1i
x=x(:)
The real part works but the complex part isn't limited to -0.5 to 1
0.2419028288441536 - 0.6579427654754871i
0.2712527227134944 - 1.451964497492678i
0.3245051849394858 - 1.107556052779179i
You have two mistakes:
x=xmin+rand(1,n)*(xmax-xmin)+(xmin + rand(1,n)*(xmax-xmin))*1i
You should add xmin to the sum and change - to * in the second part.
I've added some spaces to your code so the difference more obvious:
x = xmin+rand(1,n)*(xmax-xmin) + ( rand(1,n)-(xmax-xmin) )*1i
^^^ correct ^^^ not correct: missing `xmin+`
(and as OmG noted, also a `-` instead of a `*`)
One good way to reduce the number of bugs is by avoiding code duplication. You could for example write:
rand_sequence = #(m,xmin,xmax) xmin+rand(1,n)*(xmax-xmin);
x = rand_sequence(n,xmin,xmax) + 1i*rand_sequence(n,xmin,xmax)
(This looks like more code, but the more complicated code logic is not duplicated.)
Or like this:
x = xmin + (rand(1,n)+1i*rand(1,n)) * (xmax-xmin);

Find some numbers in Matlab satisfying a bunch of inequalities

I want to find some numbers in Matlab (denominated below p11,..., p119) satisfying a bunch of inequalities (specifically, 16 inequalities). I want Matlab to keep searching until it finds such numbers. I thought about using while as below but it does no work. What is wrong? How can I proceed?
clear
rng default
%% SOME INITIAL VALUES
p11=0.3;
p12=0.4;
p13=0.1;
p14=0.2;
p15=0.2;
p16=0.2;
p17=0.06;
p18=0.03;
p19=0.02;
p110=0.04;
p111=0.07;
p112=50;
p113=0.02;
p114=0.03;
p115=0.01;
p116=0.08;
p117=0.01;
p118=0.1;
p119=0.07;
while ... %CONDITION THAT SHOULD BE SATISFIED (16 CONDITIONS)
((p11<=(p15+p19+p110+p111+p115+p116+p117+p119))+...
(p12<=(p16+p19+p112+p113+p115+p117+p118+p119))+...
(p13<=(p17+p110+p112+p114+p116+p117+p118+p119))+...
(p14<=(p18+p111+p113+p114+p115+p116+p118+p119))+...
(p11+p12<=(p15+p19+p110+p111+p115+p116+p117+p119+...
p16+p112+p113+p118))+...
(p11+p13<=(p15+p19+p110+p111+p115+p116+p117+p119+...
p17+p112+p114+p118))+...
(p11+p14<=(p15+p19+p110+p111+p115+p116+p117+p119+...
p18+p113+p114+p118))+...
(p12+p13<=(p16+p19+p112+p113+p115+p117+p118+p119+...
p17+p110+p114+p116))+...
(p12+p14<=(p16+p19+p112+p113+p115+p117+p118+p119+...
p18+p111+p114+p116))+...
(p13+p14<=(p17+p110+p112+p114+p116+p117+p118+p119+...
p18+p111+p113+p115))+...
(p11+p12+p13<=(p15+p19+p110+p111+p115+p116+p117+p119+...
p16+p112+p113+p118+...
p17+p114))+...
(p11+p12+p14<=(p15+p19+p110+p111+p115+p116+p117+p119+...
p16+p112+p113+p118+...
p18+p114))+...
(p11+p13+p14<=(p15+p19+p110+p111+p115+p116+p117+p119+...
p17+p112+p114+p118+...
p18+p113))+...
(p12+p13+p14<=(p16+p19+p112+p113+p115+p117+p118+p119+...
p17+p110+p114+p116+...
p18+p111))+...
(p11+p12+p13+p14==1)+...
(p15+p16+p17+p18+p19+p110+p111+p112+p113+p114+p115+p116+p117+p118+p119==1))~=15
% IF THE CONDITION IS NOT SATISFIED KEEP SEARCHING BY GUESSING
% OTHER NUMBERS
p11=unifrnd(0,1);
p12=unifrnd(0,1);
p13=unifrnd(0,1);
p14=unifrnd(0,1);
p15=unifrnd(0,1);
p16=unifrnd(0,1);
p17=unifrnd(0,1);
p18=unifrnd(0,1);
p19=unifrnd(0,1);
p110=unifrnd(0,1);
p111=unifrnd(0,1);
p112=unifrnd(0,1);
p113=unifrnd(0,1);
p114=unifrnd(0,1);
p115=unifrnd(0,1);
p116=unifrnd(0,1);
p117=unifrnd(0,1);
p118=unifrnd(0,1);
p119=unifrnd(0,1);
end
The while loop will run while the condition is true. If false it terminates. Your test conditions is while .... ~= 15. This is false as the initial guesses result in 15 out of 16 trues. Since 15 ~= 15 is false, the while loop doesn't run.
One way to fix the issue is to change from ~= to ==. This will run through and find a solution to that condition.
You could have seen this by creating a variable called tests and populated it like this:
tests = [(p11<=(p15+p19+p110+p111+p115+p116+p117+p119));...
... skipped a bunch of stuff ...
(p15+p16+p17+p18+p19+p110+p111+p112+p113+p114+p115+p116+p117+p118+p119==1)];
sum(tests)
ans = 15
Or any other way of tracking that value.

Performing Kernel Density Estimations in MATLAB

I have been using MATLAB to perform Kernel Density Estimations (KDE) on UTM data (X and Y coordinates). I ran into a problem that I do not seem to be understanding.
I perform the KDEs with a sample of 45 points. Everything works fine and I produce the graphs with contours.
[bandwidth,density,X,Y]=kde2d(data)
The function kde2d is code by Zdravko Botev. I obtained it from his file exchange on MathWorks. The variable 'data' is a 45x2 array of my data. The first column holds the X coordinates and the second the Y.
The problem comes when I try to do the same line of code on a subset of those 45 points. I get a recurring error:
Error using fzero (line 274)
The function values at the interval endpoints must differ in sign.
Error in kde2d (line 101)
t_star=fzero(#(t)(t-evolve(t)),[0,0.1]);
I get the same error for a bunch of those subsets on a bunch of different sets of 45 points.
The complete set has these 45 values:
1594436.281 572258.1272
1594418.48 572357.5859
1594471.362 572385.5186
1594516.726 572266.8206
1594415.313 572369.2754
1594519.701 572272.7153
1594415.377 572363.4139
1594468.365 572381.5779
1594518.139 572276.6059
1594425.496 572271.6874
1594524.259 572272.7651
1594502.555 572172.8749
1594516.747 572264.867
1594485.314 572360.2689
1594476.027 572375.7997
1594556.087 572419.6609
1594522.718 572274.7021
1594472.775 572395.3039
1594554.568 572419.6443
1594527.255 572276.7054
1594474.315 572393.3669
1594522.697 572276.6557
1594471.319 572389.4262
1594460.854 572373.6799
1594546.022 572228.0609
1594460.79 572379.5414
1594468.323 572385.4855
1594466.953 572371.7926
1594519.722 572270.7614
1594396.76 572398.3826
1594468.131 572403.0693
1594418.288 572375.1697
1594396.377 572433.5499
1594448.287 572271.9361
1594510.541 572276.523
1594424.466 572226.7345
1594413.773 572371.2124
1594511.848 572296.0774
1594513.367 572296.094
1594424.488 572224.7805
1594468.152 572401.1153
1594421.37 572371.2953
1594446.768 572271.9195
1594468.152 572401.1153
1594448.799 572225.0457
One of the subsets I am trying to use is this:
1594436.281 572258.1272
1594418.48 572357.5859
1594471.362 572385.5186
1594516.726 572266.8206
1594415.313 572369.2754
1594519.701 572272.7153
1594415.377 572363.4139
1594468.365 572381.5779
1594518.139 572276.6059
1594425.496 572271.6874
I am not sure if I should include any of Botev's code. I am hoping that the error message can be explained on its own. If not I can provide more. Thank you very much.

How to select the last column of numbers from a table created by FoldList in Mathematica

I am new to Mathematica and I am having difficulties with one thing. I have this Table that generates 10 000 times 13 numbers (12 numbers + 1 that is a starting number). I need to create a Histogram from all 10 000 13th numbers. I hope It's quite clear, quite tricky to explain.
This is the table:
F = Table[(Xi = RandomVariate[NormalDistribution[], 12];
Mu = -0.00644131;
Sigma = 0.0562005;
t = 1/12; s = 0.6416;
FoldList[(#1*Exp[(Mu - Sigma^2/2)*t + Sigma*Sqrt[t]*#2]) &, s,
Xi]), {SeedRandom[2]; 10000}]
The result for the following histogram could be a table that will take all the 13th numbers to one table - than It would be quite easy to create an histogram. Maybe with "select"? Or maybe you know other ways to solve this.
You can access different parts of a list using Part or (depending on what parts you need) some of the more specialised commands, such as First, Rest, Most and (the one you need) Last. As noted in comments, Histogram[Last/#F] or Histogram[F[[All,-1]]] will work fine.
Although it wasn't part of your question, I would like to note some things you could do for your specific problem that will speed it up enormously. You are defining Mu, Sigma etc 10,000 times, because they are inside the Table command. You are also recalculating Mu - Sigma^2/2)*t + Sigma*Sqrt[t] 120,000 times, even though it is a constant, because you have it inside the FoldList inside the Table.
On my machine:
F = Table[(Xi = RandomVariate[NormalDistribution[], 12];
Mu = -0.00644131;
Sigma = 0.0562005;
t = 1/12; s = 0.6416;
FoldList[(#1*Exp[(Mu - Sigma^2/2)*t + Sigma*Sqrt[t]*#2]) &, s,
Xi]), {SeedRandom[2]; 10000}]; // Timing
{4.19049, Null}
This alternative is ten times faster:
F = Module[{Xi, beta}, With[{Mu = -0.00644131, Sigma = 0.0562005,
t = 1/12, s = 0.6416},
beta = (Mu - Sigma^2/2)*t + Sigma*Sqrt[t];
Table[(Xi = RandomVariate[NormalDistribution[], 12];
FoldList[(#1*Exp[beta*#2]) &, s, Xi]), {SeedRandom[2];
10000}] ]]; // Timing
{0.403365, Null}
I use With for the local constants and Module for the things that are other redefined within the Table (Xi) or are calculations based on the local constants (beta). This question on the Mathematica StackExchange will help explain when to use Module versus Block versus With. (I encourage you to explore the Mathematica StackExchange further, as this is where most of the Mathematica experts are hanging out now.)
For your specific code, the use of Part isn't really required. Instead of using FoldList, just use Fold. It only retains the final number in the folding, which is identical to the last number in the output of FoldList. So you could try:
FF = Module[{Xi, beta}, With[{Mu = -0.00644131, Sigma = 0.0562005,
t = 1/12, s = 0.6416},
beta = (Mu - Sigma^2/2)*t + Sigma*Sqrt[t];
Table[(Xi = RandomVariate[NormalDistribution[], 12];
Fold[(#1*Exp[beta*#2]) &, s, Xi]), {SeedRandom[2];
10000}] ]];
Histogram[FF]
Calculating FF in this way is even a little faster than the previous version. On my system Timing reports 0.377 seconds - but such a difference from 0.4 seconds is hardly worth worrying about.
Because you are setting the seed with SeedRandom, it is easy to verify that all three code examples produce exactly the same results.
Making my comment an answer:
Histogram[Last /# F]

Is there a better way to write this in Matlab?

I have this code, but there must be a better efficient to write it:
rt= RealTrans;
rtsize=size(rt);
rtrows=rtsize(1);
Relative_Axis_Moves=[rt(1,1) rt(1,2) rt(1,3) rt(1,4) rt(1,5);
rt(2:rtrows,1)-rt(1:rtrows-1,1) rt(2:rtrows,2)-rt(1:rtrows-1,2)
rt(2:rtrows,3)-rt(1:rtrows-1,3) rt(2:rtrows,4)-rt(1:rtrows-1,4)
rt(2:rtrows,5)-rt(1:rtrows-1,5)];
There are two rows in the matrix. The first row ends at rt(1,5).
I also have the following code:
p1size=size(p1);
p1rows=p1size(1);
flank_edge_point=[0 0 0; p1(2:p1rows,2)-p1(1:p1rows-1,2) xy(2:p1rows,1)-xy(1:p1rows-1,1) xy(2:p1rows,2)-xy(1:p1rows-1,2); 0 0 xy(p1rows,2)];
How do i get xy(p1rows,2) value in matlab without p1rows?
I also have the code below which relies on the number of rows:
RAMrow=size(Relative_Axis_Moves);
RAMrow=RAMrow(1);
for i=1:RAMrow
L(i)= norm(Relative_Axis_Moves(i,:));
end
L=L';
L(RAMrow+1)= 0;
Any way to write this code more succinctly and efficiently would be greatly appreciated.
Most likely, there will be more than two rows in Relative_Axis_Moves, since the differences in the second row evaluate to arrays.
Anyway, a compact way of writing this is
Relative_Axis_Moves = [RealTrans(1,1:5);diff(RealTrans(:,1:5),1,1)];