How do I show the whole root polynomial below in python? - calculator

How do I show the 5 root polynomials below in python?
I want it to show every root.
x = Symbol('x')
det_p = x**5 - 5*x**3 + 5*x + 2
eq1 = Eq(det_p,0)
b_solve = solve(eq1)
print('Energias dos Orbitais: ', [s.evalf() for s in b_solve])
Results:
Energias dos Orbitais: [-2.00000000000000, -0.618033988749895, 1.61803398874989]

If you are working with polynomials and want to see all roots in their multiplicity then you can use either roots, which gives a dict showing multiplicity or Poly.all_roots which gives a list of possibly repeated roots:
In [3]: roots(det_p)
Out[3]:
⎧ 1 √5 1 √5 ⎫
⎨-2: 1, ─ - ──: 2, ─ + ──: 2⎬
⎩ 2 2 2 2 ⎭
In [4]: Poly(det_p, x).all_roots()
Out[4]:
⎡ 1 √5 1 √5 1 √5 1 √5⎤
⎢-2, ─ - ──, ─ - ──, ─ + ──, ─ + ──⎥
⎣ 2 2 2 2 2 2 2 2 ⎦
Relevant docs:
https://docs.sympy.org/latest/modules/polys/reference.html#symbolic-root-finding-algorithms
https://docs.sympy.org/latest/modules/polys/reference.html#sympy.polys.polytools.Poly.all_roots

Related

How to generate all possible combinations for the column vectors of a matrix, in MATLAB?

If B=[1; 2] and A=[B B B...(n times B)], how to obtain the matrix C corresponding to all the possible combinations between the column vectors of A .i.e. I want to get the combinations between n copies of the same vector.
For example, for n=3:
A =
1 1 1
2 2 2
So, C can be obtained using the function from File Exchange 'allcomb(varargin)':
C=allcomb(A(:,1),A(:,2),A(:,3))
C =
1 1 1
1 1 2
1 2 1
1 2 2
2 1 1
2 1 2
2 2 1
2 2 2
In my case n is variable. How to obtain C for any value of n?
You can put the repetitions in a cell, and use the {:} syntax to put all cell elements as inputs to allcomb
n = 3;
B = [1,2];
A = repmat( {B}, n, 1 );
C = allcomb( A{:} ); % allcomb is FileExchange.
% combvec is a documented alternative.
Output:
C =
1 1 1
1 1 2
1 2 1
1 2 2
2 1 1
2 1 2
2 2 1
2 2 2
Since the alphabets for each of the places is the same, this is really a base conversion. MATLAB only accepts integer bases, but we can use that integer as an index into the alphabet B:
B=[1; 2];
n = 3;
b = numel(B);
for k = 0:(b^n-1) % loop over all possible combinations
C(k+1,:) = dec2base(k, b, n);
end
C = C - '0' + 1; % convert 0..b-1 (in chars) into 1..b (in ints) for indexing
C = B(C); % index into alphabet B
Results:
>> C
C =
1 1 1
1 1 2
1 2 1
1 2 2
2 1 1
2 1 2
2 2 1
2 2 2
The last line of the script doesn't appear to do much in this case because the alphabet happens to be the same range as our indices, but changing the alphabet to B = [7; 14] will correctly result in:
C =
7 7 7
7 7 14
7 14 7
7 14 14
14 7 7
14 7 14
14 14 7
14 14 14
Funnily enough, allcomb from MATLAB File Exchange seems to be what you want.
allcomb([1; 2],[1; 2], [1; 2])
ans =
1 1 1
1 1 2
1 2 1
1 2 2
2 1 1
2 1 2
2 2 1
2 2 2
To do it for any n, simply construct the matrix with:
>> n = 3;
>> repmat(B, 1, n)
ans =
1 1 1
2 2 2

Symmetrically extending a matrix

