I've X axis with values [2,6,10] and for Y axis [0.5,0.4,0.2,0.2,....0.5], all values between 0 and 1.
There are certain points which correspond to 2, let's say 1/3rd and the remaining 1/3rd for 6 and remaining 1/3rd for 10. The points corresponding to 2 can have any values between 0 and 1, same applies for point 6 and point 10.
How can I plot this?
I guess you have some way to match up each Y-value to its corresponding X-value. By generating a vector of the same length as Y with these X-values they can then be plotted against each other.
The two vectors will then have the following form:
X = [2,6,2,10,6,6,10,2,....6]
Y = [0.5,0.4,0.2,0.2,0.9,0.3....0.5]
Here is a sample code
% X-data
X = [2,6,10];
% Generate random Y-data
n1 = 10;
n2 = 20;
n3 = 30;
n = n1 + n2 + n3;
Y = rand(1,n);
% Match X indices corresponding to Y
% Xall = [2,2,2,...,2,6,6,6,...,6,10,10,10,...,10]
X1 = zeros(1,n1);
X1(:) = X(1);
X2 = zeros(1,n2);
X2(:) = X(2);
X3 = zeros(1,n3);
X3(:) = X(3);
Xall = [X1 X2 X3];
plot(Xall,Y,'o')
xlim([min(X)-2,max(X)+2])
which will generate a figure of the following form
plot(a(1:3:end))
This will plot every third point.
a=[0.5,0.4,0.2,0.2,....0.5]
b=[1:3:length(a)]
plot(a(b))
Related
how to solve this question in MATLAB?
Create an array for x from 0 to 2π with 1000 elements and graph the following equation:
y = |Sin(x^x)/2^(((x^x)-pi/2)/pi)|
I have tried but it didn't work:
x = linspace(0, 2*pi, 1000);
y = abs(sin(x.^x)/(2.^(((x.^x) - pi / 2)/ pi)));
plot(x,y)
I'm currently forming a matrix from a vector in MATLAB following the scheme described below:
Given is a vector x containing ones and zeros in an arbitrary order, e.g.
x = [0 1 1 0 1];
From this, I would like to form a matrix Y that is described as follows:
Y has m rows, where m is the number of ones in x (here: 3).
Each row of Y is filled with a one at the k-th entry, where k is the position of a one in vector x (here: k = 2,3,5)
For the example x from above, this would result in:
Y = [0 1 0 0 0;
0 0 1 0 0;
0 0 0 0 1]
This is identical to an identity matrix, that has its (x=0)th rows eliminated.
I'm currently achieving this via the following code:
x = [0,1,1,0,1]; %example from above
m = sum(x==1);
Y = zeros(m,numel(x));
p = 1;
for n = 1:numel(x)
if x(n) == 1
Y(p,n) = 1;
p = p+1;
end
end
It works but I'm kind of unhappy with it as it seems rather inefficient and inelegant. Any ideas for a smoother implementation, maybe using some matrix multiplications or so are welcome.
Here are a few one-line alternatives:
Using sparse:
Y = full(sparse(1:nnz(x), find(x), 1));
Similar but with accumarray:
Y = accumarray([(1:nnz(x)).' find(x(:))], 1);
Using eye and indexing. This assumes Y is previously undefined:
Y(:,logical(x)) = eye(nnz(x));
Use find to obtain the indices of ones in x which are also the column subscripts of ones in Y. Find the number of rows of Y by adding all the elements of the vector x. Use these to initialise Y as a zero matrix. Now find the linear indices to place 1s using sub2ind. Use these indices to change the elements of Y to 1.
cols = find(x);
noofones = sum(x);
Y = zeros(noofones, size(x,2));
Y(sub2ind(size(Y), 1:noofones, cols)) = 1;
Here's an alternative using matrix multiplications:
x = [0,1,1,0,1];
I = eye(numel(x));
% construct identity matrix with zero rows
Y = I .* x; % uses implicit expansion from 2016b or later
Y = Y(logical(x), :); % take only non-zero rows of Y
Result:
Y =
0 1 0 0 0
0 0 1 0 0
0 0 0 0 1
Thanks to #SardarUsama's comment for simplifying the code a bit.
Thanks everybody for the nice alternatives! I tried out all your solutions and averaged execution times over 1e4 executions for random (1000-entry) x-vectors. Here are the results:
(7.3e-4 sec) full(sparse(1:nnz(x), find(x), 1));
(7.5e-4 sec) cols = find(x);
noofones = sum(x);
Y = zeros(noofones, size(x,2));
Y(sub2ind(size(Y), 1:noofones, cols)) = 1;
(7.7e-4 sec) Y = accumarray([(1:nnz(x)).' find(x(:))], 1);
(1.7e-3 sec) I = speye(numel(x));
Y = I .* x;
Y = full(Y(logical(x), :));
(3.1e-3 sec) Y(:,logical(x)) = eye(nnz(x));
From your comment "This is identical to an identity matrix, that has its (x=0)th rows eliminated.", well, you can also explicitly generate it as such:
Y = eye(length(x));
Y(x==0, :) = [];
Very slow option for long x, but it works slightly faster than full(sparse(... for x with 10 elements on my computer.
Here is what i want to do:
I have 4 inputs x1, x2, x3, x4
They each have a range of possible values, f.e
x1={1,2}
x2=x3=x4={1,2,3}
These values x1, x2, x3, x4 may be known, but they can also be unknow (input=0). I want to generate a matrix with all possible combinations.
So for example:
the input (0,0,2,3) means, that x1 and x2 are unknown and x3 and x4 are known. Since x1 has 2 possibilities and x2 has 3 possibilities I need 2*3=6 combinations, where x3 and x4 are fixed:
1 1 2 3
1 2 2 3
1 3 2 3
2 1 2 3
2 2 2 3
2 3 2 3
How do i archieve that? Normally i would do a couple nested for loops, but that doenst work, since i dont know which variables are known and which one are not. On the other hand perm() doenst really help either.
You can pre-generate all of the possible combinations of values for [x1 x2 x3 x4] and store it in the variable, for example comb.
From there on:
inputs = [x1 x2 x3 x4]; % Put your inputs in a vector
fixed = ~(inputs == 0); % Logical vector for where inputs is not zero
select = ismember(combs(:,fixed),inputs(fixed),'rows') % find where the values correspond
yourMatrix = combs(select,:); % Get your results
Try this (this should be generalisable):
% This is your input
ranges = {[1, 2], [1, 2, 3], [1, 2, 3], [1, 2, 3]};
input_v = [0, 0, 2, 3];
% initialise a cell to hold vectors to be combined
combine_us = cell(size(ranges));
for ii = 1:length(input_v)
% this tests for 0. If your arrays can contain 0, use NaN instead
if input_v(ii) == 0
combine_us{ii} = ranges{ii};
else
combine_us{ii} = input_v(ii);
end
end
% calculate the numbers of combinations added with every input
n_combinations = [1 cumprod(cellfun(#numel, combine_us))];
% initialize output matrix
out_v = zeros(n_combinations(end), length(input_v));
% set the output values, cycling so that each combination will be obtained
for ii = 1:length(input_v)
for jj = 1:n_combinations(end)
out_v(jj, ii) = combine_us{ii}(mod(ceil(jj / n_combinations(ii)) - 1, length(combine_us{ii} )) + 1);
end
end
I'm assuming your inputs are numeric vectors, rather than cell arrays of numbers. If they are really cell arrays of numbers, you can convert to numeric vectors with x1 = [x1{:}]; etc.
You can proceed as follows:
Build a cell array such that each cell contains either a whole input vector or a specific value thereof, according to s. This is easily done with a for loop, or with arrayfun.
Apply one of these answers to generate all combinations.
Code:
%// Inputs
x1 = [1,2];
x2 = [1,2,3];
x3 = [1,2,3];
x4 = [1,2,3];
s = [0 0 2 3];
%// Step 1
x = {x1 x2 x3 x4};
ind = s~=0;
x(ind) = arrayfun(#(y,t) {y{1}(t)}, x(ind), s(ind));
%// Step 2
n = numel(x);
combs = cell(1,n);
[combs{end:-1:1}] = ndgrid(x{end:-1:1});
combs = cat(n+1, combs{:});
combs = reshape(combs,[],n);
I have 3 arrays in matlab that are 1xN, X Y Z respectively. I need to read these arrays into a 3xN matrix respectively so I get
x1 y1 z1
x2 y2 z2
.. .. ..
xn yn zn
I have currently got the data in a Nx 3 matrix, the wrong way round. The code I have is
X = [];
Y = [];
Z = [];
for ctr = 1:length(A)
X = [X A(ctr,1)];
Y = [Y A(ctr,2)];
Z = [Z A(ctr,3)];
end
M = [X;Y;Z];
Where A is the input data from a 624*600 double cell and M is my desired matrix.
Thanks
I guess you want that:
X = [];
Y = [];
Z = [];
for ctr = 1:length(A)
X(end+1, 1) = A(ctr,1);
Y(end+1, 1) = A(ctr,2);
Z(end+1, 1) = A(ctr,3);
end
M = [X Y Z];
Faster with 1 line code:
M = [A(:, 1) A(:, 2) A(:, 3)];
I just found that you can transpose with Mt = transpose(M); which has the overall intended result but feels like 3 rights to make a left.
I am using MATLAB.
So I have 3 arrays; say a,b,c. a and b represent distances, and c represents a variable with a specific value at the point (a,b).
I have been trying to create a matrix which comprises of (b x a) cells, and the populate it with the values of c, in order to then image, heatmap it etc.
However the issue I have having is that there are many repeating values of a and b; a stays fixed and it then iterates across all values of b, then moves onto the next value of a, and so forth. The range of a and b is fixed and always iterate across equally spaced values though.
Below is the code I have created for this. So for it seems to not to work and I am out of ideas.
z_true_len = length(unique(a)); %number of z distances
r_true_len = length(unique(b)); %number of r disatances
data_matrix = zeros(r_true_len,z_true_len); %create r x z matrix, full of 0s
z_past = 0;
r_past = 0;
z_count = 1;
r_count = 1;
for count = 1: length(a)
z_current = a(count);
if z_past ~= z_current
data_matrix(1:z_count) = c(count);
z_past = z_current;
z_count = z_count + 1;
r_count = 1;
else
data_matrix(r_count:z_count) = c(count);
r_count = r_count + 1;
end
end
data_matrix
Any help would be appriciated
I included a mapping of the a and b arrays into a space of integers:
% Data
a = [ 0.5 0.5 2.5 0.5 2.5 2.5 4.5 4.5 4.5 2.5 4.5 0.5];
b = [-35 -25 -25 -15 -45 -35 -35 -45 -15 -15 -25 -45];
c = [2 1 -2 4 6 4 6 8 4 1 -5 2];
% Mapping from real to integers
a_unique = sort(unique(a));
b_unique = sort(unique(b));
a_idx = zeros(size(a));
b_idx = zeros(size(b));
for ii = 1:numel(a_unique),
a_idx(a_unique(ii)==a) = ii;
end
for ii = 1:numel(b_unique),
b_idx(b_unique(ii)==b) = ii;
end
% Create matrix
data_matrix = zeros(numel(b_unique),numel(a_unique));
for count = 1:length(a_idx),
data_matrix(b_idx(count),a_idx(count)) = c(count);
end
% Plot
figure;
imagesc(data_matrix);
You basically need to define data_matrix with the appropriate dimensions, and then fill values in using linear indexing (see sub2ind):
m = max(b); %// number of rows in result
n = max(a); %// number of columns in result
data_matrix = NaN(m,n); %// define result matrix with appropriate dimensions
data_matrix(sub2ind([m n], b, a)) = c; %// fill values using indexing
If a and b don't always contain integers: first transform into "integer labels" with the third output of unique, and then proceed as above:
[~, ~, bb] = unique(b); %// get integer labels for b
[~, ~, aa] = unique(a); %// get integer labels for a
m = max(bb); %// number of rows in result
n = max(aa); %// number of columns in result
data_matrix = NaN(m,n); %// define result matrix with appropriate dimensions
data_matrix(sub2ind([m n], bb, aa)) = c; %// fill values using indexing