<a href="https://colab.research.google.com/github/ice-bear-git/Astar-with-smoothed-path/blob/master/homework0.ipynb" target="_parent"></a>

# Homework 0

## Exercise 

Get used to using python as a calculator. Try computing all of the following:

(i) $10 \sqrt{(2(11.4+12.6))}$


```python
import numpy as np
a = 10*np.sqrt(2*(11.4+12.6))
a
```




    69.28203230275508



(ii) $e^{0.5}$


```python
import numpy as np
a = np.exp(0.5)
a
```




    1.6487212707001282



(iii) the value of $y=(10+sin(x)+x^2+cosh(x^2+1))/(sinh(x)+x^3+3x^4+e^x)$ for $x=\pi$ and $x=0.2$


```python
import numpy as np

def value(xValue):
  x = xValue
  num = 10+np.sin(x)+x**2+np.cosh(x**2+1)
  dem = np.sinh(x) + x**3 + 3*x**4 +np.exp(x)
  y = num/dem
  return y

print("When x = pi, the value of y equals: " , value(np.pi))
print("When x = 0.2, the value of y equals: " , value(0.2))

```

    When x = pi, the value of y equals:  73.47132985890015
    When x = 0.2, the value of y equals:  8.240812092855817


## Exercise

Write a function that takes as arguement $r$ for the radius of a circle and returns the diameter $r$ of the circle, as well as the circle's circumference $c$ and the area $a$. Try the function for $r=6$.


```python
import numpy as np

def triangleInfo(radius):
  r = radius
  d = 2*r
  c = 2*np.pi*r
  a = np.pi*r**2
  infoList = [d,c,a]
  return infoList

info = triangleInfo(radius=6)
print("Given radius r=6, the circle's diameter d is", info[0],
      " circumference c is ", info[1], ", and area a is ", info[2])
```

    Given radius r=6, the circle's diameter d is 12  circumference c is  37.69911184307752 , and area a is  113.09733552923255


## Exercise

Write a for loop to sum up all natural numbers from $1$ to $1,000,000$.


```python
## Method 1
def sequenceSum(startVal,endVal, increment):
  sum = 0
  item = startVal
  while (item < endVal) | (item == endVal):
    sum += item
    item +=increment
  return sum

sum1 = sequenceSum(1,1000000,1)
print("method 1", sum1)


## Method 2
a= range(1,1000001,1) # notice the exclusive or range at the right boundary
sum2 = sum(a)
print("method 2", sum2)
```

    method 1 500000500000
    method 2 500000500000


## Exercise

Compute the sum $\sum_{i=1}^{10}(i+1)$.


```python
def sequenceSum(startVal,endVal,increment,bias):
  sum = 0
  item = startVal
  while (item < endVal) | (item == endVal):
    sum += item
    item +=increment
  return sum

sum1 = sequenceSum(1,10,1,bias = 1)
print("The sum of sequence here is ", sum1)
```

    The sum of sequence here is  55


## Exercise

The curve $f(x)=x^2+3x+\sqrt5$ intersects the curve $g(x)=-x^2-2x+1$ at two points. Find the coordinates of the intersections and the gradients of the tangents to each curve at those points.


```python
"""Method 1"""
import numpy as np
import sympy as sy


def find_intersections(x,line_1,line_2):
    intersection_set = set()
    # print(type(intersection_set))
    N = len(x)-1
    index = 0
    while index < N:
        current_x, current_y1, current_y2 = x[index], line_1[index], line_2[index]
        dif = np.abs(current_y2 - current_y1)
        if dif < 1e-3:
            # print(dif)
            intersection_set.add((round(current_x, 3), round(current_y1, 2)))
        index += 1
    intersection_list = list(intersection_set)
    return intersection_list


def fun1(x):
    y1 = np.square(x)+3*x+np.sqrt(5)
    return y1


def fun2(x):
    y2 = - np.square(x)-2*x+1
    return y2


def FindGradients(current_x,tag="fun1"):
    import sympy as sy

    x = sy.symbols('x')
    y1 = x**2 + 3*x + sy.sqrt(5)
    y2 = - x**2 - 2*x + 1
    y1_dif = sy.diff(y1, x)
    y2_dif = sy.diff(y2, x)

    if tag == "fun1":
        difValue = y1_dif.subs(x,current_x)
        difValue = round(difValue.evalf(),2)
        print("The gradient of function1 at x = ", current_x, " is ", difValue)
    if tag == "fun2":
        difValue = y2_dif.subs(x,current_x)
        difValue = round(difValue.evalf(),2)
        print("The gradient of function2 at x = ", current_x, " is ", difValue)


t = np.linspace(-10, 10, 200000)
curve_1 = fun1(t)
curve_2 = fun2(t)


intersection_points = find_intersections(t, curve_1, curve_2)
print("The coordinates of intersection points are ", intersection_points)

for point in intersection_points:
    x, y = point
    FindGradients(x,"fun1")
    FindGradients(x,"fun2")
```

    The coordinates of intersection points are  [(-0.278, 1.48), (-2.222, 0.51)]
    The gradient of function1 at x =  -0.278  is  2.44
    The gradient of function2 at x =  -0.278  is  -1.44
    The gradient of function1 at x =  -2.222  is  -1.44
    The gradient of function2 at x =  -2.222  is  2.44


## Exercise

The Taylor series for sinh(x) is given by,

$$sinh(x)=x+\frac{x^3}{3!} + \frac{x^5}{5!} + \frac{x^7}{7!}+ ...$$

