Count number of unique symbols in an expression

3 vues (au cours des 30 derniers jours)
Nathaniel H Werner
Nathaniel H Werner le 3 Déc 2022
I'm trying to develop an algorithm that can count how many times each of the syms in a list of parameters (called dimensions shown below) is counted at least once. If any of them in an array containing different combinations or products of the dimensions exist more than once, then it should only register 1 for each them. This part of an algorithm taught in engineering called the Buckingham Pi theorem.
syms M L T Theta d_0
% M: mass
% L: length
% T: time
% Theta: temperature
% d_0: no dimensions, something like an angle or efficiency
% These are the different combinations of dimensions
A = L^2; % maybe an area
V = L/T; % maybe a velocity
D = M/L^3; % maybe a density
% This the array of the combinations
param = {A,V,D};
I want to count how many of the syms M L T and Theta show up in my cell param.
For example starting at the first entry in the cell array.
param{1} = A
L^2
At this step, it should count that L has shown up once, and the others 0 times each.
param{2} = V
L/T
At this step, it counts that L has shown up once, but since it was already counted so I don't want to count it again. It should also count that T has shown up once. So far 1 L, and 1 T.
param{3} = D
M/L^3
Finally, this count that M has shown up once. So far 1 L, 1 T, and 1 M.
Since there are four possible symbols, I want to end the algorithm with this.
j = num; % how many times each of the syms was counted at least once.
If a dimension is not counted, that is fine. I am only interested in counting how many times each of the dimensions in the cell array are counted at least once.
I'm not really sure how to count the dimensions in each combination, but I can handle the combinatorics.
I've tried applying some of this answer, but I've come across these errors when I get to the parameter V = L/T.
Error: Conversion to logical from sym is not possible.
dimen = [M,L,T,Theta]
n = length(param);
u_dimen = zeros(1,length(dimen));
for i=1:n
disp(['Parameter ',num2str(i)])
disp(param(i))
breakinner = false;
for d=1:length(dimen)
disp(dimen(d))
[~,powers] = coeffs(param(i),dimen(d))
exponents = mapSymType(powers, 'power', @(Z) children(Z,2))
if powers(end)==1
exponents(end) = 0
end
exponents
strcmp(class(exponents),'sym')
if exponents>=1 && u_dimen(d)==0
u_dimen(d) = 1;
breakinner = true;
end
clear powers exponents
if breakinner
break
end
end
end
But this doesn't make sense to me since on each run, even when exponents is a number strcmp(class(exponents),'sym') still outputs 1. For example, when dimen(d) = A or L^2, the exponent is a 2 and it gets through the second if statement.

Réponses (1)

Walter Roberson
Walter Roberson le 3 Déc 2022
With limits,
present = cellfun(@(expr), ismember(dimen, symvar(expr)), param, 'UniformOutput', false)
counts = sum(vertcat(present{:}), 1)
  6 commentaires
Walter Roberson
Walter Roberson le 22 Déc 2022
When you have an expression of the form @(VARIABLE) EXPRESSION then that creates an anonymous function. When the function is invoked, then inside EXPRESSION, any plain-text version of VARIABLE will be replaced by the value that is passed in at the corresponding position.
present = cellfun(@(expr), ismember(dimen, symvar(expr)), param, 'UniformOutput', false)
is nearly equivalent to
if exist('expr', 'var')
internal_hidden_variable_have_saved_expr = true;
internal_hidden_variable_saved_expr = expr;
else
internal_hidden_variable_have_saved_expr = false;
end
present = cell(size(param));
for INDEX = 1 : numel(param)
expr = param{INDEX};
present{INDEX} = ismember(dimen, symvar(expr));
end
if internal_hidden_variable_have_saved_expr
expr = internal_hidden_variable_saved_expr;
clear internal_hidden_variable_saved_expr;
else
clear expr
end
clear internal_hidden_variable_have_saved_expr
except internal_hidden_variable_have_saved_expr and internal_hidden_variable_saved_expr would be internal variable names guaranteed not to conflict with any existing variable.
Which is to say that in the form @(VARIABLE) EXPRESSION, that VARIABLE acts as a temporary variable that takes on the value passed in during the execution of EXPRESSION and is afterwards restored to whatever it was.
Nathaniel H Werner
Nathaniel H Werner le 23 Déc 2022
OK, but MATLAB tells me to remove the comma, and then I get the same error. I am running 2021b.

Connectez-vous pour commenter.

Produits


Version

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by