Learning outcomes for *numerical algorithms*:

- Deep knowledge of the most fundamental algorithms for linear algebra, ordinary and partial differential equations, optimization, and statistical uncertainty quantification.
- Overview of advanced algorithms and how they can be accessed in available software.
- Knowledge of high-performance computing elements: memory usage, vectorized and parallel algorithms.
- Understanding of approximation errors.
- Application of fundamental and advanced algorithms to classical model problems as well as real-world problems with assessment of the uncertainty in the answer.

- Knowledge of at least one computer algebra system and how it is applied to perform classical mathematics (calculus, linear algebra, differential equations - with verification).

- Extensive experience with programming in a high-level language (MATLAB, Python, R). Experience with programming in a compiled language (Fortran, C, C++).
- Extensive experience with implementing and applying numerical algorithms in reusable software that acknowledges the generic nature of the mathematical algorithms.
- Knowledge of basic software engineering elements: functions, classes, modules/libraries, testing procedures and frameworks, scripting for automated and reproducible experiments, documentation tools, and version control systems.
- Extensive experience with debugging software, e.g., as part of implementing comprehensive tests.

- Extensive experience with programming of testing procedures.
- Deep knowledge of testing/verification methods:
- Exact solution of numerical models
- Method of manufactured solutions (choose solution and fit a problem)
- Classical analytical solutions (incl. asymptotic solutions)
- Computing of asymptotic approximation errors (convergence rates)
- Step-wise construction of tests to aid debugging.

- Experience with deriving computational models from basic principles in applied sciences (physics, geology, biology, etc.).
- Experience with bringing models on dimensionless form to reduce and simplify input data and increase the understanding of the model by interpreting its dimensionless parameters.
- Experience with solving real problems from applied sciences.

- Experience with different visualization techniques for different types of computed data.
- Extensive experience with presenting computed results in scientific reports and oral presentations.

By deep knowledge we here mean the understanding of the underlying fundamental ideas and concepts from which a plethora of seemingly different methods and technologies can be derived. In other words, the deep knowledge brings structure to all the technical details.

Obtaining this type knowledge requires time in class and a lot of
exercises. In addition, the students need to *reflect* about theory and
practice. The reflection process is often difficult to implement.
Below are some suggestions.

A useful concept is *simplify, understand, and then
generalize*. Giving a superficial overview of a bunch of unrelated
methods and their applications to unrelated scientific problems equips
the students with a wide toolbox, but fails to enhance a fundamental
understanding of how multidisciplinary topics play together. Instead,
we believe in the following list.

- Pick a few selected classes of problems,
- start out with simplified models,
- apply general, fundamental ideas to construct algorithms,
- understand all details to correctly implement the algorithms,
- understand how to judge the numerical quality of the algorithms,
- understand how to verify that the computations are mathematically correct.

After obtaining an understanding of the simplified problem, one can generalize the models to real applications, but illustrate how the insight from the simplified models and methods gives very valuable knowledge when attacking the generalizations. The focus on simplified models help to detach the mathematics from a lot of discipline-dependent application details and cultivate the common mathematical and implementational ideas.

This philosophy is closely related to the *Key principle* stated earlier:

- solving a complicated problem first starts with the purpose of breaking up the problem into subtasks that belong to general classes of well-studied problems in mathematics,
- each subproblem is understood with great help simplified models in that class,
- and finally a synthesis of the subproblems can solve the original problem.

(**hpl 1**: Need to highlight educational methods: instruction based teaching, project work, ...)