Matlab function as Simulink block - matlab

I tryed to write an Matlab function in Simulink.
My first func like this:
function y = fcn(u, v)
coder.extrinsic('detectSURFFeatures');
boxPoints = detectSURFFeatures(u);
%scenePoints = detectSURFFeatures(v);
vBoxPoints = boxPoints.selectStrongest(100);
y = 0;
y = vBoxPoints;
But I see errors:
1. Attempt to extract field 'selectStrongest' from 'mxArray'.
2.Undefined function or variable 'vBoxPoints'. The first assignment to a local variable determines its class.
3. Error in port widths or dimensions. Output port 1 of 'detecting_cross/MATLAB Function/v' is a [400x239] matrix.
Pls, help.

The data returned from extrinsic functions are mxArray types. If you want to get the values from these mxArrays you need to pre-declare them so that the result of extrinsic function can be auto-converted to that type. You can use something like
boxPoints = struct('selectStrongest',zeros(100,1));
before calling detectSUTFFeatures. If the mxArray does not match the one from the function, you will get a run-time error. Your errors 2 and 3 are because of the first problem.

Related

Matlab: Detect number of input arguments for function handle from outside of the function

I begin with a symbolic function of one variable, calculate the symbolic derivatives of orders 1 through N, and then convert those symbolic functions into function handles and store the function handles in a cell array. I then evaluate each function handle at the same input value using a loop. The problem I have is that it is possible for one of the derivatives to be a constant (with higher order derivatives being zero, of course). As I was trying to give each function handle an input, I face the "Too many input arguments" error. I would like to be able to check, in advance, whether the function handle is a constant so I can avoid the error, but I can't figure out how to do that.
In case a small working example is helpful, I provide the following
symVar = sym('symVar');
startFunc = symVar^4 + symVar^3 + symVar^2;
derivesCell = cell(5);
for J=1:5
derivesCell(J) = {matlabFunction(diff(startFunc,symVar,J))};
end
cumSum = 0;
evalPoint = 2;
for J=1:5
cumSum = cumSum + derivesCell{J}(evalPoint);
end
Execution produces "Error using symengine>#()2.4e1
Too many input arguments."
tl;dr: You can do this with nargin:
>> nargin(derivesCell{5})
ans =
0
>> nargin(derivesCell{3})
ans =
1
Explanation:
Most people are familiar with the use of nargin as a "special variable" inside the function, but it can be used outside the context of a function definition, as a function that takes a function_handle argument, returning the number of input arguments that function handle takes. From the documentation:
NARGIN(FUN) returns the number of declared inputs for the
M-file function FUN. The number of arguments is negative if the
function has a variable number of input arguments. FUN can be
a function handle that maps to a specific function, or a string
containing the name of that function.

MATLAB: varargin (cell) not compatible with fminsearch (double)?

