Forum: Digitale Signalverarbeitung / DSP / Machine Learning Fehlermeldung Matlab


von Tom Heinze (Gast)


Lesenswert?

Hallo zusammen.

Code:
function xest  = fcn(yk, x, xkm1)
....
for 1=1:1:k
   ...
   xest = xk;
   xkm1 = xk
   i = i+1;
end
end

liefert:
Data 'xest' (#61) is inferred as a variable size matrix, while its
specified type is something else.


Was bedeutet das?
und wie kann ich das beheben?

VG, Tom

von Markus B. (russenbaer)


Lesenswert?

Hallo,
Was willst Du tu, d.h. was ist die Absicht hinter dem Code?
Der Code schaut ziemlich sinnlos aus.
xest und xkm1 wird bei jedem Schleifendurchlauf von xk überschrieben.

lg

von Karl (Gast)


Lesenswert?

Wie wäre es mit dem vollständigen Code?

von Tom Heinze (Gast)


Lesenswert?

Markus B. schrieb:
> Hallo,
> Was willst Du tu, d.h. was ist die Absicht hinter dem Code?
> Der Code schaut ziemlich sinnlos aus.
> xest und xkm1 wird bei jedem Schleifendurchlauf von xk überschrieben.
>
> lg

Also ich möchte die drei Gleichungen des EKF (Extended Kalman Filter) 
implementieren.

Das war nur ein gedanklicher Erguss, schließlich gings ja um die 
Fehlermeldung.
n = 4;
R=0.0142^2; %Kovarianz des Messrauschen;
Q=0.005^2*eye(n); %Kovarianz des Systemrauschen
T = 0.02; %Sampletime

Der Code:
function [x_k, P_k]  = EKF(yk, xkm1, Pkm1, ukm1)
%Definieren der Jacobimatrix
J_k=@(xkm1)[0, 1, 0, 0; xkm1(1) xkm1(3) 1 0; sin(xkm1(2)) xkm1(4) 1 0; 1 
0 0 xkm1(1)*xkm1(2)];
I = eye(4)
Phi = I+T*F_k; %Transitionsmatrix (Taylorrehihe die nach lin. Glied 
abegbrochen wird)
H = [1 0 0 0]; %Messvektor
Ps_k = Phi*Pkm1*Phi'+Q; % Prädiktive Kovarianzmatrix
K_k = Ps_k*H'*inv(H*Ps_k*H'+R); %Kalman Matrix
P_k = (eye(4)-K_k*H)*Ps_k*(eye(4)-K_k*H)'+K_k*R*K_k'; %Korrigierte 
Kovarianzmatrix
x_k = Phi*xkm1+H*ukm1 + K_k*(yk-H*Phi*xkm1-H*1*ukm1); % korrigierter 
Zustandsvektor
end

Dieser Ansatz führt gleich auf mehrer Probleme.

Zb Bei der Funktion J. Diese kann nicht mit einer Matrix verrechnet 
werden, muss aber in jedem Abtastschritt neu berechnet werden.

Anforderungen:
Ich brauche eineFunktion f die Abhängig ist von den Zustandgrößen. 
Hiermit wird die Jacobi-matrix bestimmt (in jedem Schritt). Damit lässt 
sich zunächst im Prädiktoschritt eine Kovarianzmatrix berechnen. 
Weiterhin die Kalmanmatrix. Anschließend kann die korrigierte Kovarianz 
und der korrigierte Zustandsvektor bestimmt werden.

von Markus B. (russenbaer)


Lesenswert?

Hallo,

Ohne mich jetzt in die Gleichungen einlesen zu wollen:
1
J_k=@(xkm1)[0, 1, 0, 0; xkm1(1) xkm1(3) 1 0; sin(xkm1(2)) xkm1(4) 1 0; 1 0 0 xkm1(1)*xkm1(2)];
Definiert eine anonyme Funktion in Matlab. Wenn Du eine Matrix haben 
wills die Elemente von xkm1 verwendet:
1
J_k=[0, 1, 0, 0; ...
2
    xkm1(1), xkm1(3), 1, 0; ...
3
sin(xkm1(2)), xkm1(4), 1, 0; ...
4
 1, 0, 0, xkm1(1)*xkm1(2)];
Die anonyme Funktion wird in Deinem weiteren Code nicht aufgerufen bzw. 
J_k wird nirgends verwendet...
1
T, F_k, Q, R
 fallen vom Himmel, d.h. die werden Deiner Funktion nicht übergeben bzw. 
in Deiner Funktion weder definiert noch initialisiert.
1
x_k = Phi*xkm1+H*ukm1 + K_k*(yk-H*Phi*xkm1-H*1*ukm1); % korrigierter Zustandsvektor
Im letzten Teil dieser Zeile gibts was unnötiges:
1
*1*

Mit dem normalen * werden immer Matrixmultiplikationen ausgeführt. Falls 
Du elementeweise multiplizieren bzw. dividieren wills muss .* bzw ./ 
verwendet werden. Dabei müssen die Matrizen exakt die gleiche Dimension 
haben.


lg

von Tom Heinze (Gast)


Lesenswert?

Inzwischen habe ich eine Lösung mit Hilfe symbolischer Variablen 
gefunden.

Allerdings bekomme ich dann:

