How to create vector of binary values based on correspondence between two other vectors in MATLAB [duplicate] - matlab

I'm developing a program with MatLab that calculates powers of numbers, adds them together, and then sees if any of the first set of numbers (numbers to powers) equals any of the added numbers to powers. I'm trying to check this for each value in the first array, however, I am getting an output like this:
m =
1
128
2187
16384
78125
279936
823543
2097152
4782969
10000000
for each m value, which is just the result of a simple for loop of the array. So when I go to check if m is in the array, it checks is [1, 128,2187,16384,78125...] in the array, and the answer is no. How can I get it to evaluate each individual entry, like this:
Array n is [1,128,2187,16384]
for m = n
m = 1
Is m in array? No
m = 128
Is m in array? No
m = 2187
Is m in array? Yes
m = 16384
Is m in array? No
end
My code is below:
C = [];
D = [];
E = [];
F = [];
numbers1 = [];
numbers2 = [];
numbers = 10;
powers = 10;
for i = 1:numbers
for j = 3:powers
C = [C;i^j];
end
C = transpose(C);
D = [D;C];
C = [];
end
[~,b] = unique(D(:,1)); % indices to unique values in first column of D
D(b,:); % values at these rows
for i = D
for a = D
E = [E;i+a];
end
E = transpose(E);
F = [F;E];
E = [];
end
[~,b] = unique(F(:,1)); % indices to unique values in first column of F
F(b,:); % values at these rows
for m = D % this is the for loop mentioned above
m
end

Example vectors:
>> m = [1 3 5 9];
n = [5 2 1 4 8];
To check if each element of vector m is in n, use ismember:
>>ismember(m,n)
ans =
1 0 1 0
To get the values, not the indices: use logical indexing on m:
>> m(ismember(m,n))
ans =
1 5
or directly use intersect:
>> intersect(m,n)
ans =
1 5

Related

How to Compute f(x) for a=1 and various values of the parameter b on the interval 0<x<3

I tried using below codes with no luck
f = 0;
a = 1;
b = [1 2 3.5];
for x = 0:3
f = (a * b * x).^(b-1)*exp(-a*x.^b);
end
disp (f);
Assuming the domain is x and the comparison parameter is b we can loop through the values of b to create three distinct vectors for which the function, f is plotted for. Here the value of b is swapped on each iteration of the for-loop. The resultant end up being f with 3 rows by 4 columns where the columns correspond to the x-values/domain and the rows correspond to the value of parameter, b.
x = (0:3);
a = 1;
B = [1 2 3.5];
for Parameter_Index = 1: length(B)
b = B(Parameter_Index);
f(Parameter_Index,:) = (a.*b.*x).^(b-1).*exp(-a.*x.^b);
end
plot(x,f(1,:),x,f(2,:),x,f(3,:));
xlabel("x"); ylabel("f(x)");
legend("B = " + num2str(B(1)),"B = " + num2str(B(2)),"B = " + num2str(B(3)));
Ran using MATLAB R2019b

Create a matrix with alternate rows from two matrices [MATLAB]

