sort 2 matrices for minimum numbers sum and divide them

I have r = [ 1 3 4 5 ......n]
and x = [ 5 8 9 4 ......n]
I will like to do this computation
when m = 1
sort the lowest number of r and divide it with the lowest number of x till the end n
for example =[ 1/4, 3/5, 4/8, 5/9.......n]
when m = 2
= [(1 + 3) / (5 + 4) , (4 +5)/(8+9) , ...........n]
when m =3
=[ (1 + 3 + 4)/( 4 + 5 + 8),................n]
Thanks for your help in advance
Tino

2 commentaires

Stephen23
Stephen23 le 4 Juin 2019
Modifié(e) : Stephen23 le 4 Juin 2019
And what should be the last term if n is not exactly divisble by m ?
Hi Stephen
if the last term is not divisible it is ignored. That is to say the computation stops when it is not divisible by mHope to hear from you soonest
Tino

Connectez-vous pour commenter.

 Réponse acceptée

Stephen23
Stephen23 le 4 Juin 2019
Modifié(e) : Stephen23 le 4 Juin 2019
This is MATLAB, so don't waste your time writing inefficient loops.
Learn to write simpler vectorized code, just like experienced MATLAB users do:
>> r = sort([1,3,4,5,10]); % sorted!
>> x = sort([5,8,9,4,10]); % sorted!
>> m = 1;
>> n = m*fix(numel(r)/m);
>> sum(reshape(r(1:n),m,[]),1) ./ sum(reshape(x(1:n),m,[]),1)
ans =
0.25000 0.60000 0.50000 0.55556 1.00000
>> m = 2;
>> n = m*fix(numel(r)/m);
>> sum(reshape(r(1:n),m,[]),1) ./ sum(reshape(x(1:n),m,[]),1)
ans =
0.44444 0.52941
>> m = 3;
>> n = m*fix(numel(r)/m);
>> sum(reshape(r(1:n),m,[]),1) ./ sum(reshape(x(1:n),m,[]),1)
ans =
0.47059

7 commentaires

Brilliant Stephen
Just one more help
if I have a data with various n columns and wishes to partition those column into 2 to perform this computation how do I go about it
for instance
1
3
4
5
6
7
8
9
2
6
and wish to divide this one column into halfs (r and x) to carry out the computation
How can I do this intitial code
Thanks again
Tino
@Tino: See code after word 'add' in my answer.
"wish to divide this one column into halfs (r and x) to carry out the computation"
Most likely you would use indexing. But your example is not very clear (e.g. you mention "I have a data with various n columns" and then show data that only has one column) and you did not provide any example output data, so it is not clear exactly how you want that data "divided" up.
Please show the expected output data for your example column of values.
Tino
Tino le 4 Juin 2019
Modifié(e) : Tino le 4 Juin 2019
for instance when I get a data input which can contain several columns ( nth column) for instance let us 3 column data
1 4 1
2 1 3
3 1 2
4 1 1
5 1 2
6 2 3
each data column is divided by 2 to get
r and x
for the computation above
for column one
r = [ 1 2 3]
x = [4 5 6]
computation
for column two
r = [4 1 1]
x = [1 1 2]
computation
for column three
r = [1 3 2]
x = [1 2 3]
computation
I hope this is clear
Thanks
Stephen23
Stephen23 le 4 Juin 2019
Modifié(e) : Stephen23 le 5 Juin 2019
@Tino: it seems that you want to loop over the columns, e.g. where M is your matrix:
A = [1,4,1;2,1,3;3,1,2;4,1,1;5,1,2;6,2,3];
S = size(A);
m = 1;
n = m*fix(S(1)/2/m);
for k = 1:S(2)
r = A(1:n,k);
x = A(1+n:2*n,k);
Z = sum(reshape(r,m,[]),1) ./ sum(reshape(x,m,[]),1)
end
Giving:
Z =
0.25 0.4 0.5
Z =
4 1 0.5
Z =
1 1.5 0.66667
Thanks for your help Stephen
How do I make it
0.25 4 1
0.4 1 1.5
0.5 0.5 0.66667
You ve been a big help
Hoping to hear from you soon
Stephen23
Stephen23 le 5 Juin 2019
Modifié(e) : Stephen23 le 5 Juin 2019
>> S = size(A);
>> m = 1;
>> n = m*fix(S(1)/2/m);
>> r = A(1:n,:)
>> x = A(1+n:2*n,:)
>> Z = sum(reshape(r,m,[]),1) ./ sum(reshape(x,m,[]),1);
>> Z = reshape(Z,[],S(2)).'
Z =
0.25000 0.40000 0.50000
4.00000 1.00000 0.50000
1.00000 1.50000 0.66667
>> Z = sum(permute(reshape(r,m,[],S(2)),[3,2,1]),3) ./ ...
sum(permute(reshape(x,m,[],S(2)),[3,2,1]),3)
Z =
0.25000 0.40000 0.50000
4.00000 1.00000 0.50000
1.00000 1.50000 0.66667

