5 views (last 30 days)

Show older comments

Hi friends from community,

I am very confused on how to manage 'eval' function existing in my code, i need it to be removed from my code and run the function as fast as possible.

The subIndex function runs as to solve such a problem.

Given an integer N, I want the summation of these M non-negative integers be less or equal than N.

List all cases of , such that .

For example

N = 2, M = 2;

Then p becomes

p = [0,0; 1,0; 0,1; 2,0; 0,2; 1,1];

Following is the function with 'eval':

function p = subIndex(M,N)

s = (N+1)*ones(1,M);

r = (1:prod(s))';

ch = '[';

for i = 1:1:M

ch = [ch,'f',num2str(i),','];

end

eval([ch(1:end-1),']=ind2sub(s,r);']);

p = eval([ch(1:end-1),']-1']);

q = sum(p,2);

[~,idx] = sort(q);

p = p(idx,:);

q = sum(p,2)<=N&sum(p,2)>=1;

p = p(q,:);

end

Robert U
on 3 Sep 2021

Hi Wan Ji,

you can use cell-arrays. You don't need to assign variables with different names to multiple outputs.

function p = subIndex(M,N)

% Given an integer N, I want the summation of these M non-negative integers be less or equal than N.

% List all cases of p1,p2,...pM, such that sum(p1...pM) <= N.

s = (N+1)*ones(1,M);

r = (1:prod(s))';

f = cell(1,M);

[f{:}] = ind2sub(s,r);

f = [f{:}];

p = f-1;

q = sum(p,2);

[~,idx] = sort(q);

p = p(idx,:);

q = sum(p,2)<=N&sum(p,2)>=1;

p = p(q,:);

end

Kind regards,

Robert

Stephen
on 4 Sep 2021

Walter Roberson
on 3 Sep 2021

[f{1:M-1}] = ind2sub(s, r);

p = cell2mat(f)-1;

However, it looks to me as if you are doing "integer partitions" of M. People have posted functions for that, including https://www.mathworks.com/matlabcentral/answers/226437-obtain-all-integer-partitions-for-a-given-integer#answer_497158

Walter Roberson
on 3 Sep 2021

Ah yes I was confused about what the -1 was doing in the original code. I see now that it was skipping a final comma. eval() is such a mess to use!

Also... strjoin() would have avoided having to remove the comma. And the loop could have been avoided with

strjoin("f"+(1:M), ',')

Chunru
on 3 Sep 2021

N = 2, M = 2;

%p = [0,0; 1,0; 0,1; 2,0; 0,2; 1,1];

p = subIndex(M,N)

p = subIndex1(M,N)

function p = subIndex(M,N)

s = (N+1)*ones(1,M);

r = (1:prod(s))';

ch = '[';

for i = 1:1:M

ch = [ch,'f',num2str(i),','];

end

eval([ch(1:end-1),']=ind2sub(s,r);']);

p = eval([ch(1:end-1),']-1']);

q = sum(p,2);

[~,idx] = sort(q);

p = p(idx,:);

q = sum(p,2)<=N&sum(p,2)>=1;

p = p(q,:);

end

function p = subIndex1(M,N)

% Consider the M numbers are index pf M-D matrix, each dim has N+1 elements

s = (N+1)*ones(1,M);

k = cumprod(s);

ii = (0:k(end)-1)'; % linear index (0 based)

idx = zeros(length(ii), M); % sub []xM

% linear index i--> sub idx of size Mx1 (0 based)

for j=M:-1:2

ir = rem(ii, k(j-1));

idx(:, j) = (ii - ir) /k(j-1);

ii = ir;

end

idx(:, 1) = ii;

p = idx(sum(idx,2)<=N, :);

end

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

Start Hunting!