I want to merge the two data into one. But as they are in two different times that's why I cannot just combine them.
I need to add them by keeping the time as it is.
How can I do this?
data_1_y_axes=[0,1,3,5,4,6,8,9,7]
time_1_x_axes=[.02,0.03,.05,.06,.07,0.08,0.09,.1,.2]
data_2_y_axes=[0,2,4,5,2,7,5,7,5]
time_2_x_axes=[.002,0.004,.006,.009,.02,0.04,0.06,.07,.09]
plot(time_1_x_axes,data_1_y_axes)
hold on
plot(time_2_x_axes,data_2_y_axes)
My expected data will be as follows:
New_data=[ 0, 2,4,5,2+0,1,7,3,5+5,7+4,6,5+8,9,7]
New_time=[.002,.004,.006,.009,.02,.03,.04,.05,.06,.07,.08,.09,.1,.2]
How can I do this?
Here is another way to do it without using a for loop. This will run much faster:
data_1_y_axes=[0,1,3,5,4,6,8,9,7]
time_1_x_axes=[.02,0.03,.05,.06,.07,0.08,0.09,.1,.2]
data_2_y_axes=[0,2,4,5,2,7,5,7,5]
time_2_x_axes=[.002,0.004,.006,.009,.02,0.04,0.06,.07,.09]
[time_merged,i1,i2] = intersect(time_1_x_axes, time_2_x_axes)
data_merged = data_1_y_axes(i1) + data_2_y_axes(i2)
[time1_remaining, ir1] = setdiff(time_1_x_axes, time_merged)
[time2_remaining, ir2] = setdiff(time_2_x_axes, time_merged)
[time_merged, idx] = sort([time_merged time_1_x_axes(ir1) time_2_x_axes(ir2)])
data_merged = [data_merged data_1_y_axes(ir1) data_2_y_axes(ir2)]
data_merged = data_merged(idx)
plot(time_merged,data_merged)
You could combine the x and y axis arrays, then aggregate by x-axis values using
unique to get unique x values and their indices within the y values) and
accumarray to add up all of the y values with a common x axis index
Using your example data, this would look like:
y1 =[0,1,3,5,4,6,8,9,7];
x1 =[.02,0.03,.05,.06,.07,0.08,0.09,.1,.2];
y2 =[0,2,4,5,2,7,5,7,5];
x2 =[.002,0.004,.006,.009,.02,0.04,0.06,.07,.09];
x = [x1, x2]; % Combine x axis data
y = [y1, y2]; % Combine y axis data
[x, ~, idx] = unique( x(:) ); % Get unique x, and their indices
y = accumarray( idx, y ); % Add up y values according to x value index
Aggregating Sample Values With Different Sampling Times
The following approach combines the data into a single vectors, Time_Vector and Data_Vector. Then the unique() function is used to find the unique sample times that exist within Time_Vector. A for-loop is used to evaluate the indices where the same sample time exists by using the find() function. After finding these indices the corresponding values are obtained by using matrix indexing (finds all the values that occur at a given sample time). The aggregate is then taken of this array by using the sum() function.
data_1_y_axes = [0,1,3,5,4,6,8,9,7];
time_1_x_axes = [0.02,0.03,0.05,0.06,0.07,0.08,0.09,0.1,0.2];
data_2_y_axes = [0,2,4,5,2,7,5,7,5];
time_2_x_axes = [0.002,0.004,0.006,0.009,0.02,0.04,0.06,0.07,0.09];
Data_Vector = [data_1_y_axes data_2_y_axes];
Time_Vector = [time_1_x_axes time_2_x_axes];
Unique_Times = unique(Time_Vector);
for Sample_Index = 1: length(Unique_Times)
Time_Value = Unique_Times(Sample_Index);
Indices_With_Matching_Time = find(Time_Vector == Time_Value);
Output_Data(Sample_Index) = sum(Data_Vector(Indices_With_Matching_Time));
end
plot(Unique_Times,Output_Data);
Ran using MATLAB R2019b
Given a vector X of discrete positive integers with size 160*1, and a table Tb1 in size 40*200, that contains a list of indices to be deleted from X Each column from the 200 columns in Tb1 points to 40 elements to be deleted from original X.
I create a new matrix of the remaining 120*200 elements by using a for loop with 200 iterations, that at round i deletes 40 elements from a copy of the original X according to the indices listed in Tb1(:,i), but it takes too much time and memory.
How can I get the result without using loops and with a minimum number of operations?
Here are different methods:
Method1:
idx = ~hist(tbl, 1:160);
[f,~]=find(idx);
result1 = reshape(M(f),120,200);
Method2:
idx = ~hist(tbl, 1:160);
M2=repmat(M,200,1);
result2 = reshape(M2(idx),120,200);
Method 3 & 4:
% idx can be generated using accumarray
idx = ~accumarray([tbl(:) reshape(repmat(1:200,40,1),[],1)],true,[160,200],#any);
%... use method 1 and 2
Method5:
M5=repmat(M,200,1);
M5(bsxfun(#plus,tbl,0:160:160*199))=[];
result5 = reshape(M5,120,200);
Assuming that M is an array of integers and tbl is the table of indices.
It can be tested with the following data:
M = rand(160,1);
[~,tbl] = sort(rand(160,200));
tbl = tbl(1:40,:);
However it is more efficient if you generate indices of elements to be remained instead of indices of elements to be removed.
I am trying to create roandom boolean arrays in Matlab with atleast one 1 in each row.
you can use randi to generate random integers?
A = randi([0 1], 50, 10);
Generate a 50-by-10 array of integer values drawn uniformly from 0 or 1 and
you can convert matrix to dataset array by
ds = mat2dataset(A);
to convert a binary row to a number - as in the previous answers:
bin2dec(num2str(A(n,:)));
Suppose you want a random logical (boolean) matrix of size m-by-n with roughly p=0.25 entries set to true at each row but not less than one, then you can simply:
P = rand(m,n); %// generate random numbers in [0,1]
th = min( max(P,[],2), 1-p ); %// set threshold
B = bsxfun( #ge, P, th ); %// threshold the probability matrix to get random boolean entries
Note that the threshold is determined by the amount of true values you want per row, but it is also truncated to the max value of each row, ensuring that at least one element (at random) will be set to true.
Here's one way. Let
M = 5; %// number of columns
N = 4; %// number of rows
p = .5; %// initial probability of 1
You can generate the matrix with the given probability of ones, and then fill in a one at a random position in each row (possibly overwriting a zero) to make sure there's at least a one in each row:
result = rand(M,N)<p; %// generate matrix
result(bsxfun(#plus, floor(N*rand(1,M))*M, 1:M)) = 1; %// at least a one per row
This question is related to matlab: find the index of common values at the same entry from two arrays.
Suppose that I have an 1000 by 10000 matrix that contains value 0,1,and 2. Each row are treated as a sample. I want to calculate the pairwise distance between those samples according to the formula d = 1-1/(2p)sum(a/c+b/d) where a,b,c,d can treated as as the row vector of length 10000 according to some definition and p=10000. c and d are probabilities such that c+d=1.
An example of how to find the values of a,b,c,d: suppose we want to find d between sample i and bj, then I look at row i and j.
If kth entry of row i and j has value 2 and 2, then a=2,b=0,c=1,d=0 (I guess I will assign 0/0=0 in this case).
If kth entry of row i and j has value 2 and 1 or vice versa, then a=1,b=0,c=3/4,d=1/4.
The similar assignment will give to the case for 2,0(a=0,b=0,c=1/2,d=1/2),1,1(a=1,b=1,c=1/2,d=1/2),1,0(a=0,b=1,c=1/4,d=3/4),0,0(a=0,b=2,c=0,d=1).
The matlab code I have so far is using for loops for i and j, then find the cases above by using find, then create two arrays for a/c and b/d. This is extremely slow, is there a way that I can improve the efficiency?
Edit: the distance d is the formula given in this paper on page 13.
Provided those coefficients are fixed, then I think I've successfully vectorised the distance function. Figuring out the formulae was fun. I flipped things around a bit to minimise division, and since I wasn't aware of pdist until #horchler's comment, you get it wrapped in loops with the constants factored out:
% m is the data
[n p] = size(m, 1);
distance = zeros(n);
for ii=1:n
for jj=ii+1:n
a = min(m(ii,:), m(jj,:));
b = 2 - max(m(ii,:), m(jj,:));
c = 4 ./ (m(ii,:) + m(jj,:));
c(c == Inf) = 0;
d = 1 - c;
distance(ii,jj) = sum(a.*c + b.*d);
% distance(jj,ii) = distance(ii,jj); % optional for the full matrix
end
end
distance = 1 - (1 / (2 * p)) * distance;