Unrecognized function or variable 'datachk'?

Soryy for the long Description. I have prepared a target function for optimization and am using it to build contours for now. Here is a function (a shorten version) to pass parameters to the target function:
function y = OptimizeFilter(A0, f, x0)
A0Val = vpa(A0);
fVal = vpa(f);
xC1 = linspace(0.1, 1.9);
yR1 = linspace(0.1, 1.9);
[XC1, YR1] = meshgrid(xC1, yR1);
fun=@(xx,yy) Target([xx,1,yy,1]);
Z=arrayfun(fun, XC1, YR1,'uniformoutput',false); % 2 last params I put in w/o much understanding on MATLAB's hint
contour(XC1, YR1, Z);
function y = Target(x)
y = 0;
for i = 1:length(fVal)
aCurrent = AmplAndDers(x0(1), x0(2), x0(3), x0(4), fVal(i), x(1), x(2), x(3), x(4));
dev = aCurrent - A0Val(i);
y = y + dev^2;
end
end
end
-----------------------
AmplAndDers() was generated by MATLAB out for objective function and its derivatives (1st and 2nd). It starts with (94 lines long):
function Ampl = AmplAndDers(C1_0,C2_0,R1_0,R2_0,w,x1,x2,x3,x4)
t2 = C1_0.^2;
t3 = C2_0.^2;
t4 = R1_0.^2;
t5 = R2_0.^2;
t6 = w.^2;
t8 = x1.^2;
t9 = x2.^2;
t10 = x3.^2;
t11 = x4.^2;
t12 = C2_0.*R1_0.*x3;
...
It behaves reasonably if I call from Command Window:
OptimizeFilter([1.12511646 3.8376244], [2089.296131 7585.77575], [0.1e-6 1.5e-9 16000 11000]);
but not when I call:
OptimizeFilter(A_Init, f, [0.1e-6 1.5e-9 16000 11000]);
Instead of prompt response in first case, it took 11 mins before it failed:
Unrecognized function or variable 'datachk'.
Error in contour (line 46)
[pvpairs, ~, ~, errmsg, warnmsg] = matlab.graphics.chart.internal.contourobjHelper('parseargs', false,
args{:});
Error in OptimizeFilter (line 28)
contour(XC1, YR1, Z);
I have a suspicion that the problem might be some remnants of symbolic business persisting in AmplAndDers() because terminating the run I would see some references to symbolic scope like:
In ./ (line 366)
X = privBinaryOp(A, B, 'symobj::zipWithImplicitExpansion', 'symobj::divide');
In AmplAndDers (line 53)
Ampl = 1.0./sqrt(t46);
In OptimizeFilter/Target (line 58)
aCurrent = AmplAndDers(x0(1), x0(2), x0(3), x0(4), fVal(i), x(1), x(2), x(3), x(4));
In OptimizeFilter>@(xx,yy)Target([xx,1,yy,1]) (line 21)
fun=@(xx,yy) Target([xx,1,yy,1]);
In OptimizeFilter (line 24)
Z=arrayfun(fun, XC1, YR1,'uniformoutput',false);
Admittedly C1_0, C2_0, ... and x are syms in Workspace, but I do pass numeric values to AmplAndDers(). Is that a problem?

3 Comments

Please provide information about XC1, YR1, Z including their class and size.
All of them are not declared explicitly. The output for class() and size() for them:
XC1Class = 'double'
XC1Size = 100 100
YR1Class = 'double'
YR1Size = 100 100
The above sizes are set by meshgrid() itself.
ZClass = 'cell'
ZSize = 100 100
Lookng forward. Thanks.
I see. Walter Roberson addressed this below. Matlab's error message is certainly not helpful in understanding that the inputs are unexpected.

Sign in to comment.

 Accepted Answer

Z=arrayfun(fun, XC1, YR1,'uniformoutput',false); % 2 last params I put in w/o much understanding on MATLAB's hint
You use 'uniformoutput', false, which tells arrayfun that the output is a cell array.
ZClass = 'cell'
and that confirms it.
contour(XC1, YR1, Z);
so you are passing a cell array as the third parameter to contour(). However,
there are no syntaxes for contour() that permit you to pass a cell array as the third parameter.
If I read the code correctly it looks to me as if each of the outputs from the function would be a scalar, so I would expect it to work if you set 'uniformoutput', true

