How to assign vector elements to get a square wave? [duplicate] - matlab

This question already has answers here:
How to have square wave in Matlab symbolic equation
(3 answers)
Closed 6 years ago.
I have a vector T that is defined as
T=zeros(1,4)
I want to define T such that T(1) and T(2) are equal to 1 and T(3) and T(4) are equal to 0. So that when I plot T it looks like a square wave.
I have tried
for i=1:2:size(T,2)
T(i:i+1)=1
end
figure; plot(T);
But this does not give the desired result. It turns out to be [1,0,1,0].
What is the right way to do this assignment?
To differentiate from questions about plotting square waves:
I wanted to find out how exactly to create the loop that would plot to look like a square wave, without explicitly defining frequency or using the symbolic equation. I would then use this information to modify another script that would do the same thing but a larger vector T where the "period" is not the same. Sometimes it is 11s, sometimes 9s and so on.

The period is 4, not 2:
for i=1:4:size(T,2)
T(i:i+1)=1
end
figure; plot(T);

If you have access to the signal processing toolbox, an alternative is using the square function:
T = (1+square(0:pi/2:3*pi/2))/2 %// 1 1 0 0

Related

Matlab `quantile` doesn't interpolate between sample values on ECDF?

According to Matlab's help, quantile interpolates linearly between points on the empirical cumulative distribution function (ECDF). Importantly, the points interpolated between are the mid-points of the risers at each step. I'm finding the actual behaviour to be significantly different. Here is my example, the ECDF, and a line segment to show the interpolation:
y= [ 1 2 5 5 5 5 5 5 9 10 ]
ecdf(y)
grid on
set(get(gca,'Children'),'LineWidth',2)
hold on
% Line segment for interpolation
x2points=[2;5]; y2points=[0.15;0.5];
plot(x2points,y2points)
From the interpolation line segment, we would expect the quantile for F(x)=0.3 to be around x=3.3, but instead, it is x=5.
yInterior=0.3 % Value to get `x` for
xInterior=interp1(y2points,x2points,yInterior) % ans = 3.2857
xInterior=quantile(y,yInterior) % ans x=5
Is there another piece of documentation elsewhere that I'm missing which explains this difference?
Am I the only one seeing this?
I'm using Matlab 2015b.

How can I generate random variables with my own Probability Mass Function in MATLAB? [duplicate]

This question already has answers here:
Weighted random numbers in MATLAB
(4 answers)
Closed 7 years ago.
I have to generate a random variable that ranges from 20 to 30,
with 0.1 interval,
and the pmf of it is given by 1x101 matrix (for x=20, 20.1, ... 29.9, 30).
Now I have to make random variable with this given pmf,
But all I know about generating R.V is something related to gaussian, or uniformly distributed function.
So is there any way to implement generating random variables with arbitrary pmf?
I think this should do the trick.
%// First I created some random data
N=1e6;
x=randn(1,N);x=(x-min(x))/(max(x)-min(x));
pmf=hist(x,101)./N;
%// It's a normal distribution but scaled to output to [0 1]
%// First, get the cdf
xh=cumsum(pmf);
%// Create the list of possible values of this random variable
Y=20:.1:30;
%// Create a uniformly distributed random variable between 0 and 1
R=rand()
%// Find where the cdf value is closest to R
[~,J]=min(abs(xh-R));
%// Find the resulting sample values
Y(J)
%// Just a little plot to make sure it's working
hold on
plot(Y,xh)
plot([20 30],[R R],[Y(J) Y(J)],[0 1])
hold off
I think what you are trying to do is multinomial sampling, see http://se.mathworks.com/help/stats/mnrnd.html?refresh=true
If you just want one sample, you can (crudely) do something like
find( mnrnd(1,pmf))
where pmf is the vector of probabilities (assert(sum(pmf)==1))
Note that there is nothing special of using 20:.1:30, you basically have 101 bins each with probability given by pmf

