Replacing symbolic derivatives in MATLAB - matlab

I have a symbolic function that looks like this
syms x y(x) h
fn(x) = y + (h^2*(diff(y(x), x) + 2))/2 + (h^5*diff(y(x), x, x, x, x))/120 + (h^3*diff(y(x), x, x))/6 + (h^4*diff(y(x), x, x, x))/24 + h*(2*x + y(x) - 1)
I'd like to replace all instances of derivatives of y with its first derivative, i.e.
subs(fn, sym('diff(y(x), x)'), dy)
where dy is already defined as
dy(x) = 2*x + y(x) - 1
The result is the following:
ans(x) =
y + (h^2*(2*x + y(x) + 1))/2 + (h^5*diff(y(x), x, x, x, x))/120 + (h^3*diff(y(x), x, x))/6 + (h^4*diff(y(x), x, x, x))/24 + h*(2*x + y(x) - 1)
It replaces the first derivative, but not the higher derivatives. What I want is for the h^5 term to have (h^5*diff(dy(x), x, x, x). Is there any way to do that?
My current method is pretty hackish and involves converting the sym to a string, replacing first derivatives with dy, then converting back to a sym and evaluating to reduce the order of each term of the series by one, but it has to be recursive because at each stage derivatives of dy are then replaced by something containing diff(y, ...). I was hoping there would be a cleaner way to deal with this.

You need to keep in mind that Matlab treats things like diff(y,x) and diff(y,x,2) as distinct variables. It doesn't know how to substitute diff(y,x) into diff(y,x,2) because such a general operation for an abstract function (one with out an explicit definition, e.g., y(x)) is ill-defined.
How about something like this that performs substitution from the opposite end, starting with the highest order derivatives:
syms y(x) h
dy(x) = 2*x + y - 1
fn(x) = y + (h^2*(diff(y, x) + 2))/2 + (h^5*diff(y, x, 4))/120 + (h^3*diff(y, x, 2))/6 + (h^4*diff(y, x, 3))/24 + h*(2*x + y - 1)
fn2 = subs(fn, diff(y, x, 4), diff(dy, x, 3));
fn2 = subs(fn2, diff(y, x, 3), diff(dy, x, 2));
fn2 = subs(fn2, diff(y, x, 2), diff(dy, x));
fn2 = subs(fn2, diff(y, x), dy);
This returns
fn2(x) =
y(x) + (h^2*(2*x + y(x) + 1))/2 + (h^3*(2*x + y(x) + 1))/6 + (h^4*(2*x + y(x) + 1))/24 + (h^5*(2*x + y(x) + 1))/120 + h*(2*x + y(x) - 1)
Or you can leave dy(x) as an abstract symbolic expression initially:
syms y(x) dy(x) h
fn(x) = y + (h^2*(diff(y, x) + 2))/2 + (h^5*diff(y, x, 4))/120 + (h^3*diff(y, x, 2))/6 + (h^4*diff(y, x, 3))/24 + h*(2*x + y - 1)
fn2 = subs(fn, diff(y, x, 4), diff(dy, x, 3));
fn2 = subs(fn2, diff(y, x, 3), diff(dy, x, 2));
fn2 = subs(fn2, diff(y, x, 2), diff(dy, x));
fn2 = subs(fn2, diff(y, x), dy)
which returns
fn2(x) =
y(x) + (h^4*diff(dy(x), x, x))/24 + (h^2*(dy(x) + 2))/2 + (h^5*diff(dy(x), x, x, x))/120 + (h^3*diff(dy(x), x))/6 + h*(2*x + y(x) - 1)

Related

How to solve the following problem on MATLAB

a(x) here is a type of equation used in signal
Let
y(x) = x^3 + x^2 + x + 1
a(x) is inputed by the user so for example if user inputs
a(x) = D2 + D + 6
y(x)*a(x) = D2(x^3 + x^2 + x + 1) + D(x^3 + x^2 + x + 1) + 6(x^3 + x^2 + x + 1)
here D2(x^3 + x^2 + x + 1) = 6x + 2 and D(x^3 + x^2 + x + 1) = 3x^2 + 2x + 1
So D is differentiation and D2 is double differential
So i want to know how i would do something like this on MATLAB
Use Matlab symbolic computation toolbox https://www.mathworks.com/products/symbolic.html
Calculus
Evaluate exact analytical solutions for definite or indefinite integral,
calculate derivatives of symbolic expressions or functions,
and approximate functions using series expansions.

Create a g-torus

I'm looking for an easy, elegant way to create a triangle mesh of a torus with an arbitrary number of holes. Here are some examples.
First, the AI had a problem with the question title, then a human decided "Closed. This question needs to be more focused."
Anyway, here is one direction:
% sphere
%fun = #(x, y, z) x.^2 + y.^2 + z.^2 - 1;
% 3-torus
% http://metamathological.blogspot.com/2013/01/today-i-learned-how-to-plot-doughnut.html
fun = #(x, y, z) (x.^2 + (y - 2).^2 - 1) .* ((x - sqrt(3)).^2 + (y + 1).^2 - 1) .* ((x + sqrt(3)).^2 + (y + 1).^2 - 1) - 0.0015*(x.^2 + y.^2 + 7*z.^2).^5;
% 4-torus
%fun = #(x, y, z) ((x - 2).^2 + (y - 2).^2 - 1) .* ((x - 2).^2 + (y + 2).^2 - 1) .* ((x + 2).^2 + (y - 2).^2 - 1) .* ((x + 2).^2 + (y + 2).^2 - 1) - 0.02*(x.^2 + y.^2 + 7*z.^2).^5;
res = 0.1;
r = 8;
x = -r:res:r;
y = -r:res:r;
z = -r:res:r;
[X, Y, Z] = meshgrid(x, y, z);
V = fun(X,Y,Z); % volumetric function (e.g. distance function)
I = isosurface(x ,y , z, V, 0); % extract level set as a mesh
p = patch(I);
isonormals(X, Y, Z, V, p);
p.FaceColor = 'red';
p.EdgeColor = 'none';
daspect([1 1 1])
view(3);
axis tight;
camlight;
lighting gouraud;

Express an expression in terms of other expressions in MATLAB

Is there any way to express an expression in terms of other expressions in MATLAB?
For example, the following expressions have been written as sum (X + Y) and product (XY)
1/X + 1/Y = (X + Y)/XY
1/X^2 + 1/Y^2 + 2/(XY) = (X + Y)^2/(XY)
2*X/Y + 2*Y/X = 2*((X + Y)^2 - 2*X*Y)/(XY)
I know about the rewrite() function but I couldn't find how it can be used to do what I want?
There are a few different functions you can try to change the format of your symbolic expression:
collect: collects coefficients (can specify an expression to collect powers of):
>> collect(1/X + 1/Y)
ans =
(X + Y)/(Y*X)
simplify: perform algebraic simplification:
>> simplify(1/X^2 + 1/Y^2 + 2/(X*Y))
ans =
(X + Y)^2/(X^2*Y^2)
numden: convert to a rational form, with a numerator and denominator:
>> [n, d] = numden(2*X/Y + 2*Y/X)
n =
2*X^2 + 2*Y^2
d =
X*Y
>> n/d
ans =
(2*X^2 + 2*Y^2)/(X*Y)

Simplifying following Boolean Expression and verify using Karnaugh Map

I'm having trouble simplifying these two boolean expressions algebraically and proving them with a Karnaugh Map. How can I do this?
These are my two expressions:
1) (X * Y) + (X' * Y * Z')+ (Y * Z)
2) (X * Y') + Z + (X' + Y)+ (Y * Z)
I've tried going through it using the boolean theorems and laws to reduce them but I always come up with different answers. My answers usually comes up as this.
1) (Y * Z') + (X' * Y)
2) (X' * Y') + (X * Y' * Z')
I don't know if my K-Map is wrong, but I do need someone to help me understand how to solve this problem and the steps or laws I need to get the answer, so that I can master it. It is practice for exam, and I suck at boolean algebra. I appreciate it.
Let's start with the first expression:
E = XY + X'YZ' + YZ
The three terms have Y, then we can factor it out
E = Y(X + X'Z' + Z)
Now let's concentrate in the expression in parenthesis S = X + X'Z' + Z:
S = X + X'Z' + Z
= X + (X + Z)' + Z (De Morgan)
= (X + Z) + (X + Z)' (regrouping)
so, despite the fact that this still looks complex it has the form
S = p + p'
for p = X + Z, right? But p + p' = 1 (or true) no matter the value of p. Thus the expression S is 1 and we get
E = Y(X + X'Z' + Z) = YS = Y1 = Y
In other words, the first expression reduces to Y.
Notice also that it is not that hard to see why S = 1 without rewriting it. There are three cases: (a) If X is true, then certainly the expression is true. (b) If Z is true, the result is true also. (c) If none of X and Z are true then both are false and X'Z' is true. So, in each of these 3 cases at least one of the terms is true, hence their sum.
Let's now consider the second expression
F = XY' + Z + (X' + Y) + YZ
The first thing to note is that XY' is the opposite of (X' + Y):
(X' + Y) = (XY')' (De Morgan)
So,
F = XY' + (XY')' + Z + YZ
Again, regardless of the fact that XY' + (XY')' looks complicated, it is an expression of the form p + p'. But p + p' = 1 (it is always true) and therefore
F = 1 + Z + YZ = 1
no matter the values of Y and Z. So, the second expression is nothing but 1 (aka true).

Solve finds wrong solution?

I have this equation in x and y:
(x + y)^(1/2) - 6*y*(x + y)^5 - (x + y)^6 + (x - 1)/(2*(x + y)^(1/2)) = 0.
Now I call the solver:
R_c = #(y)solve((x + y)^(1/2) - 6*y*(x + y)^5 - (x + y)^6 + (x - 1)/(2*(x + y)^(1/2)), x, 'Real', true);
which gives me the implicit solutions as a function of y. Now try
R_c(.3)
to find the explicit solution at y = 0.3. MATLAB's answer is:
ans =
0.42846617518653978966562924618638
0.15249587894102346284238111155954
0.12068186494007759990714181154349
However, the last entry in this array is NOT a solution. Test:
double(subs(subs((x + y)^(1/2) - 6*y*(x + y)^5 - (x + y)^6 + (x - 1)/(2*(x + y)^(1/2)), x, .12068186494007759990714181154349), y, .3))
yields
-0.0585.
This is not a rounding error. The other 2 solutions work perfectly and solve the equation correctly. I wonder where MATLAB the third value gets from. Can anyone help?