How to assign symbol to Matrix - python-3.x

I want to verify the Cayley-Hamilton theorem in python. To do so, i have to update x to matrix A. How can I do so
** subs function is not working here
from sympy import symbols, Matrix
import numpy as np
x = symbols(['x'])
A = Matrix([[4, 5, 6],
[7, 8, 9],
[10, 11,12]])
LL = np.eye(3)*x
DEttt = A - LL
Deter = DEttt.det() #characteristics equation
print(Deter.subs(x,A))

Related

IPython: Audio: concating list to add chords results in one single chord not several played one-by-one: `+=` vs `append`

I am completetly new to IPython hence I am sorry in case this is totally obvious:
import IPython.display as ipd
import scipy
from scipy import signal as sp
import math
import numpy as np
I defined two functions which should help me generate chords:
def f_k(f_0, k):
return f_0*2**((k%12)/12)
def h_k(k, f0, t):
return math.sin(2*math.pi*f_k(f0, k)*t)
F = 44000
T = 2
f0 = 440
N = F*T
I define H0:
H0 = []
for k in [0,4,7]:
H0.append([h_k(k, f0, t) for t in np.linspace(0, T, N)])
ipd.Audio(H0, rate=F)
and it plays 2 seconds as expected because of the discretization through linspace.
I defined a few several chords and I wanted to concat the lists to get several chords (I expected the sound to be 8 secs long)
H5 = []
for k in [5,9,12]:
H5.append([h_k(k, f0, t) for t in np.linspace(0, T, N)])
H7 = []
for k in [7, 11, 14]:
H7.append([h_k(k, f0, t) for t in np.linspace(0, T, N)])
H9 = []
for k in [5,9,16]:
H9.append([h_k(k, f0, t) for t in np.linspace(0, T, N)])
added_sample = []
for h in [H0, H7, H9, H5]:
added_sample += h
ipd.Audio(added_sample, rate=F)
Yet the sound is somehow 2secs long. Could someone explain how to add chords insted of 'layering' them? Any hint would be greatly appreciated!
Maybe this small example will help you see the different between append and +=:
For each we run:
In [54]: alist = [1,2,3]; blist = [4,5]
append adds one item to the list:
In [55]: alist.append(blist); alist
Out[55]: [1, 2, 3, [4, 5]]
+= is a list join:
In [57]: alist += blist; alist
Out[57]: [1, 2, 3, 4, 5]
and is the equivalent of extend:
In [59]: alist.extend(blist); alist
Out[59]: [1, 2, 3, 4, 5]
The non-in-place version of extend:
In [61]: alist + blist
Out[61]: [1, 2, 3, 4, 5]

sklearn train_test_split returns some elements in both test/train

I have a data-set X with 260 unique observations.
when running x_train,x_test,_,_=test_train_split(X,y,test_size=0.2) I would assume that
[p for p in x_test if p in x_train] would be empty, but it is not. Actually it turns out that only two observations in x_test is not in x_train.
Is that intended or...?
EDIT (posted the data I am using):
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split as split
import numpy as np
DATA=load_breast_cancer()
X=DATA.data
y= DATA.target
y=np.array([1 if p==0 else 0 for p in DATA.target])
x_train,x_test,y_train,y_test=split(X,y,test_size=0.2,stratify=y,random_state=42)
len([p for p in x_test if p in x_train]) #is not 0
EDIT 2.0: Showing that the test works
a=np.array([[1,2,3],[4,5,6]])
b=np.array([[1,2,3],[11,12,13]])
len([p for p in a if p in b]) #1
This is not a bug with the implementation of train_test_split in sklearn, but a weird peculiarity of how the in operator works on numpy arrays. The in operator first does an elementwise comparison between two arrays, and returns True if ANY of the elements match.
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6]])
b = np.array([[6, 7, 8], [5, 5, 5]])
a in b # True
The correct way to test for this kind of overlap is using the equality operator and np.all and np.any. As a bonus, you also get the indices that overlap for free.
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6]])
b = np.array([[6, 7, 8], [5, 5, 5], [7, 8, 9]])
a in b # True
z = np.any(np.all(a == b[:, None, :], -1)) # False
a = np.array([[1, 2, 3], [4, 5, 6]])
b = np.array([[6, 7, 8], [1, 2, 3], [7, 8, 9]])
a in b # True
overlap = np.all(a == b[:, None, :], -1)
z = np.any(overlap) # True
indices = np.nonzero(overlap) # (1, 0)
You need to check using the following:
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split as split
import numpy as np
DATA=load_breast_cancer()
X=DATA.data
y= DATA.target
y=np.array([1 if p==0 else 0 for p in DATA.target])
x_train,x_test,y_train,y_test=split(X,y,test_size=0.2,stratify=y,random_state=42)
len([p for p in x_test.tolist() if p in x_train.tolist()])
0
Using x_test.tolist() the in operator will work as intended.
Reference: testing whether a Numpy array contains a given row

