let evaluate net input =
   (* helper to do the processing of all layers *)
   let rec loop rep activation =
      (* get the current layer *)
      match rep with
         neurons :: rest_rep ->
            begin
               if Array.length (get_synapses neurons.(0)) != Array.length activation +1 then
                  raise (Invalid_argument "Net size does not match input")
               else ();
               (* add the bias *)
               let activation = Array.append [|1.0|] activation in
               (* calculate the weighted sums *)
               let output = neurons |*| activation in
               (* descend to next layer *)
               loop rest_rep output
            end
      |  [] -> activation (* we have reached the output layer  -> return *)
   in
   (* apply inputs to all layers *)
   loop net input