<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Using C++
Lecture 11 will cover the baiscs of C++ progamming.
Lecture 12 will cover how to call C++ libraries from Python using pybind11
Since we are mainly learning C++ to wrap for use in Python, we will ignore C++ I/O.
The compilation process
Hello, world
Step1:  A simple function
Step2:  Using header files
Step3:  Notes
Step4:  A reusable Makefile
Step5:  Linking to a library
Step6:  Arrays, pointers and dereferencing
Step7:  Loops in C++
Step8:  Functions in C++
Step9:  Anonymous functions
Step10:  Templates
Step11:  Function pointers
Step12:  Using a numeric library
We show the Armadillo numeric library here; in the next lecture, we will show the competing Eigen libary.
<ASSISTANT_TASK:>
Python Code:
%mkdir hello
%cd hello
%%file hello.cpp
#include <iostream>
using std::cout;
using std::endl;
                
int main() {
    cout << "Hello, world" << endl;
}
! g++ hello.cpp -o hello
! ./hello
%cd ..
Explanation: Using C++
Lecture 11 will cover the baiscs of C++ progamming.
Lecture 12 will cover how to call C++ libraries from Python using pybind11
Since we are mainly learning C++ to wrap for use in Python, we will ignore C++ I/O.
The compilation process
Hello, world
End of explanation
%mkdir add1
%cd add1
%%file add.cpp
#include <iostream>
using std::cout;
using std::endl;
        
double add(double a, double b) {
    return a + b;
}
int main() {
    double a = 1.0, b= 2.0;
    
    double c = add(a, b);
    
    cout << a << " + " << b << " = " << c << endl;
}
! g++ add.cpp -o add
! ./add
%cd ..
Explanation: A simple function
End of explanation
%mkdir add2
%cd add2
%%file add.hpp
#pragma once
double add(double a, double b);
%%file add.cpp
double add(double a, double b) {
    return a + b;
}
%%file add_driver.cpp
#include "add.hpp"
#include <iostream>
using std::cout;
using std::endl;
        
int main() {
    double a = 1.0, b = 2.0;
    
    double c = add(a, b);
    
    cout << a << " + " << b  << " = " << c << endl;
}
%%bash
g++ add_driver.cpp add.cpp -o add_driver
./add_driver
%cd ..
Explanation: Using header files
End of explanation
%mkdir add3
%cp add2/add.cpp add2/add.hpp add2/add_driver.cpp add3/
%cd add3
%%file Makefile
add_driver: add_driver.o add.o
	g++ add_driver.o add.o -o add_driver
    
add_driver.o: add_driver.cpp add.hpp
	g++ -c add_driver.cpp
add.o: add.cpp
	g++ -c add.cpp
    
.PHONY: clean
clean: 
	rm add_driver *.o
! make
! make clean
! make
Explanation: Notes:
#pragma once is non-standard but very widely supported
if you want to be pedantic, use traditional guards
```c++
%%file src/add.hpp
ifndef ADD_HPP
define ADD_HPP
double add(double a, double b);
endif / ADD_HPP /
```
Using make
End of explanation
%%file Makefile
# Declaration of variables
CC = g++
CC_FLAGS = -Wall -std=c++11
 
# File names
EXEC = add_driver
SOURCES = $(wildcard *.cpp)
OBJECTS = $(SOURCES:.cpp=.o)
 
# Main target
$(EXEC): $(OBJECTS)
	$(CC) $(OBJECTS) -o $(EXEC)
 
# To obtain object files
%.o: %.cpp
	$(CC) -c $(CC_FLAGS) $< -o $@
 
# To remove generated files
clean:
	rm -f $(EXEC) $(OBJECTS)
%%bash
make clean
make
./add_driver
%cd ..
Explanation: A reusable Makefile
End of explanation
%mkdir linker
%cd linker
%%file test_linker.cpp
#include <cmath>
#include <iostream>
using std::cout;
using std::endl;
        
int main() {
    cout << "2^10 = " << pow(2, 10) << endl;
}
%%file Makefile
# Declaration of variables
CC = g++
CC_FLAGS = -Wall -std=c++11
 
