error using parallel.p​ool.consta​nt/get value MATLAB (parallel computing toolbox) - matlab

so this is my code (not sure about function handle in parfeval). The error I get is on line 11. I dont understand the error
poolobj=parpool('my_cluster',8);
[up, op]=ndgri(1e-3:1e-2:1,1e-3:1e-2:1);
up=reshape(up, [1,size(up,1)*size(up,2)]);
up=reshape(up, [1,size(up,1)*size(up,2)]);
z=rand(5,5e3);
addAttachedFiles('<path to my function/cores_random.m');%%to add the function files to workers on the pool
C1=parallel.pool.Constant(z);%%use parallel.pool.Constant to copy these variables into workers
U2=parallel.pool.Constant(up);
O2=parallel.pool.Constant(op);
for i=1:size(up,2)
f1(i)=parfeval(poolobj,#cores_random,3,U2.value(i),O2.Value(i),C1.Value(1,:)); %%line 11
f2(i)=parfeval(poolobj,#cores_random,3,U2.value(i),O2.Value(i),C1.Value(2,:));
f3(i)=parfeval(poolobj,#cores_random,3,U2.value(i),O2.Value(i),C1.Value(3,:));
f4(i)=parfeval(poolobj,#cores_random,3,U2.value(i),O2.Value(i),C1.Value(4,:));
f5(i)=parfeval(poolobj,#cores_random,3,U2.value(i),O2.Value(i),C1.Value(5,:));
end
for j=1:size(up,2):-1:1
[idx1,u1,o1,ep1]=fetchNext(f1);
[idx2,u2,o2,ep2]=fetchNext(f2);
[idx3,u3,o3,ep3]=fetchNext(f3);
[idx4,u4,o4,ep4]=fetchNext(f4);
[idx5,u5,o5,ep5]=fetchNext(f5);
end
I got an error
{Error using paralle.pool.Constant/get.Value The value of a parallel.pool.Constant is only available on the workers.
Error in main_parallel_norm (line 11)
f1(i)=parfeval(poolobj,#cores_random,3,U2.value(i),O2.Value(i),C1.Value(1,:));
the function cores_random is as the following:
[uu,oo,ep]=cores_random(up,op,z)
%%doing some calculations here
%%z is of size 1*1e3
%%up is scalar op is scalar
end

As the error message states, the Value property of a parallel.pool.Constant is available only on the workers. As written, your parfeval requests are trying to access it on the client. Briefly, your code looks like this:
c = parallel.pool.Constant(42);
f = parfeval(pool, #myFcn, 1, c.Value);
This forces the client to evaluate c.Value when setting up the parfeval call.
What you should do instead is pass the Constant itself into the parfeval request, and then access the Value field on the workers. One way to do that is like this:
c = parallel.pool.Constant(42);
f = parfeval(pool, #(const) myFcn(const.Value), 1, c);
This ensures that the const.Value expression is only evaluated on the workers. (Alternatively, you could modify myFcn to know that it needs to call const.Value on its input arguments.)

Related

Informative feedback from assert with matrices in Matlab

Does there exist a simple function in Matlab that will give more informative feedback when using assert with matrices than the simple application of the assert function?
My simple application is:
>> assert(all([1 2; 3 4] == [1 2; 3 5], 'all'))
Assertion failed.
In Python, with numpy.testing.assert_equal the feedback from a failed assertion shows the two arrays.
I guess it would be possible to define further the arguments to the assert function errmsg, value1 and value2.
assert is to validate intermediate values inside your code, so you get an error when something is not as you expect, and you can debug it. This is the “fail early” philosophy. You don’t need to get a detailed output here, it tells you that you need to break out the debugger.
Your use case seems closer to testing the output of a function, to verify it works as intended. This is a very different use case, for which MATLAB has the testing framework.
For example, your equality comparison would be implemented through verifyEqual:
testCase = matlab.unittest.TestCase.forInteractiveUse;
verifyEqual(testCase,A,B)
Here's one of the many ways assert can be used in conjunction with the try/catch and throw commands to catch errors and take specific actions (e.g. print a message and throw an exception that can be captured by the calling function:
function out = myfun(A, B)
out = 0;
try
assert(all(size(A)==size(B)), 'Matrix sizes do not match')
catch exc % contains the message passed by assert
fprintf('Size of A is: %d, %d\n',size(A)); % show the actual dimensions
fprintf('Size of B is: %d, %d\n',size(B));
out = 1;
throw(exc) % throws exc and returns control to the caller
end
try
assert(isequal(A,B), 'Matrix are not identical.')
catch exc % contains the message passed by assert
disp(A==B) % show 0 where elements don't match
out = 1;
throw(exc) % throws exc and returns control to the caller
end
end
Calling myfun with A=ones(4,4) and B=ones(4,5) produces the following output:
Calling myfun with A=ones(4,4) and B=2*ones(4,4) leads to:
As I mentioned at the very beginning, the function above represent one of the possible implementations.

Operations with function handle in matlab

Could you please help me with the following issue: I have the following function handle:
r1 = #(lambda) b + lambda*(r - b); % r and b are vectors of return data
I want to find the optimal lambdas that set me a mean function to zero, for a given set of powers within that function. What I tried to do and didn't work, as it returns me an error for undefined operators for input arguments of type 'function_handle' is:
lambda0 = 0.3;
for a = 2:10 %power coefficient
S1(a) = fzero(mean((r - b)*r1.^(1/(a - 1))),lambda0);
end
Any suggestion as to how to go about this problem is highly appreciated! Thank you in advance.
fzero accepts a function handle as the first input. As you currently have it, you're trying to pass a statement as the first input. This statement can't even be properly evaluated because you are trying to perform numerical operations on a function handle (more on this in a bit).
You need to instead do something like this where we create a new function handle that evaluates the original function handle and performs the other operations you need.
S1(a) = fzero(#(lambda)mean((r - b)*r1(lambda).^(1/(a - 1))),lambda0);
Further Explanation
Performing operations on a function handle is not the same as performing them on the result.
So for example, if we had a function handle:
func = #(x)2*x;
If we evaluation this, by calling it with an input value for x
func(2)
4
This works as we would expect. If now we really want the value (2*x)^2, we could try to write it the way that you wrote your statement in your question
func2 = func^2;
We will get an error!
Undefined operator '^' for input arguments of type 'function_handle'.
This does not work because MATLAB attempts to apply the ^ operation to the function handle itself and not the value of the evaluated function handle.
Instead, we would need to create a new function handle that essentially wraps the other one and performs any additional options:
func2 = #(x)func(x)^2;
func2(2)
16
Bringing it Full-Circle
So if we go back to your question, you defined your anonymous function r1 like this.
r1 = #(lambda) b + lambda*(r - b); % r and b are vectors of return data
This all looks great. You have one input argument and you reference r and b from the parent workspace.
Now when you call fzero you try to perform operations on this function handle in hopes of creating a new function handle.
mean((r - b)*r1.^(1/(a - 1)))
Like we just showed this will result in a very similar error
Undefined operator .^ for input arguments of type 'function_handle'
So we need to wrap this into a new function.
newfunc = #(lambda)mean((r - b)*r1(lambda).^(1 / (a - 1)));
Now we can safely pass this to fzero.
result = fzero(newfunc, lambda0);

MatLab function, variable output

function [ muln, varargout ] = my_mul( varargin )
%MY_MUL This function is used to multiply numbers.
% My_mul function multiplies array of entered numbers, and outputs single
% solution.
% For example: my_mul(12, 2, 3, 5) gives ans = 360
if nargout >=1
disp('Error, wrong number of output arguments');
varargout{1} = 0;
return
end
if nargin <= 1
disp('Error, small number of input argumnets');
return
else
muln = 1;
for i = 1:nargin
muln = muln*varargin{i};
end
end
end
Hi, everyone, I'm just doing my assignment for uni and have a qiuck question.
How can I make this function to give an error if it is called with more than one output.(It meant to give only one) Thanks!
In your function definition, you have defined your function to allow for an unlimited number of outputs. The keyword varargout is a place-holder for a variable number of outputs.
As you have stated in your question, you only want one possible output which in your case looks to be muln. So if you simply remove varargout from your function definition, MATLAB should automatically throw an error if too many outputs are requested
function muln = my_mul(varargin)
If you ever do need to use varargout but want to place constraints on how many outputs are provided for any given scenario, you can check the number of output arguments that were requested using nargout and then throw an error with the error function.
if nargout > 4
error('my_mul:TooManyOutputs', 'Too many outputs requested');
end
My opinion is that if a return value is expected the function needs to throw. Otherwise the caller (function calling this function) will expect everything to be ok. Note that disp('Error') gives information to the developer, but it does not give the program any indication on what happens. More importantly, the information does not give any indication of where the error occurs. This can force the developer to do heavy debugging just to find the error, which is completely unnecessary.
The use of variable output arguments should only be used in case a different number of output arguments should be expected. An example is some customized plot function
function varargout = myplot(varargin)
filename = '';
idx = find(strcmp(varargin,'filename'));
if (~isempty(idx) && length(varargin)<idx+1 && ~ischar(varargin{idx+1}))
error('filename property must be followed by a directory');
elseif(~isempty(idx))
filename = varargin{idx+1};
varargin([idx,idx+1]) = [];
end
h = plot(varargin{:});
varagout{1} = h;
if (~isempty(idx))
save(filename, h);
end
varagout{2} = filename;
This function works as plot except it saves the figure to file in case a filename is specified. In case the developer needs the handle it will be returned and in case the developer wants the save directory it can be returned as well. None of these arguments are necessary though. The developer may want to use this function as a standard plot function and this means that the user may want to call myplot as myplot(x,y);which does not return a value. Further note that even if 'filename' is not specified, the function can still return 2 outputs. The second output may be an empty array of char, but two outputs for the caller will never cause a crash.
Also, note that no further error handling is required. The only unchecked crashes are in plot and save. How this is handled may be different for different users and this means that it only is reasonable to let the user catch the error and handle it (as he would have done if save or plot would have thrown).
Apart from this you may also want to have a check so that the number of output variables are within the correct range (in this case 0,1 or 2 outputs).

Not enough input arguments when calling GA toolbox

I called Matlab's genetic algorithm solver, ga, in the following way:
[theta,fval,exitflag] = ga(smmobj,26,[],[],[],[],LB,UB,[],[]);
where theta is a 26-by-1 column vector that needs to be optimized.
So in the main function, it goes like this:
clc
clear
global var1 var2...
load ('abcd.mat')
theta0=[1 2 3....];
LB=[26-by-1 row vector];
UB=[26-by-1 row vector];
[theta,fval,exitflag] = ga(smmobj,26,[],[],[],[],LB,UB,[],[]);
The fitness function, smmobj, is defined as:
function [obj]=smmobj(theta)
global var1 var2...
But when I run it, it always says:
Error using smmobj (line 4)
Not enough input arguments.
Error in SMMga (line 32)
[theta,fval,exitflag] = ga(smmobj,26,[],[],[],[],LB,UB,[],[]);
But I run the fitness function by itself, it works.
[theta,fval,exitflag] = ga(smmobj,26,[],[],[],[],LB,UB,[],[]);
will throw that error because you are essentially calling the function smmobj (with no parameters) instead of passing your ga function a function handle to your objective function. You do this using the # symbol so
[theta,fval,exitflag] = ga(#smmobj,26,[],[],[],[],LB,UB,[],[]);
Incidentally, I would recommend that you do not use global in order to pass the extra parameters of var1 and var2 to your objective function but rather use anonymous functions:
[theta,fval,exitflag] = ga(#(x)(smmobj(x,var1,var2)),26,[],[],[],[],LB,UB,[],[]);
and then change smmobj's definition to
function [obj]=smmobj(theta,var1,var2)

How to write a function that does not throw a "wrong number of arguments" error

I am trying to write a minimal function that can be called with a variable number of arguments but that will not throw a wrong number of arguments error if miscalled.
Here is where I start from :
function varargout=fname(varargin)
% FNAME
% Usage: output=fname(input)
% Arguments check
if(nargin~=1 || nargout~=1)
disp('Function fname requires one input argument');
disp('and one output argument');
disp('Try `help fname`');
varargout(1:nargout)={0};
return;
end
input=varargin{1};
output=input;
varargout(1)={output};
end
However this does not work as I would like it to. Is there a way to write a function that :
never throw a "wrong number of arguments" error (so that the rest of the execution can continue)
accepts variable number of input and output arguments and checks them inside the function
(maybe more tricky) if the number of input / output arguments is not correct, does not replace the value of the provided output arguments (so that any misplaced call does not erase the previous value of the output argument)
I am open to any suggestions / other methods.
Thank you for your help.
UPDATE: thanks to #Amro for his answer, I guess what I miss here is either a call by address of reference for Matlab functions or a way to interrupt a function without returning anything and without stopping the rest of the execution.
Here is one way to implement your function:
function varargout = fname(input,varargin)
%# FNAME
%# Usage: output=fname(input)
%%# INPUT
if nargin<1
varargout(1:nargout) = {[]};
warning('Not enough input arguments.'), return
end
if ~isempty(varargin)
warning('Too many input arguments.')
end
%%# YOUR CODE: manipulate input, and compute output
output = input;
%%# OUTPUT
varargout{1} = output;
if nargout>1
warning('Too many output arguments.')
varargout(2:nargout) = {[]};
end
end
Obviously you can customize the warning messages to your liking...
Also, if you want your function to simply print the message instead of issuing warnings, replace all WARNING calls with simple DISP function calls.
Examples of function call:
fname()
fname(1)
fname(1,2)
x = fname()
x = fname(1)
x = fname(1,2)
[x,y] = fname()
[x,y] = fname(1)
[x,y] = fname(1,2)
The above calls execute as expected (showing warning messages when applicable). One caveat though, in the last three calls, if the variable y already existed in the workspace prior to the calls, it would be overwritten by the empty value y=[] in each...
If I understand your question correctly, then the answer is no. If a caller calls a function like this:
[a, b, c] = fname('foo');
then fname is required to return (at least) three outputs. There's no way to tell MATLAB that it should leave b and c alone if fname only returns one output.