Clear Filters
Clear Filters

Point Categorisation via a suggested Mathematica If Statement

1 view (last 30 days)
I've been trying to figure out how to convert this for too long but without success - I'm hoping this is more obvious to a fresh set of eyes. I have a function defined in mathematica:
f=If[-y <= x <= y || y <= -x <= -y, Sign[y], 0]
Which is then applied as:
k_x = A * f;
k_y = A * -f
k_z = 0;
Plotted as a quiver this results in the following on my set of evaluation points (where A is some scalar, =1 for simplicity here):
I know the conditionals need to be seperated out to apply this in MATLAB. My current best attempt is:
N = 3; % Number of equations
nr = length(location.x); % Number of columns
k = zeros(N,nr); % Allocate f
k_x = zeros(1,nr); k_y = zeros(1,nr);
for ind = 1:length(location.x)
if (-location.y(ind) <= location.x(ind) && location.x(ind) <= location.y(ind)) || ...
(location.y(ind) <= -location.x(ind) && -location.x(ind) <= -location.y(ind))
k_x(ind) = sign(location.y(ind));
k_y(ind) = 0;
elseif (location.x(ind) <= -location.y(ind) && -location.y(ind) <= -location.x(ind)) || ...
(-location.x(ind) <= location.y(ind) && location.y(ind) <= location.x(ind))
k_y(ind) = sign(location.x(ind));
k_x(ind) = 0;
k_x(ind) = 0;
k_y(ind) = 0;
k(1,:) = k_x; %kx
k(2,:) = -k_y; %ky
k(3,:) = 0; %kz
figure; quiver3(location.x,location.y,location.z,k(1,:),k(2,:),k(3,:)); hold on;
This almost works, but the corners don't have the same diagonal as the result I'm expecting from the function (as seen below). The 'diagonal' vectors which I don't achieve in my own function are really important. I also feel like the if loop is probably not the best way to evaluate this function.
An example location structure array is also attached here if testing/applying the code is useful.
Thanks in advance.
Geoff Hayes
Geoff Hayes on 9 Apr 2020
Edited: Geoff Hayes on 9 Apr 2020
ADSW121365 - the conditions for the if statement look fine. I just don't understand how the elseif conditions relate to the Mathematica equation that you have shown (which only references Sign[y] and not Sign[x]). And is the data in the mat-file the same data used for the Mathematica plot?
ADSW121365 on 9 Apr 2020
Edited: ADSW121365 on 9 Apr 2020
This is from some legacy code I'm trying to re-write in MATLAB but I have never used and don't have access to mathematica, but the database was saved as plain text, so assuming numerical storage isn't an issue the data should be identical.
You're correct about the elseif conditions. If you comment out this section and remove the additional k_y function such this matches the mathematica code, it only selects half of the points, so I added the elseif which made it select the other half of the points, but clearly something I've done is incorrect.

Sign in to comment.

Accepted Answer

ADSW121365 on 10 Apr 2020
Edited: ADSW121365 on 14 Apr 2020
Utilising Walters suggested syntax, the expected code in MATLAB is:
f_1 = (abs(location.x) <= abs(location.y)).*sign(location.y); %Selects X Axis points
f_2 = (abs(location.y) <= abs(location.x)).*sign(location.x); %Selects Y Axis Points
f(1,:) = A.*f_1; %Kx
f(2,:) = -A.*f_2; %Ky
f(3,:) = 0; %KJz
As mentioned in my initial post, I'm not sure why I require two functions in MATLAB, but the writer in mathematica could achieve the same thing with a single function - if anyone can manage this it would be nice to have, but is unimportant in general.
Walter Roberson
Walter Roberson on 14 Apr 2020
The point is that you wrote,
f_2 = (abs(location.y) <= abs(location.x)).*sign(location.x); %Selects Y Axis Points
which uses sign(x) instead of sign(y) and using sign(x) is not correct according to the Mathematica statement. Using the sign(y) like I did reproduces the Mathematica statement. If the Mathematica is correct, then the code I posted is correct and the code you posted using sign(x) is not correct.
Conversely, if you find that you need sign(x) to get the plot you were interested in, then the implication is that the Mathematica posted is not correct.
ADSW121365 on 14 Apr 2020
Edited: ADSW121365 on 14 Apr 2020
I follow your point, but I'm fairly happy that the origonal post made it clear I'm looking for the plots, not a direct recreation of the mathematica code - perhaps the question title could be less ambiguous though.
EDIT: I changed the title to something hopefully less ambiguous to future readers.

Sign in to comment.

More Answers (1)

Walter Roberson
Walter Roberson on 9 Apr 2020
f = (abs(x) <= abs(y)).*sign(y);
Which can be done in vectorized form.
k_x = A*f;
k_y = -k_x;
k_z = zeros(size(k_x));
No loop needed provided that x and y are the same size (such as might be produced by ndgrid or meshgrid)
  1 Comment
ADSW121365 on 10 Apr 2020
Edited: ADSW121365 on 10 Apr 2020
Appreciate the response - the vectorised form is particularily helpful. Unfortunetly, this bit of code still doesn't achieve the same thing as mathematica with results on the attached data like:
I'm unsure as to why the mathematica version works for all points whilst a direct MATLAB implementation doesn't - this is why I added the elseif command to my own attempted code - it seems like the conditional works differently inside mathematica such all points are selected and diagonals assigned only to points on the diagonal planes (see red quiver plot in the inital post). But I have no access to or experience in mathematica to try and figure out how the function works/ to adapt it.
Hope you're able to help further, I'm going to try and find a solution using your suggested syntax and will post it if I'm successful.

Sign in to comment.


Find more on MATLAB in Help Center and File Exchange




Community Treasure Hunt

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

Start Hunting!