How to compute 1D convolution in Matlab? - 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');

Related

How to create a polynomial that accepts vectors?

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.

Turning matrix diagonals to columns

I am looking for a matrix operation of the form: B = M*A*N where A is some general square matrix and M and N are the matrices I want to find.
Such that the columns of B are the diagonals of A. The first column the main diagonal, the second the diagonal shifted by 1 from the main and so on.
e.g. In MATLAB syntax:
A = [1, 2, 3
4, 5, 6
7, 8, 9]
and
B = [1, 2, 3
5, 6, 4
9, 7, 8]
Edit:
It seems a pure linear algebra solution doesn't exist. So I'll be more precise about what I was trying to do:
For some vector v of size 1 x m. Then define C = repmat(v,m,1). My matrix is A = C-C.';.
Therefore, A is essentially all differences of values in v but I'm only interested in the difference up to some distance between values.
Those are the diagonals of A; but m is so large that the construction of such m x m matrices causes out-of-memory issues.
I'm looking for a way to extract those diagonals in a way that is as efficient as possible (in MATLAB).
Thanks!
If you're not actually looking for a linear algebra solution, then I would argue that constructing three additional matrices the same size as A using two matrix multiplications is very inefficient in both time and space complexity. I'm not sure it's even possible to find a matrix solution, given my limited knowledge of linear algebra, but even if it is it's sure to be messy.
Since you say you only need the values along some diagonals, I'd construct only those diagonals using diag:
A = [1 2 3;
4 5 6;
7 8 9];
m = size(A, 1); % assume A is square
k = 1; % let's get the k'th diagonal
kdiag = [diag(A, k); diag(A, k-m)];
kdiag =
2
6
7
Diagonal 0 is the main diagonal, diagonal m-1 (for an mxm matrix) is the last. So if you wanted all of B you could easily loop:
B = zeros(size(A));
for k = 0:m-1
B(:,k+1) = [diag(A, k); diag(A, k-m)];
end
B =
1 2 3
5 6 4
9 7 8
From the comments:
For v some vector of size 1xm. Then B=repmat(v,m,1). My matrix is A=B-B.'; A is essentially all differences of values in v but I'm only interested in the difference up to some distance between values.
Let's say
m = 4;
v = [1 3 7 11];
If you construct the entire matrix,
B = repmat(v, m, 1);
A = B - B.';
A =
0 2 6 10
-2 0 4 8
-6 -4 0 4
-10 -8 -4 0
The main diagonal is zeros, so that's not very interesting. The next diagonal, which I'll call k = 1 is
[2 4 4 -10].'
You can construct this diagonal without constructing A or even B by shifting the elements of v:
k = 1;
diag1 = circshift(v, m-k, 2) - v;
diag1 =
2 4 4 -10
The main diagonal is given by k = 0, the last diagonal by k = m-1.
You can do this using the function toeplitz to create column indices for the reshuffling, then convert those to a linear index to use for reordering A, like so:
>> A = [1 2 3; 4 5 6; 7 8 9]
A =
1 2 3
4 5 6
7 8 9
>> n = size(A, 1);
>> index = repmat((1:n).', 1, n)+n*(toeplitz([1 n:-1:2], 1:n)-1);
>> B = zeros(n);
>> B(index) = A
B =
1 2 3
5 6 4
9 7 8
This will generalize to any size square matrix A.

Evaluating MATLAB Quadratic rBform

I have created a planar piecewise biarc curve in MATLAB using the rscvn function. I have been able to plot it as follows:
p = [0 1 2 3; 2 6 3 9];
B = rscvn(p)
fnplt(B)
hold on
scatter([0 1 2 3],[2 6 3 9]);
hold off
Unfortunately I can't for the life of me figure out how to evaluate the function B for an arbitrary position, say 2.6.
How should I attempt this in MATLAB?
You can evaluate a function from the curve fitting toolbox using the fnval function.
See https://www.mathworks.com/help/curvefit/fnval.html
Example code
p = [0 1 2 3; 2 6 3 9];
B = rscvn(p);
fnval(B,2.6)
Output
ans =
1.8526
5.1884
Edit From your comment and the format of your data I assume you are actually looking to estimate a continuous function from your data. In that case you can use.
p = [0 1 2 3; 2 6 3 9];
C = csapi(p(1,:), p(2,:));
fnplt(C)
hold on
scatter([0 1 2 3],[2 6 3 9]);
hold off
fnval(C,2.6)
Output
ans =
4.4960

Multiplying matrix Matlab

I have a matrix M[1,98] and a matrix N[1,x], let's assume in this case x =16.
What I want is to multiply N by M , make the sum by element, and increment the matrix M. With the finality of getting an output of [1,98].
It's a bit confusing. An example:
M=[2 3 4 5 6 7]
N=[1 2 3]
it1=(2*1)+(3*2)+(4*3)+(5*0)+...=20
it2=(3*1)+(4*2)+(5*3)+(6*0)+...=26
it3=..
Output=[20 26 ... ... ... ...]
Like that until the end but considering the size of the matrix N variable. M has always the same size.
That's a convolution:
result = conv(M, N(end:-1:1), 'valid');
To achieve the result you want you need to flip the second vector and keep only the "valid" part of the convolution (no border effects).
In your example:
>> M = [2 3 4 5 6 7];
>> N = [1 2 3];
>> result = conv(M, N(end:-1:1), 'valid')
result =
20 26 32 38

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)