0

So I have a class called agent with these following properties:

classdef agent < handle

       properties
       x 
       v
       goal
       v_pref
       end

Here, x and v are 1-by-2 vectors. Let's suppose that I have an n-by-1 object array where each part of the array contains instances of the class called agent. Currently, I am having trouble overwriting the assignment behavior of my code. Whenever I am doing something like this:

obj.x([1;3], 1) = [ 5; 3];

I want to overwrite object 1 and 3s 1st element of x with 5 and 3, respectively.

So essentially I want these commands to be equivalent as above

obj(1).x(1) = 5;
obj(3).x(1) = 3;

Is there a way to do this in matlab using subsasgn or any other overloading function.

mtber75
  • 938
  • 1
  • 8
  • 15
  • no its not. I tried what was suggested on that page and it did not work. – mtber75 Aug 10 '14 at 23:09
  • I managed to assign only one element to `x`: `[obj([1,3]).x] = deal(5,3)`. That overwrites `x` as a `1x1` double. – Yvon Aug 10 '14 at 23:24

1 Answers1

0

The problem with subsasgn and subsref:

>> obj([1,3])
ans = 
  1x2 agent array with properties:

    x
    v
    goal
    v_pref

>> obj([1,3]).x
ans =
     0     5
ans =
     0     3
>> obj([1,3]).x(2)
Scalar index required for this type of multi-level indexing. 
>> 

It seems Matlab isn't designed to handle this intention.

Also, with the following code:

S(1).type='()';
S(1).subs={1,3};
S(2).type='.';
S(2).subs='x';
S(3).type='()';
S(3).subs={2};

subsref(obj,S)

According to Mathworks' documentation, S(1).subs={1,3}; means to access obj(1,3), but not obj([1,3]). Changing it to S(1).subs={[1,3]}; also leads to the previous error.


Here's an alternative way.

Add this method to the class:

   methods
       function storex(obj,ind,x)
           if length(x) == 1
               x = repmat(x,length(ind),1);
           end
           for ii = 1:length(ind)
               obj(ind(ii)).x(2) = x(ii);
           end
       end
   end

and call it as

>> obj.storex([1,3],8)
>> obj.x
ans =
     0     8
ans =
     []
ans =
     0     8
>> obj.storex([2,3],[4,3])
>> obj.x
ans =
     0     8
ans =
     0     4
ans =
     0     3
>> 

Possible reference: "The expression a(:) does not produce a single output object, but rather a stream of them. MATLAB just hasn't been designed to apply two levels of indexing to a stream of them. It can do this a(:).b, but apparently not this a(:).b.c" https://www.mathworks.com/matlabcentral/newsreader/view_thread/245627

Yvon
  • 2,903
  • 1
  • 14
  • 36
  • Hmmm, is it possible to do this without for loops or array/cell fun? I was successful in making this with loops. However, the difficulty is doing this without any loops. I'm probably going to run this 1,000 times when my codes are fully developed and I would like to optimize the bases of my code as much as I can. – mtber75 Aug 11 '14 at 01:07
  • AFAIK even if you could find any way to implement this without a `for`, by calling other functions (either from 3rd party or built-in) you indirectly use `for`. As I understand, Matlab isn't designed in that way. – Yvon Aug 11 '14 at 01:11