Connectez-vous pour commenter.

Plus de réponses (3)

I am assuming n is a multiple of m. In that case this works:
r=sort(r);
x=sort(x);
m=input('enter value of m:');
if m==1
for ii=1:numel(r)
Answer(1,ii)=r(1,ii)/x(1,ii);
end
Answer
elseif m==2
Answer(1,1)=(r(1,1)+r(1,2))/(x(1,1)+x(1,2));
for ii=3:2:numel(r)
Answer(1,(ii+1)/2)=(r(1,ii)+r(1,ii+1))/(x(1,ii)+x(1,ii+1));
end
Answer
elseif m==3
Answer(1,1)=(r(1,1)+r(1,2)+r(1,3))/(x(1,1)+x(1,2)+x(1,3));
n=0;
for ii=4:3:numel(r)
Answer(1,(ii-n)/2)=(r(1,ii)+r(1,ii+1)+r(1,ii+2))/(x(1,ii)+x(1,ii+1)+x(1,ii+2));
n=n+1;
end
Answer
else
disp('Invalid Value of m')
end
There may be better and optimized way of doing this also.
P.S: How about adding a 'Homework' tag next time and showing what you attempted in addition to 'Hope to hear from you soonest'? Everybody wil not be as free as i am today! Cheers!!
Pullak Barik
Pullak Barik le 4 Juin 2019
Modifié(e) : Pullak Barik le 4 Juin 2019
Hi!
I assume that r and x are just vectors, and not matrices with more than one dimension.
I guess the following function will work for you-
function result = sort_sum_and_divide(r, x, m)
r = sort(r);
x = sort(x);
n = length(r);
if(length(r) == length(x)) %To check if the input is wrong
i = 1:m:n;
if(i(end) + m - 1 > n)
i(end) = []; %To drop the elements at the end if they can not be grouped
end
result = zeros(1, length(i)); %preallocation of result array
for idx = 1:length(i)
result(idx) = sum(r(i(idx):i(idx)+m-1))./sum(x(i(idx):i(idx)+m-1));
end
else
disp('Length of r and x are not the same');
end
end

2 commentaires

Stephen23
Stephen23 le 4 Juin 2019
Modifié(e) : Stephen23 le 4 Juin 2019
@Pullak Barik: note that concatenation onto the result array like that is not considered good practice, and detrimentally affects efficiency:
The MATLAB documentation recommends preallocating arrays before the loop:
Ya, I could preallocate my result array. Thanks.

Connectez-vous pour commenter.

Andrei Bobrov
Andrei Bobrov le 4 Juin 2019
Modifié(e) : Andrei Bobrov le 4 Juin 2019
m = 3;
r = [ 1 3 4 5 30];
x = [ 5 8 9 4 78];
out = funt(r,x,3);
function out = funt(r,x,m)
ad = nan(mod(-numel(r),m),1);
a = sort(cat(3,[r(:);ad],[x(:);ad]));
b = sum(reshape(a,m,[],2),'omitnan');
out = b(:,:,1)./b(:,:,2);
end
add
rx = [1
3
4
5
6
7
8
9
2
6];
m = 2;
rrxx = sum(sort(reshape([reshape(rx,[],2);nan(mod(-numel(rx)/2,m),2)],...
m,[],2)),'omitnan');
out = rrxx(:,:,1)./rrxx(:,:,2);

2 commentaires

Thanks Andrei Just one more help
if I have a data with various n columns and wishes to partition those column into 2 to perform this computation how do I go about it
for instance
1
3
4
5
6
7
8
9
2
6
and wish to divide this one column into halfs (r and x) to carry out the computation accross several columns
How can I do this intitial code
Thanks again
Tino
Hi Andrei
Your code is givng me the right answer
I have r = [ 1 3 4 5 ......n]
and x = [ 5 8 9 4 ......n]
I will like to do this computation
when m = 1
sort the lowest number of r and divide it with the lowest number of x till the end n
for example =[ 1/4, 3/5, 4/8, 5/9.......n]
when m = 2
= [(1 + 3) / (5 + 4) , (4 +5)/(8+9) , ...........n]
when m =3
=[ (1 + 3 + 4)/( 4 + 5 + 8),................n]
Thanks for your help in advance
Tino

Connectez-vous pour commenter.

Catégories

Produits

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by