# File names
EXEC = test_linker
SOURCES = $(wildcard *.cpp)
OBJECTS = $(SOURCES:.cpp=.o)
 
# Main target
$(EXEC): $(OBJECTS)
	$(CC) $(OBJECTS) -o $(EXEC)
 
# To obtain object files
%.o: %.cpp
	$(CC) -c $(CC_FLAGS) $< -o $@
 
# To remove generated files
clean:
	rm -f $(EXEC) $(OBJECTS)
! make
! ./test_linker
%cd ..
Explanation: Linking to a library
End of explanation
%mkdir arrays
%cd arrays
%%file arrays.cpp
#include <cmath>
#include <iostream>
using std::cout;
using std::endl;
        
int main() {
    
    // pointers and address-of opertor
    int a = 1, b = 2;
    int *p = &a, *q = &b;
    
    cout << a << ", " << b << endl;
    cout << *p << ", " << *q << endl;
    cout << p << ", " << q << endl;
    // An array name is just a pointer
    int ms[] = {1,2,3,4};
    
    // using indexing
    cout << ms[0] << ", " << ms[1] << endl;
    // using pointer arithmetic
    cout << *(ms) << ", " << *(ms + 0) << ", " << *(ms + 2) << endl; 
    cout << 2[ms] << ", " << 3[ms] << endl; // wait, what??
    
    // size of an array
    cout << sizeof(ms)/sizeof(*ms) << endl;    
}
%%file Makefile
# Declaration of variables
CC = g++
CC_FLAGS = -Wall -std=c++11
 
# File names
EXEC = arrays
SOURCES = $(wildcard *.cpp)
OBJECTS = $(SOURCES:.cpp=.o)
 
# Main target
$(EXEC): $(OBJECTS)
	$(CC) $(OBJECTS) -o $(EXEC)
 
# To obtain object files
%.o: %.cpp
	$(CC) -c $(CC_FLAGS) $< -o $@
 
# To remove generated files
clean:
	rm -f $(EXEC) $(OBJECTS)
%%bash
make
./arrays
%cd ..
Explanation: Arrays, pointers and dereferencing
End of explanation
%mkdir loops
%cd loops
%%file loops.cpp
#include <cmath>
#include <iostream>
using std::cout;
using std::endl;
        
int main() {
    double xs[] = {0,1,2,3,4,5,6,7,8,9};    
   
    // looping with an index
    for (int i=0; i<sizeof(xs)/sizeof(*xs); i++) {
        cout << pow(xs[i], 2) << " ";
    }
    cout << endl;
    
    // looping with an iterator
    for (auto it=std::begin(xs); it!=std::end(xs); it++) {
        cout << pow(*it, 2) << " ";
    }
    cout << endl;
    
    // ranged for loop
    for (auto x : xs) {
        cout << pow(x, 2) << " ";
    }
    cout << endl;
    
}
%%file Makefile
# Declaration of variables
CC = g++
CC_FLAGS = -Wall -std=c++11
 
# File names
EXEC = loops
SOURCES = $(wildcard *.cpp)
OBJECTS = $(SOURCES:.cpp=.o)
 
# Main target
$(EXEC): $(OBJECTS)
	$(CC) $(OBJECTS) -o $(EXEC)
 
# To obtain object files
%.o: %.cpp
	$(CC) -c $(CC_FLAGS) $< -o $@
 
# To remove generated files
clean:
	rm -f $(EXEC) $(OBJECTS)
%%bash
make clean
make
./loops
%cd ..
Explanation: Loops in C++
End of explanation
%mkdir funcs1
%cd funcs1
%%file funcs1.cpp
#include <iostream>
using std::cout;
using std::endl;
        
double sum(double *xs, int n) {
    double s = 0.0;
    
    for (int i=0; i<n; i++) {
        s += xs[i];
    }
    return s;
}    
void triple(double *xs, double * ys, int n) {   
     for (int i=0; i<n; i++) {
        ys[i] = 3 * xs[i];
    }
}
    
