Reputation: 47
I have to make a function that takes 3 inputs like e0
, e1
and e2
. The function will have 2 outputs x
and y
.
x
will be the combinations of e0
, e1
and e2
. y
will be a column vector containing sums of columns of x
.
The following conditions must be met when creating the function:
e0
, e1
and e2
each have a single number. Here's an example:
combination pattern of X (first 3 columns): pattern for y is the sum of x
1 1 1 3
2 1 1 4
3 1 1 5
1 2 1 4
2 2 1 5
3 2 1 6
1 3 1 5
2 3 1 6
and so on... and so on....
So far I have only been able to do this much with x
and y
displayed separately.
function [x,y]=create(e0,e1,e2)
switch nargin
case 2
e1=0;
e2=0;
case 1
e2=0;
case 0
disp('no input')
end
I googled my problem and found that combvec and allcomb should help but i cant figure out how.. Please help any answer or hint will be a great help.
Upvotes: 0
Views: 203
Reputation: 6084
You were on the right track with allcomb
. You are in fact looking for the cartesian product:
[e0, e1, e2] x [e0, e1, e2] x [e0, e1, e2] == [e0, e1, e2]^3.
You don't need allcomb
though, as ndgrid
can already do this.
Let's start with your code. It has a bug. Basically case 2
and case 1
are flipped.
function [x,y] = create(e0,e1,e2)
switch nargin
case 2
e1=0; % <- When nargin==2, this value is set, and you overwrite it.
e2=0;
case 1
e2=0; % <- When nargin==1, e1 must also be set to zero.
case 0
disp('no input') % <- use `error` instead of `disp`? If not, use `return` here.
end
You would then need to check that the numbers provided are not matrices. This can be achieved with something like that. (Fill in the blanks.)
assert(numel(e1)==1 && numel(__)___ && numel(__)___,'Input sizes are incorrect');
To generate the cartesian product [e0, e1, e2] x [e0, e1, e2] x [e0, e1, e2]
you are looking for, you can either use this answer for allcomb
or this answer for the built-in ndgrid
.
sets = {[e0,e1,e2], [e0,e1,e2], [e0,e1,e2]};
cartProd1 = allcomb(sets{:})
[x y z] = ndgrid(sets{:});
cartProd2 = [x(:) y(:) z(:)]
You could swap the columns of cartProd
if you want the correct ordering.
For generating the sum along the rows, use
sum(cartProd,2)
Upvotes: 1
Reputation: 104484
What you want are permutations not combinations. You listed that 2 3 1
and 3 2 1
are different, yet if you were to make this a combination, you would consider these as being the same. As such, I'm going to refer you to this post instead:
How to find all permutations (with repetition) in MATLAB?
I'm specifically going to take Rody Oldenhuis's answer. Therefore, you can construct all possible permutations by:
x = unique(nchoosek(repmat([e0 e1 e2], 1, 3), 3), 'rows');
This will create an array of all possible permutations with e0
e1
and e2
. As such, using your example with e0 = 1, e1 = 2, e2 = 3
, we get:
x =
1 1 1
1 1 2
1 1 3
1 2 1
1 2 2
1 2 3
1 3 1
1 3 2
1 3 3
2 1 1
2 1 2
2 1 3
2 2 1
2 2 2
2 2 3
2 3 1
2 3 2
2 3 3
3 1 1
3 1 2
3 1 3
3 2 1
3 2 2
3 2 3
3 3 1
3 3 2
3 3 3
Now to finally get what you want, you just have to sum over the rows, so do:
y = sum(x, 2)
y =
3
4
5
4
5
6
5
6
7
4
5
6
5
6
7
6
7
8
5
6
7
6
7
8
7
8
9
You've already written the case to handle when the user doesn't enter anything for e0
, e1
and/or e2
, so all you have to do is take your code, and piece what I wrote above into your function. It should give what you want.
Upvotes: 0