diff --git a/apps/plots.py b/apps/plots.py
index 277cd656d121a3d924d263285c2076cfe82e6898..388525f34745b16ed9c875e3f66bf07213f27e13 100644
--- a/apps/plots.py
+++ b/apps/plots.py
@@ -52,7 +52,7 @@ def add_points(fig, ax, points):
 def add_polygons(fig, ax, polygons):
     for polygon in polygons:
         # only plot first two dims
-        p = mpl.patches.Polygon(polygon[:,0:2], True, fill=False, color="black", zorder=2)
+        p = mpl.patches.Polygon(np.array(polygon)[:,0:2], True, fill=False, color="black", zorder=2)
         ax.add_patch(p)
         # theoretically patch collections could be more efficient
         #p = PatchCollection(patches, alpha=0.4)
diff --git a/optimization/optimizers/conjugate_gradient_descent/main.cpp b/optimization/optimizers/conjugate_gradient_descent/main.cpp
index cfd85344c1366464bf7a0ace6d4f7f304a04f300..6ef15440ff9fa82c4368bc4937564d34c721c806 100644
--- a/optimization/optimizers/conjugate_gradient_descent/main.cpp
+++ b/optimization/optimizers/conjugate_gradient_descent/main.cpp
@@ -49,6 +49,7 @@ int main(int const argc, char const** argv) {
     using Objective = Rosenbrock<-1>;
     Objective objective;
     objective.dim() = dim;
+
     ConjugateGradientDescent<-1> optimizer(gradient_threshold, progress_threshold, max_iterations);
     VectorXs minimum = optimizer.optimize(objective, initial_point);
     std::cout << "n iterations: " << optimizer.n_iterations() << '\n';
diff --git a/optimization/optimizers/gradient_descent/CMakeLists.txt b/optimization/optimizers/gradient_descent/CMakeLists.txt
index e66c1437d1fabc91d480df3c6a1fc85f61a888ec..c2c77038db0eb22eb7dfc9a9960d2b1921eaba04 100644
--- a/optimization/optimizers/gradient_descent/CMakeLists.txt
+++ b/optimization/optimizers/gradient_descent/CMakeLists.txt
@@ -3,6 +3,6 @@ if (VISUALIZE)
         main.cpp
     )
     target_link_libraries(gradient_descent optimization_lib clara)
-    make_plot_target(gradient_descent 2d ARGS -d 2)
-    make_plot_target(gradient_descent 10d ARGS -d 10)
+    make_plot_target(gradient_descent 2d ARGS -d 2 -l 0.0015)
+    make_plot_target(gradient_descent 10d ARGS -d 10 -l 0.0005 -n 10000)
 endif()
diff --git a/optimization/optimizers/gradient_descent/main.cpp b/optimization/optimizers/gradient_descent/main.cpp
index 43ed1225f1eac075fcbb53902a32a8084fd78c6e..854576978eb3f9f43b2965d59ef4e81c2668ad31 100644
--- a/optimization/optimizers/gradient_descent/main.cpp
+++ b/optimization/optimizers/gradient_descent/main.cpp
@@ -34,14 +34,22 @@ int main(int const argc, char const** argv) {
         exit(1);
     }
 
-    Vector2<Scalar> initial_point = Vector2<Scalar>(x0, y0);
+    VectorXs initial_point;
+    initial_point.resize(dim);
+    initial_point[0] = x0;
+    initial_point[1] = y0;
+    for (uint32_t i = 2; i < dim; ++i) {
+        initial_point[i] = -1;
+    }
 
     //using Objective = Paraboloid<Vector2<Scalar>>;
     //Objective objective(dim);
-    using Objective = Rosenbrock<2>;
+    using Objective = Rosenbrock<-1>;
     Objective objective;
-    GradientDescent<2> optimizer(learning_rate, n_steps);
-    VectorNs<2> minimum = optimizer.optimize(objective, initial_point);
+    objective.dim() = dim;
+
+    GradientDescent<-1> optimizer(learning_rate, n_steps);
+    VectorXs minimum = optimizer.optimize(objective, initial_point);
     std::cout << "n evaluations: " << n_steps << '\n';
     std::cout << "final point: " << minimum << '\n';
 