The function 'syms' is not supported for standalone code Generation.

Um die Fragestellung nochmals auf den Punkt zu bringen.

Ich benötige ein Programm, dass beginnend mit einem Startvektor x0 = 
[x10 x20 x30 x40]'

Die Ableitung der Vektorunktion f an der Stelle x0 berechnet 
(Jacobimatrix).

Habe ich mit einer externen Funktion gelöst.

Nun soll mit dieser die Kovarianzen etc berechnet werden.

Nur der Startvektor ist das Problem, weil ich den ja nur beim ersten 
Schritt brache.

Die Variablen xkm1 usw. kommen vom Modell als Eingangsgrößen. das ist 
eine Matlab-Function

von Karl (Gast)


Lesenswert?

Falls Du Dich wunderst warum nur spärliche Hilfe kommt, könnte es daran 
liegen, dass Du Dein Problem nicht klar beschreibst.
Kenne mich zwar nicht sonderlich mit den Sachen aus die Du machen 
möchtest, aber Matlab kann ich ganz passabel. Bitte vollständiges M-File 
das den Fehler reproduziert, wenn Du Hilfe möchtest.

von Tom Heinze (Gast)


Lesenswert?

Karl schrieb:
> Falls Du Dich wunderst warum nur spärliche Hilfe kommt, könnte es
> daran
> liegen, dass Du Dein Problem nicht klar beschreibst.
> Kenne mich zwar nicht sonderlich mit den Sachen aus die Du machen
> möchtest, aber Matlab kann ich ganz passabel. Bitte vollständiges M-File
> das den Fehler reproduziert, wenn Du Hilfe möchtest.

M-File Steht oben...

Das Problem ist wie folgt zu erläutern.

ich möchte eine Funktion f, die eine nicht-lineare Funktion des 
Zustandsvektors x(t) und des Eingangsgrößenvektors u(t) ist, 
differenzieren.

Die Funktion f sei zB. folgender Form:

Nun soll die Funktion f in jedem Schritt k differenziert werden, und 
zwar am zugehörigen Zustansvektor x_k.

Das ist der Hauptpunkt der Berechnungen.

Ich habe es so versucht

function J = Jacobi(x)
coder.extrinsic('syms')
%Parameter
...

syms x1 x2 x3
f = ...

J = subs(jacobian(f), [x1 x2 x3],x)
end

von Jan K. (jan_k)


Lesenswert?

Willst du symbolisch oder numerisch rechnen? Ich schätze letzteres, 
daher lass das mit dem syms!

Soll das was in Simulink werden?

Oben schreibst du was davon, dass die Startwerte nicht initialisiert 
sind. Warum tust du das dann nicht? Ist es Simulink? Da kann man für 
Blöcke/Parameter normalerweise Startwerte angeben.

Ist es "normales" Matlab: Entweder Startwerte von außen initialisieren, 
oder in der Funktion behandeln und den ersten Aufruf von darauf 
folgenden unterscheiden. Mit exist() und isempty() findest du heraus, ob 
die Variablen schon existieren...

von Tom Heinze (Gast)


Lesenswert?

Jan K. schrieb:
> Willst du symbolisch oder numerisch rechnen? Ich schätze
> letzteres,
> daher lass das mit dem syms!
>
> Soll das was in Simulink werden?
>
> Oben schreibst du was davon, dass die Startwerte nicht initialisiert
> sind. Warum tust du das dann nicht? Ist es Simulink? Da kann man für
> Blöcke/Parameter normalerweise Startwerte angeben.
>
> Ist es "normales" Matlab: Entweder Startwerte von außen initialisieren,
> oder in der Funktion behandeln und den ersten Aufruf von darauf
> folgenden unterscheiden. Mit exist() und isempty() findest du heraus, ob
> die Variablen schon existieren...

Es ist sowohl Matlab(M) als auch Simulink(Si). Ich habe eine 
Matlab-function in mein Si-Modell eingebunden. mir ist es egal ob 
numerisch oder symbolisch. Symbolisch müsste dann irgendwann ersetzt 
werden durch die entsprechenden numerischen Werte.

Es muss on jedem k-ten Schritt der insgesamt 1001 Schritte die 
Jacobimatrix berechnet werden. Dann die übrigen Matrizen. Eigentlich ist 
es nur gefordert einige Startwerte einzulesen und anschließend mit den 
kontinuierlich geschätzten werten weiter zu rechnen.

von Jan K. (jan_k)


Lesenswert?

Okay, du brauchst die partiellen Ableitungen nur von den Zuständen, 
nicht von der Zeit? Bin mir nicht sicher, ob das numerisch Sinn macht, 
du brauchst ja definitiv "Umgebungswerte" deiner Funktion zum 
numerischen Ableiten. 
http://www.mathworks.com/matlabcentral/fileexchange/13490-adaptive-robust-numerical-differentiation 
Ist jedenfalls eine Toolbox, mit der du experimentieren könntest.

Wenn sich die Funktion aber nicht ändert, wieso berechnest du die 
Jacobian nicht analytisch vorab und baust sie in Simulink ein? Dafür 
gibts hier 1, 2 nützliche Funktionen, damit du das nicht abtippen musst: 
https://www.mathworks.com/help/symbolic/code-generation.html

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.