Problems calling fminsearch (not enough input arguments)

3 views (last 30 days)
I have an LED that is pulsing on and off to transmit data. I want to process the waveform received by a photodiode into 0s and 1s and measure the number of errors compared to what was actually transmitted.
To do this, first I specify a threshold voltage. Any sample below this threshold is a 0, and any sample equal or greater than this is a 1. This converts the waveform into a sequence of 0s and 1s. Secondly, I sample this sequence at particular intervals to find a sequence of 0s and 1s to compare to the transmitted signal. These intervals are determined by the rising edge of master clock signal – I have included the option to add an offset to this (so, e.g. instead of using samples 10, 20, 30…, using an offset of 5 then samples 15, 25, 35 would be used instead). So far I have it working when you manually enter guesses for the threshold (“th_Rx”) and an offset (“Rx_offset”). Adjusting the values of th_Rx and Rx_offset will yield different numbers of errors, i.e. there is some optimum value of th_Rx and Rx_offset that will give the minimum number of errors. I would like to automate that, so Matlab will try to find this optimum, rather than relying on manual guesswork.
I’m trying to use fminsearch to find values of th_Rx and Rx_offset that give the lowest number of errors (“nerrs”). I have a function, “BER_optimise” that will output the number of errors when I manually enter values for th_Rx and Rx_offset, but I can’t get this to work with fminsearch. Here’s the function (there are a few lines I’ve omitted where I read in “rx”, “ook” and “sample_times” from the base workspace using “evalin”):
function n_errs = BER_optimise(th_Rx, Rx_offset) % Function uses input arguments th_MISO_Rx and Rx_sample_offset, and outputs the number of errors (n_errs)
%Threshold the LED waveform
rx(rx<th_Rx) = 0; % Set all values below thresh to 0
rx(rx>th_Rx) = 1; % Set all values above thresh to 1
rx(rx==th_Rx) = 1; % Set all values equal to thresh to 1
% Sample the thresholded waveform
Rx_sig = MISO_Rx_th(sample_times+Rx_offset);
% Compare Rx_sig with actual transmitted data, find # of errors
[nerr, ber] = biterr(ook,Rx_sig);
n_errs = nerr
If I use this function in the command window, it works, e.g. : entering “BER_optimise(0.01,10);” displays “n_errs = 0” However, when I try to implement this in my main script, using fminsearch to try to optimise the values for “tx_Rx” and “Rx_offset” I get an error. The line calling fminsearch is:
output = fminsearch(BER_optimise,x0);
Where x0 is a variable containing some starting guesses. The error I get is:
*Not enough input arguments.
Error in BER_optimise (line 7) rx(rx<th_MISO_Rx) = 0; % Set all values below thresh to 0 Error in Mainscript (line 79) output= fminsearch(BER_optimise,x0);*
Can anyone suggest what I might be missing here? Thanks in advance

Answers (2)

Star Strider
Star Strider on 18 Apr 2016
The fminsearch (and many other functions) want vectors as arguments. I can’t run your code, so I can only offer a possible solution for you to experiment with:
output = fminsearch(@(prms) BER_optimise(prms(1), prms(2)),x0);
Star Strider
Star Strider on 19 Apr 2016
The ‘perms’ variable creates a vector to pass to fminsearch. I created a second anonymous function:
@(prms) BER_optimise(prms(1), prms(2))
that ‘nests’ your function in a form that fminsearch can use. This is a common approach to such problems.
See the documentaiton for ‘Anonymous Functions’ in Function Basics for details on them.
See the documentation on fminsearch for details on the sort of function argument it requires.
See the link Torsten posted on parameterising functions.

Sign in to comment.

DK on 28 Dec 2020
I may not understand parameterizing function. But can you see the code, and why it has the same error above?
function rresult = calibgrain(DBn_2,dateob,Tb)
dss = linspace(0.01,3,100);
ggf = linspace(0.5,5,100);
rresult = [];
for ii = 1:length(dss)
for jj = 1:length(ggf)
dsnowi = dss(ii);grfactor = ggf(jj);
startparms = [dsnowi, grfactor];
%rosen = @RMSE1 RMSE1(startparms);
%fminsearch(@(prms) BER_optimise(prms(1), prms(2)),x0)
bestparms = fminsearch(@(parms) RMSE1(parms), startparms);
%bestparms = fminsearch(@RMSE1,RMSE1(startparms)); %fminsearchbnd(@(x) f(x,c),[0.3;1], [0 0],[5 5])
dsnowi = bestparms(1);
grfactor = bestparms(2);
[dsns_2,lws,btotals,phis,dsnows_y2_r1,tsnows,sds_0,kss,tsss,gds,outmelts,YEH,YEV,YEVH, YEHV,result,compaction,ritisi,stor,ro] = msnow(1,6552,DBn_2,dsnowi,grfactor);
rmsecomp = calcrmse(YEH,dateob,Tb);
rresult = [rresult ;dsnowi grfactor rmsecomp];
end % end of jj loop
end % end of ii loop
function thisrmse = RMSE1(parms)
% nest this function inside calibgrain so that it has
% access to all of calibgrain's variables.
dsnowi = parms(1);
grfactor = parms(2);
[dsns_2,lws,btotals,phis,dsnows_y2_r1,tsnows,sds_0,kss,tsss,gds,outmelts,YEH,YEV,YEVH, YEHV,result,compaction,ritisi,stor,ro] = msnow(1,6552,DBn_2,dsnowi,grfactor);
thisrmse = calcrmse(YEH,dateob,Tb);
end % end of function RMSE1
end % end of function calibgrain


Find more on Programming 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!