jsonencode of state space model
2 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
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 Commenti
Paul
il 14 Apr 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
il 14 Apr 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).
Risposte (1)
Rik
il 14 Apr 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 Commenti
Rik
il 14 Apr 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
il 15 Apr 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.
Vedere anche
Categorie
Scopri di più su JSON Format in Help Center e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!