How can I extend a matrix in MATLAB by symmetrically replicating the boundary values? For example, if X is my matrix, extended matrix Xextsym should look like the following:
X =
1 2 3
4 5 6
Xextsym =
5 4 4 5 6 6 5
2 1 1 2 3 3 2
2 1 1 2 3 3 2
5 4 4 5 6 6 5
5 4 4 5 6 6 5
2 1 1 2 3 3 2
I'm aware that a function called wextend exists in the Wavelet Toolbox for this task exactly, but I don't have it.
Here is a function that extends a given matrix A by symmetric reflection, adding w element in each of four directions. Usage example:
symextend([1 2 3; 4 5 6], 2)
returns the extended matrix in your question.
function R = symextend(A, w)
[m, n] = size(A);
B = [A A(:, n:-1:1); A(m:-1:1, :) A(m:-1:1, n:-1:1)];
repm = 2*ceil(0.5+0.5*w/m);
repn = 2*ceil(0.5+0.5*w/n);
C = repmat(B, repm, repn);
R = C(m*repm + 1 - w : m*repm + m + w, n*repn + 1 - w : n*repn + n + w)
end
Idea: first reflect A once in each direction (this produces B), then repeat B with repmat, obtaining C. Finally, a suitable piece is carved out of C. The tricky parts are counting how many times to repeat, and which part to carve out.

Create a multidimensional array following a pattern

