Newer
Older
% GTVECTORLAB2CRYST Express laboratory row vector(s) in crystal CS.
Yoann Guilhem
committed
%
% -----------------------------------
Yoann Guilhem
committed
%
% INPUT:
% Vs = <double> Vector(s) expressed in the lab CS.
% g = <double> Array containing crystal orientation matrix(ces).
% mode = <string> Can be either 'diag' or a 3 coord vector {[3 1 2]},
% <int> This affect the output shape when multiple input
% vectors and matrices, i.e. M>1 and N>1
% See further explanations about the output.
Yoann Guilhem
committed
%
% OUTPUT:
% Vc = <double> Input vector(s) Vs expressed in the crystal CS.
% Shape of output depends of input size (see below).
Yoann Guilhem
committed
%
% Note:
% This function can be used in different modes:
% - Vs = 1x3 array (1 row vector) , g = 3x3xN array
% output: N vectors expressed in the crystal CS defined by g matrices
% output size: [N 3]
Yoann Guilhem
committed
%
% - Vs = Mx3 array (M row vectors) , g = 3x3 array
% output: M vectors expressed in the crystal CS defined by g matrix
% output size: [M 3]
Yoann Guilhem
committed
%
% - Vs = Mx3 array (M row vectors) , g = 3x3xN array
% output: MxN vectors expressed in the crystals CS defined by g matrices
% output size: [M 3 N] by default, can be modified using numeric mode
% 1: input vector coordinate dimension (3)
% 2: input orientation matrix dimension (N)
% 3: input vector index dimension (M)
Yoann Guilhem
committed
%
% - diag mode (only if M=N, need 'diag' mode, otherwise previous case)
% Vs = Mx3 array (M row vectors) , g = 3x3xN array (M=N)
% output: M vectors expressed in the crystal CS defined by g matrices
% output size: [M 3 M]
Yoann Guilhem
committed
%
% Version 001 17-10-2012 by YGuilhem
% Get number of vectors (M) and orientation matrices (N)
M = size(Vs, 1);
N = size(g, 3);
diag = false;
if ~exist('mode', 'var') || isempty(mode)
mode = [3 1 2];
elseif isnumeric(mode)
mode = mode(:).';
if size(mode, 2) ~= 3 || ~all(between(mode, ones(size(mode)), 3*ones(size(mode))))
gtError('gtVectorLab2Cryst:wrong_mode', ...
'Numeric mode should have 3 coordinates in [1 3]!');
end
elseif ischar(mode) && strcmp(mode, 'diag')
if M ~= N
gtError('gtVectorLab2Cryst:wrong_mode', ...
['''diag'' mode needs as many vectors as matrices!']);
end
diag = true;
Yoann Guilhem
committed
else
gtError('gtVectorLab2Cryst:wrong_mode', ...
['Unknown mode ''' mode '''!']);
Yoann Guilhem
committed
end
% Check input orientation matrices g size
if (~isreal(g))
gtError('gtVectorLab2Cryst:wrong_input_type', ...
'Wrong input g type, wait a 3x3xN real array!');
elseif (size(g, 1) ~= 3 || size(g, 2) ~= 3)
gtError('gtVectorLab2Cryst:wrong_input_size', ...
'Input array g should be sized 3x3xN!');
Yoann Guilhem
committed
end
% Check input vectors size
gtError('gtVectorLab2Cryst:wrong_input_size', ...
'Input array Vs should be sized Mx3!');
end
Yoann Guilhem
committed
% Transpose and reshape Vs
Vs = reshape(Vs.', [1 3 M]);
Yoann Guilhem
committed
% Multiply and sum along 2nd axis to reproduce Vc = g . Vs
%Vc = squeeze(sum(bsxfun(@times, Vs, g), 2));
Vc = squeeze(sum(Vs([1 1 1], :, ones(N, 1)).*g, 2)).';
Yoann Guilhem
committed
% % Transpose g to get gT, reshape it and expand it along 1st axis
% g = reshape(g, [1 3 3]);
%
% % Reshape Vs
% Vs = reshape(Vs, [M 1 3]);
%
% % Multiply and sum along 3rd axis to reproduce Vc = g . Vs
% Vc = sum(bsxfun(@times, g, Vs), 3);
Yoann Guilhem
committed
% Can be simply done with this formulae
Vc = (g * Vs.').';
Yoann Guilhem
committed
% Transpose and reshape Vc
Vs = reshape(Vs.', [1 3 M]);
Yoann Guilhem
committed
% Multiply and sum along 2nd axis to reproduce Vc = g . Vs
%Vc = squeeze(sum(bsxfun(@times, g, Vs), 2)).';
Vc = squeeze(sum(g.*Vs([1 1 1], :, :), 2)).';
Yoann Guilhem
committed
elseif (M > 1 && N > 1)
% % Transpose and reshape Vs
% Vs = reshape(Vs.', [1 3 1 M]);
%
% % Multiply and sum along 2nd axis to reproduce Vc = g . Vs
% Vc = permute(squeeze(sum(bsxfun(@times, g, Vs), 2)), mode);
Yoann Guilhem
committed
% Faster Version of the code in the comment
g_temp = reshape(permute(g, [2 1 3]), 3, [])';
Vc = g_temp * (Vs.');
Vc = reshape(Vc, 3, size(g, 3), []);
Vc = permute(Vc, mode);
Yoann Guilhem
committed
else
gtError('gtVectorLab2Cryst:wrong_input_size', ...
['Cannot handle the case where size(Vs)=' num2str(size(Vs)) ...
' and length(g)=' num2str(N)]);
end
end % end of function