I am trying to sort the outputs from sine or cosine function as below. I have a set of angles, for which I compute the sine and then I sort the result of the sine. Is there a way in which I could avoid sorting the sine output and apply a function to the original sorted angle indexes? I presume this is a very stupid question and the answer is NO, but I thought whether there could be a combination in which I could apply a function to ixs1 to get ixs2, so ixs2 = f(ixs1);
ang = rand(1,100)*2*pi;
[~,ixs1] = sort(ang);
[~,ixs2] = sort(sin(ang));
plot(ixs1,'.');hold on;
plot(ixs2);

2 Kommentare

as you expected , the answer is NO because sin is not a monotonic function on 0 - 2pi range
if you had a monotonic function, both indexes would be in linear relationship
ang = rand(1,100)*2*pi;
[~,ixs1] = sort(ang);
% [~,ixs2] = sort(sin(ang)); % answer = NO
[~,ixs2] = sort(1+3*(ang)+0.3*(ang).^2); % answer = YES
plot(ixs1,ixs2,'*');
Thanks. I wanted to test different algorithms in Matlab for later implementation in VHDL real-time code. And sorting integer numbers seems easier than decimal numbers after the sin/cos functions...
On the option by @Mathieu NOE, would splitting the sine in two monotonically increasing parts do the work? Restricting it from 90 to 270 and from 270 to 450 (with proper wraps if required). Each part could be easily sorted, but it's true that sorting one and the other part may be the difficult part, however one is just the inverse of the other
ang1 = 90:0.1:270;
ang2 = 270:0.1:(360+90);
s1 = sind(ang1);
s2 = sind(ang2);
plot(s1);hold on;
plot(s2);

Melden Sie sich an, um zu kommentieren.

 Akzeptierte Antwort

John D'Errico
John D'Errico am 9 Jan. 2023
Bearbeitet: John D'Errico am 9 Jan. 2023

0 Stimmen

The simplest way to achieve what you want is to compute the sin, and then do the sort. Anything else you could do would be more complex, even if you could cobble up a solution. And since the sin and sort functions are so easy and fast to use, why is there a problem?
Sigh. CAN you do it? Well, technically yes. Is it any faster, any simpler? Not really. Again, is there really a good reason to not want to just compute the sin?
The point is, to recognize the sin function is periodic over an interval of length 2*pi, AND it is monotonic over the interval [-pi/2,pi/2].
fplot(@sin,[-pi/2,pi/2])
We would effectively need to use the simple identities
sin(x + 2*k*pi) = sin(x)
for any integer k. That gets you into an inteval of length 2*pi. As well, we would need this one:
sin(pi - x) = sin(x)
How can you use that information?
For example, I'll pick a large set of random numbers.
x = rand(1,1000)*50;
They will be spread out over a rather large interval, so any prediction of the sort order, merely from x will be difficult. Not impossible. Anyway, now apply those identities in a careful way.
xhat = pi - mod(x,2*pi);
xhat(xhat > pi/2) = pi - xhat(xhat > pi/2);
xhat(xhat < -pi/2) = -pi - xhat(xhat < -pi/2);
Now, test to see if the sort indices from sort(xhat) are the same as those from sort(sin(x)).
[~,idx1] = sort(xhat);
[~,idx2] = sort(sin(x));
isequal(idx1,idx2)
ans = logical
1
We can also see that now all elements live in the interval [-pi/2,pi/2], so as long as I used the above identities properly, the sort tags must now behave as desired since sin(x) is monotonic on that interval.
min(xhat) >= -pi/2
ans = logical
1
max(xhat) <= pi/2
ans = logical
1
Is there any real gain? I seriously doubt there is much, if any. We could probably test the amount of time needed. I would not be at all surprised if just doing the sort on sin(x) was not just as easy. But whatever floats your boat. If you want to know why what I did works, well, just spend some time thinking about those identities, and how they apply to what I did.

3 Kommentare

Albert Zurita
Albert Zurita am 9 Jan. 2023
Bearbeitet: Albert Zurita am 10 Jan. 2023
Hi, this is a very good alternative. Exactly in line with what I drafted earlier, but I didn't quite catch the coding for that. The main idea is to do the sorting with integer numbers, avoiding decimals or any sine/cosine which converts into decimals.
I am now adapting your code to my needs. I have a vector x with integer numbers going from 0 to 282 for which I would ideally do:
x = floor(rand(1,1000)*n_blocks);
[~,idx2] = sort(sind(x*360/n_blocks));
So the integer numbers are converted to 'pseudoangle' and the sine is executed, then sorted. Instead I would like to sort the original indexes in the way they would be sorted after the sin operation. I adapted then your code as follows, playing with what 90º and 180º would look like in index number instead of angle. I multiply the index number by 4 in order to avoid decimals when getting the equivalent 90º angle2index.
n_blocks = 282;
x = unique(floor(rand(1,1000)*n_blocks));
xhat = x*4;
xhat(xhat > n_blocks) = n_blocks*2 - xhat(xhat > n_blocks);
xhat(xhat < -n_blocks) = -n_blocks*2 - xhat(xhat < -n_blocks);
[~,idx1] = sort(xhat);
[~,idx2] = sort(sind(x*360/n_blocks));
isequal(idx1,idx2)
The problem is that this is not true, it is only true when n_blocks is an odd number.
I am sure you don't want to hear me singing like Mick Jagger. ;-) But here it goes "You can't always get what you want..." Yeah, the Stones did it better.
The point is, you are implicitly hoping to approximate pi by the ratio of two integers. And what do we know about pi? Ok, outside of the perusal of some backward school boards, pi is an irrational number, in fact transcendental. Most importantly, irrational. And what do we know about irrational numbers? There is NO pair of integers that repreoduces pi exactly as a ratio of those integers. If you did find one, you would be in line for a Fields medal. And incidentally, also in line for a place on one of those backward boards of education.
At best, you might consider using a better implicit approximation for pi.
rats(pi)
ans = ' 355/113 '
rats(pi,24)
ans = ' 1146408/364913 '
But no matter what, this is still not exact.
You cannot do what you want using integer arithmetic, and have the result be exact.
Albert Zurita
Albert Zurita am 11 Jan. 2023
Hehe, understood. In any case for an approximation it is already very good the option you proposed. Thanks!

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Kategorien

Produkte

Version

R2022a

Community Treasure Hunt

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

Start Hunting!

Translated by