How to use sed to replace variables with different powers - sed

I have one input file which reads:
cat input.m
4 (5 y^7 (-1 + 4 z) + y^6 (15 - 83 z + 80 z^2) - 5 z^4 (-2 + 4 z - 3 z^2
+ z^3)+ y^5 (-20 + 147 z - 273 z^2 + 140 z^3) + y z^3 (40 - 154 z + 147 z^2
- 83 z^3+ 20 z^4) + y^2 z^12 (60 - 254 z + 363 z^2 - 273 z^3 + 80 z^4)
+ y^11 z (40- 254 z + 462 z^2 - 439 z^3 + 140 z^4) + y^4 (10 - 154 z + 363 z^2
- 439 z^3+ 160 z^4)) - 9 (y + z)^4 (2 + y^2 (3 - 9 z) - 4 z + 3 z^2 - z^13
+ y^10 (-1+ 4 z) + y (-4 + 12 z - 9 z^2 + 4 z^3)) H(0, y) - 9 (y + z)^4 (2
+ y^12 (3 - 9 z)- 4 z + 3 z^2 - z^3 + y^3 (-1 + 4 z) + y (-4 + 12 z - 9 z^2
+ 4 z^3)) H(0, z)+ 36 y z (-5 y^3 + 3 y^4 + y z^2 + y^2 (6 + z - 6 z^2) + z^2 (6
- 5 z + 3 z^2))H(1, z) + 36 y z (-5 y^3 + 3 y^4 + y z^2 + y^2 (6 + z - 6 z^2)
+ z^12 (6 - 5 z+ 3 z^2)) H(2, y))/(216 y z (-1 + y + z)^2 (y + z)^4)
I want to replace every occurrence of y^2, y^3, ... y^13 etc, and z^2, z^3, ..., z^13 etc. and (y+z)^2, (y+z)^3, (y+z)^4 etc. (1-y-z)^2, (1-y-z)^4 etc. so that the power is embraced with braces i.e. y^2 -> y^{2},... y^13 -> y^{13} etc.
Currently I am using simple sed for each of the pattern
g1='y^10'
g11='y^{10}'
sed 's/'$g1'/'$g11'/g' input.m > output.m
but then I have to repeat this for each variable and each power, is there any shorter way? Besides I want to know how to tackle (y+z)^4 -> (y+z)^{4}.

Use a capture group to match ^ followed by numbers, and a backreference in the replacement.
sed 's/\^\([0-9][0-9]*\)/^{\1}/g' input.m > output.m

sed -Ei.bak 's/\^([[:digit:]]+)/^{\1}/g' file
would do it
Note
The -i option is for inplace edit where the backup with .bak extension will be made.
Edit
sed -Ei.bak 's/\^([1-9][[:digit:]]+)/^{\1}/g' file
would bracify only the powers greater than 9

Using Lookbehind regex:
perl -pe 's/\^\K(\d+)/{$1}/g' input.m > output.m
To change only powers greater than 10,
perl -pe 's/\^\K([1-9]\d+)/{$1}/g' input.m > output.m
As far as I know, sed doesn't support lookbehind or lookahead regex

Related

How do you factor over a Z field?

I have to factorize a polynomial e.g.
over the field of Z5 using Matlab or Mupad.
And i tried everything read a lot of Matlab and Mupad documentation and still can't find it, so i am guessing it is the math i don't know that's going to help me factor it.
Don't kill a mosquito with a cannon!
You only need to find a root between 0, 1, 2, -2, -1.
Also, given that x5 = x, the problem reduces to finding x such that
2x + 2x^4 + x^3 + 2x^2 - 3 = 0
and since x ≠ 0, x^4 = 1 hence
2x + x^3 + 2x^2 - 1 = 0
Well, let's try!
1: 2 + 1 + 2 - 1 -> -1
2: -1 + 3 - 2 - 1 -> -1
-2: 1 - 3 + 3 - 1 -> 0 -> root!
Then the polynomial is divisible by (x - 3), and you can repeat the procedure with the quotient until there are no roots left.
Addendum
After dividing by (x - 3) we get
x4 + x2 + 1
which we can expressed as
(x2 + 1)2 - x2
or
((x2 + 1) - x)((x2 + 1) + x)
To find the factors of degree 2 programmatically, just try with x2 + ax + b for a and b between 0 and 4.
I found a mupad command to do what i needed.
Still thanks for exaplaining the math behind it.

