Undefined function 'mtimes' for input arguments of type 'struct'
2 views (last 30 days)
Show older comments
If I'm correct, this error means that I'm trying to multiply a struct somewhere. But I'm not.
Here is the full error message:
The following error occurred converting from struct to Rays:
Undefined function 'mtimes' for input arguments of type 'struct'.
Error in Bench/trace (line 327)
rays( i + 1 ) = rays( i ).interaction( self.elem{ i }, out_fl );
Error in SRfunc (line 52)
rays_through = bench.trace( rays_in ); %0: include even rays that missed some elements on the bench
For context, I'm making a ray tracing model with the aid of Optometrika's ray tracing library. Since the error is happening when calling the interaction() function, I'll post that code too:
function rays_out = interaction( self, surf, out_fl )
% INTERACTION calculates rays properties after interacting with
% a Surface
% find intersections and set outcoming rays starting points
[ rays_out, nrms ] = self.intersection( surf );
rays_out.n = zeros(self.cnt * 2, 3); %preallocate direction vectors
% separate transmitted and reflected parts of the bundle
transmitted.I = rays_out.I(1:self.cnt);
transmitted.n = rays_out.n(1:self.cnt, :);
transmitted.nrefr = rays_out.nrefr(1:self.cnt);
reflected.I = rays_out.I(self.cnt+1 : end);
reflected.n = rays_out.n(self.cnt+1 : end, :);
reflected.nrefr = rays_out.nrefr(self.cnt+1 : end);
miss = transmitted.I < 0; % indices of the rays
% opposite = dot( self.n, nrms, 2 ) < 0;
% rays_out.I( opposite) = 0; %
med1 = surf.glass{1};
med2 = surf.glass{2};
% determine refractive indices before and after the surface
cs1 = dot( nrms, self.n, 2 ); % cosine between the ray direction and the surface direction
opp_rays = cs1 < 0; %self.nrefr == refrindx( self.w, med2 ); %cs1 < 0; % rays hitting the surface from the opposite direction
old_refr( ~opp_rays ) = refrindx( self.w( ~opp_rays ), med1 ); % refractive index before the surface
old_refr( opp_rays ) = refrindx( self.w( opp_rays ), med2 ); % refractive index before the surface
if strcmp( med2, 'mirror' )
new_refr = refrindx( self.w, med1 ); % refractive index after the surface
elseif strcmp( med1, 'mirror' )
new_refr = refrindx( self.w, med2 ); % refractive index after the surface
else
new_refr( ~opp_rays ) = refrindx( self.w( ~opp_rays ), med2 ); % refractive index after the surface
new_refr( opp_rays ) = refrindx( self.w( opp_rays ), med1 ); % refractive index after the surface
end
old_refr = old_refr';
if size( new_refr, 1 ) < size( new_refr, 2 )
new_refr = new_refr';
end
% calculate refraction
switch( class( surf ) )
case { 'Aperture', 'Screen', 'Retina' }
case { 'GeneralLens' 'AsphericLens' 'FresnelLens' 'ConeLens' 'CylinderLens' 'Plane' 'Lens' }
% calculate refraction (Snell's law)
reflected.n = self.n - 2 .* (repmat( cs1, 1, 3 ) .* nrms); %partial reflection
inside_already = ( ~miss ) & ( abs( transmitted.nrefr - old_refr ) > 1e-12 ); % rays that are already inside the surface (entered it previously)
transmitted.nrefr( ~miss ) = new_refr( ~miss ); % change refractive index of the rays that crossed the surface
reflected.nrefr = old_refr;
if strcmp( med1, 'mirror' ) || strcmp( med2, 'mirror' ) % if a mirror
transmitted.n = self.n - 2 .* (repmat( cs1, 1, 3 ) .* nrms); % Snell's law of reflection
%rays_out.nrefr = refrindx( self.w, med1 ); % refractive index before the surface
if strcmp( med1, 'mirror' ) && strcmp( med2, 'air' ) % mirror facing away
transmitted.I( cs1 > 0 & ~miss ) = 0; % zero rays hitting such mirror from the back
elseif strcmp( med1, 'air' ) && strcmp( med2, 'mirror' ) % mirror facing toward me
transmitted.I( cs1 < 0 & ~miss ) = 0; % zero rays hitting such mirror from the back
end
elseif strcmp( med1, 'soot' ) || strcmp( med2, 'soot' ) % opaque black
transmitted.I( ~miss ) = 0; % zero rays that hit the element
reflected.I( ~miss ) = 0; % zero rays that hit the element
else % transparent surface
rn = self.nrefr ./ transmitted.nrefr; % ratio of in and out refractive indices
cs2 = sqrt( 1 - rn.^2 .* ( 1 - cs1.^2 ) );
transmitted.n = repmat( rn, 1, 3 ) .* self.n - repmat( rn .* cs1 - sign( cs1 ) .* cs2, 1, 3 ) .* nrms; % refracted direction
tmp = cs1;
cs1( opp_rays ) = -cs1( opp_rays );
% calculate transmitted intensity (Fresnel formulas)
rs = ( rn .* cs1 - cs2 ) ./ ( rn .* cs1 + cs2 );
rp = ( cs1 - rn .* cs2 ) ./ ( cs1 + rn .* cs2 );
refraction_loss = ( abs( rs ).^2 + abs( rp ).^2 ) / 2;
transmitted.I( ~miss ) = ( 1 - refraction_loss( ~miss ) ) .* transmitted.I( ~miss ); % intensity of the transmitted rays
%handle partial reflection
reflected.I(~miss) = refraction_loss(~miss) .* reflected.I(~miss); %intensity of reflected parts
%return reflected and transmitted variables to
%rays_out struct
rays_out.I(1:self.cnt) = transmitted.I;
rays_out.n(1:self.cnt, :) = transmitted.n;
rays_out.nrefr(1:self.cnt) = transmitted.nrefr;
rays_out.I(self.cnt+1:end) = reflected.I;
rays_out.n(self.cnt+1:end, :) = reflected.n;
rays_out.nrefr(self.cnt+1:end) = reflected.nrefr;
end
otherwise
error( [ 'Surface ' class( surf ) ' is not defined!' ] );
end
% process rays that missed the element
if out_fl == 0 || strcmp( med1, 'soot' ) || strcmp( med2, 'soot' ) % if tracing rays missing elements or for apertures
% use the original rays here
rays_out.I( miss ) = self.I( miss );
rays_out.r( miss, : ) = self.r( miss, : );
rays_out.n( miss, : ) = self.n( miss, : );
else
% default, exclude such rays
rays_out.I( miss ) = 0;
rays_out.r( miss, : ) = Inf;
end
rays_out.I( isnan( rays_out.I ) ) = 0;
%rays_out.I( rays_out.n( :, 1 ) < 0 ) = 0; % zero rays that point back to the source
end
4 Comments
Guillaume
on 25 Jul 2018
That is very puzzling since there's no call to mtimes on the line that raises the error.
Have you tried dbstop if error ?
Answers (0)
See Also
Categories
Find more on Loops and Conditional Statements 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!