How can I define Y to be different for different X values like a histogram - matlab

I'm trying to plot a probability mass function for the probability of certain sums when rolling three dices and I found this example in MathCad and wondered if there is anything like it in MatLab?

I imagine you’d build that as a lookup table rather than a series of if/else statements. It is easy to compute the probabilities using convolution:
f1 = ones(1,6);
f2 = conv(f1,f1);
f = conv(f2,f1);
% because f contains values from x=3 to 18,
% rather than starting at 1 as MATLAB arrays do,
% we add two zeros to the front:
f = [0,0,f];
Now f(x) returns the probability of throwing x.

Related

animation to show generation of certain random line segments

I am trying to understand these by myself
,
I want to simulate some straight lines, in Matlab, as follows:
f(t,z)=a(z)t+b(z) where a(z) and b(z) are uniformly distributed random variable in the interval [-1,1] and t is time between [-2,2]. More simply: f(t)= at+b, and z is the random index of the constant (a,b) and let say [-1,+1] is the sample space for z and z is uniformly distributed.
Could anyone help me with the code? Is there any way to show the random generation of the straight line as an animation? Thank you very much for any help.
I am trying like this:
a= rand(-1,1);
b=rand(-1,1);
-2<t<2;
f=a*t+b;
plot(t, f);
But I am getting error Unrecognized function or variable 't'.
Your attempt is not valid MATLAB syntax,
-2<t<2 does not do anything, other than produce the error you're seeing because t does not exist
f = a*t+b you can't define functions like this, you probably want to use an anonymous function.
You can't plot t because you haven't defined it, and you can't plot f because you haven't properly defined that either in terms of a valid t.
You need to define some discrete values for t. In this case two values is enough, because you're only plotting straight lines anyway. You could use linspace or the colon operator to create a finer spaced array for whatever reason.
N = 10; % Number of lines to plot
t = [-2,2]; % We want lines between -2 and 2
a = rand(N,1)*2-1; % N random values between -1 and +1
b = rand(N,1)*2-1; % N random values between -1 and +1
f = #(t,z) a(z)*t + b(z); % Define f in terms of axis t and index z
% Plotting
figure; hold on;
for iz = 1:N
plot( t, f(t,iz) );
end
This gives an image something like this:
If you need an "animation", you could add a pause, e.g. pause(1) inside the loop

storing and accessing with matrices of more than two dimensions

