Expected scalar value: MATLAB Coder - matlab

I get the following error while using MATLAB coder for generating a c++ code from m file with a call to a c function ompmex.c
C function calls always return scalar values but a non-scalar value is expected here.
My code is:
function [D,gamma] = DSGD2(X,H) %#codegen
[Xr,Xc]=size(X);
[Hr,Hc]=size(H);
D=zeros(Hr,Hc,'double');
D=X(:,11:210);
d1=sqrt(sum(D.*D)); D=D./repmat(d1,Xr,1);
beta=zeros(Xr,Xc,'double');
beta=coder.ceval('ompmex',H,X,H'*H,200);
Can anybody help on this. I am not getting a working answer online

function [D,gamma] = DSGD2(X,H) %#codegen
[Xr,Xc] = size(X);
[Hr,Hc] = size(H);
D = zeros(Hr,Hc,'double');
D = X(:,11:210);
d1 = sqrt(sum(D.*D));
D = D./repmat(d1,Xr,1);
% coder.ceval is tricky. I recommand to use it only if the function is
% created by c-coder too (and not as mex function!)! you need a c executable
% or a c library (generated before you trigger codegen for DSGD2).
% further more, ceval can not handle multiple
% outputs. as a workaround, always use structs for output - and for
% input too!
s = struct('beta',(zeros(Xr,Xc,'double')));
% make it work in matlab too and call ompmex function
if coder.target('MATLAB')
s = ompmex(H,X,H'*H,200);
else
coder.ceval('ompmex_initialize')
s = coder.ceval('ompmex',H,X,H'*H,200);
coder.ceval('ompmex_terminate')
end
% read out stuct value
beta = zeros(Xr,Xc,'double');
beta = s.beta;
gamma = 0; % not given by you, but c-coder needs it. so change to what ever you need
end

Related

matlab coder requirements stricter than normal matlab

Consider the following matlab program:
function results = prog()
opts.x = 1;
if ~isfield(opts, 'y'); opts.y = 1; end
'asdf'
return
I am able to run this program successfully in matlab however when I try to use coder to convert it to C I get the following error:
This structure does not have a field 'y'; new fields cannot be added when structure has been read or used.
I would like to know if there is a way to convert to C using coder (or possible some other tool) that does not use a stricter compiler as seems to be the case with coder as I am using it. I am using matlab version R2019B.
Please note that this is just one of many examples of how coder is using a stricter compiler than normal matlab. I have a fairly large program that I would like to convert to C and I don't want to have to go through each error (there are over 100).
Like Daniel mentioned, optional fields of structs don't exist in C, which is why MATLAB Coder errors on that code.
To make this code work with MATLAB Coder, opts could always have property y, but make it variable-sized and initialized to empty:
function results = prog()
opts.x = 1;
opts.y = [];
coder.varsize('opts.y');
if isempty(opts.y); opts.y = 1; end
'asdf'
end
Or you could create another options variable optsWithY that will have field y, even if opts doesn't:
function results = prog()
opts.x = 1;
optsWithY = opts;
if ~isfield(opts, 'y'); optsWithY.y = 1; end
'asdf'
end
This could even be moved into a helper function and assigned back to opts:
function results = prog()
opts.x = 1;
opts = addOpt(opts, 'y', 1);
'asdf'
end
function newOpts = addOpt(opts, field, defaultValue)
newOpts = opts;
if ~isfield(opts, field)
newOpts.(field) = defaultValue;
end
end
The difference between this and the original code is partial assignment opts.y = ... vs complete assignment opts = ....
Or like Cris mentioned, MATLAB Compiler will be a lot closer to MATLAB (though you won't get C code)

Array of objects in generable matlab function

In simulink model I have a matlab function block. Inside the function I would like to create an array of objects in a way it is compatible with code generation.
My question is similar to the one answered here: Construct an array of objects in MATLAB
The problem is "compatible with code generation" part.
When I try to do it with repmatmatlab returns:
Arrays of objects are not supported for code generation.
When I try to do it with array of objects I see:
Recursive calls are not allowed. Function 'dummyClass.dummyClass'
participated in a recursive call.
Please find below the code I run:
embedded matlab function
function y = fcn(u)
%#codegen
x = [1 2 3];
% %% repmat way
% aa = dummyClass(x(1));
% aaArray = repmat(aa,1,3);
%% array of objects
aa = dummyClass(x);
y = u;
class file
classdef dummyClass
properties
value
end
methods
function obj = dummyClass(value)
%% array of objects
if nargin~=0
m = size(value,1);
n = size(value,2);
obj(m,n) = dummyClass;
for i = 1:m
for j = 1:n
obj(a,b).value = value(a,b);
end
end
end
% %% repmat
% obj.value = value;
end
end
end
Uncomment
As of MATLAB R2017a, there's no way to create arrays of objects that is compatible with code generation using MATLAB Coder or Simulink Coder.
As the first error message says, "arrays of objects are not supported for code generation" - it's not a problem with any specific way you're attempting to create them, they're just not supported at all.
MathWorks may introduce this feature in a future version, but it's not there right now.

Integrating function with two variables in Matlab

Hey I'm having trouble integrating a function in MATLAB, constantly getting errors. I'm trying to fill a matrix with the function. exp(x-1)*x^j+k
I2 = zeros(26,3);
k = [0.13, 0.0024, 0.000035];
for i = 1:length(k)
for j = 0:25
fun = #(x,j) exp(x-1).*x.^j+k(i);
I2(j,i) = integral(fun,0,1);
end %end j-loop
end %end i-loop
display(I2);
Thanks.
In the current form the function handle is expecting two inputs but you want a function with a single input for integral. Changing your function handle definition to the following should fix this.
fun = #(x) exp(x-1)*x^j+k(i);

Conversion function for 3D value into 2D in MATLAB

I have written a function for converting 3D values into 2D, but not able to get it working may be I am parsing the wrong values.
I am passing the value in the valuse as 2 coordinates and trying to get into Output in 2D. Can anyone please do the correction in the function below and help me in running the function?
% Perspective Projection
function Output = perspective_projection(Input)
Output = zeros(size(Input));
for ii = 1: length(Input)
Output(ii,1) = Input(ii,1)/Input(ii,3);
Output(ii,2)=Input(ii,2)/Input(ii,3);
end
value = [6,4,2];
[a1,b1] = perspective_projection(a1)
BSXFUN method as suggested by Rody is an elegant way, but if you would like to keep your loop, try this -
% Perspective Projection
function Output = perspective_projection(Input)
Output = zeros(size(Input,1),2);
for ii = 1: size(Input,1)
Output(ii,1) = Input(ii,1)/Input(ii,3);
Output(ii,2) = Input(ii,2)/Input(ii,3);
end
If I understand you correctly, you should rewrite your function as:
function Output = perspective_projection(Input)
Output = bsxfun(#rdivide, Input(:,1:2), Input(:,3));
end
or, judging from the way you seem to be calling it:
function [OutputX,OutputY] = perspective_projection(Input)
OutputX = Input(:,1)./Input(:,3);
OutputY = Input(:,2)./Input(:,3);
end
Note that your function is quite simple (I wouldn't even use a function):
[X,Y] = deal(Input(:,1)./Input(:,3), Input(:,2)./Input(:,3));
As for your original function: the error is in the initialization:
function Output = perspective_projection(Input)
%// WRONG: this initializes a 3D array!
Output = zeros(size(Input));
%// ...but you want a 2D array
for ii = 1: length(Input)
Output(ii,1) = Input(ii,1)/Input(ii,3);
Output(ii,2) = Input(ii,2)/Input(ii,3);
end
end
and of course, the multiple outputs (but it's not quite clear to me whether you want that or not...)

lagranges method

I found following code on internet. I am new to matlab. Now the problem whenever i copy-paste this code then it shows me error message.
function[p] = lagrange_interpolation(X,Y)
|
Error: Function definitions are not permitted in this context.
The code snippet is:
function[p] = lagrange_interpolation(X,Y)
L = zeros(n);
p = zeros(1,n);
% computing L matrice, so that each row i holds the polynom L_i
% Now we compute li(x) for i=0....n ,and we build the polynomial
for k=1:n
multiplier = 1;
outputConv = ones(1,1);
for index = 1:n
if(index ~= k && X(index) ~= X(k))
outputConv = conv(outputConv,[1,-X(index)]);
multiplier = multiplier * ((X(k) - X(index))^-1);
end
end
polynimialSize = length(outputConv);
for index = 1:polynimialSize
L(k,n - index + 1) = outputConv(polynimialSize - index + 1);
end
L(k,:) = multiplier .* L(k,:);
end
% continues
end
In all likelihood, you are probably attempting to mix random code along with your function. There are two types of M files:
scripts - have "random" code that is executed independent of anything else
functions - are the "classic" definition of functions
You cannot mix the two (that's a lie, but for now a good one). So if you are defining a function, that should be the only code in your .m file.
You should later use this function in either the command window or another function or a script by calling it via p = blahblah(bleaurgh);.
TL;DR: Make sure the function code is the only code in the script file, save it with the same name.m, call the function from somewhere else.