jsonencode of state space model
조회 수: 2 (최근 30일)
이전 댓글 표시
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
Paul
2025년 4월 14일
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
2025년 4월 14일
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).
답변 (1개)
Rik
2025년 4월 14일
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
Rik
2025년 4월 14일
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
2025년 4월 15일
- 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.
참고 항목
카테고리
Help Center 및 File Exchange에서 JSON Format에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!