Generate all possible combinations of a few variables of a maximum length using certain mathematical operators/functions?

2 views (last 30 days)
I’m trying to do something that shouldn’t be impossible but is a bit cumbersome and tricky for me to figure out how to write: I want to first define a set of mathematical operators/functions that I allow, for example lets say I allow +, -, *, / and cos() of a variable (so, addition, subtraction, multiplication, division and cosine in other words). And I have a number of variables, lets say a and b to keep it simple.
I would like to generate all possible combinations of a and b that can be calculated using these allowed operators but whilst keeping the expression under a specific length. So say I want to limit the length to only allow the usage of a maximum of two variables, it could be that a is used two times, a is used one time, b is used two times, b is used one time or that a and b are together used to generate the combination.
To give and example of what I mean – using the rules I have stated above in my example, a and b would generate the following combinations:
a
b
a+b
a+a
b+a
b+b
a-a
a-b
b-a
b-b
a*a
a*b
b*b
b*a
a/a
a/b
b/a
a/b
b/b
cos(a)
cos(b)
cos(a)+b
cos(a)-b
cos(a)*cos(b)
a/cos(b)
cos(b)/cos(a)
And so on and so on. Even with just two variables and five allowed operators the number of combinations become pretty much too many to manually list, but I hope you understand what I want to create.
If this is possible to create I would also like to be able to add more allowed operators, so for example sin(), sqrt(), tan(), mean(),log(), exp() and so on. And I would also like to be able to generate the combinations with more than two variables and with a slightly longer allowed max length, for example 3 or 4 variable usages.
Is this in any way possible to generate?
Thanks in advance.

Accepted Answer

Guillaume
Guillaume on 8 Feb 2016
Edited: Guillaume on 8 Feb 2016
There are three parts to what you want:
  1. generate all possible combinations of variables with an unary operator
  2. generate all possible combinations of 2 or more arguments and
  3. apply all possible binary operators to the previous combinations
For 1: This is the cartesian product of the set of unary operators with the set of variables. You achieve this with ndgrid
variables = {'a', 'b'}; %can be as many as you want. limited by memory
unaryops = {'?', 'cos(?)'}; %can be as many as you want. ? to be replaced by variable
[idxuop, idxvar] = ndgrid(1:numel(unaryops), 1:numel(variables)); %cartesian product of indices
uopvar = strrep(unaryops(idxuop), '?', variables(idxvar));
For 2: again this a cartesian product, but you need to add an empty element to the uopvar set (for the case where no binary operation is applied)
uopvar = [uopvar(:); {''}]; %add empty element
[idxvar1, idxvar2] = ndgrid(1:numel(uopvar)); %cartesian product with self
binoparg1 = uopvar(idxvar1(:));
binoparg2 = uopvar(idxvar2(:));
3 is fairly straighforward. You can use a loop or cellfun to apply all binary operators to the arguments of step 2, using strcat:
binaryops = {'+', '-', '/', '*'};
expressions = cellfun(@(bop) strcat(binoparg1, bop, binoparg2), binaryops(:), 'UniformOutput', false);
expressions = vertcat(expressions{:})
All that's left is some tidying up for those cases where no binary ops are applied (disallowing these would simply things). regexprep to remove these binaryops attached to empty variable, and unique to remove duplicate help:
expressions = unique(regexprep(expressions, sprintf('^[%1$s]|[%1$s]$', [binaryops{:}]), ''))
  5 Comments
Guillaume
Guillaume on 8 Feb 2016
unaryops is supposed to be made of strings with a '?' placeholder for the variable. Thus unaryops should be:
unaryops = {'?', ... %identity operation
'cos(?)', 'sin(?)', 'tan(?)', ... %trigonometric functions
'sqrt(?)'};
The '?' is later replaced by the actual variable in that line:
uopvar = strrep(unaryops(idxuop), '?', variables(idxvar));

Sign in to comment.

More Answers (1)

Joseph Cheng
Joseph Cheng on 8 Feb 2016
Edited: Joseph Cheng on 8 Feb 2016
This is certainly possible and to perform this easily i'd tackle this in two parts.
  1. create function to perform single variable operations the sin(), cos(), tan(), sqrt()... with input of variable to be operated
  2. another function for inbetween operations (+,-,/,...) with input of two variables to be operated on.
each function would also take in a number which you'll use as a switch/case statement to get the output.
With something like this you can write nested for loops to go through combinations for however many variables.
  1 Comment
Peta
Peta on 8 Feb 2016
I’m not entirely sure what you mean. Do you mean I should create a function that takes one variable and performs all the allowed operations on it? So that functionOne(a) returns:
a
Sin(a)
Cos(a)
Tan(a)
Etc.
And functionOne(b) returns:
b
Sin(b)
Cos(b)
Tan(b)
Etc.
And function two takes the outputs of functionOne(a) and functionOne(b) and generates the calculation between them? So that functionTwo(functionOne(a),functionOne(b)) returns:
a + b
Sin(a) + sin(b)
Cos(a) + Cos(b)
Tan(a) + tan(b)
Etc.
Or did I misunderstand you?

Sign in to comment.

Products

Community Treasure Hunt

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

Start Hunting!