How to convert a Maple expression x*y to Matlab for the result x.*y? - matlab

A Maple expression (for example, x^3+x*y) can be converted to Matlab by
with(CodeGeneration):
Matlab(x^3+x*y);
However, in Matlab, there are two kinds of product: A*B and A.*B. The above way will give x^3+x*y. Is there a convenient way to get the result x.^3+x.*y?

The language definition for Maple's CodeGeneration[Matlab] can be extended to handle various instances of the elementwise tilde (~) operator.
Since 'x*~y' seems to automatically simplify to `~`[`*`](x, ` $`, y), and since there appears to be a hard-coded error emitted by the presence of the name " $", then that name is substituted by NULL in the usage code below.
> restart:
> with(CodeGeneration): with(LanguageDefinition):
> LanguageDefinition:-Define("NewMatlab", extend="Matlab",
> AddFunction("`~`[`^`]", [Vector,integer]::Vector,
> proc(X,Y)
> Printer:-Print(X,".^",Y)
> end proc,
> numeric=double),
> AddFunction("`~`[`*`]", [Vector,integer]::Vector,
> proc(X,Y)
> Printer:-Print(X,".*",Y)
> end proc,
> numeric=double));
> expr:=''x^~y + x^~3 + x*~y'':
> Translate(subs(` $`=NULL, expr ), language="NewMatlab");
cg = x.^y + x.^3 + x.*y;
> p := proc(x,y)
> x^~y + x^~3 + x*~y;
> end proc:
> f := subs(` $`=NULL, eval(p) ):
> Translate(f, language="NewMatlab");
function freturn = f(x, y)
freturn = x.^y + x.^3 + x.*y;

For whatever it's worth, Maple 2015 can do this translation directly, without the extra help kindly provided by acer:
> f := (x,y)->x^~y + x^~3 + x*~y:
> CodeGeneration:-Matlab(f);
function freturn = f(x, y)
freturn = x .^ y + x .^ 3 + x .* y;

If the Matlab(x^3+x*y) expression gives out the code x^3+x*y in written format, then you can simply convert it into x.^3+x.y , just by using "Find & Replace" option of any notepad application. Just find all "" and "^" , and then replace them with ".*" and ".^" .
Hope this helps.

Related

Recovering the name of a variable in Maple

I am programming a procedure in Maple. This procedure receive a list of vector fields (from the ``DifferentialGeometry'' package). I want that in the output they appear, together with the performed computations, the name of the vector fields introduced by the user.
During the procedure I refer to them by the name I have given to the parameter, but I don't actually know the "names of the variables". Is there a way to recover them? I have being looking for in the Maple documentation and in the DGinfo help, but I didn't get anything.
EXAMPLE ADDED
I have simplified the problem to the following. Consider the code:
with(DifferentialGeometry);
DGsetup([x, u], M);
X := evalDG(D_u*x+2*D_x);
myproc := proc (var)
return evalDG(var+D_u)
end proc;
myproc(X)
The output is
But I want modify the code in such a way that the output were something like
X+D_u is 2 D_x + (1+x) D_u
That is, I want to use the name ("X") of the variable in the output, not only the value (2 D_x + x D_u).
Thank you for your time.
Here is one way of handling your example.
restart;
with(DifferentialGeometry):
DGsetup([x, u], M):
myproc := proc(var::uneval) local evar;
evar := eval(var);
return evalDG(var+D_u) = evalDG(evar+D_u);
end proc:
X := evalDG(D_u*x+2*D_x):
myproc(X);
X + D_u = 2 D_u + (1 + x) D_u
Here is a variant on that idea, with two such parameters on the procedure, but also handling then in a more general manner.
restart;
with(DifferentialGeometry):
DGsetup([x, u], M):
myproc := proc(var1::uneval, var2::uneval)
local evars, res;
evars := [var1=eval(var1), var2=eval(var2)];
res := var1 + var2 + D_u;
return res = evalDG(eval(res, evars));
end proc:
X1 := evalDG(D_u*x+2*D_x):
X2 := evalDG(D_u*x+3*D_x):
myproc(X1, X2);
X1 + X2 + D_u = 5 D_x + (1 + 2 x) D_x

