How to create a polynomial that accepts vectors? - matlab

I have a problem with creating a polynomial function of arbitrary length in Matlab, that would work, when used with a vector as an argument.
I have to do an algorithm, that includes and returns a value of a polynomial.
Bellow is my code:
n = 4 % For simplicity, could be arbitrary positive integer
f = #(x) x.^[0:n] %Coefficients are 1 (for this example), if not, would be multiplied with vector of them
p = #(x) sum(f(x)) %My polynomial
>> p(5)
ans =
781
This goes as planed. But because I need a plot, I need my polynomial to be able to receive vectors of values and return them. But when I do this, an error pops up.
Example:
>>p([1 2 3 4])
Error using .^
Matrix dimensions must agree.
Error in #(x)x.^[0:n]
Error in #(x)sum(f(x))
What I want it to return is a vector of length 4 with values of my polynomial [p(1) p(2) p(3) p(4)]
I got around this by creating a values vector with a for loop, but am just wondering, is it possible to change my code, so this would work?

The problem can be easily fixed using a row and a column vector, instead of two row vectors:
p([1 2 3 4]')
and explicitly defining the dimension along which you want to take the summation:
p = #(x) sum(f(x), 2)
Explanation
Note that .^ is an element wise operation. p([1 2 3 4 5]) works, because both row vectors have the same size, but doesn't return the desired result, i.e. it calculates 1^0 + 2^1 + 3^2 + 4^3 + 5^4 = 701.
Matlab automatically expands (in pseudo matlab code)
[1 .^ [0 1 2 3 4]
2
3
4]
to
[1 1 1 1 .^ [0 1 2 3 4
2 2 2 2 0 1 2 3 4
3 3 3 3 0 1 2 3 4
4 4 4 4] 0 1 2 3 4]
Backward compatibility (2006-2016a)
The definition of f should be changed because matlab does not support automatic arithmetic expansion yet.
f = #(x) bsxfun(#power, x, 0:n);
Backward compatibility (1996-2005)
bsxfun didn't exist yet, so one should resort to repmat.

Related

How to compute 1D convolution in Matlab?

Suppose I have 2 vectors, data vector:
x=[2 1 2 1]
and weights vector
y=[1 2 3]
I want Matlab to convolve these vectors in sense of 1D neural network, i.e. run y as window against x and compute convolutions:
If I run built-in function conv then I get
>> conv(x,y)
ans =
2 5 10 8 8 3
which contains correct values in the middle but has something unknown at margins. Manual for conv function looks completely different with what I want.
If I run
>> conv(x,y, 'same')
ans =
5 10 8 8
I also get something strange.
You were very close to solving it by specifying the 3rd input to conv, but instead of 'same' you should've used 'valid':
x = [2 1 2 1];
y = [1 2 3];
conv(x,y,'valid')
ans =
10 8
Just reverse the filter:
x = [2,1,2,1];
y = [1,2,3];
z = conv(x,flip(y),'valid');

Applying median filter to data with 2 axes

I have the following code:
x = VarName3;
y = VarName4;
x = (x/6000)/60;
plot(x, y)
Where VarName3 and VarName4 are 3000x1. I would like to apply a median filter to this in MATLAB. However, the problem I am having is that, if I use medfilt1, then I can only enter a single array of variables as the first argument. And for medfilt2, I can only enter a matrix as the first argument. But the data looks very obscured if I convert x and y into a matrix.
The x is time and y is a list of integers. I'd like to be able to filter out spikes and dips. How do I go about doing this? I was thinking of just eliminating the erroneous data points by direct manipulation of the data file. But then, I don't really get the effect of a median filter.
I found a solution using sort.
Median is the center element, so you can sort three elements, and take the middle element as median.
sort function also returns the index of the previous syntaxes.
I used the index information for restoring the matching value of X.
Here is my code sample:
%X - simulates time.
X = [1 2 3 4 5 6 7 8 9 10];
%Y - simulates data
Y = [0 1 2 0 100 1 1 1 2 3];
%Create three vectors:
Y0 = [0, Y(1:end-1)]; %Left elements [0 0 1 2 0 2 1 1 1 2]
Y1 = Y; %Center elements [0 1 2 0 2 1 1 1 2 3]
Y2 = [Y(2:end), 0]; %Right elements [1 2 0 2 1 1 1 2 3 0]
%Concatenate Y0, Y1 and Y2.
YYY = [Y0; Y1; Y2];
%Sort YYY:
%sortedYYY(2, :) equals medfilt1(Y)
%I(2, :) equals the index: value 1 for Y0, 2 for Y1 and 3 for Y2.
[sortedYYY, I] = sort(YYY);
%Median is the center of sorted 3 elements.
medY = sortedYYY(2, :);
%Corrected X index of medY
medX = X + I(2, :) - 2;
%Protect X from exceeding original boundries.
medX = min(max(medX, min(X)), max(X));
Result:
medX =
1 2 2 3 6 7 7 8 9 9
>> medY
medY =
0 1 1 2 1 1 1 1 2 2
Use a sliding window on the data vector centred at a given time. The value of your filtered output at that time is the median value of the data in the sliding window. The size of the sliding window is an odd value, not necessarily fixed to 3.

Checking values of two vectors against eachother and then using the column location of equal entries to extract colums from a matrix in matlab

I'm doing a curve fitting problem in Matlab and so far I've set up some orthonormal polynomials along a specified range of x-values with x = (0:0.0001:40);
The polynomials themselves are each a manipulation of that x vector and are stored as a row in a matrix. I also have some have data entries in the form of two vectors - one for the data x-coords and one for the actual values. I need a way to use the x-coords of my data points to find the same values in my continuous x-vector and then take the corresponding columns from my polynomial matrix and add them to a new matrix.
EDIT: To be more clear. I have, for example:
x = [0 1 2 3 4 5]
Polynomial =
1 1 1 1 1 1
0 1 2 3 4 5
0 1 4 9 16 25
% Data values:
x-coord = [1 3 4]
values = [5 3 8]
I want to check the x-coord values against 'x' to find the corresponding columns and then pull out those columns from the polynomial matrix to get:
Polynomial =
1 1 1
1 3 4
1 9 16
If your x, Polynomial, and xcoord are the same length you could use logical indexing which is elegant; something along the lines of Polynomial(x==xcoord). But since this doesn't seem to be the case, there's a less fancy solution with a for-loop and find(xcoord(i)==x)

Impulse response function in matlab

There are examples for summation of a vector but not for matrix in Matlab. So please help solve the following:
How to write impulse response function in matlab?
I want program in Matlab for the equation:
hij(t) = ∑_(k=1)to n (φik*φjk*e-xwk*sin(wdk(t))/(M*wdk))
h is impulse response function
φ is mode shape
x is constant
wk is kth mode nat frequency
wdk is kth mode damped frequency
M is mass matrix.
Summing on a matrix, in general, looks like this:
>> A = randi(5,[3,6]) % Creating a random [3 x 6] integer matrix
A =
3 4 4 1 2 4
3 4 4 3 3 2
4 2 1 5 2 3
>> sum(A) % Sums on rows (dim=1 is default) so you get a [1 x 6] vector
ans =
10 10 9 9 7 9
>> sum(A,2) % Sums on columns (dim=2) so you get a [3 x 1] vector
ans =
18
19
17
And similarly if you had a 3D matrix V, then you could do sum(V,3) to sum on the slices.
If you want more specific help, please note the dimensions of each input (phi_i, phi_j, M, w, and wd)

How do you concatenate the rows of a matrix into a vector?

For an m-by-m (square) array, how do you concatenate all the rows into a column vector with size m^2 ?
There are a couple of different ways you can collapse your matrix into a vector, depending upon how you want the contents of your matrix to fill that vector. Here are two examples, one using the function reshape (after first transposing the matrix) and one using the colon syntax (:):
>> M = [1 2 3; 4 5 6; 7 8 9]; % Sample matrix
>> vector = reshape(M.', [], 1) % Collect the row contents into a column vector
vector =
1
2
3
4
5
6
7
8
9
>> vector = M(:) % Collect the column contents into a column vector
vector =
1
4
7
2
5
8
3
6
9
A very important note in changing a matrix to a vector is that , MATLAB produce the output vector form the columns of the matrix, if you use A(:)
for example :
A = [1 2 3 ; 4 5 6]
B = A (:)
B = [1 4 2 5 3 6]
You can see the direction of changing in the following image.