Input space separated matrix in matlab of dim (m X n) - matlab

I am just a beginner using MatLab. I wanted to add 2 matrices in which user inputs dimension of matrix and then inputs values.
Values are inserted element by element.
I want user to input values row-wise, i.e., for a 2x3 matrix, user should input 2 lines, each line with 3 space separated integer values.
m = input('Enter no. of rows ');
n = input('Enter no. of columns ');
A = zeros(m, n);
B = zeros(m, n);
C = zeros(m, n);
disp('Enter elements in matrix A ');
for i=1 : m
for j=1 : n
A(i,j) = input('\');
end
end
disp('Enter elements in matrix B ');
for i = 1 : m
for j = 1 : n
B(i, j) = input('\');
C(i, j) = A(i, j) + B(i, j);
end
end
clc;
disp('Matrix A is');
A
disp('Matrix B is');
B
disp('Matrix A + B is');
C
How shall i do that?

You could do it using:
for j=1 : n
A(:,j) = input('\');
end
Then the user has to enter a row like [1,2,3,4]
My recommendation is to ask for the full matrix at once. This way the user can enter a variable name which contains the intended function.

Related

Reshape error on Matlab I can't figure out?

Trying to add a row and column of zeroes to a user inputted matrices, can't fin any way past the reshape error
n = input ('Please Enter Desired Number of Rows:');
disp (''); % User prompted to enter the desied rows for the matrices.
m = input ('Please Enter Desired Number of Columns:');
disp (''); % User prompted to enter the desired columns for the matrices.
for x = 1:n
for y = 1:m
p (x,y) = input ('Enter Matrice Values:');
end
end
p = reshape (p, n, m);
% Adding Row of Zeros
a = zeros (1,m+1)
% Adding Column of Zeros
b= zeros (n,1)
Output_Matrix = [p b; a]
You don't need to reshape, get the size of p that was input by the user using [m, n] = size(p) and create Output_Matrix that's one row and one column bigger. Set the first m rows and n columns to p. Finally don't forget to preallocate any arrays before accessing them.
% User prompted to enter the desied rows for the matrices.
m = input('Please Enter Desired Number of Rows: '); disp ('')
% User prompted to enter the desired columns for the matrices.
n = input('Please Enter Desired Number of Columns: '); disp ('')
p = zeros(m,n);
for x = 1:m
for y = 1:n
p(x,y) = input('Enter Matrice Values: ');
end
end
[m, n] = size(p);
Output_Matrix = zeros(m+1,n+1);
Output_Matrix(1:end-1,1:end-1) = p;
Output_Matrix =
1 2 3 0
4 5 6 0
7 8 9 0
0 0 0 0
If you have a p matrix from some previous code and you want to expand it, you can simply do this to get that extra row and column of 0's appended:
% p is pre-existing from some other code
p(end+1,end+1) = 0; % this appends extra row and column of 0's
But if you are building the p from scratch and know the desired size ahead of time, then Chris's comment about pre-allocating p to zeros(m+1,n+1) is probably the way to go.

Can I vectorize this matrix task in MATLAB?

I have a square matrix A which I would like to manipulate using a matrix D. The result will be the matrix B. The entry B(i, j) will be a sum of a number of elements from A(:, j), as determined by D.
Let me show what I have in codes -
A = magic(3); % initial matrix
D = [1, 2, 3; 2, 2, 3; 1, 3, 1]; % map matrix
B = zeros(3); % resultant matrix
for i = 1:3
for j = 1:3
B(D(i, j), j) = B(D(i, j), j) + A(i, j);
end
end
Now, to explain we have D as :
D = [1, 2, 3;
2, 2, 3;
1, 3, 1];
These D values basically act as the row indices to accumulate into output array B, while column indices would be iterating numbers themselves -
col = [1 2 3;
1 2 3;
1 2 3];
Thus, the summations are :
B(1,1) += A(1,1) % Indices from first row from D to select B
B(2,2) += A(1,2)
B(3,3) += A(1,3)
B(2,1) += A(2,1) % Indices from second row from D to select B
B(2,2) += A(2,2)
B(3,3) += A(2,3)
B(1,1) += A(3,1) % Indices from third row from D to select B
B(3,2) += A(3,2)
B(1,3) += A(3,3)
Thus, at B(1,1) we would accumulate two values from A : A(1,1) and A(3,1) and so on.
When the matrices are large, this process takes a long time. Is there a way to vectorize this computation?
Here's one approach using accumarray and bsxfun -
[m,n] = size(A);
% Generate all linear indices corresponding to D
idx = bsxfun(#plus,D,m*(0:n-1))
% Use accumarray to accumulate values for each of those indices.
% We need some reshaping to get a final 2D output after feeding in column
% vectors for using accumarray
Bout = reshape(accumarray(idx(:),A(:),[m*n,1]),[m,n])
Sample run -
>> % Setup inputs and run loopy version
A = randi(9,4,6);
D = randi(size(A,1),4,6);
B = zeros(size(A));
for i = 1:size(A,1)
for j = 1:size(A,2)
B(D(i, j), j) = B(D(i, j), j) + A(i, j);
end
end
% Proposed vectorized method
>> [m,n] = size(A);
>> idx = bsxfun(#plus,D,m*(0:n-1));
>> Bout = reshape(accumarray(idx(:),A(:),[m*n,1]),[m,n]);
% Verify results
>> max(abs(Bout(:)-B(:)))
ans =
0

How to request multiple inputs, n number of times

For the code below, I want to take the input values b and k, n times:
syms Q i w h2 h1 k
% n is number of layers for computation
n = input (' ')
for j = 1:n
k1 = input (' '); b1 = input (' ');
% up to...
k(n) = input (' '); b(n) = input (' ');
% so that i want to use the various inputs of b and k to calculate Q.
Qi=( -b(i) * k(i) )*((h2-h1)/w)
Q=symsum(Qi, i, 1, 3)
Within your loop, you can prompt for the input and store it into an array of k and b values
% Pre-allocate k and b arrays
k = zeros(1, n);
b = zeros(1, n);
for ind = 1:n
% Prompt for the next k value
k(ind) = input('');
% Prompt for the next b value
b(ind) = input('');
end
Alternately, you could prompt the user for an array directly
k = input('Please enter an array for k in the form [k1, k2, k3]');
b = input('Please enter an array for b in the form [b1, b2, b3]');
Using these arrays you could compute Q for each value of k and b
Q = (-b .* k)*((h2-h1)/w);

Matlab: How to read data into a matrix

I have a data file matrix.txt, it has three columns. The first column stores the row index, the second column stores the column index, the third column stores the value. How do I read these into a matrix called mat. To be explicit, suppose our mat is a n*n square matrix, let n=2 for instance. In the text file, it has:
0 0 10
1 1 -10
The element in mat not specified is 0. Thus mat is supposed to be:
mat = 10 0
0 -10
How do I achieve this?
This should work for the generic 2-D case.
% Read in matrix specification
fID = fopen('matrix.txt');
tmp = fscanf(fID, '%u%u%f', [3 inf])';
fclose(fID);
% Use the maximum row and column subscripts to obtain the matrix size
tmp(:, 1:2) = tmp(:, 1:2) + 1; % MATLAB doesn't use 0-based indexing
matsize = [max(tmp(:,1)), max(tmp(:,2))];
% Convert subscripts to linear indices
lidx = sub2ind(matsize, tmp(:,1), tmp(:,2));
mat = zeros(matsize); % Initialize matrix
mat(lidx) = tmp(:,3); % Assign data
Using a sample matrix.txt:
0 0 10
1 1 -10
1 2 20
We receive:
>> mat
mat =
10 0 0
0 -10 20
Since in MATLAB, indices begin with 1 (not zero), we should add 1 to our indices in code.
r and c stand for row and column.
Alsom and n is for m by n zero matrix
A = importdata('matrix.txt');
r = A(:, 1)';
c = A(:, 2)';
m = max(r);
n = max(c);
B = zeros(m + 1, n + 1);
for k = 1:size(A,1);
B(r(k) + 1, c(k) + 1) = A(k, 3);
end
Result:
B =
10 0
0 -10
I see I am too slow, but I decided post my answer anyway...
I initialized matrix A as a vector, and used reshape:
%Load all file to matrix at once
%You may consider using fopen and fscanf, in case Matrix.txt is not ordered perfectly.
row_column_val = load('Matrix.txt', '-ascii');
R = row_column_val(:, 1) + 1; %Get vector of row indexes (add 1 - convert to Matalb indeces).
C = row_column_val(:, 2) + 1; %Get vector of column indexes (add 1 - convert to Matalb indeces).
V = row_column_val(:, 3); %Get vector of values.
nrows = max(R); %Number of rows in matrix.
ncols = max(C); %Number of columns in matrix.
A = zeros(nrows*ncols, 1); %Initialize A as a vector instead of a matrix (length of A is nrows*ncols).
%Put value v in place c*ncols + r for all elements of V, C and R.
%The formula is used for column major matrix (Matlab stored matrices in column major format).
A((C-1)*nrows + R) = V;
A = reshape(A, [nrows, ncols]);

Discrete probability distribution calculation in Matlab

I have given P(x1...n) discrete independent probability values which represent for example the possibility of happening X.
I want a universal code for the question: With which probability does happening X occur at the same time 0-n times?
For example:
Given: 3 probabilities P(A),P(B),P(C) that each car(A,B,C) parks. Question would be: With which probability would no car, one car, two cars, and three cars park?
The answer for example for two cars parking at the same time would be:
P(A,B,~C) = P(A)*P(B)*(1-P(C))
P(A,~B,C) = P(A)*(1-P(B))*P(C)
P(~A,B,C) = (1-P(A))*P(B)*P(C)
P(2 of 3) = P(A,B,~C) + P(A,~B,C) + P(~A,B,C)
I have written the code for all possibilities, but the more values I get, of course the slower it gets due to more possible combinations.
% probability: Vector with probabilities P1, P2, ... PN
% result: Vector with results as stated above.
% All possibilities:
result(1) = prod(probability);
shift_vector = zeros(anzahl_werte,1);
for i = 1:anzahl_werte
% Shift Vector allocallization
shift_vector(i) = 1;
% Compute all unique permutations of the shift_vector
mult_vectors = uperm(shift_vector);
% Init Result Vector
prob_vector = zeros(length(mult_vectors(:,1)), 1);
% Calc Single Probabilities
for k = 1:length(mult_vectors(:,1))
prob_vector(k) = prod(abs(mult_vectors(k,:)'-probability));
end
% Sum of this Vector for one probability.
result(i+1) = sum(prob_vector);
end
end
%%%%% Calculate Permutations
function p = uperm(a)
[u, ~, J] = unique(a);
p = u(up(J, length(a)));
end % uperm
function p = up(J, n)
ktab = histc(J,1:max(J));
l = n;
p = zeros(1, n);
s = 1;
for i=1:length(ktab)
k = ktab(i);
c = nchoosek(1:l, k);
m = size(c,1);
[t, ~] = find(~p.');
t = reshape(t, [], s);
c = t(c,:)';
s = s*m;
r = repmat((1:s)',[1 k]);
q = accumarray([r(:) c(:)], i, [s n]);
p = repmat(p, [m 1]) + q;
l = l - k;
end
end
%%%%% Calculate Permutations End
Does anybody know a way to speed up this function? Or maybe Matlab has an implemented function for that?
I found the name of the calculation:
Poisson binomial distribution
How about this?
probability = [.3 .2 .4 .7];
n = numel(probability);
combs = dec2bin(0:2^n-1).'-'0'; %'// each column is a combination of n values,
%// where each value is either 0 or 1. A 1 value will represent an event
%// that happens; a 0 value will represent an event that doesn't happen.
result = NaN(1,n+1); %// preallocate
for k = 0:n; %// number of events that happen
ind = sum(combs,1)==k; %// combinations with exactly k 1's
result(k+1) = sum(prod(...
bsxfun(#times, probability(:), combs(:,ind)) + ... %// events that happen
bsxfun(#times, 1-probability(:), ~combs(:,ind)) )); %// don't happen
end