@@ -52,7 +60,7 @@ int main(int const argc, char const** argv) {
     }
 
     if (!vis_file_path.empty()) {
-        json data = GradientDescentVis<2>{optimizer};
+        json data = GradientDescentVis<-1>{optimizer};
         std::ofstream vis_file(vis_file_path);
         vis_file << data.dump(4) << '\n';
     }
diff --git a/optimization/optimizers/nelder_mead/CMakeLists.txt b/optimization/optimizers/nelder_mead/CMakeLists.txt
index e057569b3d516dc5a064b938b9507e038425bf7f..cd984f8c32545f0334434e890783ae9120ca55b3 100644
--- a/optimization/optimizers/nelder_mead/CMakeLists.txt
+++ b/optimization/optimizers/nelder_mead/CMakeLists.txt
@@ -4,5 +4,5 @@ if (VISUALIZE)
     )
     target_link_libraries(nelder_mead optimization_lib clara)
     make_plot_target(nelder_mead 2d ARGS -d 2)
-    make_plot_target(nelder_mead 10d ARGS -d 10)
+    make_plot_target(nelder_mead 10d ARGS -d 10 -n 10000)
 endif()
diff --git a/optimization/optimizers/nelder_mead/main.cpp b/optimization/optimizers/nelder_mead/main.cpp
index 95b36dcf866818b1903646caf87f0f39f496e05f..e7522264ba4dc651d55b9e6376c55db5bc8865ad 100644
--- a/optimization/optimizers/nelder_mead/main.cpp
+++ b/optimization/optimizers/nelder_mead/main.cpp
@@ -14,12 +14,14 @@ using json = nlohmann::json;
 int main(int const argc, char const** argv) {
     std::string log_file_path;
     std::string vis_file_path;
+    uint32_t dim = 2;
     uint32_t max_evaluations = 1000;
     Scalar relative_y_tolerance = 1e-8;
 
     auto const cli =
         clara::Arg(log_file_path, "log_file_path")("Location of the optimization log") |
         clara::Arg(vis_file_path, "vis_file_path")("Location of the visualization file") |
+        clara::Opt(dim, "dim")["-d"]["--dim"]("Dimension of the search space") |
         clara::Opt(max_evaluations, "max_evaluations")["-n"]["--max-evals"]("Max number of function evaluations") |
         clara::Opt(relative_y_tolerance, "relative_y_tolerance")["-y"]["--rel-y-tol"]("Relative tolerance for function values (termination condition)");
     auto const result = cli.parse(clara::Args(argc, argv));
@@ -28,17 +30,22 @@ int main(int const argc, char const** argv) {
         exit(1);
     }
 
-    Eigen::Matrix<Scalar, 2, 3> simplex;
-    simplex.col(0) = Vector2s(-1, 2);
-    simplex.col(1) = Vector2s(-1, 1);
-    simplex.col(2) = Vector2s(-2, 2);
+    MatrixXs simplex;
+    simplex.resize(dim, dim + 1);
+    simplex.fill(-1);
+    simplex.row(1).fill(2);
+    for (uint32_t i = 0; i < dim; ++i) {
+        simplex(i, i + 1) -= 1;
+    }
 
     //using Objective = Paraboloid<Vector2<Scalar>>;
     //Objective objective(dim);
-    using Objective = Rosenbrock<2>;
+    using Objective = Rosenbrock<-1>;
     Objective objective;
-    NelderMead<Objective, 2> optimizer(max_evaluations, relative_y_tolerance);
-    VectorNs<2> minimum = optimizer.optimize(objective, simplex);
+    objective.dim() = dim;
+
+    NelderMead<Objective, -1> optimizer(max_evaluations, relative_y_tolerance);
+    VectorXs minimum = optimizer.optimize(objective, simplex);
     std::cout << "n evaluations: " << optimizer.n_evaluations() << '\n';
     std::cout << "final point: " << minimum << '\n';
 
@@ -49,7 +56,7 @@ int main(int const argc, char const** argv) {
     }
 
     if (!vis_file_path.empty()) {
-        json data = NelderMeadVis<Objective, 2>{optimizer};
+        json data = NelderMeadVis<Objective, -1>{optimizer};
         std::ofstream vis_file(vis_file_path);
         vis_file << data.dump(4) << '\n';
     }