Update matrix values inside MATLAB Function block
Ältere Kommentare anzeigen
Hi all!
I'm having trouble with updating a matrix inside a MATLAB function block. I'm trying to implement a Q-learning algorithm using only basic MATLAB and Simulink for vehicle control. When I try to update my Q-table, which I defined as a parameter in the MATLAB Function workspace, it gives me the following error:
'Expected either a logical, char, int, fi, single, or double. Found an mxArray. MxArrays are returned from calls to the MATLAB interpreter and are not supported inside expressions. They may only be used on the right-hand side of assignments and as arguments to extrinsic functions.'
My outside Simulink initialization code is:
%tuneable parameters
epsilon = 0.9;
epsilonDecayRate = 0.001;
epsilonMin = 0.01;
%sampleTime = 0.1;
gamma = 0.95;
Pedal = 10; %#
Steer = 30; %deg
%discretizing state and action space
discVx = [5 6 7 8 9 10 11 12 13 14 15];
discVy = [-5 -4.5 -4 -3.5 -3 -2.5 -2 -1.5 -1 -0.5 0];
discR = linspace(0,1,11);
discPed = linspace(0,1,Pedal+1);
discSteer = linspace(-200,100,(300/Steer)+1);
%skeleton arrays for search
actInfo = [];
for i=1:(Pedal+1)
for j=1:((300/Steer)+1)
actInfo(end+1,:) = [discPed(i) discSteer(j)];
end
end
numofacts = (Pedal+1)*((300/Steer)+1);
obsInfo = [];
for i=1:length(discVx)
for j=1:length(discVy)
for k=1:length(discR)
obsInfo(end+1,:) = [discVx(i) discVy(j) discR(k)];
end
end
end
numofstats = length(discVx)*length(discVy)*length(discR);
%Q-table
Q = zeros([numofstats numofacts]);
Q = randi([-5000 -3000],[numofstats numofacts]);
And the MATLAB Function is:
function [pedal,steer] = trainMyQtable(v_x, v_y, r, v_x_, v_y_, r_,...
reward, Q, obsInfo, actInfo, epsilon, epsilonDecayRate, epsilonMin,...
discVx, discVy, discR, lastPed, lastSteer, gamma)
%discretize and detect states
[dump,index1] = min(abs(discVx-v_x_));
[dump,index2] = min(abs(discVy-v_y_));
[dump,index3] = min(abs(discR-r_));
laststate = [discVx(index1);discVy(index2);discR(index3)];
[dump,index1] = min(abs(discVx-v_x));
[dump,index2] = min(abs(discVy-v_y));
[dump,index3] = min(abs(discR-r));
newstate = [discVx(index1);discVy(index2);discR(index3)];
lastObsIndx = ismember(obsInfo, laststate);
newObsIndx = ismember(obsInfo, newstate);
%update table value
actIndx = ismember(actInfo, [lastPed lastSteer]);
TD_error = reward + gamma * max(Q(newObsIndx,:)) - Q(lastObsIndx,actIndx);
Q(lastObsIndx,actIndx) = Q(lastObsIndx,actIndx) + alpha*TD_error;
%get action with exploration
choice = rand(1);
if choice > epsilon
pedal = randsample(actInfo(:,1),1);
steer = randsample(actInfo(:,2),1);
else
[~,newActIndx] = max(Q(newObsIndx,:));
[pedal,steer] = actInfo(newActIndx,:);
end
epsilon = max([epsilon*epsilonDecayRate epsilonMin]);
The problem is with the line
Q(lastObsIndx,actIndx) = Q(lastObsIndx,actIndx) + alpha*TD_error;
Can anyone give me a way to get around this issue? Or maybe a more clever way to implement a Q-table? Any insight would be appreciated. Thank you!
2 Kommentare
Mitchell Thurston
am 11 Dez. 2021
you might be able to declare Q as a fi type? I don't know enough about Q learning to say how you should design the table, but since the error says fi type is allowed, you could just declare Q like
Q = randi([-5000 -3000],[numofstats numofacts], 1, 32, 23);
Not sure what level of precision you need, but the "32, 23" gives single precision.
https://www.mathworks.com/help/fixedpoint/ref/embedded.fi.html
Szilard Hunor Toth
am 12 Dez. 2021
Akzeptierte Antwort
Weitere Antworten (0)
Kategorien
Mehr zu Speed Optimization finden Sie in Hilfe-Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!