How do I create a simplified logic circuit of this given [(A’B’)’ + (A’+ B’)’]’ ? and What is the simplified Boolean expression?

I have to draw the simplified logic circuit of this given [(A’B’)’ + (A’+ B’)’]’ and also get the simplified boolean expression
From DeMorgan Theory
((A'B')' + (A'+ B')')'=(A+B + AB)'
(A+B + AB)' = (A+B)'. (AB)'
(A+B)'. (AB)' = (A'.B') .(A'+B')
assume
X=A' ,Y=B'
we can conclude that
(XY)(X+Y) is (XY)
as both (XY) and (X+Y) has to be 1 to produce 1 at output as seen from truth table of (XY)(X+Y) is (XY) is identical to XY
so as final result
((A'B')' + (A'+ B')')'=(A+B + AB)'
(A+B + AB)' = (A+B)'. (AB)'
(A+B)'. (AB)' = (A'.B') .(A'+B') = A'B'
before simplifying
after simplifying
comparing outputs to make sure
(A'B')' = A + B
Using DeMorgan's theorem (AB)' = A' + B'
(A'+B')' = AB
Again, using DeMorgan's theorem (A+B)' = A'B'
Therefore, now we have the expression:
(A+B + AB)'
Taking A+B as X and AB as Y
(X+Y)' = X'Y'
= (A+B)'·(AB)'
Now, creating a logic circuit is fairly simple for this expression, inputs A and B are fed to a NOR gate and NAND gate simultaneously whose outputs act as input to an AND gate

Matlab: replace specific argument that appears more than once

let's say I have s=g(1,2,0)+g(1,3,0)+u(1,3)+g(1,1,0) where g, u are functions; I want to replace all 3rd arguments of g to something I choose without going through my script and doing it manually.
x = ... % assign some value beforehand
s = g(1,2,x) + g(1,3,x) + u(1,3) + g(1,1,x)
What follows is an ugly hack and I don't recommend using it:
g = #(a,b,c) g(a,b,0)
This redefines g function in a way that executing after that:
s = g(1,2,5) + g(1,3,3) + u(1,3) + g(1,1,2)
actually executes:
s = g(1,2,0) + g(1,3,0) + u(1,3) + g(1,1,0)

Finding all solutions to a non-linear equation system with MuPAD