using for loop with in a for loop

For a given array v=[1,2,3] I am trying to print the sum of the product of each element with s for a range of s
import numpy as np
v=[1,2,3]
for s in range(0,5):
for i in range (0,3):
tot= np.multiply(v[i],s)
b.append(tot)
print (b)
my output is
[0, 0, 0, 1, 2, 3, 2, 4, 6, 3, 6, 9, 4, 8, 12]
I am trying to get the out put as
[[0, 0, 0], [1, 2, 3], [2, 4, 6], [3, 6, 9], [4, 8, 12]]
I am not quite sure how the second for loop is working inside the first for loop. If someone can explain that, it would be wonderful.
You'd create a new list for each iteration of the outer for loop:
v=[1,2,3]
b = []
for s in range(0,5):
result = []
for i in range (0,3):
tot= np.multiply(v[i],s)
result.append(tot)
b.append(result)
print (b)
You could just use * to multiply values, and you can iterate directly over v (no need to use a range)`:
v = [1, 2, 3]
b = []
for s in range(5):
result = []
for i in v:
result.append(i * s)
b.append(result)
You can replace both loops with list comprehensions:
b = [[i * s for i in v] for s in range(5)]
import numpy as np
v=np.array([1,2,3])
b=[]
for s in range(0,5):
b.append(list(v*s))
print (b)
Should do what you want. Don't forget numpy's extremely powerful broadcasting capability.
v=[1,2,3]
b=[]
for s in range(0,5):
b.append([])
for i in range (0,3):
tot= np.multiply(v[i],s)
b[s].append(tot)
print(b)

Making a matrix from several vectors

Is it possible to make a Matrix out of several vectors in theano?
like:
vector1, vector2, vector3 = theano.tensor.vector()
Matrix = [vector1, vector2, vector3]
similar to the numpy operation:
Matrix = numpy.asarray([vector1, vector 2, vector3])
You can use theano.tensor.stack.
Here's a working example:
import theano
import theano.tensor as tt
vector1, vector2, vector3 = tt.vectors(3)
matrix = tt.stack(vector1, vector2, vector3)
f = theano.function([vector1, vector2, vector3], matrix)
print f([1, 2, 3], [4, 5, 6], [7, 8, 9])
where prints
[[ 1. 2. 3.]
[ 4. 5. 6.]
[ 7. 8. 9.]]

Numpy arrays: can I multiply only a few elements in the array and not all of them?

I am using Python3 and numpy with matplotlib on a project to get Jupiter's Mass from observational telescope astrometry. I want to take an array of numbers, say from 1 to 10, and multiply only a few of them in order, say 1 to 4, by -1.
So 1 to 4 is now negative and 5 to 10 is still positive. I imagine out put like this:
L = [1,2,3,4,5,6,7,8,9,10]
array_L = np.array(L)
>>>array_L
array([1,2,3,4,5,6,7,8,9,10])
neg = array_L[0:4]
>>>neg
array([1,2,3,4])
Neg = neg * -1
>>>Neg
array([-1,-2,-3,-4])
Now I need a way of combining neg and array_L into a new final array that would output like this:
# pseudo code: Neg + array_L(minus elements 0 to 4) = New_L
New_L = array([-1,-2,-3,-4, 5, 6, 7, 8, 9, 10])
Also I know it may be possible to do a limited element iteration over just the elements I want and not the whole array. I can do some of these operations on the list vs the array if it would make it easier.
You are almost there! Try this:
L = array([1,2,3,4,5,6,7,8,9,10])
L[0:4] *= -1
print(L)
Just like with regular python lists, you can do operations on slices of NumPy arrays to change them in-place:
>>> import numpy
>>> L = [1,2,3,4,5,6,7,8,9,10]
>>> array_L = numpy.array(L)
>>> array_L
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
>>> array_L[0:4] *= -1
>>> array_L
array([-1, -2, -3, -4, 5, 6, 7, 8, 9, 10])

Resources