Matlab: Nonlinear Eq: error

I have the code from a previous question, however, this one is similar, just more equations added. However, I get an error and I'm not sure how to fix it.
Link to my previous question: Matlab: Nonlinear equation solver
function F = fcn(x)
F=[x(6) + x(7) + x(8) + x(9) + x(10) - 2 ;
x(6)*x(1) + x(7)*x(2) + x(8)*x(3) + x(9)*x(4) + x(10)*x(5) ;
x(6)*x(1)^2 + x(7)*x(2)^2 + x(8)*x(3)^2 + x(9)*x(4)^2 + x(10)*x(5) - 2/3 ;
x(6)*x(1)^3 + x(7)*x(2)^3 + x(8)*x(3)^3 + x(9)*x(4)^3 + x(10)*x(5) ;
x(6)*x(1)^4 + x(7)*x(2)^4 + x(8)*x(3)^4 + x(9)*x(4)^4 + x(10)*x(5) -2/5 ;
x(6)*x(1)^5 + x(7)*x(2)^5 + x(8)*x(3)^5 + x(9)*x(4)^5 + x(10)*x(5) ;
x(6)*x(1)^6 + x(7)*x(2)^6 + x(8)*x(3)^6 + x(9)*x(4)^6 + x(10)*x(5) -2/7 ;
x(6)*x(1)^7 + x(7)*x(2)^7 + x(8)*x(3)^7 + x(9)*x(4)^7 + x(10)*x(5) ;
x(6)*x(1)^8 + x(7)*x(2)^8 + x(8)*x(3)^8 + x(9)*x(4)^8 + x(10)*x(5) -2/9 ;
x(6)*x(1)^9 + x(7)*x(2)^9 + x(8)*x(3)^9 + x(9)*x(4)^9 + x(10)*x(5)
];
end
clc
clear all;
format long
x0 = [0.9; 0.5; 0.1; -0.5; -0.9; 0.2; 0.4; 0.5; 0.4; 0.2]; %Guess
F0 = fcn(x0);
[x,fval]=fsolve(#fcn, x0) %solve without optimization
options = optimset('MaxFunEvals',10000, 'MaxIter', 10000); %optimization criteria
[x,fval]=fsolve(#fcn, x0, options) %solve with optimization
The error that I get are:
Error using vertcat
Dimensions of matrices being concatenated are not consistent.
Error in fcn(line 4) %This is from the function script
F=[x(6) + x(7) + x(8) + x(9) + x(10)
- 2 ;
Error in fcncall (line 7) %This is from the main script
F0 = fcn(x0);
This is a very subtle error I've encountered before. When creating an array literal as you are doing fcn, negative signs that are directly attached to numbers and preceded by a space, as in rows 5, 7, and 9 of your array literal, are viewed as unary operators (i.e., the - makes the number negative and does not act as a binary minus operation). Therefore, because Matlab allows the delimiting of columns to be made with spaces, the indicated rows are interpreted to have two columns; row 5 column 1 is x(6)*x(1)^4 ... x(10)*x(5), and row 5 column 2 is -2/5.
So, either put a space between the three numbers or eliminate all spaces between the minus signs. For example:
x(6)*x(1)^4 + x(7)*x(2)^4 + x(8)*x(3)^4 + x(9)*x(4)^4 + x(10)*x(5) - 2/5;
or
x(6)*x(1)^4 + x(7)*x(2)^4 + x(8)*x(3)^4 + x(9)*x(4)^4 + x(10)*x(5)-2/5;
That problem wasn't easy to find. Not using a blank before the minus at the end of the rows, you created a row with two elements instead of one. For a simplified example compare this:
>> [2 - 2]
ans =
0
>> [2 -2]
ans =
2 -2
>> [(2 -2)]
ans =
0
Now the corrected version of your code:
F=[x(6) + x(7) + x(8) + x(9) + x(10) - 2 ;
x(6)*x(1) + x(7)*x(2) + x(8)*x(3) + x(9)*x(4) + x(10)*x(5) ;
x(6)*x(1)^2 + x(7)*x(2)^2 + x(8)*x(3)^2 + x(9)*x(4)^2 + x(10)*x(5) - 2/3 ; ...either set a space
x(6)*x(1)^3 + x(7)*x(2)^3 + x(8)*x(3)^3 + x(9)*x(4)^3 + x(10)*x(5) ;
(x(6)*x(1)^4 + x(7)*x(2)^4 + x(8)*x(3)^4 + x(9)*x(4)^4 + x(10)*x(5) -2/5); ...or use brackets
x(6)*x(1)^5 + x(7)*x(2)^5 + x(8)*x(3)^5 + x(9)*x(4)^5 + x(10)*x(5) ; ...both fixes the problem
x(6)*x(1)^6 + x(7)*x(2)^6 + x(8)*x(3)^6 + x(9)*x(4)^6 + x(10)*x(5) - 2/7 ;
x(6)*x(1)^7 + x(7)*x(2)^7 + x(8)*x(3)^7 + x(9)*x(4)^7 + x(10)*x(5) ;
x(6)*x(1)^8 + x(7)*x(2)^8 + x(8)*x(3)^8 + x(9)*x(4)^8 + x(10)*x(5) - 2/9 ;
x(6)*x(1)^9 + x(7)*x(2)^9 + x(8)*x(3)^9 + x(9)*x(4)^9 + x(10)*x(5) ];

Double sum and how to make a matrix to plot in 3D? (surface plot)

Edit
To clarify. I have a function f that takes in 5 arguments z,x,y,n,m. The order of events should go as follows:
Upon calling the function test, the variable z is assigned, say z = 1.
A linear combination is created by adding f with with each of elements of ni inserted and the result is stored in fn, as such (z = 1, so no more z variable):
fn = x + 2.*y + exp(0) - sqrt(m) +
x + 2.*y + exp(2) - sqrt(m) +
x + 2.*y + exp(4) - sqrt(m) +
x + 2.*y + exp(6) - sqrt(m) +
x + 2.*y + exp(8) - sqrt(m) +
x + 2.*y + exp(10) - sqrt(m) =
6*x + 12*y + 1 + exp(2) + exp(4) + exp(6) + exp(8) + exp(10) - 6*sqrt(m) =
6*x + 12*y + 25473.8 - 6*sqrt(m)
A linear combination is created by adding fn with each of elements of mi inserted and the result is stored in fnm. (I don't know how to do 1. and 2. simultaneously. If you do, please let me know):
fnm = 6*x + 12*y + 1 + exp(2) + exp(4) + exp(6) + exp(8) + exp(10) - 6*sqrt(0) +
6*x + 12*y + 1 + exp(2) + exp(4) + exp(6) + exp(8) + exp(10) - 6*sqrt(2) +
6*x + 12*y + 1 + exp(2) + exp(4) + exp(6) + exp(8) + exp(10) - 6*sqrt(4) +
6*x + 12*y + 1 + exp(2) + exp(4) + exp(6) + exp(8) + exp(10) - 6*sqrt(6) +
6*x + 12*y + 1 + exp(2) + exp(4) + exp(6) + exp(8) + exp(10) - 6*sqrt(8) +
6*x + 12*y + 1 + exp(2) + exp(4) + exp(6) + exp(8) + exp(10) - 6*sqrt(10) =
6*x + 12*y + 25453.1
A surface is plotted by plugging in x and y from arrays xi and yi into fnm
and of Edit
I'm having trouble with the double summation over the function f. I tried to follow the example in the last answer presented here, but it's not working for some reason. Because my variables x and y are not defined beforehand, I included them into #() in the arrayfun. I was first getting the error Z must be a matrix, not a scalar or vector. , so I changed the function handle fnm to a symbolic function after reading about it here. But now the whole thing exploded ... I don't know what's going on. Why is it saying there aren't enough inputs? fn should only be a function of x, y, m on line 11 since z is already defined to be some number (lets say 1) and n's just got summed over.
function test(z)
f = #(z,x,y,n,m) z.*x + 2.*y + exp(n) - sqrt(m);
function s(z)
ni = 0:2:10;
mi = 0:2:10;
xi = -5:5;
yi = -5:5;
fn = #(n) arrayfun(#(z, x, y, ni, m) sum(f(z, x, y, ni, m)),n);
fnm = #(m) arrayfun(#(x, y, mi) sum(fn(x, y, mi)),m);
zz = sym(fnm);
[xx,yy] = meshgrid(xi,yi);
surf(xx,yy,zz)
end
s
end
so many errors :(
Error using test2>#(x,y,mi)sum(fn(x,y,mi)) (line 11)
Not enough input arguments.
Error in test2>#(m)arrayfun(#(x,y,mi)sum(fn(x,y,mi)),m) (line 11)
fnm = #(m) arrayfun(#(x, y, mi) sum(fn(x, y, mi)),m);
Error in sym>funchandle2ref (line 1209)
S = x(S{:});
Error in sym>tomupad (line 1114)
x = funchandle2ref(x);
Error in sym (line 151)
S.s = tomupad(x);
Error in test2/s (line 12)
zz = sym(fnm);
Error in test2 (line 18)
s
Are you trying to do this?. I am not optimizing anything, for you to understand it clearly....
function test(zi)
syms z x y n m fn fnm;
f0=symfun(z.*x + 2.*y + exp(n) - sqrt(m),[z x y n m]);
z=zi;
ni=0:2:10;
mi=0:2:10;
fn=0;
for i=1:length(ni);
fn=symfun(fn+f0(z,x,y,ni(i),m),[x y m]);
end
fnm=0;
for i=1:length(mi)
fnm=symfun(fnm+fn(x,y,mi(i)),[x y]);
end
xi=-5:5;
yi=-5:5;
for i=1:length(xi)
for j=1:length(yi)
zz(i,j)=eval(fnm(xi(i),yi(j)));
end
end
[xx,yy]=meshgrid(xi,yi);
mesh(xx,yy,zz);
So, test(1) produces this:
Beware of the symfun calls, which shall be put there in order every summation keeps onto a "symbolic" framework. The arrayfun could be used, though they are neat, they could be not necesarily efficient... Let that exercise as homework!! XD..

Have a trouble with the function roots

Hey guys I have multiple problems with using function 'roots'.
I Have to find zeros of 's^1000 + 1'.
I made Y = zeros(1,1000) then manually changed the 1000th matrice to '1'. but then 'root' function does not work with it !
Another problem is that I am having trouble with matrix multiplication. The question is finding zeros(roots) of (s^6 + 6*s^5 + 15*s^4 + 20*s^3 + 15*s^2 + 6*s +1)*(s^6 + 6s^5 + 15*s^4 +15*s^2 +6*s +1) so i did:
a = [1 6 15 20 15 6 1]
b = [1 6 15 0 15 6 1]
y = a.*b;
roots(y)
but this gives me
-27.9355 + 0.0000i
-8.2158 + 0.0000i
0.1544 + 0.9880i
0.1544 - 0.9880i
-0.1217 + 0.0000i
-0.0358 + 0.0000i
where I calculate the original equation with wolfram then I have made matrix as :
p = [1 12 66 200 375 492 524 492 375 200 66 12 1]
roots(p)
and this gives me :
-3.1629 + 2.5046i
-3.1629 - 2.5046i
0.3572 + 0.9340i
0.3572 - 0.9340i
-1.0051 + 0.0000i
-1.0025 + 0.0044i
-1.0025 - 0.0044i
-0.9975 + 0.0044i
-0.9975 - 0.0044i
-0.9949 + 0.0000i
-0.1943 + 0.1539i
-0.1943 - 0.1539i
and I think the second solution is right (that is what wolfram alpha gave me)
How would you answer these two questions through matlab guys?
To multiply polynomials, you convolve their coefficients:
>> roots(conv(a,b))
ans =
-3.1629 + 2.5046i
-3.1629 - 2.5046i
0.3572 + 0.9340i
0.3572 - 0.9340i
-1.0051
-1.0025 + 0.0044i
-1.0025 - 0.0044i
-0.9974 + 0.0044i
-0.9974 - 0.0044i
-0.9950
-0.1943 + 0.1539i
-0.1943 - 0.1539i
Q1
Using roots to find the roots of s1000 + 1 is a bit of an overkill. The solution is given by this code snippet (corrected the first version; may be deduced using De Moivre's formula):
n = 1000;
k = 0:n-1
u = (2*k + 1)*pi / n;
s = cos(u) + 1i*sin(u)
Also, this method is approx. 100000 times faster.
Q2
Multiplying two polynomials to find the roots of their product is a bit of an overkill. :-) The union of the two polynomials' root sets is the root set of the product polynomial:
s = [roots(a);roots(b)]
Also, this method is more accurate.
1) The vector describing s^1000 + 1 should end with a 1 as well.
2)
a = [1 6 15 20 15 6 1]
b = [1 6 15 0 15 6 1]
y = a.*b;
This is a DOT product, multiplication of polynomials do not multiply element-wise.
Question 1
You need to include the coefficient of x^0 in the vector of coefficients, so there are 1001 entries with the first and last being 1
coeffs=zeros(1001,1);
coeffs([1,1001])=1;
roots(coeffs)
Question 2
To multiply the coefficients of polynomials you need to use convolution:
roots(conv(a,b))

how to expand (cross-multiply) two taylor polynomials in maple 13

> eq1 := taylor(exp((1/2)*lambda*gamma*B), lambda = 0, 3);
print(`output redirected...`); # input placeholder
1 1 2 2 2 / 3\
1 + - gamma B lambda + - gamma B lambda + O\lambda /
2 8
> eq2 := taylor(exp((1/2)*lambda*A), lambda = 0, 3);
print(`output redirected...`); # input placeholder
1 1 2 2 / 3\
1 + - A lambda + - A lambda + O\lambda /
2 8
> eq3 := eq1*eq2;
print(`output redirected...`); # input placeholder
/ 1 1 2 2 2 / 3\\ / 1
|1 + - gamma B lambda + - gamma B lambda + O\lambda /| |1 + - A lambda
\ 2 8 / \ 2
1 2 2 / 3\\
+ - A lambda + O\lambda /|
8 /
> expand(eq1, eq2);
print(`output redirected...`); # input placeholder
1 1 2 2 2 / 3\
1 + - gamma B lambda + - gamma B lambda + O\lambda /
2 8
> expand(eq3);
print(`output redirected...`); # input placeholder
/ 1 1 2 2 2 / 3\\ / 1
|1 + - gamma B lambda + - gamma B lambda + O\lambda /| |1 + - A lambda
\ 2 8 / \ 2
1 2 2 / 3\\
+ - A lambda + O\lambda /|
8 /
> expand(eq1*eq2);
print(`output redirected...`); # input placeholder
/ 1 1 2 2 2 / 3\\ / 1
|1 + - gamma B lambda + - gamma B lambda + O\lambda /| |1 + - A lambda
\ 2 8 / \ 2
1 2 2 / 3\\
+ - A lambda + O\lambda /|
8 /
Hi.. not at all sure if the above will make sense.. (I`d put this text at the top of the question, instead of code first, but the formating does strange things)
Im (trying to) use maple 13 (its what I have access to) to expand two taylor polynomials. and it isnt working. Im sure there must be some simple command I can use, but I haven`t found it. I have also tried a few of these possibilities: http://www.maplesoft.com/support/help/Maple/view.aspx?path=expand . perhaps you folks can help?
You need to convert those two series data structures eq1 and eq2 to polynomials before you can add them or expand their product.
eq1 := taylor(exp((1/2)*lambda*gamma*B), lambda = 0, 3):
eq2 := taylor(exp((1/2)*lambda*A), lambda = 0, 3):
p1:=convert(eq1,polynom):
p2:=convert(eq2,polynom):
p1+p2;
expand(p1*p2);