Write a function that finds an approximate solution for $sinh(x)$. Try your function for $x=4$ and compute the error between your approximate answer and numpy's `sinh()` function. Report how many terms you need in order to achieve an error 

$$\epsilon < 1e-4$$.


```python
import numpy as np
import sympy as sy

global x
x = sy.symbols('x')


def approximate_sinh(term_Num = 3):
    global x
    # x = sy.symbols('x')
    exp = 0
    n=1
    while n< term_Num+1:
        exp += x**(2*n-1)/sy.factorial(2*n-1)
        n +=1

    # print(exp)
    return exp


N = range(1, 10)
i = 1
while i < len(N):
    # print(i)
    sym_exp = approximate_sinh(term_Num = i)
    error = np.abs(np.sinh(4)-sym_exp.subs(x,4))
    if error < 1e-4:
        print("The required minimum number of terms to accurately approximating sinh() is ",i)
        print("And the current expression is ", sym_exp)
        break
    else:
        i += 1
```

    The required minimum number of terms to accurately approximating sinh() is  8
    And the current expression is  x**15/1307674368000 + x**13/6227020800 + x**11/39916800 + x**9/362880 + x**7/5040 + x**5/120 + x**3/6 + x


## Exercise 

Consider the functions $f(x)=x^2$, $g(x)=sin(x)$, and $h(x)=sinh(x+1)-e^{2x}$. Write lambda functions that represents each of these functions. Then write another function that takes as its arguements two functions and the value of $x$ and returns the composition of the functions (e.g., $f(g(x))=f\circ g(x)$). Use this to find:

(i) $g\circ f(5.0)$

(ii) $f \circ g(2)$

(iii) $h \circ(g\circ f)(2\pi)$


```python
""" Lambda functions, also referred to as 'Anonymous function'
is same as a regular python function but can be defined without a name.
ref: https://www.machinelearningplus.com/python/lambda-function/#1.-What-is-Lambda-Function-in-Python?"""

import numpy as np

# calculate squares using lambda
f = lambda x: x*x
g = lambda x: np.sin(x)
h = lambda x: np.sinh(x+1)-np.exp(2*x)


def nesting_g_f(f, g, x_value):
    return g(f(x_value))


print(nesting_g_f(f, g, x_value=5))
```

    -0.13235175009777303



```python
""" Lambda functions, also referred to as 'Anonymous function'
is same as a regular python function but can be defined without a name.
ref: https://www.machinelearningplus.com/python/lambda-function/#1.-What-is-Lambda-Function-in-Python?"""

import numpy as np

# calculate squares using lambda
f = lambda x: x*x
g = lambda x: np.sin(x)
h = lambda x: np.sinh(x+1)-np.exp(2*x)


def nesting_f_g(f, g, x_value):
    return f(g(x_value))


print(nesting_f_g(f, g, x_value=2))
```

    0.826821810431806



```python
""" Lambda functions, also referred to as 'Anonymous function'
is same as a regular python function but can be defined without a name.
ref: https://www.machinelearningplus.com/python/lambda-function/#1.-What-is-Lambda-Function-in-Python?"""

import numpy as np

# calculate squares using lambda
f = lambda x: x*x
g = lambda x: np.sin(x)
h = lambda x: np.sinh(x+1)-np.exp(2*x)


def nesting_h_g_f(f, g, h,x_value):
    return h(g(f(x_value)))

print(nesting_h_g_f(f, g, h, x_value=2*np.pi))
```

    -3.5295864605536447



## Exercise

Implement the following matirx addition in Python using Numpy.


$$
 \mathbf{A} + \mathbf{B} = \begin{bmatrix} 
1 & 2 \\
3 & 4 \\
\end{bmatrix}
+
\begin{bmatrix} 
1 & 1  \\
1 & 1 \\
\end{bmatrix}
=
\begin{bmatrix} 
2 & 3  \\
4 & 5 \\
\end{bmatrix}
$$




```python
""" Implementing matrix operation with numpy only
ref: https://numpy.org/doc/stable/reference/generated/numpy.matrix.html
"""
import numpy as np

A = np.matrix('1 2; 3 4')
B = np.matrix('1 1; 1 1')
C = A+B
print(C)
```

Write a double for-loop that iterates over the elements of the numpy arrays and adds the two matrices together.


```python
""" Implementing matrix operation with numpy only
ref: https://numpy.org/doc/stable/reference/generated/numpy.matrix.html
"""
import numpy as np

A = np.matrix('1 2; 3 4')
B = np.matrix('1 1; 1 1')
list_C = []
item_B = 1  # as all the elements of B equal to ONE
for row_A in A:
    print(row_A)
    for item_A in row_A:
        item_C = item_A + item_B
        list_C.append(item_C)

print(list_C)
print(np.array(list_C))
```

    [[1 2]]
    [[3 4]]
    [matrix([[2, 3]]), matrix([[4, 5]])]
    [[[2 3]]
    
     [[4 5]]]




2382423bcb03234fbaa762d68475d36155489a2e
ipynb
Jupyter Notebook
homework0.ipynb
ice-bear-git/Astar-with-smoothed-path
28931020836284abf130c589c61d9add5fb7019e
Apache-2.0
homework0.ipynb
ice-bear-git/Astar-with-smoothed-path
28931020836284abf130c589c61d9add5fb7019e
Apache-2.0
homework0.ipynb
ice-bear-git/Astar-with-smoothed-path
28931020836284abf130c589c61d9add5fb7019e
Apache-2.0
Qwen/Qwen-72B
1. YES
2. YES