My question is if there is a good way to use MuPAD functions in a Matlab script. The background is that I have a problem where I need to find all solutions to a set of non-linear equations. The previous solution was to use solve in Matlab, which works for some of my simulations (i.e., some of the sets of input T) but not always. So instead I'm using MuPAD in the following way:
function ut1 = testMupadSolver(T)
% # Input T should be a vector of 15 elements
mupadCommand = ['numeric::polysysroots({' eq1(T) ' = 0,' ...
eq2(T) '= 0},[u, v])'];
allSolutions = evalin(symengine, mupadCommand);
ut1 = allSolutions;
end
function strEq = eq1(T)
sT = #(x) ['(' num2str(T(x)) ')'];
strEq = [ '-' sT(13) '*u^4 + (4*' sT(15) '-2*' sT(10) '-' sT(11) '*v)*u^3 + (3*' ...
sT(13) '-3*' sT(6) '+v*(3*' sT(14) '-2*' sT(7) ')-' sT(8) '*v^2)*u^2 + (2*' ...
sT(10) '-4*' sT(1) '+v*(2*' sT(11) '-3*' sT(2) ')+v^2*(2*' sT(12) ' - 2*' ...
sT(3) ')-' sT(4) '*v^3)*u + v*(' sT(7) '+' sT(8) '*v+' sT(9) '*v^2)+' sT(6)];
end
function strEq = eq2(T)
sT = #(x) ['(' num2str(T(x)) ')'];
strEq = ['(' sT(14) '-' sT(13) '*v)*u^3 + u^2*' '(' sT(11) '+(2*' sT(12) '-2*' sT(10) ...
')*v-' sT(11) '*v^2) + u*(' sT(7) '+v*(2*' sT(8) '-3*' sT(6) ')+v^2*(3*' sT(9) ...
'-2*' sT(7) ') - ' sT(8) '*v^3) + v*(2*' sT(3) '-4*' sT(1) '+v*(3*' sT(4) ...
'-3*' sT(2) ')+v^2*(4*' sT(5) ' - 2*' sT(3) ')-' sT(4) '*v^3)+' sT(2)];
end
I have two queries:
1) In order to use MuPAD I need to rewrite my two equations for the equation-system as strings, as you can see above. Is there a better way to do this, preferably without the string step?
2) And regarding the format output; when
T = [0 0 0 0 0 0 0 0 0 0 1 0 1 0 1];
the output is:
testMupadSolver(T)
ans =
matrix([[u], [v]]) in {matrix([[4.4780323328249527319374854327354], [0.21316518769990291263811232040432]]), matrix([[- 0.31088044854742790561428736573347 - 0.67937835289645431373983117422178*i], [1.1103383836576028262792542770062 + 0.39498445715599777249947213893789*i]]), matrix([[- 0.31088044854742790561428736573347 + 0.67937835289645431373983117422178*i], [1.1103383836576028262792542770062 - 0.39498445715599777249947213893789*i]]), matrix([[0.47897094942962218512261248590261], [-1.26776233072168360314707025141]]), matrix([[-0.83524238515971910583152318717102], [-0.66607962429342496204955062300669]])} union solvelib::VectorImageSet(matrix([[0], [z]]), z, C_)
Can MuPAD give the solutions as a set of vectors or similarly? In order to use the answer above I need to sort out the solutions from that string-set of solutions. Is there a clever way to do this? My solution so far is to find the signs I know will be present in the solution, such as '([[' and pick the numbers following, which is really ugly, and if the solution for some reason looks a little bit different than the cases I've covered it doesn't work.
EDIT
When I'm using the solution suggested in the answer below by #horchler, I get the same solution as with my previous implementation. But for some cases (not all) it takes much longer time. Eg. for the T below the solution suggested below takes more than a minute whilst using evalin (my previous implementation) takes one second.
T = [2.4336 1.4309 0.5471 0.0934 9.5838 -0.1013 -0.2573 2.4830 ...
36.5464 0.4898 -0.5383 61.5723 1.7637 36.0816 11.8262]
The new function:
function ut1 = testMupadSolver(T)
% # Input T should be a vector of 15 elements
allSolutions = feval(symengine,'numeric::polysysroots', ...
[eq1(T),eq2(T)],'[u,v]');
end
function eq = eq1(T)
syms u v
eq = -T(13)*u^4 + (4*T(15) - 2*T(10) - T(11)*v)*u^3 + (3*T(13) - 3*T(6) ...
+ v*(3*T(14) -2*T(7)) - T(8)*v^2)*u^2 + (2*T(10) - 4*T(1) + v*(2*T(11) ...
- 3*T(2)) + v^2*(2*T(12) - 2*T(3)) - T(4)*v^3)*u + v*(T(7) + T(8)*v ...
+ T(9)*v^2) + T(6);
end
function eq = eq2(T)
syms u v
eq = (T(14) - T(13)*v)*u^3 + u^2*(T(11) + (2*T(12) - 2*T(10))*v ...
- T(11)*v^2) + u*(T(7) + v*(2*T(8) - 3*T(6) ) + v^2*(3*T(9) - 2*T(7)) ...
- T(8)*v^3) + v*(2*T(3) - 4*T(1) + v*(3*T(4) - 3*T(2)) + v^2*(4*T(5) ...
- 2*T(3)) - T(4)*v^3) + T(2);
end
Is there a good reason to why it takes so much longer time?
Firstly, Matlab communicates with MuPAD via string commands so ultimately there is no way of getting around the use of strings. And because it's the native format, if you're passing large amounts of data into MuPAD, the best approach will be to convert everything to strings fast and efficiently (sprintf is usually best). However, in your case, I think that you can use feval instead of evalin which allows you to pass in regular Matlab datatypes (under the hood sym/feval does the string conversion and calls evalin). This method is discussed in this MathWorks article. The following code could be used:
T = [0 0 0 0 0 0 0 0 0 0 1 0 1 0 1];
syms u v;
eq1 = -T(13)*u^4 + (4*T(15) - 2*T(10) - T(11)*v)*u^3 + (3*T(13) - 3*T(6) ...
+ v*(3*T(14) -2*T(7)) - T(8)*v^2)*u^2 + (2*T(10) - 4*T(1) + v*(2*T(11) ...
- 3*T(2)) + v^2*(2*T(12) - 2*T(3)) - T(4)*v^3)*u + v*(T(7) + T(8)*v ...
+ T(9)*v^2) + T(6);
eq2 = (T(14) - T(13)*v)*u^3 + u^2*(T(11) + (2*T(12) - 2*T(10))*v ...
- T(11)*v^2) + u*(T(7) + v*(2*T(8) - 3*T(6) ) + v^2*(3*T(9) - 2*T(7)) ...
- T(8)*v^3) + v*(2*T(3) - 4*T(1) + v*(3*T(4) - 3*T(2)) + v^2*(4*T(5) ...
- 2*T(3)) - T(4)*v^3) + T(2);
allSolutions = feval(symengine, 'numeric::polysysroots',[eq1,eq2],'[u,v]');
The last argument still needed to be a string (or omitted) and adding ==0 to the equations also doesn't work, but the zero is implicit anyways.
For the second question, the result returned by numeric::polysysroots is very inconvenient and not easy to work with. It's a set (DOM_SET) of matrices. I tried using coerce to convert the result to something else to no avail. I think you best bet it to convert the output to a string (using char) and parse the result. I do this for simpler output formats. I'm not sure if it will be helpful, but feel free to look at my sym2float which just handles symbolic matrices (the 'matrix([[ ... ]])' part go your output) using a few optimizations.
A last thing. Is there a reason your helper function includes superfluous parentheses? This seems sufficient
sT = #(x)num2str(T(x),17);
or
sT = #(x)sprintf('%.17g',T(x));
Note that num2str only converts to four decimal places by default. int2str (or %d should be used if T(x) is always an integer).

