Undefined function 'mtimes' for input arguments of type 'struct'
2 次查看(过去 30 天)
显示 更早的评论
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 个评论
Guillaume
2018-7-25
That is very puzzling since there's no call to mtimes on the line that raises the error.
Have you tried dbstop if error ?
回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Loops and Conditional Statements 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!