I have functions I've built using variable arguments but now I want to optimize these functions. However, in the current form, varargin doesn't seem to work well with FMINSEARCH? What can I do? Is there something wrong?
I am trying to do the following:
y = #(varargin)-fn_backtest_v0002(varargin{:});
start = {3,0,0.5,10,0.05,0,1,1};
max = fminsearch(y,start);
But I get this error:
Error using fminsearch (line 96)
FMINSEARCH only accepts inputs of data type double.
From the simple examples of FMINSEARCH, a vector should be used, however I have varargin in my functions which require arguments to be of cell type.
Any help appreciated.
You should write a wrapper function that accepts vector as parameter and passes them in the format that fn_backtest_v0002 expects to get. For example:
function out = fn_backtest_v0002(varargin)
.... %Your code here
end
And the wrapper function:
function out = fn_backtest_v0002_wrapper(vec)
out = -fn_backtest_v0002(num2cell(vec));
end
Then, you can use the wrapper function with fminsearch :
start = [3,0,0.5,10,0.05,0,1,1];
max = fminsearch(y,#fn_backtest_v0002_wrapper);
Another alternative is to re-write fn_backtest_v0002 to have vector input arguments (Which makes much more sense than varargin in your case.
Thanks to Andrey for idea of wrapper function. (I am a programming newbie).
This is exactly how I did it.
Create wrapper function:
function [ out ] = fn_backtest_v0002_wrapper( vec )
cell = num2cell(vec);
out = fn_backtest_v0002(cell{:});
end
Then I can run the following commands successfully:
y = #(vec)-fn_backtest_v0002_wrapper(vec);
start = [3,0,0.5,10,0.05,0,1,1];
max = fminsearch(y,start);

How to store a function-wrapped solve call?

Bear with me please, I'm completely new to matlab. I am attempting to store the call to eigenvalue in another function, but it's giving me the error: Too many output arguments.
function eigenvalue(M)
syms l;
eq = det(M - l*[1 0; 0 1]);
solve(eq == 0)
end
I've tried storing it in many different ways, but nothing seems to work:
>> a = eigenvalue(M)
Error using eigenvalue
Too many output arguments.
>> [a, b] = eigen(M)
Error using eigenvalue
Too many output arguments.
The weird thing is that if I solve a normal polynomial equation I can do sol=solve(x^2==4) just fine and access sol(0)and sol(1)without any problems. I guess that I haven't picked up on a simple matlab concept and thanks to anyone who's willing to help!
Your problem is that you don't have any output arguments in your function.
function eigenvalue(M)
In MATLAB, you should* use the following syntax:
function output = func_name(input_1,input_2,...)
You have 2 alternatives:
You can skip the first line and save it as script, as this:
syms l;
eq = det(M - l*[1 0; 0 1]);
solve(eq == 0)
Or, you can save it as a function, but with output variable(s), like this:
function output = eigenvalue(M)
syms l;
eq = det(M - l*[1 0; 0 1]);
output = solve(eq == 0)
end
*You should use the syntax I described, but you can use the syntax you used as well. However, if you do, the function won't give you anything back except possibly printing the result to screen. You will not get to use any variables created inside the function.
If you want a function to provide an output argument then you have to declare it in the function definition. E.g.
function a = eigenvalue(M)
You then need to make sure you assign a value to each output variable in the function body.

matlab coder covert m-file to c++?

I used MATLAB coder to covert M-file to cpp-file.
There generated problem when is building.
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.
MATLAB code :
nms = sum(transpose(X).^2);
nms0=-1 * nms;
nms2=transpose(nms0);
nms3=transpose(X);
nms4=nms2*ones(1,n);
nms5=ones(n,1)*nms;
nms6=2*X*nms3;
nms7=zeros(150,150);
nms7=nms4-nms5; //This line is wrong
nms8=nms7 + nms6;
K = exp(nms8);
I want to know why code has been run correct in MATLAB,but it has error when is building
This error happens when you try to use result of extrinsic functions in expressions. In the code you provided is "n" or "X" the result of an extrinsic function? Even if they are not directly a result of an extrinsic function, they may have been computed based on data from other extrinsic functions.
One way to fix the problem is to help MATLAB coder convert these extrinsic data to known types. You can do that by pre-defining them with known data. For example,
coder.extrinsic('some_extrinsic_fcn');
y = zeros(10,1);
y = some_extrinsic_fcn();
y = y * 2;
In this case some_extrinsic_fcn should return a double precision vector with 10 elements. This resulting mxArray will be auto-converted and stored in y. Without the line "y = zeros(10,1);" y will be of mxArray type and the line "y = y * 2;" will cause an error.

MATLAB Function (Solving an Error)

I have one file with the following code:
function fx=ff(x)
fx=x;
I have another file with the following code:
function g = LaplaceTransform(s,N)
g = ff(x)*exp(-s*x);
a=0;
b=1;
If=0;
h=(b-a)/N;
If=If+g(a)*h/2+g(b)*h/2;
for i=1:(N-1)
If=If+g(a+h*i)*h;
end;
If
Whenever I run the second file, I get the following error:
Undefined function or variable 'x'.
What I am trying to do is integrate the function g between 0 and 1 using trapezoidal approximations. However, I am unsure how to deal with x and that is clearly causing problems as can be seen with the error.
Any help would be great. Thanks.
Looks like what you're trying to do is create a function in the variable g. That is, you want the first line to mean,
"Let g(x) be a function that is calculated like this: ff(x)*exp(-s*x)",
rather than
"calculate the value of ff(x)*exp(-s*x) and put the result in g".
Solution
You can create a subfunction for this
function result = g(x)
result = ff(x) * exp(-s * x);
end
Or you can create an anonymous function
g = #(x) ff(x) * exp(-s * x);
Then you can use g(a), g(b), etc to calculate what you want.
You can also use the TRAPZ function to perform trapezoidal numerical integration. Here is an example:
%# parameters
a = 0; b = 1;
N = 100; s = 1;
f = #(x) x;
%# integration
X = linspace(a,b,N);
Y = f(X).*exp(-s*X);
If = trapz(X,Y) %# value returned: 0.26423
%# plot
area(X,Y, 'FaceColor',[.5 .8 .9], 'EdgeColor','b', 'LineWidth',2)
grid on, set(gca, 'Layer','top', 'XLim',[a-0.5 b+0.5])
title('$\int_0^1 f(x) e^{-sx} \,dx$', 'Interpreter','latex', 'FontSize',14)
The error message here is about as self-explanatory as it gets. You aren't defining a variable called x, so when you reference it on the first line of your function, MATLAB doesn't know what to use. You need to either define it in the function before referencing it, pass it into the function, or define it somewhere further up the stack so that it will be accessible when you call LaplaceTransform.
Since you're trying to numerically integrate with respect to x, I'm guessing you want x to take on values evenly spaced on your domain [0,1]. You could accomplish this using e.g.
x = linspace(a,b,N);
EDIT: There are a couple of other problems here: first, when you define g, you need to use .* instead of * to multiply the elements in the arrays (by default MATLAB interprets multiplication as matrix multiplication). Second, your calls g(a) and g(b) are treating g as a function instead of as an array of function values. This is something that takes some getting used to in MATLAB; instead of g(a), you really want the first element of the vector g, which is given by g(1). Similarly, instead of g(b), you want the last element of g, which is given by g(length(g)) or g(end). If this doesn't make sense, I'd suggest looking at a basic MATLAB tutorial to get a handle on how vectors and functions are used.