<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 # Scipy and Numpy
Scipy builds on Numpy, and for all basic array handling needs you can use Numpy functions
Step1:  If you need to using only some function, you may use the from ... import command.
Step2:  This whole stuff with numpy is required a lot of practice since it's a big library itself. In this session we only cover some of it. 
Array
You can make an array right of the blue with np.array.
Step3:  As usual, you could access the coordinates with the brackets. Remember that Python start it's counting at 0. For better or worse, Numpy have a different data type than pure Python. We can access the dimension of the matrix with a.shape if a is the name of our matriks. It could also reshape with a.reshape(m,n) where (m,n) is the new dimension (NumPy can have more than 2 dimensional being). There's also arange to create an array of evenly spaced numbers. You also could transpose the matrix simply by transpose.
Step4:  Numpy has an ability to broadcast matrix, that is to treat arrays of different shapes during arithmetic operations. If the arrays are in the same shape, we did the binary operation coordinat-by-coordinate. But operations on arrays of non-similar shapes is still possible in NumPy.
Step5:  Iteration on Array
You can also iterating in array using nditer. We can compare it if we reshape it first, then iterating as iteration on list, or we iterating directly with nditer.
Step6:  Arithmetic Operations
NumPy is not failed our expectation with linear algebra. Beside binary operation, NumPy also support the "usual" arithmetic operation on matrix, namely
Step7:  Ploting with Matplotlib
Matplotlib is one of the most favorite library to ploting data. Lots of capability with great support and easy to use nature make matplotlib one of the choice. Another libraries worth mentioned are Cairoplot, plotly, and MathGL. You'll see more that just that if you dig a little bit deeper.
Step8:  Example
Given function $f$ such that $$f
Step9:  Attempt to solve the problem
For a glance, we didn't see any anomaly. We will try approach with two ways, first one is to bruto force, and the second one is to find it's derivatives to get a clear understanding of it's nature.
With the first approach, we need to see the graph closer. We may need to zooming it a little bit.
Step10:  Hence, we knew that it cutted by a horizontal lines three times, so he is not injective.
The second approach is more elegant on many ways, but it's not imaginable with graphics. We knew that an injective function would be a strictly increasing (or decreasing) function) with finitely many stasionary point. We can come up with it's derivatives to get to know whether it's alwas positive or always negative or not. The given function's derivatives are
Step11:  And we got the result that the peak value is negative. So this graph at some point is going down, so it is not injective.
Example
Find all solution of the equation $$ 8 \sin x = x$$ for all reals $x$.
Attempt to solve the problem
Before we going anywhere, we should plot it (since we have the ability to do so). First thing first, remember that $\sin x$ are bounded on $[-1,1]$, so we can bound our graphics to be around $[-8,8]$.
Step12:  Little bit easy huh? Since both $x$ and $\sin x$ are odd, we can consider on one sides positive or negative, and we got one solution, namely $x=0$.
Step13:  Noting that $\sin$ is always up and down, it would only intersect the lines once every $\pi/2$ interval. Hence, we could brute force our way in in the intevals.
<ASSISTANT_TASK:>
Python Code:
import numpy as np
Explanation: # Scipy and Numpy
Scipy builds on Numpy, and for all basic array handling needs you can use Numpy functions:
End of explanation
from scipy import some_module
some_module.some_function()
Explanation: If you need to using only some function, you may use the from ... import command.
End of explanation
import numpy as np
a = np.array([[1,2,3],[2,3,4]])
print(a)
print(a[0,1])
Explanation: This whole stuff with numpy is required a lot of practice since it's a big library itself. In this session we only cover some of it. 
Array
You can make an array right of the blue with np.array.
End of explanation
import numpy as np
a = np.array([[1,2,3],[2,3,4]])
b = np.arange(1,7)
c = np.arange(6)
b = b+c
b = b.reshape(2,3)
print(a+b)
Explanation: As usual, you could access the coordinates with the brackets. Remember that Python start it's counting at 0. For better or worse, Numpy have a different data type than pure Python. We can access the dimension of the matrix with a.shape if a is the name of our matriks. It could also reshape with a.reshape(m,n) where (m,n) is the new dimension (NumPy can have more than 2 dimensional being). There's also arange to create an array of evenly spaced numbers. You also could transpose the matrix simply by transpose.
End of explanation
a = np.array([1,2,3])
b = np.array([[10,20,30],[20,30,40],[30,40,50]])
a+b
Explanation: Numpy has an ability to broadcast matrix, that is to treat arrays of different shapes during arithmetic operations. If the arrays are in the same shape, we did the binary operation coordinat-by-coordinate. But operations on arrays of non-similar shapes is still possible in NumPy.
End of explanation
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print('Original array is:')
print(a)
print('\n')
print('Transpose of the original array is:')
b = a.T
print(b)
print('\n')
print('Sorted in C-style order:')
c = b.copy(order = 'C')
print(c)
for x in np.nditer(c):
   print(x),
print('\n')
print('Sorted in F-style order:')
c = b.copy(order = 'F')
print(c)
for x in np.nditer(c):
   print(x),
