It's there any function in Matlab that generates random real numbers in a closed interval. I found something with unifrnd() but it's generating numbers in an open interval.
If I use unifrnd(x,y); I get (x,y) interval, instead of [x,y].
Given the discussion of accuracy in the comments, you could use something like:
mag = floor(log10( y - x))
num = unifrnd(x-(10^mag)*eps, y+(10^mag)*eps)
This essentially adds one "point" to the discrete interval representation, taking into account the accuracy based on the size of the numbers you're using. unifrnd() is essentially a wrapper around rand() (which means you don't really need the stats toolbox to do this), and thus it is really just scaling the uniform distribution on (0,1). If you're worried about the endpoints though, that matters, because you can't get more granular than the product the magnitude of your interval length with eps.
Related
I want to create a sinusoidal wave that has the following properties :
a sine wave with f=400Hz amp=1 from 0 to 2s
a sine wave with f=200Hz amp=1 from 2 to 3s
a sine wave with f=800Hz amp=2 from 3 to 5s
Here is my matlab Code :
t=linspace(0,5,5000);
x=zeros(1,length(t));
n1=0:1999;
n2=2000:2999;
n3=3000:4999;
x(1:2000)=1*sin(2*pi*400*n1);
x(2001:3000)=1*sin(2*pi*200*n2);
x(3001:5000)=2*sin(2*pi*800*n3);
plot(t,x)
and here is the plot that I had, still it looks not logical at all,
So I would like to know the error in my code
In this type of problem, where you're naturally looking at physical quantities, it's very helpful to be consistent with this all the way through your calculations.
Specifically, you specify Hz (1/seconds), a physical unit, so when you calculate everything else, you need to be consistent with that.
To do this in your equation, it's most straightforward to put time directly in the sin function, like sin(2*pi*f*t). But since you want to break the array apart using different n, it probably easiest to do that and then use t=linspace(0,5,50000) and dt = 5.0/50000 or dt = t(2) - t(1), and sin(2*pi*400*dt*n1). Read this as dt*n1 converts the integers in n1 to time in seconds.
Note the physical units too: 400 in above is actually 400Hz, and the time is in seconds, so the units of 2*pi*400*dt*n1 and 2*pi*f*t are Hz * s = 1, that is, the units cancel, which is what you need.
There is a tendency for programmers to want to define away some unit, like say seconds=1. This is possible and technically correct and can save a multiplication or two. It almost always leads to errors.
Note also that you should change from t=linspace(0,5,5000) to something like t=linspace(0,5,50000). The reason should now be clear: you're looking at frequencies from 400-800Hz, or almost 1kHz, or 1 oscillation per millisecond. To see a sine wave, you'll need to get in a few data points per oscillation, and 50000 points in 5 seconds will now give about 10 points per millisecond, which is barely enough to see a reasonable sine wave. Or, however you want to think of the calculation, somehow you need to be sure you sample at a high enough rate.
That is, the specific error that your encountering is that by using integers instead of fractions of a second for your time array, you're taking much too large of steps for the sin function. That's always a possible problems with the sin function, but even if you did plot a sin that looked like a sin (say, by using a frequency like 0.003Hz instead of 400Hz) it would still be incorrect because it wouldn't have the proper time axis. So you need to both get the units correct, and make sure that you get enough data per oscillation to see the sine wave (or whatever it is you happen to be looking for).
I have a cumulative rain, R = 100 mm for t = 10 days. I want to distribute the R over t through square wave so that the cumulative of the square wave is equal to R. In fact, I want to generate different scenario by changing the frequency and duration of rainfall, however, for all cases, the cumulative R should be same.
Please suggest.
Regards,
Imran
Do it on paper first - this is arguably a maths question really.
The trick is to be clear about all your definitions (this is also why you're getting downvotes - those same definitions are required for people to give you detailed help).
Start with the definition of a square wave that fits your requirements (i.e. the two levels it occupies). Define your cumulative and determine how to compute it. You should then be able to write an expression which relates the duty cycle of the square wave (choose a letter for this parameter) and the total time period (your t) to the cumulative (your R). Then you can invert the relationship such that, for a given cumulative R and time t you can recover the required duty cycle.
When you've done this you'll probably find it a great deal easier to implement in matlab.
If you have trouble with any of these stages then ask a new question about it, remembering to include what you've tried so far.
The original question was to model a lightbulb, which are used 24/7, and usually one lasts 25 days. A box of bulbs contains 12. What is the probability that the box will last longer than a year?
I had to use MATLAB to model a Gaussian curve based on an exponential variable.
The code below generates a Gaussian model with mean = 300 and std= sqrt(12)*25.
The reason I had to use so many different variables and add them up was because I was supposed to be demonstrating the central limit theorem. The Gaussian curve represents the probability of a box of bulbs lasting for a # of days, where 300 is the average number of days a box will last.
I am having trouble using the gaussian I generated and finding the probability for days >365. The statement 1-normcdf(365,300, sqrt(12)*25) was an attempt to figure out the expected value for the probability, which I got as .2265. Any tips on how to find the probability for days>365 based on the Gaussian I generated would be greatly appreciated.
Thank you!!!
clear all
samp_num=10000000;
param=1/25;
a=-log(rand(1,samp_num))/param;
b=-log(rand(1,samp_num))/param;
c=-log(rand(1,samp_num))/param;
d=-log(rand(1,samp_num))/param;
e=-log(rand(1,samp_num))/param;
f=-log(rand(1,samp_num))/param;
g=-log(rand(1,samp_num))/param;
h=-log(rand(1,samp_num))/param;
i=-log(rand(1,samp_num))/param;
j=-log(rand(1,samp_num))/param;
k=-log(rand(1,samp_num))/param;
l=-log(rand(1,samp_num))/param;
x=a+b+c+d+e+f+g+h+i+j+k+l;
mean_x=mean(x);
std_x=std(x);
bin_sizex=.01*10/param;
binsx=[0:bin_sizex:800];
u=hist(x,binsx);
u1=u/samp_num;
1-normcdf(365,300, sqrt(12)*25)
bar(binsx,u1)
legend(['mean=',num2str(mean_x),'std=',num2str(std_x)]);
[f, y]=ecdf(x) will create an empirical cdf for the data in x. You can then find the probability where it first crosses 365 to get your answer.
Generate N replicates of x, where N should be several thousand or tens of thousands. Then p-hat = count(x > 365) / N, and has a standard error of sqrt[p-hat * (1 - p-hat) / N]. The larger the number of replications is, the smaller the margin of error will be for the estimate.
When I did this in JMP with N=10,000 I ended up with [0.2039, 0.2199] as a 95% CI for the true proportion of the time that a box of bulbs lasts more than a year. The discrepancy with your value of 0.2265, along with a histogram of the 10,000 outcomes, indicates that actual distribution is still somewhat skewed. In other words, using a CLT approximation for the sum of 12 exponentials is going to give answers that are slightly off.
I'm trying to create confidence interval for a set of data not randomly distributed and very skewed at right. Surfing, I discovered a pretty rude method that consists in using the 97.5% percentile (of my data) for the upperbound CL and 2.5% percentile for your lower CL.
Unfortunately, I need a more sophisticated way!
Then I discovered the bootstrap, precisley the MATLAB bootci function, but I'm having hard time to undestand how to used it properly.
Let's say that M is my matrix containing my data (19x100), and let's say that:
Mean = mean(M,2);
StdDev = sqrt(var(M'))';
How can I compute the asymmetrical CI for every row of the Mean vector using bootci?
Note: earlier, I was computing the CI in this very wrong way: Mean +/- 2 * StdDev, shame on me!
Let's say you have a 100x19 data set. Each column has a different distribution. We'll choose the log normal distribution, so that they skew to the right.
means = repmat(log(1:19), 100, 1);
stdevs = ones(100, 19);
X = lognrnd(means, stdevs);
Notice that each column is from the same distribution, and the rows are separate observations. Most functions in MATLAB operate on the rows by default, so it's always preferable to keep your data this way around.
You can compute bootstrap confidence intervals for the mean using the bootci function.
ci = bootci(1000, #mean, X);
This does 1000 resamplings of your data, calculates the mean for each resampling and then takes the 2.5% and 97.5% quantiles. To show that it's an asymmetric confidence interval about the mean, we can plot the mean and the confidence intervals for each column
plot(mean(X), 'r')
hold on
plot(ci')
In real probability, there is a 0% chance that a random number p, selected from all of the real numbers in the interval (0,1), will be 0.5. However, what are the odds that
rand == 0.5
in MATLAB? I suppose this is like asking how many double-precision numbers are between zero and one, or maybe there are other factors at play.
No particular info on MATLAB's generator...
In general even simple pseudo-random generators have long enough cycles which would cover all values representable by double.
If MATLAB uses some other form of generating random numbers it would be even better - so assuming it uniformly covers whole range of double values.
I believe probability would be: distance between representable numbers around values you are interested divided by length of the interval. See What is the minimal step in double data type? (.NET) for discussion on the distance.
Looking at this question, we see that there are 262 - 252
doubles in the interval (0 1). Therefore, the probability of picking any single one (like 0.5) would be roughly equal to one divided by this number, or
>> p = 1/(2^62-2^52)
ans =
2.170523997312134e-019
However, as horchler already indicates, it also depends on the type of random number generator you use, as well as MATLAB's implementation thereof. Sadly, I have only basic knowledge on the implementaion details for each, but you can look here for a list of available random number generators in MATLAB and google a bit further for more precise numbers.
I am not sure whether Alexei was trying to say this, but inspired by him I think the probability will indeed be approximately the distance between numbers around 0.5.
Therefore I expect the probability to be approximately:
eps(0.5)
Which evaluates to 1.1102e-16
Given the monotonic nature of the difference between double numbers I would actually think this holds:
eps(0.5-eps(0.5)) <= yourprobability <= eps(0.5)
Implying a range of 5.5511e-17 to 1.1102e-16