Matlab Generating a Matrix - matlab

I am trying to generate a matrix in matlab which I will use to solve a polynomial regression formula.
Here is how I am trying to generate the matrix:
I have an input vector X containing N elements and an integer d. d is the integer to know how many times we will add a new column to the matrix we are trying to generate int he following way.
N = [X^d X^{d-1} ... X^2 X O]
O is a vector of same length as X with all 1's.
Everytime d > 2 it does not work.
Can you see any errors in my code (i am new to matlab):
function [ PR ] = PolyRegress( X, Y, d )
O = ones(length(X), 1)
N = [X O]
for j = 2:d
tmp = power(X, j)
N = [tmp N]
end
%TO DO: compute PR
end

It looks like the matlab function vander already does what you want to do.

The VANDER function will only generate powers of the vector upto d = length(X)-1. For a more general solution, you can use the BSXFUN function (works with any value of d):
N = bsxfun(#power, X(:), d:-1:0)
Example:
>> X = (1:.5:2);
>> d = 5;
>> N = bsxfun(#power, X(:), d:-1:0)
N =
1 1 1 1 1 1
7.5938 5.0625 3.375 2.25 1.5 1
32 16 8 4 2 1
I'm not sure if this is the order you want, but it can be easily reversed: use 0:d instead of d:-1:0...

Related

How to create a mxn matrix with a specific rank in matlab?

I want to create a m by n matrix with rank k.
Like A is 8 × 8 with rank 5 or B is 4 × 6 with rank 4.
So I try to write a function in MATLAB like below.
My thought is:
generate an m by n zeros matrix
generate m by n matrix and convert it into reduced row echelon form
assign rank of 2.'s matrix to num
if num = k, then assign current matrix to the output
break the iteration
function output = check_rank(m,n,k)
while 1
output = zeros(m,n);
matrix = randi(20,m,n);
tmp = rref(matrix);
num = rank(tmp);
if (num == k)
output = matrix;
break;
end
disp(output);
end
A = check_rank(8,8,4)
The outcome is an infinite loop and all the answers are 6x6 zeros matrix:
Command Window Output
I have also tried method in the how to create a rank k matrix using matlab?
A = zeros(8,8);
for i = 1:4, A = A + randn(8,1) * randn(1,8); end
A
rank(A)
It can reach my goal, but I have no idea how it work successfully?
Thanks, #anonymous!
If you want to generate a random matrix with specified rank, you can try to build a user function like below
function [Y,rk] = fn(m,n,k)
P = orth(randn(m,k));
Q = orth(randn(n,k))';
Y = P*Q;
rk = rank(Y);
end
where P and Q are unitary matrices. Y is the generated matrix with random values, and rk helps you check the rank.
Example
>> [Y,rk] = fn(8,6,5)
Y =
3.8613e-02 7.5837e-03 -7.1011e-02 -7.0392e-02 -3.8519e-02 1.6612e-01
-3.1381e-02 -3.6287e-02 1.4888e-01 -7.6202e-02 -3.7867e-02 3.2707e-01
-1.9689e-01 2.2684e-01 1.2606e-01 -1.2657e-03 1.9724e-01 7.2793e-02
-1.2652e-01 7.7531e-02 1.3906e-01 3.1568e-02 1.8327e-01 -1.3804e-01
-2.6604e-01 -1.4345e-01 1.6961e-03 -9.7833e-02 5.9299e-01 -1.5765e-01
1.7787e-01 -3.5007e-01 3.8482e-01 -6.0741e-02 -2.1415e-02 -2.4317e-01
8.9910e-02 -2.5538e-01 -1.8029e-01 -7.0032e-02 -1.0739e-01 2.2188e-01
-3.4824e-01 3.7603e-01 2.8561e-02 2.6553e-02 2.4871e-02 6.8021e-01
rk = 5
You can easily use eye function:
I = eye(k);
M = zeros(m,n);
M(1:k, 1:k) = I;
The rank(M) is equal to k.

There is a function in Matlab to create a matrix, where each element is the same function of matrix indexes?

For example, a matrix where each value at row r and column c is
a=[r^2+c^2]
like a=[1, 4; 4; 18]
or
A=[F(r,c)]
A=[F(1,1) F(1,2) F(1,3);
F(2,1) F(2,2) F(2,3);
F(3,1) F(3,2) F(3,3)]
or
A(r,c)=F(r,c)
Mehtod 1
You can do it manually. First, create two matrices for rows and columns indices (suppose the matrix is n x m):
R = repmat((1:n).',[1, m]);
C = repmat((1:m),[n, 1]);
Then, write the function base on these two:
result = R.^2 + C.^2; % F(x,y) = x^2 + y^2
Or define the function inline and apply it on those two:
F = #(x,y)(x.^2 + y.^2);
result = F(R,C);
Mehtod 2
By #Cris Luengo, you can do it the first part by the meshgird function as well. Hence, we can generate R and C like the following:
[C,R] = meshgrid(1:n, 1:m)

How to zero out the centre k by k matrix in an input matrix with odd number of columns and rows

I am trying to solve this problem:
Write a function called cancel_middle that takes A, an n-by-m
matrix, as an input where both n and m are odd numbers and k, a positive
odd integer that is smaller than both m and n (the function does not have to
check the input). The function returns the input matrix with its center k-by-k
matrix zeroed out.
Check out the following run:
>> cancel_middle(ones(5),3)
ans =
1 1 1 1 1
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
1 1 1 1 1
My code works only when k=3. How can I generalize it for all odd values of k? Here's what I have so far:
function test(n,m,k)
A = ones(n,m);
B = zeros(k);
A((end+1)/2,(end+1)/2)=B((end+1)/2,(end+1)/2);
A(((end+1)/2)-1,((end+1)/2)-1)= B(1,1);
A(((end+1)/2)-1,((end+1)/2))= B(1,2);
A(((end+1)/2)-1,((end+1)/2)+1)= B(1,3);
A(((end+1)/2),((end+1)/2)-1)= B(2,1);
A(((end+1)/2),((end+1)/2)+1)= B(2,3);
A(((end+1)/2)+1,((end+1)/2)-1)= B(3,1);
A(((end+1)/2)+1,((end+1)/2))= B(3,2);
A((end+1)/2+1,(end+1)/2+1)=B(3,3)
end
You can simplify your code. Please have a look at
Matrix Indexing in MATLAB. "one or both of the row and column subscripts can be vectors", i.e. you can define a submatrix. Then you simply need to do the indexing correct: as you have odd numbers just subtract m-k and n-k and you have the number of elements left from your old matrix A. If you divide it by 2 you get the padding on the left/right, top/bottom. And another +1/-1 because of Matlab indexing.
% Generate test data
n = 13;
m = 11;
A = reshape( 1:m*n, n, m )
k = 3;
% Do the calculations
start_row = (n-k)/2 + 1
start_col = (m-k)/2 + 1
A( start_row:start_row+k-1, start_col:start_col+k-1 ) = zeros( k )
function b = cancel_middle(a,k)
[n,m] = size(a);
start_row = (n-k)/2 + 1;
start_column = (m-k)/2 + 1;
end_row = (n-k)/2 + k;
end_column = (m-k)/2 + k;
a(start_row:end_row,start_column:end_column) = 0;
b = a;
end
I have made a function in an m file called cancel_middle and it basically converts the central k by k matrix as a zero matrix with the same dimensions i.e. k by k.
the rest of the matrix remains the same. It is a general function and you'll need to give 2 inputs i.e the matrix you want to convert and the order of submatrix, which is k.

Multiply each row of a matrix with its transposed self

The formula I have to translate to Octave/Matlab goes something like this:
\sum (v_i - m) (v_i - m)^T
I have a matrix, and I need to take each row, subtract m from it and then multiply it with its own transpose. I wrote the inner part as a function:
function w = str(v, m)
y = v - m
w = y * transpose(y)
end
My matrix is like this
xx = [1 2 3 4 5; 1 2 3 4 5; 1 2 3 4 5]
Now I have no idea how to apply this function to each row in a matrix and then sum them up to a new matrix. Maybe someone can help me here.
EDIT: The result is not the dot product. I'm looking for v * v^T, which has a matrix as result!
Probably you need this
X = bsxfun( #minus, A, m );
Y = X'* X;
Suppose the matrix is A, then the solution is
total = sum(sum((A-m).*(A-m),2));
A.*A is an element wise multiplication, hence sum(A.*A,2) returns a column vector, with each element being the self dot product of each row in A.
If m is a vector then, it is slightly more complicated.
[p,~]=size(A);
total = sum(sum((A-repmat(m,p,1)).*(A-repmat(m,p,1)),2));
Cheers.
In the end, I wrote this:
function w = str(v, m)
y = v - m;
w = y' * y;
end
y = zeros(5,5);
for i=1:12
y = y + str(A(i,:), m);
end
Surely not the most elegant way to do this, but it seems to work.
You can subtract the mean using bsxfun
>> v_m = bsxfun( #minus, v, m );
For the sum of outer product of all vectors you can use bsxfun again
>> op = bsxfun( #times, permute( v, [3 1 2]), permute( v, [1 3 2] ) );
>> op = sum( op, 3 );
There are two ways to solve this issue:
Assume A is your matrix:
sum(drag(A' * A))
will do the job. However, it is slightly more efficient with the following:
sum((A .* A)(:))

Obtain matrix of indices in octave / matlab

Given some multidimensional matrix A in Octave / Matlab,
What's the easiest way to get a matrix of the same size as A where all elements are replaced by their index along the k'th dimension
ie for the matrix
A =
ans(:,:,1) =
0.095287 0.191905
0.226278 0.749100
ans(:,:,2) =
0.076826 0.131639
0.862747 0.699016
I want a function f such that
f(A,1) =
ans(:,:,1) =
1 1
2 2
ans(:,:,2) =
1 1
2 2
f(A,2) =
ans(:,:,1) =
1 2
1 2
ans(:,:,2) =
1 2
1 2
and
f(A, 3) =
ans(:,:,1) =
1 1
1 1
ans(:,:,2) =
2 2
2 2
Also, given a sparse matrix B
What's the easiest way to get another sparse matrix of the same size where the nonzero elements are replaced by their index along the k'th dimension? (so same problem as above, but for only the nonzero elements)
Ideally I'm looking for a way which is well-vectorized for octave (meaning it doesn't explicitly loop over anything)
CLARIFICATION: For the sparse matrix one, I'm looking for a solution which does not involve creating a full size(B) matrix at any point
ndgrid() does what you want, although not in the format you are looking for. If you know the dims of the input A beforehand, you can use the following line to create the N-dimentional mesh grid:
% for matrix a where ndims(a) == 3
[x, y, z] = ndgrid (1:size(a,1), 1:size(a,2), 1:size(a,3));
% x is like f(a, 1)
% y is like f(a, 2)
% z is like f(a, 3)
You may be able to write a custom wrapper around ndgrid() to convert it to the function format you are looking for.
In case anyone's curious, since I didn't know about ndgrid, here's the answer I came up with:
function [y] = indices(a,k)
s = size(a);
n = s(k);
D = length(s);
x = permute(a,[k,1:(k-1),(k+1):D]);
y = reshape(x,n,[]);
y = diag(1:n) * ones(size(y));
y = reshape(y,size(x));
y = permute(y,[(2:k),1,(k+1):D]);
endfunction
function [y] = spindices(a,k)
s = size(a);
n = s(k);
D = length(s);
x = permute(a,[k,1:(k-1),(k+1):D]);
y = reshape(x,n,[]);
y = spdiag(1:n) * spones(y);
y = reshape(y,size(x));
y = permute(y,[(2:k),1,(k+1):D]);
endfunction