mtex
mtex copied to clipboard
Recent versions of MTEX behave differently between MATLAB R2019a and R2021b
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:
When using R2021b, with the exact same script and MTEX version, the resultant plot looked like this:
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
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
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 |
---|---|
![]() |
![]() |
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 |
---|---|
![]() |
![]() |
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.
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