Axis scale and labeling in MATLAB plot [duplicate]

This question already has answers here:
matlab multiple x axis one below another
(3 answers)
Closed 7 years ago.
I've an FFT plot with negative and positive frequencies on X axis. I have a peak at Synchronous Frequency say 1X (1 times of fundamental frequency) and another peak sub synchronous frequency 0.30X (0.30 times of fundamental frequency). Now I want both the scaling to be labeled on the axis. I used the following code.
%for setting 1X frequency ( Synchronous frequency)
set(gca,'XTick',-5000:2500:5000)
set(gca,'XTickLabel',{'-2X','-1X','0','1X','-2X'})
%for setting 0.30X ( Sub harmonic frequency)
set(gca,'XTick',-700:700:700)
set(gca,'XTickLabel',{'-0.3X','0','0.3X'})
But I see only the second scaling where as the first is not being plotted. Is there any other way to plot this with 2 absolute values. Please find reference image. Thanks in advance.
As you can notice in the figure. I've been able to label the first set of frequencies (1X,1 1/2X, etc). Now I also want the second set(-30X , 0.30X etc) as I indicated with arrow arrow.
i am not sure what are you looking for but maybe this will work for you
c=[-3:3 -3:0.3:3]; % spacing of 1 and 0.3
c=c.*2500; % 2500 is fundamental frequency
c=unique(sort(c));
for i=1:length(c)
str1{i}=[num2str(c(i)/2500,'%.1f'),'X'];
end
plot(1,1,'+'); % random
hold on;
set(gca,'XTick',c,'XTickLabel',str1);
xlim([min(c) max(c)]);
Maybe I'm missing something or have misunderstood your question, but why don't you lump it into one command? As mentioned in the comments, the last set of commands overwrite the first one.
set(gca,'XTick',[-5000 -2500 -700 0 700 2500 5000])
set(gca,'XTickLabel',{'-2X','-1X','-0.3X','0','0.3X','1X','-2X'})

3-D Plotting with MATLAB for Galton's Skewness and Moor's Kurtosis

