I have a matrix A in Matlab of dimension hxk where element ik reports an index from {1,2,...,s<=h}. The indices can be repeated across rows. I want to obtain B of dimension sx(k-1) where element j is the sum of the rows of A(:,1:k-1) with index j. For example if
A = [0.4 5 6 0.3 1;
0.6 -0.7 3 2 2;
0.3 4.5 6 8.9 1;
0.9 0.8 0.7 3 3;
0.7 0.8 0.9 0.5 2]
the result shoud be
B = [0.7 9.5 12 9.2;
1.3 0.1 3.9 2.5;
0.9 0.8 0.7 3]
You'd need a multi-column version of accumarray. Failing that, you can use sparse as follows:
[m n] = size(A);
rows = ceil(1/(n-1):1/(n-1):m);
cols = repmat(1:n-1,1,m);
B = full(sparse(A(rows,end), cols, A(:,1:end-1).'));
cell2mat(arrayfun(#(x) sum(A(A(:,end)==x,1:end-1),1), unique(A(:,end)), 'UniformOutput', false))
The key point is selecting rows A(A(:,end)==x,1:end-1) where x is a unique element of A(:,end)
Related
MATLAB software
i=[0 1.264241 1.729329 1.900426 1.963369 1.986524 1.995042 1.998176 1.999329 1.999753 1.999909];
t=[0 0.2 0.4 0.6 0.8 1 1.2 1.4 1.6 1.8 2];
How can I call the value of i if the user input is from the t array as the position for both array is the same?
For example, if I call the value 0.2 the program will call the value 1.264341 from array i.
You can use input to get the user to enter a number, and ismembertol to find the number's index in t. Once you have the index, you can get the corresponding value in i. You could even throw an error if the number entered is not found in t. Here's an example:
i=[0 1.264241 1.729329 1.900426 1.963369 1.986524 1.995042 1.998176 1.999329 1.999753 1.999909];
t=[0 0.2 0.4 0.6 0.8 1 1.2 1.4 1.6 1.8 2];
x = input('Enter number:\n');
[~,ind] = ismembertol(x,t);
if ind > 0
fprintf('Corresponding number in i is %g\n', i(ind))
else
error('Number not found in i')
end
I have 2 columns like this:
0.0 1.2
0.0 2.3
0.0 1.5
0.1 1.0
0.1 1.2
0.1 1.4
0.1 1.7
0.4 1.1
0.4 1.3
0.4 1.5
In the 1st column, 0.0 is repeated 3 times. I want to sum corresponding elements
(1.2 + 2.3 + 1.5) in the 2nd column. Similarly, 0.1 is repeated 4 times in the 1st
column. I want to sum the corresponding elements (1.0 + 1.2 + 1.4 + 1.7) in the 2nd
column and so on.
I am trying like this
for i = 1:length(col1)
for j = 1:length(col2)
% if col2(j) == col1(i)
% to do
end
end
end
This is a classical use of unique and accumarray:
x = [0.0 1.2
0.0 2.3
0.0 1.5
0.1 1.0
0.1 1.2
0.1 1.4
0.1 1.7
0.4 1.1
0.4 1.3
0.4 1.5]; % data
[~, ~, w] = unique(x(:,1)); % labels of unique elements
result = accumarray(w, x(:,2)); % sum using the above as grouping variable
You can also use the newer splitapply function instead of accumarray:
[~, ~, w] = unique(x(:,1)); % labels of unique elements
result = splitapply(#sum, x(:,2), w); % sum using the above as grouping variable
a=[0.0 1.2
0.0 2.3
0.0 1.5
0.1 1.0
0.1 1.2
0.1 1.4
0.1 1.7
0.4 1.1
0.4 1.3
0.4 1.5]
% Get unique col1 values, and indices
[uniq,~,ib]=unique(a(:,1));
% for each unique value in col1
for ii=1:length(uniq)
% sum all col2 values that correspond to the current index of the unique value
s(ii)=sum(a(ib==ii,2));
end
Gives:
s =
5.0000 5.3000 3.9000
I am trying to make an array Z that have indexes of the most frequent occurring difference between two elements in the array X. So if the most frequent occurring difference between two elements in X is 3 then I would get all the indexes in X that have that difference into array Z.
x = [ 0.2 0.4 0.6 0.4 0.1 0.2 0.2 0.3 0.4 0.3 0.6];
ct = 0;
difference_x = diff(x);
unique_x = unique(difference_x);
for i = 1:length(unique_x)
for j = 1:length(x)
space_between_elements = abs(x(i)-x(i+1));
if space_between_elements == difference_x
ct = ct + 1;
space_set(i,ct) = j;
end
end
end
I DonĀ“t get the indexes of X containing the most frequent difference from this code.
It appears you want to find how many unique differences there are, with "difference" interpreted in an absoulte-value sense; and also find how many times each difference occurs.
You can do that as follows:
x = [ 0.2 0.4 0.6 0.4 0.1 0.2 0.2 0.3 0.4 0.3 0.6]; %// data
difference_x = abs(diff(x));
unique_x = unique(difference_x); %// all differences
counts = histc(difference_x, unique_x); %// count for each difference
However, comparing reals for uniqueness (or equality) is problematic because of finite precision. You should rather apply a tolerance to declare two values as "equal":
x = [ 0.2 0.4 0.6 0.4 0.1 0.2 0.2 0.3 0.4 0.3 0.6]; %// data
tol = 1e-6; %// tolerance
difference_x = abs(diff(x));
difference_x = round(difference_x/tol)*tol; %// apply tolerance
unique_x = unique(difference_x); %// all differences
counts = histc(difference_x, unique_x); %// count for each difference
With your example x, the second approach gives
>> unique_x
unique_x =
0 0.1000 0.2000 0.3000
>> counts
counts =
1 4 3 2
I have to implement a Huffman encoder in MATLAB/Octave (unfortunately), so I am using a cell array for maximum flexibility. I want to append symbol indices as they are merged to the earlier indices so I can track what symbols are merged as the processing goes up the tree.
Here's an example:
Index Prob. Index Prob. Index Prob.
1 0.5 1 0.5 1 0.5
2 0.2 3,4 0.3 ---> 0.4 2,3,4 0.4
3 0.2 ---> 0.3 2 0.1 ---/
4 0.1 ---/
As you can see, symbols 3 and 4 get merged, and then the indices are merged and both lists are resorted in descending order of probability.
So I declared a cell array:
% cell index
myinds = num2cell(1:numel(probs));
D = 2; % binary
Unfortunately, when I try to merge the two, I get a size mismatch error;
% 3. add subtrees
myinds(end-(D-1)) = [myinds(end-(D-1)) mergedinds(2:end)];
% remove merged leaves
myinds((end-D):end) = []
The output of either side seems conceptually to be what I want, though:
octave> [myinds(end-(D-1)) mergedinds(2:end)]
ans =
{
[1,1] = 3
[1,2] = 4
}
octave> myinds(end-(D-1))
ans =
{
[1,1] = 6
}
I would like to store the Index column above as the algorithm steps through the illustrated process. I can just grow a matrix each time but that's slow and inefficient. As I understand it a cell array will do what I want, but I can't make it work.
I have an array of size m x n. Each row has n elements which shows some probability (between 0 and 1). I want to find the row which has the max difference between its elements while it would be better if its nonzero elements are greater as well.
For example in array Arr:
Arr = [0.1 0 0.33 0 0.55 0;
0.01 0 0.10 0 0.2 0;
1 0.1 0 0 0 0;
0.55 0 0.33 0 0.15 0;
0.17 0.17 0.17 0.17 0.17 0.17]
the best row would be 3rd row, because it has more distinct values with greater values. How can I compute this using Matlab?
It seems that you're looking for the row with the greatest standard deviation, which is basically a measure of how much the values vary from the average.
If you want to ignore zero elements, use Shai's useful suggestion to replace zero elements to NaN. Indeed, some of MATLAB's built-in functions allow ignoring them:
Arr2 = Arr;
Arr2(~Arr) = NaN;
To find the standard deviation we'll employ nanstd (not std, because it doesn't ignore NaN values) along the rows, i.e. the 2nd dimension:
nanstd(Arr2, 0, 2)
To find the greatest standard deviation and it's corresponding row index, we'll apply nanmax and obtain both output variables:
[stdmax, idx] = nanmax(nanstd(Arr2, 0, 2));
Now idx holds hold the index of the desired row.
Example
Let's run this code on the input that you provided in your question:
Arr = [0.1 0 0.33 0 0.55 0;
0.01 0 0.10 0 0.2 0;
1 0.1 0 0 0 0;
0.55 0 0.33 0 0.15 0;
0.17 0.17 0.17 0.17 0.17 0.17];
Arr2 = Arr;
Arr2(~Arr) = NaN;
[maxstd, idx] = nanmax(nanstd(Arr2, 0, 2))
idx =
3
Note that the values in row #3 differ one from another much more than those in row #1, and therefore the standard deviation of row #3 is greater. This also corresponds to your comment:
... ergo a row with 3 zero and 3 non-zero but close values is worse than a row with 4 zeros and 2 very different values.
For this reason I believe that in this case 3 is indeed the correct answer.
It seems like you wish to ignore 0s in your matrix. You may achieve this by setting them to NaN and proceed using special build-in functions that ignore NaNs (e.g., nanmin, nanmax, etc.)
Here is a sample code for finding the row (ri) with the largest difference between minimal (nonzero) response and the maximal response:
nArr = Arr;
nArr( Arr == 0 ) = NaN; % replace zeros with NaNs
mn = nanmin(nArr, [], 2); % find minimal, non zero response at each row
mx = nanmax(nArr, [], 2); % maximal response
[~, ri] = nanmax( mx - mn ); % fid the row with maximal difference