Combine columns into a single number per row - matlab

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.

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

Find the row/column with the lowest maxima

Consider the matrix below:
A = randi([0 100], 5, 7)
62 59 20 42 49 41 83
37 34 13 65 82 47 24
93 33 19 93 30 37 20
42 49 74 96 26 41 21
14 85 14 90 77 4 96
first I want to find the maxima of each row and the column index:
83 7
82 5
93 1
96 4
96 7
then I need to find the row with the lowest maxima:
82 5 2
so far, I have implemented this:
close all;
clear all;
clc;
A = randi([0 100], 5, 7);
[M1, I1] = max(A, [], 2);
[M1, I1]
[M2, I2] = min(M1);
[M2, I1(I2), I2]
Though it feels like a workaround, I wondered if there is a more canonical way to do this? Maybe a built-in function or min/max syntax for this specific purpose?
P.S. Shared this question also on the MATLAB Discord channel.
What about this with find?
M = min(max(A,[],2));
[i,j] = find(A == M);
[M,j,i]

MATLAB CODE Rectification

The below code is not running in matlab. I am trying an anonymous function in matlab.Can you pls tell me whats wrong in this line :
Inv_Y_Quant = blockproc(BB,[8 8], InvQuant);
and the related code is below:
clear all
clc
I = imread('cameraman.tif');
% convert it to double
I = im2double(I);
% "Trim by 128"
I = I-128;
% Generate the DCT matrix
T = dctmtx(8);
% Generate Function handler for DCT
MyFun1 = #(block_struct) T * block_struct.data * T';
% BlockProcess the DCT the function for 8 by 8 blocks
B = blockproc(I,[8 8],MyFun1);
% Form the Quantization matrix
Q = [ 16 11 10 16 24 40 51 61
12 12 14 19 26 58 60 55
14 13 16 24 40 57 69 56
14 17 22 29 51 87 80 62
18 22 37 56 68 109 103 77
24 35 55 64 81 104 113 92
49 64 78 87 103 121 120 101
72 92 95 98 112 100 103 99];
% now generate function handler for the quantization
MyFun2 = #(block_struct)block_struct.data ./Q;
% perform the quantization
BB = blockproc(B,[8 8],MyFun2);
InvQuant = #(block_struct)round(block_struct.data.*Q);
Inv_Y_Quant = blockproc(BB,[8 8], InvQuant);
InvDct = #(block_struct)dct_matrix'*block_struct.data*dct_matrix;
Z = blockproc(Inv_Y_Quant, [8 8], InvDct);
Z = Z+128;
figure, imshow(Z)
Z = uint8(Z);
figure, imshow(Z)
%imwrite(Z, 'Mar7.tif');
%b = imread('Mar7.tif');
%imshow(b)
As you wrote in your comment, the problem is that you try to use array dct_matrix in anonymous function InvDct. This array was never defined in your code.
Did you meant to use matrix T (init as dctmtx(8))?
edit:
When using parameters in anonymous functions (as dct_matrix in this example), these parameters should be defined before the anonymous function is defined.

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.

Adding multiple nth elements of a matrix repeatedly

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