フィルターのクリア

How to avoid non-constant expression in MATLAB coder (recursive cell reassignment)

8 ビュー (過去 30 日間)
I'm working on a state-space cascading function for filters. Ideally the filter code I am writing will be suitable for MATLAB coder as the reason I wrote it was because butter() is not compatible. When trying to build the .mex file I encounter the error:
Non-constant expression or empty matrix. This expression must be constant because its value determines the size or class of some expression.
Here is my code
function [Ac,Bc,Cc,Dc] = cascadeSSM(A,B,C,D, nCascs)
% CASCADESSM A function to cascade linear state-space matrices for the
% purpose of cascading filters etc.
%
% Author: Ben Holmes
% Date: 2018/05/19
% License: GPL V3
%
% This function is derived from the answer
% https://math.stackexchange.com/questions/2201067/cascade-of-state-space-models-for-linear-systems
% From user
% https://math.stackexchange.com/users/506682/arash
%
% Inputs:
% - A,B,C,D are cell matrices where each cell is a matrix to cascade
%
% Outputs:
% - Ac, Bc, Cc, Dc are the resultant cascaded matrices of default numeric
% type.
% Make sure that each cell matrix is of the same length, i.e. there are the
% same number of matrices to cascade of A, B, C, and D.
if length(A) ~= length(B) || length(A) ~= length(C) || length(A) ~= length(D) || length(A) ~= nCascs
error('There must be the same number of each matrix');
end
% The algorithm operates in place, removing matrices from the cell matrix
% and then exiting when they have all been cascaded.
if nCascs > 1
[Ac, Bc, Cc, Dc] = recursiveCascade(A,B,C,D, nCascs);
else
% Don't cascade, just output.
% Useful for when you want to sometimes cascade and sometimes not.
Ac = A{:};
Bc = B{:};
Cc = C{:};
Dc = D{:};
end
end
function [Ac, Bc, Cc, Dc] = recursiveCascade(A, B, C, D, nCasc)
[Ac, Bc, Cc, Dc] = cascadeOnce({A{1} A{2}}, {B{1} B{2}},...
{C{1} C{2}}, {D{1} D{2}});
if length(A) >= 3
[Ac, Bc, Cc, Dc] = recursiveCascade({Ac, A{3:nCasc}}, {Bc, B{3:nCasc}}, {Cc, C{3:nCasc}}, {Dc, D{3:nCasc}}, nCasc-1);
end
end
function [Ac, Bc, Cc, Dc] = cascadeOnce(A, B, C, D)
Ac = [A{1} zeros(size(A{1},1), size(A{2},2)); B{2}*C{1} A{2}];
Bc = [B{1}; B{2}*D{1}];
Cc = [D{2}*C{1} C{2}];
Dc = D{2}*D{1};
end
The issue happens in the calculation of zeros(size(A{1},1), size(A{2},2)) in cascadeOnce due to A{3:nCasc} in the call to recursiveCascade.
I've been trying to figure out ways of rewriting the code such that it is coder compatible but this has me stumped. Initially it was written as in this gist, but this failed with Coder due to reassigning matrix sizes, which is why it is now written recursively.
Thanks for any help on the issue.

採用された回答

Walter Roberson
Walter Roberson 2018 年 5 月 19 日
You might have to initialize the variables in cascadeOnce with constant size and then trim them down according to the data requirement on the call.
Alternately you could possibly configure for dynamic memory.
  1 件のコメント
Ben Holmes
Ben Holmes 2018 年 5 月 20 日
I didn't quite get the configuring for dynamic memory as I thought that was set in the Coder app settings. Doing a bit more reading however I found that simply by adding coder.varsize('Ac',[100 100]), i.e. setting all matrices to be up to 100x100 I could get the code to build. This wasn't the only step, there was a bit of trial and error but it does work now!
I can't get the formatting to work properly in this comment so I'm going to leave this link to my gist.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeMATLAB Coder についてさらに検索

製品


リリース

R2017b

Community Treasure Hunt

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

Start Hunting!

Translated by