Update matrix values inside MATLAB Function block
Show older comments
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 Comments
Mitchell Thurston
on 11 Dec 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
on 12 Dec 2021
Accepted Answer
More Answers (0)
Categories
Find more on Speed Optimization in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!