I am trying to study some codes inside a wireless communication textbook, which I have a piece of code from the textbook:
function PL=PL_free(fc,dist,Gt,Gr)
% Free Space Path loss Model
% Input
% fc : carrier frequency[Hz]
% dist : between base station and mobile station[m]
% Gt : transmitter gain
% Gr : receiver gain
% output
% PL : path loss[dB]
lamda = 3e8/fc;
tmp = lamda./(4*pi*dist);
if nargin>2
tmp = tmp*sqrt(Gt);
end
if nargin>3
tmp = tmp*sqrt(Gr);
end
PL = -20*log10(tmp);
And inside the textbook, there is also a graph that is generated based on this Matlab code. My question is, how can I create this graph based on the function myself? Do I need to have a data source for all of the variables? If I cannot get a data source like an excel file, is there any way inside Matlab there is a built-in tool that supports creating this graph? The graph is like this:
(I understand the concept of the plot which is in the command, enter some data of the function, but it will only show the answer of the function output. I cannot find a suitable solution anywhere online so here I come)
After revision:
I haven't testet this, but something along the lines of:
fc = __ % Choose value
Gt = __ % Choose value
Gr = __ % Choose value
dist = logspace(0, 3, 16);
PL=PL_free(fc,dist,Gt,Gr);
semilogx(dist, PL, 'ro')
Alternatively:
dist = logspace(0, 3, 16);
PL = zeros(1, numel(dist));
for ii = 1:numel(dist)
PL(ii) = PL_free(fc, dist, Gt, Gr);
end
semilogx(dist, PL, 'ro')
I'm not sure if linspace or logspace is best here.linspace creates a vector with equally spaced values, while logspace creates a vector with logarithmically spaced values. To plot more values you can do hold on or hold all, and do semilogx with a new PL.
Related
I need help creating a closed-loop system using unity feedback such that the system resembles the one in the image.
There are 4 states in the system and K is a 1x4 matrix. The open loop system is described by:
%State-space model
A=[-0.231308504369119,0.0544096693079551,-0.000124548233093912,-0.990288665751696;0,0,1,0;-21.9913440608126,0,-4.27507057923922,1.16034911016267;11.8852437044909,0,-0.450303860814642,-0.711734908447950];
B=[-0.0109680172306510,0.0630660990762435;0,0;-32.2767539463422,5.44547987525456;-2.63365317966200,-7.15884612728451];
C=eye(4);
D=zeros(4,1);
% this is the cruise speed (TAS)
V = 180;
g0 = 9.81;
%% Open-loop response
% Check the eigenvalues. Note the bad damping of the Dutch roll and
% spiral modes
eigA = eig(A);
% Aileron control only.
Ba = B(:,1);
% Create state-space system (open loop system, only aileron control), generate simulation output for a step input on
% the aileron
sa = ss(A, Ba, C, D);
I have tried:
feedback(K,-1*ones(1,4),-1)
but this doesn't work. I get the error:
not enough input arguments
How do I fix this?
I am currently trying to plot in matlab a wind rose diagram with data wind velocities and directions for a given period.
The main program is such that after plotting several plots on the Weibull distribution, it calls another matlab program to produce a wind rose.
The wind rose program is essentially here: https://www.mathworks.com/matlabcentral/fileexchange/47248-wind-rose
and the main program is mainly based on https://www.mathworks.com/matlabcentral/fileexchange/41996-computing-weibull-distribution-parameters-from-a-wind-speed-time-series?focused=3786165&tab=function
I've been working yesterday on a very old matlab edition and I had serious problems with making the code run.
Today with Octave in a Ubuntu machine and after some efforts I managed to get a result with a minor problem: the wind rose did not had all the information it should have.
I run the program in a new version of matlab and then I got the following message:
Error using WindRose (line 244)
is not a valid property for WindRose function.
Error in octavetestoforiginalprogram (line 184)
[figure_handle,count,speeds,directions,Table] = WindRose(dir,vel,Options);
How can the program run in Octave and now produces such an error, I don't understand.
Does anyone have an idea of what this error means?
Note: I am posting the entire code below if anyone wants to read it:
%% EXTRACT AND PLOT RAW DATA
% Extract wind speed data from a file
v = xlsread('1981-1985_timeseries.xlsx');
% Plot the measured wind speed
plot(v)
title('Wind speed time series');
xlabel('Measurement #');
ylabel('Wind speed [m/s]');
%% PROCESS DATA
% Remove nil speed data (to avoid infeasible solutions in the following)
v(find(v==0)) = [];
% Extract the unique values occuring in the series
uniqueVals = unique(v);
uniqueVals(isnan(uniqueVals))=[];
% Get the number of unique values
nbUniqueVals = length(uniqueVals);
% Find the number of occurences of each unique wind speed value
for i=1:nbUniqueVals
nbOcc = v(find(v==uniqueVals(i)));
N(i) = length(nbOcc);
end
% Get the total number of measurements
nbMeas = sum(N);
% To take into account the measurement resolution
% (i.e., a measured wind speed of 2.0 m/s may actually correspond to a
% real wind speed of 2.05 or 1.98 m/s), compute the delta vector which
% contains the difference between two consecutive unique values
delta(1) = uniqueVals(1);
for i=2:nbUniqueVals
delta(i) = uniqueVals(i) - uniqueVals(i-1);
end
% Get the frequency of occurence of each unique value
for i=1:nbUniqueVals
prob(i) = N(i)/(nbMeas*delta(i));
end
% Get the cumulated frequency
freq = 0;
for i=1:nbUniqueVals
freq = prob(i)*delta(i) + freq;
cumFreq(i) = freq;
end
%% PLOT THE RESULTING DISTRIBUTION
% Plot the distribution
figure
subplot(2,1,1);
pp=plot(uniqueVals,prob)
title('Distribution extracted from the time series');
xlabel('Wind speed [m/s]');
ylabel('Probability');
% Plot the cumulative distribution
subplot(2,1,2);
plot(uniqueVals,cumFreq)
title('Cumulative distribution extracted from the time series');
xlabel('Wind speed [m/s]');
ylabel('Cumulative probability');
%% EXTRACT THE PARAMETERS USING A GRAPHICAL METHOD
% See the following references for more explanations:
% - Akdag, S.A. and Dinler, A., A new method to estimate Weibull parameters
% for wind energy applications, Energy Conversion and Management,
% 50 :7 1761�1766, 2009
% - Seguro, J.V. and Lambert, T.W., Modern estimation of the parameters of
% the Weibull wind speed distribution for wind energy analysis, Journal of
% Wind Engineering and Industrial Aerodynamics, 85 :1 75�84, 2000
% Linearize distributions (see papers)
ln = log(uniqueVals);
lnln = log(-log(1-cumFreq));
% Check wether the vectors contain inifinite values, if so, remove them
test = isinf(lnln);
for i=1:nbUniqueVals
if (test(i)==1)
ln(i)= [];
lnln(i)= [];
end
end
% Extract the line parameters (y=ax+b) using the polyfit function
params = polyfit(ln,lnln',1);
a = params(1);
b = params(2);
y=a*ln+b;
% Compare the linealized curve and its fitted line
figure
plot(ln,y,'b',ln,lnln,'r')
title('Linearized curve and fitted line comparison');
xlabel('x = ln(v)');
ylabel('y = ln(-ln(1-cumFreq(v)))');
% Extract the Weibull parameters c and k
k = a
c = exp(-b/a)
%% CHECK RESULTS
% Define the cumulative Weibull probability density function
% F(V) = 1-exp(-((v/c)^k)) = 1-exp(-a2), with a1 = v/c, a2 = (v/c)^k
a1 = uniqueVals/c;
a2 = a1.^k;
cumDensityFunc = 1-exp(-a2);
% Define the Weibull probability density function
%f(v)=k/c*(v/c)^(k-1)*exp(-((v/c)^k))=k2*a3.*exp(-a2),
% with k2 = k/c, a3 = (v/c)^(k-1)
k1 = k-1;
a3 = a1.^k1;
k2 = k/c;
densityFunc = k2*a3.*exp(-a2);
% Plot and compare the obtained Weibull distribution with the frequency plot
figure
subplot(2,2,1);
pp=plot(uniqueVals,prob,'.',uniqueVals,densityFunc, 'r')
title('Weibull probability density function');
xlabel('v');
ylabel('f(v)');
subplot(2,2,3)
h=hist(v);
title('Wind speed time series');
xlabel('Measurement #');
ylabel('Wind speed [m/s]');
h=h/(sum(h)*10);
bar(h)
% Same for the cumulative distribution
subplot(2,2,2);
plot(uniqueVals,cumFreq,'.',uniqueVals,cumDensityFunc, 'r')
title('Cumulative Weibull probability density function');
xlabel('v');
ylabel('F(V)');
%inner
figure
hold on
pp=plot(uniqueVals,prob,'.',uniqueVals,densityFunc, 'r')
title('Weibull probability density function');
xlabel('v');
ylabel('f(v)');
bar(h)
hold off
%inner
%rose
w=xlsread('rose.xlsx');
dir=w(:,2)*10;
vel=w(:,1);
Options = {'anglenorth','FreqLabelAngle',0,'angleeast','FreqLabelAngle',90,'labels',{'N (0)','S (180)','E (90)','W (270)'},'freqlabelangle',45,'nDirections',20,'nFreq',25,'LegendType',1};
[figure_handle,count,speeds,directions,Table] = WindRose(dir,vel,Options);
close all; clear Options;
After a quick read of the script documentation, here is what I found concerning the creation of the windrose plot:
% With options in a cell array:
Options = {'anglenorth',0,'angleeast',90,'labels',{'N (0°)','S (180°)','E (90°)','W (270°)'},'freqlabelangle',45};
[figure_handle,count,speeds,directions,Table] = WindRose(dir,spd,Options);
% With options in a structure:
Options.AngleNorth = 0;
Options.AngleEast = 90;
Options.Labels = {'N (0°)','S (180°)','E (90°)','W (270°)'};
Options.FreqLabelAngle = 45;
[figure_handle,count,speeds,directions,Table] = WindRose(dir,spd,Options);
close all;
% Usual calling:
[figure_handle,count,speeds,directions,Table] = WindRose(dir,spd,'anglenorth',0,'angleeast',90,'labels',{'N (0°)','S (180°)','E (90°)','W (270°)'},'freqlabelangle',45);
Your error is:
Error using WindRose (line 244)
is not a valid property for WindRose function.
Error in octavetestoforiginalprogram (line 184)
[figure_handle,count,speeds,directions,Table] = WindRose(dir,vel,Options);
And it is being produced within the routine that undertakes option arguments sanitization. Since options must be provided in the form of name-value pairs... it seems that the script is detecting a mismatching number of elements and one or more names with a missing value. And here they are:
Options =
{'anglenorth','FreqLabelAngle',0,'angleeast','FreqLabelAngle',90,'labels',{'N
(0)','S (180)','E (90)','W
(270)'},'freqlabelangle',45,'nDirections',20,'nFreq',25,'LegendType',1};
The two properties marked with a bold font have no value associated to them (unlike the examples in the tutorial) and this probably messes up the whole parametrization process. Probably, the first option being extracted is anglenorth = FreqLabelAngle, which is not correct.
I have a set of frequency data with peaks to which I need to fit a Gaussian curve and then get the full width half maximum from. The FWHM part I can do, I already have a code for that but I'm having trouble writing code to fit the Gaussian.
Does anyone know of any functions that'll do this for me or would be able to point me in the right direction? (I can do least squares fitting for lines and polynomials but I can't get it to work for gaussians)
Also it would be helpful if it was compatible with both Octave and Matlab as I have Octave at the moment but don't get access to Matlab until next week.
Any help would be greatly appreciated!
Fitting a single 1D Gaussian directly is a non-linear fitting problem. You'll find ready-made implementations here, or here, or here for 2D, or here (if you have the statistics toolbox) (have you heard of Google? :)
Anyway, there might be a simpler solution. If you know for sure your data y will be well-described by a Gaussian, and is reasonably well-distributed over your entire x-range, you can linearize the problem (these are equations, not statements):
y = 1/(σ·√(2π)) · exp( -½ ( (x-μ)/σ )² )
ln y = ln( 1/(σ·√(2π)) ) - ½ ( (x-μ)/σ )²
= Px² + Qx + R
where the substitutions
P = -1/(2σ²)
Q = +2μ/(2σ²)
R = ln( 1/(σ·√(2π)) ) - ½(μ/σ)²
have been made. Now, solve for the linear system Ax=b with (these are Matlab statements):
% design matrix for least squares fit
xdata = xdata(:);
A = [xdata.^2, xdata, ones(size(xdata))];
% log of your data
b = log(y(:));
% least-squares solution for x
x = A\b;
The vector x you found this way will equal
x == [P Q R]
which you then have to reverse-engineer to find the mean μ and the standard-deviation σ:
mu = -x(2)/x(1)/2;
sigma = sqrt( -1/2/x(1) );
Which you can cross-check with x(3) == R (there should only be small differences).
Perhaps this has the thing you are looking for? Not sure about compatability:
http://www.mathworks.com/matlabcentral/fileexchange/11733-gaussian-curve-fit
From its documentation:
[sigma,mu,A]=mygaussfit(x,y)
[sigma,mu,A]=mygaussfit(x,y,h)
this function is doing fit to the function
y=A * exp( -(x-mu)^2 / (2*sigma^2) )
the fitting is been done by a polyfit
the lan of the data.
h is the threshold which is the fraction
from the maximum y height that the data
is been taken from.
h should be a number between 0-1.
if h have not been taken it is set to be 0.2
as default.
i had similar problem.
this was the first result on google, and some of the scripts linked here made my matlab crash.
finally i found here that matlab has built in fit function, that can fit Gaussians too.
it look like that:
>> v=-30:30;
>> fit(v', exp(-v.^2)', 'gauss1')
ans =
General model Gauss1:
ans(x) = a1*exp(-((x-b1)/c1)^2)
Coefficients (with 95% confidence bounds):
a1 = 1 (1, 1)
b1 = -8.489e-17 (-3.638e-12, 3.638e-12)
c1 = 1 (1, 1)
I found that the MATLAB "fit" function was slow, and used "lsqcurvefit" with an inline Gaussian function. This is for fitting a Gaussian FUNCTION, if you just want to fit data to a Normal distribution, use "normfit."
Check it
% % Generate synthetic data (for example) % % %
nPoints = 200; binSize = 1/nPoints ;
fauxMean = 47 ;fauxStd = 8;
faux = fauxStd.*randn(1,nPoints) + fauxMean; % REPLACE WITH YOUR ACTUAL DATA
xaxis = 1:length(faux) ;fauxData = histc(faux,xaxis);
yourData = fauxData; % replace with your actual distribution
xAxis = 1:length(yourData) ;
gausFun = #(hms,x) hms(1) .* exp (-(x-hms(2)).^2 ./ (2*hms(3)^2)) ; % Gaussian FUNCTION
% % Provide estimates for initial conditions (for lsqcurvefit) % %
height_est = max(fauxData)*rand ; mean_est = fauxMean*rand; std_est=fauxStd*rand;
x0 = [height_est;mean_est; std_est]; % parameters need to be in a single variable
options=optimset('Display','off'); % avoid pesky messages from lsqcurvefit (optional)
[params]=lsqcurvefit(gausFun,x0,xAxis,yourData,[],[],options); % meat and potatoes
lsq_mean = params(2); lsq_std = params(3) ; % what you want
% % % Plot data with fit % % %
myFit = gausFun(params,xAxis);
figure;hold on;plot(xAxis,yourData./sum(yourData),'k');
plot(xAxis,myFit./sum(myFit),'r','linewidth',3) % normalization optional
xlabel('Value');ylabel('Probability');legend('Data','Fit')
I have a large number (~1000) of files from a data logger that I am trying to process.
If I wanted to plot the trend from a single one of these log files I could do it using
plot(timevalues,datavalues)
I would like to be able to view all of these lines at same time in a similar way to how an oscilloscope has a "persistant" mode.
I can probably cobble together something that uses histograms but am hoping there is pre-existing or more elegant solution to this problem.
You can do exactly what you are suggesting yourself, i.e. plotting the heatmap of the signals.
Consider the following: I'll build a test signals (out of sine waves of different amplitude), then I'll plot the heatmap via hist3 and imagesc.
The idea is to build an auxiliary signal which is just the juxtaposition of all your time histories (both in x and y), then extract basic bivariate statistics out of that.
% # Test signals
xx = 0 : .01 : 2* pi;
center = 1;
eps_ = .2;
amps = linspace(center - eps_ , center + eps_ , 100 );
% # the auxiliary signal will be stored in the following variables
yy = [];
xx_f = [];
for A = amps
xx_f = [xx_f,xx];
yy = [yy A*sin(xx)];
end
% # final heat map
colormap(hot)
[N,C] = hist3([xx_f' yy'],[100 100]);
imagesc(C{1},C{2},N')
You can use also jet colormap instead of hot colormap for readability.
In the following the amplitude is gaussian instead of homogeneus.
here's a "primitive" solution that is just using hist:
%# generate some fake data
x=-8:0.01:8;
y=10*sinc(x);
yy=bsxfun(#plus,y,0.1*randn(numel(x),1000)' );
yy(randi(1000,1,200),:)= 5-randi(10)+ circshift(yy(randi(1000,1,200),:),[1 randi(numel(x),1,200)]);
%# get plot limit parameters
plot(x,yy)
yl=get(gca,'Ylim');
xl=get(gca,'Xlim');
close all;
%# set 2-d histogram ranges
ybins=100;
xbins=numel(x);
yrange=linspace(yl(1),yl(2),ybins);
xrange=linspace(xl(1),xl(2),xbins);
%# prealocate
m=zeros(numel(yrange),numel(xrange));
% build 2d hist
for n=1:numel(x)
ind=hist(yy(:,n),yrange);
m(:,n)=m(:,n)+ind(:);
end
imagesc(xrange,yrange,m)
set(gca,'Ydir','normal')
Why don't you normalize the data and then add all the lines together? You could then plot the heatmap from the single datafile.
Hi i am trying to make a simple distribution histogram using some code from stack overflow
however i am unable to get it to work. i know that there are is a simple method for this using statistic toolbox but form a learning point of view i prefer a more explanatory code - can any one help me ?
%%
clear all
load('Mini Project 1.mat')
% Set data to var2
data = var2;
% Set the number of bins
nbins = 0:.8:8;
% Create a histogram plot of data sorted into (nbins) equally spaced bins
n = hist(data,nbins);
% Plot a bar chart with y values at each x value.
% Notice that the length(x) and length(y) have to be same.
bar(nbins,n);
MEAN = mean(data);
STD = sqrt(mean((data - MEAN).^2)); % can also use the simple std(data)
f = ( 1/(STD*sqrt(2*pi)) ) * exp(-0.5*((nbins-MEAN)/STD).^2 );
f = f*sum(nbins)/sum(f);
hold on;
% Plots a 2-D line plot(x,y) with the normal distribution,
% c = color cyan , Width of line = 2
plot (data,f, 'c', 'LineWidth', 2);
xlabel('');
ylabel('Firmness of apples after one month of storage')
title('Histogram compared to normal distribution');
hold of
You are confusing
hist
with
histc
Read up on both.
Also, you are not defining the number of bins, you are defining the bins themselves .
I don't have Matlab at hand now, but try the following:
If you want to compare a normal distribution to the bar plot bar(nbins,n), you should first normalize it:
bar(nbins,n/sum(n))
See if this solves your problem.
If not, try also removing the line f = f*sum(nbins)/sum(f);.