Effacer les filtres
Effacer les filtres

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

2 vues (au cours des 30 derniers jours)
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.

Réponse acceptée

Guillaume
Guillaume le 8 Fév 2016
Modifié(e) : Guillaume le 8 Fév 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 commentaires
Guillaume
Guillaume le 8 Fév 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));
Peta
Peta le 8 Fév 2016
Oh, I misunderstood that. It works great now, thank you!

Connectez-vous pour commenter.

Plus de réponses (1)

Joseph Cheng
Joseph Cheng le 8 Fév 2016
Modifié(e) : Joseph Cheng le 8 Fév 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 commentaire
Peta
Peta le 8 Fév 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?

Connectez-vous pour commenter.

Catégories

En savoir plus sur Logical dans Help Center et File Exchange

Produits

Community Treasure Hunt

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

Start Hunting!

Translated by