diff --git a/Circuit/__init__.py b/.gitignore
similarity index 100%
rename from Circuit/__init__.py
rename to .gitignore
diff --git a/Elements/__init__.py b/__main__.py
similarity index 100%
rename from Elements/__init__.py
rename to __main__.py
diff --git a/elements/__init__.py b/elements/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..9664db059251e7c9e9a2e29007f3fe619d4c6b51
--- /dev/null
+++ b/elements/__init__.py
@@ -0,0 +1,2 @@
+import numpy as np
+import cmath
diff --git a/elements/main.py b/elements/main.py
new file mode 100644
index 0000000000000000000000000000000000000000..ddc33e25797f36ec6f4574055e65a34969be05c7
--- /dev/null
+++ b/elements/main.py
@@ -0,0 +1,58 @@
+class Source:
+    def __init__(self, initial_vector=np.array([0., 0.+0j])):
+        self.photon = initial_vector
+        self.next = None
+
+
+class Screen:
+    def __init__(self, previous=(None, None)):
+        self.previous = previous
+
+
+class Element:
+    def __init__(self, previous): ## previous is either a single (previous_object, output) tuple, or a 2-dictionary of tuples
+        self.previous = previous  ## (as in {"left": (Object 1, "label of chosen output of object 1"), "right": (obj2, "label2")})
+        self.next = None
+
+class Plate(Element):
+    def __init__(self, jones_matrix = np.eye((2, 2), dtype='complex')):
+        self.jones_matrix = jones_matrix
+        self.output_vector = None
+
+    def out(self, side):
+        previous_element = self.previous[0]
+        previous_element_output_side = self.previous[1]
+        self.output_vector = self.jones_matrix @ previous_element(previous_element_output_side) # matrix-vector product : jones matrix times state vector given by the out(side) method of the previous component
+        return self.output_vector
+
+class BeamSplitter(Element):
+    """matrix is a 4x4 complex ndarray, two first dimensions regard left input, two next are right. So it's blockwise defined."""
+    def __init__(self, matrix = np.eye((4, 4), dtype='complex')):
+        self.matrix = matrix
+        self.output_vector = None
+
+    def out(self, side):
+        if self.previous["left"] is None:
+            left_input_state = np.zeros((2,), dtype="complex") # if no input on the left, then |\psi> = 0
+        else:
+            left_input_element = self.previous["left"][0]
+            left_input_element_output_side = self.previous["left"][1]
+            left_input_state = left_input_element.out(left_input_element_output_side)
+
+        if self.previous["right"] is None:
+            left_input_state = np.zeros((2,), dtype="complex") # if no input on the right, then |\psi> = 0
+        else:
+            right_input_element = self.previous["right"][0]
+            right_input_element_output_side = self.previous["right"][1]
+            right_input_state = right_input_element.out(right_input_element_output_side)
+
+        input_state = np.concatenate((left_input_state, right_input_state))
+        self.output_vector = self.matrix @ input_state
+
+        if side == "left":
+            ans, _ = np.split(self.output_vector)
+
+        elif side == "right":
+            _, ans = np.split(self.output_vector)
+
+        return ans
diff --git a/Graphics/__init__.py b/graphics/__init__.py
similarity index 100%
rename from Graphics/__init__.py
rename to graphics/__init__.py
diff --git a/main.py b/requirements.txt
similarity index 100%
rename from main.py
rename to requirements.txt