matlab, user inputs a matrix into variable - matlab

I have this code for matlab to multiply matrixes how di i make the user add the matrixes and then use the matrixes in the code?
eg [n,m] = input(user inputs matrix here)
[n,m] = size(A);
[p,q] = size(B);
C = zeros(n,p);
if p~=m
error('Inner Matrix Dimensions Must Agree.')
end
for k = 1:n
for j = 1:q
temp=0;
for i = 1:p
temp = temp+(A(k,i)*B(i,j));
end
C(k,j) = temp;
end
end

You can use in the script:
A = input('input array A ');
B = input('input array B ');
[n,m] = size(A);
[p,q] = size(B);
C = zeros(n,p);
if p~=m
error('Inner Matrix Dimensions Must Agree.')
end
for k = 1:n
for j = 1:q
temp=0;
for i = 1:p
temp = temp+(A(k,i)*B(i,j));
end
C(k,j) = temp;
end
end
or you can write the above as a function:
function C = matrixmultiply(A,B)
[n,m] = size(A);
[p,q] = size(B);
C = zeros(n,p);
if p~=m
error('Inner Matrix Dimensions Must Agree.')
end
for k = 1:n
for j = 1:q
temp=0;
for i = 1:p
temp = temp+(A(k,i)*B(i,j));
end
C(k,j) = temp;
end
end
end

Related

How to correct grid search?

Trying to find the optimal hyperparameters for my svm model using a grid search, but it simply returns 1 for the hyperparameters.
function evaluations = inner_kfold_trainer(C,q,k,features_xy,labels)
features_xy_flds = kdivide(features_xy, k);
labels_flds = kdivide(labels, k);
evaluations = zeros(k,3);
for i = 1:k
fprintf('Fold %i of %i\n',i,k);
train_data = cell2mat(features_xy_flds(1:end ~= i));
train_labels = cell2mat(labels_flds(1:end ~= i));
test_data = cell2mat(features_xy_flds(i));
test_labels = cell2mat(labels_flds(i));
%AU1
train_labels = train_labels(:,1);
test_labels = test_labels(:,1);
[k,~] = size(test_labels);
%train
sv = fitcsvm(train_data,train_labels, 'KernelFunction','polynomial', 'PolynomialOrder',q,'BoxConstraint',C);
sv.predict(test_data);
%Calculate evaluative measures
%svm_outputs = zeros(k,1);
sv_predictions = sv.predict(test_data);
[precision,recall,F1] = evaluation(sv_predictions,test_labels);
evaluations(i,1) = precision;
evaluations(i,2) = recall;
evaluations(i,3) = F1;
end
save('eval.mat', 'evaluations');
end
an inner-fold cross validation function
and below the grid function where something seems to be going wrong
function [q,C] = grid_search(features_xy,labels,k)
% n x n grid
n = 3;
q_grid = linspace(1,19,n);
C_grid = linspace(1,59,n);
tic
evals = zeros(n,n,3);
for i = 1:n
for j = 1:n
fprintf('## i=%i, j=%i ##\n', i, j);
svm_results = inner_kfold_trainer(C_grid(i), q_grid(j),k,features_xy,labels);
evals(i,j,:) = mean(svm_results(:,:));
% precision only
%evals(i,j,:) = max(svm_results(:,1));
toc
end
end
f = evals;
% retrieving the best value of the hyper parameters, to use in the outer
% fold
[M1,I1] = max(f);
[~,I2] = max(M1(1,1,:));
index = I1(:,:,I2);
C = C_grid(index(1))
q = q_grid(index(2))
end
When I run grid_search(features_xy,labels,8) for example, I get C=1 and q=1, for any k(the no. of folds) value. Also features_xy is a 500*98 matrix.

tangent tangent correlation calculation in matrix form MATLAB