10 Comments

A0Val = vpa(A0);
fVal = vpa(f);
Why are you converting those to symbolic ?
When you apply vpa() to a numeric (such as double()) value, vpa() creates a software (symbolic) floating point number that approximates the numeric value. The result is symbolic, and using the result in expressions will force the output of those expressions to be symbolic.
When you apply vpa() to a symbolic expression, it will try to approximate the expression as a software (symbolic) floating point number. For example,
Pi = sym(pi)
Pi = 
π
foo = cos(Pi/7)
foo = 
vpa(foo)
ans = 
0.90096886790241912623610231950745
If you have int() expressions then vpa() will ask for symbolic numeric integration -- but since not all integrations converge, vpa() might not succeed, so the result of vpa() can still sometimes be calls to int() even if only one variable is involved.
If you want to convert a symbolic expression to double precision (hardware numbers instead of software numbers) then use double() and MATLAB will try. Again, it might not succeed even if only one variable is involved.
AmplAndDers() was generated by MATLAB out for objective function
You used matlabFunction(). matlabFunction() took your symbolic expression and created MATLAB source code from it; I can tell by what you posted that you asked matlabFunction() to write the code to a file. If you do not ask to write to file, then matlabFunction() uses str2func() to create an anonymous function from the MATLAB code it created; if you do ask to write to afile, then matlabFunction() creates a plain @ function handle instead of an anonymous function. Either way, MATLAB is executing inside the symbolic engine at the time the function handle is created, and so the debugging information that MATLAB associates with the function handle is information relevant to the lines of code inside the symbolic toolbox that created the function handle.
And that is why when you interrupt the function as it is executing, the debugging information shows the symbolic engine: because the handle was created inside the symbolic engine. This does not mean that the symbolic engine is used to execute the function: it just means there is an element of a datastructure that says "This function handle was created at line 1317 of such-and-such a function".
> Is there any way to discover what does the function do for so long
Yes. Run the profiler.
Before the section of code you'd like to time, add profile on and then after the section, add profile viewer to generate a report where time is spent within the section.
You need to not do
A0Val = vpa(A0);
fVal = vpa(f);
and instead
A0Val = double(A0);
fVal = double(f);
Your use of vpa() forced entire expressions to be calculated in software instead of in hardware. Software calculations are much slower.
Your AmplAndDers function is vectorized with respect to its inputs, unless there were int() or vpaintegral() or limits() (or possibly a couple of other functions) in which the input variables informed the boundaries... those situations do not automatically vectorize correctly.
So, you can probably do
function y = Target(x)
aCurrent = AmplAndDers(x0(1), x0(2), x0(3), x0(4), fVal, x(1), x(2), x(3), x(4));
dev = aCurrent(:) - A0Val(:);
y = sum(dev.^2)
end
Thanks, Walter. I am still tentative with MATLAB so I missed this elegant opportunity. Unfortunately, it did not improve the timing.
Thanks, Adam. I set a k counter and included this into the code:
if (k==1100)
profile on
end
if (k==1101)
profile viewer
end
Thus the captured profile is attached. I need better minds than mine to interpret it ;-)
That profile implies that you could speed up your computation if you close the workspace browser and directory browser views.
Wow! It runs twice faster now. Still not fast enough, I reckon. I will continue running and observing. Thanks.
Again: We are drifting away from the title topic. Should I start another Answer for the slow arrayrun()?
Yes, you should start a different Question about the slow arrayfun() . When you do, you should post all your current code.
The profile information you showed cannot be explained based upon the code you claim to be executing in this current Question, and every time I press you on that, you say that the parts I am noticing are no longer part of your code, so you need to present clean information to fresh eyes.
It will have to be a different volunteer that looks through it, though, as I am caught up on internal evidence that your code is not what you claim it to be, and you no longer trust my analysis.
"... , and you no longer trust my analysis." Walter, that's unexpected and regrettable because I do not trust anyone on MATLAB as much as I trust you. My apologies.

Sign in to comment.

More Answers (0)

Products

Release

R2021a

Community Treasure Hunt

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

Start Hunting!