I am using ode45 to solve a system with 4 variables. For each time I execute the code:
[t y] = ode45(#func, tspan, y0);
t will be a one dimensional matrix, while y will be a 2 dimensional matrix, with 4 columns, each of which is the solution for one of the variables in question.
I want to run multiple trials of this, and keep them in a 3D matrix my_y_results and my_t_results. I want to be able to, for example, plot the final value of a certain variable for a particular initial condition, as I change the initial condition. How would I do this?
So, on each iteration of the loop below, I want to place the new values in a new matrix.
for i = 1:1:10
y0 = **some value**
[t_temp, y_temp] = ode45(#func, tspan, y0);
my_t_results = **something**
my_y_results = *something* //your code here
end
Also, how would I access the different values after setting them? For example, to get the last value of the variable y(1) for each of the 10 trials, what code would I use?
Higher dimensions can be accessed similar to the usual row and column dimensions. Let's assume t is Nx1 and y is Nx4, and that we are running M trials (note that each trial will have to have the same number of points, N, in order to store the data in a 3-dimensional array).
Your array my_t_results doesn't have to be 3-dimensional and can simply be NxM, where each column is the time vector for a different trial.
The array my_y_results would be Nx4xM and can be defined in MATLAB with:
my_y_results = zeros(N,4,M);
At the end of each i'th trial you would store the results like this:
my_y_results(:,:,i) = y;
And of course accessing the data is similar:
y_i = my_y_results(:,:,i);

Square wave function for Matlab

I'm new to programming in Matlab. I'm trying to figure out how to calculate the following function:
I know my code is off, I just wanted to start with some form of the function. I have attempted to write out the sum of the function in the program below.
function [g] = square_wave(n)
g = symsum(((sin((2k-1)*t))/(2k-1)), 1,n);
end
Any help would be much appreciated.
Update:
My code as of now:
function [yout] = square_wave(n)
syms n;
f = n^4;
df = diff(f);
syms t k;
f = 1; %//Define frequency here
funcSum = (sin(2*pi*(2*k - 1)*f*t) / (2*k - 1));
funcOut = symsum(func, v, start, finish);
xsquare = (4/pi) * symsum(funcSum, k, 1, Inf);
tVector = 0 : 0.01 : 4*pi; %// Choose a step size of 0.01
yout = subs(xsquare, t, tVector);
end
Note: This answer was partly inspired by a previous post I wrote here: How to have square wave in Matlab symbolic equation - However, it isn't quite the same, which is why I'm providing an answer here.
Alright, so it looks like you got the first bit of the question right. However, when you're multiplying things together, you need to use the * operator... and so 2k - 1 should be 2*k - 1. Ignoring this, you are symsuming correctly given that square wave equation. The input into this function is only one parameter only - n. What you see in the above equation is a Fourier Series representation of a square wave. A bastardized version of this theory is that you can represent a periodic function as an infinite summation of sinusoidal functions with each function weighted by a certain amount. What you see in the equation is in fact the Fourier Series of a square wave.
n controls the total number of sinusoids to add into the equation. The more sinusoids you have, the more the function is going to look like a square wave. In the question, they want you to play around with the value of n. If n becomes very large, it should start approaching what looks like to be a square wave.
The symsum will represent this Fourier Series as a function with respect to t. What you need to do now is you need to substitute values of t into this expression to get the output amplitude for each value t. They define that for you already where it's a vector from 0 to 4*pi with 1001 points in between.
Define this vector, then you'll need to use subs to substitute the time values into the symsum expression and when you're done, cast them back to double so that you actually get a numeric vector.
As such, your function should simply be this:
function [g] = square_wave(n)
syms t k; %// Define t and k
f = sin((2*k-1)*t)/(2*k-1); %// Define function
F = symsum(f, k, 1, n); %// Define Fourier Series
tVector = linspace(0, 4*pi, 1001); %// Define time points
g = double(subs(F, t, tVector)); %// Get numeric output
end
The first line defines t and k to be symbolic because t and k are symbolic in the expression. Next, I'll define f to be the term inside the summation with respect to t and k. The line after that defines the actual sum itself. We use f and sum with respect to k as that is what the summation calls for and we sum from 1 up to n. Last but not least, we define a time vector from 0 to 4*pi with 1001 points in between and we use subs to substitute the value of t in the Fourier Series with all values in this vector. The result should be a 1001 vector which I then cast to double to get a numerical result and we get your desired output.
To show you that this works, we can try this with n = 20. Do this in the command prompt now:
>> g = square_wave(20);
>> t = linspace(0, 4*pi, 1001);
>> plot(t, g);
We get:
Therefore, if you make n go higher... so 200 as they suggest, you'll see that the wave will eventually look like what you expect from a square wave.
If you don't have the Symbolic Math Toolbox, which symsum, syms and subs relies on, we can do it completely numerically. What you'll have to do is define a meshgrid of points for pairs of t and n, substitute each pair into the sequence equation for the Fourier Series and sum up all of the results.
As such, you'd do something like this:
function [g] = square_wave(n)
tVector = linspace(0, 4*pi, 1001); %// Define time points
[t,k] = meshgrid(tVector, 1:n); %// Define meshgrid
f = sin((2*k-1).*t)./(2*k-1); %// Define Fourier Series
g = sum(f, 1); %// Sum up for each time point
end
The first line of code defines our time points from 0 to 4*pi. The next line of code defines a meshgrid of points. How this works is that for t, each column defines a unique time point, so the first column is 200 zeroes, up to the last column which is a column of 200 4*pi values. Similarly for k, each row denotes a unique n value so the first row is 1001 1s, followed by 1001 2s, up to 1001 1s. The implications with this is now each column of t and k denotes the right (t,n) pairs to compute the output of the Fourier series for each time that is unique to that column.
As such, you'd simply use the sequence equation and do element-wise multiplication and division, then sum along each individual column to finally get the square wave output. With the above code, you will get the same result as above, and it'll be much faster than symsum because we're doing it numerically now and not doing it symbolically which has a lot more computational overhead.
Here's what we get when n = 200:
This code with n=200 ran in milliseconds whereas the symsum equivalent took almost 2 minutes on my machine - Mac OS X 10.10.3 Yosemite, 16 GB RAM, Intel Core i7 2.3 GHz.

Numerical Integration Problems with Product Rule due to differnet resolution

I am facing some problem during calculation of Numerical Integration with two data set.
For integration i am using simpsons 1/3 rule.
function I = Simpsons(f,a,b,n)
if numel(f)>1 % If the input provided is a vector
n=numel(f)-1; h=(b-a)/n;
I= h/3*(f(1)+2*sum(f(3:2:end-2))+4*sum(f(2:2:end))+f(end));
else
h=(b-a)/n; xi=a:h:b;
I= h/3*(f(xi(1))+2*sum(f(xi(3:2:end-2)))+4*sum(f(xi(2:2:end)))+f(xi(end)));
end
This code correctly calculates the integration.
Now the problem occurs during the calculation of multiplied values.
for example I have two functions f and g both are depending on same variable.
the variables is in the same ranges. SO lower Limit and Upper Limit is same.
$\int_a^b \! f(x) *g(x) \, \mathrm{d} x.$
here the resolution of x is different. Means for f(x) we have 1000 data where as for g(x) we have 1700 data points. so element by element multiplication cant be done.
How to Solve this integration ..
you'll need to interpolate one of your functions, f or g, to the other function points, for 1D functions that is achievable using interp1.
For example:
% x1 an x2 have the same limits but different # of elements
x1 = linspace(-10,10,100);
x2 = sort(rand(1,170)*20-10); # non-unifrom points from -10 to 10
f1 = sin(x1);
f2 = cos(x2);
now say we want to multiply f1*f2, we need them to have the # of elements, so
f2i= interp1(x2,f2,x1,'spline');
will make f2 to have the same # of elements as f1, or instead
f1i= interp1(x1,f1,x2,'spline');
will make f1 to have the same # of elements as f2.

Modified linear interpolation with missing data

Imagine a set of data with given x-values (as a column vector) and several y-values combined in a matrix (row vector of column vectors). Some of the values in the matrix are not available:
%% Create the test data
N = 1e2; % Number of x-values
x = 2*sort(rand(N, 1))-1;
Y = [x.^2, x.^3, x.^4, x.^5, x.^6]; % Example values
Y(50:80, 4) = NaN(31, 1); % Some values are not avaiable
Now i have a column vector of new x-values for interpolation.
K = 1e2; % Number of interplolation values
x_i = rand(K, 1);
My goal is to find a fast way to interpolate all y-values for the given x_i values. If there are NaN values in the y-values, I want to use the y-value which is before the missing data. In the example case this would be the data in Y(49, :).
If I use interp1, I get NaN-values and the execution is slow for large x and x_i:
starttime = cputime;
Y_i1 = interp1(x, Y, x_i);
executiontime1 = cputime - starttime
An alternative is interp1q, which is about two times faster.
What is a very fast way which allows my modifications?
Possible ideas:
Do postprocessing of Y_i1 to eliminate NaN-values.
Use a combination of a loop and the find-command to always use the neighbour without interpolation.
Using interp1 with spline interpolation (spline) ignores NaN's.