THE QUESTION IS
Is there a compact way to evaluate an antidevivative expression: x**3 / 2 | x = a; x = b
When we have an indefinite integral of the form:
# Pseudocode as I cannot write it in math mode
expr = x**2; a = 1; b = 5;
F = integral(expr, x); # integral of expr
Definite_integral = F.subs(x, b) - F.subs(x, a);
We can also do this by just using the built-in integrate function
# Pseudocode
expr = x**2;
a = 1; b = 5;
Definite_integra = integrate(expr, x, a, b) # integrate expr from a to b
However, the problem is that I start with an expression for the antiderivative
x**3 / 3
Ideally, I'd just want to express it with itegration brackets, example:
I don't want to repeat myself and write the expression twice and I don't really want to declare the expression as a (unnecessary; only used unce) function just to express it as: f(b) - f(a) or more in line with Ti Nspire notation: f(x)|x=b - f(x)|x=a
You can define bracket using a little helper function.
The screenshot below is from the Notes area.
Related
Suppose I have a function f(x) defined, which gives nan when it is very large, say x>100. Fortunately, when x>100, I can replace f by another function g. So I would like to define:
h = #(x)isnan(f(x)).*f(x)+isnan(f(x)).*g(x)
However, when I substitute h(1001), it gives nan. Is it possible to define h so that it gives g(1001) instead of nan? The only restriction is that I need to have anonymous function h for later use, say I would like to use it in integration, i.e., integral(h,0,inf).
Example: Suppose I have a function:
f = #(x)x.*1./x
This function is very easy and must be 1. I construct a function:
g = #(x)isnan(f(x)).*0+isnan(f(x)).*1
How to make g to be well defined so that I can still evaluate integral(g,-1,1)? For this example, I know I can evaluate it easily, but my restriction is that I need to define anonymous function g and use integral to do it.
You would need to make a regular function and wrap it with the anonymous function.
i.e.
function r = ternary(a, b, c)
if (a)
r = b;
else
r = c;
end
end
h = #(x)ternary(isnan(f(x)), g(x), f(x));
Note that this will evaluate your function twice. A less generalized solution for your particular case that won't evaluate the function twice.
function r = avoidNAN(a, b)
if (isnan(a))
r = b;
else
r = a;
end
end
There is a solution without any additional functions:
f = #(x)x.*1./x;
g = #(x)100+x;
h= #(x)getfield(struct('a',f(x),'b',g(x)),char(isnan(f(x))+'a'))
For use within the least square fitting routine lsqcurvefit, I need a function in terms of a series representation like :
F = #(D, t) F0 - D(1)*(1-exp(-t))...
- D(2)*(1-exp(-t))...
- D(3)*(1-exp(-t))...
...
- D(n)*(1-exp(-t));
However, the amount of terms in the series is to be determined by the user; so the anonymous function F needs to be created within a loop, like
F = #(D, t) F0;
for i=1:n
F = F - D(i)*(1-exp(-t));
end
Unfortunately, the above method is not working within MATLAB; is there a possibility to get it work?
Unless I'm misunderstanding something, your function is not actually recursive. You can just do:
F = #(D,t) F0 - sum(D*(1-exp(-t));
or, if you want to specify n explicitly:
F = #(D,n,t) F0 - sum(D(1:n)*(1-exp(-t));
or, if t is a vector the same size as D:
F = #(D,n,t) F0 - D(1:n)*(1-exp(-t(1:n)).';
The best way to do this is with a combination of anonymous and normal functions.
recursionDepth = 5
CoefficientList = ones(numel(recursionDepth) + 1);
functionResults = #(t) myFunction(t, CoefficientList, recursionDepth);
function F = myFunction(t, CoefficientList, Depth)
F = CoefficientList(1);
for idx = 1:Depth
F = CoefficientList(idx) * (1 - exp(-1));
end
end
What I've done here is defined the full function that contains your model with all of its parameters, and then wrapped that into an anonymous function that sets the user selectable, unchanging parameters within the anonymous function, and leaves the single adjustable parameter as the input. You'll have to adjust for your particular model, but that is your basic template.
I have a symbolic function exp(a+b), and would like to factor out A=exp(a) to produce exp(a+b) = A*exp(b), but I cannot figure out how to do this in MATLAB. Below is my attempt:
syms a b A
X = exp(a+b);
Y = subs(X,exp(a),A) % = A*exp(b)
however, Y = exp(a+b). For some reason, MATLAB cannot determine:
exp(a+b) = exp(a) * exp(b) = A*exp(b).
Any help is greatly appreciated.
First, expand the expression so that the exponents are separated then do the substitution. By default, when writing out an expression for the first time (before running it through any functions), MATLAB will try and simplify your expression and so exp(a)*exp(b) can be much better expressed using exp(a+b). This is why your substitution had no effect. However, if you explicitly want to replace a part of the expression that is encompassed by an exponent with a base, expand the function first, then do your substitution:
>> syms a b A;
>> X = exp(a+b);
>> Xexpand = expand(X)
Xexpand =
exp(a)*exp(b)
>> Y = subs(Xexpand, exp(a), A)
Y =
A*exp(b)
I have a symbolic expression in MATLAB with a == operator that I can use in solve(). What I want is to separate out the left hand side and the right hand side of the expression into two separate symbolic expressions.
For example:
expr = sym('[1-x^2==2*y; 1+x^2==x+y]');
side1 = lhs(expr); % returns side1 = [1-x^2; 1+x^2];
of course my expressions are far more complicated, and it is always vector or matrix form.
Workaround 1
I can use the MuPAD built-in function lhs() but I wanted to know if it possible to do this using only MATLAB functions and I want to make it work for vectors of expressions and not just one value.
This is what I have so far that works as expected. Maybe the result filling can be vectorized somehow by using : but I have not manage to get it working.
function [ r ] = lhs( expr )
%LHS Returns the left hand side an expression
% LHS(sym('[1-x^2==2*y'; 1+x^2==x+y]')) = [1-x^2; 1+x^2]
cmd = #(e)['lhs(',char(e),')'];
[m,n] = size(expr);
r = sym(zeros(m,n));
for i=1:m
for j=1:n
r(i,j) = evalin(symengine, cmd(expr(i,j)));
end
end
end
Starting R2017a, use "lhs" and "rhs" as
syms x
expr = [1-x^2==2*y; 1+x^2==x+y];
lhsExpr = lhs(expr)
lhsExpr =
1 - x^2
x^2 + 1
rhsExpr = rhs(expr)
rhsExpr =
2*y
x + y
expr = sym('[1-x^2==2*y; 1+x^2==x+y]');
lr = children(expr);
lr{1}
ans =
[ 1 - x^2, 2*y]
Note that this is more robust than EitanT's string manipulation for a simple reason: Your left- and right-hand sides may contain equals-signs themselves.
I'm thinking regular expressions, so here's my shot at this.
Let's say you have a symbolic expression expr, for instance:
expr = sym('[1-x^2==2*y; 1+x^2==x+y]')
Since it cannot be assumed to be a scalar expression, the first step would be splitting it into sub-elements, and converting each one to a string, like so:
C = arrayfun(#(n)char(expr(n)), 1:numel(expr), 'Uniform', false)
(I'm not using a simple char(expr) conversion because it adds the matrix([[...]]) syntax).
Now we use a regular expression search-and-replace to extract the LHS:
C = arrayfun(#(n)char(expr(n)), 1:numel(expr), 'Uniform', false)
C = regexprep(C, '([^><=]*)(?:[><=]*)(.*)', '$1') %// $1 for lhs, $2 for rhs
And then concatenate the elements back into a string and convert it into a symbolic expression:
str = sprintf('%s,', C{:})
result = reshape(sym(str(1:end - 1)), size(expr))
Voila.
Here are copy-paste friendly lhs and rhs functions:
function y = lhs(x)
C = arrayfun(#(n)char(x(n)), 1:numel(x), 'Uniform', false);
C = regexprep(C, '([^><=]*)(?:[><=]*)(.*)', '$1');
str = sprintf('%s,', C{:});
y = reshape(sym(str(1:end - 1)), size(x));
function y = rhs(x)
C = arrayfun(#(n)char(x(n)), 1:numel(x), 'Uniform', false);
C = regexprep(C, '([^><=]*)(?:[><=]*)(.*)', '$2');
str = sprintf('%s,', C{:});
y = reshape(sym(str(1:end - 1)), size(x));
Note that the only difference between lhs and rhs are the replaced tokens in regexprep.
Using $1 extracts the left-hand side, and using $2 extracts the right-hand side.
Say I have a function
a = b / c
and I ask the user to input two of these variables, either b and a or c and a and I want it to calculate the unknown variable without needing to write a function for every variable
In this case I would use:
pseudo-code
if input is a & b
then c = b / a
if input is a & c
then b = a * c
if input is b & c
then a = b / c
I know this is a function with only three variables so it is easy to put it in an if-statement and voilĂ BUT I want to apply it to a system containing lots of equations (a jet engine for example). I used TkSolver before and it was really great, you throw as many equations as you want at it (a jet engine was an example!), you only need to give a number of known quantities and in a few seconds, all the unknowns are calculated (even if I had a known quantity in one side of the equation and unknown on another side mixed with known ones, it will do the maths!)
So, is there a way to do this in MatLab or perhaps python which I'm learning?
Edit to the question, thanks for directing me to use the Symbolic toolbox, it's great, I have another problem:
I couldn't think of a way to let the program know which of the variables is entered. I can do this:
syms f a b c
f = a * c - b %(I want to write a = b / c)
c = 10; a = 5;
X = eval(solve(f,b))
What I want now is a way of letting the user enter two knowns (e.g c & a) and the code will recognise them and solve to the unknown variable (e.g b).
Edit 2: I managed to get what I want, it's a bit long and there might be another way of achieving the same thing.
clear, clc
syms a b c
var = [{'a'}, {'b'}, {'c'}];
var1n = 0;
var2n = 0;
while isvarname(var1n) == 0
var1n = input('Which variable is known: ','s');
while ( any( strcmpi(var1n,var) ) )== 0
fprintf('\nThe variable entered is wrong, please enter a, b, or c')
var1n = input('\nWhich variable is known: ', 's');
end
end
fprintf('\nPlease enter the value of %s', var1n)
var1v = input(': ');
eval([var1n '=' num2str(var1v)]);
while isvarname(var2n) == 0
var2n = input('What is the second known variable: ', 's');
while ( any( strcmpi(var2n,var) ) ) == 0
fprintf('\nThe variable entered is wrong, please enter a, b, or c')
var2n = input('\nWhat is the second known variable: ', 's');
end
end
fprintf('\nPlease enter the value of %s', var2n)
var2v = input(': ');
eval([var2n '=' num2str(var2v)]);
var3n = char ( var ( find( strcmpi(var1n, var) == strcmpi(var2n, var) ) ) );
var3v = solve(a - b / c);
eval([var3n '=' char(var3v)]);
You could use this: http://www.mathworks.de/help/toolbox/symbolic/solve.html but you have to have the symbolic math toolbox (:
EDIT: On the documentation page of solve there's a sentence:
If the right side of an equation is 0, specify the left side as a
symbolic expression or a string:
That means, if you want to solve a = b/c for the value which is NOT set, simply rewrite the equation so that there is a zero on the right hand side:, i.e. a - b/c = 0, than you can use:
syms a b c
% E.g. assign values to a and c and automatically let matlab chose the 'free' variable (in this case, it's b:
a = input('Input var a: ')
a = input('Input var c: ')
solve(a - b/c)
which than gives you b (e.g. entering a = 10 and c = 40 gives you b = a * c = 400). Input function is explained here: http://www.mathworks.de/help/techdoc/ref/input.html! Hope that helps!