How do I change a copy of a cell array without changing the original cell array?

I have a 1x2 cell array of two collisionBox objects.
I want to create a copy of the cell array and then change the Pose matrices in the collisionBox objects.
However, when I change the copy, the original changes as well.
How to create a copy of a cell array that is not linked to the original?
ws_ = ws;
ws_{1}{1}.Pose(1,4) = -ws{1}{1}.Pose(1,4);
ws_{1}{1}.Pose(3,4) = -ws{1}{1}.Pose(3,4);
ws_{1}{2}.Pose(1,4) = -ws{1}{2}.Pose(1,4);
ws_{1}{2}.Pose(3,4) = -ws{1}{2}.Pose(3,4);

6 Comments

Your code should not change anything inside ws. What makes you think it does?
This is what I'm getting. I would expect ws not to be changed. But it returns the same value as ws_.
>> ws{1}{1}.Pose
ans =
1.0000 0 0 -0.4800
0 1.0000 0 0
0 0 1.0000 -0.7800
0 0 0 1.0000
>> ws_ = ws;
ws_{1}{1}.Pose(1,4) = -ws{1}{1}.Pose(1,4);
ws_{1}{1}.Pose(3,4) = -ws{1}{1}.Pose(3,4);
>> ws{1}{1}.Pose
ans =
1.0000 0 0 0.4800
0 1.0000 0 0
0 0 1.0000 0.7800
0 0 0 1.0000
>> ws_{1}{1}.Pose
ans =
1.0000 0 0 0.4800
0 1.0000 0 0
0 0 1.0000 0.7800
0 0 0 1.0000
As you can see below, I'm unable to reproduce your issue in the latest release. If I can't reproduce it, I can't troubleshoot.
The only possible way I can think of, is if ws{1}{1} contains an object of a handle class, not a normal double. Then the Pose method could be used to modify/return the exact same array, leading to this behavior.
ws{1}{1}.Pose=eye(4);
ws{1}{1}.Pose(1,4)=-0.4;
ws{1}{1}.Pose(3,4)=-0.78;
ws_ = ws;
ws_{1}{1}.Pose(1,4) = -ws{1}{1}.Pose(1,4);
ws_{1}{1}.Pose(3,4) = -ws{1}{1}.Pose(3,4);
ws{1}{1}.Pose
ans = 4×4
1.0000 0 0 -0.4000 0 1.0000 0 0 0 0 1.0000 -0.7800 0 0 0 1.0000
ws_{1}{1}.Pose
ans = 4×4
1.0000 0 0 0.4000 0 1.0000 0 0 0 0 1.0000 0.7800 0 0 0 1.0000
Yes, ws{1}{1} contains a collisionBox object from Robotics System Toolbox.
>> class(ws)
ans =
'cell'
>> class(ws{1})
ans =
'cell'
>> class(ws{1}{1})
ans =
'collisionBox'
>> class(ws{1}{1}.Pose)
ans =
'double'
After learning that this is not cell array specific, but rather handle class specific, I found this workaround here
copyStream = getByteStreamFromArray(objToCopy);
objCopy = getArrayFromByteStream(copyStream);
Works for cel array as well.
This has indeed nothing to do with the cell. There are two fundamental kinds of variables: handle classes and data classes. A handle will only contain a pointer to the data itself, so copying the variable will only create a new pointer to the same data. Copying a data variable will create a copy of the data itself (although for memory efficiency Matlab uses a copy-on-write system where a variable is only actually duplicated when you change an element).

Sign in to comment.

Answers (0)

Asked:

on 28 Jun 2021

Commented:

Rik
on 29 Jun 2021

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!