mtex icon indicating copy to clipboard operation
mtex copied to clipboard

Recent versions of MTEX behave differently between MATLAB R2019a and R2021b

Open Begley-Dev opened this issue 3 years ago • 3 comments

I stumbled across an odd bug. Long story short, I have been generating synthetic ODFs for a project, and I upgraded my MATLAB from Release 2019a to R2021b in the middle of that effor, and when I ran the same code after upgrading, I got a different result. My best guess is that something isn't respecting specimenSymmetry when used with R2021b, but I haven't found a source of the issue.

The Code The full script that generates the figures that I've attached will be included in the .zip file, I took out some of the code for this snippet so it didn't take up so much space.

v_matlab = ['R' version('-release')];
v_mtex =  strrep(getMTEXpref('version'), ' ', '');

CS = crystalSymmetry('cubic');
SS = specimenSymmetry('1');

hw = 16*degree;

o_s1 = orientation.SR(CS,SS);
%And the same for the other 3 SR orientations, both copper orientations, and both brass orientations.

h = Miller({0,0,1},{0,1,1},{1,1,1},CS,SS);

odf_s1 = unimodalODF(o_s1, CS,specimenSymmetry('1'),'halfwidth', hw);
%And the same for the other 3 SR orientations, both copper orientations, and both brass orientations.

odf = odf_s1 + odf_s2 + odf_s3 + odf_s4 + 0.5*odf_copper + 0.5*odf_copper2 + odf_brass + odf_brass2;

f = figure;
plotPDF(odf,h, 'projection', 'eangle')
mtexColorMap LaboTeX;
hold on
plotPDF(odf, h, 'contour', 1:2.5:13, 'linecolor', 'black', 'ShowText', 'on', 'upper', 'projection', 'eangle');
hold off
mtexColorbar;
saveas(f, ['PF_' v_matlab '_' v_mtex '.png'], 'png')

Results When using R2019a, the resultant plot looked like this: PF_R2019a_MTEX5 7 0

When using R2021b, with the exact same script and MTEX version, the resultant plot looked like this: PF_R2021b_MTEX5 7 0

There is a clear lack of symmetry across the y axis. As far as I can tell, the R2019a result would be the expected output of the code as written (but regardless, two recent versions of MATLAB should have the same result when used with the same version of MTEX.)

MTEX Version I have a half dozen old versions of MTEX on my computer, so I went ahead and tested this issue across all of them. For MTEX 5.4.0 and below, results from both MATLAB versions are the same, and match the R2019a results for later MTEX versions. For MTEX 5.5.2 through to the current Github develop branch, R2021b gives the asymmetric result.

MTEX Version R2019a R2021b
5.2.8 As Expected As Expected
5.4.0 As Expected As Expected
5.5.2 As Expected Asymmetric
5.6.0 As Expected Asymmetric
5.6.1 As Expected Asymmetric
5.7.0 As Expected Asymmetric
5.7.1 (Github as of 12/17/2021) As Expected Asymmetric

I've attached my full script and the output images from all of my version tests in the .zip file below. Version_Issue.zip

Begley-Dev avatar Dec 17 '21 21:12 Begley-Dev

Hi and thank you for the detailed description of the issue. What I can tell is that copper and copper2 were changed to the definition using Millers 47f773f5b1a3c25544353326f57ede9dcc4e43cd in 5.5.1 and I think there's a - missing and both might be switched. I changed them such that produce two distinct orientations. However, since I'm not a metal person, I don't know which should be which, so maybe you could have a look at it (c9da657e0ba0779a9e0eb61e501a0cd813053a65). Before, both were producing the same orientation (with Matlab 2021b).

