Effacer les filtres
Effacer les filtres

Quickest way to have a symbolic function exist only on a specified interval [a,b]

3 vues (au cours des 30 derniers jours)
Suppose i have some symbolic function. Can i, without the use of if statements (or with the use of... it would be preferable without), define that function to only exist for values on some interval [a, b] or (a, b)?
Do i multiply it by a step function or something?
Ideally i would like to have the function defined only within a certain area. Such an area is enclosed by two curves.
ps., is it possible to use the code tags inline on this forum?

Réponse acceptée

Walter Roberson
Walter Roberson le 24 Juil 2017
  2 commentaires
Maurilio Matracia
Maurilio Matracia le 9 Sep 2020
Does this work with function handles? Or maybe there is another way to do that?
Walter Roberson
Walter Roberson le 9 Sep 2020
In many (but not all) cases, the standard way to deal with function handles in piecewise() is to invoke the function handle on symbolic parameters,
f = @(x,y) sin(x) + cos(y^2)
syms X Y
piecewise(X < 3, f(X,Y), f(Y,X)/X)
Sometimes this runs into minor glitches in the function that can be rewritten without a lot of effort, such as
function Y = PQR(X)
Y = zeros(size(X));
for K = 1 : numel(X); Y(K) = sin(X(K)).^2 - cos(X(K)); end
end
This would fail if you passed symbolic X into it because Y is initialized to double precision, and symbolic right hand side for the assignment would fail. These kinds of small glitches can often be overcome with techniques such as
function Y = PQR(X)
Y = zeros(size(X), 'like', X);
for K = 1 : numel(X); Y(K) = sin(X(K)).^2 - cos(X(K)); end
end
which would cause Y to be initialized as symbolic if X is symbolic.
If, however, the code has if statements that test the values, then you might end up having to rewrite the code in terms of piecewise(). If you are doing something like looping until a tolerance is met, then there isn't really any good way to handle that for symbolic inputs except to rewrite it all in terms of vpasolve() or similar.
If the code has calls to mod() testing an input that could be symbolic, you have to rewrite the call, because mod() does... odd... things with symbolic inputs. Fortunately, there is the old trick of mod(A,B) -> A - floor(A/B).*B ... though be careful with negatives.
If the code has calls to max() or min() then the symbolic alternatives can turn into messy expressions in piecewise().
But keep in mind that the original question was for symbolic functions. ;-)
The standard trick for dealing with numeric functions is to use a construct such as
logical_test_for_first_range .* first_function(variables) + logical_test_for_second_range .* second_function(variables)
This relies upon it being acceptable that both functions are going to be invoked, including on the range they are not "valid", with the output not being selected being multiplied by 0. This is not the most efficient of possibilities, but it can be acceptable at times. The major difficulty with it is that the unselected function must not return nan or inf when it is called with parameters it is not designed for. For example,
(x == 0) .* ones(size(x)) + (x ~= 0) .* (1./x)
This does not return 1 at the locations where x is 0: the x==0 selects the zeros and calculates 1s for them no problem, but the (x ~= 0) would be 0 where x == 0, and 1./0 is inf and 0 * inf -> nan . And nan + 1 is nan.
This particular case can be handled by rewritting to
1./(x + (x == 0))
The x == 0 would be 1 only where x == 0, and x would be 0 at those locations, so you would get a denominator of 1 at those locations, and everywhere else you would get a denominator of x. So this would work out as 1/x at non-zero and 1 at zero, like the logical-test approach looks like it generates.

Connectez-vous pour commenter.

Plus de réponses (0)

Community Treasure Hunt

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

Start Hunting!

Translated by