int main() {
    double xs[] = {1,2,3,4};
    int n = sizeof(xs)/sizeof(*xs);
    
    cout << sum(xs, n) << endl;
    
    double ys[n];
    
    triple(xs, ys, n);
        for (auto y : ys) {
        cout << y << " ";
    }
    cout << endl;    
}
%%file Makefile
# Declaration of variables
CC = g++
CC_FLAGS = -Wall -std=c++11
 
# File names
EXEC = funcs1
SOURCES = $(wildcard *.cpp)
OBJECTS = $(SOURCES:.cpp=.o)
 
# Main target
$(EXEC): $(OBJECTS)
	$(CC) $(OBJECTS) -o $(EXEC)
 
# To obtain object files
%.o: %.cpp
	$(CC) -c $(CC_FLAGS) $< -o $@
 
# To remove generated files
clean:
	rm -f $(EXEC) $(OBJECTS)
%%bash
make
./funcs1
%cd ..
Explanation: Functions in C++
End of explanation
%mkdir funcs2
%cd funcs2
%%file funcs2.cpp
#include <iostream>
using std::cout;
using std::endl;
        
int main() {
    double k = 5.0;
    double a = 1.0, b = 2.0;
    
    auto add1 = [](int a, int b) { return a + b; };
    auto add2 = [k](int a, int b) { return a + b + k; };
    auto add3 = [&k](int a, int b) { return a + b + k; };
    k *= 2;
    
    cout << "Lambda: " << add1(a, b) << endl;
    cout << "Lambda with capture by value: " << add2(a, b) << endl;
    cout << "Lmabda with capture by reference: " << add3(a, b) << endl;
}
%%file Makefile
# Declaration of variables
CC = g++
CC_FLAGS = -Wall -std=c++11
 
# File names
EXEC = funcs2
SOURCES = $(wildcard *.cpp)
OBJECTS = $(SOURCES:.cpp=.o)
 
# Main target
$(EXEC): $(OBJECTS)
	$(CC) $(OBJECTS) -o $(EXEC)
 
# To obtain object files
%.o: %.cpp
	$(CC) -c $(CC_FLAGS) $< -o $@
 
# To remove generated files
clean:
	rm -f $(EXEC) $(OBJECTS)
%%bash
make clean
make
./funcs2
%cd ..
Explanation: Anonymous functions
End of explanation
%mkdir templates
%cd templates
%%file templates.cpp
#include <iostream>
#include <vector>
#include <list>
#include <numeric>
using std::cout;
using std::endl;
using std::list;
using std::vector;
template<typename T>
T sum(vector<T> xs) {
    T s = 0.0;
    for (auto x : xs) {
        s += x;
    }
    return s;
}
int main(){
    vector<int> ns = {1,2,3};
    vector<double> xs = {4.5, 6.4, 7.8};
    
    // sum works with integers
    cout << "Sum of ints: " << sum(ns) << endl;
    
    // sum works with doubles
    cout << "Sum of doubles: " << sum(xs) << endl;
    
    // iota from the numeric library behaves like range
    list<int> ys(10);
    std::iota(ys.begin(), ys.end(), -3);
    
    // accumulate from the numeric library behavses like reduce with default operation of addition   
    cout << "Sum from iota: " << std::accumulate(ys.begin(), ys.end(), 6.0) << endl;
    // Note that the initial value determines the template type
    cout << "Sum of doubles using accumulate: " << std::accumulate(xs.begin(), xs.end(), 0.0) << endl;
    cout << "Surpise: " << std::accumulate(xs.begin(), xs.end(), 0) << endl;
    // The binary operation can be user-defined
    auto op = std::multiplies<int>();
    cout << "Product of ints: " << std::accumulate(ns.begin(), ns.end(), 1, op) << endl;
}
%%file Makefile
# Declaration of variables
CC = g++
CC_FLAGS = -Wall -std=c++11
 
# File names
EXEC = templates
SOURCES = $(wildcard *.cpp)
OBJECTS = $(SOURCES:.cpp=.o)
 
# Main target
$(EXEC): $(OBJECTS)
	$(CC) $(OBJECTS) -o $(EXEC)
 
