diff --git a/src/main.rs b/src/main.rs
index d5cdc82..e7101c7 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,20 +1,120 @@
use std::iter::Sum;
-use std::ops::Mul;
+use std::ops::{Mul, Sub};
type Point = [A; N];
type Parameters = [Point; M];
+#[macro_export]
+macro_rules! tensor {
+ ($x:ty , $i: expr) => {[$x; $i]};
+ ($x:ty , $i: expr, $($is:expr),+) => {[tensor!($x, $($is),+); $i]};
+}
+
+pub trait Extensible1 {
+ fn apply(&self, other: &A, op: &F) -> Self
+ where
+ F: Fn(&A, &A) -> A;
+}
+
+pub trait Extensible2 {
+ fn apply(&self, other: &Self, op: &F) -> Self
+ where
+ F: Fn(&A, &A) -> A;
+}
+
+impl Extensible1 for [T; N]
+where
+ T: Extensible1 + Copy + Default,
+{
+ fn apply(&self, other: &A, op: &F) -> Self
+ where
+ F: Fn(&A, &A) -> A,
+ {
+ let mut result = [Default::default(); N];
+ for (i, coord) in self.iter().enumerate() {
+ result[i] = T::apply(coord, other, op);
+ }
+ result
+ }
+}
+
+impl Extensible2 for [T; N]
+where
+ T: Extensible2 + Copy + Default,
+{
+ fn apply(&self, other: &Self, op: &F) -> Self
+ where
+ F: Fn(&A, &A) -> A,
+ {
+ let mut result = [Default::default(); N];
+ for (i, coord) in self.iter().enumerate() {
+ result[i] = T::apply(coord, &other[i], op);
+ }
+ result
+ }
+}
+
+#[macro_export]
+macro_rules! extensible1 {
+ ($x: ty) => {
+ impl Extensible1<$x> for $x {
+ fn apply(&self, other: &$x, op: &F) -> Self
+ where
+ F: Fn(&Self, &Self) -> Self,
+ {
+ op(self, other)
+ }
+ }
+ };
+}
+
+#[macro_export]
+macro_rules! extensible2 {
+ ($x: ty) => {
+ impl Extensible2<$x> for $x {
+ fn apply(&self, other: &Self, op: &F) -> Self
+ where
+ F: Fn(&Self, &Self) -> Self,
+ {
+ op(self, other)
+ }
+ }
+ };
+}
+
+extensible1!(u8);
+extensible1!(f64);
+
+extensible2!(u8);
+extensible2!(f64);
+
+pub fn extension1(t1: &T, t2: &A, op: F) -> T
+where
+ T: Extensible1,
+ F: Fn(&A, &A) -> A,
+{
+ t1.apply::(t2, &op)
+}
+
+pub fn extension2(t1: &T, t2: &T, op: F) -> T
+where
+ T: Extensible2,
+ F: Fn(&A, &A) -> A,
+{
+ t1.apply::(t2, &op)
+}
+
fn dot_points(x: &Point, y: &Point) -> A
where
- A: Sum<::Output> + Copy,
+ A: Sum<::Output> + Copy + Default + Mul