I know there are many plotting documents for Matlab online and I am pretty sure that it has been asked many times. I aplogize in advance for any inconvenience.
I am dealing with a new distribution and I need to draw 3D plot for different values of parameters (I can do it with Excel or any other programs, however, since my other graphs is drawn with MATLAB, and I need to put this 3D in Matlab, too, to publish it as an article). I calculated the result using MATLAB loops, however, plotting gives me the hardest time. I had no other choice but to ask for your assistance. I have these equations for different alphas and betas with a constant sigma and calculate Galton's Skewness and Moor's Kurtosis given with the last two equations.
median=sqrt(2*(sigma^2)*beta*gammaincinv(0.5,alpha));
q1=sqrt(2*(sigma^2)*beta*gammaincinv((6/8),alpha));
q3=sqrt(2*(sigma^2)*beta*gammaincinv((2/8),alpha));
q4=sqrt(2*(sigma^2)*beta*gammaincinv((7/8),alpha));
q5=sqrt(2*(sigma^2)*beta*gammaincinv((5/8),alpha));
q6=sqrt(2*(sigma^2)*beta*gammaincinv((3/8),alpha));
q7=sqrt(2*(sigma^2)*beta*gammaincinv((1/8),alpha));
galtonskewness=(q1-2*median+q3)/(q1-q3);
moorskurtosis=(q4-q5+q6-q7)/(q1-q3);
Let's assume that,
sigma=1
beta=[0.1 0.2 0.5 1 2 5];
alpha=[0.1 0.2 0.5 1 2 5];
I have used mesh(X,Y,Z) for the same range of alphas and betas with the same increment but I take the error "these values cannot be complex". I just want to draw something like the one below.
It must be something easy that I am missing out, but I do not understand where the mistake is. I appreciate any help. Thank you!
I ran the above code for a 2D mesh of points for alpha and beta between 0.1 and 5 for both dimensions and I got results for both.
I suspect it's due to your alpha and beta declaration. You are only providing a few points, and if you try to use mesh, it won't get good results. Therefore, define a meshgrid of points for both alpha and beta, then vectorize your MATLAB code to produce the kurotsis and skewness curves. Only under certain situations should you use for loops. In general, you should avoid using them whenever possible.
How meshgrid works is that given a range of X and Y values, it will produce two (or three if you want 3D co-ordinates) arrays where each location in each array gives you the spatial co-ordinate at that particular location. Therefore, if we did something like:
[X,Y] = meshgrid(1:3, 1:3);
This is what we get:
X =
1 2 3
1 2 3
1 2 3
Y =
1 1 1
2 2 2
3 3 3
Notice that in a 2D grid, for the top-left corner, (x,y) = (1,1), and so for the corresponding location in X, we get 1 and Y we get 1. If you do the same logic for any other position in the 2D grid, you simply look at the X and Y values in each array and it will tell you what the component is for each dimension.
As such, instead of looping through all possible points in your grid, generate them all using meshgrid, then vectorize the computation by calculating your values all at once rather than individually. Once you do this, you have the right structure to be able to put this into mesh.
Therefore, try doing this instead:
%// Define meshgrid of points
[alpha,beta] = meshgrid(0.1:0.1:5, 0.1:0.1:5);
%// From your code
sigma = 1;
%// Calculate quantities - Notice that this is all vectorized
med=sqrt(2*(sigma^2)*beta.*gammaincinv(0.5,alpha));
q1=sqrt(2*(sigma^2)*beta.*gammaincinv((6/8),alpha));
q3=sqrt(2*(sigma^2)*beta.*gammaincinv((2/8),alpha));
q4=sqrt(2*(sigma^2)*beta.*gammaincinv((7/8),alpha));
q5=sqrt(2*(sigma^2)*beta.*gammaincinv((5/8),alpha));
q6=sqrt(2*(sigma^2)*beta.*gammaincinv((3/8),alpha));
q7=sqrt(2*(sigma^2)*beta.*gammaincinv((1/8),alpha));
galtonskewness=(q1-2*med+q3)./(q1-q3);
moorskurtosis=(q4-q5+q6-q7)./(q1-q3);
%// Show our meshes
figure;
mesh(alpha, beta, galtonskewness);
figure;
mesh(alpha, beta, moorskurtosis);
Also take note that I renamed your median variable to med. MATLAB has a function called median and so you don't want to unintentionally shadow over this function with a variable of the same name.
This is what I get:
Take note that I'm not getting the plots that you have placed in your post. It may be because I'm choosing the wrong variables to define the mesh, or perhaps your equations may be incorrect. Double check what you know in theory to what you have here in code and try again.
This should hopefully give you enough to start with though!

generate white noise in matlab interval [-1 1] [duplicate]

This question already has answers here:
Generate white noise with amplitude between [-1 1] with Matlab
(6 answers)
Closed 9 years ago.
I would like to create or generate white noise in the range of [-1 1], but I don't know exactly how to do it. My programming language of choice is matlab. As far as I know there exists a function named randn and also a function named wgn (white gaussian noise). So please help me with this issue, to clarify, for example I want to generate following equation:
x(t)=20*sin(2*pi*f1*t)+30*cos(2*pi*f2*t)+A3*white noise
where A3=amplitude and white noise is in the range [-1 1]. Please help me and clarify how to do it. My confusion is related to white noise, not about the others, let's assume that t is changing from 1 to 100.
white noise is a random signal with a flat (constant) power spectral density. for that you can use rand. In order to obtain white noise in the interval [-1 1] you can just add to your expression white_noise=(rand(1,t)*2-1) .
I am not quite sure, but as natan says, you should be able to generate white noise from a uniform distribution of random samples.
I would proceed as follows:
wn = unifrnd(-seed,seed,[m,n])/seed;