Pi value estimation with series - matlab

Here's my problem:
Compute the value of π using the following series:
((π^2)-8)/16=[sum from 1 to pos. infinity] 1/(((2n−1)^2)*((2n+1)^2))
• Find the smallest number of terms required to obtain an absolute value of the error on π smaller than 10e−8.
Here's my code:
x=0;
for i=1:1000
x=x+(1/((((2*i)-1)^2)*(((2*i)+1)^2)));
z=sqrt((x*16)+8);
error=abs(z-pi);
if (error < 10e-8)
i
break
end
end
The answer that I get is 81 when the loop breaks, but it is not the right answer. I have been trying to figure out what is wrong with my code that it doesn't do what I need.
I've been staring at the code for quite a while and cant see where I made a mistake.

I found the problem. The error is supposed to be less than 10^-8 not 10e-8. Somehow the numbers got changed over when copying.

Related

How do I get lines to stop extending beyond plot border? (Matlab)

I am writing a report for a class and am having some issues with the lines of an unstable plot going beyond the boundary of the graph and overlapping the title and xlabel. This is despite specifying a ylim from -2 to 2. Is there a good way to solve this issue?
Thanks!
plot(X,u(:,v0),X,u(:,v1),X,u(:,v2),X,u(:,v3),X,u(:,v4))
titlestr = sprintf('Velocity vs. Distance of %s function using %s: C=%g, imax=%g, dx=%gm, dt=%gsec',ICFType,SDType,C,imax,dx,dt);
ttl=title(titlestr);
ylabl=ylabel("u (m/s)");
xlabl=xlabel("x (m)");
ylim([-2 2])
lgnd=legend('t=0','t=1','t=2','t=3','t=4');
ttl.FontSize=18;
ylabl.FontSize=18;
xlabl.FontSize=18;
lgnd.FontSize=18;
EDIT: Minimum reproducible example
mgc=randi([-900*10^10,900*10^10], [1000,2]);
mgc=mgc*1000000;
plot(mgc(:,1),mgc(:,2))
ylim([-1,1])
This is odd. It really looks like a Bug... partly
The reason is probably that the angle of the lines are so narrow that MATLAB runs into rounding errors when calculating the points to draw for your limits very small limits given very large numbers. (You see that you don't run into this problem when you don't scale the matrix mgc.
mgc = randi([-900*10^10,900*10^10], [1000,2]);
plot(mgc(:,1),mgc(:,2))
ylim([-1,1])
but if you scale it further, you run into this problem...
mgc = randi([-900*10^10,900*10^10], [1000,2]);
plot(mgc(:,1)*1e6,mgc(:,2)*1e6)
ylim([-1,1])
While those numbers are nowhere near the maximum number a double can represent (type realmax in the command window to see that this is a number with 308 zeros!); limiting the plot to [-1,1] on one of the axes -- note that you obtain the same phenom on the x-axis -- let MATLAB run into precision problems.
First of all, you see that it plots much less lines than before (in my case)... although, I just said to zoom on the y-axis. The thing is, that MATLAB does not recalculate the lines for the section but it really zooms into it (I guess that this may cause resolution errors with regard to pixels?)
Well, lets have a look at the data (Pro-tip, you can get the data of a line from a MATLAB figure by calling this snippet
datObj = findobj(gcf,'-property','YData','-property','XData');
X = datObj.XData;
Y = datObj.YData;
xlm = get(gca,'XLim'); % get the current x-limits
) We see that it represents the original data set, which is not surprising as you can also zoom out again.
Note that his only occurs if you have such a chaotic, jagged line. If you sort it, it does not happen.
quick fix:
Now, what happens, if we calculate the exact points for this section?
m = diff(Y)./diff(X); % slope
n = Y(1:end-1)-m.*X(1:end-1); % offset
x = [(-1-n); (1-n)]./m;
y = ones(size(x))./[-1 1].';
% plot
plot([xMinus1;xPlus1],(ones(length(xMinus1),2).*[-1 1]).')
xlim(xlm); % limit to exact same scale as before
The different colors indicate that they are now individual lines and not a single wild chaos;)
It seems Max pretty much hit the nail on the head as it pertains to the reason for this error is occurring. Per Enrico's advice I went ahead and submitted a bug report. MathWorks responded saying they were unsure it was "unexpected behavior" and would look into it more shortly. They also did suggest a temporary workaround (which, in my case, may be permanent).
This workaround is to put
set(gca,'ClippingStyle','rectangle');
directly after the plotting line.
Below is a modified version of the minimum reproducible example with this modification.
mgc=randi([-900*10^10,900*10^10], [1000,2]);
mgc=mgc*1000000;
plot(mgc(:,1),mgc(:,2))
set(gca,'ClippingStyle','rectangle');
ylim([-1,1])

Matlab not taking last number in array?

I've got a Subscripted assignment dimension mismatch problem.
I've already localized the issue, and know exactly what is going on, I just don't know why.
Here's the problematic piece of code:
mFrames(:,i) = vSignal(round(start:1:frameLength*samplingRate));
start=start+frameShift*samplingRate;
frameLength = frameLength+frameShift;
I've already checked what's going on in debugmode; usually my resulting column length of mFrames is 128, this stays the same until i=1004. Then, my column length changes to 127.
I've checked the values involved while in debug mode, and it simply does not make sense what is going on. At i==1004 start=32097 and frameLength*samplingRate=32224.
That's a difference of 127 meaning 128 points, that should work.
BUT when i assign a vector A=round(start:1:frameLength*samplingRate)
OR B=start:1:frameLength*samplingRate
In both cases I get a vector going from 32097 to 32223. This ALTHOUGH when I give in frameLength*samplingRate matlab is giving me 32224.
In other words, matlab is telling me it's using one number, but when I test I find it's using a different one.
Any help appreciated.
I suspect your 32224 is not actually 32224. MATLAB's default format only displays so many decimal places, so when dealing with floating point numbers, what is printed on screen is not necessarily the "exact" value.
Let's go back a step and look at how the synatx x = start:step:end works.
1:1:10 should give us numbers in steps of 1 from 1 to 10. Fair enough, that makes sense. What if we set the end value to something that's slightly above 10?
e.g.:
1:1:10.1
Well, it still gives us 1:1:10, (or 1:10, 1 being the default step) because we can't have values higher than the end-point, so 11 isn't a correct step.
So what about this:
1:1:9.99
Spoiler: it's the same as 1:9
And this?
1:1:9.9999999
Yep, still 1:9
But if we do this:
a = 9.9999999;
Then with default format, the value of a will be shown on the command line and in your list of workspace variables as 10.0000.
Now, if frameLength and samplingRate are both stored as floating point numbers, it's possible that the number you see as 32224 is not 32224 but very slightly below that. You can check this by changing your default format - e.g. format long at the command line - to show more decimal places.
The simplest solution is probably to do something like:
B=start:1:round(frameLength*samplingRate)
Or try to store the relevant values as integers (e.g., uint32).

Finding the first element less than a certain value in an unsorted vector (MATLAB)

Pretty simple, and I thought I knew what I was doing, but apparently not. Anyways.
I need to find the first element in a vector that is less than a specific value. Here is the code that I have been using:
t = 0:0.01:5;
u = ((2)*exp(-10.*t).*cos((4.*sqrt(6)).*t) + ((5)./sqrt(6)).*exp(-10.*t).*sin((4.*sqrt(6)).*t));
for a = 1:size(u)
if u(a) < (0.05)
disp(a)
break
end
end
The value that I'm trying to find is the first element less than 0.05, however, when I run my code, I don't get anything.
What could I be doing wrong?
Thanks!
#user2994291 has correctly pointed out where your loop based solution is going wrong (+1).
However I would also add that what you are trying to do can simply be accomplished by:
find(u < 0.05, 1, 'first')
Technically, the third input is not necessary - you could just use:
find(u < 0.05, 1)
However, I seem to recall reading at some point that find will work faster if you provide the third input.
The upper bound of your for loop is probably equal to 1.
In your case, u is a row vector (can't say 100% for sure in MATLAB as I only have access to GNU Octave right now), but calling size(u) will probably give back [1 501] as an answer. Your for-loop will select 1 as upper bound.
Try replacing size(u) with size(u,2) or, even better, with length(u). I get a = 24 as an answer.
Edit:
from your questions I assume you are a MATLAB beginner, therefore I strongly advise you to look into the built-in debugger (you can add breakpoints by clicking on the left vertical bar next to the desired line of code), this would have helped you identify the error with ease and will save you a lot of time in the future.

Incorrect Square Wave Plot

I'm embarrassed to ask this as I believe I may be missing something obvious, but I just can't see where I am going wrong. As part of a larger program I am investigating the application of discretisation methods to approximate the convection equation on a square wave. However, I have noticed that in some cases the bounds of my square wave are being incorrectly applied. It should have the initial conditions of 1 when 10.25<=X<=10.5 and 0 everywhere else. This is an example of the issue:
L=20; %domain length
dx=0.01; %space step
nx=(L/dx); %number of steps in space
x=0:dx:(nx-1)*dx; %steps along x
sqr=zeros(1,nx); %pre-allocate array space
for j=1:nx
if ((10.25<=x(j))&&(x(j)<=10.5))
sqr(j)=1;
else
sqr(j)=0;
end
d=plot(x,sqr,'r','LineWidth',2); axis([10.1 10.6 0 1.1]);
drawnow;
In this case, the wave displays incorrectly, with x=10.5 taking a value of 0 and not 1, like so:
https://dl.dropboxusercontent.com/u/8037738/project/square_wave.png
The weird thing is that if I change the domain length to a different value it sometimes displays correctly. This is when the domain length is set to 30 and it displays correctly:
https://dl.dropboxusercontent.com/u/8037738/project/square_wave_correct.png
I really don't understand because my x array is always discretised in 0.01 intervals, so it will never 'miss' 10.5 when it loops through. I hope I have explained this problem adequately enough and if it is a stupid mistake on my part I apologise in advance.
You forgot the end when you finish with the if
L=20; %domain length
dx=0.01; %space step
nx=(L/dx); %number of steps in space
x=0:dx:(nx-1)*dx; %steps along x
sqr=zeros(1,nx); %pre-allocate array space
eps = 1.e-8;
for j=1:nx
if ((10.25-eps<=x(j))&&(x(j)<=10.5+eps))
sqr(j)=1;
else
sqr(j)=0;
end
end
d=plot(x,sqr,'r','LineWidth',2); axis([10.1 10.6 0 1.1]);
drawnow;
I also recomend you to use a small tolerance when using comparisons with float values, like the x(j)<=10.5
if you se the difference at that point, matlab tell you
x(1051)-10.5
ans =
1.776356839400250e-15
so because of the round-off the value of x(j) was lightly larger that 10.5, not equal as you were expecting
Your issue is that the x values do not fall exactly on the space step. For example, if you look at the following:
j=1051;
format long;
x(j)
ans =
10.500000000000002
The answer from sebas fixes this issue by adding the tolerance to each of the bounds. You could also try rounding x(j) to the nearest 100th before performing the logic in the if statement:
roundn(x(j), -2)

keving murphy's hmm matlab toolbox assertion error

I am working on a project that needs to use hidden markov models. I downloaded Kevin Murphy's toolbox. I have some problems about the usage. In the toolbox webpage, he says that first input of dhmm_em and dhmm_logprob are symbol sequence data. On their examples, they give row vectors as data. So, when I give my symbol sequence as row vector, I get error;
??? Error using ==> assert at 9
assertion violated:
Error in ==> fwdback at 105
assert(approxeq(sum(alpha(:,t)),1))
Error in ==> dhmm_logprob at 17
[alpha, beta, gamma, ll] = fwdback(prior,
transmat, obslik, 'fwd_only', 1);
Error in ==> mainCourseProject at 110
loglik(train_act) =
dhmm_logprob(orderedSymbols,
hmm{train_act}.prior,
hmm{train_act}.trans,
hmm{act}.emiss);
However, before giving this error, code works for some symbol vectors. When I give my data as column vector, functions work fine, no errors. So why exactly am I getting this error?
You might say that I should be giving not single vectors, but vector sets, I also tried to collect my feature vectors in a struct and give row vectors as such, but nothing changed, I still get assertion error.
By the way, my symbol sequence does not have any zeros, I am doing everything almost the same as they showed in their examples, so I would be greatful if anyone could help me please.
Im not sure, but from the function call stack shown above, shouldn't the last line be hmm{train_act}.emiss instead of hmm{act}.emiss.
In other words when you computing the log-probability of a sequence, you should pass components that belong to the same HMM model (transition matrix, emission matrix, and prior probabilities).
By the way, the ASSERT in the code is a sanity check that a vector of probabilities should sum to 1. Oftentimes, when working with very small values (log-probabilities), numerical stability issues can creep in... You could edit the APPROXEQ function to relax the comparison a bit, by giving it a bigger margin of error
This error message and the code it refers to are human-readable. An assertion is a guard put in by the programmer, to ensure that certain conditions are met. In this case, what is the condition? approxeq(sum(alpha(:,t)),1) I'd venture to say that approxeq wants the values to be approximately equal, so this boils down to: sum(alpha(:,t)) ~= 1
Without knowing anything about the code, I'd also guess that these refer to probabilities. The probabilities of a node's edges must sum to one. Hopefully this starts you down a productive debugging path. If you can't figure out what's wrong with your input that produces this condition, start wading into the code a bit to see where this alpha vector comes from, and how it ended up invalid.