What I really can't explain at the moment, is why this bug didn't crop up with old Matlab version (which unfortunately I can't test at the moment). What is the output of

CS = crystalSymmetry('cubic');
h = Miller(0,0,1,CS);

o1 = orientation.byEuler(270*degree,35*degree,45*degree,CS);
o2 = orientation.byMiller([1 1 2],[1 -1 1],CS);
o3 = orientation.byEuler(90*degree,35*degree,45*degree,CS);
o4 = orientation.byMiller([1 1 2],[-1 1 -1],CS);

plotPDF(o1,h,'label','o1')
hold on
plot(o2,'label','o2','add2all','textaboveMarker')
plot(o3,'label','o3','add2all')
plot(o4,'label','o4','add2all','textaboveMarker')
hold off

with both Matlab versions? For me, o1 and o2 are pretty close and distinct from o3 and o4.

Cheers, Rüdiger

kilir avatar Dec 18 '21 12:12 kilir

Hi Rüdiger,

Sorry, I was a little delayed in my response because of the holidays.

I ran your, code in both versions of MATLAB, and it seems to work as expected, and I've attached those plots below.

R2019a R2021b
2019a_570 2021b_570

I tested a little further, though, and it looks like the issue is deeper. I added a 5th point to the test script you gave me, which is one of the copper orientations before your partial fix:

o5 = orientation.byMiller([1 1 2],[-1 1 1],CS)
R2019a R2021b
2019a_extrapoint 2021b_extrapoint

To make a long story short, I followed this bug all the way to line 64 of the byMiller method in orientation.

[err,id] = min(abs(90 - angle(uvw,hkl(:),'noSymmetry')./degree),[],2);

byMiller runs the same up until that point in both releases of Matlab, but the id variable changes value depending on the version of Matlab. I split up the script a little bit so I could look at what was getting passed to the min function:

temp = abs(90 - angle(uvw,hkl(:),'noSymmetry')./degree;
[err,id] = min(temp,[],2);

An example of which is this:

temp = 1×48    
   28.1255   28.1255    0.0000   28.1255   28.1255         0         0   28.1255   28.1255   70.5288   70.5288   70.5288   28.1255    0.0000   28.1255   28.1255    0.0000   28.1255   70.5288   70.5288   70.5288         0   28.1255   28.1255   28.1255   28.1255         0   28.1255   28.1255         0    0.0000   28.1255   28.1255   70.5288   70.5288   70.5288   28.1255         0   28.1255   28.1255    0.0000   28.1255   70.5288   70.5288   70.5288    0.0000   28.1255   28.1255

All of the 0.0000 are actually MATLAB rounding errors where the value is somewhat more like 1e-16, and that's the problem. In R2019a, it returns the 6th index of this array because that's the first true minimum in the array, but in R2021b, it returns the 3rd index because there's no rounding artifact in that index. As far as I can tell, in R2019a, the parts with rounding artifacts are the antipodes of the true minimums (which for cubic symmetry, should also have the same angle for this calculation).

I think that the core issue is that the byMiller algorithm isn't particularly robust when it comes to differentiating between antipodes. byEuler seems to be perfectly fine, so on my machine I'm going to just set copper, copper2 and the other default orientations back to byEuler definitions to be safe, but I'm happy to give more information and test fixes across release versions.

Begley-Dev avatar Jan 10 '22 19:01 Begley-Dev

Hi, thank you for diving into this. I'm using matlab R2021b, Update2, latest mtex from development. Using your example

CS = crystalSymmetry('cubic');
o5 = orientation.byMiller([1 1 2],[-1 1 1],CS)

and setting a break point here https://github.com/mtex-toolbox/mtex/blob/c9da657e0ba0779a9e0eb61e501a0cd813053a65/geometry/%40orientation/byMiller.m#L64

in my case, I get id=6 which is the first one without the rounding issue. I rather suspect the order to change elsewhere (Miller/symmeterise ? ) while I have no explanation at the moment why we should not get the same result using identical Matlab and Mtex versions. I'll think about it.

If you step into the function, how does your uvw(1:6) look like (in R2019a and R2021b)?

K>> uvw(1:6)
 
ans = Miller  
 size: 1 x 6
 symmetry: m-3m
        u       v       w
  -0.5774  0.5774  0.5774
   0.5774 -0.5774  0.5774
   0.5774  0.5774 -0.5774
   0.5774 -0.5774 -0.5774
  -0.5774  0.5774 -0.5774
  -0.5774 -0.5774  0.5774

Cheers, Rüdiger

kilir avatar Jan 11 '22 11:01 kilir