So, I have a really long symbolic exrpression in Matlab that I want to copy/paste into a JavaScript-code to animate a numerical solution for it. The problem is that some places in my code i get exponents (mostly ^2), when I'd rather have Matlab express it as A*A.
I have mulitple (and different) expressions like
cos(th2t)^2
That I would rather have expressed as
cos(th2t)*cos(th2t)
Any way I can do this? The alternative is to use a text editor afterward and search for powers of 2 and replace it, but there are multiple different expressions, so that would take some time...
This is an example of one of the exrpressions I end up with:
(J31*(2*ddth2t*cos(th1t) - 2*w12*w13 - 4*dth1t*dth2t*sin(th1t) - 4*dth2t*w13*sin(th1t) + dth1t^2*sin(2*th2t)*cos(th1t) - w12^2*sin(2*th2t)*cos(th1t) + w13^2*sin(2*th2t)*cos(th1t) + 2*dth2t*w11*sin(2*th2t) + 2*w12*w13*cos(th2t)^2 + ddth1t*sin(2*th2t)*sin(th1t) + 4*dth1t*dth2t*cos(th2t)^2*sin(th1t) + 2*dth1t*w13*sin(2*th2t)*cos(th1t) + 4*dth2t*w13*cos(th2t)^2*sin(th1t) + w11*w12*sin(2*th2t)*sin(th1t) + 4*dth1t*w12*cos(th1t)^2*cos(th2t)^2 - 2*dth1t*w11*sin(2*th1t)*cos(th2t)^2 - 2*dth2t*w11*sin(2*th2t)*cos(th1t)^2 + 2*w12*w13*cos(th1t)^2*cos(th2t)^2 - w11*w13*sin(2*th1t)*cos(th2t)^2 - 4*dth2t*w12*cos(th1t)*cos(th2t)*sin(th1t)*sin(th2t)))/(2*(J11 + J31))
Steve's answer should work fine if you want to rely on the ** operator. However, since that operator is not officially supported, and that solution doesn't directly answer the OP's question, here is a function that can expand out the exponents in a symbolic expression.
function [ text ] = remove_powers( exp )
%Cleans the powers from T, and return expanded text representation
% Define functions
enclose =#(t) ['(' t ')'];
expand_pow=#(b,p) strjoin(strcat(cell(1,p),enclose(char(b))),'*');
count_pow=#(s) arrayfun(#(k) count(char(s(k)),'^'), 1:length(s));
sym2str = #(s) strrep(char(s), ' ', '');
% Check for fractions
[N,D]=numden(exp);
if ~isequal(D,sym(1))
% pass up the num and den
text = [remove_powers(N) '/' enclose(remove_powers(D))];
else
% Split a into subterms
Ts = children(exp);
% Clean children
has_pow=count_pow(Ts)>0;
text = sym2str(exp);
if sum(count_pow(Ts))<count_pow(exp)
% We have removed a power, clean it, expand it, and pass up
text = expand_pow(remove_powers(Ts(1)),Ts(2));
else
% Just clean the unclean children and pass up
for t=Ts(has_pow)
text = strrep(text,sym2str(t),remove_powers(t));
end
end
end
end
The function uses the children function in Matlab to recursively clean each subexpression and replace it (as text) in the parent. This method is better than using regex because it avoids the issue of parsing the syntax, as Steve mentioned in the comment with respect to cos(x^2+2*y)^2.
Which makes for a good example:
syms x y real
exp = cos(x^2+2*y)^2;
cleaned_exp = remove_powers(exp)
Outputs: (cos(2*y+(x)*(x)))*(cos(2*y+(x)*(x)))
Notice that since Matlab is doing the parsing, there was no need to parse the order of precedence for the '^' operators, which could be difficult to accomplish with regex.
To test the OP's example:
syms ddth1t dth1t th1t ddth2t dth2t th2t w11 w12 w13 J11 J31 real
exp = (J31*(2*ddth2t*cos(th1t) - 2*w12*w13 - 4*dth1t*dth2t*sin(th1t) - 4*dth2t*w13*sin(th1t) + dth1t^2*sin(2*th2t)*cos(th1t) - w12^2*sin(2*th2t)*cos(th1t) + w13^2*sin(2*th2t)*cos(th1t) + 2*dth2t*w11*sin(2*th2t) + 2*w12*w13*cos(th2t)^2 + ddth1t*sin(2*th2t)*sin(th1t) + 4*dth1t*dth2t*cos(th2t)^2*sin(th1t) + 2*dth1t*w13*sin(2*th2t)*cos(th1t) + 4*dth2t*w13*cos(th2t)^2*sin(th1t) + w11*w12*sin(2*th2t)*sin(th1t) + 4*dth1t*w12*cos(th1t)^2*cos(th2t)^2 - 2*dth1t*w11*sin(2*th1t)*cos(th2t)^2 - 2*dth2t*w11*sin(2*th2t)*cos(th1t)^2 + 2*w12*w13*cos(th1t)^2*cos(th2t)^2 - w11*w13*sin(2*th1t)*cos(th2t)^2 - 4*dth2t*w12*cos(th1t)*cos(th2t)*sin(th1t)*sin(th2t)))/(2*(J11 + J31));
cleaned_exp = remove_powers(exp);
isequal(sym(cleaned_exp),exp) % This should be 1
count(cleaned_exp,'^') % This should be 0
As expected, the new expression is equivalent to the original, but has no '^' symbols.
This answer suggests that you could call the exponential operator in Javascript with e.g. A**2. As such you could replace all instances of ^ with **.
(Solution from comments)
Related
I need to compute some fairly long expressions that contain common subexpressions. For example, consider the following two expressions:
double dfdx1 = 2 * (-x2 + x1 - sin(b2)*n34 + cos(b2)*sin(c2)*n24 - cos(b2)*cos(c2)*n14 + sin(b1)*m34 - cos(b1)*sin(c1)*m24 + cos(b1)*cos(c1)*m14);
double dfdx2 = -2 * (-x2 + x1 - sin(b2)*n34 + cos(b2)*sin(c2)*n24 - cos(b2)*cos(c2)*n14 + sin(b1)*m34 - cos(b1)*sin(c1)*m24 + cos(b1)*cos(c1)*m14);
Aside from eliminating all the trigonometric functions, one obvious elimination is dfdx2 = -dfdx1. The question is whether the compiler will recognise this. I found that using MATLAB's MuPad generate::optimize() function does not, which rather surprised me.
More generally, will the compiler recognise that f2 = -f1 in the example below:
double f1 = a*a + b*b - c*a - c*b;
double f2 = c*a + c*b - a*a - b*b;
Or will it just eliminate the terms a*a, b*b, c*a and c*b?
I am using the MSVC compiler, but I guess that they all do pretty much the same thing.
Normally compilers should recognize this and carry out the asked transformation if you enable "fast math" (-ffast-math for gcc). The reason is that floating point operations are not perfectly exact and the order of the evaluation of an expression might matter.
Example (for doubles, all constants are actually considered being results of other operations):
"1e100"+"1.0"-"1e100" results in 0.0
"1e100"-"1e100"+"1.0" results in 1.0
So the compiler will only reorder expressions if you explicitly allow such transformations.
I would like to have short-hand form about many parameters which I just need to keep fixed in Matlab 2016a because I need them in many places, causing many errors in managing them separately.
Code where the signal is 15x60x3 in dimensions
signal( 1:1 + windowWidth/4, 1:1 + windowWidth,: );
Its pseudocode
videoParams = 1:1 + windowWidth/4, 1:1 + windowWidth,: ;
signal( videoParams );
where you cannot write videoParams as string but should I think write ":" as string and everything else as integers.
There should be some way to do the pseudocode.
Output of 1:size(signal,3) is 3 so it gives 1:3. I do not get it how this would replace : in the pseudocode.
Extension for horcler's code as function
function videoParams = fix(k, windowWidth)
videoParams = {k:k + windowWidth/4, k:k + windowWidth};
end
Test call signal( fix(1,windowWidth){:}, : ) but still unsuccessful giving the error
()-indexing must appear last in an index expression.
so I am not sure if such a function is possible.
How can you make such a int-string-int input for the matrix?
This can be accomplished via comma-separated lists:
signal = rand(15,60,3); % Create random data
windowWidth = 2;
videoParams = {1:1+windowWidth/4, 1:1+windowWidth, 1:size(signal,3)};
Then use the comma-separated list as such:
signal(videoParams{:})
which is equivalent to
signal(1:1+windowWidth/4, 1:1+windowWidth, 1:size(signal,3))
or
signal(1:1+windowWidth/4, 1:1+windowWidth, :)
The colon operator by itself is shorthand for the entirety of a dimension. However, it is only applicable in a direct context. The following is meaningless (and invalid code) as the enclosing cell has no defined size for its third element:
videoParams = {1:1+windowWidth/4, 1:1+windowWidth, :};
To work around this, you could of course use:
videoParams = {1:1+windowWidth/4, 1:1+windowWidth};
signal(videoParams{:},:)
I have the following equation and want to simplify it using Matlab's MuPAD.
So, I used this in MuPAD:
Simplify(Gb = Gm*((2*(Gd+t)+3*Gm+3*P*(Gd+t-Gm))/(2*(Gd+t)+3*Gm-2*P*(Gd+t-Gm))))
and I get this:
Gb*(3*Gm + 2*Gd + 2*t - 2*P*(Gd - Gm + t)) = Gm*(3*Gm + 2*Gd + 2*t + 3*P*(Gd - Gm + t)) and 3*Gm + 2*Gd + 2*t <> 2*P*(Gd - Gm + t)
I cannot understand the first and second part (after "and"), what are these?
As per MuPAD's documentation, the relational operator <> denotes inequality, i.e., the left- and right-hand side are not equal. In other words, the simplification (before "and") is only valid if 3*Gm + 2*Gd + 2*t is not equal to 2*P*(Gd - Gm + t). This is the same thing as requiring that the denominator of the original expression not be zero (which would make it undefined).
Note that in MuPAD for Matlab R2015b, the <> operator is displayed as ≠ and "and" is rendered as ∧ (logical and):
I am working on a property of a given set of natural numbers and it seems difficult to compute. I build a function 'fun' which takes two inputs, one is the cardinal value and another is the set. If the set is empty then fun should return 0 because fun depends on the product of the set and fun on all subsets of the complement set.
For clarification here is an example:
S is a set given S={1,2,3,4}. The function fun(2,S) is defined as
fun(2,S)=prod({1,2})*[fun(1,{3}) + fun(1,{4}) + fun(2,{3,4})] +
prod({1,3})*[fun(1,{2}) + fun(1,{4}) + fun(2,{2,4})] +
prod({1,4})*[fun(1,{3}) + fun(1,{2}) + fun(2,{2,3})] +
prod({2,3})*[fun(1,{4}) + fun(1,{1}) + fun(2,{1,4})] +
prod({2,4})*[fun(1,{1}) + fun(1,{3}) + fun(2,{3,1})] +
prod({3,4})*[fun(1,{1}) + fun(1,{2}) + fun(2,{1,2})]
prod is defined as the product of all elements in a set, for example
prod({1,2})=2;
prod({3,2})=6
I am trying to compute the function fun using recursive method in MATLAB but it's not working. The base case is the cardinal value should be more than zero that means there should be at least one element in the set other wise prod will be zero and fun will return zero.
Update Pseudo code:
fun(i,S)
if |S|=1 && i!=0
return prod(S)
else if i==0
return 0
else
prod(subset s', s' is a subset of S and |s'|=i)*(sum over fun((for i=1 to m),{S-s'}), m=|S-s'|) //I don't know how to write code for this part and need help.
end if
end fun
prod(s)
n=|s|
temp=1
for i=1 to n
temp *=s(i) //s(1) is the 1st element of s
end for
return temp
end prod
Thanks.
With the pseudo code you added to your question it's nearly impossible to implement the function. Everything is put into one line which is incomplete (at least the outer sum is missing).
1) Formalize your algorithm in a way it can be used to implement. The following pseudo code is probably not correct because I don't exactly know what you want, but it should give an idea how to do it.
fun(i,S)
if i==0
return 0
else if |S|=1
return S
else
r=0
for s1 in subsets of S with size i
f=0
for s2 in subsets of setdiff(S,s') with size <=i
f=f+fun(s2,|s2|)
end
r=r+prod(s1)*f
end for
end if
end fun
2) use arrays [1,2,3,4] instead of cells {1,2,3,4}
3) prod is a built-in function, no need to reimplement it.
I've did my code like that :
r= randper(3)
switch num2str(r(i))
case '1' F1=func1(var1);
case '2' F2=func2(var2);
case '3' F3=func3(var3);
otherwise disp('error');
end
In Matlab, i coudn't find the way to concatenate r with "func" and that could e read as a function not as string
Usually in other langage I could do it like that (it's just an example)
r= randper(3)
F+r(i)=func+r(i)(var+r(i))
Q: How could I shorten my code in one line ?
Thanks !
Ok, there's two ways of doing this: the quick way, and the nice way.
The quick way uses eval which evaluates a string as though it were m-code.
r= randper(3)
eval('F' + num2str(r(i)) + ' = func' + r(i) + '(var' + r(i) + ')');
The nice way creates an array of function pointers and then calls those:
func{1} = #func1;
func{2} = #func2;
func{3} = #func3;
r = randperm(3);
F{r(i)} = func{r(i)}(var(r(i)));
The above method helps avoid the myriad of issues that can crop up when you have used eval.