diff --git a/quad/computation_graph/src/computation_graph.c b/quad/computation_graph/src/computation_graph.c
index 9fb4ffcc82fd4e06eb390fcfd353d7a5bd539960..d64fa753f1e1d287e8bc55717a8f3b7ce6d27435 100644
--- a/quad/computation_graph/src/computation_graph.c
+++ b/quad/computation_graph/src/computation_graph.c
@@ -4,6 +4,10 @@
 #include "computation_graph.h"
 
 #define GRAPH_MAX_DEPTH 20
+#define GRAPH_MAX_INPUTS 20
+
+// Array to store input values for passing to the execute function of each node
+static double exec_input_vals[GRAPH_MAX_INPUTS];
 
 struct computation_graph *create_graph() {
     struct computation_graph *the_graph = malloc(sizeof(struct computation_graph));
@@ -24,7 +28,7 @@ int graph_set_source(struct computation_graph *graph,
     }
     struct graph_node *dest_node = &graph->nodes[dest_cntl_id];
     struct graph_node *src_node = &graph->nodes[src_cntl_id];
-    if (dest_input >= dest_node->n_inputs || src_output >= src_node->n_outputs) {
+    if (dest_input >= dest_node->type->n_inputs || src_output >= src_node->type->n_outputs) {
         return -1;
     }
 
@@ -34,15 +38,11 @@ int graph_set_source(struct computation_graph *graph,
     return 0;
 }
 
-int graph_create_node(struct computation_graph *graph,
-                      const char* name,
-                      const char* const* input_names,
-                      const char* const* output_names,
-                      int n_inputs,
-                      int n_outputs,
-                      execute_node_t exec_func,
-                      reset_node_t reset_func,
-                      void *state) {
+int graph_add_node(struct computation_graph *graph,
+                   const char* name,
+                   const struct graph_node_type *type,
+                   void *state) {
+    assert(type->n_inputs <= GRAPH_MAX_INPUTS);
     int new_id = graph->n_nodes;
     if (new_id >= graph->size) {
         int new_capacity = graph->n_nodes == 0 ? 1 : graph->n_nodes * 2;
@@ -55,34 +55,29 @@ int graph_create_node(struct computation_graph *graph,
     }
     struct graph_node *new_node = &graph->nodes[new_id];
     new_node->name = strdup(name);
-    new_node->input_names = input_names;
-    new_node->output_names = output_names;
-    new_node->output_values = malloc(n_outputs * sizeof(double));
-    new_node->input_values = malloc(n_inputs * sizeof(double));
+    new_node->type = type;
+    new_node->output_values = malloc(type->n_outputs * sizeof(double));
+    new_node->param_values = malloc(type->n_params * sizeof(double));
     new_node->state = state;
-    new_node->execute = exec_func;
-    new_node->reset = reset_func;
-    new_node->n_inputs = n_inputs;
-    new_node->n_outputs = n_outputs;
-    new_node->input_srcs = malloc(n_inputs * sizeof(struct input_type));
+    new_node->input_srcs = malloc(type->n_inputs * sizeof(struct input_type));
     int i;
-    for (i = 0; i < n_inputs; i++) {
+    for (i = 0; i < type->n_inputs; i++) {
         new_node->input_srcs[i].controller_id = -1;
     }
     graph->n_nodes += 1;
     return new_id;
 }
 
-int graph_set_input_val(struct computation_graph *graph, int node_id, int input_id, double value) {
-    if (node_id >= graph->n_nodes || input_id >= graph->nodes[node_id].n_inputs) {
+int graph_set_param_val(struct computation_graph *graph, int node_id, int param_id, double value) {
+    if (node_id >= graph->n_nodes || param_id >= graph->nodes[node_id].type->n_params) {
         return -1;
     }
-    graph->nodes[node_id].input_values[input_id] = value;
+    graph->nodes[node_id].param_values[param_id] = value;
     return 0;
 }
 
 double graph_get_output(const struct computation_graph *graph, int node_id, int output_id) {
-    if (node_id >= graph->n_nodes || output_id >= graph->nodes[node_id].n_outputs) {
+    if (node_id >= graph->n_nodes || output_id >= graph->nodes[node_id].type->n_outputs) {
         return -1;
     }
     return graph->nodes[node_id].output_values[output_id];
@@ -96,22 +91,23 @@ void graph_compute_node_rec(struct computation_graph *graph, int node_id, int de
     if (node_id >= graph->n_nodes) {
         return;
     }
+    // TODO: Fix self-reference loop
     struct graph_node *node = &graph->nodes[node_id];
     if (node->processed_state == PROCESSED) {
         return;
     }
     int input_id;
-    for (input_id = 0; input_id < node->n_inputs; input_id++) {
+    for (input_id = 0; input_id < node->type->n_inputs; input_id++) {
         int src_cntl_id = node->input_srcs[input_id].controller_id;
         if (src_cntl_id != -1) {
             if (graph->nodes[src_cntl_id].processed_state == UNPROCESSED) {
                 graph_compute_node_rec(graph, src_cntl_id, depth + 1);
             }
             int src_output_id = node->input_srcs[input_id].controller_output;
-            node->input_values[input_id] = graph->nodes[src_cntl_id].output_values[src_output_id];
+            exec_input_vals[input_id] = graph->nodes[src_cntl_id].output_values[src_output_id];
         }
     }
-    (*node->execute)(node->state, node->input_values, node->output_values);
+    (*node->type->execute)(node->state, node->param_values, exec_input_vals, node->output_values);
     node->processed_state = PROCESSED;
 }
 
@@ -130,22 +126,24 @@ int export_dot(const struct computation_graph* graph, FILE* of) {
     int i;
     for (i = 0; i < graph->n_nodes; i++) {
         struct graph_node *node = &graph->nodes[i];
-        // Separate node and inputs as a cluster
-        fprintf(of, "subgraph cluster_%d {\n", i);
         // Create node
-        fprintf(of, "\"%s\"\n", node->name);
-        // Draw inputs to graph
+        fprintf(of, "\"%s\"[label=\"", node->name);
+        fprintf(of, "Name: %s\n", node->name); // Node name first
         int j;
-        for (j = 0; j < node->n_inputs; j++) {
-            // Block for input to node
-            fprintf(of, "\"%s[%s]\"[shape=box]\n", node->name, node->input_names[j]);
-            // Link inputs to node
-            fprintf(of, "\"%s[%s]\" -> \"%s\"[label=\"%.3f\"]\n", node->name, node->input_names[j], node->name,
-                    node->input_values[j]);
+        // Add parameters as labels
+        for (j = 0; j < node->type->n_params; j++) {
+            fprintf(of, "%s=%.3f\n", node->type->param_names[j], node->param_values[j]);
+        }
+        fprintf(of, "\"]\n"); // Close label bracket
+        //
+        for (j = 0; j < node->type->n_inputs; j++) {
+            struct graph_node* src_node = &graph->nodes[node->input_srcs[j].controller_id];
+            int output_id = node->input_srcs[j].controller_output;
+            const char* output_name = src_node->type->output_names[output_id];
+            fprintf(of, "\"%s\" -> \"%s\" [label=\"%s=%.3f\"]\n", src_node->name, node->name, output_name, src_node->output_values[output_id]);
         }
-        fprintf(of, "}\n"); // Close cluster
     }
-
+    /*
     // Draw the links between nodes
     for (i = 0; i < graph->n_nodes; i++) {
         struct graph_node *node = &graph->nodes[i];
@@ -161,7 +159,7 @@ int export_dot(const struct computation_graph* graph, FILE* of) {
             }
         }
     }
-
-    fprintf(of, "}"); // Close graph
+    */
+    fprintf(of, "}"); // Close graph1
     return 0;
 }
\ No newline at end of file
diff --git a/quad/computation_graph/src/computation_graph.h b/quad/computation_graph/src/computation_graph.h
index 18c7930d1b666c63578e8fee9f4d4699d23f07bd..301187cf4ee8b59c5c01f921e856a03e89fb4732 100644
--- a/quad/computation_graph/src/computation_graph.h
+++ b/quad/computation_graph/src/computation_graph.h
@@ -3,7 +3,10 @@
 
 #include <stdio.h>
 
-typedef void (*execute_node_t)(void *state, const double *inputs, double *outputs);
+typedef void (*execute_node_t)(void *state,
+                               const double* params,
+                               const double *inputs,
+                               double *outputs);
 
 typedef void (*reset_node_t)(void *state);
 
@@ -19,17 +22,25 @@ struct computation_graph {
     struct graph_node *nodes;
 };
 
-struct graph_node {
-    char *name;
-    const char* const *input_names;
-    const char* const *output_names;
-    double *output_values;
-    double *input_values;
+// Declares a node type
+struct graph_node_type {
+    const char* const* input_names;
+    const char* const* output_names;
+    const char* const* param_names;
     int n_inputs;
     int n_outputs;
-    void *state;
+    int n_params;
     execute_node_t execute;
     reset_node_t reset;
+};
+
+// Declares an instance of a node
+struct graph_node {
+    const char *name;
+    const struct graph_node_type* type;
+    double *output_values;
+    double *param_values;
+    void *state;
     int processed_state;
     struct input_type {
         int controller_id;
@@ -41,19 +52,14 @@ struct computation_graph *create_graph();
 
 int graph_set_source(struct computation_graph *graph, int dest_cntl, int dest_input, int src_cntl, int src_output);
 
-int graph_create_node(struct computation_graph *graph,
-                      const char* name,
-                      const char* const *input_names,
-                      const char* const *output_names,
-                      int n_inputs,
-                      int n_outputs,
-                      execute_node_t exec_func,
-                      reset_node_t reset_func,
-                      void *state);
+int graph_add_node(struct computation_graph *graph,
+                   const char *name,
+                   const struct graph_node_type *type,
+                   void *state);
 
 double graph_get_output(const struct computation_graph *graph, int node_id, int output_id);
 
-int graph_set_input_val(struct computation_graph *graph, int node_id, int input_id, double value);
+int graph_set_param_val(struct computation_graph *graph, int node_id, int param_id, double value);
 
 void graph_compute_node(struct computation_graph *graph, int node_id);
 
diff --git a/quad/computation_graph/src/main.c b/quad/computation_graph/src/main.c
index 19a188ac2374e01c3d1a8f880a105917d35b409e..761a1ac515d36423276fb0908b73a1ffe82567f3 100644
--- a/quad/computation_graph/src/main.c
+++ b/quad/computation_graph/src/main.c
@@ -1,29 +1,33 @@
 #include <stdio.h>
 #include "computation_graph.h"
-#include "node_add2.h"
+#include "node_add.h"
 #include "node_mult.h"
+#include "node_constant.h"
+#include "node_pow.h"
 
 int main() {
     struct computation_graph *graph = create_graph();
-    int add2_id = graph_add_node_add2(graph, "add1");
-    graph_set_input_val(graph, add2_id, ADD2_SUMMAND1, 3);
-    graph_set_input_val(graph, add2_id, ADD2_SUMMAND2, 2);
 
-    int add3_id = graph_add_node_add2(graph, "add2");
-    graph_set_input_val(graph, add3_id, ADD2_SUMMAND2, 5);
-    graph_set_source(graph, add3_id, ADD2_SUMMAND1, add2_id, ADD2_SUM);
+    int const1 = graph_add_node_const(graph, "Const 1");
+    graph_set_param_val(graph, const1, CONST_SET, 2);
+    int const2 = graph_add_node_const(graph, "Const 2");
+    graph_set_param_val(graph, const2, CONST_SET, 3);
 
-    int mult1_id = graph_add_node_mult(graph, "mult");
-    graph_set_source(graph, mult1_id, MULT_MULTIPLICAND1, add2_id, ADD2_SUM);
-    graph_set_source(graph, mult1_id, MULT_MULTIPLICAND2, add3_id, ADD2_SUM);
+    int add1_id = graph_add_node_add(graph, "Add");
+    graph_set_source(graph, add1_id, ADD_SUMMAND1, const1, CONST_VAL);
+    graph_set_source(graph, add1_id, ADD_SUMMAND2, const2, CONST_VAL);
 
-    graph_compute_node(graph, mult1_id);
+    int pow1_id = graph_add_node_pow(graph, "Pow");
+    graph_set_param_val(graph, pow1_id, POW_EXP, 3);
+    graph_set_source(graph, pow1_id, POW_BASE, add1_id, ADD_SUM);
+
+    graph_compute_node(graph, pow1_id);
 
     FILE* dot_fp;
     dot_fp = fopen("..\\comp_graph.dot", "w");
     export_dot(graph, dot_fp);
     fclose(dot_fp);
-    printf("Sum is %f\n", graph_get_output(graph, mult1_id, ADD2_SUM));
+    printf("Sum is %f\n", graph_get_output(graph, pow1_id, POW_RESULT));
     fflush(stdout);
     return 0;
 }
diff --git a/quad/computation_graph/src/node_add.c b/quad/computation_graph/src/node_add.c
new file mode 100644
index 0000000000000000000000000000000000000000..a28ca657b6ebe25838806b8369c1669aefb99323
--- /dev/null
+++ b/quad/computation_graph/src/node_add.c
@@ -0,0 +1,25 @@
+#include "node_add.h"
+#include <stdlib.h>
+
+static void add_nodes(void *state, const double* params, const double *inputs, double *outputs) {
+    outputs[ADD_SUM] = inputs[ADD_SUMMAND1] + inputs[ADD_SUMMAND2];
+}
+static void reset(void *state) {}
+
+static const char* const in_names[2] = {"Summand 1", "Summand 2"};
+static const char* const out_names[1] = {"Sum"};
+static const char* const param_names[0] = {};
+const struct graph_node_type node_add_type = {
+        .input_names = in_names,
+        .output_names = out_names,
+        .param_names = param_names,
+        .n_inputs = 2,
+        .n_outputs = 1,
+        .n_params = 0,
+        .execute = add_nodes,
+        .reset = reset
+};
+
+int graph_add_node_add(struct computation_graph *graph, const char* name) {
+    return graph_add_node(graph, name, &node_add_type, NULL);
+}
diff --git a/quad/computation_graph/src/node_add.h b/quad/computation_graph/src/node_add.h
new file mode 100644
index 0000000000000000000000000000000000000000..5c90ea16cfd390e126a600415e4e173bf5076943
--- /dev/null
+++ b/quad/computation_graph/src/node_add.h
@@ -0,0 +1,17 @@
+#ifndef __NODE_ADD_H__
+#define __NODE_ADD_H__
+#include "computation_graph.h"
+
+int graph_add_node_add(struct computation_graph *graph, const char* name);
+
+const extern struct graph_node_type node_add_type;
+
+enum graph_node_add_inputs {
+    ADD_SUMMAND1,
+    ADD_SUMMAND2,
+};
+
+enum graph_node_add_outputs {
+    ADD_SUM
+};
+#endif // __NODE_ADD_H__
\ No newline at end of file
diff --git a/quad/computation_graph/src/node_add2.c b/quad/computation_graph/src/node_add2.c
deleted file mode 100644
index 62c9c1a844a5ab66f027df76af411e412c056466..0000000000000000000000000000000000000000
--- a/quad/computation_graph/src/node_add2.c
+++ /dev/null
@@ -1,15 +0,0 @@
-#include "node_add2.h"
-#include <stdlib.h>
-
-static const char* const in_names[2] = {"Summand 1", "Summand 2"};
-static const char* const out_names[1] = {"Sum"};
-
-static void add_nodes(void *state, const double *inputs, double *outputs) {
-    outputs[ADD2_SUM] = inputs[ADD2_SUMMAND1] + inputs[ADD2_SUMMAND2];
-}
-
-static void reset(void *state) {}
-
-int graph_add_node_add2(struct computation_graph *graph, const char* name) {
-    return graph_create_node(graph, name, in_names, out_names, 2, 1, &add_nodes, &reset, NULL);
-}
diff --git a/quad/computation_graph/src/node_add2.h b/quad/computation_graph/src/node_add2.h
deleted file mode 100644
index ba2d3e0e03043fb50e6c537d660bee4a63ece79a..0000000000000000000000000000000000000000
--- a/quad/computation_graph/src/node_add2.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#include "computation_graph.h"
-
-int graph_add_node_add2(struct computation_graph *graph, const char* name);
-
-enum graph_node_add2_inputs {
-    ADD2_SUMMAND1,
-    ADD2_SUMMAND2
-};
-
-enum graph_node_add2_outputs {
-    ADD2_SUM
-};
diff --git a/quad/computation_graph/src/node_constant.c b/quad/computation_graph/src/node_constant.c
new file mode 100644
index 0000000000000000000000000000000000000000..47ab571d5636d45c7e27ff3d47c45f3e7f305e38
--- /dev/null
+++ b/quad/computation_graph/src/node_constant.c
@@ -0,0 +1,25 @@
+#include "node_constant.h"
+#include <stdlib.h>
+
+static void output_const(void *state, const double *params, const double *inputs, double *outputs) {
+    outputs[CONST_VAL] = params[CONST_SET];
+}
+static void reset(void *state) {}
+
+static const char* const in_names[0] = {};
+static const char* const out_names[1] = {"Constant"};
+static const char* const param_names[1] = {"Constant"};
+const struct graph_node_type node_const_type = {
+        .input_names = in_names,
+        .output_names = out_names,
+        .param_names = param_names,
+        .n_inputs = 0,
+        .n_outputs = 1,
+        .n_params = 1,
+        .execute = output_const,
+        .reset = reset
+};
+
+int graph_add_node_const(struct computation_graph *graph, const char* name) {
+    return graph_add_node(graph, name, &node_const_type, NULL);
+}
diff --git a/quad/computation_graph/src/node_constant.h b/quad/computation_graph/src/node_constant.h
new file mode 100644
index 0000000000000000000000000000000000000000..67acbc2d733393bb12af640bb34ff3e99b344150
--- /dev/null
+++ b/quad/computation_graph/src/node_constant.h
@@ -0,0 +1,16 @@
+#ifndef __NODE_CONSTANT_H__
+#define __NODE_CONSTANT_H__
+#include "computation_graph.h"
+
+int graph_add_node_const(struct computation_graph *graph, const char* name);
+
+const extern struct graph_node_type node_const_type;
+
+enum graph_node_const_params {
+    CONST_SET
+};
+
+enum graph_node_const_outputs {
+    CONST_VAL
+};
+#endif //__NODE_CONSTANT_H__
\ No newline at end of file
diff --git a/quad/computation_graph/src/node_mult.c b/quad/computation_graph/src/node_mult.c
index cc4a1b21db51a9f806d33b0b6af2d0c162bf24a1..b727249f62a3fda1dba8aca5701c50868c5aa550 100644
--- a/quad/computation_graph/src/node_mult.c
+++ b/quad/computation_graph/src/node_mult.c
@@ -1,15 +1,25 @@
 #include "node_mult.h"
 #include <stdlib.h>
 
-static const char* const in_names[2] = {"Multiplicand 1", "Multiplicand 2"};
-static const char* const out_names[1] = {"Product"};
-
-static void mult_nodes(void *state, const double *inputs, double *outputs) {
+static void mult_nodes(void *state, const double* params, const double *inputs, double *outputs) {
     outputs[MULT_PRODUCT] = inputs[MULT_MULTIPLICAND1] * inputs[MULT_MULTIPLICAND2];
 }
-
 static void reset(void *state) {}
 
+static const char* const in_names[2] = {"Multiplicand 1", "Multiplicand 2"};
+static const char* const out_names[1] = {"Product"};
+static const char* const param_names[0] = {};
+const struct graph_node_type node_mult_type = {
+        .input_names = in_names,
+        .output_names = out_names,
+        .param_names = param_names,
+        .n_inputs = 2,
+        .n_outputs = 1,
+        .n_params = 0,
+        .execute = mult_nodes,
+        .reset = reset
+};
+
 int graph_add_node_mult(struct computation_graph *graph, const char* name) {
-    return graph_create_node(graph, name, in_names, out_names, 2, 1, &mult_nodes, &reset, NULL);
+    return graph_add_node(graph, name, &node_mult_type, NULL);
 }
diff --git a/quad/computation_graph/src/node_mult.h b/quad/computation_graph/src/node_mult.h
index 744bf85f08ddd35238ed624f496cf18aa62a1ffa..39b37cd59f0dbb20516be1983d5c86c2291ca49d 100644
--- a/quad/computation_graph/src/node_mult.h
+++ b/quad/computation_graph/src/node_mult.h
@@ -1,12 +1,18 @@
+#ifndef __NODE_MULT_H__
+#define __NODE_MULT_H__
 #include "computation_graph.h"
 
 int graph_add_node_mult(struct computation_graph *graph, const char* name);
 
+const extern struct graph_node_type node_mult_type;
+
 enum graph_node_mult_inputs {
     MULT_MULTIPLICAND1,
-    MULT_MULTIPLICAND2
+    MULT_MULTIPLICAND2,
 };
 
 enum graph_node_mult_outputs {
     MULT_PRODUCT
 };
+
+#endif  // __NODE_MULT_H__
\ No newline at end of file
diff --git a/quad/computation_graph/src/node_pow.c b/quad/computation_graph/src/node_pow.c
new file mode 100644
index 0000000000000000000000000000000000000000..2e817fc39d8bc227b7d876ad98f7f3c40bd03448
--- /dev/null
+++ b/quad/computation_graph/src/node_pow.c
@@ -0,0 +1,26 @@
+#include "node_pow.h"
+#include <stdlib.h>
+#include <math.h>
+
+static void pow_nodes(void *state, const double* params, const double *inputs, double *outputs) {
+    outputs[POW_RESULT] = pow(inputs[POW_BASE], params[POW_EXP]);
+}
+static void reset(void *state) {}
+
+static const char* const in_names[1] = {"Base"};
+static const char* const out_names[1] = {"Result"};
+static const char* const param_names[1] = {"Exponent"};
+const struct graph_node_type node_pow_type = {
+        .input_names = in_names,
+        .output_names = out_names,
+        .param_names = param_names,
+        .n_inputs = 1,
+        .n_outputs = 1,
+        .n_params = 1,
+        .execute = pow_nodes,
+        .reset = reset
+};
+
+int graph_add_node_pow(struct computation_graph *graph, const char* name) {
+    return graph_add_node(graph, name, &node_pow_type, NULL);
+}
diff --git a/quad/computation_graph/src/node_pow.h b/quad/computation_graph/src/node_pow.h
new file mode 100644
index 0000000000000000000000000000000000000000..be98299548aaf5147687e4c248383038d1d56f14
--- /dev/null
+++ b/quad/computation_graph/src/node_pow.h
@@ -0,0 +1,20 @@
+#ifndef __NODE_POW_H__
+#define __NODE_POW_H__
+#include "computation_graph.h"
+
+int graph_add_node_pow(struct computation_graph *graph, const char* name);
+
+const extern struct graph_node_type node_pow_type;
+
+enum graph_node_pow_inputs {
+    POW_BASE
+};
+
+enum graph_node_pow_params {
+    POW_EXP
+};
+
+enum graph_node_add2_outputs {
+    POW_RESULT
+};
+#endif // __NODE_POW_H__
\ No newline at end of file