Consider the following calculation of the tangent tangent correlation which is performed in a for loop
v1=rand(25,1);
v2=rand(25,1);
n=25;
nSteps=10;
mean_theta = zeros(nSteps,1);
for j=1:nSteps
theta=[];
for i=1:(n-j)
d = dot([v1(i) v2(i)],[v1(i+j) v2(i+j)]);
n1 = norm([v1(i) v2(i)]);
n2 = norm([v1(i+j) v2(i+j)]);
theta = [theta acosd(d/n1/n2)];
end
mean_theta(j)=mean(theta);
end
plot(mean_theta)
How can matlab matrix calculations be utilized to make this performance better?
There are several things you can do to speed up your code. First, always preallocate. This converts:
theta = [];
for i = 1:(n-j)
%...
theta = [theta acosd(d/n1/n2)];
end
into:
theta = zeros(1,n-j);
for i = 1:(n-j)
%...
theta(i) = acosd(d/n1/n2);
end
Next, move the normalization out of the loops. There is no need to normalize over and over again, just normalize the input:
v = [v1,v2];
v = v./sqrt(sum(v.^2,2)); % Can use VECNORM in newest MATLAB
%...
theta(i) = acosd(dot(v(i,:),v(i+j,:)));
This does change the output very slightly, within numerical precision, because the different order of operations leads to different floating-point rounding error.
Finally, you can remove the inner loop by vectorizing that computation:
i = 1:(n-j);
theta = acosd(dot(v(i,:),v(i+j,:),2));
Timings (n=25):
Original: 0.0019 s
Preallocate: 0.0013 s
Normalize once: 0.0011 s
Vectorize: 1.4176e-04 s
Timings (n=250):
Original: 0.0185 s
Preallocate: 0.0146 s
Normalize once: 0.0118 s
Vectorize: 2.5694e-04 s
Note how the vectorized code is the only one whose timing doesn't grow linearly with n.
Timing code:
function so
n = 25;
v1 = rand(n,1);
v2 = rand(n,1);
nSteps = 10;
mean_theta1 = method1(v1,v2,nSteps);
mean_theta2 = method2(v1,v2,nSteps);
fprintf('diff method1 vs method2: %g\n',max(abs(mean_theta1(:)-mean_theta2(:))));
mean_theta3 = method3(v1,v2,nSteps);
fprintf('diff method1 vs method3: %g\n',max(abs(mean_theta1(:)-mean_theta3(:))));
mean_theta4 = method4(v1,v2,nSteps);
fprintf('diff method1 vs method4: %g\n',max(abs(mean_theta1(:)-mean_theta4(:))));
timeit(#()method1(v1,v2,nSteps))
timeit(#()method2(v1,v2,nSteps))
timeit(#()method3(v1,v2,nSteps))
timeit(#()method4(v1,v2,nSteps))
function mean_theta = method1(v1,v2,nSteps)
n = numel(v1);
mean_theta = zeros(nSteps,1);
for j = 1:nSteps
theta=[];
for i=1:(n-j)
d = dot([v1(i) v2(i)],[v1(i+j) v2(i+j)]);
n1 = norm([v1(i) v2(i)]);
n2 = norm([v1(i+j) v2(i+j)]);
theta = [theta acosd(d/n1/n2)];
end
mean_theta(j) = mean(theta);
end
function mean_theta = method2(v1,v2,nSteps)
n = numel(v1);
mean_theta = zeros(nSteps,1);
for j = 1:nSteps
theta = zeros(1,n-j);
for i = 1:(n-j)
d = dot([v1(i) v2(i)],[v1(i+j) v2(i+j)]);
n1 = norm([v1(i) v2(i)]);
n2 = norm([v1(i+j) v2(i+j)]);
theta(i) = acosd(d/n1/n2);
end
mean_theta(j) = mean(theta);
end
function mean_theta = method3(v1,v2,nSteps)
v = [v1,v2];
v = v./sqrt(sum(v.^2,2)); % Can use VECNORM in newest MATLAB
n = numel(v1);
mean_theta = zeros(nSteps,1);
for j = 1:nSteps
theta = zeros(1,n-j);
for i = 1:(n-j)
theta(i) = acosd(dot(v(i,:),v(i+j,:)));
end
mean_theta(j) = mean(theta);
end
function mean_theta = method4(v1,v2,nSteps)
v = [v1,v2];
v = v./sqrt(sum(v.^2,2)); % Can use VECNORM in newest MATLAB
n = numel(v1);
mean_theta = zeros(nSteps,1);
for j = 1:nSteps
i = 1:(n-j);
theta = acosd(dot(v(i,:),v(i+j,:),2));
mean_theta(j) = mean(theta);
end
Here is a full vectorized solution:
i = 1:n-1;
j = (1:nSteps).';
ij= min(i+j,n);
a = cat(3, v1(i).', v2(i).');
b = cat(3, v1(ij), v2(ij));
d = sum(a .* b, 3);
n1 = sum(a .^ 2, 3);
n2 = sum(b .^ 2, 3);
theta = acosd(d./sqrt(n1.*n2));
idx = (1:nSteps).' <= (n-1:-1:1);
mean_theta = sum(theta .* idx ,2) ./ sum(idx,2);
Result of Octave timings for my method,method4 from the answer provided by #CrisLuengo and the original method (n=250):
Full vectorized : 0.000864983 seconds
Method4(Vectorize) : 0.002774 seconds
Original(loop) : 0.340693 seconds

cant find my code error in LU decomposition [duplicate]

I am trying to implement my own LU decomposition with partial pivoting. My code is below and apparently is working fine, but for some matrices it gives different results when comparing with the built-in [L, U, P] = lu(A) function in matlab
Can anyone spot where is it wrong?
function [L, U, P] = lu_decomposition_pivot(A)
n = size(A,1);
Ak = A;
L = zeros(n);
U = zeros(n);
P = eye(n);
for k = 1:n-1
for i = k+1:n
[~,r] = max(abs(Ak(:,k)));
Ak([k r],:) = Ak([r k],:);
P([k r],:) = P([r k],:);
L(i,k) = Ak(i,k) / Ak(k,k);
for j = k+1:n
U(k,j-1) = Ak(k,j-1);
Ak(i,j) = Ak(i,j) - L(i,k)*Ak(k,j);
end
end
end
L(1:n+1:end) = 1;
U(:,end) = Ak(:,end);
return
Here are the two matrices I've tested with. The first one is correct, whereas the second has some elements inverted.
A = [1 2 0; 2 4 8; 3 -1 2];
A = [0.8443 0.1707 0.3111;
0.1948 0.2277 0.9234;
0.2259 0.4357 0.4302];
UPDATE
I have checked my code and corrected some bugs, but still there's something missing with the partial pivoting. In the first column the last two rows are always inverted (compared with the result of lu() in matlab)
function [L, U, P] = lu_decomposition_pivot(A)
n = size(A,1);
Ak = A;
L = eye(n);
U = zeros(n);
P = eye(n);
for k = 1:n-1
[~,r] = max(abs(Ak(k:end,k)));
r = n-(n-k+1)+r;
Ak([k r],:) = Ak([r k],:);
P([k r],:) = P([r k],:);
for i = k+1:n
L(i,k) = Ak(i,k) / Ak(k,k);
for j = 1:n
U(k,j) = Ak(k,j);
Ak(i,j) = Ak(i,j) - L(i,k)*Ak(k,j);
end
end
end
U(:,end) = Ak(:,end);
return
I forgot that If there was a swap in matrix P I had to swap also the matrix L. So just add the next line after after swapping P and everything will work excellent.
L([k r],:) = L([r k],:);
Both functions are not correct.
Here is the correct one.
function [L, U, P] = LU_pivot(A)
[m, n] = size(A); L=eye(n); P=eye(n); U=A;
for k=1:m-1
pivot=max(abs(U(k:m,k)))
for j=k:m
if(abs(U(j,k))==pivot)
ind=j
break;
end
end
U([k,ind],k:m)=U([ind,k],k:m)
L([k,ind],1:k-1)=L([ind,k],1:k-1)
P([k,ind],:)=P([ind,k],:)
for j=k+1:m
L(j,k)=U(j,k)/U(k,k)
U(j,k:m)=U(j,k:m)-L(j,k)*U(k,k:m)
end
pause;
end
end
My answer is here:
function [L, U, P] = LU_pivot(A)
[n, n1] = size(A); L=eye(n); P=eye(n); U=A;
for j = 1:n
[pivot m] = max(abs(U(j:n, j)));
m = m+j-1;
if m ~= j
U([m,j],:) = U([j,m], :); % interchange rows m and j in U
P([m,j],:) = P([j,m], :); % interchange rows m and j in P
if j >= 2; % very_important_point
L([m,j],1:j-1) = L([j,m], 1:j-1); % interchange rows m and j in columns 1:j-1 of L
end;
end
for i = j+1:n
L(i, j) = U(i, j) / U(j, j);
U(i, :) = U(i, :) - L(i, j)*U(j, :);
end
end

How can I easily create this matrix?

How can I easily create the following matrix in MATLAB?
With A (nxn), B (nxp) and N a positive integer.
Gamma = [B 0 0 ... 0 ;
A*B B 0 ... 0 ;
A^2*B A*B B ... 0 ;
... ... ... ... ... ;
A^(N-1)*B A^(N-2)*B A^(N-3)*B ... B];
How about
[g{1:N,1:N}] = deal( zeros(n,p) );
g{1,1} = B;
for ii = 2:N
g( ii, 2:end ) = g( ii-1, 1:end-1 );
g{ ii, 1 } = A * g{ ii-1, 1 };
end
Gamma = cell2mat( g );
This works, though it is less efficient than it could be.
n = size(A,1);
p = size(B,2);
N = 3;
Gamma = zeros(N*n, N*p);
for ii = 1:N
for jj = 1:N
if ii >= jj
Gamma((ii-1)*n+1:ii*n,(jj-1)*p+1:jj*p) = A^(ii-jj) * B;
end
end
end
Edit: Here's a more efficient version, that does the minimum amount of matrix multiplication.
n = size(A,1);
p = size(A,2);
N = 3;
Gamma = zeros(N*n, N*p);
# Pre-compute all the matrix multiplications we'll need.
memo = cell(1, N);
memo{1} = B;
for ii = 1:N-1
memo{ii+1} = A * memo{ii};
end
for ii = 1:N
for jj = 1:N
if ii >= jj
Gamma((ii-1)*n+1:ii*n,(jj-1)*p+1:jj*p) = memo{ii-jj+1};
end
end
end

Local thresholding in MATLAB

I am trying to implement local thresholding in MATLAB 7.7. This is what my original image looks like:
As seen the the word Test is covered in black. This image is a PNG image having dimensions 919x551. I want to apply local thresholding to this image so that I can get the word Test to be visible clearly.
I have implemented the following code that works by dividing the entire image into sub images of 60*60 blocks.
However, when I am doing so, I am not getting the desired output.
My code:
clc;
clear all;
close all;
im = imread('C:\samples\test100.png');
subplot(3,3,1);
imshow(im);
title('original image');
im = rgb2gray(im);
im = double(im);
subplot(3,3,2);
imshow(im);
title('gray scale image');
[row col] = size(im);
max_im = max(max(im));
h = zeros(1,max_im+1);
!1st block
for n = 1:1:60
for m = 1:1:60
a(n,m) = im(n,m);
end
end
a = a+1;
for n = 1:1:60
for m = 1:1:60
t = a(n,m);
h(t) = h(t)+1;
end
end
subplot(3,3,3);
bar(h)
[X,Y] = ginput(1);
for n = 1:1:60
for m = 1:1:60
if a(n,m)<X
a(n,m) = 0;
else
a(n,m) = 255;
end
end
end
subplot(3,3,4);
imshow(uint8(a))
title('1st block image');
!2nd block
for n = 1:1:60
for m = 61:1:60
b(n,m-60) = im(n,m)
end
end
b = b+1;
for n = 1:1:60
for m = 1:1:60
t = b(n,m);
h(t) = h(t)+1;
end
end
figure(2)
bar(h)
[X,Y] = ginput(1);
for n = 1:1:60
if b(n,m)<X
b(n,m) = 0;
else
b(n,m) = 255;
end
end
imshow(uint8(b))
!3rd block
for n = 61:1:120
for m = 1:1:60
c(n-60,m) = im(n,m);
end
end
c = c+1;
for n = 1:1:60
for m = 1:1:60
t = c(n,m);
h(t) = h(t)+1;
end
end
figure(3)
bar(h)
[X,Y] = ginput(1);
for n = 1:1:60
for m = 1:1:60
if c(n,m)< X
c(n,m) = 0;
else
c(n,m) = 255;
end
end
end
imshow(uint8(c))
!final block
for n = 1:1:row
for m = 61:1:col
d(n-60,m-60) = im(n,m);
end
end
d = d+1;
for n = 1:1:60
for m = 1:1:60
t = d(n,m);
h(t) = h(t)+1;
end
end
figure(4);
bar(h);
[X,Y] = ginput(1);
for n = 1:1:60
for m = 1:1:60
if d(n,m)<X
d(n,m) = 0;
else
d(n,m) = 255;
end
end
end
imshow(uint8(d))
s = [a b;c d];
figure(5);
imshow(uint(s))
When I try to run the entire code I get an error as:
??? Undefined function or method 'local' for input arguments of type 'char'
However, when I run only the code for the 1st block I get the following output.
How will I get the word Test visible by creating sub-images and then merging them together?
You can scan the greyscale image horizontally and then find the position of non-zero (or above the threshold) values and set that interval to be filled with white (256 or 1 if using im2double).
for j=1:551
row = im(:,j)
test = 0;
im2=zeros(size(im))
i=0;
%Left black area
while (test == 0 && i<919)
im2(i,j)=0;
if row(i)>threshold
test=1;
end;
i=i+1;
end;
%White inner area
while (test == 1 && i<919)
im2(i,j)=1
if row(i)>threshold
test=0;
end;
i=i+1;
end;
%Left black area
while (i<919)
im2(i,j)=0;
i=i+1;
end;
This doesn't work with letters that have an empty area (such as 'p'), but you can modify the code a little to do that.