I am making a 3 dimensional array, using matlab, that progresses according to a pattern. Athough I could write out the Array manually I am sure there is a quicker way to do it.
multiArray = cat(3,...
[1+randn(4,3); 1*randn(4,3)],...
[2+randn(4,3); 2*randn(4,3)],...
[3+randn(4,3); 3*randn(4,3)]);
If I want to make the above array to be 8x3x25 then the last line would be
[25+randn(4,3); 25*randn(4,3)]
But how can I make such an array without going through all the tedious intervening steps?
While mikkola basically got the solution, there is no need to shift dimensions at the end.
s=[4,3,25];
it=reshape(1:s(3),1,1,[]);
out = [bsxfun(#plus , it, randn(s));...
bsxfun(#times, it, randn(s))];
Here's a possible way using bsxfun.
%// 25 x 4 x 3 with elements for i + randn(4,3)
P = bsxfun(#plus, (1:25)', randn(25,4,3));
%// 25 x 4 x 3 with elements for i * randn(4,3)
T = bsxfun(#times, (1:25)', randn(25,4,3));
%// Concatenate and shift dimensions to get desired size output
multiArray = shiftdim([P T], 1);
If you don't mind taking things to 4D for efficiency purposes -
N = 25; %// Number of 3D slices
out = randn(4,2,3,N);
out(:,1,:,:) = bsxfun(#plus,permute(1:N,[1 4 3 2]),out(:,1,:,:));
out(:,2,:,:) = bsxfun(#times,permute(1:N,[1 4 3 2]),out(:,2,:,:));
out = reshape(out,8,3,N);
To legitimize the solution, let's start off with an input of A = randn(8,3,N) and initialize the output out with it. Also, let's take number of 3D slices as a small number, so say N = 3.
Thus,
>> N = 3;
A = randn(8,3,N);
out = reshape(A,[4 2 3 N]); %// This replaces "out = randn(4,2,3,N)"
Next up, we run the code that will change out -
>> out(:,1,:,:) = bsxfun(#plus,permute(1:N,[1 4 3 2]),out(:,1,:,:));
out(:,2,:,:) = bsxfun(#times,permute(1:N,[1 4 3 2]),out(:,2,:,:));
out = reshape(out,8,3,N);
Now, start validating per 3D slice -
>> out(1:4,:,1) - A(1:4,:,1)
ans =
1 1 1
1 1 1
1 1 1
1 1 1
>> out(1:4,:,2) - A(1:4,:,2)
ans =
2 2 2
2 2 2
2 2 2
2 2 2
>> out(1:4,:,3) - A(1:4,:,3)
ans =
3 3 3
3 3 3
3 3 3
3 3 3
>> out(5:end,:,1)./A(5:end,:,1)
ans =
1 1 1
1 1 1
1 1 1
1 1 1
>> out(5:end,:,2)./A(5:end,:,2)
ans =
2 2 2
2 2 2
2 2 2
2 2 2
>> out(5:end,:,3)./A(5:end,:,3)
ans =
3 3 3
3 3 3
3 3 3
3 3 3

Laplacian Filter Formula

I tried Laplacian filter method but i think I did somethings wrong with its formula.
My original matrix (f)
a b
a 1 2
b 3 4
New matrix (g) by padding old matrix and replicating the origial one for using 3x3 filter mask
a b c d e f
a 1 2 1 2 1 2
b 3 4 3 4 3 4
c 1 2 1 2 1 2
d 3 4 3 4 3 4
e 1 2 1 2 1 2
f 3 4 3 4 3 4
The filter (m)
a b c
a 0 1 0
b 1 -4 1
c 0 1 0
Then I start at [c,c] in the new matrix. What I did in the calculation was
g(c,c) = g (c,c) + -1* (m(a,a)*g(b,b) + m(a,b)*g(b,c) + m(a,c)*g(b,d) + m(b,a)*g(c,b) + m(b,b)*g(c,c) + m(b,c)*g(c,d) + m(c,a)*g(d,b) + m(c,b)*g(d,c) + m(c,c)*g(d,d));
After performing the filter on g(c,c) , g(c,d) , g(d,c) , g (d,d), I crop the matrix as filtered these filter point to the new matrix, but the result look really weird. (not like in the book). I tried doing it in matlab by myself.
Can someday help me with this? Thank you very much
To get the same results as Nasser's method using conv2 and filter2 (which are only the same because your filter has symmetric rows), first you can't do it in-place. Previously filtered entries will mess up the subsequent calculations. Second, I'm not sure where that g(c,c) + -1* comes in. A normal filter calculation for g(c,c) would be:
r(c,c) = m(a,a)*g(b,b) + m(a,b)*g(b,c) + m(a,c)*g(b,d) +...
m(b,a)*g(c,b) + m(b,b)*g(c,c) + m(b,c)*g(c,d) +...
m(c,a)*g(d,b) + m(c,b)*g(d,c) + m(c,c)*g(d,d);
where r is the result matrix. This method (repeated for the other 3 values in the original matrix) gives:
r =
c d
c 6 2
d -2 -6
UPDATE
using:
A =
1 2 1 2 1 2
3 4 3 4 3 4
1 2 1 2 1 2
3 4 3 4 3 4
1 2 1 2 1 2
3 4 3 4 3 4
mask =
0 1 0
1 -4 1
0 1 0
imfilter gives:
imfilter(A,mask)
ans =
1 -2 3 -2 3 -3
-6 -6 -2 -6 -2 -9
4 2 6 2 6 1
-6 -6 -2 -6 -2 -9
4 2 6 2 6 1
-7 -8 -3 -8 -3 -11
The function suggested above,
for i=1:2
for j=1:2
r(i,j) = m(1,1)*g(i+1,j+1) + m(1,2)*g(i+1,j+2) + m(1,3)*g(i+1,j+3) +...
m(2,1)*g(i+2,j+1) + m(2,2)*g(i+2,j+2) + m(2,3)*g(i+2,j+3) +...
m(3,1)*g(i+3,j+1) + m(3,2)*g(i+3,j+2) + m(3,3)*g(i+3,j+3);
end
end
gives:
ans =
6 2
-2 -6
Does this match what you expect to see?
Note: The function above is not how I would implement it, but it follows the example that you gave for clarity.

Common way to generate finite geometric series in MATLAB

Suppose I have some number a, and I want to get vector [ 1 , a , a^2 , ... , a^N ]. I use [ 1 , cumprod( a * ones( 1 , N - 1 ) ) ] code. What is the best (and propably efficient) way to do it?
What about a.^[0:N] ?
ThibThib's answer is absolutely correct, but it doesn't generalize very easily if a happens to a vector. So as a starting point:
> a= 2
a = 2
> n= 3
n = 3
> a.^[0: n]
ans =
1 2 4 8
Now you could also utilize the built-in function vander (although the order is different, but that's easily fixed if needed), to produce:
> vander(a, n+ 1)
ans =
8 4 2 1
And with vector valued a:
> a= [2; 3; 4];
> vander(a, n+ 1)
ans =
8 4 2 1
27 9 3 1
64 16 4 1