how to solve this boolean algrbra expression

I would like help simplifying this boolean algebra expression:
B*C + ~A*~B + ~A*~C => A*B*C + ~A
I need to know the steps of how to simplify it to the ABC + ~A
'*' indicates "AND"
'+' indicates "OR"
"~A" indicates "A NOT"
Any help would be appreciated!
Thank you!
For a better view, i'll skip * for conjunction, and use ' for negation.
First you shall expand the 2 term disjunctions: Expand B*C , A'*B' and A'*C'
1) (A + A')BC + A'B'(C + C') + A'(B + B')C'
now distribute the parentheses.
2) ABC + A'BC + A'B'C + A'B'C' + A'BC' + A'B'C'
the fourth term and the last term are the same, A'B'C', so ignore one of them since p + p = p or you can expand the situation for your needs (might be needed for some situations) as in p+p+p+p+....+p = p
3) So now, lets try to search for common terms. See the 2nd term and 5th term, A'BC and A'BC'. Take common parenthesis, A'B(C+C') => A'B.
Do the same for 3rd term and the 4th term, A'B'C and A'B'C'. A'B'(C+C') => A'B' since X+X' = 1.
now we have:
ABC + A'B + A'B'
4) take common parenthesis again, 2nd and 3rd term: A'(B+B')
There you have ABC + A'
BC + A'B' + A'C' => ABC + A'