Explanation: Iteration on Array
You can also iterating in array using nditer. We can compare it if we reshape it first, then iterating as iteration on list, or we iterating directly with nditer.
End of explanation
import numpy as np 
a = np.arange(9, dtype = np.float_).reshape(3,3) 
b = np.arange(9, dtype = np.float_).reshape(3,3) 
print(a)
print(np.add(a,b))
print(np.subtract(a,b))
print(np.multiply(a,b))
Explanation: Arithmetic Operations
NumPy is not failed our expectation with linear algebra. Beside binary operation, NumPy also support the "usual" arithmetic operation on matrix, namely: np.add,np.subtract,np.multiply.
End of explanation
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(1,11) 
y = 1 + 2 * x + x*x
plt.title("Matplotlib demo") 
plt.xlabel("x axis caption") 
plt.ylabel("y axis caption") 
plt.plot(x,y) 
plt.show()
Explanation: Ploting with Matplotlib
Matplotlib is one of the most favorite library to ploting data. Lots of capability with great support and easy to use nature make matplotlib one of the choice. Another libraries worth mentioned are Cairoplot, plotly, and MathGL. You'll see more that just that if you dig a little bit deeper.
End of explanation
import numpy as np
from numpy import poly1d
import matplotlib.pyplot as plt
x = np.linspace(-10,10)
y = x*x*x + 2*x*x + 1.3333*x + 1
plt.title("Computational Mathematics, Problem Final Test ") 
plt.xlabel("x axis") 
plt.ylabel("y axis") 
plt.plot(x,y) 
plt.show()
Explanation: Example
Given function $f$ such that $$f:x \mapsto x^3 + 2x^2 + 1.3333x + 1. $$
Plot graphic $y=f(x)$. Prove that the function is not injective.
End of explanation
import numpy as np
from numpy import poly1d
import matplotlib.pyplot as plt
x = np.linspace(-.675,-.658,100)
y = x*x*x + 2*x*x + 1.3333*x + 1
z = x * 0 + 0.7037259
plt.title("Computational Mathematics, Problem Final Test ") 
plt.xlabel("x axis") 
plt.ylabel("y axis") 
plt.plot(x,y,x,z) 
plt.show()
Explanation: Attempt to solve the problem
For a glance, we didn't see any anomaly. We will try approach with two ways, first one is to bruto force, and the second one is to find it's derivatives to get a clear understanding of it's nature.
With the first approach, we need to see the graph closer. We may need to zooming it a little bit.
End of explanation
a, b, c = 3,4,1.33333
D1 = (-b + np.sqrt(b*b - 4*a*c))/(2*a)
D2 = (-b - np.sqrt(b*b - 4*a*c))/(2*a)
x = (D1+D2)/2
0 < 3*x*x + 4*x + 1.33333
Explanation: Hence, we knew that it cutted by a horizontal lines three times, so he is not injective.
The second approach is more elegant on many ways, but it's not imaginable with graphics. We knew that an injective function would be a strictly increasing (or decreasing) function) with finitely many stasionary point. We can come up with it's derivatives to get to know whether it's alwas positive or always negative or not. The given function's derivatives are: $$3x^2 + 4x + 1.33333.$$ 
Since it's a quadratics, we can find it's roots, check it's peak, and tell is it different sign than the rest of the graph or not. But since it's concave up, we only need to check whether it's negative or not.
End of explanation
import numpy as np
from numpy import poly1d
import matplotlib.pyplot as plt
x = np.linspace(-9,9,10000)
y = 8*np.sin(x)
z = x 
plt.title("Computational Mathematics, Problem Final Test ") 
plt.xlabel("x axis") 
plt.ylabel("y axis") 
plt.plot(x,y,x,z) 
plt.show()
Explanation: And we got the result that the peak value is negative. So this graph at some point is going down, so it is not injective.
Example
Find all solution of the equation $$ 8 \sin x = x$$ for all reals $x$.
Attempt to solve the problem
Before we going anywhere, we should plot it (since we have the ability to do so). First thing first, remember that $\sin x$ are bounded on $[-1,1]$, so we can bound our graphics to be around $[-8,8]$.
End of explanation
import numpy as np
from numpy import poly1d
import matplotlib.pyplot as plt
x = np.linspace(0,9,1000)
y = 8*np.sin(x)
z = x 
plt.title("Computational Mathematics, Problem Final Test ") 
plt.xlabel("x axis") 
plt.ylabel("y axis") 
plt.plot(x,y,x,z) 
plt.show()
Explanation: Little bit easy huh? Since both $x$ and $\sin x$ are odd, we can consider on one sides positive or negative, and we got one solution, namely $x=0$.
End of explanation
from scipy import optimize
import numpy as np
def f(x):
    return 8*np.sin(x) - x
a = (np.pi)/2
root1 = optimize.bisect(f, 2, 4)
root2 = optimize.bisect(f, 4, 5*a)
root3 = optimize.bisect(f, 5*a, 8)
print(root1)
print(root2)
print(root3)
Explanation: Noting that $\sin$ is always up and down, it would only intersect the lines once every $\pi/2$ interval. Hence, we could brute force our way in in the intevals.
End of explanation
<END_TASK>