Error: scalar cannot be indexed with

Hello,

Windows 10 (Octave 6.2.0)

I am trying to run the attached code, but it fails at line 51
Source code:
Black Hole simulation

Input parameters:

>> obs(1) = struct('type','fixed','r',2,'phi',pi/4,'pulsePeriod',0.5,'n',400) ;
>> obs(2) = struct('type','free','r',1.5,'phi',pi/4,'pulsePeriod',0.5,'n',400) ;
>> run_Schwarzschild(obs,8,[0 2.5 0 2.5])
error: scalar cannot be indexed with .
error: called from
    run_Schwarzschild at line 51 column 10

Not sure how to solve this? Did send to old e-mail link so apologies if duplicated.

Lester
run_Schwarzschild.m (6.8 KB)

The variable o assigned on line 42 is a handle not a struct, you should probably change that line to

o(k) = get (plot (...))

and access the field as

o(k).color

on line 51 to make this work …

Where did you get this code from? Is it supposed to work? Does it run in matlab?

c.

Hello,

Yes the code does run under Matlab, see hyperlink in message " Black Hole Simulation"

Schwarzschild black hole simulation - File Exchange - MATLAB Central (mathworks.com)

Lester

You may want to file a compatibility bug, then.

The issue is that plot seems to return a class object now in Matlab rather than a handle as it used to do in the past.

I was not aware of this change in Matlab, I don’t know if core developers are …

c.

Don’t file a bug. This is known behavior.

Matlab started out with a plotting system called “Handle Graphics”. When you call a plot function it would essentially return a pointer to the plot; And with this pointer you could read or write plot internal variables using the functions get and set.

Example Code:

x = 1:10;
y = x.^2;
h = plot (x, y);
% Reading a value
markerstyle = get (h, 'marker');
% Writing a value
set (h, 'marker', 's')

A few years ago Matlab completely re-worked their graphics system and it is now known as “Handle Graphics 2”. The return value from a plot command is no longer a handle but a graphics object (an instance of a class if you are familiar with object oriented programming). Properties of objects can be read or written using dot-notation. The same example above can now be written as

obj = plot (x, y);
markerstyle = obj.Marker;
obj.Marker = 's';

Matlab supports either style, while Octave only supports the first. You can get this code to work by simply replacing the object-oriented style with the get/set style. I only see three instances in the code so this would be easy.

Hello,

The code got a little further along with your suggestion get(o(k).'color'); code gets as far as line 91

>> run_Schwarzschild(obs,8,[0 2.5 0 2.5])
error: in indexed assignment of matrix, last lhs index must be ()
error: called from
    run_Schwarzschild at line 91 column 20

It does seem that there are compatibility issues with Matlab; no idea which version the original code is in.

Lester

Code should be get (o(k), 'color'). The dot . in your code should be a comma ,.

See if that helps.

Hello,

I checked the code and it was a comma:

h(k) = plot( obs(k).photons.X(:,2).*cos(obs(k).photons.X(:,3)) ,  obs(k).photons.X(:,2).*sin(obs(k).photons.X(:,3)) , '.' , 'Color' , get(o(k),'color')) ;

This leads to an error at line 91:

Line 91 o(k).XData = obs(k).x(2)*cos(obs(k).x(3)) ;
Line 92 o(k).YData = obs(k).x(2)*sin(obs(k).x(3)) ;

error: in indexed assignment of matrix, last lhs index must be ()

The graphics plot does progress further. I do not have Matlab to directly check this so it is very much trial and error

Thanks

Lester

To write data use the set command. Try

set (o(k), 'XData', obs(k).x(2)*cos(obs(k).x(3))) ;
set (o(k), 'YData', obs(k).x(2)*sin(obs(k).x(3))) ;

Tested the code update which gave the following:

>> run_Schwarzschild(obs,8,[0 2.5 0 2.5])
error: mx_el_eq: nonconformant arguments (op1 is 1x4, op2 is 1x5)
error: called from
    run_Schwarzschild at line 71 column 9

Line 71 if obs(k).type == "fixed"
72            %observer is at fixed r
73           obs(k).tau = obs(k).tau + dt*real(sqrt(1-1/obs(k).r)) ;

obs(1)
    type = fixed
    r = 2
    phi = 0.7854
    pulsePeriod = 0.5000
    n = 400

obs(2)
    type = free
    r = 1.5000
    phi = 0.7854
    pulsePeriod = 0.5000
    n = 400

obs(1 and 2) both have the same structure (1x5) so bit confused!

Quick update. Changed the following lines

for k=1:length(obs)
        %if obs(k).type == "fixed"
         if strcmp(obs(k).type,'fixed')==1
            %observer is at fixed r
            obs(k).tau = obs(k).tau + dt*real(sqrt(1-1/obs(k).r)) ;
        %elseif obs(k).type == "free"
         elseif strcmp(obs(k).type,'free')==2 

Now the error goes down to:

run_Schwarzschild(obs,8,[0 2.5 0 2.5])
error: =: nonconformant arguments (op1 is 402x1, op2 is 402x1)
error: called from
    run_Schwarzschild at line 104 column 12
A0 = sum( C_t.*obs(k).photons.V.*permute(obs(k).photons.V,[1 3 2]) , [2 3] ) ;
Line 104        obs(k).photons.V(:,2) = obs(k).photons.V(:,2) - dt*sum( C_r.*obs(k).photons.V.*permute(obs(k).photons.V,[1 3 2]) , [2 3] ) + dt*obs(k).photons.V(:,2).*A0;
        obs(k).photons.V(:,3) = obs(k).photons.V(:,3) - dt*sum( C_p.*obs(k).photons.V.*permute(obs(k).photons.V,[1 3 2]) , [2 3] ) + dt*obs(k).photons.V(:,3).*A0;

This Matlab code is certainly a challenge. The error does not make sense. Sorry for all the queries.

This makes sense. Matlab distinguishes between character vectors which use the single quote character ' for definition and strings which use the double quote " character for definition. Strings have an operator == defined for them, but character vectors do not so you need to use strcmp.

I think the remaining error is that the sum function in Octave takes just one dimension to sum over, while Matlab allows multiple dimensions to be specified. You can work around this by just calling sum twice. In the code on line 104 the summation is occurring across the 2nd and 3rd dimensions so I’m showing that replacement.

Matlab : sum (x, [2 3])
Octave : sum (sum (x, 2), 3)