# To obtain object files
%.o: %.cpp
	$(CC) -c $(CC_FLAGS) $< -o $@
 
# To remove generated files
clean:
	rm -f $(EXEC) $(OBJECTS)
%%bash
make clean
make
./templates
%cd ..
Explanation: Templates
End of explanation
%mkdir func_ptrs
%cd func_ptrs
%%file func_ptrs.cpp
#include <numeric>
#include <functional>
#include <iostream>
#include <vector>
using std::cout;
using std::endl;
using std::vector;
    
double sum(vector<double> xs) {
    return std::accumulate(xs.begin(), xs.end(), 0.0);
}
double prod(vector<double> xs) {
    return std::accumulate(xs.begin(), xs.end(), 1.0, std::multiplies<double>());
}
 
// funciton pointers in C++ are easy    
using func = std::function<double(double)>;
      
// now you can pass in a funciton as an argument
double mystery(double x, func f) {
    return f(x);
}
double foo(double x) {
    return 2*x + 1;
}
double bar(double x) {
    return 42*x;
}
int main() {
    vector<double> xs = {1.2, 2.3};
    cout << sum(xs) << endl;
    cout << prod(xs) << endl;  
    
    // auto can crate iterables of functions!
    auto funcs = {sum, prod};    
    for (auto f: funcs) {
        cout << f(xs) << endl;   
    }
    
    int x = 2;    
    cout << mystery(x, foo) << endl;
    cout << mystery(x, bar) << endl;
    cout << mystery(x, [](double x) {return x*x;}) << endl;
    
}
%%file Makefile
# Declaration of variables
CC = g++
CC_FLAGS = -Wall -std=c++11
 
# File names
EXEC = func_ptrs
SOURCES = $(wildcard *.cpp)
OBJECTS = $(SOURCES:.cpp=.o)
 
# Main target
$(EXEC): $(OBJECTS)
	$(CC) $(OBJECTS) -o $(EXEC)
 
# To obtain object files
%.o: %.cpp
	$(CC) -c $(CC_FLAGS) $< -o $@
 
# To remove generated files
clean:
	rm -f $(EXEC) $(OBJECTS)
%%bash
make clean
make
./func_ptrs
%cd ..
Explanation: Function pointers
End of explanation
%mkdir numeric
%cd numeric
%%file numeric.cpp
#include <iostream>
#include <fstream>
#include <armadillo>
using std::cout;
using std::ofstream;
        
int main() 
{
    using namespace arma;
    vec u = linspace<vec>(0,1,5);
    vec v = ones<vec>(5);
    mat A = randu<mat>(4,5); // uniform random deviates
    mat B = randn<mat>(4,5); // normal random deviates
    cout << "\nVecotrs in Armadillo\n";
    cout << u << endl;
    cout << v << endl;
    cout << u.t() * v << endl;
    cout << "\nRandom matrices in Armadillo\n";
    cout << A << endl;
    cout << B << endl;
    cout << A * B.t() << endl;
    cout << A * v << endl;
    cout << "\nQR in Armadillo\n";
    mat Q, R;
    qr(Q, R, A.t() * A);
    cout << Q << endl;
    cout << R << endl;
}
%%file Makefile
# Declaration of variables
CC = g++
CC_FLAGS = -Wall -std=c++11
LD_FLAGS = -larmadillo # Add library for linking
# File names
EXEC = numeric
SOURCES = $(wildcard *.cpp)
OBJECTS = $(SOURCES:.cpp=.o)
 
# Main target
$(EXEC): $(OBJECTS)
	$(CC) $(LD_FLAGS) $(OBJECTS) -o $(EXEC)
 
# To obtain object files
%.o: %.cpp
	$(CC) -c $(CC_FLAGS) $< -o $@
 
# To remove generated files
clean:
	rm -f $(EXEC) $(OBJECTS)
%%bash
make clean
make
./numeric
%cd ..
Explanation: Using a numeric library
We show the Armadillo numeric library here; in the next lecture, we will show the competing Eigen libary.
End of explanation
<END_TASK>