I have the following question:
Write a program that:
Starts by requesting an A matrix by keyboard.
Next, if the number of columns of A is odd, the last column of additional zeros must be added. From this moment matrix, A has an even number (n) of columns.
The program will divide the input matrix into two sub-matrices.
The first sub-matrix (A1) contains the first n / 2 columns of A. The second sub-matrix (A2) has the last n / 2 columns.
Finally, the program must calculate and write on the screen a matrix B that has the rows of A1 in the odd rows and those of A2 in the pairs.
Example code
A = input('Enter a matrix:')
% A = magic(5) % for example
[filA, colA] = size(A);
if rem(colA,2)==1
A = [A, zeros(filA,1)]
colA = colA + 1;
end
A1 = A(:, [1:colA/2])
A2 = A(:, [1+(colA/2):colA])
%B
Here is the solution I propose you:
A = [1 2 3; 1 2 3; 1 2 3; 1 2 3];
[A_r,A_c] = size(A);
if (mod(A_c,2) ~= 0)
A = [A zeros(A_r,1)];
A_c = A_c + 1;
end
off = A_c / 2;
A1 = A(:,1:off);
A2 = A(:,(off+1):A_c);
B = reshape([A1(:) A2(:)].',2*A_r,[])
It makes use of the reshape function for interleaving the rows of the matrices A1 and A2. By omitting the ; at the end of the last line, you let Matlab print the output of the final computation in the console, which is:
B =
1 2
3 0
1 2
3 0
1 2
3 0
1 2
3 0
Using a step by step debugging approach, you can see how every step is being performed.
My solution
clear all, clc;
A = input('Ingrese una matriz:')
[filA, colA] = size(A);
if rem(colA,2)==1
A = [A, zeros(filA,1)]
colA = colA + 1;
end
A1 = A(:, [1:colA/2])
A2 = A(:, [1+(colA/2):colA])
B = A2([1;1]*(1:size(A2,1)),:)
B(1:2:end,:) = A1

Performance of using a matrix as vector index

In my code I have a slow part of which the idea can be summarized in the following short example:
A = randi(10,5); %Random 5×5 matrix containing integers ranging from 0 to 10
B = rand(10,1); %Random 10×1 vector containing values ranging from 0 to 1
C = B(A); %New 5×5 matrix consisting of elements from B, indexed using A
In my case, the matrix A is sized 1000×1000, B is a 500×1 vector and C is also 1000×1000. Given that this 3rd line is in a for loop, where A is constant and B is updated every iteration, how can I further improve speed performance? According to the profile viewer 75% of code execution is at this single line. As expected, using a for loop for this operation is much slower (10x for a 1000×1000 matrix):
AA = A(:); %Convert matrix to vector
for k=1:length(AA) %Loop through this vector and use it as index
D(k) = B(AA(k));
end
E = reshape(D,5,5); %Reshape vector to matrix of 5x5
Any ideas to optimize this?
Edit: Script used to measure performance:
N = 1500;
A = randi(500,N);
AA = A(:);
D = zeros(N,N);
B = rand(500,1);
f1 = #() VectorIndex(A,B);
timeit(f1,1)
f2 = #() LoopIndex(AA,B,N);
timeit(f2,1)
function C = VectorIndex(A,B)
C = B(A);
end
function D = LoopIndex(AA,B,N)
D = zeros(N,N);
for k=1:length(AA)
D(k) = B(AA(k));
end
D = reshape(D,N,N);
end

Placing values(numbers) in a multilayers cell matrix in MATLAB

Assume Q is a matrix which has 3 cells and in each cell it has 2 other cells, means:
Q={ { [] [] } ; { [] [] }; { [] [] } }
Moreover, if we have "a" and "b" which they have 3 member each, and we would like to place
"a(1,1)" into "Q{1}{1}",
"b(1,1)" into "Q{1}{2}",
"a(2,1)" into "Q{2}{1}",
"b(2,1)" into "Q{2}{2}",
"a(3,1)" into "Q{3}{1}",
"b(3,1)" into "Q{3}{2}",
For example, if
a = [2; 3; 4];
b = [1; 5; 8]
Then Q should be like
Q={{2 1};
{3 5};
{4 8}}
Please note that we need a vectorized code and not a for-loop code as I already have the latter one, as shown next -
for i=1:size(Q,2)
Q{i}{1}=a(i,:)
Q{i}{2}=b(i,:)
end
Thanks.
Code
Q = mat2cell(num2cell([a b]),ones(1,numel(a)),2)
Example
Code with input and output display
a = [2; 3; 4]; %// Inputs
b = [1; 5; 8];
Q = mat2cell(num2cell([a b]),ones(1,numel(a)),2); %// Output
celldisp(Q) %// Display results
Output on code run
Q{1}{1} =
2
Q{1}{2} =
1
Q{2}{1} =
3
Q{2}{2} =
5
Q{3}{1} =
4
Q{3}{2} =
8
Benchmarking
Function for loop method
function out = loop1(a,b)
out = cell(size(a,1),1);
for i=1:size(out,1)
out{i}{1}=a(i,:);
out{i}{2}=b(i,:);
end
return;
Function for vectorized method
function out = vec1(a,b)
out = mat2cell(num2cell([a b]),ones(1,numel(a)),2);
return;
Benchmarking Code
N_arr = [50 100 200 500 1000 2000 5000 10000 50000]; %// array elements for N
timeall = zeros(2,numel(N_arr));
for k1 = 1:numel(N_arr)
N = N_arr(k1);
a = randi(9,N,1);
b = randi(9,N,1);
f = #() loop1(a,b);
timeall(1,k1) = timeit(f);
clear f
f = #() vec1(a,b);
timeall(2,k1) = timeit(f);
clear f
end
%// Graphical display of benchmark results
figure,
hold on
plot(N_arr,timeall(1,:),'-ro')
plot(N_arr,timeall(2,:),'-kx')
legend('Loop Method','Vectorized Method')
xlabel('Datasize (N) ->'),ylabel('Time(sec) ->')
Results
Conclusions
Looks like vectorized method is the way to go, as it's showing almost double the performance (in terms of runtime) as compared to the loop approach across a wide range of datasizes.

How to vectorize double loop in Matlab?

y = 0;
for m = 0:variable
for n = 0:m
y = y + f(n,m);
end
end
I vectorized the inner loop this way,
y = 0;
for m = 0:variable
n = 0:m
y = y + f(n,m);
end
This resulted in around 60% speed increase for my code. How do I also vectorize the outer loop?
You are probably looking for the meshgrid function. It is designed to fill in the sort of m by n combinations that it looks like you need. For example:
>> m = 1:4;
>> n = 1:3;
>> [mGridValues, nGridValues] = meshgrid(m,n)
mGridValues =
1 2 3 4
1 2 3 4
1 2 3 4
nGridValues =
1 1 1 1
2 2 2 2
3 3 3 3
This is a little more complicated since your inner loop depends on the value of your outer loop. So you will need to mask out the undesired [n, m] pairs (see below).
Modifying the prototype code that you have provided, you would end up with something like this:
[mValues, nValues] = meshgrid(0:variable, 0:variable); %Start with a full combination of values
mask = mValues >= nValues; %Identify all values where m >= n
mValues = mValues(mask); % And then remove pairs which do not
nValues = nValues(mask); % meet this criteria
y = f(nValues, mValues ); %Perform whatever work you are performing here