• Labs icon Lab
  • Data
Labs

Solving Problems with Numerical Methods Hands-on Practice

In this lab, "Exploring Numerical Methods with R," you will delve into the fundamentals of numerical methods, contrasted with analytical techniques, to solve mathematical problems using R. Through hands-on practice, you'll implement various interpolation techniques, apply graph theory concepts, optimize complex problems using local search algorithms, and master calculus fundamentals such as integration and differentiation. By the end of this lab, you'll gain a comprehensive skill set in R programming, ready to tackle real-world mathematical challenges with confidence.

Labs

Path Info

Duration
Clock icon 1h 0m
Published
Clock icon Sep 16, 2024

Contact sales

By filling out this form and clicking submit, you acknowledge ourΒ privacy policy.

Table of Contents

  1. Challenge

    Exploring Numerical Methods with R

    RStudio Guide

    To get started, click on the 'workspace' folder in the bottom right pane of RStudio. Click on the file entitled "Step 1...". You may want to drag the console pane to be smaller so that you have more room to work. You'll complete each task for Step 1 in that R Markdown file. Remember, you must run the cells with the play button at the top right of each cell for a task before moving onto the next task in the R Markdown file. Continue until you have completed all tasks in this step. Then when you are ready to move onto the next step, you'll come back and click on the file for the next step until you have completed all tasks in all steps of the lab.


    Exploring Numerical Methods with R

    To review the concepts covered in this step, please refer to the Understanding Numerical Methods module of the Solving Problems with Numerical Methods course.

    Understanding numerical methods is important because it lays the foundation for solving complex mathematical problems using computational techniques. Write basic code in R to demonstrate the basics of numerical methods, including a simple example using the Jacobi method for solving a system of linear equations.

    Dive into the world of numerical methods by exploring how they differ from analytical techniques and why this distinction is crucial for solving complex problems. Using R, you will practice solving a simple problem numerically and analytically to understand the practical differences and applications. Goal: Understand the fundamental concepts of numerical methods and their applications. Tools: R programming language.


    Task 1.1: Loading Required Libraries

    Before diving into numerical methods, let's ensure that all necessary libraries are loaded. You do not need to install these libraries, as they come pre-installed in the environment. For this lab, we'll need RcppArmadillo, Rlinsolve, ggplot2, and pracma for numerical computations and visualizations.

    πŸ” Hint

    Use the library() function to load each of the three libraries mentioned.

    πŸ”‘ Solution
    library('RcppArmadillo')
    library('Rlinsolve')
    library('ggplot2')
    library('pracma')
    

    Task 1.2: Constructing a 2x2 Linear System

    To delve deeper into numerical methods, let's construct a simpler system of linear equations. Create a 2x2 matrix A representing the coefficients of the equations, and a 2x1 vector b representing the constants on the right side of the equations. The matrix should have the values c(4, 1, 2, 3) and the vector should have the values c(5, 6).

    πŸ” Hint

    For the matrix A, use matrix(c(value1, value2, value3, value4), nrow = 2, ncol = 2, byrow = T) to define it. For vector b, use matrix(c(value1, value2), nrow = 2, ncol = 1, byrow = T) to fill it with constants.

    πŸ”‘ Solution
    A <- matrix(c(4, 1, 2, 3), nrow = 2, ncol = 2, byrow = T)
    b <- matrix(c(5, 6), nrow = 2, ncol = 1, byrow = T)
    

    Task 1.3: Solving the System Using the Jacobi Method

    Now that we have our system of equations defined, let's solve it using the Jacobi method. Use the lsolve.jacobi() function from the Rlinsolve library to find the solution. Print the solution and the number of iterations used. Then, use ggplot2 to plot the error at each iteration step.

    πŸ” Hint

    To solve the system, use lsolve.jacobi(A, b, weight = 1, verbose = F). To print the solution, use out$x. To print the number of iterations, use out$iter. To plot the error over iterations, first create a data frame with the iteration numbers and errors, then use ggplot() and geom_line() to plot it.

    πŸ”‘ Solution
    # Solve
    out <- lsolve.jacobi(A, b, weight = 1, verbose = F)
    
    # Print the solution
    print(out$x)
    
    # Print the numer of iterations
    print(out$iter)
    
    # Plot the error over iterations
    error <- out$errors
    iteration <- out$iter
    iter_seq <- seq.int(0, iteration, 1)
    error_per_iter <- data.frame(iter_seq, error)
    ggplot(error_per_iter, aes(x = iter_seq, y = error)) + geom_line(col = 'red', size = 2)
    

    Task 1.4: Analytical Solution of the System

    To understand the difference between numerical and analytical solutions, let's solve the same system of equations analytically using the rref() function from the pracma library. This will give us the Reduced Row Echelon Form (RREF) of the augmented matrix [A|b], which represents the system of equations.

    πŸ” Hint

    To solve the system analytically, use rref(cbind(A, b)) to get the RREF of the augmented matrix [A|b]. Then, print the solution using print(rref_solution).

    πŸ”‘ Solution
    rref_solution <- rref(cbind(A, b))
    print(rref_solution)
    
  2. Challenge

    Implementing Interpolation Techniques in R

    Implementing Interpolation Techniques in R

    To review the concepts covered in this step, please refer to the Applying Numerical Methods to Solve Problems module of the Solving Problems with Numerical Methods course.

    Interpolation and Extrapolation are important because they allow us to estimate unknown values within a set of known data points or beyond them. This step will cover different interpolation techniques, including linear, polynomial, and spline interpolation.

    Practice implementing various interpolation techniques in R to estimate unknown values within toy datasets created for you in the example code. You will use the approx, approxfun, and spline functions in R to perform linear, polynomial, and spline interpolation, respectively. Goal: Gain hands-on experience with interpolation techniques in R. Tools: R programming language, approx, approxfun, spline functions.


    Task 2.1: Exploring Linear Interpolation with approx

    Load the stats library. Given the predefined data points, use linear interpolation with the approx function. Visualize the result with plot().

    πŸ” Hint

    Use library() to load the stats package. Use the approx function by providing it with the x and y parameters, which are vectors of your known data points. Finally, visualize the interpolated data by using the plot function with linear_interp as the argument.

    πŸ”‘ Solution
    # Load the stats library
    library(stats)
    
    # Predefined data points
    x <- c(1, 3, 5, 7, 9)
    y <- c(2, 8, 24, 45, 73)
    
    # Perform linear interpolation using the approx function
    linear_interp <- approx(x = x, y = y)
    
    # Visualize the interpolated values
    plot(linear_interp)
    

    Task 2.2: Polynomial Interpolation with poly.calc

    Load the polynom package. Now perform polynomial interpolation on the data from the previous step. Estimate values against the provided x_seq data and plot the results.

    πŸ” Hint

    Instead of library(stats), use library(polynom) to access polynomial interpolation functions. Replace the approx function with poly.calc, providing it with the same x and y vectors. To interpolate, use the predict function, passing in the result of poly.calc and the provided x_seq.

    πŸ”‘ Solution
    # Load the polynom library
    library(polynom)
    
    # Calculate the polynomial interpolation coefficients
    poly_coefs <- poly.calc(x, y)
    
    # Provided sequence of x values for plotting the polynomial curve
    x_seq <- seq(min(x), max(x), length.out = 100)
    
    # Calculate interpolated y values using the polynomial coefficients
    y_poly <- predict(poly_coefs, x_seq)
    
    # Visualize the interpolated values
    plot(x_seq, y_poly)
    

    Task 2.3: Exploring Spline Interpolation

    Perform spline interpolation on x and y using the spline function. Plot the results.

    πŸ” Hint

    Start by using the spline function with x and y as its parameters to perform the spline interpolation. After obtaining the spline interpolation result, visualize it by calling the plot function and passing the result of the spline interpolation as its argument.

    πŸ”‘ Solution
    # Perform spline interpolation on the predefined data points
    spline_interp <- spline(x = x, y = y)
    
    # Visualize the spline interpolation
    plot(spline_interp)
    
  3. Challenge

    Solving Linear Equations with Iterative and Direct Methods

    Solving Linear Equations with Iterative and Direct Methods

    To review the concepts covered in this step, please refer to the Applying Numerical Methods to Solve Problems module of the Solving Problems with Numerical Methods course.

    Solving systems of linear equations is important because it's a fundamental problem in numerical analysis with applications across various fields. This step will focus on using both direct (Gaussian elimination) and iterative (Jacobi method) techniques to solve linear equations.

    Apply direct and iterative numerical techniques to solve a system of linear equations in R. You will use Gaussian elimination and the Jacobi method to understand the differences and applications of each approach. Goal: Master solving systems of linear equations using direct and iterative methods. Tools: R programming language.


    Task 3.1: Loading Required Libraries

    Before we start solving linear equations, let's ensure that all necessary libraries are loaded. For this lab, we will need the Matrix library for creating matrices and the pracma and Rlinsolve libraries for numerical methods.

    πŸ” Hint

    Use the library() function to load the Matrix, Rlinsolve, and pracma libraries.

    πŸ”‘ Solution
    library('Matrix')
    library('Rlinsolve')
    library('pracma')
    

    Task 3.2: Creating a System of Linear Equations

    Use the predefined data to create a system of linear equations that we will solve using both direct and iterative methods. Define a matrix A representing the coefficients of the system and a vector b representing the constants on the right side of the equations. Print the matrix and vector.

    πŸ” Hint

    Use the predefined code to create the data, the print with the print() function.

    πŸ”‘ Solution
    A <- matrix(c(4, -1, 0, -1, 3, -1, 0, -1, 3), nrow = 3, ncol = 3)
    b <- c(3, 3, -1)
    print(A)
    print(b)
    

    Task 3.3: Solving with Gauss Jordan Elimination

    Now that we have our system of linear equations, let's solve it by reducing it to row echelon form. Use the rref function from the pracma library to achieve this.

    πŸ” Hint

    The rref() function takes a single argument: the augmented matrix [A|b] combining both the coefficient matrix A and the constant vector b. You can use cbind to combine them. After solving, use print() to display the reduced matrix, from which the solutions can be inferred.

    πŸ”‘ Solution
    # Reduce the matrix to row echelon form
    reduced_matrix <- rref(cbind(A, b))
    
    # Display the reduced matrix
    print(reduced_matrix)
    

    Task 3.4: Exploring Direct and Iterative Methods for Solving Linear Equations

    In this task, you will compare the effectiveness of direct and iterative methods for solving a system of linear equations. You will use the solve function for the direct method and the lsolve.jacobi function from the Rlinsolve package for the iterative method. Compare the solutions obtained from both methods to understand their differences and applications.

    πŸ” Hint

    To solve the system using the direct method, use the solve function with A and b as parameters and print the result. For the iterative method, initialize an initial guess vector x0, set a tolerance tol, and specify the maximum number of iterations max_iter. Use the lsolve.jacobi function with these parameters to solve the system and print the solution.

    πŸ”‘ Solution
    # Direct solution
    direct_solution <- solve(A, b)
    print(direct_solution)
    
    # Iterative solution
    x0 <- rep(0, 3) # Initial guess
    tol <- 1e-5 # Tolerance
    max_iter <- 100 # Maximum iterations
    
    iterative_solution <- lsolve.jacobi(A, b, x0, tol, max_iter)
    print(iterative_solution$x)
    
  4. Challenge

    Graph Theory Applications with R

    Graph Theory Applications with R

    To review the concepts covered in this step, please refer to the Working with Graphs Using Numerical Techniques module of the Solving Problems with Numerical Methods course.

    Graph theory is important because it provides tools for modeling relationships between entities, which is essential in various fields such as computer science, biology, and social sciences. This step will explore creating and manipulating graphs using the igraph library in R.

    Utilize the igraph library in R to create and analyze graphs. You will practice creating different types of graphs (including, directed, undirected, connected, and disconnected) and apply shortest path algorithms to solve real-world problems. Goal: Understand and apply graph theory concepts using R. Tools: R programming language, igraph library.


    Task 4.1: Loading the igraph Library

    Before we can start working with graphs in R, we need to ensure that the igraph library is loaded. This will give us access to all the functions necessary for creating and manipulating graphs.

    πŸ” Hint

    Use the library() function and pass the name of the library as a string.

    πŸ”‘ Solution
    library('igraph')
    

    Task 4.2: Creating an Undirected Graph

    Create an undirected graph with 5 nodes and the following edges: (1,2), (2,3), (3,4), (4,5), (5,1). Visualize the graph using the plot() function.

    πŸ” Hint

    Use the graph() function with edge and n parameters for creating the graph. Then, use plot() to visualize it.

    πŸ”‘ Solution
    # Create an undirected graph
    g <- graph(edge = c(1,2, 2,3, 3,4, 4,5, 5,1), n = 5, directed = FALSE)
    # Visualize the graph
    plot(g)
    

    Task 4.3: Creating a Directed Graph

    Now, create a directed graph using the same nodes and edges as the previous task. Visualize the graph to see the difference.

    πŸ” Hint

    Set the directed parameter to TRUE when creating the graph.

    πŸ”‘ Solution
    # Create a directed graph
    g_directed <- graph(edge = c(1,2, 2,3, 3,4, 4,5, 5,1), n = 5, directed = TRUE)
    # Visualize the graph
    plot(g_directed)
    

    Task 4.4: Finding Shortest Path

    Find the shortest path between node 1 and node 5 in the directed graph you created earlier. Print the path.

    πŸ” Hint

    Use the shortest_paths() function, specifying the source and target nodes.

    πŸ”‘ Solution
    path <- shortest_paths(g_directed, from = 1, to = 5)
    print(path)
    

    Task 4.5: Analyzing Graph Connectivity

    Check if the directed graph is strongly connected. A graph is strongly connected if there is a path between all pairs of vertices.

    πŸ” Hint

    Use the is_connected() function with the mode parameter set to strong.

    πŸ”‘ Solution
    # Check if the graph is strongly connected
    is_strongly_connected <- is_connected(g_directed, mode = 'strong')
    print(is_strongly_connected)
    
  5. Challenge

    Optimizing the N-Queens Problem with Local Search

    Optimizing the N-Queens Problem with Local Search

    To review the concepts covered in this step, please refer to the Implementing Local Search and Optimizations module of the Solving Problems with Numerical Methods course.

    Local search algorithms are important because they offer a way to find optimal or near-optimal solutions to complex optimization problems that may not be solvable through traditional methods. This step will focus on applying local search techniques, including simulated annealing and threshold accepting, to solve the N-queens problem.

    Implement local search algorithms to find a solution to the N-queens problem in R. You will use stochastic local search, simulated annealing, and threshold accepting algorithms to position N-queens on an NxN chessboard without any attacking each other. Goal: Apply local search algorithms to solve optimization problems. Tools: R programming language.


    Task 5.1: Loading the NMOF Package

    Before we start implementing local search algorithms, we need to ensure that the necessary R package is loaded. For this lab, we'll be using the NMOF package, which provides functions for numerical optimization, including local search algorithms.

    πŸ” Hint

    Use the library() function to load the NMOF package. Replace the empty string with the name of the package.

    πŸ”‘ Solution
    library('NMOF')
    

    Task 5.2: Initializing the Chessboard

    To solve the N-queens problem, we first need to initialize a data frame to represent the position of each queen. Create a function named initializeChessboard that takes an integer N as input. The function should return a dataframe with a column called row that ranges from 1:N. The dataframe should also have a column called queen_position that represents the position of each queen on that row. That column can be initialized with NA values. Call the function to initialize an 10x10 chessboard named chessboard.

    πŸ” Hint

    Use the data.frame() function to create a data frame. You can use rep(NA, N) to create a vector of NAs of length N for initializing the cells.

    πŸ”‘ Solution
    initializeChessboard <- function(N) {
      data_frame <- data.frame(row = 1:N, queen_position = rep(NA, N))
      return(data_frame)
    }
    chessboard <- initializeChessboard(8)
    

    Task 5.3: Randomly Placing the Queens

    Now that we have a function to initialize the chessboard, the next step is to place the queens on the board. Create a function named placeQueensRandomly that takes the chessboard data frame and the number of queens N as input, and returns the chessboard with N queen placed at a random position in each row. Place 10 queens on chessboard.

    πŸ” Hint

    Use the sample.int() function to generate a random position for the N queens.

    πŸ”‘ Solution
    placeQueensRandomly <- function(chessboard, N) {
      chessboard$queen_position <- sample.int(N, N, replace = FALSE)
      return(chessboard)
    }
    chessboard <- placeQueensRandomly(chessboard, 10)
    

    Task 5.4: Visualizing the Chessboard

    To better understand the placement of queens on the chessboard, it's helpful to visualize it. Create a function named visualizeChessboard that takes the chessboard data frame as input and prints a visual representation of the chessboard with queens placed on it. Use '_' to represent an empty space and 'Q' to represent a queen.

    πŸ” Hint

    You can use a loop to iterate through each row of the chessboard and print a row of '_' characters, replacing the character with 'Q' where a queen is placed.

    πŸ”‘ Solution
    visualizeChessboard <- function(chessboard) {
      N <- nrow(chessboard)
      for (i in 1:N) {
        row <- rep('_', N)
        row[chessboard$queen_position[i]] <- 'Q'
        cat(paste(row, collapse = '  '))
        cat('\n')
      }
    }
    visualizeChessboard(chessboard)
    

    Task 5.5: Applying Stochastic Local Search

    The provided functions help count the number of attacks and move the queens. Apply local search algorithms to find a solution where no queens attack each other. Use the stochastic local search algorithm. Use the LSopt function from the NMOF package to optimize the placement of queens. Visualize the solved chessboard.

    πŸ” Hint

    Use the LSopt function with appropriate arguments, including the initial position of queens, the neighbor function, and the number of steps.

    πŸ”‘ Solution
    # Provided functions
    num_attacks <- function(rand_position) {
      sum(duplicated(rand_position)) + 
        sum(duplicated(rand_position - seq_along(rand_position))) + 
        sum(duplicated(rand_position + seq_along(rand_position)))
    }
    move_one_queen <- function(rand_position, N=10){
      step <- 4
      i <- sample.int(N, 1)
      
      rand_position[i] <- rand_position[i] + sample(c(1:step, -(1:step)), 1)
      
      if (rand_position[i] > N)
        rand_position[i] <- 1
      else if (rand_position[i] < 1)
        rand_position[i] <- N
      
      rand_position
    }
    
    # Solve the N-queens problem
    stochastic_local_search <- LSopt(num_attacks, list(x0 = chessboard$queen_position, neighbour = move_one_queen, printBar = TRUE, nS = 10000))
    
    # Use visualizeChessboard to see the result
    solved_chessboard <- chessboard
    solved_chessboard$queen_position <- stochastic_local_search$xbest
    visualizeChessboard(solved_chessboard)
    
  6. Challenge

    Implementing Integration and Differentiation in R

    Implementing Integration and Differentiation in R

    To review the concepts covered in this step, please refer to the Implementing Integration and Differentiation module of the Solving Problems with Numerical Methods course.

    Understanding integration and differentiation is important because these are fundamental concepts in calculus with applications in various fields such as physics, engineering, and economics. This step will cover implementing these concepts in R to solve real-world problems.

    Practice calculating derivatives and performing integration in R. You will use R functions to calculate the derivative of a function and integrate functions to find areas under curves or solve differential equations. Goal: Master the concepts of differentiation and integration using R. Tools: R programming language.


    Task 6.1: Loading Necessary Libraries

    Before we start implementing integration and differentiation in R, let's ensure that the necessary libraries are loaded. For this lab, we will need the mosaic and Deriv libraries. The mosaic library provides functions for mathematical operations, while Deriv allows us to perform symbolic differentiation.

    πŸ” Hint

    Use the library() function to load both mosaic and Deriv libraries.

    πŸ”‘ Solution
    library('mosaic')
    library('Deriv')
    

    Task 6.2: Calculating the Derivative

    Now that we have the necessary libraries loaded, let's calculate the derivative of a simple function, f(x) = 3x^2 + 2x + 1.

    πŸ” Hint

    Use the Deriv() function from the Deriv library to calculate the derivative of the function f. You need to pass the function f as an argument to Deriv().

    πŸ”‘ Solution
    # Define the function
    f1 <- function(x) {3 * x^2 + 2 * x + 1}
    
    # Calculate the derivative
    f_prime <- Deriv(f1)
    print(f_prime)
    

    Task 6.3: Performing Integration

    After calculating derivatives, let's move on to integration. Calculate the definite integral of the function f(x) = x^3 - x from x=0 to x=2.

    πŸ” Hint

    Use the integrate() function from the mosaic library to calculate the definite integral of the function f from x=0 to x=2. The lower and upper arguments of integrate() should be set to 0 and 2, respectively.

    πŸ”‘ Solution
    # Define the function
    f2 <- function(x) {x^3 - x}
    
    # Perform the integration from x=0 to x=2
    result <- integrate(f2, lower = 0, upper = 2)
    print(result$value)
    

What's a lab?

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Provided environment for hands-on practice

We will provide the credentials and environment necessary for you to practice right within your browser.

Guided walkthrough

Follow along with the author’s guided walkthrough and build something new in your provided environment!

Did you know?

On average, you retain 75% more of your learning if you get time for practice.