Adding multiple nth elements of a matrix repeatedly - matlab

I have a matrix 63 rows x 7 columns
I want to select every 7th,8th,9th ongoing value in each column and add them to create a new value.
i.e.
7 8 9th added to a new value
16 17 18th added to a new value...etc
25 26 27th
34 35 36th
43 44 45th
52 53 54th
61 62 63th
So I should end up with a 7x7 matrix.
Without doing this manually, is there a simple command so that if the dimensions of the matrix changes, the output will always be correct?

You can do that easily with a bit of reshaping.
originalMatrix = (1:63)'*(1:7); %'
[nRows,nCols] = size(originalMatrix); %# =63 in this example
stepSize = 9;
nTriplets = floor(nRows/stepSize); %# =7 in this example
%# create index list
idx = bsxfun(#minus,stepSize:stepSize:nRows,[2 1 0]'); %'
idx = idx(:); %# reshape to a vector
%# create 3-by-7-by-7 array from original matrix
tmpMatrix = reshape(originalMatrix(idx,:),3,nTriplets,nCols);
%# sum along dim 1 (to sum e.g. the 7th, 8th, and 9th value)
result = squeeze(sum(tmpMatrix,1));
result =
24 48 72 96 120 144 168
51 102 153 204 255 306 357
78 156 234 312 390 468 546
105 210 315 420 525 630 735
132 264 396 528 660 792 924
159 318 477 636 795 954 1113
186 372 558 744 930 1116 1302

matrix=(1:63)'*(1:7);
n=7;
startind = n:(n+2):size(matrix,1);
endind = (n+2):(n+2):size(matrix,1);
tmp=cumsum(matrix);
tmp(endind,:)-tmp(startind,:)
This will, of course, only work if startind and endind have the same length, which would not be the case for, say, a matrix of size 62x7.

If I had understood your question properly, this slip of code should do what you want. But I admit, maybe it's not the most efficient Matlab code ever-written...
k = 9; n = 7; m = k*n; % 63
A = randi(5,m,n);
startIdx = k*(1:n)+n-k;
endIdx = k*(1:n);
B = zeros(n,n);
for i = 1:n
tmp = A(startIdx(i):endIdx(i),:);
B(i,:) = sum(tmp,1);
end

Related

How to perform reduced row echelon form on a non-square GF matrix (GF(2^8)) in matlab

%GF(2^8)
m=8
mat1 = gf([160 28 233 185 176],8);
result1 = gf([160 28 233 185 176],8)/gf([160],8)
% 1 77 174 32 220
[R,jb] = rref([1 77 174 32 220;189 244 80 245 190])
I use the result from result1 as 1st row and progressively add the next row vector [189 244 80 245 190]
% reduced row echelon
mat2 = [1 77 174 32 220;189 244 80 245 190]
a = gf([1 77 174 32 220;189 244 80 245 190],8);
r2 = a(2,:); r1 = gf(189,8) * a(1,:);
subt = r2 -r1; a(2,:)= subt./gf(122,8);
a(1,:) = a(1,:)- (gf(77,8) *a(2,:));
disp(a)
mat3 = [[1 0 101 105 110]; [0 1 163 128 97]; [157 233 247 64 118]];
m3 = gf(mat3,8);
m3(3,:)= m3(3,:) - (gf(157,8) * m3(1,:))
m3(3,:)= m3(3,:) - (gf(233,8) * m3(2,:))
m3(3,:)= m3(3,:)./ gf(29,8) .
rref works without GF(2^8). But I am unable to perform the reduction using GF(2^8) . Can someone help me to find a solution and how to proceed?
I will be using the result from the above and append another row-vector to the it. Is there any function we can solve it, instead of going step-by-step

Getting the highest correlation coefficient from the given data set

I would like to compare the following given data set
a = '235 148 89 19 222';
b = '112 128 144 160 176';
c = '192 192 192 192 192';
d = '64 64 64 64 64';
with
y = [230 138 79 15 212];
Then calculate the correlation coefficient by comparing each of the given data set with y. Then, display the string with the highest correlation coefficient found.
I can find it for calculating it for two values with the command
c = corrcoef( a, y );
c = abs(c(2,1));
but how do I iterate through each data set using a for loop and display the result with highest the corrcoef?
Here is the piece of code which I have written, but I don't know how to proceed with the 'for loop'
a = '235 148 89 19 222';
b = '112 128 144 160 176';
c = '192 192 192 192 192';
d = '64 64 64 64 64';
y = '230 138 79 15 212';
s = {a;b;c;d};
s = cellfun(#strsplit, s, 'UniformOutput', false);
s = vertcat(s{:});
for i = 1:size(s,1)
end
First of all the easy way to transform a string of number to array is using
str2num like this:
>> an = str2num(a)
an =
235 148 89 19 222
to concatenate stings in a matrix as rows use char and then convert it to a matrix:
>> S = char(a,b,c,d)
S =
235 148 89 19 222
112 128 144 160 176
192 192 192 192 192
64 64 64 64 64
>> N = str2num(S)
N =
235 148 89 19 222
112 128 144 160 176
192 192 192 192 192
64 64 64 64 64
then the only thing you need is to go trought the matrix:
>> [rows,columns] = size(N)
rows =
4
columns =
5
we need to iterate over all the rows
>> N(1,:)
ans =
235 148 89 19 222
in the matlab help:
R = corrcoef(A,B) returns coefficients between two random variables A and B.
>> R = corrcoef(N(1,:),y)
R =
1.0000 0.9995
0.9995 1.0000
so then applying your measure to the loop
>> for i = 1:rows
R = corrcoef(N(i,:),y);
rr(i) = abs(R(2,1));
end
>> rr
rr =
0.9995 0.2789 NaN NaN
finally the max of that vector is the row that you want
>> [value,position] = max(rr)
value =
0.9995
position =
1
>> N
N =
235 148 89 19 222
112 128 144 160 176
192 192 192 192 192
64 64 64 64 64
>> N(position,:)
ans =
235 148 89 19 222
Is there a special reason for using strings and cells instead of integer values and matrices?
What about the following solution:
a = [235 148 89 19 222;...
112 128 144 160 176;...
192 192 192 192 192;...
64 64 64 64 64];
b = zeros(size(a));
y = [230 138 79 15 212];
for i=1:length(a(:,1))
b(i,:) = a(i,:)- y;
end;
[~, minLine] = min(sum(abs(b')));
disp(minLine);
Here every line in the given dataset a(matrix) is compared with the given vector y, by calculating the difference and storing the values in a second matrix b.
After the loop the minimal sum is calculated and gives you the line in a, which is correlating most to y

Combine columns into a single number per row

I need to combine each column in a row into a single number
A = [8 1 6
3 5 7
4 9 2];
My goal is to have this form:
B = [816; 357; 492]
There are a few ways that you can do this. The fastest is likely to consider that each row of your matrix contains digits in base-10 and to combine these digits together we should multiply the first column by 10^2 (100), the second column by 10^1 (10) and the third column by 10^0 (1) and then sum across each row.
We can easily accomplish that with this one-liner which constructs all the powers of 10, and then performs matrix multiplication with A to perform the multiplication and summation.
A = [8 1 6; 3 5 7; 4 9 2];
B = A * flip(10.^(0:size(A, 2)-1))';
% 816
% 357
% 492
Another slower but possible solution would be to convert your rows to a string and then convert the string back to a number.
B = str2double(reshape(sprintf('%d', A), size(A, 2), []));
#Suever: I don't understand why did you delete the discussion, I am new in this group; any way, i put all the tests that i did and the result:
`function testtttt ()
%%%% Solution1 stackoverflow %%%%
%A=importdata('file.mat');
%B= (A * flip(10.^(0:size(A, 2)-1))')
%Result: B =
% 2.1194e+17
% 2.4989e+17
% 3.5458e+16
% 2.3669e+17
% 1.7582e+17
%%%%%%%%% Solution2 Matlab Forum %%%%%%%%%%%
% A=importdata('file.mat');
% B= num2str (A * flip(10.^(0:size(A, 2)-1))')
%Result: B =
% 211935227421357568
% 249886223928308032
% 35457727150655748
% 236691335688358080
% 175820284169194336
%%%%%%%%% Solution3 Matlab Forum %%%%%%%%%%%
% A=importdata('file.mat');
% B= dec2hex(str2num(strcat(num2str(A)')'))
%Result: B =
% D0
% E7
% 20
% E9
% A1
% 18
% 47
% 8C
% F5
% F7
% 28
% F8
.....
%%%%%%%%% Solution4 Matlab Forum %%%%%%%%%%%
A = importdata('file.mat'); % file.mat contains my matrix
[l c ] = size (A) ;
%B = cell (l,1);
for i =1 : l
B{i} = A(i, [1:16]) %however b{i} = a(i, :)
end
%Result: B =
{
[1,1] =
208 15 217 252 128 35 50 252 209 120 97 140 235 220 32 251
[1,2] =
231 174 143 43 125 66 49 143 48 139 81 103 154 229 93 229
[1,3] =
32 10 237 65 224 22 83 238 31 15 252 27 179 48 173 221
[1,4] =
233 18 178 101 90 109 225 184 210 168 183 185 190 169 96 205
[1,5] =
161 133 149 18 115 65 120 123 163 227 105 157 98 240 221 142
........
endfunction `
the best solution is the third that i found in matlab forum. Then the result found in solution 2 are caused by the using of octave. Thank you for your help.

MATLAB accessing conditional values and performing operation in single column

Just started MATLAB 2 days ago and I can't figure out a non-loop method (since I read they were slow/inefficient and MATLAB has better alternatives) to perform a simple task.
I have a matrix of 5 columns and 270 rows. What I want to do is:
if the value of an element in column 5 of matrix goodM is below 90, I want to take that element and and subtract it from 90.
So far I tried:
test = goodM(:,5) <= 90;
goodM(test) = 999;
It changes all goodM values within column 1 not 5 into 999, in addition this method doesn't allow me to perform operations on the elements below 90 in column 5. Any elegant solution to doing this?
edit:: goodM(:,5)(test) = 999; doesn't seem to work either so I have no idea to specify the target column.
I am assuming you are looking to operate on elements that have values below 90 as your text in the question reads, rather than 'below or equal to' as represented by '<=' as used in your code. So try this -
ind = find(goodM(:,5) < 90) %// Find indices in column 5 that have values less than 90
goodM(ind,5) = 90 - goodM(ind,5) %// Operate on those elements using indices obtained from previous step
Try this code:
b=90-a(a(:,5)<90,5);
For example:
a =
265 104 479 13 176
26 110 447 208 144
379 163 179 366 464
301 48 274 391 26
429 374 174 184 297
495 375 312 373 82
465 272 399 447 420
205 170 373 122 84
1 417 63 65 252
271 277 412 113 500
then,
b=90-a(a(:,5)<90,5);
b =
64
8
6

Selecting elements of a vector based on two vectors of starting and ending positions matlab

I would appreciate your help with the following problem in matlab:
I have a vector and I would like to select parts of it based on the following two vector of start and end indices of parts:
aa = [1 22 41 64 83 105 127 147 170 190 212 233]
bb = [21 40 63 82 104 126 146 169 189 211 232 252]
Basically I would like to perform some function on V(1:21), V(22:40),... V(233:252).
I have tried V(aa:bb) or V(aa(t):bb(t)) where t = 1:12 but I get only V(1:21), probably because V(22:40) has 19 elements compared to V(1:21) which has 22 elements.
Is there a fast way of programming this?
Put your selection in a cell array, and apply your function to each cell:
aa = [1 22 41 64 83 105 127 147 170 190 212 233]
bb = [21 40 63 82 104 126 146 169 189 211 232 252]
V = rand(252,1); % some sample data
selV = arrayfun(#(t) V(aa(t):bb(t)), 1:12,'uniformoutput',false);
result = cellfun(#yourfunction,selV)
% or
result = cellfun(#(selVi) yourfunction(selVi), selV);
If the function you want to apply has scalar output to every vector input, this should give you an 1x12 array. If the function gives vector output, you'll have to include the uniformoutput parameter:
result = cellfun(#(selVi) yourfunction(selVi), selV,'uniformoutput',false);
which gives you a 1x12 cell array.
If you want to run this in a highly condensed form, you can write (in two lines, for clarity)
aa = [1 22 41 64 83 105 127 147 170 190 212 233]
bb = [21 40 63 82 104 126 146 169 189 211 232 252]
V = rand(252,1); % some sample data borrowed from #Gunther
%# create an anonymous function that accepts start/end of range as input
myFunctionHandle = #(low,high)someFunction(V(low:high));
%# calculate result
%# if "someFunction" returns a scalar, you can drop the 'Uni',false part
%# from arrayfun
result = arrayfun(myFunctionHandle(low,high),aa,bb,'uni',false)
Note that this may run more slowly than an explicit loop at the moment, but arrayfun is likely to be multithreaded in a future release.