19) HW2 Review#

Last time#

  • Solving Systems

    • Direct methods

    • Iterative methods

    • Example of a PDE

Today#

    1. Review of HW2

    1. Submission expectations

    • 2.1 Assignments in Julia

Review of Assignment 2#

Here is my solution for the bisection.c code:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

double a1 = -4.0; // static memory variable
double b1 = -2.0; // static memory variable
double a2 = 2.0;  // static memory variable
double b2 = 4.0;  // static memory variable

int bisect_hist(double *hist, double a, double b, double tol);

// define the function exp(-x)*(3.2*sin(x)- 0.5*cos(x)) = 3
double f(double x0){
    double x;
    x = exp(-x0)*(3.2*sin(x0)- 0.5*cos(x0)) - 3;
    return x;
}

int bisect_hist(double *hist, double a, double b, double tol) {
    int it = 0;

    printf("Execution for interval: [a,b] = [%f, %f] \n", a, b);

    if (f(a)*f(b) >= 0 ) {
        printf("f(a)f(b)<0 not satisfied! f has no root in [a,b] = [%f, %f]\n", a, b);
        return -1;
    }

    while (fabs(b-a) > tol) {
        double mid = (a + b)/2.0;
        hist[it] = mid;
        if (f(a) * f(mid) < 0) {
            b = mid;
        }
        else {
            a = mid;
        }
        it++;
    }

    return it;
}

int main(void){
    double tol = 1e-4; // stack memory variable

    double *hist_xstar1; // stack memory variable
    hist_xstar1 = malloc(100*sizeof(double)); // heap memory allocated, and hist_xstar points to it

    double *hist_xstar2; // stack memory variable
    hist_xstar2 = malloc(100*sizeof(double)); // heap memory allocated, and hist_xstar2 points to it

    // call the bisection method by reference
    int num_it1 = bisect_hist(hist_xstar1, a1, b1, tol);

    // Is it a root?
    if (num_it1 >= 0) {
        printf("We found xstar1: %f, and f(xstar1) is: %e \n", hist_xstar1[num_it1-1], f(hist_xstar1[num_it1-1]));
        printf("The bisection method has found the root %f at the %d iteration \n", hist_xstar1[num_it1-1], num_it1);
    }

    int num_it2 = bisect_hist(hist_xstar2, a2, b2, tol);

    // is this a root?
    if (num_it2 >= 0) {
        printf("We found xstar2: %f, and f(xstar2) is: %f \n", hist_xstar2[num_it2-1], f(hist_xstar1[num_it2-1]));
        printf("The bisection method has found the root %f at the %d iteration \n", hist_xstar2[num_it2-1], num_it2);
    }

    // free the allocated heap memory
    free(hist_xstar1);
    free(hist_xstar2);
}

Common mistakes#

Here is a list of common mistakes that a few people made and you should not make:

  • Not using the absolute value to compute the length of the interval \([a,b]\). What if the values were complex? Distances (or lengths) are non-negative numbers by definition.

  • Using while ((b - a) / 2.0 > tol) as a stopping criterion, effectively doubling the tolerance

  • Using the midpoint of the interval fabs(f(mid_point)) > tol to check for the stopping criterion

  • Not checking the necessary condition for the function to have a root in the interval. That is, not checking that it has opposite signs at the endpoints f(a)*f(b)<0

  • Using == to check if a floating point number is equal to zero, as in if (f(mid_point) == 0.0). You should never use == to check if any floating point number is equal to zero, because of floating point arithmetic and rounding errors. Always check if it is within a desired tolerance. Alternatively, if you are not given a specific tolerance, check against machine \(\varepsilon\), but do not check == 0.

Submission expectations#

  • In general, when you receive an Assignment via a GitHub Classroom link, you want to clone your assignment repository, by doing

git clone your_assignment_repository_url
  • You can also work on a back-up repository or directory of your choice if you want to, for your scrap work, but you have to clone the assignment repository and submit your work there to be considered for submission and grading.

  • As soon as you clone your Assignment repository, move to that repository

cd your_assignment_repository
  • Create a new feature branch and switch to that. You can do this in two ways:

    • git checkout -b name_of_your_branch

    • git branch name_of_your_branch and then git checkout name_of_your_branch

  • Do NOT work directly off main

  • You can work on your feature branch as much as you like and create repeated incremental snapshots of your work via git commit. Always remember to use meaningful commit messages to remind yourself (and others) about your work in that moment in time. In a terminal you can simply do this by

git commit -m "Your commit message"

You can also write multi-line more detailed commit messages if you want. Just simply separate them with a space, and repeat the -m option, as in:

git commit -m "Your commit message" -m "Your more detailed message on a new line"
  • When you are satisfied with your committed work, you can push it to your working branch via:

git push origin your_branch_name

If it is the first time you are doing this, git will automatically tell you that you can open a Pull Request with your changes. Just CTRL-click on the URL that git shows you in the terminal and you will be sent to your Pull Request web interface.

Any successive changes that you want to push to your branch, they will be automatically reflected on the open PR.

  • Only changes made within the deadline (including the lateness window) will be graded.

  • Remember not to attempt to close or merge your PR without any Reviewer (in this case your instructor) approval.

  • Always remember to double check the File changed tab in your PR. If you see files that should not belong there (e.g., files automatically created by your IDE or virtual environment files) remove them.

  • If you are using an IDE that automatically creates hidden project files that you might inadvertently push to your branch, it is always a good practice to use a .gitignore file that specify which files you do not want to be tracked by git, and therefore, pushed to your branch. Recall that we covered this in our first lecture.

2.1 Assignments in Julia#

  • If you are asked to submit your code in Julia, recall what we have covered during our first lecture.

    • You are required to submit not only your Julia code (i.e., the file with the .jl extension), but also the Project.toml and Manifest.toml files that are created when you instantiate your environment. These files will be automatically populated if you need to use any Julia package that is available in the Julia registry, meaning, any package that you add by doing

    ]add PackageName
    

    or in the Julia REPL:

    using Pkg
    Pkg.add("PackageName")
    

    These files are fundamental for your reviewer to be able to reproduce exactly your environment, run your code, and reproduce your results.