From 5220f74262542a5bd345e3b91a613005ead786c5 Mon Sep 17 00:00:00 2001
From: Elias Pipping <elias.pipping@fu-berlin.de>
Date: Mon, 10 Oct 2011 17:09:04 +0200
Subject: [PATCH] Add octave interface to minimise()

---
 src/H.m             |  9 ++++++++
 src/Makefile.am     |  2 ++
 src/duneminimise.cc | 54 +++++++++++++++++++++++++++++++++++++++++++++
 src/duneminimise.mk | 16 ++++++++++++++
 src/foo.m           | 40 +++++++++++++++++++++++++++++++++
 5 files changed, 121 insertions(+)
 create mode 100644 src/H.m
 create mode 100644 src/duneminimise.cc
 create mode 100644 src/duneminimise.mk
 create mode 100644 src/foo.m

diff --git a/src/H.m b/src/H.m
new file mode 100644
index 00000000..72fd1b21
--- /dev/null
+++ b/src/H.m
@@ -0,0 +1,9 @@
+% -*- mode:octave -*-
+
+function ret = H(s)
+  if s < 1
+    ret = 1*s;
+  else
+    ret = 2*s+1*(1-2);
+  end
+end
diff --git a/src/Makefile.am b/src/Makefile.am
index 0eba1530..2b7ac107 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -39,3 +39,5 @@ DISTCHECK_CONFIGURE_FLAGS = --with-dune-common=$(DUNE_COMMON_ROOT) --with-dune-f
 include $(top_srcdir)/am/global-rules
 
 include $(top_srcdir)/flymake.mk
+
+include $(srcdir)/duneminimise.mk
diff --git a/src/duneminimise.cc b/src/duneminimise.cc
new file mode 100644
index 00000000..4617157f
--- /dev/null
+++ b/src/duneminimise.cc
@@ -0,0 +1,54 @@
+/* -*- mode:c++; mode:semantic -*- */
+
+#include <octave/oct.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <dune/common/exceptions.hh>
+
+#include "samplefunctional.hh"
+
+#include <cassert>
+
+DEFUN_DLD(duneminimise, args, nargout, "the help string") {
+  ColumnVector current(args(0).matrix_value());
+  // FIXME: We're only working with dimension two for now
+  assert(current.length() == 2);
+
+  int const dim = 2;
+  typedef Dune::SampleFunctional<dim> SampleFunctional;
+
+  SampleFunctional::SmallMatrix A;
+  A[0][0] = 3;
+  A[0][1] = 1.5;
+  A[1][0] = 1.5;
+  A[1][1] = 4;
+  SampleFunctional::SmallVector b;
+  b[0] = 1;
+  b[1] = 2;
+
+  Dune::SampleFunction f;
+  SampleFunctional J(A, b, Dune::MyNonlinearity<dim>(f));
+
+  SampleFunctional::SmallVector start;
+  start[0] = current(0);
+  start[1] = current(1);
+
+  /// END OF SETUP
+
+  SampleFunctional::SmallVector correction;
+  Dune::minimise(J, start, correction);
+  start += correction;
+
+  ColumnVector foo(dim);
+  foo(0) = start[0];
+  foo(1) = start[1];
+
+  return octave_value(foo);
+}
+
+// Compile using:
+// mkoctfile duneoctave.cc -I$HOME/dune-git-svn/dune-fufem
+// -I$HOME/dune-git-svn/dune-tnnmg -ldunecommon && octave --eval duneoctave
diff --git a/src/duneminimise.mk b/src/duneminimise.mk
new file mode 100644
index 00000000..c7f4bd31
--- /dev/null
+++ b/src/duneminimise.mk
@@ -0,0 +1,16 @@
+MKOCTFILE=mkoctfile
+
+bin_PROGRAMS = duneminimise.oct
+
+# this would work if shared libraries were only passed via -L and -l, not directly
+#duneminimise_LINK = libtool --tag=CXX --mode link $(MKOCTFILE) $(AM_LDFLAGS) -o $@
+
+duneminimise.oct: duneminimise.o
+	$(MKOCTFILE) -o $@ $< -ldunecommon
+
+duneminimise.o: duneminimise.cc
+	$(MKOCTFILE) $(AM_CPPFLAGS) -c -o $@ $<
+
+.PHONY:
+run-octave: duneminimise.oct
+	octave --path $(abs_builddir) --path $(abs_srcdir)
diff --git a/src/foo.m b/src/foo.m
new file mode 100644
index 00000000..36d6110c
--- /dev/null
+++ b/src/foo.m
@@ -0,0 +1,40 @@
+% -*- mode:octave -*-
+
+clear all
+close all
+
+x = (-300:10:300);
+y = (-300:10:300)';
+v = ones(length(x),1);
+X = v * x;
+Y = y * v';
+A = [3 1.5; 1.5 4];
+b = [1; 2];
+
+myfunc = @(x)(1/2 * (A * x)' * x - b' * x + H(norm(x)));
+
+for i=1:length(x)
+  for j=1:length(y)
+      vec = [ X(i,j); Y(i,j) ];
+      val = myfunc(vec);
+      f(i,j) = val;
+  end
+end
+axis([-10, 10, -10, 10]);
+mesh(x, y, f)
+hold on;
+
+oldvec = [279; -96];
+
+for i=1:6
+  newvec=duneminimise(oldvec);
+  line([oldvec(1) newvec(1)], ...
+       [oldvec(2) newvec(2)], ...
+       [myfunc(oldvec) myfunc(newvec)], ...
+       'color', 'r');
+  norm(oldvec-newvec)
+  oldvec=newvec;
+end
+
+hold off;
+
-- 
GitLab