aboutsummaryrefslogtreecommitdiff
path: root/sem4
diff options
context:
space:
mode:
Diffstat (limited to 'sem4')
-rw-r--r--sem4/embedded/emb_m2/emb_m2.ino233
-rw-r--r--sem4/embedded/emb_m2/myfloat_red.h57
-rw-r--r--sem4/hpp/pythonAB/opg_a_b.ipynb347
3 files changed, 637 insertions, 0 deletions
diff --git a/sem4/embedded/emb_m2/emb_m2.ino b/sem4/embedded/emb_m2/emb_m2.ino
new file mode 100644
index 0000000..c6a6a07
--- /dev/null
+++ b/sem4/embedded/emb_m2/emb_m2.ino
@@ -0,0 +1,233 @@
+#include "myfloat_red.h"
+
+// Number of numbers
+#define NN 100
+#define PRINT_PRECISION 10
+
+#define NEXT_OPG(c) Serial.print("\nOpgave "); Serial.println(c++);
+#define AND_OPG(c) Serial.print("and "); Serial.println(c++);
+
+unsigned int opg_count = 1;
+
+void printmydoubarr(myfloat_type *arr, size_t len) {
+ Serial.print("[ ");
+ for(size_t i = 0; i < len; i++) {
+ Serial.print(myfloat2double( &arr[i] ), PRINT_PRECISION);
+ Serial.print(" ");
+ }
+ Serial.println("]");
+}
+
+void printarr(double *arr, size_t len) {
+ Serial.print("[ ");
+ for(size_t i = 0; i < len; i++) {
+ Serial.print(arr[i], PRINT_PRECISION);
+ Serial.print(" ");
+ }
+ Serial.println("]");
+}
+
+unsigned long factorial(unsigned int n) {
+ unsigned long res = 1;
+ for(unsigned int i = 2; i <= n; i++) {
+ res *= i;
+ }
+
+ return res;
+}
+
+double sineTayler(double x, unsigned int n) {
+ double sum = 0;
+
+ for(unsigned int i = 0; i <= n; i++) {
+ sum += ((double)pow(-1, i) / (double)factorial(2 * i + 1)) * (double)pow(x, 2 * i + 1);
+ }
+
+
+ return sum;
+}
+
+#define TAU 1.57079632679
+// After some trial and error the best TAYLORN was 2
+#define TAYLORN 2
+double sine(double x) {
+
+ // Works by finding value in specific -pi/2 to pi/2 period.
+ int period = x / TAU;
+
+ // One cycle of sin takes 4 periods.
+ // If 0 just return the sine approx x
+ // If 1 do negative sine approx on x - TAU
+ // If 2 do negative sine approx x
+ // If 3 do sine approx on period x - TAU
+ x = abs(x - TAU*period);
+
+ double res = 12;
+
+ switch( abs(period % 4) ) {
+ case 0:
+ res = sineTayler(x, TAYLORN);
+ break;
+ case 1:
+ res = -sineTayler(x - TAU, TAYLORN);
+ break;
+ case 2:
+ res = -sineTayler(x, TAYLORN);
+ break;
+ case 3:
+ res = sineTayler(x - TAU, TAYLORN);
+ break;
+ }
+ // Remember to multiply with sign
+ int sign = period < 0 ? -1 : 1;
+
+ // Should never return because all cases are handled
+ return res * sign;
+
+}
+
+void mean_rel_error(double *da, myfloat_type *mda, size_t len, double *sign) {
+ // Calculate and print the relative error using the formula
+ // X - x
+ // ----- Where x is the calculated value and X is the real value( As real as double gets )
+ // X
+ double errorsum = 0;
+ Serial.print("Rel Err : [ ");
+ for(size_t i = 0; i < len; i++) {
+ //Serial.println(errorsum, PRINT_PRECISION);
+ // Make space for sign
+ if( sign[i] < 0 ) {
+ Serial.print(" ");
+ }
+ // Handle devide by 0
+ double error = da[i] ? abs(da[i] - myfloat2double(&mda[i])) / abs(da[i]) : 0;
+ Serial.print(error, PRINT_PRECISION);
+ Serial.print(" ");
+
+ // Save sum for mean
+ errorsum += error;
+ }
+ Serial.println("]");
+
+ // Calculate mean
+ double mean = errorsum / len;
+ Serial.print("Mean Err: "); Serial.println(mean, PRINT_PRECISION);
+}
+
+void setup() {
+ Serial.begin(115200);
+
+ NEXT_OPG(opg_count);
+ // OPG1. Create some doubles
+ double da[NN];
+ for(int i = 0; i < NN; i++) {
+ da[i] = ((double)random(-5000, 5000)) / 1000.0;
+ }
+ Serial.print("Original: "); printarr(da, NN);
+
+ NEXT_OPG(opg_count);
+ // OPG2. Convert to mda
+ myfloat_type mda[NN];
+ for(int i = 0; i < NN; i++) {
+ doub2mydouble(da[i], &mda[i]);
+ }
+
+ Serial.print("Mydoub : "); printmydoubarr(mda, NN);
+
+ NEXT_OPG(opg_count);
+ // OPG3. Calculate the mean relative error
+ mean_rel_error(da, mda, NN, da);
+
+ {
+ NEXT_OPG(opg_count);
+ // OPG4. Compute some stuff
+ double da2[NN];
+ for(int i = 0; i < NN; i++) {
+ da2[i] = da[i] * da[i];
+ }
+ Serial.print("Orig pow: "); printarr(da2, NN);
+
+ NEXT_OPG(opg_count);
+ // OPG5.
+ myfloat_type mda2[NN];
+ for(int i = 0; i < NN; i++) {
+ // This thing sometimes does weird stuff -4.06*(-4.06) -> -16.00
+ mult_float(&mda[i], &mda[i], &mda2[i]);
+ }
+ Serial.print("Mda pow: "); printmydoubarr(mda2, NN);
+
+ NEXT_OPG(opg_count);
+ // OPG6. Doing the mean error thing
+ mean_rel_error(da2, mda2, NN, da);
+ }
+
+ {
+ // OPG7. Measure execution time
+ NEXT_OPG(opg_count);
+ double a = da[1];
+ unsigned long begin = micros();
+ for(int i = 1; i < NN; i++) {
+ a *= da[i];
+ }
+
+ unsigned long time1 = micros() - begin;
+ Serial.print("Exe time: "); Serial.println(time1);
+ Serial.print("a : "); Serial.println(a);
+
+ NEXT_OPG(opg_count);
+ // Convert to myfloat
+ myfloat_type f1;
+ doub2mydouble(a, &f1);
+
+ Serial.print("f1 : "); Serial.println(myfloat2double(&f1));
+
+ NEXT_OPG(opg_count);
+ // OPG8-9.
+ begin = micros();
+ for(int i = 0; i < NN; i++) {
+ // Multiply
+ myfloat_type f;
+ mult_float(&f1, &mda[i], &f);
+
+ // Copy back
+ memcpy(&f1, &f, sizeof(myfloat_type));
+ }
+
+ unsigned long time2 = micros() - begin;
+ Serial.print("Exe time: "); Serial.println(time2);
+ Serial.print("f1 : "); Serial.println(myfloat2double(&f1));
+ Serial.println("Overflow");
+
+ NEXT_OPG(opg_count);
+ // OPG10. Difference relative to biggest result
+
+ unsigned long absdiff = abs( time1 - time2 );
+ Serial.print("Abs diff: "); Serial.println(absdiff);
+ double reldiff = (double)absdiff / max(abs(time1), abs(time2));
+ Serial.print("Rel diff: "); Serial.println(reldiff);
+ }
+
+ NEXT_OPG(opg_count);
+ // OPG11. Impl sine
+ // Hardest value should be TAU as it's the furthest from center.
+ unsigned long begin = micros();
+ double res = sine(TAU);
+ unsigned long time1 = micros() - begin;
+ Serial.print("own sin : "); Serial.println(res, PRINT_PRECISION);
+
+ begin = micros();
+ double correct = sin(TAU);
+ unsigned long time2 = micros() - begin;
+ Serial.print("ard sin : "); Serial.println(correct, PRINT_PRECISION);
+
+ double error = correct ? abs(correct - res) / abs(correct) : 0;
+ Serial.print("rel err : "); Serial.println(error, PRINT_PRECISION);
+
+ Serial.print("\nown time: "); Serial.println(time1);
+ Serial.print("ard time: "); Serial.println(time2);
+
+}
+
+void loop() {
+
+}
diff --git a/sem4/embedded/emb_m2/myfloat_red.h b/sem4/embedded/emb_m2/myfloat_red.h
new file mode 100644
index 0000000..b553233
--- /dev/null
+++ b/sem4/embedded/emb_m2/myfloat_red.h
@@ -0,0 +1,57 @@
+/*
+ Low level precision floating point lib
+ Author: Henrik Schiøler
+*/
+
+//low precision floating pt type
+typedef struct myfloat
+{
+ signed char mantissa;
+ signed char exponent;
+} myfloat_type;
+
+
+//convert from double to low precision type
+void doub2mydouble(double arg, myfloat_type *res)
+{
+ int exponent;
+ double temp;
+ exponent = ceil(log(abs(arg))/log(2)); //base 2 logarithm
+ temp=arg*pow(2,7-exponent);
+ res->mantissa = (signed char)temp;
+ res->exponent = exponent-7;
+}
+
+//convert from low precision type to double
+double myfloat2double(myfloat_type *arg1)
+{
+ double res = (double)(arg1->mantissa) * pow(2,arg1->exponent);
+ return res;
+}
+
+//multiply to low precision types
+void mult_float(myfloat_type *arg1,myfloat_type *arg2,myfloat_type *result)
+{
+ int temp;
+ unsigned char sign;
+
+ sign=0x80 & ((unsigned char)arg1-> mantissa ^ (unsigned char)arg2-> mantissa); //find sign of result
+
+ char i=0;
+ temp = (int)(arg1-> mantissa) * (int)(arg2-> mantissa);
+
+ temp = temp & 0x7f00; //take away sign from product
+
+ while(abs(temp)>128)
+ {
+ i++;
+ temp=temp>>1;
+ }
+
+ result->mantissa = (unsigned char) temp;
+
+ result->mantissa = result->mantissa | sign; //add recorded sign
+
+ result->exponent = arg1->exponent + arg2->exponent + i;
+
+}
diff --git a/sem4/hpp/pythonAB/opg_a_b.ipynb b/sem4/hpp/pythonAB/opg_a_b.ipynb
new file mode 100644
index 0000000..7214643
--- /dev/null
+++ b/sem4/hpp/pythonAB/opg_a_b.ipynb
@@ -0,0 +1,347 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Opgaver til python A og B kursus"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Opgave 1\n",
+ "\n",
+ "Make a function that can appproximate an integral using mid point integration:\n",
+ "\n",
+ "$$ \\int_a^b f(x) dx \\approx h \\cdot \\sum_{i=0}^{n-1} f(a + 1/2 h + ih)$$\n",
+ "\n",
+ "1. Make a Python function midpointint(f, a, b, n): that performs the mid point integration where f is a scalar function that can be evaluated as f(x).\n",
+ "2. Compute closed form solutions of $\\int_a^b f(x) dx$ for your favorite $f$ e.g. exp, sin, cos\n",
+ "3. Validate you implementation with the closed form solution"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def midpointint(f, a, b, n): \n",
+ " \"\"\" \n",
+ " Approximates int(a to b) f(x) dx using midpoint integration. \n",
+ " \"\"\" \n",
+ " h = (b-a)/n \n",
+ " \n",
+ " # Create a generator and sum it \n",
+ " gen = (f(a + 1/2 * h + i * h) for i in range(0, n-1)) \n",
+ " \n",
+ " return h * sum(gen)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "I like $f(x) = e^x$ so that is what we will do. With $a = 0, b = 10$.\n",
+ "\n",
+ "$$\\int_0^{10} e^x dx = e^{10} -1 \\approx 22025$$"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "21806.207938916818"
+ ]
+ },
+ "execution_count": 10,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import math\n",
+ "f = lambda x: math.exp(x)\n",
+ "midpointint(f, 0, 10, 1000)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Trying a $f(x) = sin(x)$ with in same interval.\n",
+ "\n",
+ "$$\\int_0^{10} sin(x) dx \\approx 1.8391$$"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "1.8444773816015885"
+ ]
+ },
+ "execution_count": 11,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "f = lambda x: math.sin(x)\n",
+ "midpointint(f, 0, 10, 1000)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Opgave 3"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Make a Python script, which defines and prints the following integer arrays:\n",
+ "\n",
+ "$$ D_1 = \\left[\\begin{matrix}\n",
+ " 1 & 0 & 1 \\\\\n",
+ " 0 & 2 & 0 \\\\\n",
+ " 1 & 0 & 1\n",
+ "\\end{matrix}\\right]$$\n",
+ "\n",
+ "$$ D_2 = \\left[\\begin{matrix}\n",
+ " 1 & 8 & 1 \\\\\n",
+ " 8 & 2 & 8 \\\\\n",
+ " 1 & 8 & 1\n",
+ "\\end{matrix}\\right]$$\n",
+ "\n",
+ "\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 31,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[[1, 8, 1], [8, 2, 8], [1, 8, 1]]"
+ ]
+ },
+ "execution_count": 31,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "D1 = [\n",
+ " [1, 0, 1],\n",
+ " [0, 2, 0],\n",
+ " [1, 0, 1]\n",
+ "]\n",
+ "D2 = [\n",
+ " [1, 8, 1],\n",
+ " [8, 2, 8],\n",
+ " [1, 8, 1]\n",
+ "]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "In the script further compute the following:\n",
+ "\n",
+ "1. Make a list of tuples containing indices to matrix elements $(D_2)_{i,j}$ where $(D_2)_{i,j} > 1$. Print the list and validate that it is correct."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[(0, 1), (1, 0), (1, 1), (1, 2), (2, 1)]"
+ ]
+ },
+ "execution_count": 22,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# This can be done using list comprehention\n",
+ "[(i, j) for (i, r) in enumerate(D2) for (j, c) in enumerate(r) if c > 1]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[(0, 1), (1, 0), (1, 1), (1, 2), (2, 1)]"
+ ]
+ },
+ "execution_count": 26,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Or generators\n",
+ "def gen():\n",
+ " for (i, r) in enumerate(D2):\n",
+ " for (j, c) in enumerate(r):\n",
+ " if c > 1:\n",
+ " yield (i, j)\n",
+ " \n",
+ "list(gen())"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "2. Make a new matrix as:\n",
+ "$$ F = \\left[\\begin{matrix}\n",
+ "D_2 & D_2 \\\\\n",
+ "D_2 & D_2\n",
+ "\\end{matrix}\\right]$$\n",
+ "Print **F** and the shape of **F** as a tuple.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 39,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "(6, 6)\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "[[1, 8, 1, 1, 8, 1],\n",
+ " [8, 2, 8, 8, 2, 8],\n",
+ " [1, 8, 1, 1, 8, 1],\n",
+ " [1, 8, 1, 1, 8, 1],\n",
+ " [8, 2, 8, 8, 2, 8],\n",
+ " [1, 8, 1, 1, 8, 1]]"
+ ]
+ },
+ "execution_count": 39,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Multiplying list concatinates it with itself.\n",
+ "\n",
+ "F = [2*r for r in D2] * 2\n",
+ "\n",
+ "# outer inner\n",
+ "print((len(F), len(F[0])))\n",
+ "F"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "3. Compute and print the sum of all elements of the **F** matrix."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 59,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "152"
+ ]
+ },
+ "execution_count": 59,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "sum((c for r in F for c in r))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "4. Use Python to determine and print the number of ‘1’, ‘2’ and ‘8’ values in **F**."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 65,
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1: 16, 2: 4, 8: 16\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Not very efficient because we loop multiple times.\n",
+ "count = lambda n: sum((1 for r in F for c in r if c == n))\n",
+ "\n",
+ "print(f\"1: {count(1)}, 2: {count(2)}, 8: {count(8)}\")"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.1"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}