<jupyter_start><jupyter_text>Python Basic Programs  1. Complex NumbersWrite a function `rand_complex(n)` that returns a list of `n` random complex numbers uniformly distributed in the unit circle (i.e., the magnitudes of the numbers are all between 0 and 1). Give the function a docstring. Demonstrate the function by making a list of 25 complex numbers.<jupyter_code>import numpy as np
import random as random
import matplotlib.pyplot as plt
def rand_complex (n):
  """To get random complex numbers uniformly distribued in the unit circle.
     Unit circle= A circle of unit radius, i.e. a radius of 1.
     Condition for unit circle: If (x,y) is a point on the circumference of the circle.
                                Then, (x^2+y^2=1). 

    Parameter n: Required number of complex numbers, type int.

    Returns m: An array of complex numbers within the unit circle.
  """
  m = []                          #Initializing an empty array
  for i in range(n):
    a = np.random.uniform(-1 , 1) #Get a random number between -1 & 1
    b = np.sqrt(1-a**2)           #Get a number that fulfills (a^2+b^2=1 or b=square-root of(1-a^2))
    br = np.random.uniform(-b , b)#Get a random number between -b & b
    z = complex (a , br)          #Forms complex number of the form (a + br j)
    m.append(z)                   #Append the array with complex numbers generated 
    plt.scatter(a , br)           #Plot the complex numbers
    circle=plt.Circle((0,0),1, fill= False)
    plt.gca().add_patch(circle)
  return m

rand_complex(25)<jupyter_output><empty_output><jupyter_text>2. HashesWrite a function `to_hash(L) `that takes a list of complex numbers `L` and returns an array of hashes of equal length, where each hash is of the form `{ "re": a, "im": b }`. Give the function a docstring and test it by converting a list of 25 numbers generated by your `rand_complex` function.<jupyter_code>def to_hash(L):
  """Returns the hash or dictionary values of a list of complex numbers.

     Parameter L: List of complex numbers.

     Returns a: An array of hashes of equal length in the form {"re": a, "im": b}  
  """
  a = []                            #Initializing an empty array
  b = len(L)                        #Get the length of array list
  for i in range(b):  
    x = L[i].real                   #Stores real values of complex numbers
    y = L[i].imag                   #Stores imaginary values of complex numbers
    a.append({ "re": x, "im": y })  #Add all the real and imaginary parts to the array in the form of hashes
  return a

to_hash(rand_complex(25))<jupyter_output><empty_output><jupyter_text>3. MatricesWrite a function `lower_traingular(n)` that returns an $n \times n$ numpy matrix with zeros on the upper diagonal, and ones on the diagonal and lower diagonal. For example, `lower_triangular(3)` would return```pythonarray([[1, 0, 0],       [1, 1, 0],       [1, 1, 1]])```<jupyter_code>import numpy as np
def lower_traingular(n):
  """Forms an nxn lower triangular matrix, with zeros above diagonal
     and ones on diagonal and below diagonal
  
     Parameter n: Dimension of resultant nxn matrix, type int.  

     Returns x: Desired lower triangular nxn matrix.
  """
  x = np.zeros((n , n))   #Forms a matrix of zeros of desired dimension
  for i in np.arange(n): 
    for j in np.arange(n):
      if (i>=j):          #Selecting diagonal and lower diagonal places
        x[i][j]=1         #Inputs 1 wherever the condition applies
  return x  
    
lower_traingular(3)<jupyter_output><empty_output><jupyter_text>4. NumpyWrite a function `convolve(M,K)` that takes an $n \times m$ matrix $M$ and a $3 \times 3$ matrix $K$ (called the kernel) and returns their convolution as in [this diagram](https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTYo2_VuAlQhfeEGJHva3WUlnSJLeE0ApYyjw&usqp=CAU).Please do not use any predefined convolution functions from numpy or scipy. Write your own. If the matrix $M$ is too small, your function should return a exception.You can read more about convolution in [this post](https://setosa.io/ev/image-kernels/).The matrix returned will have two fewer rows and two fewer columns than $M$. Test your function by making a $100 \times 100$ matrix of zeros and ones that as an image look like the letter X and convolve it with the kernel$$K = \frac{1}{16} \begin{pmatrix}1 & 2 & 1 \\2 & 4 & 2 \\1 & 2 & 1\end{pmatrix}$$Use `imshow` to display both images using subplots.<jupyter_code>import numpy as np
import matplotlib.pyplot as plt

#Take user inputs for image dimensions 
n = int(input("Enter no of rows for image: "))
m = int(input("Enter no of columns for image: "))

#To form an image in the form of X of desired dimensions
img = np.zeros((n , m))  
for i in range(n):
  for j in range(m):
    if (i==j or i+j==m-1):
      img[i][j] = 1

#Kernel provided for convolution
ker = (1/16)*np.array([[1, 2, 1], [2, 4, 2], [1, 2, 1]])
k = ker.shape[0]

#Defining dimensions of resultant image
#Dimensions 2 rows and columns lesser than given image (as kernel is 3x3) 
res = np.zeros(((n-k+1) , (m-k+1)))

#Perfom Convolution
def convolve(M , K):
  """Performs the convolution of a nxm image by a kernel of 3x3 and provides a resultant image.

     Parameters:
     M= nxm image on which convolution is to be performed.
     K= 3x3 kernel.

     Raises: Exception as dimensions of input image can not be less than kernel dimensions.   
  """
  if (img.shape[0]<ker.shape[0] or img.shape[1]<ker.shape[1]):
    raise Exception("Image dimensions less than kernel dimensions")
  else:
    for i in range(n-k+1):
      for j in range(m-k+1):
        res[i][j] = np.sum(ker * img[i:i+k,j:j+k])

convolve(img , ker)

#Plot the given image and resultant image
fig = plt.figure(figsize = (10,10))
fig.add_subplot(1, 2, 1)
plt.title("Image")
plt.imshow(img)
fig.add_subplot(1, 2, 2)
plt.title("Result")
plt.imshow(res)<jupyter_output>Enter no of rows for image: 100
Enter no of columns for image: 100<jupyter_text>5. Symbolic ManipulationUse sympy to specify and solve the following equations for $x$.- $x^2 + 2x - 1 = 0$ - $a x^2 + bx + c = 0$Also, evaluate the following integrals using sympy- $\int x^2 dx$- $\int x e^{6x} dx$- $\int (3t+5)\cos(\frac{t}{4}) dt$<jupyter_code>import math
from sympy import *
init_printing(use_latex='mathjax')
x = Symbol("x")
solve((x**2) + (2*x) - 1)
x, a, b, c = symbols("x a b c")
solve(a*(x**2) + b*x + c)
expr = (x**2)*diff(x)
integrate (expr, x)
expr = x*(exp(6*x))*diff(x)
integrate (expr, x)
t = Symbol("t")
expr = (3*t+5)*cos(t/4)*diff(t)
integrate (expr, t)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1151625645700395, 'fraction_numerical': 0.020814342145244608, 'mean_word_length': 3.3596026490066224, 'pattern_counts': {'":': 6, '<': 22, '<?xml version=': 0, '>': 21, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '421015', 'license': 'MIT', 'n_tokens_mistral': 2278, 'n_tokens_neox': 2156, 'n_words': 856, 'path': 'Basic Python Programs/Python Basic Programs.ipynb', 'repo_name': 'joy6543/Mathematics-and-Analytical-Methods', 'size': '6582'}