jsonencode of state space model
2 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
I am trying to store data I need to persist between calls to a microservice in a Java HashMap. To do this, my data structure needs to be serialized/deserialized, and jsonencode/jsondecode seemed like a reasonable option (yes, I know about getByteStreamFromArray, but it's undocumented). One of the elements of my data structure is a state space model:
>> sys = ss(A,B,C,D)
ss with properties:
A: [4×4 double]
B: [4×1 double]
C: [0 0 0 1.9531e+03]
D: 0
E: []
Offsets: []
Scaled: 0
StateName: {4×1 cell}
StatePath: {4×1 cell}
StateUnit: {4×1 cell}
InternalDelay: [0×1 double]
InputDelay: 0
OutputDelay: 0
InputName: {''}
InputUnit: {''}
InputGroup: [1×1 struct]
OutputName: {''}
OutputUnit: {''}
OutputGroup: [1×1 struct]
Notes: [0×1 string]
UserData: []
Name: ''
Ts: 0.0167
TimeUnit: 'seconds'
SamplingGrid: [1×1 struct]
>> sys1 = jsondecode(jsonencode(sys))
struct with fields:
A: [4×4 double]
B: [4×1 double]
C: [4×1 double]
D: 0
E: []
Offsets: []
Scaled: 0
StateName: {4×1 cell}
StatePath: {4×1 cell}
StateUnit: {4×1 cell}
InternalDelay: []
InputDelay: 0
OutputDelay: 0
InputName: {''}
InputUnit: {''}
InputGroup: [1×1 struct]
OutputName: {''}
OutputUnit: {''}
OutputGroup: [1×1 struct]
Notes: []
UserData: []
Name: ''
Ts: 0.0167
TimeUnit: 'seconds'
SamplingGrid: [1×1 struct]
Now, this is really close, but not close enough:
>> u=ones(1,100);
>> out=lsim(sys,u);
>> out=lsim(sys1,u);
Error using lsim (line 93)
Not enough input arguments.
Is there a way on convincing MATLAB that sys1 is a "ss with properties" rather than a "struct with fields"? Preferably something more elegant than creating a new model and copying all the fields of the structure.
2 comentarios
Paul
el 14 de Abr. de 2025
Also, the encode->decode operation changes row vectors to column vectors, so you'll have to deal with that.
A = rand(4);
B = rand(4,2);
C = [0,0,0,1];
D = [1,2];
sys = ss(A,B,C,D);
sys1 = jsondecode(jsonencode(sys));
sys1.C
sys1.D
Interestingly enough, there is no problem if C and D are matrices
C = [0,0,0,1;0,0,0,2];
D = [1,2;3 4];
sys = ss(A,B,C,D);
sys1 = jsondecode(jsonencode(sys));
sys1.C
sys1.D
Is that a bug for the case where C and D are vectors?
Rik
el 14 de Abr. de 2025
This isn't a bug for vectors, but a quirk of the JSON standard. Since it only supports vectors, matrices are encoded as lists of vectors. Mathworks could have chosen to write column vectors as a list of lists, but that is uncommon and should probably be hidden behind an optional parameter, since the direction of vectors wouldn't matter in most applications where data is converted to JSON.
jsonencode([1 2 3])
jsonencode([1;2;3])
jsonencode([1 2;3 4])
You could write your own implementation of a JSON encoder of course. That is a lot harder than a JSON parser, but with a bit of dedication it is not too hard to cover most cases (it's the exceptions that will get you).
Respuestas (1)
Rik
el 14 de Abr. de 2025
A=rand(4);
B=rand(4);
C=[0 0 0 1.9531e+03];
D=0;
sys = ss(A,B,C,D);
sys_info = jsondecode(jsonencode(sys));
try
sys2 = ss(sys_info.A,sys_info.B,sys_info.C,sys_info.D);
catch ME
warning(['Because I don''t have a nice example, the assignment above doesn''t work.\n'...
'Instead, it fails with this error:\n%s'],ME.message)
sys2 = ss(A,B,C,D);
end
properties_list = fieldnames(sys_info);
for n=1:numel(properties_list)
% skip ABCD
if ismember(properties_list{n},{'A','B','C','D'}),continue,end
% copy over the property
sys2.(properties_list{n})=sys_info.(properties_list{n});
end
sys2
3 comentarios
Rik
el 14 de Abr. de 2025
I don't know about expected, but it isn't a full blown bug. You need a list of lists to force a column vector, and since that isn't really clean JSON, you wouldn't do that by default.
jsondecode('[[1],[2],[3]]')
It also assumes row-major matrix definitions (while the Matlab internal default is column-major).
A=zeros(2,2);
A(3)=1;
IsRowMajor = isequal(A,[0 0;1 0])
IsColumnMajor = isequal(A,[0 1;0 0])
Paul
el 15 de Abr. de 2025
- MATLAB does not guarantee that the shape of an array is preserved. For example, a 1-by-N numeric vector is encoded as an array. If you call jsondecode, then MATLAB decodes the array as an N-by-1 vector.
Ver también
Categorías
Más información sobre JSON Format en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!