diff --git a/wpiutil/src/generate/GenericNumber.java.in b/wpiutil/src/generate/GenericNumber.java.in
deleted file mode 100644
index 5a36582..0000000
--- a/wpiutil/src/generate/GenericNumber.java.in
+++ /dev/null
@@ -1,34 +0,0 @@
-/*----------------------------------------------------------------------------*/
-/* Copyright (c) 2019 FIRST. All Rights Reserved.                             */
-/* Open Source Software - may be modified and shared by FRC teams. The code   */
-/* must be accompanied by the FIRST BSD license file in the root directory of */
-/* the project.                                                               */
-/*----------------------------------------------------------------------------*/
-
-package edu.wpi.first.wpiutil.math.numbers;
-
-import edu.wpi.first.wpiutil.math.Nat;
-import edu.wpi.first.wpiutil.math.Num;
-
-/**
- * A class representing the number ${num}.
-*/
-public final class N${num} extends Num implements Nat<N${num}> {
-  private N${num}() {
-  }
-
-  /**
-   * The integer this class represents.
-   *
-   * @return The literal number ${num}.
-  */
-  @Override
-  public int getNum() {
-    return ${num};
-  }
-
-  /**
-   * The singleton instance of this class.
-  */
-  public static final N${num} instance = new N${num}();
-}
diff --git a/wpiutil/src/generate/Nat.java.in b/wpiutil/src/generate/Nat.java.in
deleted file mode 100644
index 8c471f6..0000000
--- a/wpiutil/src/generate/Nat.java.in
+++ /dev/null
@@ -1,27 +0,0 @@
-/*----------------------------------------------------------------------------*/
-/* Copyright (c) 2019 FIRST. All Rights Reserved.                             */
-/* Open Source Software - may be modified and shared by FRC teams. The code   */
-/* must be accompanied by the FIRST BSD license file in the root directory of */
-/* the project.                                                               */
-/*----------------------------------------------------------------------------*/
-
-package edu.wpi.first.wpiutil.math;
-
-//CHECKSTYLE.OFF: ImportOrder
-{{REPLACEWITHIMPORTS}}
-//CHECKSTYLE.ON
-
-/**
- * A natural number expressed as a java class.
- * The counterpart to {@link Num} that should be used as a concrete value.
- *
- * @param <T> The {@link Num} this represents.
- */
-@SuppressWarnings({"MethodName", "unused", "PMD.TooManyMethods"})
-public interface Nat<T extends Num> {
-  /**
-   * The number this interface represents.
-   *
-   * @return The number backing this value.
-   */
-  int getNum();
diff --git a/wpiutil/src/generate/NatGetter.java.in b/wpiutil/src/generate/NatGetter.java.in
deleted file mode 100644
index d268fab..0000000
--- a/wpiutil/src/generate/NatGetter.java.in
+++ /dev/null
@@ -1,3 +0,0 @@
-  static Nat<N${num}> N${num}() {
-    return N${num}.instance;
-  }
diff --git a/wpiutil/src/main/java/edu/wpi/first/wpiutil/CombinedRuntimeLoader.java b/wpiutil/src/main/java/edu/wpi/first/wpiutil/CombinedRuntimeLoader.java
new file mode 100644
index 0000000..8f0d53e
--- /dev/null
+++ b/wpiutil/src/main/java/edu/wpi/first/wpiutil/CombinedRuntimeLoader.java
@@ -0,0 +1,184 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2020 FIRST. All Rights Reserved.                             */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.wpiutil;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public final class CombinedRuntimeLoader {
+  private CombinedRuntimeLoader() {
+  }
+
+  private static String extractionDirectory;
+
+  public static synchronized String getExtractionDirectory() {
+    return extractionDirectory;
+  }
+
+  private static synchronized void setExtractionDirectory(String directory) {
+    extractionDirectory = directory;
+  }
+
+  public static native String setDllDirectory(String directory);
+
+  private static String getLoadErrorMessage(String libraryName, UnsatisfiedLinkError ule) {
+    StringBuilder msg = new StringBuilder(512);
+    msg.append(libraryName).append(" could not be loaded from path\n"
+        + "\tattempted to load for platform ")
+        .append(RuntimeDetector.getPlatformPath())
+        .append("\nLast Load Error: \n")
+        .append(ule.getMessage())
+        .append('\n');
+    if (RuntimeDetector.isWindows()) {
+      msg.append("A common cause of this error is missing the C++ runtime.\n"
+          + "Download the latest at https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads\n");
+    }
+    return msg.toString();
+  }
+
+  /**
+   * Extract a list of native libraries.
+   * @param <T>             The class where the resources would be located
+   * @param clazz           The actual class object
+   * @param resourceName    The resource name on the classpath to use for file lookup
+   * @return                List of all libraries that were extracted
+   * @throws IOException    Thrown if resource not found or file could not be extracted
+   */
+  @SuppressWarnings({"PMD.AvoidInstantiatingObjectsInLoops", "PMD.UnnecessaryCastRule"})
+  public static <T> List<String> extractLibraries(Class<T> clazz, String resourceName)
+      throws IOException {
+    TypeReference<HashMap<String, Object>> typeRef = new TypeReference<HashMap<String, Object>>() {
+    };
+    ObjectMapper mapper = new ObjectMapper();
+    Map<String, Object> map;
+    try (var stream = clazz.getResourceAsStream(resourceName)) {
+      map = mapper.readValue(stream, typeRef);
+    }
+
+    var platformPath = Paths.get(RuntimeDetector.getPlatformPath());
+    var platform = platformPath.getName(0).toString();
+    var arch = platformPath.getName(1).toString();
+
+    var platformMap = (Map<String, List<String>>) map.get(platform);
+
+    var fileList = platformMap.get(arch);
+
+    var extractionPathString = getExtractionDirectory();
+
+    if (extractionPathString == null) {
+      String hash = (String) map.get("hash");
+
+      var defaultExtractionRoot = RuntimeLoader.getDefaultExtractionRoot();
+      var extractionPath = Paths.get(defaultExtractionRoot, platform, arch, hash);
+      extractionPathString = extractionPath.toString();
+
+      setExtractionDirectory(extractionPathString);
+    }
+
+    List<String> extractedFiles = new ArrayList<>();
+
+    byte[] buffer = new byte[0x10000]; // 64K copy buffer
+
+    for (var file : fileList) {
+      try (var stream = clazz.getResourceAsStream(file)) {
+        Objects.requireNonNull(stream);
+
+        var outputFile = Paths.get(extractionPathString, new File(file).getName());
+        extractedFiles.add(outputFile.toString());
+        if (outputFile.toFile().exists()) {
+          continue;
+        }
+        outputFile.getParent().toFile().mkdirs();
+
+        try (var os = Files.newOutputStream(outputFile)) {
+          int readBytes;
+          while ((readBytes = stream.read(buffer)) != -1) { // NOPMD
+            os.write(buffer, 0, readBytes);
+          }
+        }
+      }
+    }
+
+    return extractedFiles;
+  }
+
+  /**
+   * Load a single library from a list of extracted files.
+   * @param libraryName The library name to load
+   * @param extractedFiles The extracted files to search
+   * @throws IOException If library was not found
+   */
+  public static void loadLibrary(String libraryName, List<String> extractedFiles)
+      throws IOException {
+    String currentPath = null;
+    String oldDllDirectory = null;
+    try {
+      if (RuntimeDetector.isWindows()) {
+        var extractionPathString = getExtractionDirectory();
+        oldDllDirectory = setDllDirectory(extractionPathString);
+      }
+      for (var extractedFile : extractedFiles) {
+        if (extractedFile.contains(libraryName)) {
+          // Load it
+          currentPath = extractedFile;
+          System.load(extractedFile);
+          return;
+        }
+      }
+      throw new IOException("Could not find library " + libraryName);
+    } catch (UnsatisfiedLinkError ule) {
+      throw new IOException(getLoadErrorMessage(currentPath, ule));
+    } finally {
+      if (oldDllDirectory != null) {
+        setDllDirectory(oldDllDirectory);
+      }
+    }
+  }
+
+  /**
+   * Load a list of native libraries out of a single directory.
+   *
+   * @param <T>             The class where the resources would be located
+   * @param clazz           The actual class object
+   * @param librariesToLoad List of libraries to load
+   * @throws IOException Throws an IOException if not found
+   */
+  public static <T> void loadLibraries(Class<T> clazz, String... librariesToLoad)
+      throws IOException {
+    // Extract everything
+
+    var extractedFiles = extractLibraries(clazz, "/ResourceInformation.json");
+
+    String currentPath = "";
+
+    try {
+      if (RuntimeDetector.isWindows()) {
+        var extractionPathString = getExtractionDirectory();
+        // Load windows, set dll directory
+        currentPath = Paths.get(extractionPathString, "WindowsLoaderHelper.dll").toString();
+        System.load(currentPath);
+      }
+    } catch (UnsatisfiedLinkError ule) {
+      throw new IOException(getLoadErrorMessage(currentPath, ule));
+    }
+
+    for (var library : librariesToLoad) {
+      loadLibrary(library, extractedFiles);
+    }
+  }
+}
diff --git a/wpiutil/src/main/java/edu/wpi/first/wpiutil/ErrorMessages.java b/wpiutil/src/main/java/edu/wpi/first/wpiutil/ErrorMessages.java
new file mode 100644
index 0000000..70387eb
--- /dev/null
+++ b/wpiutil/src/main/java/edu/wpi/first/wpiutil/ErrorMessages.java
@@ -0,0 +1,41 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018-2020 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.wpiutil;
+
+import static java.util.Objects.requireNonNull;
+
+/**
+ * Utility class for common WPILib error messages.
+ */
+public final class ErrorMessages {
+  /**
+   * Utility class, so constructor is private.
+   */
+  private ErrorMessages() {
+    throw new UnsupportedOperationException("This is a utility class!");
+  }
+
+  /**
+   * Requires that a parameter of a method not be null; prints an error message with
+   * helpful debugging instructions if the parameter is null.
+   *
+   * @param obj The parameter that must not be null.
+   * @param paramName The name of the parameter.
+   * @param methodName The name of the method.
+   */
+  public static <T> T requireNonNullParam(T obj, String paramName, String methodName) {
+    return requireNonNull(obj,
+        "Parameter " + paramName + " in method " + methodName + " was null when it"
+            + " should not have been!  Check the stacktrace to find the responsible line of code - "
+            + "usually, it is the first line of user-written code indicated in the stacktrace.  "
+            + "Make sure all objects passed to the method in question were properly initialized -"
+            + " note that this may not be obvious if it is being called under "
+            + "dynamically-changing conditions!  Please do not seek additional technical assistance"
+            + " without doing this first!");
+  }
+}
diff --git a/wpiutil/src/main/java/edu/wpi/first/wpiutil/RuntimeDetector.java b/wpiutil/src/main/java/edu/wpi/first/wpiutil/RuntimeDetector.java
index f7379dd..b4c07b7 100644
--- a/wpiutil/src/main/java/edu/wpi/first/wpiutil/RuntimeDetector.java
+++ b/wpiutil/src/main/java/edu/wpi/first/wpiutil/RuntimeDetector.java
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2017-2019 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2017-2020 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -55,7 +55,7 @@
         filePath = "/linux/athena/";
       } else if (isRaspbian()) {
         filePath = "/linux/raspbian/";
-      } else if (isAarch64Bionic()) {
+      } else if (isAarch64()) {
         filePath = "/linux/aarch64bionic/";
       } else {
         filePath = "/linux/nativearm/";
@@ -128,28 +128,12 @@
     }
   }
 
-  /** check if os is bionic aarch64.
+  /** check if architecture is aarch64.
    *
-   * @return if os is bionic aarch64
+   * @return if architecture is aarch64
    */
-  public static boolean isAarch64Bionic() {
-    if (!System.getProperty("os.arch").equals("aarch64")) {
-      return false;
-    }
-    try (BufferedReader reader = Files.newBufferedReader(Paths.get("/etc/os-release"))) {
-      String value = reader.readLine();
-      String version = "";
-      while (value != null) {
-        if (value.contains("VERSION=")) {
-          version = value;
-          break;
-        }
-        value = reader.readLine();
-      }
-      return version.contains("Bionic");
-    } catch (IOException ex) {
-      return false;
-    }
+  public static boolean isAarch64() {
+    return System.getProperty("os.arch").equals("aarch64");
   }
 
   public static boolean isLinux() {
diff --git a/wpiutil/src/main/java/edu/wpi/first/wpiutil/RuntimeLoader.java b/wpiutil/src/main/java/edu/wpi/first/wpiutil/RuntimeLoader.java
index 3e5fea7..21193a2 100644
--- a/wpiutil/src/main/java/edu/wpi/first/wpiutil/RuntimeLoader.java
+++ b/wpiutil/src/main/java/edu/wpi/first/wpiutil/RuntimeLoader.java
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2018-2019 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2018-2020 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -51,13 +51,19 @@
     m_extractionRoot = extractionRoot;
   }
 
-  private String getLoadErrorMessage() {
-    StringBuilder msg = new StringBuilder(256);
+  private String getLoadErrorMessage(UnsatisfiedLinkError ule) {
+    StringBuilder msg = new StringBuilder(512);
     msg.append(m_libraryName)
        .append(" could not be loaded from path or an embedded resource.\n"
                + "\tattempted to load for platform ")
        .append(RuntimeDetector.getPlatformPath())
+       .append("\nLast Load Error: \n")
+       .append(ule.getMessage())
        .append('\n');
+    if (RuntimeDetector.isWindows()) {
+      msg.append("A common cause of this error is missing the C++ runtime.\n"
+                 + "Download the latest at https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads\n");
+    }
     return msg.toString();
   }
 
@@ -75,7 +81,7 @@
       String resname = RuntimeDetector.getLibraryResource(m_libraryName);
       try (InputStream hashIs = m_loadClass.getResourceAsStream(hashName)) {
         if (hashIs == null) {
-          throw new IOException(getLoadErrorMessage());
+          throw new IOException(getLoadErrorMessage(ule));
         }
         try (Scanner scanner = new Scanner(hashIs, StandardCharsets.UTF_8.name())) {
           String hash = scanner.nextLine();
@@ -87,7 +93,7 @@
             // If extraction failed, extract
             try (InputStream resIs = m_loadClass.getResourceAsStream(resname)) {
               if (resIs == null) {
-                throw new IOException(getLoadErrorMessage());
+                throw new IOException(getLoadErrorMessage(ule));
               }
               jniLibrary.getParentFile().mkdirs();
               try (OutputStream os = Files.newOutputStream(jniLibrary.toPath())) {
@@ -120,7 +126,7 @@
       String hash = null;
       try (InputStream is = m_loadClass.getResourceAsStream(resname)) {
         if (is == null) {
-          throw new IOException(getLoadErrorMessage());
+          throw new IOException(getLoadErrorMessage(ule));
         }
         MessageDigest md = null;
         try {
@@ -152,7 +158,7 @@
         // If extraction failed, extract
         try (InputStream resIs = m_loadClass.getResourceAsStream(resname)) {
           if (resIs == null) {
-            throw new IOException(getLoadErrorMessage());
+            throw new IOException(getLoadErrorMessage(ule));
           }
           jniLibrary.getParentFile().mkdirs();
           try (OutputStream os = Files.newOutputStream(jniLibrary.toPath())) {
diff --git a/wpiutil/src/main/java/edu/wpi/first/wpiutil/WPIUtilJNI.java b/wpiutil/src/main/java/edu/wpi/first/wpiutil/WPIUtilJNI.java
index 941e691..3a22c7b 100644
--- a/wpiutil/src/main/java/edu/wpi/first/wpiutil/WPIUtilJNI.java
+++ b/wpiutil/src/main/java/edu/wpi/first/wpiutil/WPIUtilJNI.java
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2019 FIRST. All Rights Reserved.                             */
+/* Copyright (c) 2019-2020 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -51,6 +51,8 @@
     libraryLoaded = true;
   }
 
+  public static native long now();
+
   public static native void addPortForwarder(int port, String remoteHost, int remotePort);
   public static native void removePortForwarder(int port);
 }
diff --git a/wpiutil/src/main/java/edu/wpi/first/wpiutil/math/MatBuilder.java b/wpiutil/src/main/java/edu/wpi/first/wpiutil/math/MatBuilder.java
deleted file mode 100644
index a5490a3..0000000
--- a/wpiutil/src/main/java/edu/wpi/first/wpiutil/math/MatBuilder.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*----------------------------------------------------------------------------*/
-/* Copyright (c) 2019 FIRST. All Rights Reserved.                             */
-/* Open Source Software - may be modified and shared by FRC teams. The code   */
-/* must be accompanied by the FIRST BSD license file in the root directory of */
-/* the project.                                                               */
-/*----------------------------------------------------------------------------*/
-
-package edu.wpi.first.wpiutil.math;
-
-import java.util.Objects;
-
-import org.ejml.simple.SimpleMatrix;
-
-/**
- * A class for constructing arbitrary RxC matrices.
- *
- * @param <R> The number of rows of the desired matrix.
- * @param <C> The number of columns of the desired matrix.
- */
-public class MatBuilder<R extends Num, C extends Num> {
-  private final Nat<R> m_rows;
-  private final Nat<C> m_cols;
-
-  /**
-   * Fills the matrix with the given data, encoded in row major form.
-   * (The matrix is filled row by row, left to right with the given data).
-   *
-   * @param data The data to fill the matrix with.
-   * @return The constructed matrix.
-   */
-  @SuppressWarnings("LineLength")
-  public final Matrix<R, C> fill(double... data) {
-    if (Objects.requireNonNull(data).length != this.m_rows.getNum() * this.m_cols.getNum()) {
-      throw new IllegalArgumentException("Invalid matrix data provided. Wanted " + this.m_rows.getNum()
-          + " x " + this.m_cols.getNum() + " matrix, but got " + data.length + " elements");
-    } else {
-      return new Matrix<>(new SimpleMatrix(this.m_rows.getNum(), this.m_cols.getNum(), true, data));
-    }
-  }
-
-  /**
-   * Creates a new {@link MatBuilder} with the given dimensions.
-   * @param rows The number of rows of the matrix.
-   * @param cols The number of columns of the matrix.
-   */
-  public MatBuilder(Nat<R> rows, Nat<C> cols) {
-    this.m_rows = Objects.requireNonNull(rows);
-    this.m_cols = Objects.requireNonNull(cols);
-  }
-}
diff --git a/wpiutil/src/main/java/edu/wpi/first/wpiutil/math/MathUtil.java b/wpiutil/src/main/java/edu/wpi/first/wpiutil/math/MathUtil.java
deleted file mode 100644
index bd555dc..0000000
--- a/wpiutil/src/main/java/edu/wpi/first/wpiutil/math/MathUtil.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*----------------------------------------------------------------------------*/
-/* Copyright (c) 2019 FIRST. All Rights Reserved.                             */
-/* Open Source Software - may be modified and shared by FRC teams. The code   */
-/* must be accompanied by the FIRST BSD license file in the root directory of */
-/* the project.                                                               */
-/*----------------------------------------------------------------------------*/
-
-package edu.wpi.first.wpiutil.math;
-
-public final class MathUtil {
-  private MathUtil() {
-    throw new AssertionError("utility class");
-  }
-
-  /**
-   * Returns value clamped between low and high boundaries.
-   *
-   * @param value Value to clamp.
-   * @param low   The lower boundary to which to clamp value.
-   * @param high  The higher boundary to which to clamp value.
-   */
-  public static int clamp(int value, int low, int high) {
-    return Math.max(low, Math.min(value, high));
-  }
-
-  /**
-   * Returns value clamped between low and high boundaries.
-   *
-   * @param value Value to clamp.
-   * @param low   The lower boundary to which to clamp value.
-   * @param high  The higher boundary to which to clamp value.
-   */
-  public static double clamp(double value, double low, double high) {
-    return Math.max(low, Math.min(value, high));
-  }
-}
diff --git a/wpiutil/src/main/java/edu/wpi/first/wpiutil/math/Matrix.java b/wpiutil/src/main/java/edu/wpi/first/wpiutil/math/Matrix.java
deleted file mode 100644
index 5780498..0000000
--- a/wpiutil/src/main/java/edu/wpi/first/wpiutil/math/Matrix.java
+++ /dev/null
@@ -1,327 +0,0 @@
-/*----------------------------------------------------------------------------*/
-/* Copyright (c) 2019 FIRST. All Rights Reserved.                             */
-/* Open Source Software - may be modified and shared by FRC teams. The code   */
-/* must be accompanied by the FIRST BSD license file in the root directory of */
-/* the project.                                                               */
-/*----------------------------------------------------------------------------*/
-
-package edu.wpi.first.wpiutil.math;
-
-import java.util.Objects;
-
-import org.ejml.dense.row.CommonOps_DDRM;
-import org.ejml.dense.row.NormOps_DDRM;
-import org.ejml.simple.SimpleMatrix;
-
-/**
- * A shape-safe wrapper over Efficient Java Matrix Library (EJML) matrices.
- *
- * <p>This class is intended to be used alongside the state space library.
- *
- * @param <R> The number of rows in this matrix.
- * @param <C> The number of columns in this matrix.
- */
-@SuppressWarnings("PMD.TooManyMethods")
-public class Matrix<R extends Num, C extends Num> {
-
-  private final SimpleMatrix m_storage;
-
-  /**
-   * Gets the number of columns in this matrix.
-   *
-   * @return The number of columns, according to the internal storage.
-   */
-  public final int getNumCols() {
-    return this.m_storage.numCols();
-  }
-
-  /**
-   * Gets the number of rows in this matrix.
-   *
-   * @return The number of rows, according to the internal storage.
-   */
-  public final int getNumRows() {
-    return this.m_storage.numRows();
-  }
-
-  /**
-   * Get an element of this matrix.
-   *
-   * @param row The row of the element.
-   * @param col The column of the element.
-   * @return The element in this matrix at row,col.
-   */
-  public final double get(int row, int col) {
-    return this.m_storage.get(row, col);
-  }
-
-  /**
-   * Sets the value at the given indices.
-   *
-   * @param row     The row of the element.
-   * @param col     The column of the element.
-   * @param value The value to insert at the given location.
-   */
-  public final void set(int row, int col, double value) {
-    this.m_storage.set(row, col, value);
-  }
-
-  /**
-   * If a vector then a square matrix is returned
-   * if a matrix then a vector of diagonal elements is returned.
-   *
-   * @return Diagonal elements inside a vector or a square matrix with the same diagonal elements.
-   */
-  public final Matrix<R, C> diag() {
-    return new Matrix<>(this.m_storage.diag());
-  }
-
-  /**
-   * Returns the largest element of this matrix.
-   *
-   * @return The largest element of this matrix.
-   */
-  public final double maxInternal() {
-    return CommonOps_DDRM.elementMax(this.m_storage.getDDRM());
-  }
-
-  /**
-   * Returns the smallest element of this matrix.
-   *
-   * @return The smallest element of this matrix.
-   */
-  public final double minInternal() {
-    return CommonOps_DDRM.elementMin(this.m_storage.getDDRM());
-  }
-
-  /**
-   * Calculates the mean of the elements in this matrix.
-   *
-   * @return The mean value of this matrix.
-   */
-  public final double mean() {
-    return this.elementSum() / (double) this.m_storage.getNumElements();
-  }
-
-  /**
-   * Multiplies this matrix with another that has C rows.
-   *
-   * <p>As matrix multiplication is only defined if the number of columns
-   * in the first matrix matches the number of rows in the second,
-   * this operation will fail to compile under any other circumstances.
-   *
-   * @param other The other matrix to multiply by.
-   * @param <C2>  The number of columns in the second matrix.
-   * @return The result of the matrix multiplication between this and the given matrix.
-   */
-  public final <C2 extends Num> Matrix<R, C2> times(Matrix<C, C2> other) {
-    return new Matrix<>(this.m_storage.mult(other.m_storage));
-  }
-
-  /**
-   * Multiplies all the elements of this matrix by the given scalar.
-   *
-   * @param value The scalar value to multiply by.
-   * @return A new matrix with all the elements multiplied by the given value.
-   */
-  public final Matrix<R, C> times(double value) {
-    return new Matrix<>(this.m_storage.scale(value));
-  }
-
-  /**
-   * <p>
-   * Returns a matrix which is the result of an element by element multiplication of 'this' and 'b'.
-   * c<sub>i,j</sub> = a<sub>i,j</sub>*b<sub>i,j</sub>
-   * </p>
-   *
-   * @param other A matrix.
-   * @return The element by element multiplication of 'this' and 'b'.
-   */
-  public final Matrix<R, C> elementTimes(Matrix<R, C> other) {
-    return new Matrix<>(this.m_storage.elementMult(Objects.requireNonNull(other).m_storage));
-  }
-
-  /**
-   * Subtracts the given value from all the elements of this matrix.
-   *
-   * @param value The value to subtract.
-   * @return The resultant matrix.
-   */
-  public final Matrix<R, C> minus(double value) {
-    return new Matrix<>(this.m_storage.minus(value));
-  }
-
-
-  /**
-   * Subtracts the given matrix from this matrix.
-   *
-   * @param value The matrix to subtract.
-   * @return The resultant matrix.
-   */
-  public final Matrix<R, C> minus(Matrix<R, C> value) {
-    return new Matrix<>(this.m_storage.minus(Objects.requireNonNull(value).m_storage));
-  }
-
-
-  /**
-   * Adds the given value to all the elements of this matrix.
-   *
-   * @param value The value to add.
-   * @return The resultant matrix.
-   */
-  public final Matrix<R, C> plus(double value) {
-    return new Matrix<>(this.m_storage.plus(value));
-  }
-
-  /**
-   * Adds the given matrix to this matrix.
-   *
-   * @param value The matrix to add.
-   * @return The resultant matrix.
-   */
-  public final Matrix<R, C> plus(Matrix<R, C> value) {
-    return new Matrix<>(this.m_storage.plus(value.m_storage));
-  }
-
-  /**
-   * Divides all elements of this matrix by the given value.
-   *
-   * @param value The value to divide by.
-   * @return The resultant matrix.
-   */
-  public final Matrix<R, C> div(int value) {
-    return new Matrix<>(this.m_storage.divide((double) value));
-  }
-
-  /**
-   * Divides all elements of this matrix by the given value.
-   *
-   * @param value The value to divide by.
-   * @return The resultant matrix.
-   */
-  public final Matrix<R, C> div(double value) {
-    return new Matrix<>(this.m_storage.divide(value));
-  }
-
-  /**
-   * Calculates the transpose, M^T of this matrix.
-   *
-   * @return The tranpose matrix.
-   */
-  public final Matrix<C, R> transpose() {
-    return new Matrix<>(this.m_storage.transpose());
-  }
-
-
-  /**
-   * Returns a copy of this matrix.
-   *
-   * @return A copy of this matrix.
-   */
-  public final Matrix<R, C> copy() {
-    return new Matrix<>(this.m_storage.copy());
-  }
-
-
-  /**
-   * Returns the inverse matrix of this matrix.
-   *
-   * @return The inverse of this matrix.
-   * @throws org.ejml.data.SingularMatrixException If this matrix is non-invertable.
-   */
-  public final Matrix<R, C> inv() {
-    return new Matrix<>(this.m_storage.invert());
-  }
-
-  /**
-   * Returns the determinant of this matrix.
-   *
-   * @return The determinant of this matrix.
-   */
-  public final double det() {
-    return this.m_storage.determinant();
-  }
-
-  /**
-   * Computes the Frobenius normal of the matrix.<br>
-   * <br>
-   * normF = Sqrt{  &sum;<sub>i=1:m</sub> &sum;<sub>j=1:n</sub> { a<sub>ij</sub><sup>2</sup>}   }
-   *
-   * @return The matrix's Frobenius normal.
-   */
-  public final double normF() {
-    return this.m_storage.normF();
-  }
-
-  /**
-   * Computes the induced p = 1 matrix norm.<br>
-   * <br>
-   * ||A||<sub>1</sub>= max(j=1 to n; sum(i=1 to m; |a<sub>ij</sub>|))
-   *
-   * @return The norm.
-   */
-  public final double normIndP1() {
-    return NormOps_DDRM.inducedP1(this.m_storage.getDDRM());
-  }
-
-  /**
-   * Computes the sum of all the elements in the matrix.
-   *
-   * @return Sum of all the elements.
-   */
-  public final double elementSum() {
-    return this.m_storage.elementSum();
-  }
-
-  /**
-   * Computes the trace of the matrix.
-   *
-   * @return The trace of the matrix.
-   */
-  public final double trace() {
-    return this.m_storage.trace();
-  }
-
-  /**
-   * Returns a matrix which is the result of an element by element power of 'this' and 'b':
-   * c<sub>i,j</sub> = a<sub>i,j</sub> ^ b.
-   *
-   * @param b Scalar
-   * @return The element by element power of 'this' and 'b'.
-   */
-  @SuppressWarnings("ParameterName")
-  public final Matrix<R, C> epow(double b) {
-    return new Matrix<>(this.m_storage.elementPower(b));
-  }
-
-  /**
-   * Returns a matrix which is the result of an element by element power of 'this' and 'b':
-   * c<sub>i,j</sub> = a<sub>i,j</sub> ^ b.
-   *
-   * @param b Scalar.
-   * @return The element by element power of 'this' and 'b'.
-   */
-  @SuppressWarnings("ParameterName")
-  public final Matrix<R, C> epow(int b) {
-    return new Matrix<>(this.m_storage.elementPower((double) b));
-  }
-
-  /**
-   * Returns the EJML {@link SimpleMatrix} backing this wrapper.
-   *
-   * @return The untyped EJML {@link SimpleMatrix}.
-   */
-  public final SimpleMatrix getStorage() {
-    return this.m_storage;
-  }
-
-  /**
-   * Constructs a new matrix with the given storage.
-   * Caller should make sure that the provided generic bounds match the shape of the provided matrix
-   *
-   * @param storage The {@link SimpleMatrix} to back this value
-   */
-  public Matrix(SimpleMatrix storage) {
-    this.m_storage = Objects.requireNonNull(storage);
-  }
-}
diff --git a/wpiutil/src/main/java/edu/wpi/first/wpiutil/math/MatrixUtils.java b/wpiutil/src/main/java/edu/wpi/first/wpiutil/math/MatrixUtils.java
deleted file mode 100644
index ac4deb9..0000000
--- a/wpiutil/src/main/java/edu/wpi/first/wpiutil/math/MatrixUtils.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*----------------------------------------------------------------------------*/
-/* Copyright (c) 2019 FIRST. All Rights Reserved.                             */
-/* Open Source Software - may be modified and shared by FRC teams. The code   */
-/* must be accompanied by the FIRST BSD license file in the root directory of */
-/* the project.                                                               */
-/*----------------------------------------------------------------------------*/
-
-package edu.wpi.first.wpiutil.math;
-
-import java.util.Objects;
-
-import org.ejml.simple.SimpleMatrix;
-
-import edu.wpi.first.wpiutil.math.numbers.N1;
-
-public final class MatrixUtils {
-  private MatrixUtils() {
-    throw new AssertionError("utility class");
-  }
-
-  /**
-   * Creates a new matrix of zeros.
-   *
-   * @param rows The number of rows in the matrix.
-   * @param cols The number of columns in the matrix.
-   * @param <R> The number of rows in the matrix as a generic.
-   * @param <C> The number of columns in the matrix as a generic.
-   * @return An RxC matrix filled with zeros.
-   */
-  @SuppressWarnings("LineLength")
-  public static <R extends Num, C extends Num> Matrix<R, C> zeros(Nat<R> rows, Nat<C> cols) {
-    return new Matrix<>(
-        new SimpleMatrix(Objects.requireNonNull(rows).getNum(), Objects.requireNonNull(cols).getNum()));
-  }
-
-  /**
-   * Creates a new vector of zeros.
-   *
-   * @param nums The size of the desired vector.
-   * @param <N> The size of the desired vector as a generic.
-   * @return A vector of size N filled with zeros.
-   */
-  public static <N extends Num> Matrix<N, N1> zeros(Nat<N> nums) {
-    return new Matrix<>(new SimpleMatrix(Objects.requireNonNull(nums).getNum(), 1));
-  }
-
-  /**
-   * Creates the identity matrix of the given dimension.
-   *
-   * @param dim The dimension of the desired matrix.
-   * @param <D> The dimension of the desired matrix as a generic.
-   * @return The DxD identity matrix.
-   */
-  public static <D extends Num> Matrix<D, D> eye(Nat<D> dim) {
-    return new Matrix<>(SimpleMatrix.identity(Objects.requireNonNull(dim).getNum()));
-  }
-
-  /**
-   * Entrypoint to the MatBuilder class for creation
-   * of custom matrices with the given dimensions and contents.
-   *
-   * @param rows The number of rows of the desired matrix.
-   * @param cols The number of columns of the desired matrix.
-   * @param <R> The number of rows of the desired matrix as a generic.
-   * @param <C> The number of columns of the desired matrix as a generic.
-   * @return A builder to construct the matrix.
-   */
-  public static <R extends Num, C extends Num> MatBuilder<R, C> mat(Nat<R> rows, Nat<C> cols) {
-    return new MatBuilder<>(rows, cols);
-  }
-
-  /**
-   * Entrypoint to the VecBuilder class for creation
-   * of custom vectors with the given size and contents.
-   *
-   * @param dim The dimension of the vector.
-   * @param <D> The dimension of the vector as a generic.
-   * @return A builder to construct the vector.
-   */
-  public static <D extends Num> VecBuilder<D> vec(Nat<D> dim) {
-    return new VecBuilder<>(dim);
-  }
-}
diff --git a/wpiutil/src/main/java/edu/wpi/first/wpiutil/math/Num.java b/wpiutil/src/main/java/edu/wpi/first/wpiutil/math/Num.java
deleted file mode 100644
index c7385ea..0000000
--- a/wpiutil/src/main/java/edu/wpi/first/wpiutil/math/Num.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*----------------------------------------------------------------------------*/
-/* Copyright (c) 2019 FIRST. All Rights Reserved.                             */
-/* Open Source Software - may be modified and shared by FRC teams. The code   */
-/* must be accompanied by the FIRST BSD license file in the root directory of */
-/* the project.                                                               */
-/*----------------------------------------------------------------------------*/
-
-package edu.wpi.first.wpiutil.math;
-
-/**
- * A number expressed as a java class.
- */
-public abstract class Num {
-  /**
-   * The number this is backing.
-   *
-   * @return The number represented by this class.
-   */
-  public abstract int getNum();
-}
diff --git a/wpiutil/src/main/java/edu/wpi/first/wpiutil/math/SimpleMatrixUtils.java b/wpiutil/src/main/java/edu/wpi/first/wpiutil/math/SimpleMatrixUtils.java
deleted file mode 100644
index ea983d4..0000000
--- a/wpiutil/src/main/java/edu/wpi/first/wpiutil/math/SimpleMatrixUtils.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*----------------------------------------------------------------------------*/
-/* Copyright (c) 2019 FIRST. All Rights Reserved.                             */
-/* Open Source Software - may be modified and shared by FRC teams. The code   */
-/* must be accompanied by the FIRST BSD license file in the root directory of */
-/* the project.                                                               */
-/*----------------------------------------------------------------------------*/
-
-package edu.wpi.first.wpiutil.math;
-
-import java.util.function.BiFunction;
-
-import org.ejml.dense.row.NormOps_DDRM;
-import org.ejml.simple.SimpleBase;
-import org.ejml.simple.SimpleMatrix;
-
-public class SimpleMatrixUtils {
-  private SimpleMatrixUtils() {}
-
-  /**
-   * Compute the matrix exponential, e^M of the given matrix.
-   *
-   * @param matrix The matrix to compute the exponential of.
-   * @return The resultant matrix.
-   */
-  @SuppressWarnings({"LocalVariableName", "LineLength"})
-  public static SimpleMatrix expm(SimpleMatrix matrix) {
-    BiFunction<SimpleMatrix, SimpleMatrix, SimpleMatrix> solveProvider = SimpleBase::solve;
-    SimpleMatrix A = matrix;
-    double A_L1 = NormOps_DDRM.inducedP1(matrix.getDDRM());
-    int n_squarings = 0;
-
-    if (A_L1 < 1.495585217958292e-002) {
-      Pair<SimpleMatrix, SimpleMatrix> pair = _pade3(A);
-      return dispatchPade(pair.getFirst(), pair.getSecond(), n_squarings, solveProvider);
-    } else if (A_L1 < 2.539398330063230e-001) {
-      Pair<SimpleMatrix, SimpleMatrix> pair = _pade5(A);
-      return dispatchPade(pair.getFirst(), pair.getSecond(), n_squarings, solveProvider);
-    } else if (A_L1 < 9.504178996162932e-001) {
-      Pair<SimpleMatrix, SimpleMatrix> pair = _pade7(A);
-      return dispatchPade(pair.getFirst(), pair.getSecond(), n_squarings, solveProvider);
-    } else if (A_L1 < 2.097847961257068e+000) {
-      Pair<SimpleMatrix, SimpleMatrix> pair = _pade9(A);
-      return dispatchPade(pair.getFirst(), pair.getSecond(), n_squarings, solveProvider);
-    } else {
-      double maxNorm = 5.371920351148152;
-      double log = Math.log(A_L1 / maxNorm) / Math.log(2); // logb(2, arg)
-      n_squarings = (int) Math.max(0, Math.ceil(log));
-      A = A.divide(Math.pow(2.0, n_squarings));
-      Pair<SimpleMatrix, SimpleMatrix> pair = _pade13(A);
-      return dispatchPade(pair.getFirst(), pair.getSecond(), n_squarings, solveProvider);
-    }
-  }
-
-  @SuppressWarnings({"LocalVariableName", "ParameterName", "LineLength"})
-  private static SimpleMatrix dispatchPade(SimpleMatrix U, SimpleMatrix V,
-                                           int nSquarings, BiFunction<SimpleMatrix, SimpleMatrix, SimpleMatrix> solveProvider) {
-    SimpleMatrix P = U.plus(V);
-    SimpleMatrix Q = U.negative().plus(V);
-
-    SimpleMatrix R = solveProvider.apply(Q, P);
-
-    for (int i = 0; i < nSquarings; i++) {
-      R = R.mult(R);
-    }
-
-    return R;
-  }
-
-  @SuppressWarnings({"MethodName", "LocalVariableName", "ParameterName"})
-  private static Pair<SimpleMatrix, SimpleMatrix> _pade3(SimpleMatrix A) {
-    double[] b = new double[]{120, 60, 12, 1};
-    SimpleMatrix ident = eye(A.numRows(), A.numCols());
-
-    SimpleMatrix A2 = A.mult(A);
-    SimpleMatrix U = A.mult(A2.mult(ident.scale(b[1]).plus(b[3])));
-    SimpleMatrix V = A2.scale(b[2]).plus(ident.scale(b[0]));
-    return new Pair<>(U, V);
-  }
-
-  @SuppressWarnings({"MethodName", "LocalVariableName", "ParameterName"})
-  private static Pair<SimpleMatrix, SimpleMatrix> _pade5(SimpleMatrix A) {
-    double[] b = new double[]{30240, 15120, 3360, 420, 30, 1};
-    SimpleMatrix ident = eye(A.numRows(), A.numCols());
-    SimpleMatrix A2 = A.mult(A);
-    SimpleMatrix A4 = A2.mult(A2);
-
-    SimpleMatrix U = A.mult(A4.scale(b[5]).plus(A2.scale(b[3])).plus(ident.scale(b[1])));
-    SimpleMatrix V = A4.scale(b[4]).plus(A2.scale(b[2])).plus(ident.scale(b[0]));
-
-    return new Pair<>(U, V);
-  }
-
-  @SuppressWarnings({"MethodName", "LocalVariableName", "LineLength", "ParameterName"})
-  private static Pair<SimpleMatrix, SimpleMatrix> _pade7(SimpleMatrix A) {
-    double[] b = new double[]{17297280, 8648640, 1995840, 277200, 25200, 1512, 56, 1};
-    SimpleMatrix ident = eye(A.numRows(), A.numCols());
-    SimpleMatrix A2 = A.mult(A);
-    SimpleMatrix A4 = A2.mult(A2);
-    SimpleMatrix A6 = A4.mult(A2);
-
-    SimpleMatrix U = A.mult(A6.scale(b[7]).plus(A4.scale(b[5])).plus(A2.scale(b[3])).plus(ident.scale(b[1])));
-    SimpleMatrix V = A6.scale(b[6]).plus(A4.scale(b[4])).plus(A2.scale(b[2])).plus(ident.scale(b[0]));
-
-    return new Pair<>(U, V);
-  }
-
-  @SuppressWarnings({"MethodName", "LocalVariableName", "ParameterName", "LineLength"})
-  private static Pair<SimpleMatrix, SimpleMatrix> _pade9(SimpleMatrix A) {
-    double[] b = new double[]{17643225600.0, 8821612800.0, 2075673600, 302702400, 30270240,
-        2162160, 110880, 3960, 90, 1};
-    SimpleMatrix ident = eye(A.numRows(), A.numCols());
-    SimpleMatrix A2 = A.mult(A);
-    SimpleMatrix A4 = A2.mult(A2);
-    SimpleMatrix A6 = A4.mult(A2);
-    SimpleMatrix A8 = A6.mult(A2);
-
-    SimpleMatrix U = A.mult(A8.scale(b[9]).plus(A6.scale(b[7])).plus(A4.scale(b[5])).plus(A2.scale(b[3])).plus(ident.scale(b[1])));
-    SimpleMatrix V = A8.scale(b[8]).plus(A6.scale(b[6])).plus(A4.scale(b[4])).plus(A2.scale(b[2])).plus(ident.scale(b[0]));
-
-    return new Pair<>(U, V);
-  }
-
-  @SuppressWarnings({"MethodName", "LocalVariableName", "LineLength", "ParameterName"})
-  private static Pair<SimpleMatrix, SimpleMatrix> _pade13(SimpleMatrix A) {
-    double[] b = new double[]{64764752532480000.0, 32382376266240000.0, 7771770303897600.0,
-        1187353796428800.0, 129060195264000.0, 10559470521600.0, 670442572800.0,
-        33522128640.0, 1323241920, 40840800, 960960, 16380, 182, 1};
-    SimpleMatrix ident = eye(A.numRows(), A.numCols());
-
-    SimpleMatrix A2 = A.mult(A);
-    SimpleMatrix A4 = A2.mult(A2);
-    SimpleMatrix A6 = A4.mult(A2);
-
-    SimpleMatrix U = A.mult(A6.scale(b[13]).plus(A4.scale(b[11])).plus(A2.scale(b[9])).plus(A6.scale(b[7])).plus(A4.scale(b[5])).plus(A2.scale(b[3])).plus(ident.scale(b[1])));
-    SimpleMatrix V = A6.mult(A6.scale(b[12]).plus(A4.scale(b[10])).plus(A2.scale(b[8]))).plus(A6.scale(b[6]).plus(A4.scale(b[4])).plus(A2.scale(b[2])).plus(ident.scale(b[0])));
-
-    return new Pair<>(U, V);
-  }
-
-  private static SimpleMatrix eye(int rows, int cols) {
-    return SimpleMatrix.identity(Math.min(rows, cols));
-  }
-
-  private static class Pair<A, B> {
-    private final A m_first;
-    private final B m_second;
-
-    Pair(A first, B second) {
-      m_first = first;
-      m_second = second;
-    }
-
-    public A getFirst() {
-      return m_first;
-    }
-
-    public B getSecond() {
-      return m_second;
-    }
-  }
-}
diff --git a/wpiutil/src/main/java/edu/wpi/first/wpiutil/math/VecBuilder.java b/wpiutil/src/main/java/edu/wpi/first/wpiutil/math/VecBuilder.java
deleted file mode 100644
index deaaa41..0000000
--- a/wpiutil/src/main/java/edu/wpi/first/wpiutil/math/VecBuilder.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*----------------------------------------------------------------------------*/
-/* Copyright (c) 2019 FIRST. All Rights Reserved.                             */
-/* Open Source Software - may be modified and shared by FRC teams. The code   */
-/* must be accompanied by the FIRST BSD license file in the root directory of */
-/* the project.                                                               */
-/*----------------------------------------------------------------------------*/
-
-package edu.wpi.first.wpiutil.math;
-
-import edu.wpi.first.wpiutil.math.numbers.N1;
-
-/**
- * A specialization of {@link MatBuilder} for constructing vectors (Nx1 matrices).
- *
- * @param <N> The dimension of the vector to be constructed.
- */
-public class VecBuilder<N extends Num> extends MatBuilder<N, N1> {
-  public VecBuilder(Nat<N> rows) {
-    super(rows, Nat.N1());
-  }
-}
diff --git a/wpiutil/src/main/native/cpp/HttpUtil.cpp b/wpiutil/src/main/native/cpp/HttpUtil.cpp
index 37fea60..866ee10 100644
--- a/wpiutil/src/main/native/cpp/HttpUtil.cpp
+++ b/wpiutil/src/main/native/cpp/HttpUtil.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2016-2020 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -86,6 +86,63 @@
   return StringRef{buf.data(), buf.size()};
 }
 
+HttpQueryMap::HttpQueryMap(wpi::StringRef query) {
+  wpi::SmallVector<wpi::StringRef, 16> queryElems;
+  query.split(queryElems, '&', 100, false);
+  for (auto elem : queryElems) {
+    auto [nameEsc, valueEsc] = elem.split('=');
+    wpi::SmallString<64> nameBuf;
+    bool err = false;
+    auto name = wpi::UnescapeURI(nameEsc, nameBuf, &err);
+    // note: ignores duplicates
+    if (!err) m_elems.try_emplace(name, valueEsc);
+  }
+}
+
+std::optional<wpi::StringRef> HttpQueryMap::Get(
+    wpi::StringRef name, wpi::SmallVectorImpl<char>& buf) const {
+  auto it = m_elems.find(name);
+  if (it == m_elems.end()) return {};
+  bool err = false;
+  auto val = wpi::UnescapeURI(it->second, buf, &err);
+  if (err) return {};
+  return val;
+}
+
+HttpPath::HttpPath(wpi::StringRef path) {
+  // special-case root path to be a single empty element
+  if (path == "/") {
+    m_pathEnds.emplace_back(0);
+    return;
+  }
+  wpi::SmallVector<wpi::StringRef, 16> pathElems;
+  path.split(pathElems, '/', 100, false);
+  for (auto elem : pathElems) {
+    wpi::SmallString<64> buf;
+    bool err = false;
+    auto val = wpi::UnescapeURI(elem, buf, &err);
+    if (err) {
+      m_pathEnds.clear();
+      return;
+    }
+    m_pathBuf += val;
+    m_pathEnds.emplace_back(m_pathBuf.size());
+  }
+}
+
+bool HttpPath::startswith(size_t start, ArrayRef<StringRef> match) const {
+  if (m_pathEnds.size() < (start + match.size())) return false;
+  bool first = start == 0;
+  auto p = m_pathEnds.begin() + start;
+  for (auto m : match) {
+    auto val = m_pathBuf.slice(first ? 0 : *(p - 1), *p);
+    if (val != m) return false;
+    first = false;
+    ++p;
+  }
+  return true;
+}
+
 bool ParseHttpHeaders(raw_istream& is, SmallVectorImpl<char>* contentType,
                       SmallVectorImpl<char>* contentLength) {
   if (contentType) contentType->clear();
diff --git a/wpiutil/src/main/native/cpp/MimeTypes.cpp b/wpiutil/src/main/native/cpp/MimeTypes.cpp
new file mode 100644
index 0000000..5bf9d29
--- /dev/null
+++ b/wpiutil/src/main/native/cpp/MimeTypes.cpp
@@ -0,0 +1,71 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2020 FIRST. All Rights Reserved.                             */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "wpi/MimeTypes.h"
+
+#include "wpi/StringMap.h"
+
+namespace wpi {
+
+// derived partially from
+// https://github.com/DEGoodmanWilson/libmime/blob/stable/0.1.2/mime/mime.cpp
+StringRef MimeTypeFromPath(StringRef path) {
+  // https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types
+  static StringMap<const char*> mimeTypes{
+      // text
+      {"css", "text/css"},
+      {"csv", "text/csv"},
+      {"htm", "text/html"},
+      {"html", "text/html"},
+      {"js", "text/javascript"},
+      {"json", "application/json"},
+      {"map", "application/json"},
+      {"md", "text/markdown"},
+      {"txt", "text/plain"},
+      {"xml", "text/xml"},
+
+      // images
+      {"apng", "image/apng"},
+      {"bmp", "image/bmp"},
+      {"gif", "image/gif"},
+      {"cur", "image/x-icon"},
+      {"ico", "image/x-icon"},
+      {"jpg", "image/jpeg"},
+      {"jpeg", "image/jpeg"},
+      {"png", "image/png"},
+      {"svg", "image/svg+xml"},
+      {"tif", "image/tiff"},
+      {"tiff", "image/tiff"},
+      {"webp", "image/webp"},
+
+      // fonts
+      {"otf", "font/otf"},
+      {"ttf", "font/ttf"},
+      {"woff", "font/woff"},
+
+      // misc
+      {"pdf", "application/pdf"},
+      {"zip", "application/zip"},
+  };
+
+  static const char* defaultType = "application/octet-stream";
+
+  auto pos = path.find_last_of("/");
+  if (pos != StringRef::npos) {
+    path = path.substr(pos + 1);
+  }
+  auto dot_pos = path.find_last_of(".");
+  if (dot_pos > 0 && dot_pos != StringRef::npos) {
+    auto type = mimeTypes.find(path.substr(dot_pos + 1));
+    if (type != mimeTypes.end()) {
+      return type->getValue();
+    }
+  }
+  return defaultType;
+}
+
+}  // namespace wpi
diff --git a/wpiutil/src/main/native/cpp/TCPConnector_parallel.cpp b/wpiutil/src/main/native/cpp/TCPConnector_parallel.cpp
index de8bc2c..ee5803f 100644
--- a/wpiutil/src/main/native/cpp/TCPConnector_parallel.cpp
+++ b/wpiutil/src/main/native/cpp/TCPConnector_parallel.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2017-2019 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2017-2020 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -107,8 +107,7 @@
       }
       ++result->count;
       result->cv.notify_all();
-    })
-        .detach();
+    }).detach();
   }
 
   // wait for a result, timeout, or all finished
diff --git a/wpiutil/src/main/native/cpp/TCPStream.cpp b/wpiutil/src/main/native/cpp/TCPStream.cpp
index d4e3671..4af3e6f 100644
--- a/wpiutil/src/main/native/cpp/TCPStream.cpp
+++ b/wpiutil/src/main/native/cpp/TCPStream.cpp
@@ -1,7 +1,7 @@
 /*
    TCPStream.h
 
-   TCPStream class definition. TCPStream provides methods to trasnfer
+   TCPStream class definition. TCPStream provides methods to transfer
    data between peers over a TCP/IP connection.
 
    ------------------------------------------
diff --git a/wpiutil/src/main/native/cpp/http_parser.cpp b/wpiutil/src/main/native/cpp/http_parser.cpp
index fb56010..bc442b2 100644
--- a/wpiutil/src/main/native/cpp/http_parser.cpp
+++ b/wpiutil/src/main/native/cpp/http_parser.cpp
@@ -1771,7 +1771,7 @@
         /* Here we call the headers_complete callback. This is somewhat
          * different than other callbacks because if the user returns 1, we
          * will interpret that as saying that this message has no body. This
-         * is needed for the annoying case of recieving a response to a HEAD
+         * is needed for the annoying case of receiving a response to a HEAD
          * request.
          *
          * We'd like to use CALLBACK_NOTIFY_NOADVANCE() here but we cannot, so
diff --git a/wpiutil/src/main/native/cpp/jni/WPIUtilJNI.cpp b/wpiutil/src/main/native/cpp/jni/WPIUtilJNI.cpp
index c14b3f4..90a2291 100644
--- a/wpiutil/src/main/native/cpp/jni/WPIUtilJNI.cpp
+++ b/wpiutil/src/main/native/cpp/jni/WPIUtilJNI.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2019 FIRST. All Rights Reserved.                             */
+/* Copyright (c) 2019-2020 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -10,6 +10,7 @@
 #include "edu_wpi_first_wpiutil_WPIUtilJNI.h"
 #include "wpi/PortForwarder.h"
 #include "wpi/jni_util.h"
+#include "wpi/timestamp.h"
 
 using namespace wpi::java;
 
@@ -27,6 +28,18 @@
 
 /*
  * Class:     edu_wpi_first_wpiutil_WPIUtilJNI
+ * Method:    now
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL
+Java_edu_wpi_first_wpiutil_WPIUtilJNI_now
+  (JNIEnv*, jclass)
+{
+  return wpi::Now();
+}
+
+/*
+ * Class:     edu_wpi_first_wpiutil_WPIUtilJNI
  * Method:    addPortForwarder
  * Signature: (ILjava/lang/String;I)V
  */
diff --git a/wpiutil/src/main/native/cpp/json_serializer.h b/wpiutil/src/main/native/cpp/json_serializer.h
index 6983920..6c5ffbe 100644
--- a/wpiutil/src/main/native/cpp/json_serializer.h
+++ b/wpiutil/src/main/native/cpp/json_serializer.h
@@ -36,6 +36,7 @@
 #include <clocale> // lconv, localeconv
 #include <cmath>  // labs, isfinite, isnan, signbit, ldexp
 #include <locale> // locale
+#include <type_traits>
 
 #include "wpi/raw_ostream.h"
 
@@ -99,6 +100,18 @@
     */
     void dump_escaped(StringRef s, const bool ensure_ascii);
 
+    template <typename NumberType,
+              detail::enable_if_t<std::is_same_v<NumberType, uint64_t>, int> = 0>
+    bool is_negative_integer(NumberType x) {
+      return false;
+    }
+
+    template <typename NumberType,
+              detail::enable_if_t<std::is_same_v<NumberType, int64_t>, int> = 0>
+    bool is_negative_integer(NumberType x) {
+      return x < 0;
+    }
+
     /*!
     @brief dump an integer
 
@@ -121,7 +134,7 @@
             return;
         }
 
-        const bool is_negative = (x <= 0) and (x != 0);  // see issue #755
+        const bool is_negative = is_negative_integer(x);  // see issue #755
         std::size_t i = 0;
 
         while (x != 0)
diff --git a/wpiutil/src/main/native/cpp/llvm/Unix/Path.inc b/wpiutil/src/main/native/cpp/llvm/Unix/Path.inc
index b786813..4ec9e86 100644
--- a/wpiutil/src/main/native/cpp/llvm/Unix/Path.inc
+++ b/wpiutil/src/main/native/cpp/llvm/Unix/Path.inc
@@ -410,7 +410,7 @@
     return std::error_code();
   RealPath->clear();
 #if defined(F_GETPATH)
-  // When F_GETPATH is availble, it is the quickest way to get
+  // When F_GETPATH is available, it is the quickest way to get
   // the real path name.
   char Buffer[MAXPATHLEN];
   if (::fcntl(ResultFD, F_GETPATH, Buffer) != -1)
diff --git a/wpiutil/src/main/native/cpp/uv/GetNameInfo.cpp b/wpiutil/src/main/native/cpp/uv/GetNameInfo.cpp
index 994aadc..6a4446f 100644
--- a/wpiutil/src/main/native/cpp/uv/GetNameInfo.cpp
+++ b/wpiutil/src/main/native/cpp/uv/GetNameInfo.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2018 FIRST. All Rights Reserved.                             */
+/* Copyright (c) 2018-2020 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -19,17 +19,18 @@
 
 void GetNameInfo(Loop& loop, const std::shared_ptr<GetNameInfoReq>& req,
                  const sockaddr& addr, int flags) {
-  int err = uv_getnameinfo(loop.GetRaw(), req->GetRaw(),
-                           [](uv_getnameinfo_t* req, int status,
-                              const char* hostname, const char* service) {
-                             auto& h = *static_cast<GetNameInfoReq*>(req->data);
-                             if (status < 0)
-                               h.ReportError(status);
-                             else
-                               h.resolved(hostname, service);
-                             h.Release();  // this is always a one-shot
-                           },
-                           &addr, flags);
+  int err = uv_getnameinfo(
+      loop.GetRaw(), req->GetRaw(),
+      [](uv_getnameinfo_t* req, int status, const char* hostname,
+         const char* service) {
+        auto& h = *static_cast<GetNameInfoReq*>(req->data);
+        if (status < 0)
+          h.ReportError(status);
+        else
+          h.resolved(hostname, service);
+        h.Release();  // this is always a one-shot
+      },
+      &addr, flags);
   if (err < 0)
     loop.ReportError(err);
   else
diff --git a/wpiutil/src/main/native/cpp/uv/Loop.cpp b/wpiutil/src/main/native/cpp/uv/Loop.cpp
index 2602150..a31ad09 100644
--- a/wpiutil/src/main/native/cpp/uv/Loop.cpp
+++ b/wpiutil/src/main/native/cpp/uv/Loop.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2018 FIRST. All Rights Reserved.                             */
+/* Copyright (c) 2018-2020 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -49,13 +49,14 @@
 }
 
 void Loop::Walk(std::function<void(Handle&)> callback) {
-  uv_walk(m_loop,
-          [](uv_handle_t* handle, void* func) {
-            auto& h = *static_cast<Handle*>(handle->data);
-            auto& f = *static_cast<std::function<void(Handle&)>*>(func);
-            f(h);
-          },
-          &callback);
+  uv_walk(
+      m_loop,
+      [](uv_handle_t* handle, void* func) {
+        auto& h = *static_cast<Handle*>(handle->data);
+        auto& f = *static_cast<std::function<void(Handle&)>*>(func);
+        f(h);
+      },
+      &callback);
 }
 
 void Loop::Fork() {
diff --git a/wpiutil/src/main/native/cpp/uv/Signal.cpp b/wpiutil/src/main/native/cpp/uv/Signal.cpp
index 083b852..4569ac2 100644
--- a/wpiutil/src/main/native/cpp/uv/Signal.cpp
+++ b/wpiutil/src/main/native/cpp/uv/Signal.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2018 FIRST. All Rights Reserved.                             */
+/* Copyright (c) 2018-2020 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -24,12 +24,13 @@
 }
 
 void Signal::Start(int signum) {
-  Invoke(&uv_signal_start, GetRaw(),
-         [](uv_signal_t* handle, int signum) {
-           Signal& h = *static_cast<Signal*>(handle->data);
-           h.signal(signum);
-         },
-         signum);
+  Invoke(
+      &uv_signal_start, GetRaw(),
+      [](uv_signal_t* handle, int signum) {
+        Signal& h = *static_cast<Signal*>(handle->data);
+        h.signal(signum);
+      },
+      signum);
 }
 
 }  // namespace uv
diff --git a/wpiutil/src/main/native/cpp/uv/Timer.cpp b/wpiutil/src/main/native/cpp/uv/Timer.cpp
index 749d9a8..0fdd3be 100644
--- a/wpiutil/src/main/native/cpp/uv/Timer.cpp
+++ b/wpiutil/src/main/native/cpp/uv/Timer.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2018-2019 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2018-2020 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -34,12 +34,13 @@
 }
 
 void Timer::Start(Time timeout, Time repeat) {
-  Invoke(&uv_timer_start, GetRaw(),
-         [](uv_timer_t* handle) {
-           Timer& h = *static_cast<Timer*>(handle->data);
-           h.timeout();
-         },
-         timeout.count(), repeat.count());
+  Invoke(
+      &uv_timer_start, GetRaw(),
+      [](uv_timer_t* handle) {
+        Timer& h = *static_cast<Timer*>(handle->data);
+        h.timeout();
+      },
+      timeout.count(), repeat.count());
 }
 
 }  // namespace uv
diff --git a/wpiutil/src/main/native/cpp/uv/Work.cpp b/wpiutil/src/main/native/cpp/uv/Work.cpp
index d71ef81..e5d7bb6 100644
--- a/wpiutil/src/main/native/cpp/uv/Work.cpp
+++ b/wpiutil/src/main/native/cpp/uv/Work.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2018 FIRST. All Rights Reserved.                             */
+/* Copyright (c) 2018-2020 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -17,19 +17,20 @@
 }
 
 void QueueWork(Loop& loop, const std::shared_ptr<WorkReq>& req) {
-  int err = uv_queue_work(loop.GetRaw(), req->GetRaw(),
-                          [](uv_work_t* req) {
-                            auto& h = *static_cast<WorkReq*>(req->data);
-                            h.work();
-                          },
-                          [](uv_work_t* req, int status) {
-                            auto& h = *static_cast<WorkReq*>(req->data);
-                            if (status < 0)
-                              h.ReportError(status);
-                            else
-                              h.afterWork();
-                            h.Release();  // this is always a one-shot
-                          });
+  int err = uv_queue_work(
+      loop.GetRaw(), req->GetRaw(),
+      [](uv_work_t* req) {
+        auto& h = *static_cast<WorkReq*>(req->data);
+        h.work();
+      },
+      [](uv_work_t* req, int status) {
+        auto& h = *static_cast<WorkReq*>(req->data);
+        if (status < 0)
+          h.ReportError(status);
+        else
+          h.afterWork();
+        h.Release();  // this is always a one-shot
+      });
   if (err < 0)
     loop.ReportError(err);
   else
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/Cholesky b/wpiutil/src/main/native/eigeninclude/Eigen/Cholesky
deleted file mode 100644
index 1332b54..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/Cholesky
+++ /dev/null
@@ -1,46 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_CHOLESKY_MODULE_H
-#define EIGEN_CHOLESKY_MODULE_H
-
-#include "Core"
-#include "Jacobi"
-
-#include "src/Core/util/DisableStupidWarnings.h"
-
-/** \defgroup Cholesky_Module Cholesky module
-  *
-  *
-  *
-  * This module provides two variants of the Cholesky decomposition for selfadjoint (hermitian) matrices.
-  * Those decompositions are also accessible via the following methods:
-  *  - MatrixBase::llt()
-  *  - MatrixBase::ldlt()
-  *  - SelfAdjointView::llt()
-  *  - SelfAdjointView::ldlt()
-  *
-  * \code
-  * #include <Eigen/Cholesky>
-  * \endcode
-  */
-
-#include "src/Cholesky/LLT.h"
-#include "src/Cholesky/LDLT.h"
-#ifdef EIGEN_USE_LAPACKE
-#ifdef EIGEN_USE_MKL
-#include "mkl_lapacke.h"
-#else
-#include "src/misc/lapacke.h"
-#endif
-#include "src/Cholesky/LLT_LAPACKE.h"
-#endif
-
-#include "src/Core/util/ReenableStupidWarnings.h"
-
-#endif // EIGEN_CHOLESKY_MODULE_H
-/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/Core b/wpiutil/src/main/native/eigeninclude/Eigen/Core
deleted file mode 100644
index bd892c1..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/Core
+++ /dev/null
@@ -1,541 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2007-2011 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_CORE_H
-#define EIGEN_CORE_H
-
-#if __GNUC__ >= 9
-#pragma GCC diagnostic ignored "-Wdeprecated-copy"
-#endif
-
-// first thing Eigen does: stop the compiler from committing suicide
-#include "src/Core/util/DisableStupidWarnings.h"
-
-#if defined(__CUDACC__) && !defined(EIGEN_NO_CUDA)
-  #define EIGEN_CUDACC __CUDACC__
-#endif
-
-#if defined(__CUDA_ARCH__) && !defined(EIGEN_NO_CUDA)
-  #define EIGEN_CUDA_ARCH __CUDA_ARCH__
-#endif
-
-#if defined(__CUDACC_VER_MAJOR__) && (__CUDACC_VER_MAJOR__ >= 9)
-#define EIGEN_CUDACC_VER  ((__CUDACC_VER_MAJOR__ * 10000) + (__CUDACC_VER_MINOR__ * 100))
-#elif defined(__CUDACC_VER__)
-#define EIGEN_CUDACC_VER __CUDACC_VER__
-#else
-#define EIGEN_CUDACC_VER 0
-#endif
-
-// Handle NVCC/CUDA/SYCL
-#if defined(__CUDACC__) || defined(__SYCL_DEVICE_ONLY__)
-  // Do not try asserts on CUDA and SYCL!
-  #ifndef EIGEN_NO_DEBUG
-  #define EIGEN_NO_DEBUG
-  #endif
-
-  #ifdef EIGEN_INTERNAL_DEBUGGING
-  #undef EIGEN_INTERNAL_DEBUGGING
-  #endif
-
-  #ifdef EIGEN_EXCEPTIONS
-  #undef EIGEN_EXCEPTIONS
-  #endif
-
-  // All functions callable from CUDA code must be qualified with __device__
-  #ifdef __CUDACC__
-    // Do not try to vectorize on CUDA and SYCL!
-    #ifndef EIGEN_DONT_VECTORIZE
-    #define EIGEN_DONT_VECTORIZE
-    #endif
-
-    #define EIGEN_DEVICE_FUNC __host__ __device__
-    // We need cuda_runtime.h to ensure that that EIGEN_USING_STD_MATH macro
-    // works properly on the device side
-    #include <cuda_runtime.h>
-  #else
-    #define EIGEN_DEVICE_FUNC
-  #endif
-
-#else
-  #define EIGEN_DEVICE_FUNC
-
-#endif
-
-// When compiling CUDA device code with NVCC, pull in math functions from the
-// global namespace.  In host mode, and when device doee with clang, use the
-// std versions.
-#if defined(__CUDA_ARCH__) && defined(__NVCC__)
-  #define EIGEN_USING_STD_MATH(FUNC) using ::FUNC;
-#else
-  #define EIGEN_USING_STD_MATH(FUNC) using std::FUNC;
-#endif
-
-#if (defined(_CPPUNWIND) || defined(__EXCEPTIONS)) && !defined(__CUDA_ARCH__) && !defined(EIGEN_EXCEPTIONS) && !defined(EIGEN_USE_SYCL)
-  #define EIGEN_EXCEPTIONS
-#endif
-
-#ifdef EIGEN_EXCEPTIONS
-  #include <new>
-#endif
-
-// then include this file where all our macros are defined. It's really important to do it first because
-// it's where we do all the alignment settings (platform detection and honoring the user's will if he
-// defined e.g. EIGEN_DONT_ALIGN) so it needs to be done before we do anything with vectorization.
-#include "src/Core/util/Macros.h"
-
-// Disable the ipa-cp-clone optimization flag with MinGW 6.x or newer (enabled by default with -O3)
-// See http://eigen.tuxfamily.org/bz/show_bug.cgi?id=556 for details.
-#if EIGEN_COMP_MINGW && EIGEN_GNUC_AT_LEAST(4,6)
-  #pragma GCC optimize ("-fno-ipa-cp-clone")
-#endif
-
-#include <complex>
-
-// this include file manages BLAS and MKL related macros
-// and inclusion of their respective header files
-// #include "src/Core/util/MKL_support.h"
-
-// if alignment is disabled, then disable vectorization. Note: EIGEN_MAX_ALIGN_BYTES is the proper check, it takes into
-// account both the user's will (EIGEN_MAX_ALIGN_BYTES,EIGEN_DONT_ALIGN) and our own platform checks
-#if EIGEN_MAX_ALIGN_BYTES==0
-  #ifndef EIGEN_DONT_VECTORIZE
-    #define EIGEN_DONT_VECTORIZE
-  #endif
-#endif
-
-#if EIGEN_COMP_MSVC
-  #include <malloc.h> // for _aligned_malloc -- need it regardless of whether vectorization is enabled
-  #if (EIGEN_COMP_MSVC >= 1500) // 2008 or later
-    // Remember that usage of defined() in a #define is undefined by the standard.
-    // a user reported that in 64-bit mode, MSVC doesn't care to define _M_IX86_FP.
-    #if (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || EIGEN_ARCH_x86_64
-      #define EIGEN_SSE2_ON_MSVC_2008_OR_LATER
-    #endif
-  #endif
-#else
-  // Remember that usage of defined() in a #define is undefined by the standard
-  #if (defined __SSE2__) && ( (!EIGEN_COMP_GNUC) || EIGEN_COMP_ICC || EIGEN_GNUC_AT_LEAST(4,2) )
-    #define EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC
-  #endif
-#endif
-
-#ifndef EIGEN_DONT_VECTORIZE
-
-  #if defined (EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER)
-
-    // Defines symbols for compile-time detection of which instructions are
-    // used.
-    // EIGEN_VECTORIZE_YY is defined if and only if the instruction set YY is used
-    #define EIGEN_VECTORIZE
-    #define EIGEN_VECTORIZE_SSE
-    #define EIGEN_VECTORIZE_SSE2
-
-    // Detect sse3/ssse3/sse4:
-    // gcc and icc defines __SSE3__, ...
-    // there is no way to know about this on msvc. You can define EIGEN_VECTORIZE_SSE* if you
-    // want to force the use of those instructions with msvc.
-    #ifdef __SSE3__
-      #define EIGEN_VECTORIZE_SSE3
-    #endif
-    #ifdef __SSSE3__
-      #define EIGEN_VECTORIZE_SSSE3
-    #endif
-    #ifdef __SSE4_1__
-      #define EIGEN_VECTORIZE_SSE4_1
-    #endif
-    #ifdef __SSE4_2__
-      #define EIGEN_VECTORIZE_SSE4_2
-    #endif
-    #ifdef __AVX__
-      #define EIGEN_VECTORIZE_AVX
-      #define EIGEN_VECTORIZE_SSE3
-      #define EIGEN_VECTORIZE_SSSE3
-      #define EIGEN_VECTORIZE_SSE4_1
-      #define EIGEN_VECTORIZE_SSE4_2
-    #endif
-    #ifdef __AVX2__
-      #define EIGEN_VECTORIZE_AVX2
-    #endif
-    #ifdef __FMA__
-      #define EIGEN_VECTORIZE_FMA
-    #endif
-    #if defined(__AVX512F__) && defined(EIGEN_ENABLE_AVX512)
-      #define EIGEN_VECTORIZE_AVX512
-      #define EIGEN_VECTORIZE_AVX2
-      #define EIGEN_VECTORIZE_AVX
-      #define EIGEN_VECTORIZE_FMA
-      #ifdef __AVX512DQ__
-        #define EIGEN_VECTORIZE_AVX512DQ
-      #endif
-      #ifdef __AVX512ER__
-        #define EIGEN_VECTORIZE_AVX512ER
-      #endif
-    #endif
-
-    // include files
-
-    // This extern "C" works around a MINGW-w64 compilation issue
-    // https://sourceforge.net/tracker/index.php?func=detail&aid=3018394&group_id=202880&atid=983354
-    // In essence, intrin.h is included by windows.h and also declares intrinsics (just as emmintrin.h etc. below do).
-    // However, intrin.h uses an extern "C" declaration, and g++ thus complains of duplicate declarations
-    // with conflicting linkage.  The linkage for intrinsics doesn't matter, but at that stage the compiler doesn't know;
-    // so, to avoid compile errors when windows.h is included after Eigen/Core, ensure intrinsics are extern "C" here too.
-    // notice that since these are C headers, the extern "C" is theoretically needed anyways.
-    extern "C" {
-      // In theory we should only include immintrin.h and not the other *mmintrin.h header files directly.
-      // Doing so triggers some issues with ICC. However old gcc versions seems to not have this file, thus:
-      #if EIGEN_COMP_ICC >= 1110
-        #include <immintrin.h>
-      #else
-        #include <mmintrin.h>
-        #include <emmintrin.h>
-        #include <xmmintrin.h>
-        #ifdef  EIGEN_VECTORIZE_SSE3
-        #include <pmmintrin.h>
-        #endif
-        #ifdef EIGEN_VECTORIZE_SSSE3
-        #include <tmmintrin.h>
-        #endif
-        #ifdef EIGEN_VECTORIZE_SSE4_1
-        #include <smmintrin.h>
-        #endif
-        #ifdef EIGEN_VECTORIZE_SSE4_2
-        #include <nmmintrin.h>
-        #endif
-        #if defined(EIGEN_VECTORIZE_AVX) || defined(EIGEN_VECTORIZE_AVX512)
-        #include <immintrin.h>
-        #endif
-      #endif
-    } // end extern "C"
-  #elif defined __VSX__
-    #define EIGEN_VECTORIZE
-    #define EIGEN_VECTORIZE_VSX
-    #include <altivec.h>
-    // We need to #undef all these ugly tokens defined in <altivec.h>
-    // => use __vector instead of vector
-    #undef bool
-    #undef vector
-    #undef pixel
-  #elif defined __ALTIVEC__
-    #define EIGEN_VECTORIZE
-    #define EIGEN_VECTORIZE_ALTIVEC
-    #include <altivec.h>
-    // We need to #undef all these ugly tokens defined in <altivec.h>
-    // => use __vector instead of vector
-    #undef bool
-    #undef vector
-    #undef pixel
-  #elif (defined  __ARM_NEON) || (defined __ARM_NEON__)
-    #define EIGEN_VECTORIZE
-    #define EIGEN_VECTORIZE_NEON
-    #include <arm_neon.h>
-  #elif (defined __s390x__ && defined __VEC__)
-    #define EIGEN_VECTORIZE
-    #define EIGEN_VECTORIZE_ZVECTOR
-    #include <vecintrin.h>
-  #endif
-#endif
-
-#if defined(__F16C__) && !defined(EIGEN_COMP_CLANG)
-  // We can use the optimized fp16 to float and float to fp16 conversion routines
-  #define EIGEN_HAS_FP16_C
-#endif
-
-#if defined __CUDACC__
-  #define EIGEN_VECTORIZE_CUDA
-  #include <vector_types.h>
-  #if EIGEN_CUDACC_VER >= 70500
-    #define EIGEN_HAS_CUDA_FP16
-  #endif
-#endif
-
-#if defined EIGEN_HAS_CUDA_FP16
-  #include <host_defines.h>
-  #include <cuda_fp16.h>
-#endif
-
-#if (defined _OPENMP) && (!defined EIGEN_DONT_PARALLELIZE)
-  #define EIGEN_HAS_OPENMP
-#endif
-
-#ifdef EIGEN_HAS_OPENMP
-#include <omp.h>
-#endif
-
-// MSVC for windows mobile does not have the errno.h file
-#if !(EIGEN_COMP_MSVC && EIGEN_OS_WINCE) && !EIGEN_COMP_ARM
-#define EIGEN_HAS_ERRNO
-#endif
-
-#ifdef EIGEN_HAS_ERRNO
-#include <cerrno>
-#endif
-#include <cstddef>
-#include <cstdlib>
-#include <cmath>
-#include <cassert>
-#include <functional>
-#include <iosfwd>
-#include <cstring>
-#include <string>
-#include <limits>
-#include <climits> // for CHAR_BIT
-// for min/max:
-#include <algorithm>
-
-// for std::is_nothrow_move_assignable
-#ifdef EIGEN_INCLUDE_TYPE_TRAITS
-#include <type_traits>
-#endif
-
-// for outputting debug info
-#ifdef EIGEN_DEBUG_ASSIGN
-#include <iostream>
-#endif
-
-// required for __cpuid, needs to be included after cmath
-#if EIGEN_COMP_MSVC && EIGEN_ARCH_i386_OR_x86_64 && !EIGEN_OS_WINCE
-  #include <intrin.h>
-#endif
-
-/** \brief Namespace containing all symbols from the %Eigen library. */
-namespace Eigen {
-
-inline static const char *SimdInstructionSetsInUse(void) {
-#if defined(EIGEN_VECTORIZE_AVX512)
-  return "AVX512, FMA, AVX2, AVX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2";
-#elif defined(EIGEN_VECTORIZE_AVX)
-  return "AVX SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2";
-#elif defined(EIGEN_VECTORIZE_SSE4_2)
-  return "SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2";
-#elif defined(EIGEN_VECTORIZE_SSE4_1)
-  return "SSE, SSE2, SSE3, SSSE3, SSE4.1";
-#elif defined(EIGEN_VECTORIZE_SSSE3)
-  return "SSE, SSE2, SSE3, SSSE3";
-#elif defined(EIGEN_VECTORIZE_SSE3)
-  return "SSE, SSE2, SSE3";
-#elif defined(EIGEN_VECTORIZE_SSE2)
-  return "SSE, SSE2";
-#elif defined(EIGEN_VECTORIZE_ALTIVEC)
-  return "AltiVec";
-#elif defined(EIGEN_VECTORIZE_VSX)
-  return "VSX";
-#elif defined(EIGEN_VECTORIZE_NEON)
-  return "ARM NEON";
-#elif defined(EIGEN_VECTORIZE_ZVECTOR)
-  return "S390X ZVECTOR";
-#else
-  return "None";
-#endif
-}
-
-} // end namespace Eigen
-
-#if defined EIGEN2_SUPPORT_STAGE40_FULL_EIGEN3_STRICTNESS || defined EIGEN2_SUPPORT_STAGE30_FULL_EIGEN3_API || defined EIGEN2_SUPPORT_STAGE20_RESOLVE_API_CONFLICTS || defined EIGEN2_SUPPORT_STAGE10_FULL_EIGEN2_API || defined EIGEN2_SUPPORT
-// This will generate an error message:
-#error Eigen2-support is only available up to version 3.2. Please go to "http://eigen.tuxfamily.org/index.php?title=Eigen2" for further information
-#endif
-
-namespace Eigen {
-
-// we use size_t frequently and we'll never remember to prepend it with std:: everytime just to
-// ensure QNX/QCC support
-using std::size_t;
-// gcc 4.6.0 wants std:: for ptrdiff_t
-using std::ptrdiff_t;
-
-}
-
-/** \defgroup Core_Module Core module
-  * This is the main module of Eigen providing dense matrix and vector support
-  * (both fixed and dynamic size) with all the features corresponding to a BLAS library
-  * and much more...
-  *
-  * \code
-  * #include <Eigen/Core>
-  * \endcode
-  */
-
-#include "src/Core/util/Constants.h"
-#include "src/Core/util/Meta.h"
-#include "src/Core/util/ForwardDeclarations.h"
-#include "src/Core/util/StaticAssert.h"
-#include "src/Core/util/XprHelper.h"
-#include "src/Core/util/Memory.h"
-
-#include "src/Core/NumTraits.h"
-#include "src/Core/MathFunctions.h"
-#include "src/Core/GenericPacketMath.h"
-#include "src/Core/MathFunctionsImpl.h"
-#include "src/Core/arch/Default/ConjHelper.h"
-
-#if defined EIGEN_VECTORIZE_AVX512
-  #include "src/Core/arch/SSE/PacketMath.h"
-  #include "src/Core/arch/AVX/PacketMath.h"
-  #include "src/Core/arch/AVX512/PacketMath.h"
-  #include "src/Core/arch/AVX512/MathFunctions.h"
-#elif defined EIGEN_VECTORIZE_AVX
-  // Use AVX for floats and doubles, SSE for integers
-  #include "src/Core/arch/SSE/PacketMath.h"
-  #include "src/Core/arch/SSE/Complex.h"
-  #include "src/Core/arch/SSE/MathFunctions.h"
-  #include "src/Core/arch/AVX/PacketMath.h"
-  #include "src/Core/arch/AVX/MathFunctions.h"
-  #include "src/Core/arch/AVX/Complex.h"
-  #include "src/Core/arch/AVX/TypeCasting.h"
-  #include "src/Core/arch/SSE/TypeCasting.h"
-#elif defined EIGEN_VECTORIZE_SSE
-  #include "src/Core/arch/SSE/PacketMath.h"
-  #include "src/Core/arch/SSE/MathFunctions.h"
-  #include "src/Core/arch/SSE/Complex.h"
-  #include "src/Core/arch/SSE/TypeCasting.h"
-#elif defined(EIGEN_VECTORIZE_ALTIVEC) || defined(EIGEN_VECTORIZE_VSX)
-  #include "src/Core/arch/AltiVec/PacketMath.h"
-  #include "src/Core/arch/AltiVec/MathFunctions.h"
-  #include "src/Core/arch/AltiVec/Complex.h"
-#elif defined EIGEN_VECTORIZE_NEON
-  #include "src/Core/arch/NEON/PacketMath.h"
-  #include "src/Core/arch/NEON/MathFunctions.h"
-  #include "src/Core/arch/NEON/Complex.h"
-#elif defined EIGEN_VECTORIZE_ZVECTOR
-  #include "src/Core/arch/ZVector/PacketMath.h"
-  #include "src/Core/arch/ZVector/MathFunctions.h"
-  #include "src/Core/arch/ZVector/Complex.h"
-#endif
-
-// Half float support
-// #include "src/Core/arch/CUDA/Half.h"
-// #include "src/Core/arch/CUDA/PacketMathHalf.h"
-// #include "src/Core/arch/CUDA/TypeCasting.h"
-
-#if defined EIGEN_VECTORIZE_CUDA
-  #include "src/Core/arch/CUDA/PacketMath.h"
-  #include "src/Core/arch/CUDA/MathFunctions.h"
-#endif
-
-#include "src/Core/arch/Default/Settings.h"
-
-#include "src/Core/functors/TernaryFunctors.h"
-#include "src/Core/functors/BinaryFunctors.h"
-#include "src/Core/functors/UnaryFunctors.h"
-#include "src/Core/functors/NullaryFunctors.h"
-#include "src/Core/functors/StlFunctors.h"
-#include "src/Core/functors/AssignmentFunctors.h"
-
-// Specialized functors to enable the processing of complex numbers
-// on CUDA devices
-// #include "src/Core/arch/CUDA/Complex.h"
-
-#include "src/Core/IO.h"
-#include "src/Core/DenseCoeffsBase.h"
-#include "src/Core/DenseBase.h"
-#include "src/Core/MatrixBase.h"
-#include "src/Core/EigenBase.h"
-
-#include "src/Core/Product.h"
-#include "src/Core/CoreEvaluators.h"
-#include "src/Core/AssignEvaluator.h"
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN // work around Doxygen bug triggered by Assign.h r814874
-                                // at least confirmed with Doxygen 1.5.5 and 1.5.6
-  #include "src/Core/Assign.h"
-#endif
-
-#include "src/Core/ArrayBase.h"
-#include "src/Core/util/BlasUtil.h"
-#include "src/Core/DenseStorage.h"
-#include "src/Core/NestByValue.h"
-
-// #include "src/Core/ForceAlignedAccess.h"
-
-#include "src/Core/ReturnByValue.h"
-#include "src/Core/NoAlias.h"
-#include "src/Core/PlainObjectBase.h"
-#include "src/Core/Matrix.h"
-#include "src/Core/Array.h"
-#include "src/Core/CwiseTernaryOp.h"
-#include "src/Core/CwiseBinaryOp.h"
-#include "src/Core/CwiseUnaryOp.h"
-#include "src/Core/CwiseNullaryOp.h"
-#include "src/Core/CwiseUnaryView.h"
-#include "src/Core/SelfCwiseBinaryOp.h"
-#include "src/Core/Dot.h"
-#include "src/Core/StableNorm.h"
-#include "src/Core/Stride.h"
-#include "src/Core/MapBase.h"
-#include "src/Core/Map.h"
-#include "src/Core/Ref.h"
-#include "src/Core/Block.h"
-#include "src/Core/VectorBlock.h"
-#include "src/Core/Transpose.h"
-#include "src/Core/DiagonalMatrix.h"
-#include "src/Core/Diagonal.h"
-#include "src/Core/DiagonalProduct.h"
-#include "src/Core/Redux.h"
-#include "src/Core/Visitor.h"
-#include "src/Core/Fuzzy.h"
-#include "src/Core/Swap.h"
-#include "src/Core/CommaInitializer.h"
-#include "src/Core/GeneralProduct.h"
-#include "src/Core/Solve.h"
-#include "src/Core/Inverse.h"
-#include "src/Core/SolverBase.h"
-#include "src/Core/PermutationMatrix.h"
-#include "src/Core/Transpositions.h"
-#include "src/Core/TriangularMatrix.h"
-#include "src/Core/SelfAdjointView.h"
-#include "src/Core/products/GeneralBlockPanelKernel.h"
-#include "src/Core/products/Parallelizer.h"
-#include "src/Core/ProductEvaluators.h"
-#include "src/Core/products/GeneralMatrixVector.h"
-#include "src/Core/products/GeneralMatrixMatrix.h"
-#include "src/Core/SolveTriangular.h"
-#include "src/Core/products/GeneralMatrixMatrixTriangular.h"
-#include "src/Core/products/SelfadjointMatrixVector.h"
-#include "src/Core/products/SelfadjointMatrixMatrix.h"
-#include "src/Core/products/SelfadjointProduct.h"
-#include "src/Core/products/SelfadjointRank2Update.h"
-#include "src/Core/products/TriangularMatrixVector.h"
-#include "src/Core/products/TriangularMatrixMatrix.h"
-#include "src/Core/products/TriangularSolverMatrix.h"
-#include "src/Core/products/TriangularSolverVector.h"
-#include "src/Core/BandMatrix.h"
-#include "src/Core/CoreIterators.h"
-#include "src/Core/ConditionEstimator.h"
-
-#include "src/Core/BooleanRedux.h"
-#include "src/Core/Select.h"
-#include "src/Core/VectorwiseOp.h"
-#include "src/Core/Random.h"
-#include "src/Core/Replicate.h"
-#include "src/Core/Reverse.h"
-#include "src/Core/ArrayWrapper.h"
-
-#ifdef EIGEN_USE_BLAS
-#include "src/Core/products/GeneralMatrixMatrix_BLAS.h"
-#include "src/Core/products/GeneralMatrixVector_BLAS.h"
-#include "src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h"
-#include "src/Core/products/SelfadjointMatrixMatrix_BLAS.h"
-#include "src/Core/products/SelfadjointMatrixVector_BLAS.h"
-#include "src/Core/products/TriangularMatrixMatrix_BLAS.h"
-#include "src/Core/products/TriangularMatrixVector_BLAS.h"
-#include "src/Core/products/TriangularSolverMatrix_BLAS.h"
-#endif // EIGEN_USE_BLAS
-
-#ifdef EIGEN_USE_MKL_VML
-#include "src/Core/Assign_MKL.h"
-#endif
-
-#include "src/Core/GlobalFunctions.h"
-
-#include "src/Core/util/ReenableStupidWarnings.h"
-
-#endif // EIGEN_CORE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/Eigen b/wpiutil/src/main/native/eigeninclude/Eigen/Eigen
deleted file mode 100644
index 654c8dc..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/Eigen
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "Dense"
-#include "Sparse"
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/Eigenvalues b/wpiutil/src/main/native/eigeninclude/Eigen/Eigenvalues
deleted file mode 100644
index 1ad6bcf..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/Eigenvalues
+++ /dev/null
@@ -1,60 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_EIGENVALUES_MODULE_H
-#define EIGEN_EIGENVALUES_MODULE_H
-
-#include "Core"
-
-#include "src/Core/util/DisableStupidWarnings.h"
-
-#include "Cholesky"
-#include "Jacobi"
-#include "Householder"
-#include "LU"
-
-/** \defgroup Eigenvalues_Module Eigenvalues module
-  *
-  *
-  *
-  * This module mainly provides various eigenvalue solvers.
-  * This module also provides some MatrixBase methods, including:
-  *  - MatrixBase::eigenvalues(),
-  *  - MatrixBase::operatorNorm()
-  *
-  * \code
-  * #include <Eigen/Eigenvalues>
-  * \endcode
-  */
-
-#include "src/misc/RealSvd2x2.h"
-#include "src/Eigenvalues/Tridiagonalization.h"
-#include "src/Eigenvalues/RealSchur.h"
-#include "src/Eigenvalues/EigenSolver.h"
-#include "src/Eigenvalues/SelfAdjointEigenSolver.h"
-#include "src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h"
-#include "src/Eigenvalues/HessenbergDecomposition.h"
-#include "src/Eigenvalues/ComplexSchur.h"
-#include "src/Eigenvalues/ComplexEigenSolver.h"
-#include "src/Eigenvalues/RealQZ.h"
-#include "src/Eigenvalues/GeneralizedEigenSolver.h"
-#include "src/Eigenvalues/MatrixBaseEigenvalues.h"
-#ifdef EIGEN_USE_LAPACKE
-#ifdef EIGEN_USE_MKL
-#include "mkl_lapacke.h"
-#else
-#include "src/misc/lapacke.h"
-#endif
-#include "src/Eigenvalues/RealSchur_LAPACKE.h"
-#include "src/Eigenvalues/ComplexSchur_LAPACKE.h"
-#include "src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h"
-#endif
-
-#include "src/Core/util/ReenableStupidWarnings.h"
-
-#endif // EIGEN_EIGENVALUES_MODULE_H
-/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/Householder b/wpiutil/src/main/native/eigeninclude/Eigen/Householder
deleted file mode 100644
index 89cd81b..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/Householder
+++ /dev/null
@@ -1,30 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_HOUSEHOLDER_MODULE_H
-#define EIGEN_HOUSEHOLDER_MODULE_H
-
-#include "Core"
-
-#include "src/Core/util/DisableStupidWarnings.h"
-
-/** \defgroup Householder_Module Householder module
-  * This module provides Householder transformations.
-  *
-  * \code
-  * #include <Eigen/Householder>
-  * \endcode
-  */
-
-#include "src/Householder/Householder.h"
-#include "src/Householder/HouseholderSequence.h"
-#include "src/Householder/BlockHouseholder.h"
-
-#include "src/Core/util/ReenableStupidWarnings.h"
-
-#endif // EIGEN_HOUSEHOLDER_MODULE_H
-/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/Jacobi b/wpiutil/src/main/native/eigeninclude/Eigen/Jacobi
deleted file mode 100644
index 17c1d78..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/Jacobi
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_JACOBI_MODULE_H
-#define EIGEN_JACOBI_MODULE_H
-
-#include "Core"
-
-#include "src/Core/util/DisableStupidWarnings.h"
-
-/** \defgroup Jacobi_Module Jacobi module
-  * This module provides Jacobi and Givens rotations.
-  *
-  * \code
-  * #include <Eigen/Jacobi>
-  * \endcode
-  *
-  * In addition to listed classes, it defines the two following MatrixBase methods to apply a Jacobi or Givens rotation:
-  *  - MatrixBase::applyOnTheLeft()
-  *  - MatrixBase::applyOnTheRight().
-  */
-
-#include "src/Jacobi/Jacobi.h"
-
-#include "src/Core/util/ReenableStupidWarnings.h"
-
-#endif // EIGEN_JACOBI_MODULE_H
-/* vim: set filetype=cpp et sw=2 ts=2 ai: */
-
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/LU b/wpiutil/src/main/native/eigeninclude/Eigen/LU
deleted file mode 100644
index 6418a86..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/LU
+++ /dev/null
@@ -1,50 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_LU_MODULE_H
-#define EIGEN_LU_MODULE_H
-
-#include "Core"
-
-#include "src/Core/util/DisableStupidWarnings.h"
-
-/** \defgroup LU_Module LU module
-  * This module includes %LU decomposition and related notions such as matrix inversion and determinant.
-  * This module defines the following MatrixBase methods:
-  *  - MatrixBase::inverse()
-  *  - MatrixBase::determinant()
-  *
-  * \code
-  * #include <Eigen/LU>
-  * \endcode
-  */
-
-#include "src/misc/Kernel.h"
-#include "src/misc/Image.h"
-#include "src/LU/FullPivLU.h"
-#include "src/LU/PartialPivLU.h"
-#ifdef EIGEN_USE_LAPACKE
-#ifdef EIGEN_USE_MKL
-#include "mkl_lapacke.h"
-#else
-#include "src/misc/lapacke.h"
-#endif
-#include "src/LU/PartialPivLU_LAPACKE.h"
-#endif
-#include "src/LU/Determinant.h"
-#include "src/LU/InverseImpl.h"
-
-// Use the SSE optimized version whenever possible. At the moment the
-// SSE version doesn't compile when AVX is enabled
-#if defined EIGEN_VECTORIZE_SSE && !defined EIGEN_VECTORIZE_AVX
-  #include "src/LU/arch/Inverse_SSE.h"
-#endif
-
-#include "src/Core/util/ReenableStupidWarnings.h"
-
-#endif // EIGEN_LU_MODULE_H
-/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/QR b/wpiutil/src/main/native/eigeninclude/Eigen/QR
deleted file mode 100644
index c7e9144..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/QR
+++ /dev/null
@@ -1,51 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_QR_MODULE_H
-#define EIGEN_QR_MODULE_H
-
-#include "Core"
-
-#include "src/Core/util/DisableStupidWarnings.h"
-
-#include "Cholesky"
-#include "Jacobi"
-#include "Householder"
-
-/** \defgroup QR_Module QR module
-  *
-  *
-  *
-  * This module provides various QR decompositions
-  * This module also provides some MatrixBase methods, including:
-  *  - MatrixBase::householderQr()
-  *  - MatrixBase::colPivHouseholderQr()
-  *  - MatrixBase::fullPivHouseholderQr()
-  *
-  * \code
-  * #include <Eigen/QR>
-  * \endcode
-  */
-
-#include "src/QR/HouseholderQR.h"
-#include "src/QR/FullPivHouseholderQR.h"
-#include "src/QR/ColPivHouseholderQR.h"
-#include "src/QR/CompleteOrthogonalDecomposition.h"
-#ifdef EIGEN_USE_LAPACKE
-#ifdef EIGEN_USE_MKL
-#include "mkl_lapacke.h"
-#else
-#include "src/misc/lapacke.h"
-#endif
-#include "src/QR/HouseholderQR_LAPACKE.h"
-#include "src/QR/ColPivHouseholderQR_LAPACKE.h"
-#endif
-
-#include "src/Core/util/ReenableStupidWarnings.h"
-
-#endif // EIGEN_QR_MODULE_H
-/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/SVD b/wpiutil/src/main/native/eigeninclude/Eigen/SVD
deleted file mode 100644
index 5d0e75f..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/SVD
+++ /dev/null
@@ -1,51 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_SVD_MODULE_H
-#define EIGEN_SVD_MODULE_H
-
-#include "QR"
-#include "Householder"
-#include "Jacobi"
-
-#include "src/Core/util/DisableStupidWarnings.h"
-
-/** \defgroup SVD_Module SVD module
-  *
-  *
-  *
-  * This module provides SVD decomposition for matrices (both real and complex).
-  * Two decomposition algorithms are provided:
-  *  - JacobiSVD implementing two-sided Jacobi iterations is numerically very accurate, fast for small matrices, but very slow for larger ones.
-  *  - BDCSVD implementing a recursive divide & conquer strategy on top of an upper-bidiagonalization which remains fast for large problems.
-  * These decompositions are accessible via the respective classes and following MatrixBase methods:
-  *  - MatrixBase::jacobiSvd()
-  *  - MatrixBase::bdcSvd()
-  *
-  * \code
-  * #include <Eigen/SVD>
-  * \endcode
-  */
-
-#include "src/misc/RealSvd2x2.h"
-#include "src/SVD/UpperBidiagonalization.h"
-#include "src/SVD/SVDBase.h"
-#include "src/SVD/JacobiSVD.h"
-#include "src/SVD/BDCSVD.h"
-#if defined(EIGEN_USE_LAPACKE) && !defined(EIGEN_USE_LAPACKE_STRICT)
-#ifdef EIGEN_USE_MKL
-#include "mkl_lapacke.h"
-#else
-#include "src/misc/lapacke.h"
-#endif
-#include "src/SVD/JacobiSVD_LAPACKE.h"
-#endif
-
-#include "src/Core/util/ReenableStupidWarnings.h"
-
-#endif // EIGEN_SVD_MODULE_H
-/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/StdDeque b/wpiutil/src/main/native/eigeninclude/Eigen/StdDeque
deleted file mode 100644
index bc68397..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/StdDeque
+++ /dev/null
@@ -1,27 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_STDDEQUE_MODULE_H
-#define EIGEN_STDDEQUE_MODULE_H
-
-#include "Core"
-#include <deque>
-
-#if EIGEN_COMP_MSVC && EIGEN_OS_WIN64 && (EIGEN_MAX_STATIC_ALIGN_BYTES<=16) /* MSVC auto aligns up to 16 bytes in 64 bit builds */
-
-#define EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(...)
-
-#else
-
-#include "src/StlSupport/StdDeque.h"
-
-#endif
-
-#endif // EIGEN_STDDEQUE_MODULE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/StdList b/wpiutil/src/main/native/eigeninclude/Eigen/StdList
deleted file mode 100644
index 4c6262c..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/StdList
+++ /dev/null
@@ -1,26 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_STDLIST_MODULE_H
-#define EIGEN_STDLIST_MODULE_H
-
-#include "Core"
-#include <list>
-
-#if EIGEN_COMP_MSVC && EIGEN_OS_WIN64 && (EIGEN_MAX_STATIC_ALIGN_BYTES<=16) /* MSVC auto aligns up to 16 bytes in 64 bit builds */
-
-#define EIGEN_DEFINE_STL_LIST_SPECIALIZATION(...)
-
-#else
-
-#include "src/StlSupport/StdList.h"
-
-#endif
-
-#endif // EIGEN_STDLIST_MODULE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/StdVector b/wpiutil/src/main/native/eigeninclude/Eigen/StdVector
deleted file mode 100644
index 0c4697a..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/StdVector
+++ /dev/null
@@ -1,27 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_STDVECTOR_MODULE_H
-#define EIGEN_STDVECTOR_MODULE_H
-
-#include "Core"
-#include <vector>
-
-#if EIGEN_COMP_MSVC && EIGEN_OS_WIN64 && (EIGEN_MAX_STATIC_ALIGN_BYTES<=16) /* MSVC auto aligns up to 16 bytes in 64 bit builds */
-
-#define EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(...)
-
-#else
-
-#include "src/StlSupport/StdVector.h"
-
-#endif
-
-#endif // EIGEN_STDVECTOR_MODULE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Cholesky/LDLT.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Cholesky/LDLT.h
deleted file mode 100644
index 15ccf24..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Cholesky/LDLT.h
+++ /dev/null
@@ -1,673 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2009 Keir Mierle <mierle@gmail.com>
-// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2011 Timothy E. Holy <tim.holy@gmail.com >
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_LDLT_H
-#define EIGEN_LDLT_H
-
-namespace Eigen {
-
-namespace internal {
-  template<typename MatrixType, int UpLo> struct LDLT_Traits;
-
-  // PositiveSemiDef means positive semi-definite and non-zero; same for NegativeSemiDef
-  enum SignMatrix { PositiveSemiDef, NegativeSemiDef, ZeroSign, Indefinite };
-}
-
-/** \ingroup Cholesky_Module
-  *
-  * \class LDLT
-  *
-  * \brief Robust Cholesky decomposition of a matrix with pivoting
-  *
-  * \tparam _MatrixType the type of the matrix of which to compute the LDL^T Cholesky decomposition
-  * \tparam _UpLo the triangular part that will be used for the decompositon: Lower (default) or Upper.
-  *             The other triangular part won't be read.
-  *
-  * Perform a robust Cholesky decomposition of a positive semidefinite or negative semidefinite
-  * matrix \f$ A \f$ such that \f$ A =  P^TLDL^*P \f$, where P is a permutation matrix, L
-  * is lower triangular with a unit diagonal and D is a diagonal matrix.
-  *
-  * The decomposition uses pivoting to ensure stability, so that L will have
-  * zeros in the bottom right rank(A) - n submatrix. Avoiding the square root
-  * on D also stabilizes the computation.
-  *
-  * Remember that Cholesky decompositions are not rank-revealing. Also, do not use a Cholesky
-  * decomposition to determine whether a system of equations has a solution.
-  *
-  * This class supports the \link InplaceDecomposition inplace decomposition \endlink mechanism.
-  * 
-  * \sa MatrixBase::ldlt(), SelfAdjointView::ldlt(), class LLT
-  */
-template<typename _MatrixType, int _UpLo> class LDLT
-{
-  public:
-    typedef _MatrixType MatrixType;
-    enum {
-      RowsAtCompileTime = MatrixType::RowsAtCompileTime,
-      ColsAtCompileTime = MatrixType::ColsAtCompileTime,
-      MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
-      MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
-      UpLo = _UpLo
-    };
-    typedef typename MatrixType::Scalar Scalar;
-    typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
-    typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
-    typedef typename MatrixType::StorageIndex StorageIndex;
-    typedef Matrix<Scalar, RowsAtCompileTime, 1, 0, MaxRowsAtCompileTime, 1> TmpMatrixType;
-
-    typedef Transpositions<RowsAtCompileTime, MaxRowsAtCompileTime> TranspositionType;
-    typedef PermutationMatrix<RowsAtCompileTime, MaxRowsAtCompileTime> PermutationType;
-
-    typedef internal::LDLT_Traits<MatrixType,UpLo> Traits;
-
-    /** \brief Default Constructor.
-      *
-      * The default constructor is useful in cases in which the user intends to
-      * perform decompositions via LDLT::compute(const MatrixType&).
-      */
-    LDLT()
-      : m_matrix(),
-        m_transpositions(),
-        m_sign(internal::ZeroSign),
-        m_isInitialized(false)
-    {}
-
-    /** \brief Default Constructor with memory preallocation
-      *
-      * Like the default constructor but with preallocation of the internal data
-      * according to the specified problem \a size.
-      * \sa LDLT()
-      */
-    explicit LDLT(Index size)
-      : m_matrix(size, size),
-        m_transpositions(size),
-        m_temporary(size),
-        m_sign(internal::ZeroSign),
-        m_isInitialized(false)
-    {}
-
-    /** \brief Constructor with decomposition
-      *
-      * This calculates the decomposition for the input \a matrix.
-      *
-      * \sa LDLT(Index size)
-      */
-    template<typename InputType>
-    explicit LDLT(const EigenBase<InputType>& matrix)
-      : m_matrix(matrix.rows(), matrix.cols()),
-        m_transpositions(matrix.rows()),
-        m_temporary(matrix.rows()),
-        m_sign(internal::ZeroSign),
-        m_isInitialized(false)
-    {
-      compute(matrix.derived());
-    }
-
-    /** \brief Constructs a LDLT factorization from a given matrix
-      *
-      * This overloaded constructor is provided for \link InplaceDecomposition inplace decomposition \endlink when \c MatrixType is a Eigen::Ref.
-      *
-      * \sa LDLT(const EigenBase&)
-      */
-    template<typename InputType>
-    explicit LDLT(EigenBase<InputType>& matrix)
-      : m_matrix(matrix.derived()),
-        m_transpositions(matrix.rows()),
-        m_temporary(matrix.rows()),
-        m_sign(internal::ZeroSign),
-        m_isInitialized(false)
-    {
-      compute(matrix.derived());
-    }
-
-    /** Clear any existing decomposition
-     * \sa rankUpdate(w,sigma)
-     */
-    void setZero()
-    {
-      m_isInitialized = false;
-    }
-
-    /** \returns a view of the upper triangular matrix U */
-    inline typename Traits::MatrixU matrixU() const
-    {
-      eigen_assert(m_isInitialized && "LDLT is not initialized.");
-      return Traits::getU(m_matrix);
-    }
-
-    /** \returns a view of the lower triangular matrix L */
-    inline typename Traits::MatrixL matrixL() const
-    {
-      eigen_assert(m_isInitialized && "LDLT is not initialized.");
-      return Traits::getL(m_matrix);
-    }
-
-    /** \returns the permutation matrix P as a transposition sequence.
-      */
-    inline const TranspositionType& transpositionsP() const
-    {
-      eigen_assert(m_isInitialized && "LDLT is not initialized.");
-      return m_transpositions;
-    }
-
-    /** \returns the coefficients of the diagonal matrix D */
-    inline Diagonal<const MatrixType> vectorD() const
-    {
-      eigen_assert(m_isInitialized && "LDLT is not initialized.");
-      return m_matrix.diagonal();
-    }
-
-    /** \returns true if the matrix is positive (semidefinite) */
-    inline bool isPositive() const
-    {
-      eigen_assert(m_isInitialized && "LDLT is not initialized.");
-      return m_sign == internal::PositiveSemiDef || m_sign == internal::ZeroSign;
-    }
-
-    /** \returns true if the matrix is negative (semidefinite) */
-    inline bool isNegative(void) const
-    {
-      eigen_assert(m_isInitialized && "LDLT is not initialized.");
-      return m_sign == internal::NegativeSemiDef || m_sign == internal::ZeroSign;
-    }
-
-    /** \returns a solution x of \f$ A x = b \f$ using the current decomposition of A.
-      *
-      * This function also supports in-place solves using the syntax <tt>x = decompositionObject.solve(x)</tt> .
-      *
-      * \note_about_checking_solutions
-      *
-      * More precisely, this method solves \f$ A x = b \f$ using the decomposition \f$ A = P^T L D L^* P \f$
-      * by solving the systems \f$ P^T y_1 = b \f$, \f$ L y_2 = y_1 \f$, \f$ D y_3 = y_2 \f$,
-      * \f$ L^* y_4 = y_3 \f$ and \f$ P x = y_4 \f$ in succession. If the matrix \f$ A \f$ is singular, then
-      * \f$ D \f$ will also be singular (all the other matrices are invertible). In that case, the
-      * least-square solution of \f$ D y_3 = y_2 \f$ is computed. This does not mean that this function
-      * computes the least-square solution of \f$ A x = b \f$ is \f$ A \f$ is singular.
-      *
-      * \sa MatrixBase::ldlt(), SelfAdjointView::ldlt()
-      */
-    template<typename Rhs>
-    inline const Solve<LDLT, Rhs>
-    solve(const MatrixBase<Rhs>& b) const
-    {
-      eigen_assert(m_isInitialized && "LDLT is not initialized.");
-      eigen_assert(m_matrix.rows()==b.rows()
-                && "LDLT::solve(): invalid number of rows of the right hand side matrix b");
-      return Solve<LDLT, Rhs>(*this, b.derived());
-    }
-
-    template<typename Derived>
-    bool solveInPlace(MatrixBase<Derived> &bAndX) const;
-
-    template<typename InputType>
-    LDLT& compute(const EigenBase<InputType>& matrix);
-
-    /** \returns an estimate of the reciprocal condition number of the matrix of
-     *  which \c *this is the LDLT decomposition.
-     */
-    RealScalar rcond() const
-    {
-      eigen_assert(m_isInitialized && "LDLT is not initialized.");
-      return internal::rcond_estimate_helper(m_l1_norm, *this);
-    }
-
-    template <typename Derived>
-    LDLT& rankUpdate(const MatrixBase<Derived>& w, const RealScalar& alpha=1);
-
-    /** \returns the internal LDLT decomposition matrix
-      *
-      * TODO: document the storage layout
-      */
-    inline const MatrixType& matrixLDLT() const
-    {
-      eigen_assert(m_isInitialized && "LDLT is not initialized.");
-      return m_matrix;
-    }
-
-    MatrixType reconstructedMatrix() const;
-
-    /** \returns the adjoint of \c *this, that is, a const reference to the decomposition itself as the underlying matrix is self-adjoint.
-      *
-      * This method is provided for compatibility with other matrix decompositions, thus enabling generic code such as:
-      * \code x = decomposition.adjoint().solve(b) \endcode
-      */
-    const LDLT& adjoint() const { return *this; };
-
-    inline Index rows() const { return m_matrix.rows(); }
-    inline Index cols() const { return m_matrix.cols(); }
-
-    /** \brief Reports whether previous computation was successful.
-      *
-      * \returns \c Success if computation was succesful,
-      *          \c NumericalIssue if the factorization failed because of a zero pivot.
-      */
-    ComputationInfo info() const
-    {
-      eigen_assert(m_isInitialized && "LDLT is not initialized.");
-      return m_info;
-    }
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    template<typename RhsType, typename DstType>
-    EIGEN_DEVICE_FUNC
-    void _solve_impl(const RhsType &rhs, DstType &dst) const;
-    #endif
-
-  protected:
-
-    static void check_template_parameters()
-    {
-      EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
-    }
-
-    /** \internal
-      * Used to compute and store the Cholesky decomposition A = L D L^* = U^* D U.
-      * The strict upper part is used during the decomposition, the strict lower
-      * part correspond to the coefficients of L (its diagonal is equal to 1 and
-      * is not stored), and the diagonal entries correspond to D.
-      */
-    MatrixType m_matrix;
-    RealScalar m_l1_norm;
-    TranspositionType m_transpositions;
-    TmpMatrixType m_temporary;
-    internal::SignMatrix m_sign;
-    bool m_isInitialized;
-    ComputationInfo m_info;
-};
-
-namespace internal {
-
-template<int UpLo> struct ldlt_inplace;
-
-template<> struct ldlt_inplace<Lower>
-{
-  template<typename MatrixType, typename TranspositionType, typename Workspace>
-  static bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, SignMatrix& sign)
-  {
-    using std::abs;
-    typedef typename MatrixType::Scalar Scalar;
-    typedef typename MatrixType::RealScalar RealScalar;
-    typedef typename TranspositionType::StorageIndex IndexType;
-    eigen_assert(mat.rows()==mat.cols());
-    const Index size = mat.rows();
-    bool found_zero_pivot = false;
-    bool ret = true;
-
-    if (size <= 1)
-    {
-      transpositions.setIdentity();
-      if(size==0) sign = ZeroSign;
-      else if (numext::real(mat.coeff(0,0)) > static_cast<RealScalar>(0) ) sign = PositiveSemiDef;
-      else if (numext::real(mat.coeff(0,0)) < static_cast<RealScalar>(0)) sign = NegativeSemiDef;
-      else sign = ZeroSign;
-      return true;
-    }
-
-    for (Index k = 0; k < size; ++k)
-    {
-      // Find largest diagonal element
-      Index index_of_biggest_in_corner;
-      mat.diagonal().tail(size-k).cwiseAbs().maxCoeff(&index_of_biggest_in_corner);
-      index_of_biggest_in_corner += k;
-
-      transpositions.coeffRef(k) = IndexType(index_of_biggest_in_corner);
-      if(k != index_of_biggest_in_corner)
-      {
-        // apply the transposition while taking care to consider only
-        // the lower triangular part
-        Index s = size-index_of_biggest_in_corner-1; // trailing size after the biggest element
-        mat.row(k).head(k).swap(mat.row(index_of_biggest_in_corner).head(k));
-        mat.col(k).tail(s).swap(mat.col(index_of_biggest_in_corner).tail(s));
-        std::swap(mat.coeffRef(k,k),mat.coeffRef(index_of_biggest_in_corner,index_of_biggest_in_corner));
-        for(Index i=k+1;i<index_of_biggest_in_corner;++i)
-        {
-          Scalar tmp = mat.coeffRef(i,k);
-          mat.coeffRef(i,k) = numext::conj(mat.coeffRef(index_of_biggest_in_corner,i));
-          mat.coeffRef(index_of_biggest_in_corner,i) = numext::conj(tmp);
-        }
-        if(NumTraits<Scalar>::IsComplex)
-          mat.coeffRef(index_of_biggest_in_corner,k) = numext::conj(mat.coeff(index_of_biggest_in_corner,k));
-      }
-
-      // partition the matrix:
-      //       A00 |  -  |  -
-      // lu  = A10 | A11 |  -
-      //       A20 | A21 | A22
-      Index rs = size - k - 1;
-      Block<MatrixType,Dynamic,1> A21(mat,k+1,k,rs,1);
-      Block<MatrixType,1,Dynamic> A10(mat,k,0,1,k);
-      Block<MatrixType,Dynamic,Dynamic> A20(mat,k+1,0,rs,k);
-
-      if(k>0)
-      {
-        temp.head(k) = mat.diagonal().real().head(k).asDiagonal() * A10.adjoint();
-        mat.coeffRef(k,k) -= (A10 * temp.head(k)).value();
-        if(rs>0)
-          A21.noalias() -= A20 * temp.head(k);
-      }
-
-      // In some previous versions of Eigen (e.g., 3.2.1), the scaling was omitted if the pivot
-      // was smaller than the cutoff value. However, since LDLT is not rank-revealing
-      // we should only make sure that we do not introduce INF or NaN values.
-      // Remark that LAPACK also uses 0 as the cutoff value.
-      RealScalar realAkk = numext::real(mat.coeffRef(k,k));
-      bool pivot_is_valid = (abs(realAkk) > RealScalar(0));
-
-      if(k==0 && !pivot_is_valid)
-      {
-        // The entire diagonal is zero, there is nothing more to do
-        // except filling the transpositions, and checking whether the matrix is zero.
-        sign = ZeroSign;
-        for(Index j = 0; j<size; ++j)
-        {
-          transpositions.coeffRef(j) = IndexType(j);
-          ret = ret && (mat.col(j).tail(size-j-1).array()==Scalar(0)).all();
-        }
-        return ret;
-      }
-
-      if((rs>0) && pivot_is_valid)
-        A21 /= realAkk;
-      else if(rs>0)
-        ret = ret && (A21.array()==Scalar(0)).all();
-
-      if(found_zero_pivot && pivot_is_valid) ret = false; // factorization failed
-      else if(!pivot_is_valid) found_zero_pivot = true;
-
-      if (sign == PositiveSemiDef) {
-        if (realAkk < static_cast<RealScalar>(0)) sign = Indefinite;
-      } else if (sign == NegativeSemiDef) {
-        if (realAkk > static_cast<RealScalar>(0)) sign = Indefinite;
-      } else if (sign == ZeroSign) {
-        if (realAkk > static_cast<RealScalar>(0)) sign = PositiveSemiDef;
-        else if (realAkk < static_cast<RealScalar>(0)) sign = NegativeSemiDef;
-      }
-    }
-
-    return ret;
-  }
-
-  // Reference for the algorithm: Davis and Hager, "Multiple Rank
-  // Modifications of a Sparse Cholesky Factorization" (Algorithm 1)
-  // Trivial rearrangements of their computations (Timothy E. Holy)
-  // allow their algorithm to work for rank-1 updates even if the
-  // original matrix is not of full rank.
-  // Here only rank-1 updates are implemented, to reduce the
-  // requirement for intermediate storage and improve accuracy
-  template<typename MatrixType, typename WDerived>
-  static bool updateInPlace(MatrixType& mat, MatrixBase<WDerived>& w, const typename MatrixType::RealScalar& sigma=1)
-  {
-    using numext::isfinite;
-    typedef typename MatrixType::Scalar Scalar;
-    typedef typename MatrixType::RealScalar RealScalar;
-
-    const Index size = mat.rows();
-    eigen_assert(mat.cols() == size && w.size()==size);
-
-    RealScalar alpha = 1;
-
-    // Apply the update
-    for (Index j = 0; j < size; j++)
-    {
-      // Check for termination due to an original decomposition of low-rank
-      if (!(isfinite)(alpha))
-        break;
-
-      // Update the diagonal terms
-      RealScalar dj = numext::real(mat.coeff(j,j));
-      Scalar wj = w.coeff(j);
-      RealScalar swj2 = sigma*numext::abs2(wj);
-      RealScalar gamma = dj*alpha + swj2;
-
-      mat.coeffRef(j,j) += swj2/alpha;
-      alpha += swj2/dj;
-
-
-      // Update the terms of L
-      Index rs = size-j-1;
-      w.tail(rs) -= wj * mat.col(j).tail(rs);
-      if(gamma != 0)
-        mat.col(j).tail(rs) += (sigma*numext::conj(wj)/gamma)*w.tail(rs);
-    }
-    return true;
-  }
-
-  template<typename MatrixType, typename TranspositionType, typename Workspace, typename WType>
-  static bool update(MatrixType& mat, const TranspositionType& transpositions, Workspace& tmp, const WType& w, const typename MatrixType::RealScalar& sigma=1)
-  {
-    // Apply the permutation to the input w
-    tmp = transpositions * w;
-
-    return ldlt_inplace<Lower>::updateInPlace(mat,tmp,sigma);
-  }
-};
-
-template<> struct ldlt_inplace<Upper>
-{
-  template<typename MatrixType, typename TranspositionType, typename Workspace>
-  static EIGEN_STRONG_INLINE bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, SignMatrix& sign)
-  {
-    Transpose<MatrixType> matt(mat);
-    return ldlt_inplace<Lower>::unblocked(matt, transpositions, temp, sign);
-  }
-
-  template<typename MatrixType, typename TranspositionType, typename Workspace, typename WType>
-  static EIGEN_STRONG_INLINE bool update(MatrixType& mat, TranspositionType& transpositions, Workspace& tmp, WType& w, const typename MatrixType::RealScalar& sigma=1)
-  {
-    Transpose<MatrixType> matt(mat);
-    return ldlt_inplace<Lower>::update(matt, transpositions, tmp, w.conjugate(), sigma);
-  }
-};
-
-template<typename MatrixType> struct LDLT_Traits<MatrixType,Lower>
-{
-  typedef const TriangularView<const MatrixType, UnitLower> MatrixL;
-  typedef const TriangularView<const typename MatrixType::AdjointReturnType, UnitUpper> MatrixU;
-  static inline MatrixL getL(const MatrixType& m) { return MatrixL(m); }
-  static inline MatrixU getU(const MatrixType& m) { return MatrixU(m.adjoint()); }
-};
-
-template<typename MatrixType> struct LDLT_Traits<MatrixType,Upper>
-{
-  typedef const TriangularView<const typename MatrixType::AdjointReturnType, UnitLower> MatrixL;
-  typedef const TriangularView<const MatrixType, UnitUpper> MatrixU;
-  static inline MatrixL getL(const MatrixType& m) { return MatrixL(m.adjoint()); }
-  static inline MatrixU getU(const MatrixType& m) { return MatrixU(m); }
-};
-
-} // end namespace internal
-
-/** Compute / recompute the LDLT decomposition A = L D L^* = U^* D U of \a matrix
-  */
-template<typename MatrixType, int _UpLo>
-template<typename InputType>
-LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::compute(const EigenBase<InputType>& a)
-{
-  check_template_parameters();
-
-  eigen_assert(a.rows()==a.cols());
-  const Index size = a.rows();
-
-  m_matrix = a.derived();
-
-  // Compute matrix L1 norm = max abs column sum.
-  m_l1_norm = RealScalar(0);
-  // TODO move this code to SelfAdjointView
-  for (Index col = 0; col < size; ++col) {
-    RealScalar abs_col_sum;
-    if (_UpLo == Lower)
-      abs_col_sum = m_matrix.col(col).tail(size - col).template lpNorm<1>() + m_matrix.row(col).head(col).template lpNorm<1>();
-    else
-      abs_col_sum = m_matrix.col(col).head(col).template lpNorm<1>() + m_matrix.row(col).tail(size - col).template lpNorm<1>();
-    if (abs_col_sum > m_l1_norm)
-      m_l1_norm = abs_col_sum;
-  }
-
-  m_transpositions.resize(size);
-  m_isInitialized = false;
-  m_temporary.resize(size);
-  m_sign = internal::ZeroSign;
-
-  m_info = internal::ldlt_inplace<UpLo>::unblocked(m_matrix, m_transpositions, m_temporary, m_sign) ? Success : NumericalIssue;
-
-  m_isInitialized = true;
-  return *this;
-}
-
-/** Update the LDLT decomposition:  given A = L D L^T, efficiently compute the decomposition of A + sigma w w^T.
- * \param w a vector to be incorporated into the decomposition.
- * \param sigma a scalar, +1 for updates and -1 for "downdates," which correspond to removing previously-added column vectors. Optional; default value is +1.
- * \sa setZero()
-  */
-template<typename MatrixType, int _UpLo>
-template<typename Derived>
-LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::rankUpdate(const MatrixBase<Derived>& w, const typename LDLT<MatrixType,_UpLo>::RealScalar& sigma)
-{
-  typedef typename TranspositionType::StorageIndex IndexType;
-  const Index size = w.rows();
-  if (m_isInitialized)
-  {
-    eigen_assert(m_matrix.rows()==size);
-  }
-  else
-  {
-    m_matrix.resize(size,size);
-    m_matrix.setZero();
-    m_transpositions.resize(size);
-    for (Index i = 0; i < size; i++)
-      m_transpositions.coeffRef(i) = IndexType(i);
-    m_temporary.resize(size);
-    m_sign = sigma>=0 ? internal::PositiveSemiDef : internal::NegativeSemiDef;
-    m_isInitialized = true;
-  }
-
-  internal::ldlt_inplace<UpLo>::update(m_matrix, m_transpositions, m_temporary, w, sigma);
-
-  return *this;
-}
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-template<typename _MatrixType, int _UpLo>
-template<typename RhsType, typename DstType>
-void LDLT<_MatrixType,_UpLo>::_solve_impl(const RhsType &rhs, DstType &dst) const
-{
-  eigen_assert(rhs.rows() == rows());
-  // dst = P b
-  dst = m_transpositions * rhs;
-
-  // dst = L^-1 (P b)
-  matrixL().solveInPlace(dst);
-
-  // dst = D^-1 (L^-1 P b)
-  // more precisely, use pseudo-inverse of D (see bug 241)
-  using std::abs;
-  const typename Diagonal<const MatrixType>::RealReturnType vecD(vectorD());
-  // In some previous versions, tolerance was set to the max of 1/highest (or rather numeric_limits::min())
-  // and the maximal diagonal entry * epsilon as motivated by LAPACK's xGELSS:
-  // RealScalar tolerance = numext::maxi(vecD.array().abs().maxCoeff() * NumTraits<RealScalar>::epsilon(),RealScalar(1) / NumTraits<RealScalar>::highest());
-  // However, LDLT is not rank revealing, and so adjusting the tolerance wrt to the highest
-  // diagonal element is not well justified and leads to numerical issues in some cases.
-  // Moreover, Lapack's xSYTRS routines use 0 for the tolerance.
-  // Using numeric_limits::min() gives us more robustness to denormals.
-  RealScalar tolerance = (std::numeric_limits<RealScalar>::min)();
-
-  for (Index i = 0; i < vecD.size(); ++i)
-  {
-    if(abs(vecD(i)) > tolerance)
-      dst.row(i) /= vecD(i);
-    else
-      dst.row(i).setZero();
-  }
-
-  // dst = L^-T (D^-1 L^-1 P b)
-  matrixU().solveInPlace(dst);
-
-  // dst = P^-1 (L^-T D^-1 L^-1 P b) = A^-1 b
-  dst = m_transpositions.transpose() * dst;
-}
-#endif
-
-/** \internal use x = ldlt_object.solve(x);
-  *
-  * This is the \em in-place version of solve().
-  *
-  * \param bAndX represents both the right-hand side matrix b and result x.
-  *
-  * \returns true always! If you need to check for existence of solutions, use another decomposition like LU, QR, or SVD.
-  *
-  * This version avoids a copy when the right hand side matrix b is not
-  * needed anymore.
-  *
-  * \sa LDLT::solve(), MatrixBase::ldlt()
-  */
-template<typename MatrixType,int _UpLo>
-template<typename Derived>
-bool LDLT<MatrixType,_UpLo>::solveInPlace(MatrixBase<Derived> &bAndX) const
-{
-  eigen_assert(m_isInitialized && "LDLT is not initialized.");
-  eigen_assert(m_matrix.rows() == bAndX.rows());
-
-  bAndX = this->solve(bAndX);
-
-  return true;
-}
-
-/** \returns the matrix represented by the decomposition,
- * i.e., it returns the product: P^T L D L^* P.
- * This function is provided for debug purpose. */
-template<typename MatrixType, int _UpLo>
-MatrixType LDLT<MatrixType,_UpLo>::reconstructedMatrix() const
-{
-  eigen_assert(m_isInitialized && "LDLT is not initialized.");
-  const Index size = m_matrix.rows();
-  MatrixType res(size,size);
-
-  // P
-  res.setIdentity();
-  res = transpositionsP() * res;
-  // L^* P
-  res = matrixU() * res;
-  // D(L^*P)
-  res = vectorD().real().asDiagonal() * res;
-  // L(DL^*P)
-  res = matrixL() * res;
-  // P^T (LDL^*P)
-  res = transpositionsP().transpose() * res;
-
-  return res;
-}
-
-/** \cholesky_module
-  * \returns the Cholesky decomposition with full pivoting without square root of \c *this
-  * \sa MatrixBase::ldlt()
-  */
-template<typename MatrixType, unsigned int UpLo>
-inline const LDLT<typename SelfAdjointView<MatrixType, UpLo>::PlainObject, UpLo>
-SelfAdjointView<MatrixType, UpLo>::ldlt() const
-{
-  return LDLT<PlainObject,UpLo>(m_matrix);
-}
-
-/** \cholesky_module
-  * \returns the Cholesky decomposition with full pivoting without square root of \c *this
-  * \sa SelfAdjointView::ldlt()
-  */
-template<typename Derived>
-inline const LDLT<typename MatrixBase<Derived>::PlainObject>
-MatrixBase<Derived>::ldlt() const
-{
-  return LDLT<PlainObject>(derived());
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_LDLT_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Cholesky/LLT.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Cholesky/LLT.h
deleted file mode 100644
index e1624d2..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Cholesky/LLT.h
+++ /dev/null
@@ -1,542 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_LLT_H
-#define EIGEN_LLT_H
-
-namespace Eigen {
-
-namespace internal{
-template<typename MatrixType, int UpLo> struct LLT_Traits;
-}
-
-/** \ingroup Cholesky_Module
-  *
-  * \class LLT
-  *
-  * \brief Standard Cholesky decomposition (LL^T) of a matrix and associated features
-  *
-  * \tparam _MatrixType the type of the matrix of which we are computing the LL^T Cholesky decomposition
-  * \tparam _UpLo the triangular part that will be used for the decompositon: Lower (default) or Upper.
-  *               The other triangular part won't be read.
-  *
-  * This class performs a LL^T Cholesky decomposition of a symmetric, positive definite
-  * matrix A such that A = LL^* = U^*U, where L is lower triangular.
-  *
-  * While the Cholesky decomposition is particularly useful to solve selfadjoint problems like  D^*D x = b,
-  * for that purpose, we recommend the Cholesky decomposition without square root which is more stable
-  * and even faster. Nevertheless, this standard Cholesky decomposition remains useful in many other
-  * situations like generalised eigen problems with hermitian matrices.
-  *
-  * Remember that Cholesky decompositions are not rank-revealing. This LLT decomposition is only stable on positive definite matrices,
-  * use LDLT instead for the semidefinite case. Also, do not use a Cholesky decomposition to determine whether a system of equations
-  * has a solution.
-  *
-  * Example: \include LLT_example.cpp
-  * Output: \verbinclude LLT_example.out
-  *
-  * \b Performance: for best performance, it is recommended to use a column-major storage format
-  * with the Lower triangular part (the default), or, equivalently, a row-major storage format
-  * with the Upper triangular part. Otherwise, you might get a 20% slowdown for the full factorization
-  * step, and rank-updates can be up to 3 times slower.
-  *
-  * This class supports the \link InplaceDecomposition inplace decomposition \endlink mechanism.
-  *
-  * Note that during the decomposition, only the lower (or upper, as defined by _UpLo) triangular part of A is considered.
-  * Therefore, the strict lower part does not have to store correct values.
-  *
-  * \sa MatrixBase::llt(), SelfAdjointView::llt(), class LDLT
-  */
-template<typename _MatrixType, int _UpLo> class LLT
-{
-  public:
-    typedef _MatrixType MatrixType;
-    enum {
-      RowsAtCompileTime = MatrixType::RowsAtCompileTime,
-      ColsAtCompileTime = MatrixType::ColsAtCompileTime,
-      MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
-    };
-    typedef typename MatrixType::Scalar Scalar;
-    typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
-    typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
-    typedef typename MatrixType::StorageIndex StorageIndex;
-
-    enum {
-      PacketSize = internal::packet_traits<Scalar>::size,
-      AlignmentMask = int(PacketSize)-1,
-      UpLo = _UpLo
-    };
-
-    typedef internal::LLT_Traits<MatrixType,UpLo> Traits;
-
-    /**
-      * \brief Default Constructor.
-      *
-      * The default constructor is useful in cases in which the user intends to
-      * perform decompositions via LLT::compute(const MatrixType&).
-      */
-    LLT() : m_matrix(), m_isInitialized(false) {}
-
-    /** \brief Default Constructor with memory preallocation
-      *
-      * Like the default constructor but with preallocation of the internal data
-      * according to the specified problem \a size.
-      * \sa LLT()
-      */
-    explicit LLT(Index size) : m_matrix(size, size),
-                    m_isInitialized(false) {}
-
-    template<typename InputType>
-    explicit LLT(const EigenBase<InputType>& matrix)
-      : m_matrix(matrix.rows(), matrix.cols()),
-        m_isInitialized(false)
-    {
-      compute(matrix.derived());
-    }
-
-    /** \brief Constructs a LDLT factorization from a given matrix
-      *
-      * This overloaded constructor is provided for \link InplaceDecomposition inplace decomposition \endlink when
-      * \c MatrixType is a Eigen::Ref.
-      *
-      * \sa LLT(const EigenBase&)
-      */
-    template<typename InputType>
-    explicit LLT(EigenBase<InputType>& matrix)
-      : m_matrix(matrix.derived()),
-        m_isInitialized(false)
-    {
-      compute(matrix.derived());
-    }
-
-    /** \returns a view of the upper triangular matrix U */
-    inline typename Traits::MatrixU matrixU() const
-    {
-      eigen_assert(m_isInitialized && "LLT is not initialized.");
-      return Traits::getU(m_matrix);
-    }
-
-    /** \returns a view of the lower triangular matrix L */
-    inline typename Traits::MatrixL matrixL() const
-    {
-      eigen_assert(m_isInitialized && "LLT is not initialized.");
-      return Traits::getL(m_matrix);
-    }
-
-    /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A.
-      *
-      * Since this LLT class assumes anyway that the matrix A is invertible, the solution
-      * theoretically exists and is unique regardless of b.
-      *
-      * Example: \include LLT_solve.cpp
-      * Output: \verbinclude LLT_solve.out
-      *
-      * \sa solveInPlace(), MatrixBase::llt(), SelfAdjointView::llt()
-      */
-    template<typename Rhs>
-    inline const Solve<LLT, Rhs>
-    solve(const MatrixBase<Rhs>& b) const
-    {
-      eigen_assert(m_isInitialized && "LLT is not initialized.");
-      eigen_assert(m_matrix.rows()==b.rows()
-                && "LLT::solve(): invalid number of rows of the right hand side matrix b");
-      return Solve<LLT, Rhs>(*this, b.derived());
-    }
-
-    template<typename Derived>
-    void solveInPlace(const MatrixBase<Derived> &bAndX) const;
-
-    template<typename InputType>
-    LLT& compute(const EigenBase<InputType>& matrix);
-
-    /** \returns an estimate of the reciprocal condition number of the matrix of
-      *  which \c *this is the Cholesky decomposition.
-      */
-    RealScalar rcond() const
-    {
-      eigen_assert(m_isInitialized && "LLT is not initialized.");
-      eigen_assert(m_info == Success && "LLT failed because matrix appears to be negative");
-      return internal::rcond_estimate_helper(m_l1_norm, *this);
-    }
-
-    /** \returns the LLT decomposition matrix
-      *
-      * TODO: document the storage layout
-      */
-    inline const MatrixType& matrixLLT() const
-    {
-      eigen_assert(m_isInitialized && "LLT is not initialized.");
-      return m_matrix;
-    }
-
-    MatrixType reconstructedMatrix() const;
-
-
-    /** \brief Reports whether previous computation was successful.
-      *
-      * \returns \c Success if computation was succesful,
-      *          \c NumericalIssue if the matrix.appears not to be positive definite.
-      */
-    ComputationInfo info() const
-    {
-      eigen_assert(m_isInitialized && "LLT is not initialized.");
-      return m_info;
-    }
-
-    /** \returns the adjoint of \c *this, that is, a const reference to the decomposition itself as the underlying matrix is self-adjoint.
-      *
-      * This method is provided for compatibility with other matrix decompositions, thus enabling generic code such as:
-      * \code x = decomposition.adjoint().solve(b) \endcode
-      */
-    const LLT& adjoint() const { return *this; };
-
-    inline Index rows() const { return m_matrix.rows(); }
-    inline Index cols() const { return m_matrix.cols(); }
-
-    template<typename VectorType>
-    LLT rankUpdate(const VectorType& vec, const RealScalar& sigma = 1);
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    template<typename RhsType, typename DstType>
-    EIGEN_DEVICE_FUNC
-    void _solve_impl(const RhsType &rhs, DstType &dst) const;
-    #endif
-
-  protected:
-
-    static void check_template_parameters()
-    {
-      EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
-    }
-
-    /** \internal
-      * Used to compute and store L
-      * The strict upper part is not used and even not initialized.
-      */
-    MatrixType m_matrix;
-    RealScalar m_l1_norm;
-    bool m_isInitialized;
-    ComputationInfo m_info;
-};
-
-namespace internal {
-
-template<typename Scalar, int UpLo> struct llt_inplace;
-
-template<typename MatrixType, typename VectorType>
-static Index llt_rank_update_lower(MatrixType& mat, const VectorType& vec, const typename MatrixType::RealScalar& sigma)
-{
-  using std::sqrt;
-  typedef typename MatrixType::Scalar Scalar;
-  typedef typename MatrixType::RealScalar RealScalar;
-  typedef typename MatrixType::ColXpr ColXpr;
-  typedef typename internal::remove_all<ColXpr>::type ColXprCleaned;
-  typedef typename ColXprCleaned::SegmentReturnType ColXprSegment;
-  typedef Matrix<Scalar,Dynamic,1> TempVectorType;
-  typedef typename TempVectorType::SegmentReturnType TempVecSegment;
-
-  Index n = mat.cols();
-  eigen_assert(mat.rows()==n && vec.size()==n);
-
-  TempVectorType temp;
-
-  if(sigma>0)
-  {
-    // This version is based on Givens rotations.
-    // It is faster than the other one below, but only works for updates,
-    // i.e., for sigma > 0
-    temp = sqrt(sigma) * vec;
-
-    for(Index i=0; i<n; ++i)
-    {
-      JacobiRotation<Scalar> g;
-      g.makeGivens(mat(i,i), -temp(i), &mat(i,i));
-
-      Index rs = n-i-1;
-      if(rs>0)
-      {
-        ColXprSegment x(mat.col(i).tail(rs));
-        TempVecSegment y(temp.tail(rs));
-        apply_rotation_in_the_plane(x, y, g);
-      }
-    }
-  }
-  else
-  {
-    temp = vec;
-    RealScalar beta = 1;
-    for(Index j=0; j<n; ++j)
-    {
-      RealScalar Ljj = numext::real(mat.coeff(j,j));
-      RealScalar dj = numext::abs2(Ljj);
-      Scalar wj = temp.coeff(j);
-      RealScalar swj2 = sigma*numext::abs2(wj);
-      RealScalar gamma = dj*beta + swj2;
-
-      RealScalar x = dj + swj2/beta;
-      if (x<=RealScalar(0))
-        return j;
-      RealScalar nLjj = sqrt(x);
-      mat.coeffRef(j,j) = nLjj;
-      beta += swj2/dj;
-
-      // Update the terms of L
-      Index rs = n-j-1;
-      if(rs)
-      {
-        temp.tail(rs) -= (wj/Ljj) * mat.col(j).tail(rs);
-        if(gamma != 0)
-          mat.col(j).tail(rs) = (nLjj/Ljj) * mat.col(j).tail(rs) + (nLjj * sigma*numext::conj(wj)/gamma)*temp.tail(rs);
-      }
-    }
-  }
-  return -1;
-}
-
-template<typename Scalar> struct llt_inplace<Scalar, Lower>
-{
-  typedef typename NumTraits<Scalar>::Real RealScalar;
-  template<typename MatrixType>
-  static Index unblocked(MatrixType& mat)
-  {
-    using std::sqrt;
-
-    eigen_assert(mat.rows()==mat.cols());
-    const Index size = mat.rows();
-    for(Index k = 0; k < size; ++k)
-    {
-      Index rs = size-k-1; // remaining size
-
-      Block<MatrixType,Dynamic,1> A21(mat,k+1,k,rs,1);
-      Block<MatrixType,1,Dynamic> A10(mat,k,0,1,k);
-      Block<MatrixType,Dynamic,Dynamic> A20(mat,k+1,0,rs,k);
-
-      RealScalar x = numext::real(mat.coeff(k,k));
-      if (k>0) x -= A10.squaredNorm();
-      if (x<=RealScalar(0))
-        return k;
-      mat.coeffRef(k,k) = x = sqrt(x);
-      if (k>0 && rs>0) A21.noalias() -= A20 * A10.adjoint();
-      if (rs>0) A21 /= x;
-    }
-    return -1;
-  }
-
-  template<typename MatrixType>
-  static Index blocked(MatrixType& m)
-  {
-    eigen_assert(m.rows()==m.cols());
-    Index size = m.rows();
-    if(size<32)
-      return unblocked(m);
-
-    Index blockSize = size/8;
-    blockSize = (blockSize/16)*16;
-    blockSize = (std::min)((std::max)(blockSize,Index(8)), Index(128));
-
-    for (Index k=0; k<size; k+=blockSize)
-    {
-      // partition the matrix:
-      //       A00 |  -  |  -
-      // lu  = A10 | A11 |  -
-      //       A20 | A21 | A22
-      Index bs = (std::min)(blockSize, size-k);
-      Index rs = size - k - bs;
-      Block<MatrixType,Dynamic,Dynamic> A11(m,k,   k,   bs,bs);
-      Block<MatrixType,Dynamic,Dynamic> A21(m,k+bs,k,   rs,bs);
-      Block<MatrixType,Dynamic,Dynamic> A22(m,k+bs,k+bs,rs,rs);
-
-      Index ret;
-      if((ret=unblocked(A11))>=0) return k+ret;
-      if(rs>0) A11.adjoint().template triangularView<Upper>().template solveInPlace<OnTheRight>(A21);
-      if(rs>0) A22.template selfadjointView<Lower>().rankUpdate(A21,typename NumTraits<RealScalar>::Literal(-1)); // bottleneck
-    }
-    return -1;
-  }
-
-  template<typename MatrixType, typename VectorType>
-  static Index rankUpdate(MatrixType& mat, const VectorType& vec, const RealScalar& sigma)
-  {
-    return Eigen::internal::llt_rank_update_lower(mat, vec, sigma);
-  }
-};
-
-template<typename Scalar> struct llt_inplace<Scalar, Upper>
-{
-  typedef typename NumTraits<Scalar>::Real RealScalar;
-
-  template<typename MatrixType>
-  static EIGEN_STRONG_INLINE Index unblocked(MatrixType& mat)
-  {
-    Transpose<MatrixType> matt(mat);
-    return llt_inplace<Scalar, Lower>::unblocked(matt);
-  }
-  template<typename MatrixType>
-  static EIGEN_STRONG_INLINE Index blocked(MatrixType& mat)
-  {
-    Transpose<MatrixType> matt(mat);
-    return llt_inplace<Scalar, Lower>::blocked(matt);
-  }
-  template<typename MatrixType, typename VectorType>
-  static Index rankUpdate(MatrixType& mat, const VectorType& vec, const RealScalar& sigma)
-  {
-    Transpose<MatrixType> matt(mat);
-    return llt_inplace<Scalar, Lower>::rankUpdate(matt, vec.conjugate(), sigma);
-  }
-};
-
-template<typename MatrixType> struct LLT_Traits<MatrixType,Lower>
-{
-  typedef const TriangularView<const MatrixType, Lower> MatrixL;
-  typedef const TriangularView<const typename MatrixType::AdjointReturnType, Upper> MatrixU;
-  static inline MatrixL getL(const MatrixType& m) { return MatrixL(m); }
-  static inline MatrixU getU(const MatrixType& m) { return MatrixU(m.adjoint()); }
-  static bool inplace_decomposition(MatrixType& m)
-  { return llt_inplace<typename MatrixType::Scalar, Lower>::blocked(m)==-1; }
-};
-
-template<typename MatrixType> struct LLT_Traits<MatrixType,Upper>
-{
-  typedef const TriangularView<const typename MatrixType::AdjointReturnType, Lower> MatrixL;
-  typedef const TriangularView<const MatrixType, Upper> MatrixU;
-  static inline MatrixL getL(const MatrixType& m) { return MatrixL(m.adjoint()); }
-  static inline MatrixU getU(const MatrixType& m) { return MatrixU(m); }
-  static bool inplace_decomposition(MatrixType& m)
-  { return llt_inplace<typename MatrixType::Scalar, Upper>::blocked(m)==-1; }
-};
-
-} // end namespace internal
-
-/** Computes / recomputes the Cholesky decomposition A = LL^* = U^*U of \a matrix
-  *
-  * \returns a reference to *this
-  *
-  * Example: \include TutorialLinAlgComputeTwice.cpp
-  * Output: \verbinclude TutorialLinAlgComputeTwice.out
-  */
-template<typename MatrixType, int _UpLo>
-template<typename InputType>
-LLT<MatrixType,_UpLo>& LLT<MatrixType,_UpLo>::compute(const EigenBase<InputType>& a)
-{
-  check_template_parameters();
-
-  eigen_assert(a.rows()==a.cols());
-  const Index size = a.rows();
-  m_matrix.resize(size, size);
-  if (!internal::is_same_dense(m_matrix, a.derived()))
-    m_matrix = a.derived();
-
-  // Compute matrix L1 norm = max abs column sum.
-  m_l1_norm = RealScalar(0);
-  // TODO move this code to SelfAdjointView
-  for (Index col = 0; col < size; ++col) {
-    RealScalar abs_col_sum;
-    if (_UpLo == Lower)
-      abs_col_sum = m_matrix.col(col).tail(size - col).template lpNorm<1>() + m_matrix.row(col).head(col).template lpNorm<1>();
-    else
-      abs_col_sum = m_matrix.col(col).head(col).template lpNorm<1>() + m_matrix.row(col).tail(size - col).template lpNorm<1>();
-    if (abs_col_sum > m_l1_norm)
-      m_l1_norm = abs_col_sum;
-  }
-
-  m_isInitialized = true;
-  bool ok = Traits::inplace_decomposition(m_matrix);
-  m_info = ok ? Success : NumericalIssue;
-
-  return *this;
-}
-
-/** Performs a rank one update (or dowdate) of the current decomposition.
-  * If A = LL^* before the rank one update,
-  * then after it we have LL^* = A + sigma * v v^* where \a v must be a vector
-  * of same dimension.
-  */
-template<typename _MatrixType, int _UpLo>
-template<typename VectorType>
-LLT<_MatrixType,_UpLo> LLT<_MatrixType,_UpLo>::rankUpdate(const VectorType& v, const RealScalar& sigma)
-{
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorType);
-  eigen_assert(v.size()==m_matrix.cols());
-  eigen_assert(m_isInitialized);
-  if(internal::llt_inplace<typename MatrixType::Scalar, UpLo>::rankUpdate(m_matrix,v,sigma)>=0)
-    m_info = NumericalIssue;
-  else
-    m_info = Success;
-
-  return *this;
-}
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-template<typename _MatrixType,int _UpLo>
-template<typename RhsType, typename DstType>
-void LLT<_MatrixType,_UpLo>::_solve_impl(const RhsType &rhs, DstType &dst) const
-{
-  dst = rhs;
-  solveInPlace(dst);
-}
-#endif
-
-/** \internal use x = llt_object.solve(x);
-  *
-  * This is the \em in-place version of solve().
-  *
-  * \param bAndX represents both the right-hand side matrix b and result x.
-  *
-  * This version avoids a copy when the right hand side matrix b is not needed anymore.
-  *
-  * \warning The parameter is only marked 'const' to make the C++ compiler accept a temporary expression here.
-  * This function will const_cast it, so constness isn't honored here.
-  *
-  * \sa LLT::solve(), MatrixBase::llt()
-  */
-template<typename MatrixType, int _UpLo>
-template<typename Derived>
-void LLT<MatrixType,_UpLo>::solveInPlace(const MatrixBase<Derived> &bAndX) const
-{
-  eigen_assert(m_isInitialized && "LLT is not initialized.");
-  eigen_assert(m_matrix.rows()==bAndX.rows());
-  matrixL().solveInPlace(bAndX);
-  matrixU().solveInPlace(bAndX);
-}
-
-/** \returns the matrix represented by the decomposition,
- * i.e., it returns the product: L L^*.
- * This function is provided for debug purpose. */
-template<typename MatrixType, int _UpLo>
-MatrixType LLT<MatrixType,_UpLo>::reconstructedMatrix() const
-{
-  eigen_assert(m_isInitialized && "LLT is not initialized.");
-  return matrixL() * matrixL().adjoint().toDenseMatrix();
-}
-
-/** \cholesky_module
-  * \returns the LLT decomposition of \c *this
-  * \sa SelfAdjointView::llt()
-  */
-template<typename Derived>
-inline const LLT<typename MatrixBase<Derived>::PlainObject>
-MatrixBase<Derived>::llt() const
-{
-  return LLT<PlainObject>(derived());
-}
-
-/** \cholesky_module
-  * \returns the LLT decomposition of \c *this
-  * \sa SelfAdjointView::llt()
-  */
-template<typename MatrixType, unsigned int UpLo>
-inline const LLT<typename SelfAdjointView<MatrixType, UpLo>::PlainObject, UpLo>
-SelfAdjointView<MatrixType, UpLo>::llt() const
-{
-  return LLT<PlainObject,UpLo>(m_matrix);
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_LLT_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Array.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Array.h
deleted file mode 100644
index 16770fc..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Array.h
+++ /dev/null
@@ -1,329 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_ARRAY_H
-#define EIGEN_ARRAY_H
-
-namespace Eigen {
-
-namespace internal {
-template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
-struct traits<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > : traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
-{
-  typedef ArrayXpr XprKind;
-  typedef ArrayBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > XprBase;
-};
-}
-
-/** \class Array
-  * \ingroup Core_Module
-  *
-  * \brief General-purpose arrays with easy API for coefficient-wise operations
-  *
-  * The %Array class is very similar to the Matrix class. It provides
-  * general-purpose one- and two-dimensional arrays. The difference between the
-  * %Array and the %Matrix class is primarily in the API: the API for the
-  * %Array class provides easy access to coefficient-wise operations, while the
-  * API for the %Matrix class provides easy access to linear-algebra
-  * operations.
-  *
-  * See documentation of class Matrix for detailed information on the template parameters
-  * storage layout.
-  *
-  * This class can be extended with the help of the plugin mechanism described on the page
-  * \ref TopicCustomizing_Plugins by defining the preprocessor symbol \c EIGEN_ARRAY_PLUGIN.
-  *
-  * \sa \blank \ref TutorialArrayClass, \ref TopicClassHierarchy
-  */
-template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
-class Array
-  : public PlainObjectBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
-{
-  public:
-
-    typedef PlainObjectBase<Array> Base;
-    EIGEN_DENSE_PUBLIC_INTERFACE(Array)
-
-    enum { Options = _Options };
-    typedef typename Base::PlainObject PlainObject;
-
-  protected:
-    template <typename Derived, typename OtherDerived, bool IsVector>
-    friend struct internal::conservative_resize_like_impl;
-
-    using Base::m_storage;
-
-  public:
-
-    using Base::base;
-    using Base::coeff;
-    using Base::coeffRef;
-
-    /**
-      * The usage of
-      *   using Base::operator=;
-      * fails on MSVC. Since the code below is working with GCC and MSVC, we skipped
-      * the usage of 'using'. This should be done only for operator=.
-      */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Array& operator=(const EigenBase<OtherDerived> &other)
-    {
-      return Base::operator=(other);
-    }
-
-    /** Set all the entries to \a value.
-      * \sa DenseBase::setConstant(), DenseBase::fill()
-      */
-    /* This overload is needed because the usage of
-      *   using Base::operator=;
-      * fails on MSVC. Since the code below is working with GCC and MSVC, we skipped
-      * the usage of 'using'. This should be done only for operator=.
-      */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Array& operator=(const Scalar &value)
-    {
-      Base::setConstant(value);
-      return *this;
-    }
-
-    /** Copies the value of the expression \a other into \c *this with automatic resizing.
-      *
-      * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized),
-      * it will be initialized.
-      *
-      * Note that copying a row-vector into a vector (and conversely) is allowed.
-      * The resizing, if any, is then done in the appropriate way so that row-vectors
-      * remain row-vectors and vectors remain vectors.
-      */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Array& operator=(const DenseBase<OtherDerived>& other)
-    {
-      return Base::_set(other);
-    }
-
-    /** This is a special case of the templated operator=. Its purpose is to
-      * prevent a default operator= from hiding the templated operator=.
-      */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Array& operator=(const Array& other)
-    {
-      return Base::_set(other);
-    }
-    
-    /** Default constructor.
-      *
-      * For fixed-size matrices, does nothing.
-      *
-      * For dynamic-size matrices, creates an empty matrix of size 0. Does not allocate any array. Such a matrix
-      * is called a null matrix. This constructor is the unique way to create null matrices: resizing
-      * a matrix to 0 is not supported.
-      *
-      * \sa resize(Index,Index)
-      */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Array() : Base()
-    {
-      Base::_check_template_params();
-      EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
-    }
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-    // FIXME is it still needed ??
-    /** \internal */
-    EIGEN_DEVICE_FUNC
-    Array(internal::constructor_without_unaligned_array_assert)
-      : Base(internal::constructor_without_unaligned_array_assert())
-    {
-      Base::_check_template_params();
-      EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
-    }
-#endif
-
-#if EIGEN_HAS_RVALUE_REFERENCES
-    EIGEN_DEVICE_FUNC
-    Array(Array&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_constructible<Scalar>::value)
-      : Base(std::move(other))
-    {
-      Base::_check_template_params();
-    }
-    EIGEN_DEVICE_FUNC
-    Array& operator=(Array&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_assignable<Scalar>::value)
-    {
-      other.swap(*this);
-      return *this;
-    }
-#endif
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    template<typename T>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE explicit Array(const T& x)
-    {
-      Base::_check_template_params();
-      Base::template _init1<T>(x);
-    }
-
-    template<typename T0, typename T1>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Array(const T0& val0, const T1& val1)
-    {
-      Base::_check_template_params();
-      this->template _init2<T0,T1>(val0, val1);
-    }
-    #else
-    /** \brief Constructs a fixed-sized array initialized with coefficients starting at \a data */
-    EIGEN_DEVICE_FUNC explicit Array(const Scalar *data);
-    /** Constructs a vector or row-vector with given dimension. \only_for_vectors
-      *
-      * Note that this is only useful for dynamic-size vectors. For fixed-size vectors,
-      * it is redundant to pass the dimension here, so it makes more sense to use the default
-      * constructor Array() instead.
-      */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE explicit Array(Index dim);
-    /** constructs an initialized 1x1 Array with the given coefficient */
-    Array(const Scalar& value);
-    /** constructs an uninitialized array with \a rows rows and \a cols columns.
-      *
-      * This is useful for dynamic-size arrays. For fixed-size arrays,
-      * it is redundant to pass these parameters, so one should use the default constructor
-      * Array() instead. */
-    Array(Index rows, Index cols);
-    /** constructs an initialized 2D vector with given coefficients */
-    Array(const Scalar& val0, const Scalar& val1);
-    #endif
-
-    /** constructs an initialized 3D vector with given coefficients */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2)
-    {
-      Base::_check_template_params();
-      EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 3)
-      m_storage.data()[0] = val0;
-      m_storage.data()[1] = val1;
-      m_storage.data()[2] = val2;
-    }
-    /** constructs an initialized 4D vector with given coefficients */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2, const Scalar& val3)
-    {
-      Base::_check_template_params();
-      EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 4)
-      m_storage.data()[0] = val0;
-      m_storage.data()[1] = val1;
-      m_storage.data()[2] = val2;
-      m_storage.data()[3] = val3;
-    }
-
-    /** Copy constructor */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Array(const Array& other)
-            : Base(other)
-    { }
-
-  private:
-    struct PrivateType {};
-  public:
-
-    /** \sa MatrixBase::operator=(const EigenBase<OtherDerived>&) */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Array(const EigenBase<OtherDerived> &other,
-                              typename internal::enable_if<internal::is_convertible<typename OtherDerived::Scalar,Scalar>::value,
-                                                           PrivateType>::type = PrivateType())
-      : Base(other.derived())
-    { }
-
-    EIGEN_DEVICE_FUNC inline Index innerStride() const { return 1; }
-    EIGEN_DEVICE_FUNC inline Index outerStride() const { return this->innerSize(); }
-
-    #ifdef EIGEN_ARRAY_PLUGIN
-    #include EIGEN_ARRAY_PLUGIN
-    #endif
-
-  private:
-
-    template<typename MatrixType, typename OtherDerived, bool SwapPointers>
-    friend struct internal::matrix_swap_impl;
-};
-
-/** \defgroup arraytypedefs Global array typedefs
-  * \ingroup Core_Module
-  *
-  * Eigen defines several typedef shortcuts for most common 1D and 2D array types.
-  *
-  * The general patterns are the following:
-  *
-  * \c ArrayRowsColsType where \c Rows and \c Cols can be \c 2,\c 3,\c 4 for fixed size square matrices or \c X for dynamic size,
-  * and where \c Type can be \c i for integer, \c f for float, \c d for double, \c cf for complex float, \c cd
-  * for complex double.
-  *
-  * For example, \c Array33d is a fixed-size 3x3 array type of doubles, and \c ArrayXXf is a dynamic-size matrix of floats.
-  *
-  * There are also \c ArraySizeType which are self-explanatory. For example, \c Array4cf is
-  * a fixed-size 1D array of 4 complex floats.
-  *
-  * \sa class Array
-  */
-
-#define EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix)   \
-/** \ingroup arraytypedefs */                                    \
-typedef Array<Type, Size, Size> Array##SizeSuffix##SizeSuffix##TypeSuffix;  \
-/** \ingroup arraytypedefs */                                    \
-typedef Array<Type, Size, 1>    Array##SizeSuffix##TypeSuffix;
-
-#define EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, Size)         \
-/** \ingroup arraytypedefs */                                    \
-typedef Array<Type, Size, Dynamic> Array##Size##X##TypeSuffix;  \
-/** \ingroup arraytypedefs */                                    \
-typedef Array<Type, Dynamic, Size> Array##X##Size##TypeSuffix;
-
-#define EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \
-EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 2, 2) \
-EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 3, 3) \
-EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 4, 4) \
-EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, Dynamic, X) \
-EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 2) \
-EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 3) \
-EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 4)
-
-EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(int,                  i)
-EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(float,                f)
-EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(double,               d)
-EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(std::complex<float>,  cf)
-EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(std::complex<double>, cd)
-
-#undef EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES
-#undef EIGEN_MAKE_ARRAY_TYPEDEFS
-
-#undef EIGEN_MAKE_ARRAY_TYPEDEFS_LARGE
-
-#define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \
-using Eigen::Matrix##SizeSuffix##TypeSuffix; \
-using Eigen::Vector##SizeSuffix##TypeSuffix; \
-using Eigen::RowVector##SizeSuffix##TypeSuffix;
-
-#define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(TypeSuffix) \
-EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 2) \
-EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 3) \
-EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 4) \
-EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, X) \
-
-#define EIGEN_USING_ARRAY_TYPEDEFS \
-EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(i) \
-EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(f) \
-EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(d) \
-EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cf) \
-EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cd)
-
-} // end namespace Eigen
-
-#endif // EIGEN_ARRAY_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/ArrayBase.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/ArrayBase.h
deleted file mode 100644
index 3dbc708..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/ArrayBase.h
+++ /dev/null
@@ -1,226 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_ARRAYBASE_H
-#define EIGEN_ARRAYBASE_H
-
-namespace Eigen { 
-
-template<typename ExpressionType> class MatrixWrapper;
-
-/** \class ArrayBase
-  * \ingroup Core_Module
-  *
-  * \brief Base class for all 1D and 2D array, and related expressions
-  *
-  * An array is similar to a dense vector or matrix. While matrices are mathematical
-  * objects with well defined linear algebra operators, an array is just a collection
-  * of scalar values arranged in a one or two dimensionnal fashion. As the main consequence,
-  * all operations applied to an array are performed coefficient wise. Furthermore,
-  * arrays support scalar math functions of the c++ standard library (e.g., std::sin(x)), and convenient
-  * constructors allowing to easily write generic code working for both scalar values
-  * and arrays.
-  *
-  * This class is the base that is inherited by all array expression types.
-  *
-  * \tparam Derived is the derived type, e.g., an array or an expression type.
-  *
-  * This class can be extended with the help of the plugin mechanism described on the page
-  * \ref TopicCustomizing_Plugins by defining the preprocessor symbol \c EIGEN_ARRAYBASE_PLUGIN.
-  *
-  * \sa class MatrixBase, \ref TopicClassHierarchy
-  */
-template<typename Derived> class ArrayBase
-  : public DenseBase<Derived>
-{
-  public:
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-    /** The base class for a given storage type. */
-    typedef ArrayBase StorageBaseType;
-
-    typedef ArrayBase Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl;
-
-    typedef typename internal::traits<Derived>::StorageKind StorageKind;
-    typedef typename internal::traits<Derived>::Scalar Scalar;
-    typedef typename internal::packet_traits<Scalar>::type PacketScalar;
-    typedef typename NumTraits<Scalar>::Real RealScalar;
-
-    typedef DenseBase<Derived> Base;
-    using Base::RowsAtCompileTime;
-    using Base::ColsAtCompileTime;
-    using Base::SizeAtCompileTime;
-    using Base::MaxRowsAtCompileTime;
-    using Base::MaxColsAtCompileTime;
-    using Base::MaxSizeAtCompileTime;
-    using Base::IsVectorAtCompileTime;
-    using Base::Flags;
-    
-    using Base::derived;
-    using Base::const_cast_derived;
-    using Base::rows;
-    using Base::cols;
-    using Base::size;
-    using Base::coeff;
-    using Base::coeffRef;
-    using Base::lazyAssign;
-    using Base::operator=;
-    using Base::operator+=;
-    using Base::operator-=;
-    using Base::operator*=;
-    using Base::operator/=;
-
-    typedef typename Base::CoeffReturnType CoeffReturnType;
-
-#endif // not EIGEN_PARSED_BY_DOXYGEN
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-    typedef typename Base::PlainObject PlainObject;
-
-    /** \internal Represents a matrix with all coefficients equal to one another*/
-    typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,PlainObject> ConstantReturnType;
-#endif // not EIGEN_PARSED_BY_DOXYGEN
-
-#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::ArrayBase
-#define EIGEN_DOC_UNARY_ADDONS(X,Y)
-#   include "../plugins/CommonCwiseUnaryOps.h"
-#   include "../plugins/MatrixCwiseUnaryOps.h"
-#   include "../plugins/ArrayCwiseUnaryOps.h"
-#   include "../plugins/CommonCwiseBinaryOps.h"
-#   include "../plugins/MatrixCwiseBinaryOps.h"
-#   include "../plugins/ArrayCwiseBinaryOps.h"
-#   ifdef EIGEN_ARRAYBASE_PLUGIN
-#     include EIGEN_ARRAYBASE_PLUGIN
-#   endif
-#undef EIGEN_CURRENT_STORAGE_BASE_CLASS
-#undef EIGEN_DOC_UNARY_ADDONS
-
-    /** Special case of the template operator=, in order to prevent the compiler
-      * from generating a default operator= (issue hit with g++ 4.1)
-      */
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-    Derived& operator=(const ArrayBase& other)
-    {
-      internal::call_assignment(derived(), other.derived());
-      return derived();
-    }
-    
-    /** Set all the entries to \a value.
-      * \sa DenseBase::setConstant(), DenseBase::fill() */
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-    Derived& operator=(const Scalar &value)
-    { Base::setConstant(value); return derived(); }
-
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-    Derived& operator+=(const Scalar& scalar);
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-    Derived& operator-=(const Scalar& scalar);
-
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-    Derived& operator+=(const ArrayBase<OtherDerived>& other);
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-    Derived& operator-=(const ArrayBase<OtherDerived>& other);
-
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-    Derived& operator*=(const ArrayBase<OtherDerived>& other);
-
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-    Derived& operator/=(const ArrayBase<OtherDerived>& other);
-
-  public:
-    EIGEN_DEVICE_FUNC
-    ArrayBase<Derived>& array() { return *this; }
-    EIGEN_DEVICE_FUNC
-    const ArrayBase<Derived>& array() const { return *this; }
-
-    /** \returns an \link Eigen::MatrixBase Matrix \endlink expression of this array
-      * \sa MatrixBase::array() */
-    EIGEN_DEVICE_FUNC
-    MatrixWrapper<Derived> matrix() { return MatrixWrapper<Derived>(derived()); }
-    EIGEN_DEVICE_FUNC
-    const MatrixWrapper<const Derived> matrix() const { return MatrixWrapper<const Derived>(derived()); }
-
-//     template<typename Dest>
-//     inline void evalTo(Dest& dst) const { dst = matrix(); }
-
-  protected:
-    EIGEN_DEVICE_FUNC
-    ArrayBase() : Base() {}
-
-  private:
-    explicit ArrayBase(Index);
-    ArrayBase(Index,Index);
-    template<typename OtherDerived> explicit ArrayBase(const ArrayBase<OtherDerived>&);
-  protected:
-    // mixing arrays and matrices is not legal
-    template<typename OtherDerived> Derived& operator+=(const MatrixBase<OtherDerived>& )
-    {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;}
-    // mixing arrays and matrices is not legal
-    template<typename OtherDerived> Derived& operator-=(const MatrixBase<OtherDerived>& )
-    {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;}
-};
-
-/** replaces \c *this by \c *this - \a other.
-  *
-  * \returns a reference to \c *this
-  */
-template<typename Derived>
-template<typename OtherDerived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived &
-ArrayBase<Derived>::operator-=(const ArrayBase<OtherDerived> &other)
-{
-  call_assignment(derived(), other.derived(), internal::sub_assign_op<Scalar,typename OtherDerived::Scalar>());
-  return derived();
-}
-
-/** replaces \c *this by \c *this + \a other.
-  *
-  * \returns a reference to \c *this
-  */
-template<typename Derived>
-template<typename OtherDerived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived &
-ArrayBase<Derived>::operator+=(const ArrayBase<OtherDerived>& other)
-{
-  call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar,typename OtherDerived::Scalar>());
-  return derived();
-}
-
-/** replaces \c *this by \c *this * \a other coefficient wise.
-  *
-  * \returns a reference to \c *this
-  */
-template<typename Derived>
-template<typename OtherDerived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived &
-ArrayBase<Derived>::operator*=(const ArrayBase<OtherDerived>& other)
-{
-  call_assignment(derived(), other.derived(), internal::mul_assign_op<Scalar,typename OtherDerived::Scalar>());
-  return derived();
-}
-
-/** replaces \c *this by \c *this / \a other coefficient wise.
-  *
-  * \returns a reference to \c *this
-  */
-template<typename Derived>
-template<typename OtherDerived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived &
-ArrayBase<Derived>::operator/=(const ArrayBase<OtherDerived>& other)
-{
-  call_assignment(derived(), other.derived(), internal::div_assign_op<Scalar,typename OtherDerived::Scalar>());
-  return derived();
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_ARRAYBASE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/ArrayWrapper.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/ArrayWrapper.h
deleted file mode 100644
index 688aadd..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/ArrayWrapper.h
+++ /dev/null
@@ -1,209 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_ARRAYWRAPPER_H
-#define EIGEN_ARRAYWRAPPER_H
-
-namespace Eigen { 
-
-/** \class ArrayWrapper
-  * \ingroup Core_Module
-  *
-  * \brief Expression of a mathematical vector or matrix as an array object
-  *
-  * This class is the return type of MatrixBase::array(), and most of the time
-  * this is the only way it is use.
-  *
-  * \sa MatrixBase::array(), class MatrixWrapper
-  */
-
-namespace internal {
-template<typename ExpressionType>
-struct traits<ArrayWrapper<ExpressionType> >
-  : public traits<typename remove_all<typename ExpressionType::Nested>::type >
-{
-  typedef ArrayXpr XprKind;
-  // Let's remove NestByRefBit
-  enum {
-    Flags0 = traits<typename remove_all<typename ExpressionType::Nested>::type >::Flags,
-    LvalueBitFlag = is_lvalue<ExpressionType>::value ? LvalueBit : 0,
-    Flags = (Flags0 & ~(NestByRefBit | LvalueBit)) | LvalueBitFlag
-  };
-};
-}
-
-template<typename ExpressionType>
-class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
-{
-  public:
-    typedef ArrayBase<ArrayWrapper> Base;
-    EIGEN_DENSE_PUBLIC_INTERFACE(ArrayWrapper)
-    EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ArrayWrapper)
-    typedef typename internal::remove_all<ExpressionType>::type NestedExpression;
-
-    typedef typename internal::conditional<
-                       internal::is_lvalue<ExpressionType>::value,
-                       Scalar,
-                       const Scalar
-                     >::type ScalarWithConstIfNotLvalue;
-
-    typedef typename internal::ref_selector<ExpressionType>::non_const_type NestedExpressionType;
-
-    using Base::coeffRef;
-
-    EIGEN_DEVICE_FUNC
-    explicit EIGEN_STRONG_INLINE ArrayWrapper(ExpressionType& matrix) : m_expression(matrix) {}
-
-    EIGEN_DEVICE_FUNC
-    inline Index rows() const { return m_expression.rows(); }
-    EIGEN_DEVICE_FUNC
-    inline Index cols() const { return m_expression.cols(); }
-    EIGEN_DEVICE_FUNC
-    inline Index outerStride() const { return m_expression.outerStride(); }
-    EIGEN_DEVICE_FUNC
-    inline Index innerStride() const { return m_expression.innerStride(); }
-
-    EIGEN_DEVICE_FUNC
-    inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
-    EIGEN_DEVICE_FUNC
-    inline const Scalar* data() const { return m_expression.data(); }
-
-    EIGEN_DEVICE_FUNC
-    inline const Scalar& coeffRef(Index rowId, Index colId) const
-    {
-      return m_expression.coeffRef(rowId, colId);
-    }
-
-    EIGEN_DEVICE_FUNC
-    inline const Scalar& coeffRef(Index index) const
-    {
-      return m_expression.coeffRef(index);
-    }
-
-    template<typename Dest>
-    EIGEN_DEVICE_FUNC
-    inline void evalTo(Dest& dst) const { dst = m_expression; }
-
-    const typename internal::remove_all<NestedExpressionType>::type& 
-    EIGEN_DEVICE_FUNC
-    nestedExpression() const 
-    {
-      return m_expression;
-    }
-
-    /** Forwards the resizing request to the nested expression
-      * \sa DenseBase::resize(Index)  */
-    EIGEN_DEVICE_FUNC
-    void resize(Index newSize) { m_expression.resize(newSize); }
-    /** Forwards the resizing request to the nested expression
-      * \sa DenseBase::resize(Index,Index)*/
-    EIGEN_DEVICE_FUNC
-    void resize(Index rows, Index cols) { m_expression.resize(rows,cols); }
-
-  protected:
-    NestedExpressionType m_expression;
-};
-
-/** \class MatrixWrapper
-  * \ingroup Core_Module
-  *
-  * \brief Expression of an array as a mathematical vector or matrix
-  *
-  * This class is the return type of ArrayBase::matrix(), and most of the time
-  * this is the only way it is use.
-  *
-  * \sa MatrixBase::matrix(), class ArrayWrapper
-  */
-
-namespace internal {
-template<typename ExpressionType>
-struct traits<MatrixWrapper<ExpressionType> >
- : public traits<typename remove_all<typename ExpressionType::Nested>::type >
-{
-  typedef MatrixXpr XprKind;
-  // Let's remove NestByRefBit
-  enum {
-    Flags0 = traits<typename remove_all<typename ExpressionType::Nested>::type >::Flags,
-    LvalueBitFlag = is_lvalue<ExpressionType>::value ? LvalueBit : 0,
-    Flags = (Flags0 & ~(NestByRefBit | LvalueBit)) | LvalueBitFlag
-  };
-};
-}
-
-template<typename ExpressionType>
-class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> >
-{
-  public:
-    typedef MatrixBase<MatrixWrapper<ExpressionType> > Base;
-    EIGEN_DENSE_PUBLIC_INTERFACE(MatrixWrapper)
-    EIGEN_INHERIT_ASSIGNMENT_OPERATORS(MatrixWrapper)
-    typedef typename internal::remove_all<ExpressionType>::type NestedExpression;
-
-    typedef typename internal::conditional<
-                       internal::is_lvalue<ExpressionType>::value,
-                       Scalar,
-                       const Scalar
-                     >::type ScalarWithConstIfNotLvalue;
-
-    typedef typename internal::ref_selector<ExpressionType>::non_const_type NestedExpressionType;
-
-    using Base::coeffRef;
-
-    EIGEN_DEVICE_FUNC
-    explicit inline MatrixWrapper(ExpressionType& matrix) : m_expression(matrix) {}
-
-    EIGEN_DEVICE_FUNC
-    inline Index rows() const { return m_expression.rows(); }
-    EIGEN_DEVICE_FUNC
-    inline Index cols() const { return m_expression.cols(); }
-    EIGEN_DEVICE_FUNC
-    inline Index outerStride() const { return m_expression.outerStride(); }
-    EIGEN_DEVICE_FUNC
-    inline Index innerStride() const { return m_expression.innerStride(); }
-
-    EIGEN_DEVICE_FUNC
-    inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
-    EIGEN_DEVICE_FUNC
-    inline const Scalar* data() const { return m_expression.data(); }
-
-    EIGEN_DEVICE_FUNC
-    inline const Scalar& coeffRef(Index rowId, Index colId) const
-    {
-      return m_expression.derived().coeffRef(rowId, colId);
-    }
-
-    EIGEN_DEVICE_FUNC
-    inline const Scalar& coeffRef(Index index) const
-    {
-      return m_expression.coeffRef(index);
-    }
-
-    EIGEN_DEVICE_FUNC
-    const typename internal::remove_all<NestedExpressionType>::type& 
-    nestedExpression() const 
-    {
-      return m_expression;
-    }
-
-    /** Forwards the resizing request to the nested expression
-      * \sa DenseBase::resize(Index)  */
-    EIGEN_DEVICE_FUNC
-    void resize(Index newSize) { m_expression.resize(newSize); }
-    /** Forwards the resizing request to the nested expression
-      * \sa DenseBase::resize(Index,Index)*/
-    EIGEN_DEVICE_FUNC
-    void resize(Index rows, Index cols) { m_expression.resize(rows,cols); }
-
-  protected:
-    NestedExpressionType m_expression;
-};
-
-} // end namespace Eigen
-
-#endif // EIGEN_ARRAYWRAPPER_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Assign.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Assign.h
deleted file mode 100644
index 53806ba..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Assign.h
+++ /dev/null
@@ -1,90 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2007 Michael Olbrich <michael.olbrich@gmx.net>
-// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_ASSIGN_H
-#define EIGEN_ASSIGN_H
-
-namespace Eigen {
-
-template<typename Derived>
-template<typename OtherDerived>
-EIGEN_STRONG_INLINE Derived& DenseBase<Derived>
-  ::lazyAssign(const DenseBase<OtherDerived>& other)
-{
-  enum{
-    SameType = internal::is_same<typename Derived::Scalar,typename OtherDerived::Scalar>::value
-  };
-
-  EIGEN_STATIC_ASSERT_LVALUE(Derived)
-  EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived)
-  EIGEN_STATIC_ASSERT(SameType,YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
-
-  eigen_assert(rows() == other.rows() && cols() == other.cols());
-  internal::call_assignment_no_alias(derived(),other.derived());
-  
-  return derived();
-}
-
-template<typename Derived>
-template<typename OtherDerived>
-EIGEN_DEVICE_FUNC
-EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator=(const DenseBase<OtherDerived>& other)
-{
-  internal::call_assignment(derived(), other.derived());
-  return derived();
-}
-
-template<typename Derived>
-EIGEN_DEVICE_FUNC
-EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator=(const DenseBase& other)
-{
-  internal::call_assignment(derived(), other.derived());
-  return derived();
-}
-
-template<typename Derived>
-EIGEN_DEVICE_FUNC
-EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const MatrixBase& other)
-{
-  internal::call_assignment(derived(), other.derived());
-  return derived();
-}
-
-template<typename Derived>
-template <typename OtherDerived>
-EIGEN_DEVICE_FUNC
-EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const DenseBase<OtherDerived>& other)
-{
-  internal::call_assignment(derived(), other.derived());
-  return derived();
-}
-
-template<typename Derived>
-template <typename OtherDerived>
-EIGEN_DEVICE_FUNC
-EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const EigenBase<OtherDerived>& other)
-{
-  internal::call_assignment(derived(), other.derived());
-  return derived();
-}
-
-template<typename Derived>
-template<typename OtherDerived>
-EIGEN_DEVICE_FUNC
-EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other)
-{
-  other.derived().evalTo(derived());
-  return derived();
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_ASSIGN_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/AssignEvaluator.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/AssignEvaluator.h
deleted file mode 100644
index dbe435d..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/AssignEvaluator.h
+++ /dev/null
@@ -1,935 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2011 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2011-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2011-2012 Jitse Niesen <jitse@maths.leeds.ac.uk>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_ASSIGN_EVALUATOR_H
-#define EIGEN_ASSIGN_EVALUATOR_H
-
-namespace Eigen {
-
-// This implementation is based on Assign.h
-
-namespace internal {
-  
-/***************************************************************************
-* Part 1 : the logic deciding a strategy for traversal and unrolling       *
-***************************************************************************/
-
-// copy_using_evaluator_traits is based on assign_traits
-
-template <typename DstEvaluator, typename SrcEvaluator, typename AssignFunc>
-struct copy_using_evaluator_traits
-{
-  typedef typename DstEvaluator::XprType Dst;
-  typedef typename Dst::Scalar DstScalar;
-  
-  enum {
-    DstFlags = DstEvaluator::Flags,
-    SrcFlags = SrcEvaluator::Flags
-  };
-  
-public:
-  enum {
-    DstAlignment = DstEvaluator::Alignment,
-    SrcAlignment = SrcEvaluator::Alignment,
-    DstHasDirectAccess = (DstFlags & DirectAccessBit) == DirectAccessBit,
-    JointAlignment = EIGEN_PLAIN_ENUM_MIN(DstAlignment,SrcAlignment)
-  };
-
-private:
-  enum {
-    InnerSize = int(Dst::IsVectorAtCompileTime) ? int(Dst::SizeAtCompileTime)
-              : int(DstFlags)&RowMajorBit ? int(Dst::ColsAtCompileTime)
-              : int(Dst::RowsAtCompileTime),
-    InnerMaxSize = int(Dst::IsVectorAtCompileTime) ? int(Dst::MaxSizeAtCompileTime)
-              : int(DstFlags)&RowMajorBit ? int(Dst::MaxColsAtCompileTime)
-              : int(Dst::MaxRowsAtCompileTime),
-    OuterStride = int(outer_stride_at_compile_time<Dst>::ret),
-    MaxSizeAtCompileTime = Dst::SizeAtCompileTime
-  };
-
-  // TODO distinguish between linear traversal and inner-traversals
-  typedef typename find_best_packet<DstScalar,Dst::SizeAtCompileTime>::type LinearPacketType;
-  typedef typename find_best_packet<DstScalar,InnerSize>::type InnerPacketType;
-
-  enum {
-    LinearPacketSize = unpacket_traits<LinearPacketType>::size,
-    InnerPacketSize = unpacket_traits<InnerPacketType>::size
-  };
-
-public:
-  enum {
-    LinearRequiredAlignment = unpacket_traits<LinearPacketType>::alignment,
-    InnerRequiredAlignment = unpacket_traits<InnerPacketType>::alignment
-  };
-
-private:
-  enum {
-    DstIsRowMajor = DstFlags&RowMajorBit,
-    SrcIsRowMajor = SrcFlags&RowMajorBit,
-    StorageOrdersAgree = (int(DstIsRowMajor) == int(SrcIsRowMajor)),
-    MightVectorize = bool(StorageOrdersAgree)
-                  && (int(DstFlags) & int(SrcFlags) & ActualPacketAccessBit)
-                  && bool(functor_traits<AssignFunc>::PacketAccess),
-    MayInnerVectorize  = MightVectorize
-                       && int(InnerSize)!=Dynamic && int(InnerSize)%int(InnerPacketSize)==0
-                       && int(OuterStride)!=Dynamic && int(OuterStride)%int(InnerPacketSize)==0
-                       && (EIGEN_UNALIGNED_VECTORIZE  || int(JointAlignment)>=int(InnerRequiredAlignment)),
-    MayLinearize = bool(StorageOrdersAgree) && (int(DstFlags) & int(SrcFlags) & LinearAccessBit),
-    MayLinearVectorize = bool(MightVectorize) && bool(MayLinearize) && bool(DstHasDirectAccess)
-                       && (EIGEN_UNALIGNED_VECTORIZE || (int(DstAlignment)>=int(LinearRequiredAlignment)) || MaxSizeAtCompileTime == Dynamic),
-      /* If the destination isn't aligned, we have to do runtime checks and we don't unroll,
-         so it's only good for large enough sizes. */
-    MaySliceVectorize  = bool(MightVectorize) && bool(DstHasDirectAccess)
-                       && (int(InnerMaxSize)==Dynamic || int(InnerMaxSize)>=(EIGEN_UNALIGNED_VECTORIZE?InnerPacketSize:(3*InnerPacketSize)))
-      /* slice vectorization can be slow, so we only want it if the slices are big, which is
-         indicated by InnerMaxSize rather than InnerSize, think of the case of a dynamic block
-         in a fixed-size matrix
-         However, with EIGEN_UNALIGNED_VECTORIZE and unrolling, slice vectorization is still worth it */
-  };
-
-public:
-  enum {
-    Traversal = int(MayLinearVectorize) && (LinearPacketSize>InnerPacketSize) ? int(LinearVectorizedTraversal)
-              : int(MayInnerVectorize)   ? int(InnerVectorizedTraversal)
-              : int(MayLinearVectorize)  ? int(LinearVectorizedTraversal)
-              : int(MaySliceVectorize)   ? int(SliceVectorizedTraversal)
-              : int(MayLinearize)        ? int(LinearTraversal)
-                                         : int(DefaultTraversal),
-    Vectorized = int(Traversal) == InnerVectorizedTraversal
-              || int(Traversal) == LinearVectorizedTraversal
-              || int(Traversal) == SliceVectorizedTraversal
-  };
-
-  typedef typename conditional<int(Traversal)==LinearVectorizedTraversal, LinearPacketType, InnerPacketType>::type PacketType;
-
-private:
-  enum {
-    ActualPacketSize    = int(Traversal)==LinearVectorizedTraversal ? LinearPacketSize
-                        : Vectorized ? InnerPacketSize
-                        : 1,
-    UnrollingLimit      = EIGEN_UNROLLING_LIMIT * ActualPacketSize,
-    MayUnrollCompletely = int(Dst::SizeAtCompileTime) != Dynamic
-                       && int(Dst::SizeAtCompileTime) * (int(DstEvaluator::CoeffReadCost)+int(SrcEvaluator::CoeffReadCost)) <= int(UnrollingLimit),
-    MayUnrollInner      = int(InnerSize) != Dynamic
-                       && int(InnerSize) * (int(DstEvaluator::CoeffReadCost)+int(SrcEvaluator::CoeffReadCost)) <= int(UnrollingLimit)
-  };
-
-public:
-  enum {
-    Unrolling = (int(Traversal) == int(InnerVectorizedTraversal) || int(Traversal) == int(DefaultTraversal))
-                ? (
-                    int(MayUnrollCompletely) ? int(CompleteUnrolling)
-                  : int(MayUnrollInner)      ? int(InnerUnrolling)
-                                             : int(NoUnrolling)
-                  )
-              : int(Traversal) == int(LinearVectorizedTraversal)
-                ? ( bool(MayUnrollCompletely) && ( EIGEN_UNALIGNED_VECTORIZE || (int(DstAlignment)>=int(LinearRequiredAlignment)))
-                          ? int(CompleteUnrolling)
-                          : int(NoUnrolling) )
-              : int(Traversal) == int(LinearTraversal)
-                ? ( bool(MayUnrollCompletely) ? int(CompleteUnrolling) 
-                                              : int(NoUnrolling) )
-#if EIGEN_UNALIGNED_VECTORIZE
-              : int(Traversal) == int(SliceVectorizedTraversal)
-                ? ( bool(MayUnrollInner) ? int(InnerUnrolling)
-                                         : int(NoUnrolling) )
-#endif
-              : int(NoUnrolling)
-  };
-
-#ifdef EIGEN_DEBUG_ASSIGN
-  static void debug()
-  {
-    std::cerr << "DstXpr: " << typeid(typename DstEvaluator::XprType).name() << std::endl;
-    std::cerr << "SrcXpr: " << typeid(typename SrcEvaluator::XprType).name() << std::endl;
-    std::cerr.setf(std::ios::hex, std::ios::basefield);
-    std::cerr << "DstFlags" << " = " << DstFlags << " (" << demangle_flags(DstFlags) << " )" << std::endl;
-    std::cerr << "SrcFlags" << " = " << SrcFlags << " (" << demangle_flags(SrcFlags) << " )" << std::endl;
-    std::cerr.unsetf(std::ios::hex);
-    EIGEN_DEBUG_VAR(DstAlignment)
-    EIGEN_DEBUG_VAR(SrcAlignment)
-    EIGEN_DEBUG_VAR(LinearRequiredAlignment)
-    EIGEN_DEBUG_VAR(InnerRequiredAlignment)
-    EIGEN_DEBUG_VAR(JointAlignment)
-    EIGEN_DEBUG_VAR(InnerSize)
-    EIGEN_DEBUG_VAR(InnerMaxSize)
-    EIGEN_DEBUG_VAR(LinearPacketSize)
-    EIGEN_DEBUG_VAR(InnerPacketSize)
-    EIGEN_DEBUG_VAR(ActualPacketSize)
-    EIGEN_DEBUG_VAR(StorageOrdersAgree)
-    EIGEN_DEBUG_VAR(MightVectorize)
-    EIGEN_DEBUG_VAR(MayLinearize)
-    EIGEN_DEBUG_VAR(MayInnerVectorize)
-    EIGEN_DEBUG_VAR(MayLinearVectorize)
-    EIGEN_DEBUG_VAR(MaySliceVectorize)
-    std::cerr << "Traversal" << " = " << Traversal << " (" << demangle_traversal(Traversal) << ")" << std::endl;
-    EIGEN_DEBUG_VAR(SrcEvaluator::CoeffReadCost)
-    EIGEN_DEBUG_VAR(UnrollingLimit)
-    EIGEN_DEBUG_VAR(MayUnrollCompletely)
-    EIGEN_DEBUG_VAR(MayUnrollInner)
-    std::cerr << "Unrolling" << " = " << Unrolling << " (" << demangle_unrolling(Unrolling) << ")" << std::endl;
-    std::cerr << std::endl;
-  }
-#endif
-};
-
-/***************************************************************************
-* Part 2 : meta-unrollers
-***************************************************************************/
-
-/************************
-*** Default traversal ***
-************************/
-
-template<typename Kernel, int Index, int Stop>
-struct copy_using_evaluator_DefaultTraversal_CompleteUnrolling
-{
-  // FIXME: this is not very clean, perhaps this information should be provided by the kernel?
-  typedef typename Kernel::DstEvaluatorType DstEvaluatorType;
-  typedef typename DstEvaluatorType::XprType DstXprType;
-  
-  enum {
-    outer = Index / DstXprType::InnerSizeAtCompileTime,
-    inner = Index % DstXprType::InnerSizeAtCompileTime
-  };
-
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
-  {
-    kernel.assignCoeffByOuterInner(outer, inner);
-    copy_using_evaluator_DefaultTraversal_CompleteUnrolling<Kernel, Index+1, Stop>::run(kernel);
-  }
-};
-
-template<typename Kernel, int Stop>
-struct copy_using_evaluator_DefaultTraversal_CompleteUnrolling<Kernel, Stop, Stop>
-{
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel&) { }
-};
-
-template<typename Kernel, int Index_, int Stop>
-struct copy_using_evaluator_DefaultTraversal_InnerUnrolling
-{
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel, Index outer)
-  {
-    kernel.assignCoeffByOuterInner(outer, Index_);
-    copy_using_evaluator_DefaultTraversal_InnerUnrolling<Kernel, Index_+1, Stop>::run(kernel, outer);
-  }
-};
-
-template<typename Kernel, int Stop>
-struct copy_using_evaluator_DefaultTraversal_InnerUnrolling<Kernel, Stop, Stop>
-{
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel&, Index) { }
-};
-
-/***********************
-*** Linear traversal ***
-***********************/
-
-template<typename Kernel, int Index, int Stop>
-struct copy_using_evaluator_LinearTraversal_CompleteUnrolling
-{
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel& kernel)
-  {
-    kernel.assignCoeff(Index);
-    copy_using_evaluator_LinearTraversal_CompleteUnrolling<Kernel, Index+1, Stop>::run(kernel);
-  }
-};
-
-template<typename Kernel, int Stop>
-struct copy_using_evaluator_LinearTraversal_CompleteUnrolling<Kernel, Stop, Stop>
-{
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel&) { }
-};
-
-/**************************
-*** Inner vectorization ***
-**************************/
-
-template<typename Kernel, int Index, int Stop>
-struct copy_using_evaluator_innervec_CompleteUnrolling
-{
-  // FIXME: this is not very clean, perhaps this information should be provided by the kernel?
-  typedef typename Kernel::DstEvaluatorType DstEvaluatorType;
-  typedef typename DstEvaluatorType::XprType DstXprType;
-  typedef typename Kernel::PacketType PacketType;
-  
-  enum {
-    outer = Index / DstXprType::InnerSizeAtCompileTime,
-    inner = Index % DstXprType::InnerSizeAtCompileTime,
-    SrcAlignment = Kernel::AssignmentTraits::SrcAlignment,
-    DstAlignment = Kernel::AssignmentTraits::DstAlignment
-  };
-
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
-  {
-    kernel.template assignPacketByOuterInner<DstAlignment, SrcAlignment, PacketType>(outer, inner);
-    enum { NextIndex = Index + unpacket_traits<PacketType>::size };
-    copy_using_evaluator_innervec_CompleteUnrolling<Kernel, NextIndex, Stop>::run(kernel);
-  }
-};
-
-template<typename Kernel, int Stop>
-struct copy_using_evaluator_innervec_CompleteUnrolling<Kernel, Stop, Stop>
-{
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel&) { }
-};
-
-template<typename Kernel, int Index_, int Stop, int SrcAlignment, int DstAlignment>
-struct copy_using_evaluator_innervec_InnerUnrolling
-{
-  typedef typename Kernel::PacketType PacketType;
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel, Index outer)
-  {
-    kernel.template assignPacketByOuterInner<DstAlignment, SrcAlignment, PacketType>(outer, Index_);
-    enum { NextIndex = Index_ + unpacket_traits<PacketType>::size };
-    copy_using_evaluator_innervec_InnerUnrolling<Kernel, NextIndex, Stop, SrcAlignment, DstAlignment>::run(kernel, outer);
-  }
-};
-
-template<typename Kernel, int Stop, int SrcAlignment, int DstAlignment>
-struct copy_using_evaluator_innervec_InnerUnrolling<Kernel, Stop, Stop, SrcAlignment, DstAlignment>
-{
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &, Index) { }
-};
-
-/***************************************************************************
-* Part 3 : implementation of all cases
-***************************************************************************/
-
-// dense_assignment_loop is based on assign_impl
-
-template<typename Kernel,
-         int Traversal = Kernel::AssignmentTraits::Traversal,
-         int Unrolling = Kernel::AssignmentTraits::Unrolling>
-struct dense_assignment_loop;
-
-/************************
-*** Default traversal ***
-************************/
-
-template<typename Kernel>
-struct dense_assignment_loop<Kernel, DefaultTraversal, NoUnrolling>
-{
-  EIGEN_DEVICE_FUNC static void EIGEN_STRONG_INLINE run(Kernel &kernel)
-  {
-    for(Index outer = 0; outer < kernel.outerSize(); ++outer) {
-      for(Index inner = 0; inner < kernel.innerSize(); ++inner) {
-        kernel.assignCoeffByOuterInner(outer, inner);
-      }
-    }
-  }
-};
-
-template<typename Kernel>
-struct dense_assignment_loop<Kernel, DefaultTraversal, CompleteUnrolling>
-{
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
-  {
-    typedef typename Kernel::DstEvaluatorType::XprType DstXprType;
-    copy_using_evaluator_DefaultTraversal_CompleteUnrolling<Kernel, 0, DstXprType::SizeAtCompileTime>::run(kernel);
-  }
-};
-
-template<typename Kernel>
-struct dense_assignment_loop<Kernel, DefaultTraversal, InnerUnrolling>
-{
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
-  {
-    typedef typename Kernel::DstEvaluatorType::XprType DstXprType;
-
-    const Index outerSize = kernel.outerSize();
-    for(Index outer = 0; outer < outerSize; ++outer)
-      copy_using_evaluator_DefaultTraversal_InnerUnrolling<Kernel, 0, DstXprType::InnerSizeAtCompileTime>::run(kernel, outer);
-  }
-};
-
-/***************************
-*** Linear vectorization ***
-***************************/
-
-
-// The goal of unaligned_dense_assignment_loop is simply to factorize the handling
-// of the non vectorizable beginning and ending parts
-
-template <bool IsAligned = false>
-struct unaligned_dense_assignment_loop
-{
-  // if IsAligned = true, then do nothing
-  template <typename Kernel>
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel&, Index, Index) {}
-};
-
-template <>
-struct unaligned_dense_assignment_loop<false>
-{
-  // MSVC must not inline this functions. If it does, it fails to optimize the
-  // packet access path.
-  // FIXME check which version exhibits this issue
-#if EIGEN_COMP_MSVC
-  template <typename Kernel>
-  static EIGEN_DONT_INLINE void run(Kernel &kernel,
-                                    Index start,
-                                    Index end)
-#else
-  template <typename Kernel>
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel,
-                                      Index start,
-                                      Index end)
-#endif
-  {
-    for (Index index = start; index < end; ++index)
-      kernel.assignCoeff(index);
-  }
-};
-
-template<typename Kernel>
-struct dense_assignment_loop<Kernel, LinearVectorizedTraversal, NoUnrolling>
-{
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
-  {
-    const Index size = kernel.size();
-    typedef typename Kernel::Scalar Scalar;
-    typedef typename Kernel::PacketType PacketType;
-    enum {
-      requestedAlignment = Kernel::AssignmentTraits::LinearRequiredAlignment,
-      packetSize = unpacket_traits<PacketType>::size,
-      dstIsAligned = int(Kernel::AssignmentTraits::DstAlignment)>=int(requestedAlignment),
-      dstAlignment = packet_traits<Scalar>::AlignedOnScalar ? int(requestedAlignment)
-                                                            : int(Kernel::AssignmentTraits::DstAlignment),
-      srcAlignment = Kernel::AssignmentTraits::JointAlignment
-    };
-    const Index alignedStart = dstIsAligned ? 0 : internal::first_aligned<requestedAlignment>(kernel.dstDataPtr(), size);
-    const Index alignedEnd = alignedStart + ((size-alignedStart)/packetSize)*packetSize;
-
-    unaligned_dense_assignment_loop<dstIsAligned!=0>::run(kernel, 0, alignedStart);
-
-    for(Index index = alignedStart; index < alignedEnd; index += packetSize)
-      kernel.template assignPacket<dstAlignment, srcAlignment, PacketType>(index);
-
-    unaligned_dense_assignment_loop<>::run(kernel, alignedEnd, size);
-  }
-};
-
-template<typename Kernel>
-struct dense_assignment_loop<Kernel, LinearVectorizedTraversal, CompleteUnrolling>
-{
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
-  {
-    typedef typename Kernel::DstEvaluatorType::XprType DstXprType;
-    typedef typename Kernel::PacketType PacketType;
-    
-    enum { size = DstXprType::SizeAtCompileTime,
-           packetSize =unpacket_traits<PacketType>::size,
-           alignedSize = (size/packetSize)*packetSize };
-
-    copy_using_evaluator_innervec_CompleteUnrolling<Kernel, 0, alignedSize>::run(kernel);
-    copy_using_evaluator_DefaultTraversal_CompleteUnrolling<Kernel, alignedSize, size>::run(kernel);
-  }
-};
-
-/**************************
-*** Inner vectorization ***
-**************************/
-
-template<typename Kernel>
-struct dense_assignment_loop<Kernel, InnerVectorizedTraversal, NoUnrolling>
-{
-  typedef typename Kernel::PacketType PacketType;
-  enum {
-    SrcAlignment = Kernel::AssignmentTraits::SrcAlignment,
-    DstAlignment = Kernel::AssignmentTraits::DstAlignment
-  };
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
-  {
-    const Index innerSize = kernel.innerSize();
-    const Index outerSize = kernel.outerSize();
-    const Index packetSize = unpacket_traits<PacketType>::size;
-    for(Index outer = 0; outer < outerSize; ++outer)
-      for(Index inner = 0; inner < innerSize; inner+=packetSize)
-        kernel.template assignPacketByOuterInner<DstAlignment, SrcAlignment, PacketType>(outer, inner);
-  }
-};
-
-template<typename Kernel>
-struct dense_assignment_loop<Kernel, InnerVectorizedTraversal, CompleteUnrolling>
-{
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
-  {
-    typedef typename Kernel::DstEvaluatorType::XprType DstXprType;
-    copy_using_evaluator_innervec_CompleteUnrolling<Kernel, 0, DstXprType::SizeAtCompileTime>::run(kernel);
-  }
-};
-
-template<typename Kernel>
-struct dense_assignment_loop<Kernel, InnerVectorizedTraversal, InnerUnrolling>
-{
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
-  {
-    typedef typename Kernel::DstEvaluatorType::XprType DstXprType;
-    typedef typename Kernel::AssignmentTraits Traits;
-    const Index outerSize = kernel.outerSize();
-    for(Index outer = 0; outer < outerSize; ++outer)
-      copy_using_evaluator_innervec_InnerUnrolling<Kernel, 0, DstXprType::InnerSizeAtCompileTime,
-                                                   Traits::SrcAlignment, Traits::DstAlignment>::run(kernel, outer);
-  }
-};
-
-/***********************
-*** Linear traversal ***
-***********************/
-
-template<typename Kernel>
-struct dense_assignment_loop<Kernel, LinearTraversal, NoUnrolling>
-{
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
-  {
-    const Index size = kernel.size();
-    for(Index i = 0; i < size; ++i)
-      kernel.assignCoeff(i);
-  }
-};
-
-template<typename Kernel>
-struct dense_assignment_loop<Kernel, LinearTraversal, CompleteUnrolling>
-{
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
-  {
-    typedef typename Kernel::DstEvaluatorType::XprType DstXprType;
-    copy_using_evaluator_LinearTraversal_CompleteUnrolling<Kernel, 0, DstXprType::SizeAtCompileTime>::run(kernel);
-  }
-};
-
-/**************************
-*** Slice vectorization ***
-***************************/
-
-template<typename Kernel>
-struct dense_assignment_loop<Kernel, SliceVectorizedTraversal, NoUnrolling>
-{
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
-  {
-    typedef typename Kernel::Scalar Scalar;
-    typedef typename Kernel::PacketType PacketType;
-    enum {
-      packetSize = unpacket_traits<PacketType>::size,
-      requestedAlignment = int(Kernel::AssignmentTraits::InnerRequiredAlignment),
-      alignable = packet_traits<Scalar>::AlignedOnScalar || int(Kernel::AssignmentTraits::DstAlignment)>=sizeof(Scalar),
-      dstIsAligned = int(Kernel::AssignmentTraits::DstAlignment)>=int(requestedAlignment),
-      dstAlignment = alignable ? int(requestedAlignment)
-                               : int(Kernel::AssignmentTraits::DstAlignment)
-    };
-    const Scalar *dst_ptr = kernel.dstDataPtr();
-    if((!bool(dstIsAligned)) && (UIntPtr(dst_ptr) % sizeof(Scalar))>0)
-    {
-      // the pointer is not aligend-on scalar, so alignment is not possible
-      return dense_assignment_loop<Kernel,DefaultTraversal,NoUnrolling>::run(kernel);
-    }
-    const Index packetAlignedMask = packetSize - 1;
-    const Index innerSize = kernel.innerSize();
-    const Index outerSize = kernel.outerSize();
-    const Index alignedStep = alignable ? (packetSize - kernel.outerStride() % packetSize) & packetAlignedMask : 0;
-    Index alignedStart = ((!alignable) || bool(dstIsAligned)) ? 0 : internal::first_aligned<requestedAlignment>(dst_ptr, innerSize);
-
-    for(Index outer = 0; outer < outerSize; ++outer)
-    {
-      const Index alignedEnd = alignedStart + ((innerSize-alignedStart) & ~packetAlignedMask);
-      // do the non-vectorizable part of the assignment
-      for(Index inner = 0; inner<alignedStart ; ++inner)
-        kernel.assignCoeffByOuterInner(outer, inner);
-
-      // do the vectorizable part of the assignment
-      for(Index inner = alignedStart; inner<alignedEnd; inner+=packetSize)
-        kernel.template assignPacketByOuterInner<dstAlignment, Unaligned, PacketType>(outer, inner);
-
-      // do the non-vectorizable part of the assignment
-      for(Index inner = alignedEnd; inner<innerSize ; ++inner)
-        kernel.assignCoeffByOuterInner(outer, inner);
-
-      alignedStart = numext::mini((alignedStart+alignedStep)%packetSize, innerSize);
-    }
-  }
-};
-
-#if EIGEN_UNALIGNED_VECTORIZE
-template<typename Kernel>
-struct dense_assignment_loop<Kernel, SliceVectorizedTraversal, InnerUnrolling>
-{
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel)
-  {
-    typedef typename Kernel::DstEvaluatorType::XprType DstXprType;
-    typedef typename Kernel::PacketType PacketType;
-
-    enum { size = DstXprType::InnerSizeAtCompileTime,
-           packetSize =unpacket_traits<PacketType>::size,
-           vectorizableSize = (size/packetSize)*packetSize };
-
-    for(Index outer = 0; outer < kernel.outerSize(); ++outer)
-    {
-      copy_using_evaluator_innervec_InnerUnrolling<Kernel, 0, vectorizableSize, 0, 0>::run(kernel, outer);
-      copy_using_evaluator_DefaultTraversal_InnerUnrolling<Kernel, vectorizableSize, size>::run(kernel, outer);
-    }
-  }
-};
-#endif
-
-
-/***************************************************************************
-* Part 4 : Generic dense assignment kernel
-***************************************************************************/
-
-// This class generalize the assignment of a coefficient (or packet) from one dense evaluator
-// to another dense writable evaluator.
-// It is parametrized by the two evaluators, and the actual assignment functor.
-// This abstraction level permits to keep the evaluation loops as simple and as generic as possible.
-// One can customize the assignment using this generic dense_assignment_kernel with different
-// functors, or by completely overloading it, by-passing a functor.
-template<typename DstEvaluatorTypeT, typename SrcEvaluatorTypeT, typename Functor, int Version = Specialized>
-class generic_dense_assignment_kernel
-{
-protected:
-  typedef typename DstEvaluatorTypeT::XprType DstXprType;
-  typedef typename SrcEvaluatorTypeT::XprType SrcXprType;
-public:
-  
-  typedef DstEvaluatorTypeT DstEvaluatorType;
-  typedef SrcEvaluatorTypeT SrcEvaluatorType;
-  typedef typename DstEvaluatorType::Scalar Scalar;
-  typedef copy_using_evaluator_traits<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor> AssignmentTraits;
-  typedef typename AssignmentTraits::PacketType PacketType;
-  
-  
-  EIGEN_DEVICE_FUNC generic_dense_assignment_kernel(DstEvaluatorType &dst, const SrcEvaluatorType &src, const Functor &func, DstXprType& dstExpr)
-    : m_dst(dst), m_src(src), m_functor(func), m_dstExpr(dstExpr)
-  {
-    #ifdef EIGEN_DEBUG_ASSIGN
-    AssignmentTraits::debug();
-    #endif
-  }
-  
-  EIGEN_DEVICE_FUNC Index size() const        { return m_dstExpr.size(); }
-  EIGEN_DEVICE_FUNC Index innerSize() const   { return m_dstExpr.innerSize(); }
-  EIGEN_DEVICE_FUNC Index outerSize() const   { return m_dstExpr.outerSize(); }
-  EIGEN_DEVICE_FUNC Index rows() const        { return m_dstExpr.rows(); }
-  EIGEN_DEVICE_FUNC Index cols() const        { return m_dstExpr.cols(); }
-  EIGEN_DEVICE_FUNC Index outerStride() const { return m_dstExpr.outerStride(); }
-  
-  EIGEN_DEVICE_FUNC DstEvaluatorType& dstEvaluator() { return m_dst; }
-  EIGEN_DEVICE_FUNC const SrcEvaluatorType& srcEvaluator() const { return m_src; }
-  
-  /// Assign src(row,col) to dst(row,col) through the assignment functor.
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(Index row, Index col)
-  {
-    m_functor.assignCoeff(m_dst.coeffRef(row,col), m_src.coeff(row,col));
-  }
-  
-  /// \sa assignCoeff(Index,Index)
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(Index index)
-  {
-    m_functor.assignCoeff(m_dst.coeffRef(index), m_src.coeff(index));
-  }
-  
-  /// \sa assignCoeff(Index,Index)
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeffByOuterInner(Index outer, Index inner)
-  {
-    Index row = rowIndexByOuterInner(outer, inner); 
-    Index col = colIndexByOuterInner(outer, inner); 
-    assignCoeff(row, col);
-  }
-  
-  
-  template<int StoreMode, int LoadMode, typename PacketType>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignPacket(Index row, Index col)
-  {
-    m_functor.template assignPacket<StoreMode>(&m_dst.coeffRef(row,col), m_src.template packet<LoadMode,PacketType>(row,col));
-  }
-  
-  template<int StoreMode, int LoadMode, typename PacketType>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignPacket(Index index)
-  {
-    m_functor.template assignPacket<StoreMode>(&m_dst.coeffRef(index), m_src.template packet<LoadMode,PacketType>(index));
-  }
-  
-  template<int StoreMode, int LoadMode, typename PacketType>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignPacketByOuterInner(Index outer, Index inner)
-  {
-    Index row = rowIndexByOuterInner(outer, inner); 
-    Index col = colIndexByOuterInner(outer, inner);
-    assignPacket<StoreMode,LoadMode,PacketType>(row, col);
-  }
-  
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Index rowIndexByOuterInner(Index outer, Index inner)
-  {
-    typedef typename DstEvaluatorType::ExpressionTraits Traits;
-    return int(Traits::RowsAtCompileTime) == 1 ? 0
-      : int(Traits::ColsAtCompileTime) == 1 ? inner
-      : int(DstEvaluatorType::Flags)&RowMajorBit ? outer
-      : inner;
-  }
-
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Index colIndexByOuterInner(Index outer, Index inner)
-  {
-    typedef typename DstEvaluatorType::ExpressionTraits Traits;
-    return int(Traits::ColsAtCompileTime) == 1 ? 0
-      : int(Traits::RowsAtCompileTime) == 1 ? inner
-      : int(DstEvaluatorType::Flags)&RowMajorBit ? inner
-      : outer;
-  }
-
-  EIGEN_DEVICE_FUNC const Scalar* dstDataPtr() const
-  {
-    return m_dstExpr.data();
-  }
-  
-protected:
-  DstEvaluatorType& m_dst;
-  const SrcEvaluatorType& m_src;
-  const Functor &m_functor;
-  // TODO find a way to avoid the needs of the original expression
-  DstXprType& m_dstExpr;
-};
-
-/***************************************************************************
-* Part 5 : Entry point for dense rectangular assignment
-***************************************************************************/
-
-template<typename DstXprType,typename SrcXprType, typename Functor>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-void resize_if_allowed(DstXprType &dst, const SrcXprType& src, const Functor &/*func*/)
-{
-  EIGEN_ONLY_USED_FOR_DEBUG(dst);
-  EIGEN_ONLY_USED_FOR_DEBUG(src);
-  eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
-}
-
-template<typename DstXprType,typename SrcXprType, typename T1, typename T2>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-void resize_if_allowed(DstXprType &dst, const SrcXprType& src, const internal::assign_op<T1,T2> &/*func*/)
-{
-  Index dstRows = src.rows();
-  Index dstCols = src.cols();
-  if(((dst.rows()!=dstRows) || (dst.cols()!=dstCols)))
-    dst.resize(dstRows, dstCols);
-  eigen_assert(dst.rows() == dstRows && dst.cols() == dstCols);
-}
-
-template<typename DstXprType, typename SrcXprType, typename Functor>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void call_dense_assignment_loop(DstXprType& dst, const SrcXprType& src, const Functor &func)
-{
-  typedef evaluator<DstXprType> DstEvaluatorType;
-  typedef evaluator<SrcXprType> SrcEvaluatorType;
-
-  SrcEvaluatorType srcEvaluator(src);
-
-  // NOTE To properly handle A = (A*A.transpose())/s with A rectangular,
-  // we need to resize the destination after the source evaluator has been created.
-  resize_if_allowed(dst, src, func);
-
-  DstEvaluatorType dstEvaluator(dst);
-    
-  typedef generic_dense_assignment_kernel<DstEvaluatorType,SrcEvaluatorType,Functor> Kernel;
-  Kernel kernel(dstEvaluator, srcEvaluator, func, dst.const_cast_derived());
-
-  dense_assignment_loop<Kernel>::run(kernel);
-}
-
-template<typename DstXprType, typename SrcXprType>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void call_dense_assignment_loop(DstXprType& dst, const SrcXprType& src)
-{
-  call_dense_assignment_loop(dst, src, internal::assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar>());
-}
-
-/***************************************************************************
-* Part 6 : Generic assignment
-***************************************************************************/
-
-// Based on the respective shapes of the destination and source,
-// the class AssignmentKind determine the kind of assignment mechanism.
-// AssignmentKind must define a Kind typedef.
-template<typename DstShape, typename SrcShape> struct AssignmentKind;
-
-// Assignement kind defined in this file:
-struct Dense2Dense {};
-struct EigenBase2EigenBase {};
-
-template<typename,typename> struct AssignmentKind { typedef EigenBase2EigenBase Kind; };
-template<> struct AssignmentKind<DenseShape,DenseShape> { typedef Dense2Dense Kind; };
-    
-// This is the main assignment class
-template< typename DstXprType, typename SrcXprType, typename Functor,
-          typename Kind = typename AssignmentKind< typename evaluator_traits<DstXprType>::Shape , typename evaluator_traits<SrcXprType>::Shape >::Kind,
-          typename EnableIf = void>
-struct Assignment;
-
-
-// The only purpose of this call_assignment() function is to deal with noalias() / "assume-aliasing" and automatic transposition.
-// Indeed, I (Gael) think that this concept of "assume-aliasing" was a mistake, and it makes thing quite complicated.
-// So this intermediate function removes everything related to "assume-aliasing" such that Assignment
-// does not has to bother about these annoying details.
-
-template<typename Dst, typename Src>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-void call_assignment(Dst& dst, const Src& src)
-{
-  call_assignment(dst, src, internal::assign_op<typename Dst::Scalar,typename Src::Scalar>());
-}
-template<typename Dst, typename Src>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-void call_assignment(const Dst& dst, const Src& src)
-{
-  call_assignment(dst, src, internal::assign_op<typename Dst::Scalar,typename Src::Scalar>());
-}
-                     
-// Deal with "assume-aliasing"
-template<typename Dst, typename Src, typename Func>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-void call_assignment(Dst& dst, const Src& src, const Func& func, typename enable_if< evaluator_assume_aliasing<Src>::value, void*>::type = 0)
-{
-  typename plain_matrix_type<Src>::type tmp(src);
-  call_assignment_no_alias(dst, tmp, func);
-}
-
-template<typename Dst, typename Src, typename Func>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-void call_assignment(Dst& dst, const Src& src, const Func& func, typename enable_if<!evaluator_assume_aliasing<Src>::value, void*>::type = 0)
-{
-  call_assignment_no_alias(dst, src, func);
-}
-
-// by-pass "assume-aliasing"
-// When there is no aliasing, we require that 'dst' has been properly resized
-template<typename Dst, template <typename> class StorageBase, typename Src, typename Func>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-void call_assignment(NoAlias<Dst,StorageBase>& dst, const Src& src, const Func& func)
-{
-  call_assignment_no_alias(dst.expression(), src, func);
-}
-
-
-template<typename Dst, typename Src, typename Func>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-void call_assignment_no_alias(Dst& dst, const Src& src, const Func& func)
-{
-  enum {
-    NeedToTranspose = (    (int(Dst::RowsAtCompileTime) == 1 && int(Src::ColsAtCompileTime) == 1)
-                        || (int(Dst::ColsAtCompileTime) == 1 && int(Src::RowsAtCompileTime) == 1)
-                      ) && int(Dst::SizeAtCompileTime) != 1
-  };
-
-  typedef typename internal::conditional<NeedToTranspose, Transpose<Dst>, Dst>::type ActualDstTypeCleaned;
-  typedef typename internal::conditional<NeedToTranspose, Transpose<Dst>, Dst&>::type ActualDstType;
-  ActualDstType actualDst(dst);
-  
-  // TODO check whether this is the right place to perform these checks:
-  EIGEN_STATIC_ASSERT_LVALUE(Dst)
-  EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(ActualDstTypeCleaned,Src)
-  EIGEN_CHECK_BINARY_COMPATIBILIY(Func,typename ActualDstTypeCleaned::Scalar,typename Src::Scalar);
-  
-  Assignment<ActualDstTypeCleaned,Src,Func>::run(actualDst, src, func);
-}
-template<typename Dst, typename Src>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-void call_assignment_no_alias(Dst& dst, const Src& src)
-{
-  call_assignment_no_alias(dst, src, internal::assign_op<typename Dst::Scalar,typename Src::Scalar>());
-}
-
-template<typename Dst, typename Src, typename Func>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-void call_assignment_no_alias_no_transpose(Dst& dst, const Src& src, const Func& func)
-{
-  // TODO check whether this is the right place to perform these checks:
-  EIGEN_STATIC_ASSERT_LVALUE(Dst)
-  EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Dst,Src)
-  EIGEN_CHECK_BINARY_COMPATIBILIY(Func,typename Dst::Scalar,typename Src::Scalar);
-
-  Assignment<Dst,Src,Func>::run(dst, src, func);
-}
-template<typename Dst, typename Src>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-void call_assignment_no_alias_no_transpose(Dst& dst, const Src& src)
-{
-  call_assignment_no_alias_no_transpose(dst, src, internal::assign_op<typename Dst::Scalar,typename Src::Scalar>());
-}
-
-// forward declaration
-template<typename Dst, typename Src> void check_for_aliasing(const Dst &dst, const Src &src);
-
-// Generic Dense to Dense assignment
-// Note that the last template argument "Weak" is needed to make it possible to perform
-// both partial specialization+SFINAE without ambiguous specialization
-template< typename DstXprType, typename SrcXprType, typename Functor, typename Weak>
-struct Assignment<DstXprType, SrcXprType, Functor, Dense2Dense, Weak>
-{
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
-  {
-#ifndef EIGEN_NO_DEBUG
-    internal::check_for_aliasing(dst, src);
-#endif
-    
-    call_dense_assignment_loop(dst, src, func);
-  }
-};
-
-// Generic assignment through evalTo.
-// TODO: not sure we have to keep that one, but it helps porting current code to new evaluator mechanism.
-// Note that the last template argument "Weak" is needed to make it possible to perform
-// both partial specialization+SFINAE without ambiguous specialization
-template< typename DstXprType, typename SrcXprType, typename Functor, typename Weak>
-struct Assignment<DstXprType, SrcXprType, Functor, EigenBase2EigenBase, Weak>
-{
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar> &/*func*/)
-  {
-    Index dstRows = src.rows();
-    Index dstCols = src.cols();
-    if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
-      dst.resize(dstRows, dstCols);
-
-    eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
-    src.evalTo(dst);
-  }
-
-  // NOTE The following two functions are templated to avoid their instanciation if not needed
-  //      This is needed because some expressions supports evalTo only and/or have 'void' as scalar type.
-  template<typename SrcScalarType>
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<typename DstXprType::Scalar,SrcScalarType> &/*func*/)
-  {
-    Index dstRows = src.rows();
-    Index dstCols = src.cols();
-    if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
-      dst.resize(dstRows, dstCols);
-
-    eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
-    src.addTo(dst);
-  }
-
-  template<typename SrcScalarType>
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<typename DstXprType::Scalar,SrcScalarType> &/*func*/)
-  {
-    Index dstRows = src.rows();
-    Index dstCols = src.cols();
-    if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
-      dst.resize(dstRows, dstCols);
-
-    eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
-    src.subTo(dst);
-  }
-};
-
-} // namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_ASSIGN_EVALUATOR_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Assign_MKL.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Assign_MKL.h
deleted file mode 100644
index 6866095..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Assign_MKL.h
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- Copyright (c) 2011, Intel Corporation. All rights reserved.
- Copyright (C) 2015 Gael Guennebaud <gael.guennebaud@inria.fr>
- 
- Redistribution and use in source and binary forms, with or without modification,
- are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice, this
-   list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
-   this list of conditions and the following disclaimer in the documentation
-   and/or other materials provided with the distribution.
- * Neither the name of Intel Corporation nor the names of its contributors may
-   be used to endorse or promote products derived from this software without
-   specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- ********************************************************************************
- *   Content : Eigen bindings to Intel(R) MKL
- *   MKL VML support for coefficient-wise unary Eigen expressions like a=b.sin()
- ********************************************************************************
-*/
-
-#ifndef EIGEN_ASSIGN_VML_H
-#define EIGEN_ASSIGN_VML_H
-
-namespace Eigen { 
-
-namespace internal {
-
-template<typename Dst, typename Src>
-class vml_assign_traits
-{
-  private:
-    enum {
-      DstHasDirectAccess = Dst::Flags & DirectAccessBit,
-      SrcHasDirectAccess = Src::Flags & DirectAccessBit,
-      StorageOrdersAgree = (int(Dst::IsRowMajor) == int(Src::IsRowMajor)),
-      InnerSize = int(Dst::IsVectorAtCompileTime) ? int(Dst::SizeAtCompileTime)
-                : int(Dst::Flags)&RowMajorBit ? int(Dst::ColsAtCompileTime)
-                : int(Dst::RowsAtCompileTime),
-      InnerMaxSize  = int(Dst::IsVectorAtCompileTime) ? int(Dst::MaxSizeAtCompileTime)
-                    : int(Dst::Flags)&RowMajorBit ? int(Dst::MaxColsAtCompileTime)
-                    : int(Dst::MaxRowsAtCompileTime),
-      MaxSizeAtCompileTime = Dst::SizeAtCompileTime,
-
-      MightEnableVml = StorageOrdersAgree && DstHasDirectAccess && SrcHasDirectAccess && Src::InnerStrideAtCompileTime==1 && Dst::InnerStrideAtCompileTime==1,
-      MightLinearize = MightEnableVml && (int(Dst::Flags) & int(Src::Flags) & LinearAccessBit),
-      VmlSize = MightLinearize ? MaxSizeAtCompileTime : InnerMaxSize,
-      LargeEnough = VmlSize==Dynamic || VmlSize>=EIGEN_MKL_VML_THRESHOLD
-    };
-  public:
-    enum {
-      EnableVml = MightEnableVml && LargeEnough,
-      Traversal = MightLinearize ? LinearTraversal : DefaultTraversal
-    };
-};
-
-#define EIGEN_PP_EXPAND(ARG) ARG
-#if !defined (EIGEN_FAST_MATH) || (EIGEN_FAST_MATH != 1)
-#define EIGEN_VMLMODE_EXPAND_LA , VML_HA
-#else
-#define EIGEN_VMLMODE_EXPAND_LA , VML_LA
-#endif
-
-#define EIGEN_VMLMODE_EXPAND__ 
-
-#define EIGEN_VMLMODE_PREFIX_LA vm
-#define EIGEN_VMLMODE_PREFIX__  v
-#define EIGEN_VMLMODE_PREFIX(VMLMODE) EIGEN_CAT(EIGEN_VMLMODE_PREFIX_,VMLMODE)
-
-#define EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE, VMLMODE)                                           \
-  template< typename DstXprType, typename SrcXprNested>                                                                         \
-  struct Assignment<DstXprType, CwiseUnaryOp<scalar_##EIGENOP##_op<EIGENTYPE>, SrcXprNested>, assign_op<EIGENTYPE,EIGENTYPE>,   \
-                   Dense2Dense, typename enable_if<vml_assign_traits<DstXprType,SrcXprNested>::EnableVml>::type> {              \
-    typedef CwiseUnaryOp<scalar_##EIGENOP##_op<EIGENTYPE>, SrcXprNested> SrcXprType;                                            \
-    static void run(DstXprType &dst, const SrcXprType &src, const assign_op<EIGENTYPE,EIGENTYPE> &func) {                       \
-      resize_if_allowed(dst, src, func);                                                                                        \
-      eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());                                                       \
-      if(vml_assign_traits<DstXprType,SrcXprNested>::Traversal==LinearTraversal) {                                              \
-        VMLOP(dst.size(), (const VMLTYPE*)src.nestedExpression().data(),                                                        \
-              (VMLTYPE*)dst.data() EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_##VMLMODE) );                                           \
-      } else {                                                                                                                  \
-        const Index outerSize = dst.outerSize();                                                                                \
-        for(Index outer = 0; outer < outerSize; ++outer) {                                                                      \
-          const EIGENTYPE *src_ptr = src.IsRowMajor ? &(src.nestedExpression().coeffRef(outer,0)) :                             \
-                                                      &(src.nestedExpression().coeffRef(0, outer));                             \
-          EIGENTYPE *dst_ptr = dst.IsRowMajor ? &(dst.coeffRef(outer,0)) : &(dst.coeffRef(0, outer));                           \
-          VMLOP( dst.innerSize(), (const VMLTYPE*)src_ptr,                                                                      \
-                (VMLTYPE*)dst_ptr EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_##VMLMODE));                                             \
-        }                                                                                                                       \
-      }                                                                                                                         \
-    }                                                                                                                           \
-  };                                                                                                                            \
-
-
-#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(EIGENOP, VMLOP, VMLMODE)                                                         \
-  EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, EIGEN_CAT(EIGEN_VMLMODE_PREFIX(VMLMODE),s##VMLOP), float, float, VMLMODE)           \
-  EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, EIGEN_CAT(EIGEN_VMLMODE_PREFIX(VMLMODE),d##VMLOP), double, double, VMLMODE)
-
-#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS_CPLX(EIGENOP, VMLOP, VMLMODE)                                                         \
-  EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, EIGEN_CAT(EIGEN_VMLMODE_PREFIX(VMLMODE),c##VMLOP), scomplex, MKL_Complex8, VMLMODE) \
-  EIGEN_MKL_VML_DECLARE_UNARY_CALL(EIGENOP, EIGEN_CAT(EIGEN_VMLMODE_PREFIX(VMLMODE),z##VMLOP), dcomplex, MKL_Complex16, VMLMODE)
-  
-#define EIGEN_MKL_VML_DECLARE_UNARY_CALLS(EIGENOP, VMLOP, VMLMODE)                                                              \
-  EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(EIGENOP, VMLOP, VMLMODE)                                                               \
-  EIGEN_MKL_VML_DECLARE_UNARY_CALLS_CPLX(EIGENOP, VMLOP, VMLMODE)
-
-  
-EIGEN_MKL_VML_DECLARE_UNARY_CALLS(sin,   Sin,   LA)
-EIGEN_MKL_VML_DECLARE_UNARY_CALLS(asin,  Asin,  LA)
-EIGEN_MKL_VML_DECLARE_UNARY_CALLS(sinh,  Sinh,  LA)
-EIGEN_MKL_VML_DECLARE_UNARY_CALLS(cos,   Cos,   LA)
-EIGEN_MKL_VML_DECLARE_UNARY_CALLS(acos,  Acos,  LA)
-EIGEN_MKL_VML_DECLARE_UNARY_CALLS(cosh,  Cosh,  LA)
-EIGEN_MKL_VML_DECLARE_UNARY_CALLS(tan,   Tan,   LA)
-EIGEN_MKL_VML_DECLARE_UNARY_CALLS(atan,  Atan,  LA)
-EIGEN_MKL_VML_DECLARE_UNARY_CALLS(tanh,  Tanh,  LA)
-// EIGEN_MKL_VML_DECLARE_UNARY_CALLS(abs,   Abs,    _)
-EIGEN_MKL_VML_DECLARE_UNARY_CALLS(exp,   Exp,   LA)
-EIGEN_MKL_VML_DECLARE_UNARY_CALLS(log,   Ln,    LA)
-EIGEN_MKL_VML_DECLARE_UNARY_CALLS(log10, Log10, LA)
-EIGEN_MKL_VML_DECLARE_UNARY_CALLS(sqrt,  Sqrt,  _)
-
-EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(square, Sqr,   _)
-EIGEN_MKL_VML_DECLARE_UNARY_CALLS_CPLX(arg, Arg,      _)
-EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(round, Round,  _)
-EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(floor, Floor,  _)
-EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(ceil,  Ceil,   _)
-
-#define EIGEN_MKL_VML_DECLARE_POW_CALL(EIGENOP, VMLOP, EIGENTYPE, VMLTYPE, VMLMODE)                                           \
-  template< typename DstXprType, typename SrcXprNested, typename Plain>                                                       \
-  struct Assignment<DstXprType, CwiseBinaryOp<scalar_##EIGENOP##_op<EIGENTYPE,EIGENTYPE>, SrcXprNested,                       \
-                    const CwiseNullaryOp<internal::scalar_constant_op<EIGENTYPE>,Plain> >, assign_op<EIGENTYPE,EIGENTYPE>,    \
-                   Dense2Dense, typename enable_if<vml_assign_traits<DstXprType,SrcXprNested>::EnableVml>::type> {            \
-    typedef CwiseBinaryOp<scalar_##EIGENOP##_op<EIGENTYPE,EIGENTYPE>, SrcXprNested,                                           \
-                    const CwiseNullaryOp<internal::scalar_constant_op<EIGENTYPE>,Plain> > SrcXprType;                         \
-    static void run(DstXprType &dst, const SrcXprType &src, const assign_op<EIGENTYPE,EIGENTYPE> &func) {                     \
-      resize_if_allowed(dst, src, func);                                                                                      \
-      eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());                                                     \
-      VMLTYPE exponent = reinterpret_cast<const VMLTYPE&>(src.rhs().functor().m_other);                                       \
-      if(vml_assign_traits<DstXprType,SrcXprNested>::Traversal==LinearTraversal)                                              \
-      {                                                                                                                       \
-        VMLOP( dst.size(), (const VMLTYPE*)src.lhs().data(), exponent,                                                        \
-              (VMLTYPE*)dst.data() EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_##VMLMODE) );                                         \
-      } else {                                                                                                                \
-        const Index outerSize = dst.outerSize();                                                                              \
-        for(Index outer = 0; outer < outerSize; ++outer) {                                                                    \
-          const EIGENTYPE *src_ptr = src.IsRowMajor ? &(src.lhs().coeffRef(outer,0)) :                                        \
-                                                      &(src.lhs().coeffRef(0, outer));                                        \
-          EIGENTYPE *dst_ptr = dst.IsRowMajor ? &(dst.coeffRef(outer,0)) : &(dst.coeffRef(0, outer));                         \
-          VMLOP( dst.innerSize(), (const VMLTYPE*)src_ptr, exponent,                                                          \
-                 (VMLTYPE*)dst_ptr EIGEN_PP_EXPAND(EIGEN_VMLMODE_EXPAND_##VMLMODE));                                          \
-        }                                                                                                                     \
-      }                                                                                                                       \
-    }                                                                                                                         \
-  };
-  
-EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmsPowx, float,    float,         LA)
-EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmdPowx, double,   double,        LA)
-EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmcPowx, scomplex, MKL_Complex8,  LA)
-EIGEN_MKL_VML_DECLARE_POW_CALL(pow, vmzPowx, dcomplex, MKL_Complex16, LA)
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_ASSIGN_VML_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/BandMatrix.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/BandMatrix.h
deleted file mode 100644
index 4978c91..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/BandMatrix.h
+++ /dev/null
@@ -1,353 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_BANDMATRIX_H
-#define EIGEN_BANDMATRIX_H
-
-namespace Eigen { 
-
-namespace internal {
-
-template<typename Derived>
-class BandMatrixBase : public EigenBase<Derived>
-{
-  public:
-
-    enum {
-      Flags = internal::traits<Derived>::Flags,
-      CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
-      RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
-      ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
-      MaxRowsAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime,
-      MaxColsAtCompileTime = internal::traits<Derived>::MaxColsAtCompileTime,
-      Supers = internal::traits<Derived>::Supers,
-      Subs   = internal::traits<Derived>::Subs,
-      Options = internal::traits<Derived>::Options
-    };
-    typedef typename internal::traits<Derived>::Scalar Scalar;
-    typedef Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> DenseMatrixType;
-    typedef typename DenseMatrixType::StorageIndex StorageIndex;
-    typedef typename internal::traits<Derived>::CoefficientsType CoefficientsType;
-    typedef EigenBase<Derived> Base;
-
-  protected:
-    enum {
-      DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic))
-                            ? 1 + Supers + Subs
-                            : Dynamic,
-      SizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime,ColsAtCompileTime)
-    };
-
-  public:
-    
-    using Base::derived;
-    using Base::rows;
-    using Base::cols;
-
-    /** \returns the number of super diagonals */
-    inline Index supers() const { return derived().supers(); }
-
-    /** \returns the number of sub diagonals */
-    inline Index subs() const { return derived().subs(); }
-    
-    /** \returns an expression of the underlying coefficient matrix */
-    inline const CoefficientsType& coeffs() const { return derived().coeffs(); }
-    
-    /** \returns an expression of the underlying coefficient matrix */
-    inline CoefficientsType& coeffs() { return derived().coeffs(); }
-
-    /** \returns a vector expression of the \a i -th column,
-      * only the meaningful part is returned.
-      * \warning the internal storage must be column major. */
-    inline Block<CoefficientsType,Dynamic,1> col(Index i)
-    {
-      EIGEN_STATIC_ASSERT((Options&RowMajor)==0,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
-      Index start = 0;
-      Index len = coeffs().rows();
-      if (i<=supers())
-      {
-        start = supers()-i;
-        len = (std::min)(rows(),std::max<Index>(0,coeffs().rows() - (supers()-i)));
-      }
-      else if (i>=rows()-subs())
-        len = std::max<Index>(0,coeffs().rows() - (i + 1 - rows() + subs()));
-      return Block<CoefficientsType,Dynamic,1>(coeffs(), start, i, len, 1);
-    }
-
-    /** \returns a vector expression of the main diagonal */
-    inline Block<CoefficientsType,1,SizeAtCompileTime> diagonal()
-    { return Block<CoefficientsType,1,SizeAtCompileTime>(coeffs(),supers(),0,1,(std::min)(rows(),cols())); }
-
-    /** \returns a vector expression of the main diagonal (const version) */
-    inline const Block<const CoefficientsType,1,SizeAtCompileTime> diagonal() const
-    { return Block<const CoefficientsType,1,SizeAtCompileTime>(coeffs(),supers(),0,1,(std::min)(rows(),cols())); }
-
-    template<int Index> struct DiagonalIntReturnType {
-      enum {
-        ReturnOpposite = (Options&SelfAdjoint) && (((Index)>0 && Supers==0) || ((Index)<0 && Subs==0)),
-        Conjugate = ReturnOpposite && NumTraits<Scalar>::IsComplex,
-        ActualIndex = ReturnOpposite ? -Index : Index,
-        DiagonalSize = (RowsAtCompileTime==Dynamic || ColsAtCompileTime==Dynamic)
-                     ? Dynamic
-                     : (ActualIndex<0
-                     ? EIGEN_SIZE_MIN_PREFER_DYNAMIC(ColsAtCompileTime, RowsAtCompileTime + ActualIndex)
-                     : EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime, ColsAtCompileTime - ActualIndex))
-      };
-      typedef Block<CoefficientsType,1, DiagonalSize> BuildType;
-      typedef typename internal::conditional<Conjugate,
-                 CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>,BuildType >,
-                 BuildType>::type Type;
-    };
-
-    /** \returns a vector expression of the \a N -th sub or super diagonal */
-    template<int N> inline typename DiagonalIntReturnType<N>::Type diagonal()
-    {
-      return typename DiagonalIntReturnType<N>::BuildType(coeffs(), supers()-N, (std::max)(0,N), 1, diagonalLength(N));
-    }
-
-    /** \returns a vector expression of the \a N -th sub or super diagonal */
-    template<int N> inline const typename DiagonalIntReturnType<N>::Type diagonal() const
-    {
-      return typename DiagonalIntReturnType<N>::BuildType(coeffs(), supers()-N, (std::max)(0,N), 1, diagonalLength(N));
-    }
-
-    /** \returns a vector expression of the \a i -th sub or super diagonal */
-    inline Block<CoefficientsType,1,Dynamic> diagonal(Index i)
-    {
-      eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers()));
-      return Block<CoefficientsType,1,Dynamic>(coeffs(), supers()-i, std::max<Index>(0,i), 1, diagonalLength(i));
-    }
-
-    /** \returns a vector expression of the \a i -th sub or super diagonal */
-    inline const Block<const CoefficientsType,1,Dynamic> diagonal(Index i) const
-    {
-      eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers()));
-      return Block<const CoefficientsType,1,Dynamic>(coeffs(), supers()-i, std::max<Index>(0,i), 1, diagonalLength(i));
-    }
-    
-    template<typename Dest> inline void evalTo(Dest& dst) const
-    {
-      dst.resize(rows(),cols());
-      dst.setZero();
-      dst.diagonal() = diagonal();
-      for (Index i=1; i<=supers();++i)
-        dst.diagonal(i) = diagonal(i);
-      for (Index i=1; i<=subs();++i)
-        dst.diagonal(-i) = diagonal(-i);
-    }
-
-    DenseMatrixType toDenseMatrix() const
-    {
-      DenseMatrixType res(rows(),cols());
-      evalTo(res);
-      return res;
-    }
-
-  protected:
-
-    inline Index diagonalLength(Index i) const
-    { return i<0 ? (std::min)(cols(),rows()+i) : (std::min)(rows(),cols()-i); }
-};
-
-/**
-  * \class BandMatrix
-  * \ingroup Core_Module
-  *
-  * \brief Represents a rectangular matrix with a banded storage
-  *
-  * \tparam _Scalar Numeric type, i.e. float, double, int
-  * \tparam _Rows Number of rows, or \b Dynamic
-  * \tparam _Cols Number of columns, or \b Dynamic
-  * \tparam _Supers Number of super diagonal
-  * \tparam _Subs Number of sub diagonal
-  * \tparam _Options A combination of either \b #RowMajor or \b #ColMajor, and of \b #SelfAdjoint
-  *                  The former controls \ref TopicStorageOrders "storage order", and defaults to
-  *                  column-major. The latter controls whether the matrix represents a selfadjoint
-  *                  matrix in which case either Supers of Subs have to be null.
-  *
-  * \sa class TridiagonalMatrix
-  */
-
-template<typename _Scalar, int _Rows, int _Cols, int _Supers, int _Subs, int _Options>
-struct traits<BandMatrix<_Scalar,_Rows,_Cols,_Supers,_Subs,_Options> >
-{
-  typedef _Scalar Scalar;
-  typedef Dense StorageKind;
-  typedef Eigen::Index StorageIndex;
-  enum {
-    CoeffReadCost = NumTraits<Scalar>::ReadCost,
-    RowsAtCompileTime = _Rows,
-    ColsAtCompileTime = _Cols,
-    MaxRowsAtCompileTime = _Rows,
-    MaxColsAtCompileTime = _Cols,
-    Flags = LvalueBit,
-    Supers = _Supers,
-    Subs = _Subs,
-    Options = _Options,
-    DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) ? 1 + Supers + Subs : Dynamic
-  };
-  typedef Matrix<Scalar,DataRowsAtCompileTime,ColsAtCompileTime,Options&RowMajor?RowMajor:ColMajor> CoefficientsType;
-};
-
-template<typename _Scalar, int Rows, int Cols, int Supers, int Subs, int Options>
-class BandMatrix : public BandMatrixBase<BandMatrix<_Scalar,Rows,Cols,Supers,Subs,Options> >
-{
-  public:
-
-    typedef typename internal::traits<BandMatrix>::Scalar Scalar;
-    typedef typename internal::traits<BandMatrix>::StorageIndex StorageIndex;
-    typedef typename internal::traits<BandMatrix>::CoefficientsType CoefficientsType;
-
-    explicit inline BandMatrix(Index rows=Rows, Index cols=Cols, Index supers=Supers, Index subs=Subs)
-      : m_coeffs(1+supers+subs,cols),
-        m_rows(rows), m_supers(supers), m_subs(subs)
-    {
-    }
-
-    /** \returns the number of columns */
-    inline Index rows() const { return m_rows.value(); }
-
-    /** \returns the number of rows */
-    inline Index cols() const { return m_coeffs.cols(); }
-
-    /** \returns the number of super diagonals */
-    inline Index supers() const { return m_supers.value(); }
-
-    /** \returns the number of sub diagonals */
-    inline Index subs() const { return m_subs.value(); }
-
-    inline const CoefficientsType& coeffs() const { return m_coeffs; }
-    inline CoefficientsType& coeffs() { return m_coeffs; }
-
-  protected:
-
-    CoefficientsType m_coeffs;
-    internal::variable_if_dynamic<Index, Rows>   m_rows;
-    internal::variable_if_dynamic<Index, Supers> m_supers;
-    internal::variable_if_dynamic<Index, Subs>   m_subs;
-};
-
-template<typename _CoefficientsType,int _Rows, int _Cols, int _Supers, int _Subs,int _Options>
-class BandMatrixWrapper;
-
-template<typename _CoefficientsType,int _Rows, int _Cols, int _Supers, int _Subs,int _Options>
-struct traits<BandMatrixWrapper<_CoefficientsType,_Rows,_Cols,_Supers,_Subs,_Options> >
-{
-  typedef typename _CoefficientsType::Scalar Scalar;
-  typedef typename _CoefficientsType::StorageKind StorageKind;
-  typedef typename _CoefficientsType::StorageIndex StorageIndex;
-  enum {
-    CoeffReadCost = internal::traits<_CoefficientsType>::CoeffReadCost,
-    RowsAtCompileTime = _Rows,
-    ColsAtCompileTime = _Cols,
-    MaxRowsAtCompileTime = _Rows,
-    MaxColsAtCompileTime = _Cols,
-    Flags = LvalueBit,
-    Supers = _Supers,
-    Subs = _Subs,
-    Options = _Options,
-    DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) ? 1 + Supers + Subs : Dynamic
-  };
-  typedef _CoefficientsType CoefficientsType;
-};
-
-template<typename _CoefficientsType,int _Rows, int _Cols, int _Supers, int _Subs,int _Options>
-class BandMatrixWrapper : public BandMatrixBase<BandMatrixWrapper<_CoefficientsType,_Rows,_Cols,_Supers,_Subs,_Options> >
-{
-  public:
-
-    typedef typename internal::traits<BandMatrixWrapper>::Scalar Scalar;
-    typedef typename internal::traits<BandMatrixWrapper>::CoefficientsType CoefficientsType;
-    typedef typename internal::traits<BandMatrixWrapper>::StorageIndex StorageIndex;
-
-    explicit inline BandMatrixWrapper(const CoefficientsType& coeffs, Index rows=_Rows, Index cols=_Cols, Index supers=_Supers, Index subs=_Subs)
-      : m_coeffs(coeffs),
-        m_rows(rows), m_supers(supers), m_subs(subs)
-    {
-      EIGEN_UNUSED_VARIABLE(cols);
-      //internal::assert(coeffs.cols()==cols() && (supers()+subs()+1)==coeffs.rows());
-    }
-
-    /** \returns the number of columns */
-    inline Index rows() const { return m_rows.value(); }
-
-    /** \returns the number of rows */
-    inline Index cols() const { return m_coeffs.cols(); }
-
-    /** \returns the number of super diagonals */
-    inline Index supers() const { return m_supers.value(); }
-
-    /** \returns the number of sub diagonals */
-    inline Index subs() const { return m_subs.value(); }
-
-    inline const CoefficientsType& coeffs() const { return m_coeffs; }
-
-  protected:
-
-    const CoefficientsType& m_coeffs;
-    internal::variable_if_dynamic<Index, _Rows>   m_rows;
-    internal::variable_if_dynamic<Index, _Supers> m_supers;
-    internal::variable_if_dynamic<Index, _Subs>   m_subs;
-};
-
-/**
-  * \class TridiagonalMatrix
-  * \ingroup Core_Module
-  *
-  * \brief Represents a tridiagonal matrix with a compact banded storage
-  *
-  * \tparam Scalar Numeric type, i.e. float, double, int
-  * \tparam Size Number of rows and cols, or \b Dynamic
-  * \tparam Options Can be 0 or \b SelfAdjoint
-  *
-  * \sa class BandMatrix
-  */
-template<typename Scalar, int Size, int Options>
-class TridiagonalMatrix : public BandMatrix<Scalar,Size,Size,Options&SelfAdjoint?0:1,1,Options|RowMajor>
-{
-    typedef BandMatrix<Scalar,Size,Size,Options&SelfAdjoint?0:1,1,Options|RowMajor> Base;
-    typedef typename Base::StorageIndex StorageIndex;
-  public:
-    explicit TridiagonalMatrix(Index size = Size) : Base(size,size,Options&SelfAdjoint?0:1,1) {}
-
-    inline typename Base::template DiagonalIntReturnType<1>::Type super()
-    { return Base::template diagonal<1>(); }
-    inline const typename Base::template DiagonalIntReturnType<1>::Type super() const
-    { return Base::template diagonal<1>(); }
-    inline typename Base::template DiagonalIntReturnType<-1>::Type sub()
-    { return Base::template diagonal<-1>(); }
-    inline const typename Base::template DiagonalIntReturnType<-1>::Type sub() const
-    { return Base::template diagonal<-1>(); }
-  protected:
-};
-
-
-struct BandShape {};
-
-template<typename _Scalar, int _Rows, int _Cols, int _Supers, int _Subs, int _Options>
-struct evaluator_traits<BandMatrix<_Scalar,_Rows,_Cols,_Supers,_Subs,_Options> >
-  : public evaluator_traits_base<BandMatrix<_Scalar,_Rows,_Cols,_Supers,_Subs,_Options> >
-{
-  typedef BandShape Shape;
-};
-
-template<typename _CoefficientsType,int _Rows, int _Cols, int _Supers, int _Subs,int _Options>
-struct evaluator_traits<BandMatrixWrapper<_CoefficientsType,_Rows,_Cols,_Supers,_Subs,_Options> >
-  : public evaluator_traits_base<BandMatrixWrapper<_CoefficientsType,_Rows,_Cols,_Supers,_Subs,_Options> >
-{
-  typedef BandShape Shape;
-};
-
-template<> struct AssignmentKind<DenseShape,BandShape> { typedef EigenBase2EigenBase Kind; };
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_BANDMATRIX_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Block.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Block.h
deleted file mode 100644
index 11de45c..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Block.h
+++ /dev/null
@@ -1,452 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_BLOCK_H
-#define EIGEN_BLOCK_H
-
-namespace Eigen { 
-
-namespace internal {
-template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
-struct traits<Block<XprType, BlockRows, BlockCols, InnerPanel> > : traits<XprType>
-{
-  typedef typename traits<XprType>::Scalar Scalar;
-  typedef typename traits<XprType>::StorageKind StorageKind;
-  typedef typename traits<XprType>::XprKind XprKind;
-  typedef typename ref_selector<XprType>::type XprTypeNested;
-  typedef typename remove_reference<XprTypeNested>::type _XprTypeNested;
-  enum{
-    MatrixRows = traits<XprType>::RowsAtCompileTime,
-    MatrixCols = traits<XprType>::ColsAtCompileTime,
-    RowsAtCompileTime = MatrixRows == 0 ? 0 : BlockRows,
-    ColsAtCompileTime = MatrixCols == 0 ? 0 : BlockCols,
-    MaxRowsAtCompileTime = BlockRows==0 ? 0
-                         : RowsAtCompileTime != Dynamic ? int(RowsAtCompileTime)
-                         : int(traits<XprType>::MaxRowsAtCompileTime),
-    MaxColsAtCompileTime = BlockCols==0 ? 0
-                         : ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime)
-                         : int(traits<XprType>::MaxColsAtCompileTime),
-
-    XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0,
-    IsRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1
-               : (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
-               : XprTypeIsRowMajor,
-    HasSameStorageOrderAsXprType = (IsRowMajor == XprTypeIsRowMajor),
-    InnerSize = IsRowMajor ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
-    InnerStrideAtCompileTime = HasSameStorageOrderAsXprType
-                             ? int(inner_stride_at_compile_time<XprType>::ret)
-                             : int(outer_stride_at_compile_time<XprType>::ret),
-    OuterStrideAtCompileTime = HasSameStorageOrderAsXprType
-                             ? int(outer_stride_at_compile_time<XprType>::ret)
-                             : int(inner_stride_at_compile_time<XprType>::ret),
-
-    // FIXME, this traits is rather specialized for dense object and it needs to be cleaned further
-    FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0,
-    FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0,
-    Flags = (traits<XprType>::Flags & (DirectAccessBit | (InnerPanel?CompressedAccessBit:0))) | FlagsLvalueBit | FlagsRowMajorBit,
-    // FIXME DirectAccessBit should not be handled by expressions
-    // 
-    // Alignment is needed by MapBase's assertions
-    // We can sefely set it to false here. Internal alignment errors will be detected by an eigen_internal_assert in the respective evaluator
-    Alignment = 0
-  };
-};
-
-template<typename XprType, int BlockRows=Dynamic, int BlockCols=Dynamic, bool InnerPanel = false,
-         bool HasDirectAccess = internal::has_direct_access<XprType>::ret> class BlockImpl_dense;
-         
-} // end namespace internal
-
-template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, typename StorageKind> class BlockImpl;
-
-/** \class Block
-  * \ingroup Core_Module
-  *
-  * \brief Expression of a fixed-size or dynamic-size block
-  *
-  * \tparam XprType the type of the expression in which we are taking a block
-  * \tparam BlockRows the number of rows of the block we are taking at compile time (optional)
-  * \tparam BlockCols the number of columns of the block we are taking at compile time (optional)
-  * \tparam InnerPanel is true, if the block maps to a set of rows of a row major matrix or
-  *         to set of columns of a column major matrix (optional). The parameter allows to determine
-  *         at compile time whether aligned access is possible on the block expression.
-  *
-  * This class represents an expression of either a fixed-size or dynamic-size block. It is the return
-  * type of DenseBase::block(Index,Index,Index,Index) and DenseBase::block<int,int>(Index,Index) and
-  * most of the time this is the only way it is used.
-  *
-  * However, if you want to directly maniputate block expressions,
-  * for instance if you want to write a function returning such an expression, you
-  * will need to use this class.
-  *
-  * Here is an example illustrating the dynamic case:
-  * \include class_Block.cpp
-  * Output: \verbinclude class_Block.out
-  *
-  * \note Even though this expression has dynamic size, in the case where \a XprType
-  * has fixed size, this expression inherits a fixed maximal size which means that evaluating
-  * it does not cause a dynamic memory allocation.
-  *
-  * Here is an example illustrating the fixed-size case:
-  * \include class_FixedBlock.cpp
-  * Output: \verbinclude class_FixedBlock.out
-  *
-  * \sa DenseBase::block(Index,Index,Index,Index), DenseBase::block(Index,Index), class VectorBlock
-  */
-template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> class Block
-  : public BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, typename internal::traits<XprType>::StorageKind>
-{
-    typedef BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, typename internal::traits<XprType>::StorageKind> Impl;
-  public:
-    //typedef typename Impl::Base Base;
-    typedef Impl Base;
-    EIGEN_GENERIC_PUBLIC_INTERFACE(Block)
-    EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)
-    
-    typedef typename internal::remove_all<XprType>::type NestedExpression;
-  
-    /** Column or Row constructor
-      */
-    EIGEN_DEVICE_FUNC
-    inline Block(XprType& xpr, Index i) : Impl(xpr,i)
-    {
-      eigen_assert( (i>=0) && (
-          ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && i<xpr.rows())
-        ||((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && i<xpr.cols())));
-    }
-
-    /** Fixed-size constructor
-      */
-    EIGEN_DEVICE_FUNC
-    inline Block(XprType& xpr, Index startRow, Index startCol)
-      : Impl(xpr, startRow, startCol)
-    {
-      EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
-      eigen_assert(startRow >= 0 && BlockRows >= 0 && startRow + BlockRows <= xpr.rows()
-             && startCol >= 0 && BlockCols >= 0 && startCol + BlockCols <= xpr.cols());
-    }
-
-    /** Dynamic-size constructor
-      */
-    EIGEN_DEVICE_FUNC
-    inline Block(XprType& xpr,
-          Index startRow, Index startCol,
-          Index blockRows, Index blockCols)
-      : Impl(xpr, startRow, startCol, blockRows, blockCols)
-    {
-      eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
-          && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols));
-      eigen_assert(startRow >= 0 && blockRows >= 0 && startRow  <= xpr.rows() - blockRows
-          && startCol >= 0 && blockCols >= 0 && startCol <= xpr.cols() - blockCols);
-    }
-};
-         
-// The generic default implementation for dense block simplu forward to the internal::BlockImpl_dense
-// that must be specialized for direct and non-direct access...
-template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
-class BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, Dense>
-  : public internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel>
-{
-    typedef internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel> Impl;
-    typedef typename XprType::StorageIndex StorageIndex;
-  public:
-    typedef Impl Base;
-    EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl)
-    EIGEN_DEVICE_FUNC inline BlockImpl(XprType& xpr, Index i) : Impl(xpr,i) {}
-    EIGEN_DEVICE_FUNC inline BlockImpl(XprType& xpr, Index startRow, Index startCol) : Impl(xpr, startRow, startCol) {}
-    EIGEN_DEVICE_FUNC
-    inline BlockImpl(XprType& xpr, Index startRow, Index startCol, Index blockRows, Index blockCols)
-      : Impl(xpr, startRow, startCol, blockRows, blockCols) {}
-};
-
-namespace internal {
-
-/** \internal Internal implementation of dense Blocks in the general case. */
-template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool HasDirectAccess> class BlockImpl_dense
-  : public internal::dense_xpr_base<Block<XprType, BlockRows, BlockCols, InnerPanel> >::type
-{
-    typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType;
-    typedef typename internal::ref_selector<XprType>::non_const_type XprTypeNested;
-  public:
-
-    typedef typename internal::dense_xpr_base<BlockType>::type Base;
-    EIGEN_DENSE_PUBLIC_INTERFACE(BlockType)
-    EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense)
-
-    // class InnerIterator; // FIXME apparently never used
-
-    /** Column or Row constructor
-      */
-    EIGEN_DEVICE_FUNC
-    inline BlockImpl_dense(XprType& xpr, Index i)
-      : m_xpr(xpr),
-        // It is a row if and only if BlockRows==1 and BlockCols==XprType::ColsAtCompileTime,
-        // and it is a column if and only if BlockRows==XprType::RowsAtCompileTime and BlockCols==1,
-        // all other cases are invalid.
-        // The case a 1x1 matrix seems ambiguous, but the result is the same anyway.
-        m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0),
-        m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
-        m_blockRows(BlockRows==1 ? 1 : xpr.rows()),
-        m_blockCols(BlockCols==1 ? 1 : xpr.cols())
-    {}
-
-    /** Fixed-size constructor
-      */
-    EIGEN_DEVICE_FUNC
-    inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
-      : m_xpr(xpr), m_startRow(startRow), m_startCol(startCol),
-                    m_blockRows(BlockRows), m_blockCols(BlockCols)
-    {}
-
-    /** Dynamic-size constructor
-      */
-    EIGEN_DEVICE_FUNC
-    inline BlockImpl_dense(XprType& xpr,
-          Index startRow, Index startCol,
-          Index blockRows, Index blockCols)
-      : m_xpr(xpr), m_startRow(startRow), m_startCol(startCol),
-                    m_blockRows(blockRows), m_blockCols(blockCols)
-    {}
-
-    EIGEN_DEVICE_FUNC inline Index rows() const { return m_blockRows.value(); }
-    EIGEN_DEVICE_FUNC inline Index cols() const { return m_blockCols.value(); }
-
-    EIGEN_DEVICE_FUNC
-    inline Scalar& coeffRef(Index rowId, Index colId)
-    {
-      EIGEN_STATIC_ASSERT_LVALUE(XprType)
-      return m_xpr.coeffRef(rowId + m_startRow.value(), colId + m_startCol.value());
-    }
-
-    EIGEN_DEVICE_FUNC
-    inline const Scalar& coeffRef(Index rowId, Index colId) const
-    {
-      return m_xpr.derived().coeffRef(rowId + m_startRow.value(), colId + m_startCol.value());
-    }
-
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index rowId, Index colId) const
-    {
-      return m_xpr.coeff(rowId + m_startRow.value(), colId + m_startCol.value());
-    }
-
-    EIGEN_DEVICE_FUNC
-    inline Scalar& coeffRef(Index index)
-    {
-      EIGEN_STATIC_ASSERT_LVALUE(XprType)
-      return m_xpr.coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
-                            m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
-    }
-
-    EIGEN_DEVICE_FUNC
-    inline const Scalar& coeffRef(Index index) const
-    {
-      return m_xpr.coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
-                            m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
-    }
-
-    EIGEN_DEVICE_FUNC
-    inline const CoeffReturnType coeff(Index index) const
-    {
-      return m_xpr.coeff(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
-                         m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
-    }
-
-    template<int LoadMode>
-    inline PacketScalar packet(Index rowId, Index colId) const
-    {
-      return m_xpr.template packet<Unaligned>(rowId + m_startRow.value(), colId + m_startCol.value());
-    }
-
-    template<int LoadMode>
-    inline void writePacket(Index rowId, Index colId, const PacketScalar& val)
-    {
-      m_xpr.template writePacket<Unaligned>(rowId + m_startRow.value(), colId + m_startCol.value(), val);
-    }
-
-    template<int LoadMode>
-    inline PacketScalar packet(Index index) const
-    {
-      return m_xpr.template packet<Unaligned>
-              (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
-               m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
-    }
-
-    template<int LoadMode>
-    inline void writePacket(Index index, const PacketScalar& val)
-    {
-      m_xpr.template writePacket<Unaligned>
-         (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
-          m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0), val);
-    }
-
-    #ifdef EIGEN_PARSED_BY_DOXYGEN
-    /** \sa MapBase::data() */
-    EIGEN_DEVICE_FUNC inline const Scalar* data() const;
-    EIGEN_DEVICE_FUNC inline Index innerStride() const;
-    EIGEN_DEVICE_FUNC inline Index outerStride() const;
-    #endif
-
-    EIGEN_DEVICE_FUNC
-    const typename internal::remove_all<XprTypeNested>::type& nestedExpression() const
-    { 
-      return m_xpr; 
-    }
-
-    EIGEN_DEVICE_FUNC
-    XprType& nestedExpression() { return m_xpr; }
-      
-    EIGEN_DEVICE_FUNC
-    StorageIndex startRow() const
-    { 
-      return m_startRow.value(); 
-    }
-      
-    EIGEN_DEVICE_FUNC
-    StorageIndex startCol() const
-    { 
-      return m_startCol.value(); 
-    }
-
-  protected:
-
-    XprTypeNested m_xpr;
-    const internal::variable_if_dynamic<StorageIndex, (XprType::RowsAtCompileTime == 1 && BlockRows==1) ? 0 : Dynamic> m_startRow;
-    const internal::variable_if_dynamic<StorageIndex, (XprType::ColsAtCompileTime == 1 && BlockCols==1) ? 0 : Dynamic> m_startCol;
-    const internal::variable_if_dynamic<StorageIndex, RowsAtCompileTime> m_blockRows;
-    const internal::variable_if_dynamic<StorageIndex, ColsAtCompileTime> m_blockCols;
-};
-
-/** \internal Internal implementation of dense Blocks in the direct access case.*/
-template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
-class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
-  : public MapBase<Block<XprType, BlockRows, BlockCols, InnerPanel> >
-{
-    typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType;
-    typedef typename internal::ref_selector<XprType>::non_const_type XprTypeNested;
-    enum {
-      XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0
-    };
-  public:
-
-    typedef MapBase<BlockType> Base;
-    EIGEN_DENSE_PUBLIC_INTERFACE(BlockType)
-    EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense)
-
-    /** Column or Row constructor
-      */
-    EIGEN_DEVICE_FUNC
-    inline BlockImpl_dense(XprType& xpr, Index i)
-      : Base(xpr.data() + i * (    ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && (!XprTypeIsRowMajor)) 
-                                || ((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && ( XprTypeIsRowMajor)) ? xpr.innerStride() : xpr.outerStride()),
-             BlockRows==1 ? 1 : xpr.rows(),
-             BlockCols==1 ? 1 : xpr.cols()),
-        m_xpr(xpr),
-        m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0),
-        m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0)
-    {
-      init();
-    }
-
-    /** Fixed-size constructor
-      */
-    EIGEN_DEVICE_FUNC
-    inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
-      : Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol)),
-        m_xpr(xpr), m_startRow(startRow), m_startCol(startCol)
-    {
-      init();
-    }
-
-    /** Dynamic-size constructor
-      */
-    EIGEN_DEVICE_FUNC
-    inline BlockImpl_dense(XprType& xpr,
-          Index startRow, Index startCol,
-          Index blockRows, Index blockCols)
-      : Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol), blockRows, blockCols),
-        m_xpr(xpr), m_startRow(startRow), m_startCol(startCol)
-    {
-      init();
-    }
-
-    EIGEN_DEVICE_FUNC
-    const typename internal::remove_all<XprTypeNested>::type& nestedExpression() const
-    { 
-      return m_xpr; 
-    }
-
-    EIGEN_DEVICE_FUNC
-    XprType& nestedExpression() { return m_xpr; }
-      
-    /** \sa MapBase::innerStride() */
-    EIGEN_DEVICE_FUNC
-    inline Index innerStride() const
-    {
-      return internal::traits<BlockType>::HasSameStorageOrderAsXprType
-             ? m_xpr.innerStride()
-             : m_xpr.outerStride();
-    }
-
-    /** \sa MapBase::outerStride() */
-    EIGEN_DEVICE_FUNC
-    inline Index outerStride() const
-    {
-      return m_outerStride;
-    }
-
-    EIGEN_DEVICE_FUNC
-    StorageIndex startRow() const
-    {
-      return m_startRow.value();
-    }
-
-    EIGEN_DEVICE_FUNC
-    StorageIndex startCol() const
-    {
-      return m_startCol.value();
-    }
-
-  #ifndef __SUNPRO_CC
-  // FIXME sunstudio is not friendly with the above friend...
-  // META-FIXME there is no 'friend' keyword around here. Is this obsolete?
-  protected:
-  #endif
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    /** \internal used by allowAligned() */
-    EIGEN_DEVICE_FUNC
-    inline BlockImpl_dense(XprType& xpr, const Scalar* data, Index blockRows, Index blockCols)
-      : Base(data, blockRows, blockCols), m_xpr(xpr)
-    {
-      init();
-    }
-    #endif
-
-  protected:
-    EIGEN_DEVICE_FUNC
-    void init()
-    {
-      m_outerStride = internal::traits<BlockType>::HasSameStorageOrderAsXprType
-                    ? m_xpr.outerStride()
-                    : m_xpr.innerStride();
-    }
-
-    XprTypeNested m_xpr;
-    const internal::variable_if_dynamic<StorageIndex, (XprType::RowsAtCompileTime == 1 && BlockRows==1) ? 0 : Dynamic> m_startRow;
-    const internal::variable_if_dynamic<StorageIndex, (XprType::ColsAtCompileTime == 1 && BlockCols==1) ? 0 : Dynamic> m_startCol;
-    Index m_outerStride;
-};
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_BLOCK_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/BooleanRedux.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/BooleanRedux.h
deleted file mode 100644
index 8409d87..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/BooleanRedux.h
+++ /dev/null
@@ -1,164 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_ALLANDANY_H
-#define EIGEN_ALLANDANY_H
-
-namespace Eigen { 
-
-namespace internal {
-
-template<typename Derived, int UnrollCount>
-struct all_unroller
-{
-  typedef typename Derived::ExpressionTraits Traits;
-  enum {
-    col = (UnrollCount-1) / Traits::RowsAtCompileTime,
-    row = (UnrollCount-1) % Traits::RowsAtCompileTime
-  };
-
-  static inline bool run(const Derived &mat)
-  {
-    return all_unroller<Derived, UnrollCount-1>::run(mat) && mat.coeff(row, col);
-  }
-};
-
-template<typename Derived>
-struct all_unroller<Derived, 0>
-{
-  static inline bool run(const Derived &/*mat*/) { return true; }
-};
-
-template<typename Derived>
-struct all_unroller<Derived, Dynamic>
-{
-  static inline bool run(const Derived &) { return false; }
-};
-
-template<typename Derived, int UnrollCount>
-struct any_unroller
-{
-  typedef typename Derived::ExpressionTraits Traits;
-  enum {
-    col = (UnrollCount-1) / Traits::RowsAtCompileTime,
-    row = (UnrollCount-1) % Traits::RowsAtCompileTime
-  };
-  
-  static inline bool run(const Derived &mat)
-  {
-    return any_unroller<Derived, UnrollCount-1>::run(mat) || mat.coeff(row, col);
-  }
-};
-
-template<typename Derived>
-struct any_unroller<Derived, 0>
-{
-  static inline bool run(const Derived & /*mat*/) { return false; }
-};
-
-template<typename Derived>
-struct any_unroller<Derived, Dynamic>
-{
-  static inline bool run(const Derived &) { return false; }
-};
-
-} // end namespace internal
-
-/** \returns true if all coefficients are true
-  *
-  * Example: \include MatrixBase_all.cpp
-  * Output: \verbinclude MatrixBase_all.out
-  *
-  * \sa any(), Cwise::operator<()
-  */
-template<typename Derived>
-inline bool DenseBase<Derived>::all() const
-{
-  typedef internal::evaluator<Derived> Evaluator;
-  enum {
-    unroll = SizeAtCompileTime != Dynamic
-          && SizeAtCompileTime * (Evaluator::CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT
-  };
-  Evaluator evaluator(derived());
-  if(unroll)
-    return internal::all_unroller<Evaluator, unroll ? int(SizeAtCompileTime) : Dynamic>::run(evaluator);
-  else
-  {
-    for(Index j = 0; j < cols(); ++j)
-      for(Index i = 0; i < rows(); ++i)
-        if (!evaluator.coeff(i, j)) return false;
-    return true;
-  }
-}
-
-/** \returns true if at least one coefficient is true
-  *
-  * \sa all()
-  */
-template<typename Derived>
-inline bool DenseBase<Derived>::any() const
-{
-  typedef internal::evaluator<Derived> Evaluator;
-  enum {
-    unroll = SizeAtCompileTime != Dynamic
-          && SizeAtCompileTime * (Evaluator::CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT
-  };
-  Evaluator evaluator(derived());
-  if(unroll)
-    return internal::any_unroller<Evaluator, unroll ? int(SizeAtCompileTime) : Dynamic>::run(evaluator);
-  else
-  {
-    for(Index j = 0; j < cols(); ++j)
-      for(Index i = 0; i < rows(); ++i)
-        if (evaluator.coeff(i, j)) return true;
-    return false;
-  }
-}
-
-/** \returns the number of coefficients which evaluate to true
-  *
-  * \sa all(), any()
-  */
-template<typename Derived>
-inline Eigen::Index DenseBase<Derived>::count() const
-{
-  return derived().template cast<bool>().template cast<Index>().sum();
-}
-
-/** \returns true is \c *this contains at least one Not A Number (NaN).
-  *
-  * \sa allFinite()
-  */
-template<typename Derived>
-inline bool DenseBase<Derived>::hasNaN() const
-{
-#if EIGEN_COMP_MSVC || (defined __FAST_MATH__)
-  return derived().array().isNaN().any();
-#else
-  return !((derived().array()==derived().array()).all());
-#endif
-}
-
-/** \returns true if \c *this contains only finite numbers, i.e., no NaN and no +/-INF values.
-  *
-  * \sa hasNaN()
-  */
-template<typename Derived>
-inline bool DenseBase<Derived>::allFinite() const
-{
-#if EIGEN_COMP_MSVC || (defined __FAST_MATH__)
-  return derived().array().isFinite().all();
-#else
-  return !((derived()-derived()).hasNaN());
-#endif
-}
-    
-} // end namespace Eigen
-
-#endif // EIGEN_ALLANDANY_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/CommaInitializer.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/CommaInitializer.h
deleted file mode 100644
index d218e98..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/CommaInitializer.h
+++ /dev/null
@@ -1,160 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_COMMAINITIALIZER_H
-#define EIGEN_COMMAINITIALIZER_H
-
-namespace Eigen { 
-
-/** \class CommaInitializer
-  * \ingroup Core_Module
-  *
-  * \brief Helper class used by the comma initializer operator
-  *
-  * This class is internally used to implement the comma initializer feature. It is
-  * the return type of MatrixBase::operator<<, and most of the time this is the only
-  * way it is used.
-  *
-  * \sa \blank \ref MatrixBaseCommaInitRef "MatrixBase::operator<<", CommaInitializer::finished()
-  */
-template<typename XprType>
-struct CommaInitializer
-{
-  typedef typename XprType::Scalar Scalar;
-
-  EIGEN_DEVICE_FUNC
-  inline CommaInitializer(XprType& xpr, const Scalar& s)
-    : m_xpr(xpr), m_row(0), m_col(1), m_currentBlockRows(1)
-  {
-    m_xpr.coeffRef(0,0) = s;
-  }
-
-  template<typename OtherDerived>
-  EIGEN_DEVICE_FUNC
-  inline CommaInitializer(XprType& xpr, const DenseBase<OtherDerived>& other)
-    : m_xpr(xpr), m_row(0), m_col(other.cols()), m_currentBlockRows(other.rows())
-  {
-    m_xpr.block(0, 0, other.rows(), other.cols()) = other;
-  }
-
-  /* Copy/Move constructor which transfers ownership. This is crucial in 
-   * absence of return value optimization to avoid assertions during destruction. */
-  // FIXME in C++11 mode this could be replaced by a proper RValue constructor
-  EIGEN_DEVICE_FUNC
-  inline CommaInitializer(const CommaInitializer& o)
-  : m_xpr(o.m_xpr), m_row(o.m_row), m_col(o.m_col), m_currentBlockRows(o.m_currentBlockRows) {
-    // Mark original object as finished. In absence of R-value references we need to const_cast:
-    const_cast<CommaInitializer&>(o).m_row = m_xpr.rows();
-    const_cast<CommaInitializer&>(o).m_col = m_xpr.cols();
-    const_cast<CommaInitializer&>(o).m_currentBlockRows = 0;
-  }
-
-  /* inserts a scalar value in the target matrix */
-  EIGEN_DEVICE_FUNC
-  CommaInitializer& operator,(const Scalar& s)
-  {
-    if (m_col==m_xpr.cols())
-    {
-      m_row+=m_currentBlockRows;
-      m_col = 0;
-      m_currentBlockRows = 1;
-      eigen_assert(m_row<m_xpr.rows()
-        && "Too many rows passed to comma initializer (operator<<)");
-    }
-    eigen_assert(m_col<m_xpr.cols()
-      && "Too many coefficients passed to comma initializer (operator<<)");
-    eigen_assert(m_currentBlockRows==1);
-    m_xpr.coeffRef(m_row, m_col++) = s;
-    return *this;
-  }
-
-  /* inserts a matrix expression in the target matrix */
-  template<typename OtherDerived>
-  EIGEN_DEVICE_FUNC
-  CommaInitializer& operator,(const DenseBase<OtherDerived>& other)
-  {
-    if (m_col==m_xpr.cols() && (other.cols()!=0 || other.rows()!=m_currentBlockRows))
-    {
-      m_row+=m_currentBlockRows;
-      m_col = 0;
-      m_currentBlockRows = other.rows();
-      eigen_assert(m_row+m_currentBlockRows<=m_xpr.rows()
-        && "Too many rows passed to comma initializer (operator<<)");
-    }
-    eigen_assert((m_col + other.cols() <= m_xpr.cols())
-      && "Too many coefficients passed to comma initializer (operator<<)");
-    eigen_assert(m_currentBlockRows==other.rows());
-    m_xpr.template block<OtherDerived::RowsAtCompileTime, OtherDerived::ColsAtCompileTime>
-                    (m_row, m_col, other.rows(), other.cols()) = other;
-    m_col += other.cols();
-    return *this;
-  }
-
-  EIGEN_DEVICE_FUNC
-  inline ~CommaInitializer()
-#if defined VERIFY_RAISES_ASSERT && (!defined EIGEN_NO_ASSERTION_CHECKING) && defined EIGEN_EXCEPTIONS
-  EIGEN_EXCEPTION_SPEC(Eigen::eigen_assert_exception)
-#endif
-  {
-      finished();
-  }
-
-  /** \returns the built matrix once all its coefficients have been set.
-    * Calling finished is 100% optional. Its purpose is to write expressions
-    * like this:
-    * \code
-    * quaternion.fromRotationMatrix((Matrix3f() << axis0, axis1, axis2).finished());
-    * \endcode
-    */
-  EIGEN_DEVICE_FUNC
-  inline XprType& finished() {
-      eigen_assert(((m_row+m_currentBlockRows) == m_xpr.rows() || m_xpr.cols() == 0)
-           && m_col == m_xpr.cols()
-           && "Too few coefficients passed to comma initializer (operator<<)");
-      return m_xpr;
-  }
-
-  XprType& m_xpr;           // target expression
-  Index m_row;              // current row id
-  Index m_col;              // current col id
-  Index m_currentBlockRows; // current block height
-};
-
-/** \anchor MatrixBaseCommaInitRef
-  * Convenient operator to set the coefficients of a matrix.
-  *
-  * The coefficients must be provided in a row major order and exactly match
-  * the size of the matrix. Otherwise an assertion is raised.
-  *
-  * Example: \include MatrixBase_set.cpp
-  * Output: \verbinclude MatrixBase_set.out
-  * 
-  * \note According the c++ standard, the argument expressions of this comma initializer are evaluated in arbitrary order.
-  *
-  * \sa CommaInitializer::finished(), class CommaInitializer
-  */
-template<typename Derived>
-inline CommaInitializer<Derived> DenseBase<Derived>::operator<< (const Scalar& s)
-{
-  return CommaInitializer<Derived>(*static_cast<Derived*>(this), s);
-}
-
-/** \sa operator<<(const Scalar&) */
-template<typename Derived>
-template<typename OtherDerived>
-inline CommaInitializer<Derived>
-DenseBase<Derived>::operator<<(const DenseBase<OtherDerived>& other)
-{
-  return CommaInitializer<Derived>(*static_cast<Derived *>(this), other);
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_COMMAINITIALIZER_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/ConditionEstimator.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/ConditionEstimator.h
deleted file mode 100644
index 51a2e5f..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/ConditionEstimator.h
+++ /dev/null
@@ -1,175 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2016 Rasmus Munk Larsen (rmlarsen@google.com)
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_CONDITIONESTIMATOR_H
-#define EIGEN_CONDITIONESTIMATOR_H
-
-namespace Eigen {
-
-namespace internal {
-
-template <typename Vector, typename RealVector, bool IsComplex>
-struct rcond_compute_sign {
-  static inline Vector run(const Vector& v) {
-    const RealVector v_abs = v.cwiseAbs();
-    return (v_abs.array() == static_cast<typename Vector::RealScalar>(0))
-            .select(Vector::Ones(v.size()), v.cwiseQuotient(v_abs));
-  }
-};
-
-// Partial specialization to avoid elementwise division for real vectors.
-template <typename Vector>
-struct rcond_compute_sign<Vector, Vector, false> {
-  static inline Vector run(const Vector& v) {
-    return (v.array() < static_cast<typename Vector::RealScalar>(0))
-           .select(-Vector::Ones(v.size()), Vector::Ones(v.size()));
-  }
-};
-
-/**
-  * \returns an estimate of ||inv(matrix)||_1 given a decomposition of
-  * \a matrix that implements .solve() and .adjoint().solve() methods.
-  *
-  * This function implements Algorithms 4.1 and 5.1 from
-  *   http://www.maths.manchester.ac.uk/~higham/narep/narep135.pdf
-  * which also forms the basis for the condition number estimators in
-  * LAPACK. Since at most 10 calls to the solve method of dec are
-  * performed, the total cost is O(dims^2), as opposed to O(dims^3)
-  * needed to compute the inverse matrix explicitly.
-  *
-  * The most common usage is in estimating the condition number
-  * ||matrix||_1 * ||inv(matrix)||_1. The first term ||matrix||_1 can be
-  * computed directly in O(n^2) operations.
-  *
-  * Supports the following decompositions: FullPivLU, PartialPivLU, LDLT, and
-  * LLT.
-  *
-  * \sa FullPivLU, PartialPivLU, LDLT, LLT.
-  */
-template <typename Decomposition>
-typename Decomposition::RealScalar rcond_invmatrix_L1_norm_estimate(const Decomposition& dec)
-{
-  typedef typename Decomposition::MatrixType MatrixType;
-  typedef typename Decomposition::Scalar Scalar;
-  typedef typename Decomposition::RealScalar RealScalar;
-  typedef typename internal::plain_col_type<MatrixType>::type Vector;
-  typedef typename internal::plain_col_type<MatrixType, RealScalar>::type RealVector;
-  const bool is_complex = (NumTraits<Scalar>::IsComplex != 0);
-
-  eigen_assert(dec.rows() == dec.cols());
-  const Index n = dec.rows();
-  if (n == 0)
-    return 0;
-
-  // Disable Index to float conversion warning
-#ifdef __INTEL_COMPILER
-  #pragma warning push
-  #pragma warning ( disable : 2259 )
-#endif
-  Vector v = dec.solve(Vector::Ones(n) / Scalar(n));
-#ifdef __INTEL_COMPILER
-  #pragma warning pop
-#endif
-
-  // lower_bound is a lower bound on
-  //   ||inv(matrix)||_1  = sup_v ||inv(matrix) v||_1 / ||v||_1
-  // and is the objective maximized by the ("super-") gradient ascent
-  // algorithm below.
-  RealScalar lower_bound = v.template lpNorm<1>();
-  if (n == 1)
-    return lower_bound;
-
-  // Gradient ascent algorithm follows: We know that the optimum is achieved at
-  // one of the simplices v = e_i, so in each iteration we follow a
-  // super-gradient to move towards the optimal one.
-  RealScalar old_lower_bound = lower_bound;
-  Vector sign_vector(n);
-  Vector old_sign_vector;
-  Index v_max_abs_index = -1;
-  Index old_v_max_abs_index = v_max_abs_index;
-  for (int k = 0; k < 4; ++k)
-  {
-    sign_vector = internal::rcond_compute_sign<Vector, RealVector, is_complex>::run(v);
-    if (k > 0 && !is_complex && sign_vector == old_sign_vector) {
-      // Break if the solution stagnated.
-      break;
-    }
-    // v_max_abs_index = argmax |real( inv(matrix)^T * sign_vector )|
-    v = dec.adjoint().solve(sign_vector);
-    v.real().cwiseAbs().maxCoeff(&v_max_abs_index);
-    if (v_max_abs_index == old_v_max_abs_index) {
-      // Break if the solution stagnated.
-      break;
-    }
-    // Move to the new simplex e_j, where j = v_max_abs_index.
-    v = dec.solve(Vector::Unit(n, v_max_abs_index));  // v = inv(matrix) * e_j.
-    lower_bound = v.template lpNorm<1>();
-    if (lower_bound <= old_lower_bound) {
-      // Break if the gradient step did not increase the lower_bound.
-      break;
-    }
-    if (!is_complex) {
-      old_sign_vector = sign_vector;
-    }
-    old_v_max_abs_index = v_max_abs_index;
-    old_lower_bound = lower_bound;
-  }
-  // The following calculates an independent estimate of ||matrix||_1 by
-  // multiplying matrix by a vector with entries of slowly increasing
-  // magnitude and alternating sign:
-  //   v_i = (-1)^{i} (1 + (i / (dim-1))), i = 0,...,dim-1.
-  // This improvement to Hager's algorithm above is due to Higham. It was
-  // added to make the algorithm more robust in certain corner cases where
-  // large elements in the matrix might otherwise escape detection due to
-  // exact cancellation (especially when op and op_adjoint correspond to a
-  // sequence of backsubstitutions and permutations), which could cause
-  // Hager's algorithm to vastly underestimate ||matrix||_1.
-  Scalar alternating_sign(RealScalar(1));
-  for (Index i = 0; i < n; ++i) {
-    // The static_cast is needed when Scalar is a complex and RealScalar implements expression templates
-    v[i] = alternating_sign * static_cast<RealScalar>(RealScalar(1) + (RealScalar(i) / (RealScalar(n - 1))));
-    alternating_sign = -alternating_sign;
-  }
-  v = dec.solve(v);
-  const RealScalar alternate_lower_bound = (2 * v.template lpNorm<1>()) / (3 * RealScalar(n));
-  return numext::maxi(lower_bound, alternate_lower_bound);
-}
-
-/** \brief Reciprocal condition number estimator.
-  *
-  * Computing a decomposition of a dense matrix takes O(n^3) operations, while
-  * this method estimates the condition number quickly and reliably in O(n^2)
-  * operations.
-  *
-  * \returns an estimate of the reciprocal condition number
-  * (1 / (||matrix||_1 * ||inv(matrix)||_1)) of matrix, given ||matrix||_1 and
-  * its decomposition. Supports the following decompositions: FullPivLU,
-  * PartialPivLU, LDLT, and LLT.
-  *
-  * \sa FullPivLU, PartialPivLU, LDLT, LLT.
-  */
-template <typename Decomposition>
-typename Decomposition::RealScalar
-rcond_estimate_helper(typename Decomposition::RealScalar matrix_norm, const Decomposition& dec)
-{
-  typedef typename Decomposition::RealScalar RealScalar;
-  eigen_assert(dec.rows() == dec.cols());
-  if (dec.rows() == 0)              return NumTraits<RealScalar>::infinity();
-  if (matrix_norm == RealScalar(0)) return RealScalar(0);
-  if (dec.rows() == 1)              return RealScalar(1);
-  const RealScalar inverse_matrix_norm = rcond_invmatrix_L1_norm_estimate(dec);
-  return (inverse_matrix_norm == RealScalar(0) ? RealScalar(0)
-                                               : (RealScalar(1) / inverse_matrix_norm) / matrix_norm);
-}
-
-}  // namespace internal
-
-}  // namespace Eigen
-
-#endif
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/CoreEvaluators.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/CoreEvaluators.h
deleted file mode 100644
index 910889e..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/CoreEvaluators.h
+++ /dev/null
@@ -1,1688 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2011 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2011-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2011-2012 Jitse Niesen <jitse@maths.leeds.ac.uk>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-
-#ifndef EIGEN_COREEVALUATORS_H
-#define EIGEN_COREEVALUATORS_H
-
-namespace Eigen {
-  
-namespace internal {
-
-// This class returns the evaluator kind from the expression storage kind.
-// Default assumes index based accessors
-template<typename StorageKind>
-struct storage_kind_to_evaluator_kind {
-  typedef IndexBased Kind;
-};
-
-// This class returns the evaluator shape from the expression storage kind.
-// It can be Dense, Sparse, Triangular, Diagonal, SelfAdjoint, Band, etc.
-template<typename StorageKind> struct storage_kind_to_shape;
-
-template<> struct storage_kind_to_shape<Dense>                  { typedef DenseShape Shape;           };
-template<> struct storage_kind_to_shape<SolverStorage>          { typedef SolverShape Shape;           };
-template<> struct storage_kind_to_shape<PermutationStorage>     { typedef PermutationShape Shape;     };
-template<> struct storage_kind_to_shape<TranspositionsStorage>  { typedef TranspositionsShape Shape;  };
-
-// Evaluators have to be specialized with respect to various criteria such as:
-//  - storage/structure/shape
-//  - scalar type
-//  - etc.
-// Therefore, we need specialization of evaluator providing additional template arguments for each kind of evaluators.
-// We currently distinguish the following kind of evaluators:
-// - unary_evaluator    for expressions taking only one arguments (CwiseUnaryOp, CwiseUnaryView, Transpose, MatrixWrapper, ArrayWrapper, Reverse, Replicate)
-// - binary_evaluator   for expression taking two arguments (CwiseBinaryOp)
-// - ternary_evaluator   for expression taking three arguments (CwiseTernaryOp)
-// - product_evaluator  for linear algebra products (Product); special case of binary_evaluator because it requires additional tags for dispatching.
-// - mapbase_evaluator  for Map, Block, Ref
-// - block_evaluator    for Block (special dispatching to a mapbase_evaluator or unary_evaluator)
-
-template< typename T,
-          typename Arg1Kind   = typename evaluator_traits<typename T::Arg1>::Kind,
-          typename Arg2Kind   = typename evaluator_traits<typename T::Arg2>::Kind,
-          typename Arg3Kind   = typename evaluator_traits<typename T::Arg3>::Kind,
-          typename Arg1Scalar = typename traits<typename T::Arg1>::Scalar,
-          typename Arg2Scalar = typename traits<typename T::Arg2>::Scalar,
-          typename Arg3Scalar = typename traits<typename T::Arg3>::Scalar> struct ternary_evaluator;
-
-template< typename T,
-          typename LhsKind   = typename evaluator_traits<typename T::Lhs>::Kind,
-          typename RhsKind   = typename evaluator_traits<typename T::Rhs>::Kind,
-          typename LhsScalar = typename traits<typename T::Lhs>::Scalar,
-          typename RhsScalar = typename traits<typename T::Rhs>::Scalar> struct binary_evaluator;
-
-template< typename T,
-          typename Kind   = typename evaluator_traits<typename T::NestedExpression>::Kind,
-          typename Scalar = typename T::Scalar> struct unary_evaluator;
-          
-// evaluator_traits<T> contains traits for evaluator<T> 
-
-template<typename T>
-struct evaluator_traits_base
-{
-  // by default, get evaluator kind and shape from storage
-  typedef typename storage_kind_to_evaluator_kind<typename traits<T>::StorageKind>::Kind Kind;
-  typedef typename storage_kind_to_shape<typename traits<T>::StorageKind>::Shape Shape;
-};
-
-// Default evaluator traits
-template<typename T>
-struct evaluator_traits : public evaluator_traits_base<T>
-{
-};
-
-template<typename T, typename Shape = typename evaluator_traits<T>::Shape >
-struct evaluator_assume_aliasing {
-  static const bool value = false;
-};
-
-// By default, we assume a unary expression:
-template<typename T>
-struct evaluator : public unary_evaluator<T>
-{
-  typedef unary_evaluator<T> Base;
-  EIGEN_DEVICE_FUNC explicit evaluator(const T& xpr) : Base(xpr) {}
-};
-
-
-// TODO: Think about const-correctness
-template<typename T>
-struct evaluator<const T>
-  : evaluator<T>
-{
-  EIGEN_DEVICE_FUNC
-  explicit evaluator(const T& xpr) : evaluator<T>(xpr) {}
-};
-
-// ---------- base class for all evaluators ----------
-
-template<typename ExpressionType>
-struct evaluator_base : public noncopyable
-{
-  // TODO that's not very nice to have to propagate all these traits. They are currently only needed to handle outer,inner indices.
-  typedef traits<ExpressionType> ExpressionTraits;
-  
-  enum {
-    Alignment = 0
-  };
-};
-
-// -------------------- Matrix and Array --------------------
-//
-// evaluator<PlainObjectBase> is a common base class for the
-// Matrix and Array evaluators.
-// Here we directly specialize evaluator. This is not really a unary expression, and it is, by definition, dense,
-// so no need for more sophisticated dispatching.
-
-template<typename Derived>
-struct evaluator<PlainObjectBase<Derived> >
-  : evaluator_base<Derived>
-{
-  typedef PlainObjectBase<Derived> PlainObjectType;
-  typedef typename PlainObjectType::Scalar Scalar;
-  typedef typename PlainObjectType::CoeffReturnType CoeffReturnType;
-
-  enum {
-    IsRowMajor = PlainObjectType::IsRowMajor,
-    IsVectorAtCompileTime = PlainObjectType::IsVectorAtCompileTime,
-    RowsAtCompileTime = PlainObjectType::RowsAtCompileTime,
-    ColsAtCompileTime = PlainObjectType::ColsAtCompileTime,
-    
-    CoeffReadCost = NumTraits<Scalar>::ReadCost,
-    Flags = traits<Derived>::EvaluatorFlags,
-    Alignment = traits<Derived>::Alignment
-  };
-  
-  EIGEN_DEVICE_FUNC evaluator()
-    : m_data(0),
-      m_outerStride(IsVectorAtCompileTime  ? 0 
-                                           : int(IsRowMajor) ? ColsAtCompileTime 
-                                           : RowsAtCompileTime)
-  {
-    EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
-  }
-  
-  EIGEN_DEVICE_FUNC explicit evaluator(const PlainObjectType& m)
-    : m_data(m.data()), m_outerStride(IsVectorAtCompileTime ? 0 : m.outerStride()) 
-  {
-    EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(Index row, Index col) const
-  {
-    if (IsRowMajor)
-      return m_data[row * m_outerStride.value() + col];
-    else
-      return m_data[row + col * m_outerStride.value()];
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(Index index) const
-  {
-    return m_data[index];
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  Scalar& coeffRef(Index row, Index col)
-  {
-    if (IsRowMajor)
-      return const_cast<Scalar*>(m_data)[row * m_outerStride.value() + col];
-    else
-      return const_cast<Scalar*>(m_data)[row + col * m_outerStride.value()];
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  Scalar& coeffRef(Index index)
-  {
-    return const_cast<Scalar*>(m_data)[index];
-  }
-
-  template<int LoadMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  PacketType packet(Index row, Index col) const
-  {
-    if (IsRowMajor)
-      return ploadt<PacketType, LoadMode>(m_data + row * m_outerStride.value() + col);
-    else
-      return ploadt<PacketType, LoadMode>(m_data + row + col * m_outerStride.value());
-  }
-
-  template<int LoadMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  PacketType packet(Index index) const
-  {
-    return ploadt<PacketType, LoadMode>(m_data + index);
-  }
-
-  template<int StoreMode,typename PacketType>
-  EIGEN_STRONG_INLINE
-  void writePacket(Index row, Index col, const PacketType& x)
-  {
-    if (IsRowMajor)
-      return pstoret<Scalar, PacketType, StoreMode>
-	            (const_cast<Scalar*>(m_data) + row * m_outerStride.value() + col, x);
-    else
-      return pstoret<Scalar, PacketType, StoreMode>
-                    (const_cast<Scalar*>(m_data) + row + col * m_outerStride.value(), x);
-  }
-
-  template<int StoreMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  void writePacket(Index index, const PacketType& x)
-  {
-    return pstoret<Scalar, PacketType, StoreMode>(const_cast<Scalar*>(m_data) + index, x);
-  }
-
-protected:
-  const Scalar *m_data;
-
-  // We do not need to know the outer stride for vectors
-  variable_if_dynamic<Index, IsVectorAtCompileTime  ? 0 
-                                                    : int(IsRowMajor) ? ColsAtCompileTime 
-                                                    : RowsAtCompileTime> m_outerStride;
-};
-
-template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
-struct evaluator<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
-  : evaluator<PlainObjectBase<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> > >
-{
-  typedef Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> XprType;
-  
-  EIGEN_DEVICE_FUNC evaluator() {}
-
-  EIGEN_DEVICE_FUNC explicit evaluator(const XprType& m)
-    : evaluator<PlainObjectBase<XprType> >(m) 
-  { }
-};
-
-template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
-struct evaluator<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
-  : evaluator<PlainObjectBase<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> > >
-{
-  typedef Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> XprType;
-
-  EIGEN_DEVICE_FUNC evaluator() {}
-  
-  EIGEN_DEVICE_FUNC explicit evaluator(const XprType& m)
-    : evaluator<PlainObjectBase<XprType> >(m) 
-  { }
-};
-
-// -------------------- Transpose --------------------
-
-template<typename ArgType>
-struct unary_evaluator<Transpose<ArgType>, IndexBased>
-  : evaluator_base<Transpose<ArgType> >
-{
-  typedef Transpose<ArgType> XprType;
-  
-  enum {
-    CoeffReadCost = evaluator<ArgType>::CoeffReadCost,    
-    Flags = evaluator<ArgType>::Flags ^ RowMajorBit,
-    Alignment = evaluator<ArgType>::Alignment
-  };
-
-  EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& t) : m_argImpl(t.nestedExpression()) {}
-
-  typedef typename XprType::Scalar Scalar;
-  typedef typename XprType::CoeffReturnType CoeffReturnType;
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(Index row, Index col) const
-  {
-    return m_argImpl.coeff(col, row);
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(Index index) const
-  {
-    return m_argImpl.coeff(index);
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  Scalar& coeffRef(Index row, Index col)
-  {
-    return m_argImpl.coeffRef(col, row);
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  typename XprType::Scalar& coeffRef(Index index)
-  {
-    return m_argImpl.coeffRef(index);
-  }
-
-  template<int LoadMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  PacketType packet(Index row, Index col) const
-  {
-    return m_argImpl.template packet<LoadMode,PacketType>(col, row);
-  }
-
-  template<int LoadMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  PacketType packet(Index index) const
-  {
-    return m_argImpl.template packet<LoadMode,PacketType>(index);
-  }
-
-  template<int StoreMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  void writePacket(Index row, Index col, const PacketType& x)
-  {
-    m_argImpl.template writePacket<StoreMode,PacketType>(col, row, x);
-  }
-
-  template<int StoreMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  void writePacket(Index index, const PacketType& x)
-  {
-    m_argImpl.template writePacket<StoreMode,PacketType>(index, x);
-  }
-
-protected:
-  evaluator<ArgType> m_argImpl;
-};
-
-// -------------------- CwiseNullaryOp --------------------
-// Like Matrix and Array, this is not really a unary expression, so we directly specialize evaluator.
-// Likewise, there is not need to more sophisticated dispatching here.
-
-template<typename Scalar,typename NullaryOp,
-         bool has_nullary = has_nullary_operator<NullaryOp>::value,
-         bool has_unary   = has_unary_operator<NullaryOp>::value,
-         bool has_binary  = has_binary_operator<NullaryOp>::value>
-struct nullary_wrapper
-{
-  template <typename IndexType>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const NullaryOp& op, IndexType i, IndexType j) const { return op(i,j); }
-  template <typename IndexType>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const NullaryOp& op, IndexType i) const { return op(i); }
-
-  template <typename T, typename IndexType> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T packetOp(const NullaryOp& op, IndexType i, IndexType j) const { return op.template packetOp<T>(i,j); }
-  template <typename T, typename IndexType> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T packetOp(const NullaryOp& op, IndexType i) const { return op.template packetOp<T>(i); }
-};
-
-template<typename Scalar,typename NullaryOp>
-struct nullary_wrapper<Scalar,NullaryOp,true,false,false>
-{
-  template <typename IndexType>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const NullaryOp& op, IndexType=0, IndexType=0) const { return op(); }
-  template <typename T, typename IndexType> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T packetOp(const NullaryOp& op, IndexType=0, IndexType=0) const { return op.template packetOp<T>(); }
-};
-
-template<typename Scalar,typename NullaryOp>
-struct nullary_wrapper<Scalar,NullaryOp,false,false,true>
-{
-  template <typename IndexType>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const NullaryOp& op, IndexType i, IndexType j=0) const { return op(i,j); }
-  template <typename T, typename IndexType> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T packetOp(const NullaryOp& op, IndexType i, IndexType j=0) const { return op.template packetOp<T>(i,j); }
-};
-
-// We need the following specialization for vector-only functors assigned to a runtime vector,
-// for instance, using linspace and assigning a RowVectorXd to a MatrixXd or even a row of a MatrixXd.
-// In this case, i==0 and j is used for the actual iteration.
-template<typename Scalar,typename NullaryOp>
-struct nullary_wrapper<Scalar,NullaryOp,false,true,false>
-{
-  template <typename IndexType>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const NullaryOp& op, IndexType i, IndexType j) const {
-    eigen_assert(i==0 || j==0);
-    return op(i+j);
-  }
-  template <typename T, typename IndexType> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T packetOp(const NullaryOp& op, IndexType i, IndexType j) const {
-    eigen_assert(i==0 || j==0);
-    return op.template packetOp<T>(i+j);
-  }
-
-  template <typename IndexType>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const NullaryOp& op, IndexType i) const { return op(i); }
-  template <typename T, typename IndexType>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T packetOp(const NullaryOp& op, IndexType i) const { return op.template packetOp<T>(i); }
-};
-
-template<typename Scalar,typename NullaryOp>
-struct nullary_wrapper<Scalar,NullaryOp,false,false,false> {};
-
-#if 0 && EIGEN_COMP_MSVC>0
-// Disable this ugly workaround. This is now handled in traits<Ref>::match,
-// but this piece of code might still become handly if some other weird compilation
-// erros pop up again.
-
-// MSVC exhibits a weird compilation error when
-// compiling:
-//    Eigen::MatrixXf A = MatrixXf::Random(3,3);
-//    Ref<const MatrixXf> R = 2.f*A;
-// and that has_*ary_operator<scalar_constant_op<float>> have not been instantiated yet.
-// The "problem" is that evaluator<2.f*A> is instantiated by traits<Ref>::match<2.f*A>
-// and at that time has_*ary_operator<T> returns true regardless of T.
-// Then nullary_wrapper is badly instantiated as nullary_wrapper<.,.,true,true,true>.
-// The trick is thus to defer the proper instantiation of nullary_wrapper when coeff(),
-// and packet() are really instantiated as implemented below:
-
-// This is a simple wrapper around Index to enforce the re-instantiation of
-// has_*ary_operator when needed.
-template<typename T> struct nullary_wrapper_workaround_msvc {
-  nullary_wrapper_workaround_msvc(const T&);
-  operator T()const;
-};
-
-template<typename Scalar,typename NullaryOp>
-struct nullary_wrapper<Scalar,NullaryOp,true,true,true>
-{
-  template <typename IndexType>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const NullaryOp& op, IndexType i, IndexType j) const {
-    return nullary_wrapper<Scalar,NullaryOp,
-    has_nullary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value,
-    has_unary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value,
-    has_binary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value>().operator()(op,i,j);
-  }
-  template <typename IndexType>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const NullaryOp& op, IndexType i) const {
-    return nullary_wrapper<Scalar,NullaryOp,
-    has_nullary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value,
-    has_unary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value,
-    has_binary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value>().operator()(op,i);
-  }
-
-  template <typename T, typename IndexType>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T packetOp(const NullaryOp& op, IndexType i, IndexType j) const {
-    return nullary_wrapper<Scalar,NullaryOp,
-    has_nullary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value,
-    has_unary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value,
-    has_binary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value>().template packetOp<T>(op,i,j);
-  }
-  template <typename T, typename IndexType>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T packetOp(const NullaryOp& op, IndexType i) const {
-    return nullary_wrapper<Scalar,NullaryOp,
-    has_nullary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value,
-    has_unary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value,
-    has_binary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value>().template packetOp<T>(op,i);
-  }
-};
-#endif // MSVC workaround
-
-template<typename NullaryOp, typename PlainObjectType>
-struct evaluator<CwiseNullaryOp<NullaryOp,PlainObjectType> >
-  : evaluator_base<CwiseNullaryOp<NullaryOp,PlainObjectType> >
-{
-  typedef CwiseNullaryOp<NullaryOp,PlainObjectType> XprType;
-  typedef typename internal::remove_all<PlainObjectType>::type PlainObjectTypeCleaned;
-  
-  enum {
-    CoeffReadCost = internal::functor_traits<NullaryOp>::Cost,
-    
-    Flags = (evaluator<PlainObjectTypeCleaned>::Flags
-          &  (  HereditaryBits
-              | (functor_has_linear_access<NullaryOp>::ret  ? LinearAccessBit : 0)
-              | (functor_traits<NullaryOp>::PacketAccess    ? PacketAccessBit : 0)))
-          | (functor_traits<NullaryOp>::IsRepeatable ? 0 : EvalBeforeNestingBit),
-    Alignment = AlignedMax
-  };
-
-  EIGEN_DEVICE_FUNC explicit evaluator(const XprType& n)
-    : m_functor(n.functor()), m_wrapper()
-  {
-    EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
-  }
-
-  typedef typename XprType::CoeffReturnType CoeffReturnType;
-
-  template <typename IndexType>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(IndexType row, IndexType col) const
-  {
-    return m_wrapper(m_functor, row, col);
-  }
-
-  template <typename IndexType>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(IndexType index) const
-  {
-    return m_wrapper(m_functor,index);
-  }
-
-  template<int LoadMode, typename PacketType, typename IndexType>
-  EIGEN_STRONG_INLINE
-  PacketType packet(IndexType row, IndexType col) const
-  {
-    return m_wrapper.template packetOp<PacketType>(m_functor, row, col);
-  }
-
-  template<int LoadMode, typename PacketType, typename IndexType>
-  EIGEN_STRONG_INLINE
-  PacketType packet(IndexType index) const
-  {
-    return m_wrapper.template packetOp<PacketType>(m_functor, index);
-  }
-
-protected:
-  const NullaryOp m_functor;
-  const internal::nullary_wrapper<CoeffReturnType,NullaryOp> m_wrapper;
-};
-
-// -------------------- CwiseUnaryOp --------------------
-
-template<typename UnaryOp, typename ArgType>
-struct unary_evaluator<CwiseUnaryOp<UnaryOp, ArgType>, IndexBased >
-  : evaluator_base<CwiseUnaryOp<UnaryOp, ArgType> >
-{
-  typedef CwiseUnaryOp<UnaryOp, ArgType> XprType;
-  
-  enum {
-    CoeffReadCost = evaluator<ArgType>::CoeffReadCost + functor_traits<UnaryOp>::Cost,
-    
-    Flags = evaluator<ArgType>::Flags
-          & (HereditaryBits | LinearAccessBit | (functor_traits<UnaryOp>::PacketAccess ? PacketAccessBit : 0)),
-    Alignment = evaluator<ArgType>::Alignment
-  };
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  explicit unary_evaluator(const XprType& op)
-    : m_functor(op.functor()), 
-      m_argImpl(op.nestedExpression()) 
-  {
-    EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<UnaryOp>::Cost);
-    EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
-  }
-
-  typedef typename XprType::CoeffReturnType CoeffReturnType;
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(Index row, Index col) const
-  {
-    return m_functor(m_argImpl.coeff(row, col));
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(Index index) const
-  {
-    return m_functor(m_argImpl.coeff(index));
-  }
-
-  template<int LoadMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  PacketType packet(Index row, Index col) const
-  {
-    return m_functor.packetOp(m_argImpl.template packet<LoadMode, PacketType>(row, col));
-  }
-
-  template<int LoadMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  PacketType packet(Index index) const
-  {
-    return m_functor.packetOp(m_argImpl.template packet<LoadMode, PacketType>(index));
-  }
-
-protected:
-  const UnaryOp m_functor;
-  evaluator<ArgType> m_argImpl;
-};
-
-// -------------------- CwiseTernaryOp --------------------
-
-// this is a ternary expression
-template<typename TernaryOp, typename Arg1, typename Arg2, typename Arg3>
-struct evaluator<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> >
-  : public ternary_evaluator<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> >
-{
-  typedef CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> XprType;
-  typedef ternary_evaluator<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> > Base;
-  
-  EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr) : Base(xpr) {}
-};
-
-template<typename TernaryOp, typename Arg1, typename Arg2, typename Arg3>
-struct ternary_evaluator<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>, IndexBased, IndexBased>
-  : evaluator_base<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> >
-{
-  typedef CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> XprType;
-  
-  enum {
-    CoeffReadCost = evaluator<Arg1>::CoeffReadCost + evaluator<Arg2>::CoeffReadCost + evaluator<Arg3>::CoeffReadCost + functor_traits<TernaryOp>::Cost,
-    
-    Arg1Flags = evaluator<Arg1>::Flags,
-    Arg2Flags = evaluator<Arg2>::Flags,
-    Arg3Flags = evaluator<Arg3>::Flags,
-    SameType = is_same<typename Arg1::Scalar,typename Arg2::Scalar>::value && is_same<typename Arg1::Scalar,typename Arg3::Scalar>::value,
-    StorageOrdersAgree = (int(Arg1Flags)&RowMajorBit)==(int(Arg2Flags)&RowMajorBit) && (int(Arg1Flags)&RowMajorBit)==(int(Arg3Flags)&RowMajorBit),
-    Flags0 = (int(Arg1Flags) | int(Arg2Flags) | int(Arg3Flags)) & (
-        HereditaryBits
-        | (int(Arg1Flags) & int(Arg2Flags) & int(Arg3Flags) &
-           ( (StorageOrdersAgree ? LinearAccessBit : 0)
-           | (functor_traits<TernaryOp>::PacketAccess && StorageOrdersAgree && SameType ? PacketAccessBit : 0)
-           )
-        )
-     ),
-    Flags = (Flags0 & ~RowMajorBit) | (Arg1Flags & RowMajorBit),
-    Alignment = EIGEN_PLAIN_ENUM_MIN(
-        EIGEN_PLAIN_ENUM_MIN(evaluator<Arg1>::Alignment, evaluator<Arg2>::Alignment),
-        evaluator<Arg3>::Alignment)
-  };
-
-  EIGEN_DEVICE_FUNC explicit ternary_evaluator(const XprType& xpr)
-    : m_functor(xpr.functor()),
-      m_arg1Impl(xpr.arg1()), 
-      m_arg2Impl(xpr.arg2()), 
-      m_arg3Impl(xpr.arg3())  
-  {
-    EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<TernaryOp>::Cost);
-    EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
-  }
-
-  typedef typename XprType::CoeffReturnType CoeffReturnType;
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(Index row, Index col) const
-  {
-    return m_functor(m_arg1Impl.coeff(row, col), m_arg2Impl.coeff(row, col), m_arg3Impl.coeff(row, col));
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(Index index) const
-  {
-    return m_functor(m_arg1Impl.coeff(index), m_arg2Impl.coeff(index), m_arg3Impl.coeff(index));
-  }
-
-  template<int LoadMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  PacketType packet(Index row, Index col) const
-  {
-    return m_functor.packetOp(m_arg1Impl.template packet<LoadMode,PacketType>(row, col),
-                              m_arg2Impl.template packet<LoadMode,PacketType>(row, col),
-                              m_arg3Impl.template packet<LoadMode,PacketType>(row, col));
-  }
-
-  template<int LoadMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  PacketType packet(Index index) const
-  {
-    return m_functor.packetOp(m_arg1Impl.template packet<LoadMode,PacketType>(index),
-                              m_arg2Impl.template packet<LoadMode,PacketType>(index),
-                              m_arg3Impl.template packet<LoadMode,PacketType>(index));
-  }
-
-protected:
-  const TernaryOp m_functor;
-  evaluator<Arg1> m_arg1Impl;
-  evaluator<Arg2> m_arg2Impl;
-  evaluator<Arg3> m_arg3Impl;
-};
-
-// -------------------- CwiseBinaryOp --------------------
-
-// this is a binary expression
-template<typename BinaryOp, typename Lhs, typename Rhs>
-struct evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
-  : public binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
-{
-  typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
-  typedef binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > Base;
-  
-  EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr) : Base(xpr) {}
-};
-
-template<typename BinaryOp, typename Lhs, typename Rhs>
-struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs>, IndexBased, IndexBased>
-  : evaluator_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
-{
-  typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
-  
-  enum {
-    CoeffReadCost = evaluator<Lhs>::CoeffReadCost + evaluator<Rhs>::CoeffReadCost + functor_traits<BinaryOp>::Cost,
-    
-    LhsFlags = evaluator<Lhs>::Flags,
-    RhsFlags = evaluator<Rhs>::Flags,
-    SameType = is_same<typename Lhs::Scalar,typename Rhs::Scalar>::value,
-    StorageOrdersAgree = (int(LhsFlags)&RowMajorBit)==(int(RhsFlags)&RowMajorBit),
-    Flags0 = (int(LhsFlags) | int(RhsFlags)) & (
-        HereditaryBits
-      | (int(LhsFlags) & int(RhsFlags) &
-           ( (StorageOrdersAgree ? LinearAccessBit : 0)
-           | (functor_traits<BinaryOp>::PacketAccess && StorageOrdersAgree && SameType ? PacketAccessBit : 0)
-           )
-        )
-     ),
-    Flags = (Flags0 & ~RowMajorBit) | (LhsFlags & RowMajorBit),
-    Alignment = EIGEN_PLAIN_ENUM_MIN(evaluator<Lhs>::Alignment,evaluator<Rhs>::Alignment)
-  };
-
-  EIGEN_DEVICE_FUNC explicit binary_evaluator(const XprType& xpr)
-    : m_functor(xpr.functor()),
-      m_lhsImpl(xpr.lhs()), 
-      m_rhsImpl(xpr.rhs())  
-  {
-    EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<BinaryOp>::Cost);
-    EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
-  }
-
-  typedef typename XprType::CoeffReturnType CoeffReturnType;
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(Index row, Index col) const
-  {
-    return m_functor(m_lhsImpl.coeff(row, col), m_rhsImpl.coeff(row, col));
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(Index index) const
-  {
-    return m_functor(m_lhsImpl.coeff(index), m_rhsImpl.coeff(index));
-  }
-
-  template<int LoadMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  PacketType packet(Index row, Index col) const
-  {
-    return m_functor.packetOp(m_lhsImpl.template packet<LoadMode,PacketType>(row, col),
-                              m_rhsImpl.template packet<LoadMode,PacketType>(row, col));
-  }
-
-  template<int LoadMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  PacketType packet(Index index) const
-  {
-    return m_functor.packetOp(m_lhsImpl.template packet<LoadMode,PacketType>(index),
-                              m_rhsImpl.template packet<LoadMode,PacketType>(index));
-  }
-
-protected:
-  const BinaryOp m_functor;
-  evaluator<Lhs> m_lhsImpl;
-  evaluator<Rhs> m_rhsImpl;
-};
-
-// -------------------- CwiseUnaryView --------------------
-
-template<typename UnaryOp, typename ArgType>
-struct unary_evaluator<CwiseUnaryView<UnaryOp, ArgType>, IndexBased>
-  : evaluator_base<CwiseUnaryView<UnaryOp, ArgType> >
-{
-  typedef CwiseUnaryView<UnaryOp, ArgType> XprType;
-  
-  enum {
-    CoeffReadCost = evaluator<ArgType>::CoeffReadCost + functor_traits<UnaryOp>::Cost,
-    
-    Flags = (evaluator<ArgType>::Flags & (HereditaryBits | LinearAccessBit | DirectAccessBit)),
-    
-    Alignment = 0 // FIXME it is not very clear why alignment is necessarily lost...
-  };
-
-  EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& op)
-    : m_unaryOp(op.functor()), 
-      m_argImpl(op.nestedExpression()) 
-  {
-    EIGEN_INTERNAL_CHECK_COST_VALUE(functor_traits<UnaryOp>::Cost);
-    EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
-  }
-
-  typedef typename XprType::Scalar Scalar;
-  typedef typename XprType::CoeffReturnType CoeffReturnType;
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(Index row, Index col) const
-  {
-    return m_unaryOp(m_argImpl.coeff(row, col));
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(Index index) const
-  {
-    return m_unaryOp(m_argImpl.coeff(index));
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  Scalar& coeffRef(Index row, Index col)
-  {
-    return m_unaryOp(m_argImpl.coeffRef(row, col));
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  Scalar& coeffRef(Index index)
-  {
-    return m_unaryOp(m_argImpl.coeffRef(index));
-  }
-
-protected:
-  const UnaryOp m_unaryOp;
-  evaluator<ArgType> m_argImpl;
-};
-
-// -------------------- Map --------------------
-
-// FIXME perhaps the PlainObjectType could be provided by Derived::PlainObject ?
-// but that might complicate template specialization
-template<typename Derived, typename PlainObjectType>
-struct mapbase_evaluator;
-
-template<typename Derived, typename PlainObjectType>
-struct mapbase_evaluator : evaluator_base<Derived>
-{
-  typedef Derived  XprType;
-  typedef typename XprType::PointerType PointerType;
-  typedef typename XprType::Scalar Scalar;
-  typedef typename XprType::CoeffReturnType CoeffReturnType;
-  
-  enum {
-    IsRowMajor = XprType::RowsAtCompileTime,
-    ColsAtCompileTime = XprType::ColsAtCompileTime,
-    CoeffReadCost = NumTraits<Scalar>::ReadCost
-  };
-
-  EIGEN_DEVICE_FUNC explicit mapbase_evaluator(const XprType& map)
-    : m_data(const_cast<PointerType>(map.data())),
-      m_innerStride(map.innerStride()),
-      m_outerStride(map.outerStride())
-  {
-    EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(evaluator<Derived>::Flags&PacketAccessBit, internal::inner_stride_at_compile_time<Derived>::ret==1),
-                        PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1);
-    EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(Index row, Index col) const
-  {
-    return m_data[col * colStride() + row * rowStride()];
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(Index index) const
-  {
-    return m_data[index * m_innerStride.value()];
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  Scalar& coeffRef(Index row, Index col)
-  {
-    return m_data[col * colStride() + row * rowStride()];
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  Scalar& coeffRef(Index index)
-  {
-    return m_data[index * m_innerStride.value()];
-  }
-
-  template<int LoadMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  PacketType packet(Index row, Index col) const
-  {
-    PointerType ptr = m_data + row * rowStride() + col * colStride();
-    return internal::ploadt<PacketType, LoadMode>(ptr);
-  }
-
-  template<int LoadMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  PacketType packet(Index index) const
-  {
-    return internal::ploadt<PacketType, LoadMode>(m_data + index * m_innerStride.value());
-  }
-
-  template<int StoreMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  void writePacket(Index row, Index col, const PacketType& x)
-  {
-    PointerType ptr = m_data + row * rowStride() + col * colStride();
-    return internal::pstoret<Scalar, PacketType, StoreMode>(ptr, x);
-  }
-
-  template<int StoreMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  void writePacket(Index index, const PacketType& x)
-  {
-    internal::pstoret<Scalar, PacketType, StoreMode>(m_data + index * m_innerStride.value(), x);
-  }
-protected:
-  EIGEN_DEVICE_FUNC
-  inline Index rowStride() const { return XprType::IsRowMajor ? m_outerStride.value() : m_innerStride.value(); }
-  EIGEN_DEVICE_FUNC
-  inline Index colStride() const { return XprType::IsRowMajor ? m_innerStride.value() : m_outerStride.value(); }
-
-  PointerType m_data;
-  const internal::variable_if_dynamic<Index, XprType::InnerStrideAtCompileTime> m_innerStride;
-  const internal::variable_if_dynamic<Index, XprType::OuterStrideAtCompileTime> m_outerStride;
-};
-
-template<typename PlainObjectType, int MapOptions, typename StrideType> 
-struct evaluator<Map<PlainObjectType, MapOptions, StrideType> >
-  : public mapbase_evaluator<Map<PlainObjectType, MapOptions, StrideType>, PlainObjectType>
-{
-  typedef Map<PlainObjectType, MapOptions, StrideType> XprType;
-  typedef typename XprType::Scalar Scalar;
-  // TODO: should check for smaller packet types once we can handle multi-sized packet types
-  typedef typename packet_traits<Scalar>::type PacketScalar;
-  
-  enum {
-    InnerStrideAtCompileTime = StrideType::InnerStrideAtCompileTime == 0
-                             ? int(PlainObjectType::InnerStrideAtCompileTime)
-                             : int(StrideType::InnerStrideAtCompileTime),
-    OuterStrideAtCompileTime = StrideType::OuterStrideAtCompileTime == 0
-                             ? int(PlainObjectType::OuterStrideAtCompileTime)
-                             : int(StrideType::OuterStrideAtCompileTime),
-    HasNoInnerStride = InnerStrideAtCompileTime == 1,
-    HasNoOuterStride = StrideType::OuterStrideAtCompileTime == 0,
-    HasNoStride = HasNoInnerStride && HasNoOuterStride,
-    IsDynamicSize = PlainObjectType::SizeAtCompileTime==Dynamic,
-    
-    PacketAccessMask = bool(HasNoInnerStride) ? ~int(0) : ~int(PacketAccessBit),
-    LinearAccessMask = bool(HasNoStride) || bool(PlainObjectType::IsVectorAtCompileTime) ? ~int(0) : ~int(LinearAccessBit),
-    Flags = int( evaluator<PlainObjectType>::Flags) & (LinearAccessMask&PacketAccessMask),
-    
-    Alignment = int(MapOptions)&int(AlignedMask)
-  };
-
-  EIGEN_DEVICE_FUNC explicit evaluator(const XprType& map)
-    : mapbase_evaluator<XprType, PlainObjectType>(map) 
-  { }
-};
-
-// -------------------- Ref --------------------
-
-template<typename PlainObjectType, int RefOptions, typename StrideType> 
-struct evaluator<Ref<PlainObjectType, RefOptions, StrideType> >
-  : public mapbase_evaluator<Ref<PlainObjectType, RefOptions, StrideType>, PlainObjectType>
-{
-  typedef Ref<PlainObjectType, RefOptions, StrideType> XprType;
-  
-  enum {
-    Flags = evaluator<Map<PlainObjectType, RefOptions, StrideType> >::Flags,
-    Alignment = evaluator<Map<PlainObjectType, RefOptions, StrideType> >::Alignment
-  };
-
-  EIGEN_DEVICE_FUNC explicit evaluator(const XprType& ref)
-    : mapbase_evaluator<XprType, PlainObjectType>(ref) 
-  { }
-};
-
-// -------------------- Block --------------------
-
-template<typename ArgType, int BlockRows, int BlockCols, bool InnerPanel,
-         bool HasDirectAccess = internal::has_direct_access<ArgType>::ret> struct block_evaluator;
-         
-template<typename ArgType, int BlockRows, int BlockCols, bool InnerPanel> 
-struct evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel> >
-  : block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel>
-{
-  typedef Block<ArgType, BlockRows, BlockCols, InnerPanel> XprType;
-  typedef typename XprType::Scalar Scalar;
-  // TODO: should check for smaller packet types once we can handle multi-sized packet types
-  typedef typename packet_traits<Scalar>::type PacketScalar;
-  
-  enum {
-    CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
-    
-    RowsAtCompileTime = traits<XprType>::RowsAtCompileTime,
-    ColsAtCompileTime = traits<XprType>::ColsAtCompileTime,
-    MaxRowsAtCompileTime = traits<XprType>::MaxRowsAtCompileTime,
-    MaxColsAtCompileTime = traits<XprType>::MaxColsAtCompileTime,
-    
-    ArgTypeIsRowMajor = (int(evaluator<ArgType>::Flags)&RowMajorBit) != 0,
-    IsRowMajor = (MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1) ? 1
-               : (MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1) ? 0
-               : ArgTypeIsRowMajor,
-    HasSameStorageOrderAsArgType = (IsRowMajor == ArgTypeIsRowMajor),
-    InnerSize = IsRowMajor ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
-    InnerStrideAtCompileTime = HasSameStorageOrderAsArgType
-                             ? int(inner_stride_at_compile_time<ArgType>::ret)
-                             : int(outer_stride_at_compile_time<ArgType>::ret),
-    OuterStrideAtCompileTime = HasSameStorageOrderAsArgType
-                             ? int(outer_stride_at_compile_time<ArgType>::ret)
-                             : int(inner_stride_at_compile_time<ArgType>::ret),
-    MaskPacketAccessBit = (InnerStrideAtCompileTime == 1 || HasSameStorageOrderAsArgType) ? PacketAccessBit : 0,
-    
-    FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1 || (InnerPanel && (evaluator<ArgType>::Flags&LinearAccessBit))) ? LinearAccessBit : 0,    
-    FlagsRowMajorBit = XprType::Flags&RowMajorBit,
-    Flags0 = evaluator<ArgType>::Flags & ( (HereditaryBits & ~RowMajorBit) |
-                                           DirectAccessBit |
-                                           MaskPacketAccessBit),
-    Flags = Flags0 | FlagsLinearAccessBit | FlagsRowMajorBit,
-    
-    PacketAlignment = unpacket_traits<PacketScalar>::alignment,
-    Alignment0 = (InnerPanel && (OuterStrideAtCompileTime!=Dynamic)
-                             && (OuterStrideAtCompileTime!=0)
-                             && (((OuterStrideAtCompileTime * int(sizeof(Scalar))) % int(PacketAlignment)) == 0)) ? int(PacketAlignment) : 0,
-    Alignment = EIGEN_PLAIN_ENUM_MIN(evaluator<ArgType>::Alignment, Alignment0)
-  };
-  typedef block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel> block_evaluator_type;
-  EIGEN_DEVICE_FUNC explicit evaluator(const XprType& block) : block_evaluator_type(block)
-  {
-    EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
-  }
-};
-
-// no direct-access => dispatch to a unary evaluator
-template<typename ArgType, int BlockRows, int BlockCols, bool InnerPanel>
-struct block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel, /*HasDirectAccess*/ false>
-  : unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel> >
-{
-  typedef Block<ArgType, BlockRows, BlockCols, InnerPanel> XprType;
-
-  EIGEN_DEVICE_FUNC explicit block_evaluator(const XprType& block)
-    : unary_evaluator<XprType>(block) 
-  {}
-};
-
-template<typename ArgType, int BlockRows, int BlockCols, bool InnerPanel>
-struct unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IndexBased>
-  : evaluator_base<Block<ArgType, BlockRows, BlockCols, InnerPanel> >
-{
-  typedef Block<ArgType, BlockRows, BlockCols, InnerPanel> XprType;
-
-  EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& block)
-    : m_argImpl(block.nestedExpression()), 
-      m_startRow(block.startRow()), 
-      m_startCol(block.startCol()),
-      m_linear_offset(InnerPanel?(XprType::IsRowMajor ? block.startRow()*block.cols() : block.startCol()*block.rows()):0)
-  { }
- 
-  typedef typename XprType::Scalar Scalar;
-  typedef typename XprType::CoeffReturnType CoeffReturnType;
-
-  enum {
-    RowsAtCompileTime = XprType::RowsAtCompileTime,
-    ForwardLinearAccess = InnerPanel && bool(evaluator<ArgType>::Flags&LinearAccessBit)
-  };
- 
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(Index row, Index col) const
-  { 
-    return m_argImpl.coeff(m_startRow.value() + row, m_startCol.value() + col); 
-  }
-  
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(Index index) const
-  { 
-    if (ForwardLinearAccess)
-      return m_argImpl.coeff(m_linear_offset.value() + index); 
-    else
-      return coeff(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0);
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  Scalar& coeffRef(Index row, Index col)
-  { 
-    return m_argImpl.coeffRef(m_startRow.value() + row, m_startCol.value() + col); 
-  }
-  
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  Scalar& coeffRef(Index index)
-  { 
-    if (ForwardLinearAccess)
-      return m_argImpl.coeffRef(m_linear_offset.value() + index); 
-    else
-      return coeffRef(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0);
-  }
- 
-  template<int LoadMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  PacketType packet(Index row, Index col) const 
-  { 
-    return m_argImpl.template packet<LoadMode,PacketType>(m_startRow.value() + row, m_startCol.value() + col); 
-  }
-
-  template<int LoadMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  PacketType packet(Index index) const 
-  { 
-    if (ForwardLinearAccess)
-      return m_argImpl.template packet<LoadMode,PacketType>(m_linear_offset.value() + index);
-    else
-      return packet<LoadMode,PacketType>(RowsAtCompileTime == 1 ? 0 : index,
-                                         RowsAtCompileTime == 1 ? index : 0);
-  }
-  
-  template<int StoreMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  void writePacket(Index row, Index col, const PacketType& x) 
-  {
-    return m_argImpl.template writePacket<StoreMode,PacketType>(m_startRow.value() + row, m_startCol.value() + col, x); 
-  }
-  
-  template<int StoreMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  void writePacket(Index index, const PacketType& x) 
-  {
-    if (ForwardLinearAccess)
-      return m_argImpl.template writePacket<StoreMode,PacketType>(m_linear_offset.value() + index, x);
-    else
-      return writePacket<StoreMode,PacketType>(RowsAtCompileTime == 1 ? 0 : index,
-                                              RowsAtCompileTime == 1 ? index : 0,
-                                              x);
-  }
- 
-protected:
-  evaluator<ArgType> m_argImpl;
-  const variable_if_dynamic<Index, (ArgType::RowsAtCompileTime == 1 && BlockRows==1) ? 0 : Dynamic> m_startRow;
-  const variable_if_dynamic<Index, (ArgType::ColsAtCompileTime == 1 && BlockCols==1) ? 0 : Dynamic> m_startCol;
-  const variable_if_dynamic<Index, InnerPanel ? Dynamic : 0> m_linear_offset;
-};
-
-// TODO: This evaluator does not actually use the child evaluator; 
-// all action is via the data() as returned by the Block expression.
-
-template<typename ArgType, int BlockRows, int BlockCols, bool InnerPanel> 
-struct block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel, /* HasDirectAccess */ true>
-  : mapbase_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>,
-                      typename Block<ArgType, BlockRows, BlockCols, InnerPanel>::PlainObject>
-{
-  typedef Block<ArgType, BlockRows, BlockCols, InnerPanel> XprType;
-  typedef typename XprType::Scalar Scalar;
-
-  EIGEN_DEVICE_FUNC explicit block_evaluator(const XprType& block)
-    : mapbase_evaluator<XprType, typename XprType::PlainObject>(block) 
-  {
-    // TODO: for the 3.3 release, this should be turned to an internal assertion, but let's keep it as is for the beta lifetime
-    eigen_assert(((internal::UIntPtr(block.data()) % EIGEN_PLAIN_ENUM_MAX(1,evaluator<XprType>::Alignment)) == 0) && "data is not aligned");
-  }
-};
-
-
-// -------------------- Select --------------------
-// NOTE shall we introduce a ternary_evaluator?
-
-// TODO enable vectorization for Select
-template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType>
-struct evaluator<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >
-  : evaluator_base<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >
-{
-  typedef Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> XprType;
-  enum {
-    CoeffReadCost = evaluator<ConditionMatrixType>::CoeffReadCost
-                  + EIGEN_PLAIN_ENUM_MAX(evaluator<ThenMatrixType>::CoeffReadCost,
-                                         evaluator<ElseMatrixType>::CoeffReadCost),
-
-    Flags = (unsigned int)evaluator<ThenMatrixType>::Flags & evaluator<ElseMatrixType>::Flags & HereditaryBits,
-    
-    Alignment = EIGEN_PLAIN_ENUM_MIN(evaluator<ThenMatrixType>::Alignment, evaluator<ElseMatrixType>::Alignment)
-  };
-
-  EIGEN_DEVICE_FUNC explicit evaluator(const XprType& select)
-    : m_conditionImpl(select.conditionMatrix()),
-      m_thenImpl(select.thenMatrix()),
-      m_elseImpl(select.elseMatrix())
-  {
-    EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
-  }
- 
-  typedef typename XprType::CoeffReturnType CoeffReturnType;
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(Index row, Index col) const
-  {
-    if (m_conditionImpl.coeff(row, col))
-      return m_thenImpl.coeff(row, col);
-    else
-      return m_elseImpl.coeff(row, col);
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(Index index) const
-  {
-    if (m_conditionImpl.coeff(index))
-      return m_thenImpl.coeff(index);
-    else
-      return m_elseImpl.coeff(index);
-  }
- 
-protected:
-  evaluator<ConditionMatrixType> m_conditionImpl;
-  evaluator<ThenMatrixType> m_thenImpl;
-  evaluator<ElseMatrixType> m_elseImpl;
-};
-
-
-// -------------------- Replicate --------------------
-
-template<typename ArgType, int RowFactor, int ColFactor> 
-struct unary_evaluator<Replicate<ArgType, RowFactor, ColFactor> >
-  : evaluator_base<Replicate<ArgType, RowFactor, ColFactor> >
-{
-  typedef Replicate<ArgType, RowFactor, ColFactor> XprType;
-  typedef typename XprType::CoeffReturnType CoeffReturnType;
-  enum {
-    Factor = (RowFactor==Dynamic || ColFactor==Dynamic) ? Dynamic : RowFactor*ColFactor
-  };
-  typedef typename internal::nested_eval<ArgType,Factor>::type ArgTypeNested;
-  typedef typename internal::remove_all<ArgTypeNested>::type ArgTypeNestedCleaned;
-  
-  enum {
-    CoeffReadCost = evaluator<ArgTypeNestedCleaned>::CoeffReadCost,
-    LinearAccessMask = XprType::IsVectorAtCompileTime ? LinearAccessBit : 0,
-    Flags = (evaluator<ArgTypeNestedCleaned>::Flags & (HereditaryBits|LinearAccessMask) & ~RowMajorBit) | (traits<XprType>::Flags & RowMajorBit),
-    
-    Alignment = evaluator<ArgTypeNestedCleaned>::Alignment
-  };
-
-  EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& replicate)
-    : m_arg(replicate.nestedExpression()),
-      m_argImpl(m_arg),
-      m_rows(replicate.nestedExpression().rows()),
-      m_cols(replicate.nestedExpression().cols())
-  {}
- 
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(Index row, Index col) const
-  {
-    // try to avoid using modulo; this is a pure optimization strategy
-    const Index actual_row = internal::traits<XprType>::RowsAtCompileTime==1 ? 0
-                           : RowFactor==1 ? row
-                           : row % m_rows.value();
-    const Index actual_col = internal::traits<XprType>::ColsAtCompileTime==1 ? 0
-                           : ColFactor==1 ? col
-                           : col % m_cols.value();
-    
-    return m_argImpl.coeff(actual_row, actual_col);
-  }
-  
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(Index index) const
-  {
-    // try to avoid using modulo; this is a pure optimization strategy
-    const Index actual_index = internal::traits<XprType>::RowsAtCompileTime==1
-                                  ? (ColFactor==1 ?  index : index%m_cols.value())
-                                  : (RowFactor==1 ?  index : index%m_rows.value());
-    
-    return m_argImpl.coeff(actual_index);
-  }
-
-  template<int LoadMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  PacketType packet(Index row, Index col) const
-  {
-    const Index actual_row = internal::traits<XprType>::RowsAtCompileTime==1 ? 0
-                           : RowFactor==1 ? row
-                           : row % m_rows.value();
-    const Index actual_col = internal::traits<XprType>::ColsAtCompileTime==1 ? 0
-                           : ColFactor==1 ? col
-                           : col % m_cols.value();
-
-    return m_argImpl.template packet<LoadMode,PacketType>(actual_row, actual_col);
-  }
-  
-  template<int LoadMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  PacketType packet(Index index) const
-  {
-    const Index actual_index = internal::traits<XprType>::RowsAtCompileTime==1
-                                  ? (ColFactor==1 ?  index : index%m_cols.value())
-                                  : (RowFactor==1 ?  index : index%m_rows.value());
-
-    return m_argImpl.template packet<LoadMode,PacketType>(actual_index);
-  }
- 
-protected:
-  const ArgTypeNested m_arg;
-  evaluator<ArgTypeNestedCleaned> m_argImpl;
-  const variable_if_dynamic<Index, ArgType::RowsAtCompileTime> m_rows;
-  const variable_if_dynamic<Index, ArgType::ColsAtCompileTime> m_cols;
-};
-
-
-// -------------------- PartialReduxExpr --------------------
-
-template< typename ArgType, typename MemberOp, int Direction>
-struct evaluator<PartialReduxExpr<ArgType, MemberOp, Direction> >
-  : evaluator_base<PartialReduxExpr<ArgType, MemberOp, Direction> >
-{
-  typedef PartialReduxExpr<ArgType, MemberOp, Direction> XprType;
-  typedef typename internal::nested_eval<ArgType,1>::type ArgTypeNested;
-  typedef typename internal::remove_all<ArgTypeNested>::type ArgTypeNestedCleaned;
-  typedef typename ArgType::Scalar InputScalar;
-  typedef typename XprType::Scalar Scalar;
-  enum {
-    TraversalSize = Direction==int(Vertical) ? int(ArgType::RowsAtCompileTime) :  int(ArgType::ColsAtCompileTime)
-  };
-  typedef typename MemberOp::template Cost<InputScalar,int(TraversalSize)> CostOpType;
-  enum {
-    CoeffReadCost = TraversalSize==Dynamic ? HugeCost
-                  : TraversalSize * evaluator<ArgType>::CoeffReadCost + int(CostOpType::value),
-    
-    Flags = (traits<XprType>::Flags&RowMajorBit) | (evaluator<ArgType>::Flags&(HereditaryBits&(~RowMajorBit))) | LinearAccessBit,
-    
-    Alignment = 0 // FIXME this will need to be improved once PartialReduxExpr is vectorized
-  };
-
-  EIGEN_DEVICE_FUNC explicit evaluator(const XprType xpr)
-    : m_arg(xpr.nestedExpression()), m_functor(xpr.functor())
-  {
-    EIGEN_INTERNAL_CHECK_COST_VALUE(TraversalSize==Dynamic ? HugeCost : int(CostOpType::value));
-    EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
-  }
-
-  typedef typename XprType::CoeffReturnType CoeffReturnType;
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  const Scalar coeff(Index i, Index j) const
-  {
-    if (Direction==Vertical)
-      return m_functor(m_arg.col(j));
-    else
-      return m_functor(m_arg.row(i));
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  const Scalar coeff(Index index) const
-  {
-    if (Direction==Vertical)
-      return m_functor(m_arg.col(index));
-    else
-      return m_functor(m_arg.row(index));
-  }
-
-protected:
-  typename internal::add_const_on_value_type<ArgTypeNested>::type m_arg;
-  const MemberOp m_functor;
-};
-
-
-// -------------------- MatrixWrapper and ArrayWrapper --------------------
-//
-// evaluator_wrapper_base<T> is a common base class for the
-// MatrixWrapper and ArrayWrapper evaluators.
-
-template<typename XprType>
-struct evaluator_wrapper_base
-  : evaluator_base<XprType>
-{
-  typedef typename remove_all<typename XprType::NestedExpressionType>::type ArgType;
-  enum {
-    CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
-    Flags = evaluator<ArgType>::Flags,
-    Alignment = evaluator<ArgType>::Alignment
-  };
-
-  EIGEN_DEVICE_FUNC explicit evaluator_wrapper_base(const ArgType& arg) : m_argImpl(arg) {}
-
-  typedef typename ArgType::Scalar Scalar;
-  typedef typename ArgType::CoeffReturnType CoeffReturnType;
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(Index row, Index col) const
-  {
-    return m_argImpl.coeff(row, col);
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(Index index) const
-  {
-    return m_argImpl.coeff(index);
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  Scalar& coeffRef(Index row, Index col)
-  {
-    return m_argImpl.coeffRef(row, col);
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  Scalar& coeffRef(Index index)
-  {
-    return m_argImpl.coeffRef(index);
-  }
-
-  template<int LoadMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  PacketType packet(Index row, Index col) const
-  {
-    return m_argImpl.template packet<LoadMode,PacketType>(row, col);
-  }
-
-  template<int LoadMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  PacketType packet(Index index) const
-  {
-    return m_argImpl.template packet<LoadMode,PacketType>(index);
-  }
-
-  template<int StoreMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  void writePacket(Index row, Index col, const PacketType& x)
-  {
-    m_argImpl.template writePacket<StoreMode>(row, col, x);
-  }
-
-  template<int StoreMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  void writePacket(Index index, const PacketType& x)
-  {
-    m_argImpl.template writePacket<StoreMode>(index, x);
-  }
-
-protected:
-  evaluator<ArgType> m_argImpl;
-};
-
-template<typename TArgType>
-struct unary_evaluator<MatrixWrapper<TArgType> >
-  : evaluator_wrapper_base<MatrixWrapper<TArgType> >
-{
-  typedef MatrixWrapper<TArgType> XprType;
-
-  EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& wrapper)
-    : evaluator_wrapper_base<MatrixWrapper<TArgType> >(wrapper.nestedExpression())
-  { }
-};
-
-template<typename TArgType>
-struct unary_evaluator<ArrayWrapper<TArgType> >
-  : evaluator_wrapper_base<ArrayWrapper<TArgType> >
-{
-  typedef ArrayWrapper<TArgType> XprType;
-
-  EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& wrapper)
-    : evaluator_wrapper_base<ArrayWrapper<TArgType> >(wrapper.nestedExpression())
-  { }
-};
-
-
-// -------------------- Reverse --------------------
-
-// defined in Reverse.h:
-template<typename PacketType, bool ReversePacket> struct reverse_packet_cond;
-
-template<typename ArgType, int Direction>
-struct unary_evaluator<Reverse<ArgType, Direction> >
-  : evaluator_base<Reverse<ArgType, Direction> >
-{
-  typedef Reverse<ArgType, Direction> XprType;
-  typedef typename XprType::Scalar Scalar;
-  typedef typename XprType::CoeffReturnType CoeffReturnType;
-
-  enum {
-    IsRowMajor = XprType::IsRowMajor,
-    IsColMajor = !IsRowMajor,
-    ReverseRow = (Direction == Vertical)   || (Direction == BothDirections),
-    ReverseCol = (Direction == Horizontal) || (Direction == BothDirections),
-    ReversePacket = (Direction == BothDirections)
-                    || ((Direction == Vertical)   && IsColMajor)
-                    || ((Direction == Horizontal) && IsRowMajor),
-                    
-    CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
-    
-    // let's enable LinearAccess only with vectorization because of the product overhead
-    // FIXME enable DirectAccess with negative strides?
-    Flags0 = evaluator<ArgType>::Flags,
-    LinearAccess = ( (Direction==BothDirections) && (int(Flags0)&PacketAccessBit) )
-                  || ((ReverseRow && XprType::ColsAtCompileTime==1) || (ReverseCol && XprType::RowsAtCompileTime==1))
-                 ? LinearAccessBit : 0,
-
-    Flags = int(Flags0) & (HereditaryBits | PacketAccessBit | LinearAccess),
-    
-    Alignment = 0 // FIXME in some rare cases, Alignment could be preserved, like a Vector4f.
-  };
-
-  EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& reverse)
-    : m_argImpl(reverse.nestedExpression()),
-      m_rows(ReverseRow ? reverse.nestedExpression().rows() : 1),
-      m_cols(ReverseCol ? reverse.nestedExpression().cols() : 1)
-  { }
- 
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(Index row, Index col) const
-  {
-    return m_argImpl.coeff(ReverseRow ? m_rows.value() - row - 1 : row,
-                           ReverseCol ? m_cols.value() - col - 1 : col);
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(Index index) const
-  {
-    return m_argImpl.coeff(m_rows.value() * m_cols.value() - index - 1);
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  Scalar& coeffRef(Index row, Index col)
-  {
-    return m_argImpl.coeffRef(ReverseRow ? m_rows.value() - row - 1 : row,
-                              ReverseCol ? m_cols.value() - col - 1 : col);
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  Scalar& coeffRef(Index index)
-  {
-    return m_argImpl.coeffRef(m_rows.value() * m_cols.value() - index - 1);
-  }
-
-  template<int LoadMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  PacketType packet(Index row, Index col) const
-  {
-    enum {
-      PacketSize = unpacket_traits<PacketType>::size,
-      OffsetRow  = ReverseRow && IsColMajor ? PacketSize : 1,
-      OffsetCol  = ReverseCol && IsRowMajor ? PacketSize : 1
-    };
-    typedef internal::reverse_packet_cond<PacketType,ReversePacket> reverse_packet;
-    return reverse_packet::run(m_argImpl.template packet<LoadMode,PacketType>(
-                                  ReverseRow ? m_rows.value() - row - OffsetRow : row,
-                                  ReverseCol ? m_cols.value() - col - OffsetCol : col));
-  }
-
-  template<int LoadMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  PacketType packet(Index index) const
-  {
-    enum { PacketSize = unpacket_traits<PacketType>::size };
-    return preverse(m_argImpl.template packet<LoadMode,PacketType>(m_rows.value() * m_cols.value() - index - PacketSize));
-  }
-
-  template<int LoadMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  void writePacket(Index row, Index col, const PacketType& x)
-  {
-    // FIXME we could factorize some code with packet(i,j)
-    enum {
-      PacketSize = unpacket_traits<PacketType>::size,
-      OffsetRow  = ReverseRow && IsColMajor ? PacketSize : 1,
-      OffsetCol  = ReverseCol && IsRowMajor ? PacketSize : 1
-    };
-    typedef internal::reverse_packet_cond<PacketType,ReversePacket> reverse_packet;
-    m_argImpl.template writePacket<LoadMode>(
-                                  ReverseRow ? m_rows.value() - row - OffsetRow : row,
-                                  ReverseCol ? m_cols.value() - col - OffsetCol : col,
-                                  reverse_packet::run(x));
-  }
-
-  template<int LoadMode, typename PacketType>
-  EIGEN_STRONG_INLINE
-  void writePacket(Index index, const PacketType& x)
-  {
-    enum { PacketSize = unpacket_traits<PacketType>::size };
-    m_argImpl.template writePacket<LoadMode>
-      (m_rows.value() * m_cols.value() - index - PacketSize, preverse(x));
-  }
- 
-protected:
-  evaluator<ArgType> m_argImpl;
-
-  // If we do not reverse rows, then we do not need to know the number of rows; same for columns
-  // Nonetheless, in this case it is important to set to 1 such that the coeff(index) method works fine for vectors.
-  const variable_if_dynamic<Index, ReverseRow ? ArgType::RowsAtCompileTime : 1> m_rows;
-  const variable_if_dynamic<Index, ReverseCol ? ArgType::ColsAtCompileTime : 1> m_cols;
-};
-
-
-// -------------------- Diagonal --------------------
-
-template<typename ArgType, int DiagIndex>
-struct evaluator<Diagonal<ArgType, DiagIndex> >
-  : evaluator_base<Diagonal<ArgType, DiagIndex> >
-{
-  typedef Diagonal<ArgType, DiagIndex> XprType;
-  
-  enum {
-    CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
-    
-    Flags = (unsigned int)(evaluator<ArgType>::Flags & (HereditaryBits | DirectAccessBit) & ~RowMajorBit) | LinearAccessBit,
-    
-    Alignment = 0
-  };
-
-  EIGEN_DEVICE_FUNC explicit evaluator(const XprType& diagonal)
-    : m_argImpl(diagonal.nestedExpression()),
-      m_index(diagonal.index())
-  { }
- 
-  typedef typename XprType::Scalar Scalar;
-  typedef typename XprType::CoeffReturnType CoeffReturnType;
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(Index row, Index) const
-  {
-    return m_argImpl.coeff(row + rowOffset(), row + colOffset());
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  CoeffReturnType coeff(Index index) const
-  {
-    return m_argImpl.coeff(index + rowOffset(), index + colOffset());
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  Scalar& coeffRef(Index row, Index)
-  {
-    return m_argImpl.coeffRef(row + rowOffset(), row + colOffset());
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  Scalar& coeffRef(Index index)
-  {
-    return m_argImpl.coeffRef(index + rowOffset(), index + colOffset());
-  }
-
-protected:
-  evaluator<ArgType> m_argImpl;
-  const internal::variable_if_dynamicindex<Index, XprType::DiagIndex> m_index;
-
-private:
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rowOffset() const { return m_index.value() > 0 ? 0 : -m_index.value(); }
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index colOffset() const { return m_index.value() > 0 ? m_index.value() : 0; }
-};
-
-
-//----------------------------------------------------------------------
-// deprecated code
-//----------------------------------------------------------------------
-
-// -------------------- EvalToTemp --------------------
-
-// expression class for evaluating nested expression to a temporary
-
-template<typename ArgType> class EvalToTemp;
-
-template<typename ArgType>
-struct traits<EvalToTemp<ArgType> >
-  : public traits<ArgType>
-{ };
-
-template<typename ArgType>
-class EvalToTemp
-  : public dense_xpr_base<EvalToTemp<ArgType> >::type
-{
- public:
- 
-  typedef typename dense_xpr_base<EvalToTemp>::type Base;
-  EIGEN_GENERIC_PUBLIC_INTERFACE(EvalToTemp)
- 
-  explicit EvalToTemp(const ArgType& arg)
-    : m_arg(arg)
-  { }
- 
-  const ArgType& arg() const
-  {
-    return m_arg;
-  }
-
-  Index rows() const 
-  {
-    return m_arg.rows();
-  }
-
-  Index cols() const 
-  {
-    return m_arg.cols();
-  }
-
- private:
-  const ArgType& m_arg;
-};
- 
-template<typename ArgType>
-struct evaluator<EvalToTemp<ArgType> >
-  : public evaluator<typename ArgType::PlainObject>
-{
-  typedef EvalToTemp<ArgType>                   XprType;
-  typedef typename ArgType::PlainObject         PlainObject;
-  typedef evaluator<PlainObject> Base;
-  
-  EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr)
-    : m_result(xpr.arg())
-  {
-    ::new (static_cast<Base*>(this)) Base(m_result);
-  }
-
-  // This constructor is used when nesting an EvalTo evaluator in another evaluator
-  EIGEN_DEVICE_FUNC evaluator(const ArgType& arg)
-    : m_result(arg)
-  {
-    ::new (static_cast<Base*>(this)) Base(m_result);
-  }
-
-protected:
-  PlainObject m_result;
-};
-
-} // namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_COREEVALUATORS_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/CoreIterators.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/CoreIterators.h
deleted file mode 100644
index 4eb42b9..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/CoreIterators.h
+++ /dev/null
@@ -1,127 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_COREITERATORS_H
-#define EIGEN_COREITERATORS_H
-
-namespace Eigen { 
-
-/* This file contains the respective InnerIterator definition of the expressions defined in Eigen/Core
- */
-
-namespace internal {
-
-template<typename XprType, typename EvaluatorKind>
-class inner_iterator_selector;
-
-}
-
-/** \class InnerIterator
-  * \brief An InnerIterator allows to loop over the element of any matrix expression.
-  * 
-  * \warning To be used with care because an evaluator is constructed every time an InnerIterator iterator is constructed.
-  * 
-  * TODO: add a usage example
-  */
-template<typename XprType>
-class InnerIterator
-{
-protected:
-  typedef internal::inner_iterator_selector<XprType, typename internal::evaluator_traits<XprType>::Kind> IteratorType;
-  typedef internal::evaluator<XprType> EvaluatorType;
-  typedef typename internal::traits<XprType>::Scalar Scalar;
-public:
-  /** Construct an iterator over the \a outerId -th row or column of \a xpr */
-  InnerIterator(const XprType &xpr, const Index &outerId)
-    : m_eval(xpr), m_iter(m_eval, outerId, xpr.innerSize())
-  {}
-  
-  /// \returns the value of the current coefficient.
-  EIGEN_STRONG_INLINE Scalar value() const          { return m_iter.value(); }
-  /** Increment the iterator \c *this to the next non-zero coefficient.
-    * Explicit zeros are not skipped over. To skip explicit zeros, see class SparseView
-    */
-  EIGEN_STRONG_INLINE InnerIterator& operator++()   { m_iter.operator++(); return *this; }
-  /// \returns the column or row index of the current coefficient.
-  EIGEN_STRONG_INLINE Index index() const           { return m_iter.index(); }
-  /// \returns the row index of the current coefficient.
-  EIGEN_STRONG_INLINE Index row() const             { return m_iter.row(); }
-  /// \returns the column index of the current coefficient.
-  EIGEN_STRONG_INLINE Index col() const             { return m_iter.col(); }
-  /// \returns \c true if the iterator \c *this still references a valid coefficient.
-  EIGEN_STRONG_INLINE operator bool() const         { return m_iter; }
-  
-protected:
-  EvaluatorType m_eval;
-  IteratorType m_iter;
-private:
-  // If you get here, then you're not using the right InnerIterator type, e.g.:
-  //   SparseMatrix<double,RowMajor> A;
-  //   SparseMatrix<double>::InnerIterator it(A,0);
-  template<typename T> InnerIterator(const EigenBase<T>&,Index outer);
-};
-
-namespace internal {
-
-// Generic inner iterator implementation for dense objects
-template<typename XprType>
-class inner_iterator_selector<XprType, IndexBased>
-{
-protected:
-  typedef evaluator<XprType> EvaluatorType;
-  typedef typename traits<XprType>::Scalar Scalar;
-  enum { IsRowMajor = (XprType::Flags&RowMajorBit)==RowMajorBit };
-  
-public:
-  EIGEN_STRONG_INLINE inner_iterator_selector(const EvaluatorType &eval, const Index &outerId, const Index &innerSize)
-    : m_eval(eval), m_inner(0), m_outer(outerId), m_end(innerSize)
-  {}
-
-  EIGEN_STRONG_INLINE Scalar value() const
-  {
-    return (IsRowMajor) ? m_eval.coeff(m_outer, m_inner)
-                        : m_eval.coeff(m_inner, m_outer);
-  }
-
-  EIGEN_STRONG_INLINE inner_iterator_selector& operator++() { m_inner++; return *this; }
-
-  EIGEN_STRONG_INLINE Index index() const { return m_inner; }
-  inline Index row() const { return IsRowMajor ? m_outer : index(); }
-  inline Index col() const { return IsRowMajor ? index() : m_outer; }
-
-  EIGEN_STRONG_INLINE operator bool() const { return m_inner < m_end && m_inner>=0; }
-
-protected:
-  const EvaluatorType& m_eval;
-  Index m_inner;
-  const Index m_outer;
-  const Index m_end;
-};
-
-// For iterator-based evaluator, inner-iterator is already implemented as
-// evaluator<>::InnerIterator
-template<typename XprType>
-class inner_iterator_selector<XprType, IteratorBased>
- : public evaluator<XprType>::InnerIterator
-{
-protected:
-  typedef typename evaluator<XprType>::InnerIterator Base;
-  typedef evaluator<XprType> EvaluatorType;
-  
-public:
-  EIGEN_STRONG_INLINE inner_iterator_selector(const EvaluatorType &eval, const Index &outerId, const Index &/*innerSize*/)
-    : Base(eval, outerId)
-  {}  
-};
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_COREITERATORS_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/CwiseBinaryOp.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/CwiseBinaryOp.h
deleted file mode 100644
index a36765e..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/CwiseBinaryOp.h
+++ /dev/null
@@ -1,184 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_CWISE_BINARY_OP_H
-#define EIGEN_CWISE_BINARY_OP_H
-
-namespace Eigen {
-
-namespace internal {
-template<typename BinaryOp, typename Lhs, typename Rhs>
-struct traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
-{
-  // we must not inherit from traits<Lhs> since it has
-  // the potential to cause problems with MSVC
-  typedef typename remove_all<Lhs>::type Ancestor;
-  typedef typename traits<Ancestor>::XprKind XprKind;
-  enum {
-    RowsAtCompileTime = traits<Ancestor>::RowsAtCompileTime,
-    ColsAtCompileTime = traits<Ancestor>::ColsAtCompileTime,
-    MaxRowsAtCompileTime = traits<Ancestor>::MaxRowsAtCompileTime,
-    MaxColsAtCompileTime = traits<Ancestor>::MaxColsAtCompileTime
-  };
-
-  // even though we require Lhs and Rhs to have the same scalar type (see CwiseBinaryOp constructor),
-  // we still want to handle the case when the result type is different.
-  typedef typename result_of<
-                     BinaryOp(
-                       const typename Lhs::Scalar&,
-                       const typename Rhs::Scalar&
-                     )
-                   >::type Scalar;
-  typedef typename cwise_promote_storage_type<typename traits<Lhs>::StorageKind,
-                                              typename traits<Rhs>::StorageKind,
-                                              BinaryOp>::ret StorageKind;
-  typedef typename promote_index_type<typename traits<Lhs>::StorageIndex,
-                                      typename traits<Rhs>::StorageIndex>::type StorageIndex;
-  typedef typename Lhs::Nested LhsNested;
-  typedef typename Rhs::Nested RhsNested;
-  typedef typename remove_reference<LhsNested>::type _LhsNested;
-  typedef typename remove_reference<RhsNested>::type _RhsNested;
-  enum {
-    Flags = cwise_promote_storage_order<typename traits<Lhs>::StorageKind,typename traits<Rhs>::StorageKind,_LhsNested::Flags & RowMajorBit,_RhsNested::Flags & RowMajorBit>::value
-  };
-};
-} // end namespace internal
-
-template<typename BinaryOp, typename Lhs, typename Rhs, typename StorageKind>
-class CwiseBinaryOpImpl;
-
-/** \class CwiseBinaryOp
-  * \ingroup Core_Module
-  *
-  * \brief Generic expression where a coefficient-wise binary operator is applied to two expressions
-  *
-  * \tparam BinaryOp template functor implementing the operator
-  * \tparam LhsType the type of the left-hand side
-  * \tparam RhsType the type of the right-hand side
-  *
-  * This class represents an expression  where a coefficient-wise binary operator is applied to two expressions.
-  * It is the return type of binary operators, by which we mean only those binary operators where
-  * both the left-hand side and the right-hand side are Eigen expressions.
-  * For example, the return type of matrix1+matrix2 is a CwiseBinaryOp.
-  *
-  * Most of the time, this is the only way that it is used, so you typically don't have to name
-  * CwiseBinaryOp types explicitly.
-  *
-  * \sa MatrixBase::binaryExpr(const MatrixBase<OtherDerived> &,const CustomBinaryOp &) const, class CwiseUnaryOp, class CwiseNullaryOp
-  */
-template<typename BinaryOp, typename LhsType, typename RhsType>
-class CwiseBinaryOp : 
-  public CwiseBinaryOpImpl<
-          BinaryOp, LhsType, RhsType,
-          typename internal::cwise_promote_storage_type<typename internal::traits<LhsType>::StorageKind,
-                                                        typename internal::traits<RhsType>::StorageKind,
-                                                        BinaryOp>::ret>,
-  internal::no_assignment_operator
-{
-  public:
-    
-    typedef typename internal::remove_all<BinaryOp>::type Functor;
-    typedef typename internal::remove_all<LhsType>::type Lhs;
-    typedef typename internal::remove_all<RhsType>::type Rhs;
-
-    typedef typename CwiseBinaryOpImpl<
-        BinaryOp, LhsType, RhsType,
-        typename internal::cwise_promote_storage_type<typename internal::traits<LhsType>::StorageKind,
-                                                      typename internal::traits<Rhs>::StorageKind,
-                                                      BinaryOp>::ret>::Base Base;
-    EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseBinaryOp)
-
-    typedef typename internal::ref_selector<LhsType>::type LhsNested;
-    typedef typename internal::ref_selector<RhsType>::type RhsNested;
-    typedef typename internal::remove_reference<LhsNested>::type _LhsNested;
-    typedef typename internal::remove_reference<RhsNested>::type _RhsNested;
-
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE CwiseBinaryOp(const Lhs& aLhs, const Rhs& aRhs, const BinaryOp& func = BinaryOp())
-      : m_lhs(aLhs), m_rhs(aRhs), m_functor(func)
-    {
-      EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename Rhs::Scalar);
-      // require the sizes to match
-      EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs, Rhs)
-      eigen_assert(aLhs.rows() == aRhs.rows() && aLhs.cols() == aRhs.cols());
-    }
-
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Index rows() const {
-      // return the fixed size type if available to enable compile time optimizations
-      if (internal::traits<typename internal::remove_all<LhsNested>::type>::RowsAtCompileTime==Dynamic)
-        return m_rhs.rows();
-      else
-        return m_lhs.rows();
-    }
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Index cols() const {
-      // return the fixed size type if available to enable compile time optimizations
-      if (internal::traits<typename internal::remove_all<LhsNested>::type>::ColsAtCompileTime==Dynamic)
-        return m_rhs.cols();
-      else
-        return m_lhs.cols();
-    }
-
-    /** \returns the left hand side nested expression */
-    EIGEN_DEVICE_FUNC
-    const _LhsNested& lhs() const { return m_lhs; }
-    /** \returns the right hand side nested expression */
-    EIGEN_DEVICE_FUNC
-    const _RhsNested& rhs() const { return m_rhs; }
-    /** \returns the functor representing the binary operation */
-    EIGEN_DEVICE_FUNC
-    const BinaryOp& functor() const { return m_functor; }
-
-  protected:
-    LhsNested m_lhs;
-    RhsNested m_rhs;
-    const BinaryOp m_functor;
-};
-
-// Generic API dispatcher
-template<typename BinaryOp, typename Lhs, typename Rhs, typename StorageKind>
-class CwiseBinaryOpImpl
-  : public internal::generic_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type
-{
-public:
-  typedef typename internal::generic_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type Base;
-};
-
-/** replaces \c *this by \c *this - \a other.
-  *
-  * \returns a reference to \c *this
-  */
-template<typename Derived>
-template<typename OtherDerived>
-EIGEN_STRONG_INLINE Derived &
-MatrixBase<Derived>::operator-=(const MatrixBase<OtherDerived> &other)
-{
-  call_assignment(derived(), other.derived(), internal::sub_assign_op<Scalar,typename OtherDerived::Scalar>());
-  return derived();
-}
-
-/** replaces \c *this by \c *this + \a other.
-  *
-  * \returns a reference to \c *this
-  */
-template<typename Derived>
-template<typename OtherDerived>
-EIGEN_STRONG_INLINE Derived &
-MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other)
-{
-  call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar,typename OtherDerived::Scalar>());
-  return derived();
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_CWISE_BINARY_OP_H
-
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/CwiseNullaryOp.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/CwiseNullaryOp.h
deleted file mode 100644
index ddd607e..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/CwiseNullaryOp.h
+++ /dev/null
@@ -1,866 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_CWISE_NULLARY_OP_H
-#define EIGEN_CWISE_NULLARY_OP_H
-
-namespace Eigen {
-
-namespace internal {
-template<typename NullaryOp, typename PlainObjectType>
-struct traits<CwiseNullaryOp<NullaryOp, PlainObjectType> > : traits<PlainObjectType>
-{
-  enum {
-    Flags = traits<PlainObjectType>::Flags & RowMajorBit
-  };
-};
-
-} // namespace internal
-
-/** \class CwiseNullaryOp
-  * \ingroup Core_Module
-  *
-  * \brief Generic expression of a matrix where all coefficients are defined by a functor
-  *
-  * \tparam NullaryOp template functor implementing the operator
-  * \tparam PlainObjectType the underlying plain matrix/array type
-  *
-  * This class represents an expression of a generic nullary operator.
-  * It is the return type of the Ones(), Zero(), Constant(), Identity() and Random() methods,
-  * and most of the time this is the only way it is used.
-  *
-  * However, if you want to write a function returning such an expression, you
-  * will need to use this class.
-  *
-  * The functor NullaryOp must expose one of the following method:
-    <table class="manual">
-    <tr            ><td>\c operator()() </td><td>if the procedural generation does not depend on the coefficient entries (e.g., random numbers)</td></tr>
-    <tr class="alt"><td>\c operator()(Index i)</td><td>if the procedural generation makes sense for vectors only and that it depends on the coefficient index \c i (e.g., linspace) </td></tr>
-    <tr            ><td>\c operator()(Index i,Index j)</td><td>if the procedural generation depends on the matrix coordinates \c i, \c j (e.g., to generate a checkerboard with 0 and 1)</td></tr>
-    </table>
-  * It is also possible to expose the last two operators if the generation makes sense for matrices but can be optimized for vectors.
-  *
-  * See DenseBase::NullaryExpr(Index,const CustomNullaryOp&) for an example binding
-  * C++11 random number generators.
-  *
-  * A nullary expression can also be used to implement custom sophisticated matrix manipulations
-  * that cannot be covered by the existing set of natively supported matrix manipulations.
-  * See this \ref TopicCustomizing_NullaryExpr "page" for some examples and additional explanations
-  * on the behavior of CwiseNullaryOp.
-  *
-  * \sa class CwiseUnaryOp, class CwiseBinaryOp, DenseBase::NullaryExpr
-  */
-template<typename NullaryOp, typename PlainObjectType>
-class CwiseNullaryOp : public internal::dense_xpr_base< CwiseNullaryOp<NullaryOp, PlainObjectType> >::type, internal::no_assignment_operator
-{
-  public:
-
-    typedef typename internal::dense_xpr_base<CwiseNullaryOp>::type Base;
-    EIGEN_DENSE_PUBLIC_INTERFACE(CwiseNullaryOp)
-
-    EIGEN_DEVICE_FUNC
-    CwiseNullaryOp(Index rows, Index cols, const NullaryOp& func = NullaryOp())
-      : m_rows(rows), m_cols(cols), m_functor(func)
-    {
-      eigen_assert(rows >= 0
-            && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
-            &&  cols >= 0
-            && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
-    }
-
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Index rows() const { return m_rows.value(); }
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Index cols() const { return m_cols.value(); }
-
-    /** \returns the functor representing the nullary operation */
-    EIGEN_DEVICE_FUNC
-    const NullaryOp& functor() const { return m_functor; }
-
-  protected:
-    const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_rows;
-    const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_cols;
-    const NullaryOp m_functor;
-};
-
-
-/** \returns an expression of a matrix defined by a custom functor \a func
-  *
-  * The parameters \a rows and \a cols are the number of rows and of columns of
-  * the returned matrix. Must be compatible with this MatrixBase type.
-  *
-  * This variant is meant to be used for dynamic-size matrix types. For fixed-size types,
-  * it is redundant to pass \a rows and \a cols as arguments, so Zero() should be used
-  * instead.
-  *
-  * The template parameter \a CustomNullaryOp is the type of the functor.
-  *
-  * \sa class CwiseNullaryOp
-  */
-template<typename Derived>
-template<typename CustomNullaryOp>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
-DenseBase<Derived>::NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func)
-{
-  return CwiseNullaryOp<CustomNullaryOp, PlainObject>(rows, cols, func);
-}
-
-/** \returns an expression of a matrix defined by a custom functor \a func
-  *
-  * The parameter \a size is the size of the returned vector.
-  * Must be compatible with this MatrixBase type.
-  *
-  * \only_for_vectors
-  *
-  * This variant is meant to be used for dynamic-size vector types. For fixed-size types,
-  * it is redundant to pass \a size as argument, so Zero() should be used
-  * instead.
-  *
-  * The template parameter \a CustomNullaryOp is the type of the functor.
-  *
-  * Here is an example with C++11 random generators: \include random_cpp11.cpp
-  * Output: \verbinclude random_cpp11.out
-  * 
-  * \sa class CwiseNullaryOp
-  */
-template<typename Derived>
-template<typename CustomNullaryOp>
-EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
-DenseBase<Derived>::NullaryExpr(Index size, const CustomNullaryOp& func)
-{
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
-  if(RowsAtCompileTime == 1) return CwiseNullaryOp<CustomNullaryOp, PlainObject>(1, size, func);
-  else return CwiseNullaryOp<CustomNullaryOp, PlainObject>(size, 1, func);
-}
-
-/** \returns an expression of a matrix defined by a custom functor \a func
-  *
-  * This variant is only for fixed-size DenseBase types. For dynamic-size types, you
-  * need to use the variants taking size arguments.
-  *
-  * The template parameter \a CustomNullaryOp is the type of the functor.
-  *
-  * \sa class CwiseNullaryOp
-  */
-template<typename Derived>
-template<typename CustomNullaryOp>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
-DenseBase<Derived>::NullaryExpr(const CustomNullaryOp& func)
-{
-  return CwiseNullaryOp<CustomNullaryOp, PlainObject>(RowsAtCompileTime, ColsAtCompileTime, func);
-}
-
-/** \returns an expression of a constant matrix of value \a value
-  *
-  * The parameters \a rows and \a cols are the number of rows and of columns of
-  * the returned matrix. Must be compatible with this DenseBase type.
-  *
-  * This variant is meant to be used for dynamic-size matrix types. For fixed-size types,
-  * it is redundant to pass \a rows and \a cols as arguments, so Zero() should be used
-  * instead.
-  *
-  * The template parameter \a CustomNullaryOp is the type of the functor.
-  *
-  * \sa class CwiseNullaryOp
-  */
-template<typename Derived>
-EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
-DenseBase<Derived>::Constant(Index rows, Index cols, const Scalar& value)
-{
-  return DenseBase<Derived>::NullaryExpr(rows, cols, internal::scalar_constant_op<Scalar>(value));
-}
-
-/** \returns an expression of a constant matrix of value \a value
-  *
-  * The parameter \a size is the size of the returned vector.
-  * Must be compatible with this DenseBase type.
-  *
-  * \only_for_vectors
-  *
-  * This variant is meant to be used for dynamic-size vector types. For fixed-size types,
-  * it is redundant to pass \a size as argument, so Zero() should be used
-  * instead.
-  *
-  * The template parameter \a CustomNullaryOp is the type of the functor.
-  *
-  * \sa class CwiseNullaryOp
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
-DenseBase<Derived>::Constant(Index size, const Scalar& value)
-{
-  return DenseBase<Derived>::NullaryExpr(size, internal::scalar_constant_op<Scalar>(value));
-}
-
-/** \returns an expression of a constant matrix of value \a value
-  *
-  * This variant is only for fixed-size DenseBase types. For dynamic-size types, you
-  * need to use the variants taking size arguments.
-  *
-  * The template parameter \a CustomNullaryOp is the type of the functor.
-  *
-  * \sa class CwiseNullaryOp
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
-DenseBase<Derived>::Constant(const Scalar& value)
-{
-  EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
-  return DenseBase<Derived>::NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, internal::scalar_constant_op<Scalar>(value));
-}
-
-/** \deprecated because of accuracy loss. In Eigen 3.3, it is an alias for LinSpaced(Index,const Scalar&,const Scalar&)
-  *
-  * \sa LinSpaced(Index,Scalar,Scalar), setLinSpaced(Index,const Scalar&,const Scalar&)
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
-DenseBase<Derived>::LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high)
-{
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
-  return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar,PacketScalar>(low,high,size));
-}
-
-/** \deprecated because of accuracy loss. In Eigen 3.3, it is an alias for LinSpaced(const Scalar&,const Scalar&)
-  *
-  * \sa LinSpaced(Scalar,Scalar)
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
-DenseBase<Derived>::LinSpaced(Sequential_t, const Scalar& low, const Scalar& high)
-{
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
-  EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
-  return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar,PacketScalar>(low,high,Derived::SizeAtCompileTime));
-}
-
-/**
-  * \brief Sets a linearly spaced vector.
-  *
-  * The function generates 'size' equally spaced values in the closed interval [low,high].
-  * When size is set to 1, a vector of length 1 containing 'high' is returned.
-  *
-  * \only_for_vectors
-  *
-  * Example: \include DenseBase_LinSpaced.cpp
-  * Output: \verbinclude DenseBase_LinSpaced.out
-  *
-  * For integer scalar types, an even spacing is possible if and only if the length of the range,
-  * i.e., \c high-low is a scalar multiple of \c size-1, or if \c size is a scalar multiple of the
-  * number of values \c high-low+1 (meaning each value can be repeated the same number of time).
-  * If one of these two considions is not satisfied, then \c high is lowered to the largest value
-  * satisfying one of this constraint.
-  * Here are some examples:
-  *
-  * Example: \include DenseBase_LinSpacedInt.cpp
-  * Output: \verbinclude DenseBase_LinSpacedInt.out
-  *
-  * \sa setLinSpaced(Index,const Scalar&,const Scalar&), CwiseNullaryOp
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
-DenseBase<Derived>::LinSpaced(Index size, const Scalar& low, const Scalar& high)
-{
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
-  return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar,PacketScalar>(low,high,size));
-}
-
-/**
-  * \copydoc DenseBase::LinSpaced(Index, const Scalar&, const Scalar&)
-  * Special version for fixed size types which does not require the size parameter.
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
-DenseBase<Derived>::LinSpaced(const Scalar& low, const Scalar& high)
-{
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
-  EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
-  return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar,PacketScalar>(low,high,Derived::SizeAtCompileTime));
-}
-
-/** \returns true if all coefficients in this matrix are approximately equal to \a val, to within precision \a prec */
-template<typename Derived>
-EIGEN_DEVICE_FUNC bool DenseBase<Derived>::isApproxToConstant
-(const Scalar& val, const RealScalar& prec) const
-{
-  typename internal::nested_eval<Derived,1>::type self(derived());
-  for(Index j = 0; j < cols(); ++j)
-    for(Index i = 0; i < rows(); ++i)
-      if(!internal::isApprox(self.coeff(i, j), val, prec))
-        return false;
-  return true;
-}
-
-/** This is just an alias for isApproxToConstant().
-  *
-  * \returns true if all coefficients in this matrix are approximately equal to \a value, to within precision \a prec */
-template<typename Derived>
-EIGEN_DEVICE_FUNC bool DenseBase<Derived>::isConstant
-(const Scalar& val, const RealScalar& prec) const
-{
-  return isApproxToConstant(val, prec);
-}
-
-/** Alias for setConstant(): sets all coefficients in this expression to \a val.
-  *
-  * \sa setConstant(), Constant(), class CwiseNullaryOp
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void DenseBase<Derived>::fill(const Scalar& val)
-{
-  setConstant(val);
-}
-
-/** Sets all coefficients in this expression to value \a val.
-  *
-  * \sa fill(), setConstant(Index,const Scalar&), setConstant(Index,Index,const Scalar&), setZero(), setOnes(), Constant(), class CwiseNullaryOp, setZero(), setOnes()
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setConstant(const Scalar& val)
-{
-  return derived() = Constant(rows(), cols(), val);
-}
-
-/** Resizes to the given \a size, and sets all coefficients in this expression to the given value \a val.
-  *
-  * \only_for_vectors
-  *
-  * Example: \include Matrix_setConstant_int.cpp
-  * Output: \verbinclude Matrix_setConstant_int.out
-  *
-  * \sa MatrixBase::setConstant(const Scalar&), setConstant(Index,Index,const Scalar&), class CwiseNullaryOp, MatrixBase::Constant(const Scalar&)
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
-PlainObjectBase<Derived>::setConstant(Index size, const Scalar& val)
-{
-  resize(size);
-  return setConstant(val);
-}
-
-/** Resizes to the given size, and sets all coefficients in this expression to the given value \a val.
-  *
-  * \param rows the new number of rows
-  * \param cols the new number of columns
-  * \param val the value to which all coefficients are set
-  *
-  * Example: \include Matrix_setConstant_int_int.cpp
-  * Output: \verbinclude Matrix_setConstant_int_int.out
-  *
-  * \sa MatrixBase::setConstant(const Scalar&), setConstant(Index,const Scalar&), class CwiseNullaryOp, MatrixBase::Constant(const Scalar&)
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
-PlainObjectBase<Derived>::setConstant(Index rows, Index cols, const Scalar& val)
-{
-  resize(rows, cols);
-  return setConstant(val);
-}
-
-/**
-  * \brief Sets a linearly spaced vector.
-  *
-  * The function generates 'size' equally spaced values in the closed interval [low,high].
-  * When size is set to 1, a vector of length 1 containing 'high' is returned.
-  *
-  * \only_for_vectors
-  *
-  * Example: \include DenseBase_setLinSpaced.cpp
-  * Output: \verbinclude DenseBase_setLinSpaced.out
-  *
-  * For integer scalar types, do not miss the explanations on the definition
-  * of \link LinSpaced(Index,const Scalar&,const Scalar&) even spacing \endlink.
-  *
-  * \sa LinSpaced(Index,const Scalar&,const Scalar&), CwiseNullaryOp
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(Index newSize, const Scalar& low, const Scalar& high)
-{
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
-  return derived() = Derived::NullaryExpr(newSize, internal::linspaced_op<Scalar,PacketScalar>(low,high,newSize));
-}
-
-/**
-  * \brief Sets a linearly spaced vector.
-  *
-  * The function fills \c *this with equally spaced values in the closed interval [low,high].
-  * When size is set to 1, a vector of length 1 containing 'high' is returned.
-  *
-  * \only_for_vectors
-  *
-  * For integer scalar types, do not miss the explanations on the definition
-  * of \link LinSpaced(Index,const Scalar&,const Scalar&) even spacing \endlink.
-  *
-  * \sa LinSpaced(Index,const Scalar&,const Scalar&), setLinSpaced(Index, const Scalar&, const Scalar&), CwiseNullaryOp
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(const Scalar& low, const Scalar& high)
-{
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
-  return setLinSpaced(size(), low, high);
-}
-
-// zero:
-
-/** \returns an expression of a zero matrix.
-  *
-  * The parameters \a rows and \a cols are the number of rows and of columns of
-  * the returned matrix. Must be compatible with this MatrixBase type.
-  *
-  * This variant is meant to be used for dynamic-size matrix types. For fixed-size types,
-  * it is redundant to pass \a rows and \a cols as arguments, so Zero() should be used
-  * instead.
-  *
-  * Example: \include MatrixBase_zero_int_int.cpp
-  * Output: \verbinclude MatrixBase_zero_int_int.out
-  *
-  * \sa Zero(), Zero(Index)
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
-DenseBase<Derived>::Zero(Index rows, Index cols)
-{
-  return Constant(rows, cols, Scalar(0));
-}
-
-/** \returns an expression of a zero vector.
-  *
-  * The parameter \a size is the size of the returned vector.
-  * Must be compatible with this MatrixBase type.
-  *
-  * \only_for_vectors
-  *
-  * This variant is meant to be used for dynamic-size vector types. For fixed-size types,
-  * it is redundant to pass \a size as argument, so Zero() should be used
-  * instead.
-  *
-  * Example: \include MatrixBase_zero_int.cpp
-  * Output: \verbinclude MatrixBase_zero_int.out
-  *
-  * \sa Zero(), Zero(Index,Index)
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
-DenseBase<Derived>::Zero(Index size)
-{
-  return Constant(size, Scalar(0));
-}
-
-/** \returns an expression of a fixed-size zero matrix or vector.
-  *
-  * This variant is only for fixed-size MatrixBase types. For dynamic-size types, you
-  * need to use the variants taking size arguments.
-  *
-  * Example: \include MatrixBase_zero.cpp
-  * Output: \verbinclude MatrixBase_zero.out
-  *
-  * \sa Zero(Index), Zero(Index,Index)
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
-DenseBase<Derived>::Zero()
-{
-  return Constant(Scalar(0));
-}
-
-/** \returns true if *this is approximately equal to the zero matrix,
-  *          within the precision given by \a prec.
-  *
-  * Example: \include MatrixBase_isZero.cpp
-  * Output: \verbinclude MatrixBase_isZero.out
-  *
-  * \sa class CwiseNullaryOp, Zero()
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC bool DenseBase<Derived>::isZero(const RealScalar& prec) const
-{
-  typename internal::nested_eval<Derived,1>::type self(derived());
-  for(Index j = 0; j < cols(); ++j)
-    for(Index i = 0; i < rows(); ++i)
-      if(!internal::isMuchSmallerThan(self.coeff(i, j), static_cast<Scalar>(1), prec))
-        return false;
-  return true;
-}
-
-/** Sets all coefficients in this expression to zero.
-  *
-  * Example: \include MatrixBase_setZero.cpp
-  * Output: \verbinclude MatrixBase_setZero.out
-  *
-  * \sa class CwiseNullaryOp, Zero()
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setZero()
-{
-  return setConstant(Scalar(0));
-}
-
-/** Resizes to the given \a size, and sets all coefficients in this expression to zero.
-  *
-  * \only_for_vectors
-  *
-  * Example: \include Matrix_setZero_int.cpp
-  * Output: \verbinclude Matrix_setZero_int.out
-  *
-  * \sa DenseBase::setZero(), setZero(Index,Index), class CwiseNullaryOp, DenseBase::Zero()
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
-PlainObjectBase<Derived>::setZero(Index newSize)
-{
-  resize(newSize);
-  return setConstant(Scalar(0));
-}
-
-/** Resizes to the given size, and sets all coefficients in this expression to zero.
-  *
-  * \param rows the new number of rows
-  * \param cols the new number of columns
-  *
-  * Example: \include Matrix_setZero_int_int.cpp
-  * Output: \verbinclude Matrix_setZero_int_int.out
-  *
-  * \sa DenseBase::setZero(), setZero(Index), class CwiseNullaryOp, DenseBase::Zero()
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
-PlainObjectBase<Derived>::setZero(Index rows, Index cols)
-{
-  resize(rows, cols);
-  return setConstant(Scalar(0));
-}
-
-// ones:
-
-/** \returns an expression of a matrix where all coefficients equal one.
-  *
-  * The parameters \a rows and \a cols are the number of rows and of columns of
-  * the returned matrix. Must be compatible with this MatrixBase type.
-  *
-  * This variant is meant to be used for dynamic-size matrix types. For fixed-size types,
-  * it is redundant to pass \a rows and \a cols as arguments, so Ones() should be used
-  * instead.
-  *
-  * Example: \include MatrixBase_ones_int_int.cpp
-  * Output: \verbinclude MatrixBase_ones_int_int.out
-  *
-  * \sa Ones(), Ones(Index), isOnes(), class Ones
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
-DenseBase<Derived>::Ones(Index rows, Index cols)
-{
-  return Constant(rows, cols, Scalar(1));
-}
-
-/** \returns an expression of a vector where all coefficients equal one.
-  *
-  * The parameter \a newSize is the size of the returned vector.
-  * Must be compatible with this MatrixBase type.
-  *
-  * \only_for_vectors
-  *
-  * This variant is meant to be used for dynamic-size vector types. For fixed-size types,
-  * it is redundant to pass \a size as argument, so Ones() should be used
-  * instead.
-  *
-  * Example: \include MatrixBase_ones_int.cpp
-  * Output: \verbinclude MatrixBase_ones_int.out
-  *
-  * \sa Ones(), Ones(Index,Index), isOnes(), class Ones
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
-DenseBase<Derived>::Ones(Index newSize)
-{
-  return Constant(newSize, Scalar(1));
-}
-
-/** \returns an expression of a fixed-size matrix or vector where all coefficients equal one.
-  *
-  * This variant is only for fixed-size MatrixBase types. For dynamic-size types, you
-  * need to use the variants taking size arguments.
-  *
-  * Example: \include MatrixBase_ones.cpp
-  * Output: \verbinclude MatrixBase_ones.out
-  *
-  * \sa Ones(Index), Ones(Index,Index), isOnes(), class Ones
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
-DenseBase<Derived>::Ones()
-{
-  return Constant(Scalar(1));
-}
-
-/** \returns true if *this is approximately equal to the matrix where all coefficients
-  *          are equal to 1, within the precision given by \a prec.
-  *
-  * Example: \include MatrixBase_isOnes.cpp
-  * Output: \verbinclude MatrixBase_isOnes.out
-  *
-  * \sa class CwiseNullaryOp, Ones()
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC bool DenseBase<Derived>::isOnes
-(const RealScalar& prec) const
-{
-  return isApproxToConstant(Scalar(1), prec);
-}
-
-/** Sets all coefficients in this expression to one.
-  *
-  * Example: \include MatrixBase_setOnes.cpp
-  * Output: \verbinclude MatrixBase_setOnes.out
-  *
-  * \sa class CwiseNullaryOp, Ones()
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setOnes()
-{
-  return setConstant(Scalar(1));
-}
-
-/** Resizes to the given \a newSize, and sets all coefficients in this expression to one.
-  *
-  * \only_for_vectors
-  *
-  * Example: \include Matrix_setOnes_int.cpp
-  * Output: \verbinclude Matrix_setOnes_int.out
-  *
-  * \sa MatrixBase::setOnes(), setOnes(Index,Index), class CwiseNullaryOp, MatrixBase::Ones()
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
-PlainObjectBase<Derived>::setOnes(Index newSize)
-{
-  resize(newSize);
-  return setConstant(Scalar(1));
-}
-
-/** Resizes to the given size, and sets all coefficients in this expression to one.
-  *
-  * \param rows the new number of rows
-  * \param cols the new number of columns
-  *
-  * Example: \include Matrix_setOnes_int_int.cpp
-  * Output: \verbinclude Matrix_setOnes_int_int.out
-  *
-  * \sa MatrixBase::setOnes(), setOnes(Index), class CwiseNullaryOp, MatrixBase::Ones()
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
-PlainObjectBase<Derived>::setOnes(Index rows, Index cols)
-{
-  resize(rows, cols);
-  return setConstant(Scalar(1));
-}
-
-// Identity:
-
-/** \returns an expression of the identity matrix (not necessarily square).
-  *
-  * The parameters \a rows and \a cols are the number of rows and of columns of
-  * the returned matrix. Must be compatible with this MatrixBase type.
-  *
-  * This variant is meant to be used for dynamic-size matrix types. For fixed-size types,
-  * it is redundant to pass \a rows and \a cols as arguments, so Identity() should be used
-  * instead.
-  *
-  * Example: \include MatrixBase_identity_int_int.cpp
-  * Output: \verbinclude MatrixBase_identity_int_int.out
-  *
-  * \sa Identity(), setIdentity(), isIdentity()
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::IdentityReturnType
-MatrixBase<Derived>::Identity(Index rows, Index cols)
-{
-  return DenseBase<Derived>::NullaryExpr(rows, cols, internal::scalar_identity_op<Scalar>());
-}
-
-/** \returns an expression of the identity matrix (not necessarily square).
-  *
-  * This variant is only for fixed-size MatrixBase types. For dynamic-size types, you
-  * need to use the variant taking size arguments.
-  *
-  * Example: \include MatrixBase_identity.cpp
-  * Output: \verbinclude MatrixBase_identity.out
-  *
-  * \sa Identity(Index,Index), setIdentity(), isIdentity()
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::IdentityReturnType
-MatrixBase<Derived>::Identity()
-{
-  EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
-  return MatrixBase<Derived>::NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, internal::scalar_identity_op<Scalar>());
-}
-
-/** \returns true if *this is approximately equal to the identity matrix
-  *          (not necessarily square),
-  *          within the precision given by \a prec.
-  *
-  * Example: \include MatrixBase_isIdentity.cpp
-  * Output: \verbinclude MatrixBase_isIdentity.out
-  *
-  * \sa class CwiseNullaryOp, Identity(), Identity(Index,Index), setIdentity()
-  */
-template<typename Derived>
-bool MatrixBase<Derived>::isIdentity
-(const RealScalar& prec) const
-{
-  typename internal::nested_eval<Derived,1>::type self(derived());
-  for(Index j = 0; j < cols(); ++j)
-  {
-    for(Index i = 0; i < rows(); ++i)
-    {
-      if(i == j)
-      {
-        if(!internal::isApprox(self.coeff(i, j), static_cast<Scalar>(1), prec))
-          return false;
-      }
-      else
-      {
-        if(!internal::isMuchSmallerThan(self.coeff(i, j), static_cast<RealScalar>(1), prec))
-          return false;
-      }
-    }
-  }
-  return true;
-}
-
-namespace internal {
-
-template<typename Derived, bool Big = (Derived::SizeAtCompileTime>=16)>
-struct setIdentity_impl
-{
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE Derived& run(Derived& m)
-  {
-    return m = Derived::Identity(m.rows(), m.cols());
-  }
-};
-
-template<typename Derived>
-struct setIdentity_impl<Derived, true>
-{
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE Derived& run(Derived& m)
-  {
-    m.setZero();
-    const Index size = numext::mini(m.rows(), m.cols());
-    for(Index i = 0; i < size; ++i) m.coeffRef(i,i) = typename Derived::Scalar(1);
-    return m;
-  }
-};
-
-} // end namespace internal
-
-/** Writes the identity expression (not necessarily square) into *this.
-  *
-  * Example: \include MatrixBase_setIdentity.cpp
-  * Output: \verbinclude MatrixBase_setIdentity.out
-  *
-  * \sa class CwiseNullaryOp, Identity(), Identity(Index,Index), isIdentity()
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity()
-{
-  return internal::setIdentity_impl<Derived>::run(derived());
-}
-
-/** \brief Resizes to the given size, and writes the identity expression (not necessarily square) into *this.
-  *
-  * \param rows the new number of rows
-  * \param cols the new number of columns
-  *
-  * Example: \include Matrix_setIdentity_int_int.cpp
-  * Output: \verbinclude Matrix_setIdentity_int_int.out
-  *
-  * \sa MatrixBase::setIdentity(), class CwiseNullaryOp, MatrixBase::Identity()
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity(Index rows, Index cols)
-{
-  derived().resize(rows, cols);
-  return setIdentity();
-}
-
-/** \returns an expression of the i-th unit (basis) vector.
-  *
-  * \only_for_vectors
-  *
-  * \sa MatrixBase::Unit(Index), MatrixBase::UnitX(), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(Index newSize, Index i)
-{
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
-  return BasisReturnType(SquareMatrixType::Identity(newSize,newSize), i);
-}
-
-/** \returns an expression of the i-th unit (basis) vector.
-  *
-  * \only_for_vectors
-  *
-  * This variant is for fixed-size vector only.
-  *
-  * \sa MatrixBase::Unit(Index,Index), MatrixBase::UnitX(), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(Index i)
-{
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
-  return BasisReturnType(SquareMatrixType::Identity(),i);
-}
-
-/** \returns an expression of the X axis unit vector (1{,0}^*)
-  *
-  * \only_for_vectors
-  *
-  * \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitX()
-{ return Derived::Unit(0); }
-
-/** \returns an expression of the Y axis unit vector (0,1{,0}^*)
-  *
-  * \only_for_vectors
-  *
-  * \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitY()
-{ return Derived::Unit(1); }
-
-/** \returns an expression of the Z axis unit vector (0,0,1{,0}^*)
-  *
-  * \only_for_vectors
-  *
-  * \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitZ()
-{ return Derived::Unit(2); }
-
-/** \returns an expression of the W axis unit vector (0,0,0,1)
-  *
-  * \only_for_vectors
-  *
-  * \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
-  */
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitW()
-{ return Derived::Unit(3); }
-
-} // end namespace Eigen
-
-#endif // EIGEN_CWISE_NULLARY_OP_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/CwiseTernaryOp.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/CwiseTernaryOp.h
deleted file mode 100644
index 9f3576f..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/CwiseTernaryOp.h
+++ /dev/null
@@ -1,197 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2016 Eugene Brevdo <ebrevdo@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_CWISE_TERNARY_OP_H
-#define EIGEN_CWISE_TERNARY_OP_H
-
-namespace Eigen {
-
-namespace internal {
-template <typename TernaryOp, typename Arg1, typename Arg2, typename Arg3>
-struct traits<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> > {
-  // we must not inherit from traits<Arg1> since it has
-  // the potential to cause problems with MSVC
-  typedef typename remove_all<Arg1>::type Ancestor;
-  typedef typename traits<Ancestor>::XprKind XprKind;
-  enum {
-    RowsAtCompileTime = traits<Ancestor>::RowsAtCompileTime,
-    ColsAtCompileTime = traits<Ancestor>::ColsAtCompileTime,
-    MaxRowsAtCompileTime = traits<Ancestor>::MaxRowsAtCompileTime,
-    MaxColsAtCompileTime = traits<Ancestor>::MaxColsAtCompileTime
-  };
-
-  // even though we require Arg1, Arg2, and Arg3 to have the same scalar type
-  // (see CwiseTernaryOp constructor),
-  // we still want to handle the case when the result type is different.
-  typedef typename result_of<TernaryOp(
-      const typename Arg1::Scalar&, const typename Arg2::Scalar&,
-      const typename Arg3::Scalar&)>::type Scalar;
-
-  typedef typename internal::traits<Arg1>::StorageKind StorageKind;
-  typedef typename internal::traits<Arg1>::StorageIndex StorageIndex;
-
-  typedef typename Arg1::Nested Arg1Nested;
-  typedef typename Arg2::Nested Arg2Nested;
-  typedef typename Arg3::Nested Arg3Nested;
-  typedef typename remove_reference<Arg1Nested>::type _Arg1Nested;
-  typedef typename remove_reference<Arg2Nested>::type _Arg2Nested;
-  typedef typename remove_reference<Arg3Nested>::type _Arg3Nested;
-  enum { Flags = _Arg1Nested::Flags & RowMajorBit };
-};
-}  // end namespace internal
-
-template <typename TernaryOp, typename Arg1, typename Arg2, typename Arg3,
-          typename StorageKind>
-class CwiseTernaryOpImpl;
-
-/** \class CwiseTernaryOp
-  * \ingroup Core_Module
-  *
-  * \brief Generic expression where a coefficient-wise ternary operator is
- * applied to two expressions
-  *
-  * \tparam TernaryOp template functor implementing the operator
-  * \tparam Arg1Type the type of the first argument
-  * \tparam Arg2Type the type of the second argument
-  * \tparam Arg3Type the type of the third argument
-  *
-  * This class represents an expression where a coefficient-wise ternary
- * operator is applied to three expressions.
-  * It is the return type of ternary operators, by which we mean only those
- * ternary operators where
-  * all three arguments are Eigen expressions.
-  * For example, the return type of betainc(matrix1, matrix2, matrix3) is a
- * CwiseTernaryOp.
-  *
-  * Most of the time, this is the only way that it is used, so you typically
- * don't have to name
-  * CwiseTernaryOp types explicitly.
-  *
-  * \sa MatrixBase::ternaryExpr(const MatrixBase<Argument2> &, const
- * MatrixBase<Argument3> &, const CustomTernaryOp &) const, class CwiseBinaryOp,
- * class CwiseUnaryOp, class CwiseNullaryOp
-  */
-template <typename TernaryOp, typename Arg1Type, typename Arg2Type,
-          typename Arg3Type>
-class CwiseTernaryOp : public CwiseTernaryOpImpl<
-                           TernaryOp, Arg1Type, Arg2Type, Arg3Type,
-                           typename internal::traits<Arg1Type>::StorageKind>,
-                       internal::no_assignment_operator
-{
- public:
-  typedef typename internal::remove_all<Arg1Type>::type Arg1;
-  typedef typename internal::remove_all<Arg2Type>::type Arg2;
-  typedef typename internal::remove_all<Arg3Type>::type Arg3;
-
-  typedef typename CwiseTernaryOpImpl<
-      TernaryOp, Arg1Type, Arg2Type, Arg3Type,
-      typename internal::traits<Arg1Type>::StorageKind>::Base Base;
-  EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseTernaryOp)
-
-  typedef typename internal::ref_selector<Arg1Type>::type Arg1Nested;
-  typedef typename internal::ref_selector<Arg2Type>::type Arg2Nested;
-  typedef typename internal::ref_selector<Arg3Type>::type Arg3Nested;
-  typedef typename internal::remove_reference<Arg1Nested>::type _Arg1Nested;
-  typedef typename internal::remove_reference<Arg2Nested>::type _Arg2Nested;
-  typedef typename internal::remove_reference<Arg3Nested>::type _Arg3Nested;
-
-  EIGEN_DEVICE_FUNC
-  EIGEN_STRONG_INLINE CwiseTernaryOp(const Arg1& a1, const Arg2& a2,
-                                     const Arg3& a3,
-                                     const TernaryOp& func = TernaryOp())
-      : m_arg1(a1), m_arg2(a2), m_arg3(a3), m_functor(func) {
-    // require the sizes to match
-    EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Arg1, Arg2)
-    EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Arg1, Arg3)
-
-    // The index types should match
-    EIGEN_STATIC_ASSERT((internal::is_same<
-                         typename internal::traits<Arg1Type>::StorageKind,
-                         typename internal::traits<Arg2Type>::StorageKind>::value),
-                        STORAGE_KIND_MUST_MATCH)
-    EIGEN_STATIC_ASSERT((internal::is_same<
-                         typename internal::traits<Arg1Type>::StorageKind,
-                         typename internal::traits<Arg3Type>::StorageKind>::value),
-                        STORAGE_KIND_MUST_MATCH)
-
-    eigen_assert(a1.rows() == a2.rows() && a1.cols() == a2.cols() &&
-                 a1.rows() == a3.rows() && a1.cols() == a3.cols());
-  }
-
-  EIGEN_DEVICE_FUNC
-  EIGEN_STRONG_INLINE Index rows() const {
-    // return the fixed size type if available to enable compile time
-    // optimizations
-    if (internal::traits<typename internal::remove_all<Arg1Nested>::type>::
-                RowsAtCompileTime == Dynamic &&
-        internal::traits<typename internal::remove_all<Arg2Nested>::type>::
-                RowsAtCompileTime == Dynamic)
-      return m_arg3.rows();
-    else if (internal::traits<typename internal::remove_all<Arg1Nested>::type>::
-                     RowsAtCompileTime == Dynamic &&
-             internal::traits<typename internal::remove_all<Arg3Nested>::type>::
-                     RowsAtCompileTime == Dynamic)
-      return m_arg2.rows();
-    else
-      return m_arg1.rows();
-  }
-  EIGEN_DEVICE_FUNC
-  EIGEN_STRONG_INLINE Index cols() const {
-    // return the fixed size type if available to enable compile time
-    // optimizations
-    if (internal::traits<typename internal::remove_all<Arg1Nested>::type>::
-                ColsAtCompileTime == Dynamic &&
-        internal::traits<typename internal::remove_all<Arg2Nested>::type>::
-                ColsAtCompileTime == Dynamic)
-      return m_arg3.cols();
-    else if (internal::traits<typename internal::remove_all<Arg1Nested>::type>::
-                     ColsAtCompileTime == Dynamic &&
-             internal::traits<typename internal::remove_all<Arg3Nested>::type>::
-                     ColsAtCompileTime == Dynamic)
-      return m_arg2.cols();
-    else
-      return m_arg1.cols();
-  }
-
-  /** \returns the first argument nested expression */
-  EIGEN_DEVICE_FUNC
-  const _Arg1Nested& arg1() const { return m_arg1; }
-  /** \returns the first argument nested expression */
-  EIGEN_DEVICE_FUNC
-  const _Arg2Nested& arg2() const { return m_arg2; }
-  /** \returns the third argument nested expression */
-  EIGEN_DEVICE_FUNC
-  const _Arg3Nested& arg3() const { return m_arg3; }
-  /** \returns the functor representing the ternary operation */
-  EIGEN_DEVICE_FUNC
-  const TernaryOp& functor() const { return m_functor; }
-
- protected:
-  Arg1Nested m_arg1;
-  Arg2Nested m_arg2;
-  Arg3Nested m_arg3;
-  const TernaryOp m_functor;
-};
-
-// Generic API dispatcher
-template <typename TernaryOp, typename Arg1, typename Arg2, typename Arg3,
-          typename StorageKind>
-class CwiseTernaryOpImpl
-    : public internal::generic_xpr_base<
-          CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> >::type {
- public:
-  typedef typename internal::generic_xpr_base<
-      CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> >::type Base;
-};
-
-}  // end namespace Eigen
-
-#endif  // EIGEN_CWISE_TERNARY_OP_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/CwiseUnaryOp.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/CwiseUnaryOp.h
deleted file mode 100644
index 1d2dd19..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/CwiseUnaryOp.h
+++ /dev/null
@@ -1,103 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_CWISE_UNARY_OP_H
-#define EIGEN_CWISE_UNARY_OP_H
-
-namespace Eigen { 
-
-namespace internal {
-template<typename UnaryOp, typename XprType>
-struct traits<CwiseUnaryOp<UnaryOp, XprType> >
- : traits<XprType>
-{
-  typedef typename result_of<
-                     UnaryOp(const typename XprType::Scalar&)
-                   >::type Scalar;
-  typedef typename XprType::Nested XprTypeNested;
-  typedef typename remove_reference<XprTypeNested>::type _XprTypeNested;
-  enum {
-    Flags = _XprTypeNested::Flags & RowMajorBit 
-  };
-};
-}
-
-template<typename UnaryOp, typename XprType, typename StorageKind>
-class CwiseUnaryOpImpl;
-
-/** \class CwiseUnaryOp
-  * \ingroup Core_Module
-  *
-  * \brief Generic expression where a coefficient-wise unary operator is applied to an expression
-  *
-  * \tparam UnaryOp template functor implementing the operator
-  * \tparam XprType the type of the expression to which we are applying the unary operator
-  *
-  * This class represents an expression where a unary operator is applied to an expression.
-  * It is the return type of all operations taking exactly 1 input expression, regardless of the
-  * presence of other inputs such as scalars. For example, the operator* in the expression 3*matrix
-  * is considered unary, because only the right-hand side is an expression, and its
-  * return type is a specialization of CwiseUnaryOp.
-  *
-  * Most of the time, this is the only way that it is used, so you typically don't have to name
-  * CwiseUnaryOp types explicitly.
-  *
-  * \sa MatrixBase::unaryExpr(const CustomUnaryOp &) const, class CwiseBinaryOp, class CwiseNullaryOp
-  */
-template<typename UnaryOp, typename XprType>
-class CwiseUnaryOp : public CwiseUnaryOpImpl<UnaryOp, XprType, typename internal::traits<XprType>::StorageKind>, internal::no_assignment_operator
-{
-  public:
-
-    typedef typename CwiseUnaryOpImpl<UnaryOp, XprType,typename internal::traits<XprType>::StorageKind>::Base Base;
-    EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryOp)
-    typedef typename internal::ref_selector<XprType>::type XprTypeNested;
-    typedef typename internal::remove_all<XprType>::type NestedExpression;
-
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-    explicit CwiseUnaryOp(const XprType& xpr, const UnaryOp& func = UnaryOp())
-      : m_xpr(xpr), m_functor(func) {}
-
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-    Index rows() const { return m_xpr.rows(); }
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-    Index cols() const { return m_xpr.cols(); }
-
-    /** \returns the functor representing the unary operation */
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-    const UnaryOp& functor() const { return m_functor; }
-
-    /** \returns the nested expression */
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-    const typename internal::remove_all<XprTypeNested>::type&
-    nestedExpression() const { return m_xpr; }
-
-    /** \returns the nested expression */
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-    typename internal::remove_all<XprTypeNested>::type&
-    nestedExpression() { return m_xpr; }
-
-  protected:
-    XprTypeNested m_xpr;
-    const UnaryOp m_functor;
-};
-
-// Generic API dispatcher
-template<typename UnaryOp, typename XprType, typename StorageKind>
-class CwiseUnaryOpImpl
-  : public internal::generic_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type
-{
-public:
-  typedef typename internal::generic_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type Base;
-};
-
-} // end namespace Eigen
-
-#endif // EIGEN_CWISE_UNARY_OP_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/CwiseUnaryView.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/CwiseUnaryView.h
deleted file mode 100644
index 2710330..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/CwiseUnaryView.h
+++ /dev/null
@@ -1,128 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_CWISE_UNARY_VIEW_H
-#define EIGEN_CWISE_UNARY_VIEW_H
-
-namespace Eigen {
-
-namespace internal {
-template<typename ViewOp, typename MatrixType>
-struct traits<CwiseUnaryView<ViewOp, MatrixType> >
- : traits<MatrixType>
-{
-  typedef typename result_of<
-                     ViewOp(const typename traits<MatrixType>::Scalar&)
-                   >::type Scalar;
-  typedef typename MatrixType::Nested MatrixTypeNested;
-  typedef typename remove_all<MatrixTypeNested>::type _MatrixTypeNested;
-  enum {
-    FlagsLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
-    Flags = traits<_MatrixTypeNested>::Flags & (RowMajorBit | FlagsLvalueBit | DirectAccessBit), // FIXME DirectAccessBit should not be handled by expressions
-    MatrixTypeInnerStride =  inner_stride_at_compile_time<MatrixType>::ret,
-    // need to cast the sizeof's from size_t to int explicitly, otherwise:
-    // "error: no integral type can represent all of the enumerator values
-    InnerStrideAtCompileTime = MatrixTypeInnerStride == Dynamic
-                             ? int(Dynamic)
-                             : int(MatrixTypeInnerStride) * int(sizeof(typename traits<MatrixType>::Scalar) / sizeof(Scalar)),
-    OuterStrideAtCompileTime = outer_stride_at_compile_time<MatrixType>::ret == Dynamic
-                             ? int(Dynamic)
-                             : outer_stride_at_compile_time<MatrixType>::ret * int(sizeof(typename traits<MatrixType>::Scalar) / sizeof(Scalar))
-  };
-};
-}
-
-template<typename ViewOp, typename MatrixType, typename StorageKind>
-class CwiseUnaryViewImpl;
-
-/** \class CwiseUnaryView
-  * \ingroup Core_Module
-  *
-  * \brief Generic lvalue expression of a coefficient-wise unary operator of a matrix or a vector
-  *
-  * \tparam ViewOp template functor implementing the view
-  * \tparam MatrixType the type of the matrix we are applying the unary operator
-  *
-  * This class represents a lvalue expression of a generic unary view operator of a matrix or a vector.
-  * It is the return type of real() and imag(), and most of the time this is the only way it is used.
-  *
-  * \sa MatrixBase::unaryViewExpr(const CustomUnaryOp &) const, class CwiseUnaryOp
-  */
-template<typename ViewOp, typename MatrixType>
-class CwiseUnaryView : public CwiseUnaryViewImpl<ViewOp, MatrixType, typename internal::traits<MatrixType>::StorageKind>
-{
-  public:
-
-    typedef typename CwiseUnaryViewImpl<ViewOp, MatrixType,typename internal::traits<MatrixType>::StorageKind>::Base Base;
-    EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryView)
-    typedef typename internal::ref_selector<MatrixType>::non_const_type MatrixTypeNested;
-    typedef typename internal::remove_all<MatrixType>::type NestedExpression;
-
-    explicit inline CwiseUnaryView(MatrixType& mat, const ViewOp& func = ViewOp())
-      : m_matrix(mat), m_functor(func) {}
-
-    EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryView)
-
-    EIGEN_STRONG_INLINE Index rows() const { return m_matrix.rows(); }
-    EIGEN_STRONG_INLINE Index cols() const { return m_matrix.cols(); }
-
-    /** \returns the functor representing unary operation */
-    const ViewOp& functor() const { return m_functor; }
-
-    /** \returns the nested expression */
-    const typename internal::remove_all<MatrixTypeNested>::type&
-    nestedExpression() const { return m_matrix; }
-
-    /** \returns the nested expression */
-    typename internal::remove_reference<MatrixTypeNested>::type&
-    nestedExpression() { return m_matrix.const_cast_derived(); }
-
-  protected:
-    MatrixTypeNested m_matrix;
-    ViewOp m_functor;
-};
-
-// Generic API dispatcher
-template<typename ViewOp, typename XprType, typename StorageKind>
-class CwiseUnaryViewImpl
-  : public internal::generic_xpr_base<CwiseUnaryView<ViewOp, XprType> >::type
-{
-public:
-  typedef typename internal::generic_xpr_base<CwiseUnaryView<ViewOp, XprType> >::type Base;
-};
-
-template<typename ViewOp, typename MatrixType>
-class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense>
-  : public internal::dense_xpr_base< CwiseUnaryView<ViewOp, MatrixType> >::type
-{
-  public:
-
-    typedef CwiseUnaryView<ViewOp, MatrixType> Derived;
-    typedef typename internal::dense_xpr_base< CwiseUnaryView<ViewOp, MatrixType> >::type Base;
-
-    EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
-    EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryViewImpl)
-    
-    EIGEN_DEVICE_FUNC inline Scalar* data() { return &(this->coeffRef(0)); }
-    EIGEN_DEVICE_FUNC inline const Scalar* data() const { return &(this->coeff(0)); }
-
-    EIGEN_DEVICE_FUNC inline Index innerStride() const
-    {
-      return derived().nestedExpression().innerStride() * sizeof(typename internal::traits<MatrixType>::Scalar) / sizeof(Scalar);
-    }
-
-    EIGEN_DEVICE_FUNC inline Index outerStride() const
-    {
-      return derived().nestedExpression().outerStride() * sizeof(typename internal::traits<MatrixType>::Scalar) / sizeof(Scalar);
-    }
-};
-
-} // end namespace Eigen
-
-#endif // EIGEN_CWISE_UNARY_VIEW_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/DenseBase.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/DenseBase.h
deleted file mode 100644
index 90066ae..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/DenseBase.h
+++ /dev/null
@@ -1,611 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_DENSEBASE_H
-#define EIGEN_DENSEBASE_H
-
-namespace Eigen {
-
-namespace internal {
-  
-// The index type defined by EIGEN_DEFAULT_DENSE_INDEX_TYPE must be a signed type.
-// This dummy function simply aims at checking that at compile time.
-static inline void check_DenseIndex_is_signed() {
-  EIGEN_STATIC_ASSERT(NumTraits<DenseIndex>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE); 
-}
-
-} // end namespace internal
-  
-/** \class DenseBase
-  * \ingroup Core_Module
-  *
-  * \brief Base class for all dense matrices, vectors, and arrays
-  *
-  * This class is the base that is inherited by all dense objects (matrix, vector, arrays,
-  * and related expression types). The common Eigen API for dense objects is contained in this class.
-  *
-  * \tparam Derived is the derived type, e.g., a matrix type or an expression.
-  *
-  * This class can be extended with the help of the plugin mechanism described on the page
-  * \ref TopicCustomizing_Plugins by defining the preprocessor symbol \c EIGEN_DENSEBASE_PLUGIN.
-  *
-  * \sa \blank \ref TopicClassHierarchy
-  */
-template<typename Derived> class DenseBase
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-  : public DenseCoeffsBase<Derived>
-#else
-  : public DenseCoeffsBase<Derived,DirectWriteAccessors>
-#endif // not EIGEN_PARSED_BY_DOXYGEN
-{
-  public:
-
-    /** Inner iterator type to iterate over the coefficients of a row or column.
-      * \sa class InnerIterator
-      */
-    typedef Eigen::InnerIterator<Derived> InnerIterator;
-
-    typedef typename internal::traits<Derived>::StorageKind StorageKind;
-
-    /**
-      * \brief The type used to store indices
-      * \details This typedef is relevant for types that store multiple indices such as
-      *          PermutationMatrix or Transpositions, otherwise it defaults to Eigen::Index
-      * \sa \blank \ref TopicPreprocessorDirectives, Eigen::Index, SparseMatrixBase.
-     */
-    typedef typename internal::traits<Derived>::StorageIndex StorageIndex;
-
-    /** The numeric type of the expression' coefficients, e.g. float, double, int or std::complex<float>, etc. */
-    typedef typename internal::traits<Derived>::Scalar Scalar;
-    
-    /** The numeric type of the expression' coefficients, e.g. float, double, int or std::complex<float>, etc.
-      *
-      * It is an alias for the Scalar type */
-    typedef Scalar value_type;
-    
-    typedef typename NumTraits<Scalar>::Real RealScalar;
-    typedef DenseCoeffsBase<Derived> Base;
-
-    using Base::derived;
-    using Base::const_cast_derived;
-    using Base::rows;
-    using Base::cols;
-    using Base::size;
-    using Base::rowIndexByOuterInner;
-    using Base::colIndexByOuterInner;
-    using Base::coeff;
-    using Base::coeffByOuterInner;
-    using Base::operator();
-    using Base::operator[];
-    using Base::x;
-    using Base::y;
-    using Base::z;
-    using Base::w;
-    using Base::stride;
-    using Base::innerStride;
-    using Base::outerStride;
-    using Base::rowStride;
-    using Base::colStride;
-    typedef typename Base::CoeffReturnType CoeffReturnType;
-
-    enum {
-
-      RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
-        /**< The number of rows at compile-time. This is just a copy of the value provided
-          * by the \a Derived type. If a value is not known at compile-time,
-          * it is set to the \a Dynamic constant.
-          * \sa MatrixBase::rows(), MatrixBase::cols(), ColsAtCompileTime, SizeAtCompileTime */
-
-      ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
-        /**< The number of columns at compile-time. This is just a copy of the value provided
-          * by the \a Derived type. If a value is not known at compile-time,
-          * it is set to the \a Dynamic constant.
-          * \sa MatrixBase::rows(), MatrixBase::cols(), RowsAtCompileTime, SizeAtCompileTime */
-
-
-      SizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::RowsAtCompileTime,
-                                                   internal::traits<Derived>::ColsAtCompileTime>::ret),
-        /**< This is equal to the number of coefficients, i.e. the number of
-          * rows times the number of columns, or to \a Dynamic if this is not
-          * known at compile-time. \sa RowsAtCompileTime, ColsAtCompileTime */
-
-      MaxRowsAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime,
-        /**< This value is equal to the maximum possible number of rows that this expression
-          * might have. If this expression might have an arbitrarily high number of rows,
-          * this value is set to \a Dynamic.
-          *
-          * This value is useful to know when evaluating an expression, in order to determine
-          * whether it is possible to avoid doing a dynamic memory allocation.
-          *
-          * \sa RowsAtCompileTime, MaxColsAtCompileTime, MaxSizeAtCompileTime
-          */
-
-      MaxColsAtCompileTime = internal::traits<Derived>::MaxColsAtCompileTime,
-        /**< This value is equal to the maximum possible number of columns that this expression
-          * might have. If this expression might have an arbitrarily high number of columns,
-          * this value is set to \a Dynamic.
-          *
-          * This value is useful to know when evaluating an expression, in order to determine
-          * whether it is possible to avoid doing a dynamic memory allocation.
-          *
-          * \sa ColsAtCompileTime, MaxRowsAtCompileTime, MaxSizeAtCompileTime
-          */
-
-      MaxSizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::MaxRowsAtCompileTime,
-                                                      internal::traits<Derived>::MaxColsAtCompileTime>::ret),
-        /**< This value is equal to the maximum possible number of coefficients that this expression
-          * might have. If this expression might have an arbitrarily high number of coefficients,
-          * this value is set to \a Dynamic.
-          *
-          * This value is useful to know when evaluating an expression, in order to determine
-          * whether it is possible to avoid doing a dynamic memory allocation.
-          *
-          * \sa SizeAtCompileTime, MaxRowsAtCompileTime, MaxColsAtCompileTime
-          */
-
-      IsVectorAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime == 1
-                           || internal::traits<Derived>::MaxColsAtCompileTime == 1,
-        /**< This is set to true if either the number of rows or the number of
-          * columns is known at compile-time to be equal to 1. Indeed, in that case,
-          * we are dealing with a column-vector (if there is only one column) or with
-          * a row-vector (if there is only one row). */
-
-      Flags = internal::traits<Derived>::Flags,
-        /**< This stores expression \ref flags flags which may or may not be inherited by new expressions
-          * constructed from this one. See the \ref flags "list of flags".
-          */
-
-      IsRowMajor = int(Flags) & RowMajorBit, /**< True if this expression has row-major storage order. */
-
-      InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime)
-                             : int(IsRowMajor) ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
-
-      InnerStrideAtCompileTime = internal::inner_stride_at_compile_time<Derived>::ret,
-      OuterStrideAtCompileTime = internal::outer_stride_at_compile_time<Derived>::ret
-    };
-    
-    typedef typename internal::find_best_packet<Scalar,SizeAtCompileTime>::type PacketScalar;
-
-    enum { IsPlainObjectBase = 0 };
-    
-    /** The plain matrix type corresponding to this expression.
-      * \sa PlainObject */
-    typedef Matrix<typename internal::traits<Derived>::Scalar,
-                internal::traits<Derived>::RowsAtCompileTime,
-                internal::traits<Derived>::ColsAtCompileTime,
-                AutoAlign | (internal::traits<Derived>::Flags&RowMajorBit ? RowMajor : ColMajor),
-                internal::traits<Derived>::MaxRowsAtCompileTime,
-                internal::traits<Derived>::MaxColsAtCompileTime
-          > PlainMatrix;
-    
-    /** The plain array type corresponding to this expression.
-      * \sa PlainObject */
-    typedef Array<typename internal::traits<Derived>::Scalar,
-                internal::traits<Derived>::RowsAtCompileTime,
-                internal::traits<Derived>::ColsAtCompileTime,
-                AutoAlign | (internal::traits<Derived>::Flags&RowMajorBit ? RowMajor : ColMajor),
-                internal::traits<Derived>::MaxRowsAtCompileTime,
-                internal::traits<Derived>::MaxColsAtCompileTime
-          > PlainArray;
-
-    /** \brief The plain matrix or array type corresponding to this expression.
-      *
-      * This is not necessarily exactly the return type of eval(). In the case of plain matrices,
-      * the return type of eval() is a const reference to a matrix, not a matrix! It is however guaranteed
-      * that the return type of eval() is either PlainObject or const PlainObject&.
-      */
-    typedef typename internal::conditional<internal::is_same<typename internal::traits<Derived>::XprKind,MatrixXpr >::value,
-                                 PlainMatrix, PlainArray>::type PlainObject;
-
-    /** \returns the number of nonzero coefficients which is in practice the number
-      * of stored coefficients. */
-    EIGEN_DEVICE_FUNC
-    inline Index nonZeros() const { return size(); }
-
-    /** \returns the outer size.
-      *
-      * \note For a vector, this returns just 1. For a matrix (non-vector), this is the major dimension
-      * with respect to the \ref TopicStorageOrders "storage order", i.e., the number of columns for a
-      * column-major matrix, and the number of rows for a row-major matrix. */
-    EIGEN_DEVICE_FUNC
-    Index outerSize() const
-    {
-      return IsVectorAtCompileTime ? 1
-           : int(IsRowMajor) ? this->rows() : this->cols();
-    }
-
-    /** \returns the inner size.
-      *
-      * \note For a vector, this is just the size. For a matrix (non-vector), this is the minor dimension
-      * with respect to the \ref TopicStorageOrders "storage order", i.e., the number of rows for a 
-      * column-major matrix, and the number of columns for a row-major matrix. */
-    EIGEN_DEVICE_FUNC
-    Index innerSize() const
-    {
-      return IsVectorAtCompileTime ? this->size()
-           : int(IsRowMajor) ? this->cols() : this->rows();
-    }
-
-    /** Only plain matrices/arrays, not expressions, may be resized; therefore the only useful resize methods are
-      * Matrix::resize() and Array::resize(). The present method only asserts that the new size equals the old size, and does
-      * nothing else.
-      */
-    EIGEN_DEVICE_FUNC
-    void resize(Index newSize)
-    {
-      EIGEN_ONLY_USED_FOR_DEBUG(newSize);
-      eigen_assert(newSize == this->size()
-                && "DenseBase::resize() does not actually allow to resize.");
-    }
-    /** Only plain matrices/arrays, not expressions, may be resized; therefore the only useful resize methods are
-      * Matrix::resize() and Array::resize(). The present method only asserts that the new size equals the old size, and does
-      * nothing else.
-      */
-    EIGEN_DEVICE_FUNC
-    void resize(Index rows, Index cols)
-    {
-      EIGEN_ONLY_USED_FOR_DEBUG(rows);
-      EIGEN_ONLY_USED_FOR_DEBUG(cols);
-      eigen_assert(rows == this->rows() && cols == this->cols()
-                && "DenseBase::resize() does not actually allow to resize.");
-    }
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-    /** \internal Represents a matrix with all coefficients equal to one another*/
-    typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,PlainObject> ConstantReturnType;
-    /** \internal \deprecated Represents a vector with linearly spaced coefficients that allows sequential access only. */
-    typedef CwiseNullaryOp<internal::linspaced_op<Scalar,PacketScalar>,PlainObject> SequentialLinSpacedReturnType;
-    /** \internal Represents a vector with linearly spaced coefficients that allows random access. */
-    typedef CwiseNullaryOp<internal::linspaced_op<Scalar,PacketScalar>,PlainObject> RandomAccessLinSpacedReturnType;
-    /** \internal the return type of MatrixBase::eigenvalues() */
-    typedef Matrix<typename NumTraits<typename internal::traits<Derived>::Scalar>::Real, internal::traits<Derived>::ColsAtCompileTime, 1> EigenvaluesReturnType;
-
-#endif // not EIGEN_PARSED_BY_DOXYGEN
-
-    /** Copies \a other into *this. \returns a reference to *this. */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-    Derived& operator=(const DenseBase<OtherDerived>& other);
-
-    /** Special case of the template operator=, in order to prevent the compiler
-      * from generating a default operator= (issue hit with g++ 4.1)
-      */
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-    Derived& operator=(const DenseBase& other);
-
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    Derived& operator=(const EigenBase<OtherDerived> &other);
-
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    Derived& operator+=(const EigenBase<OtherDerived> &other);
-
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    Derived& operator-=(const EigenBase<OtherDerived> &other);
-
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    Derived& operator=(const ReturnByValue<OtherDerived>& func);
-
-    /** \internal
-      * Copies \a other into *this without evaluating other. \returns a reference to *this.
-      * \deprecated */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    Derived& lazyAssign(const DenseBase<OtherDerived>& other);
-
-    EIGEN_DEVICE_FUNC
-    CommaInitializer<Derived> operator<< (const Scalar& s);
-
-    /** \deprecated it now returns \c *this */
-    template<unsigned int Added,unsigned int Removed>
-    EIGEN_DEPRECATED
-    const Derived& flagged() const
-    { return derived(); }
-
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    CommaInitializer<Derived> operator<< (const DenseBase<OtherDerived>& other);
-
-    typedef Transpose<Derived> TransposeReturnType;
-    EIGEN_DEVICE_FUNC
-    TransposeReturnType transpose();
-    typedef typename internal::add_const<Transpose<const Derived> >::type ConstTransposeReturnType;
-    EIGEN_DEVICE_FUNC
-    ConstTransposeReturnType transpose() const;
-    EIGEN_DEVICE_FUNC
-    void transposeInPlace();
-
-    EIGEN_DEVICE_FUNC static const ConstantReturnType
-    Constant(Index rows, Index cols, const Scalar& value);
-    EIGEN_DEVICE_FUNC static const ConstantReturnType
-    Constant(Index size, const Scalar& value);
-    EIGEN_DEVICE_FUNC static const ConstantReturnType
-    Constant(const Scalar& value);
-
-    EIGEN_DEVICE_FUNC static const SequentialLinSpacedReturnType
-    LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high);
-    EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType
-    LinSpaced(Index size, const Scalar& low, const Scalar& high);
-    EIGEN_DEVICE_FUNC static const SequentialLinSpacedReturnType
-    LinSpaced(Sequential_t, const Scalar& low, const Scalar& high);
-    EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType
-    LinSpaced(const Scalar& low, const Scalar& high);
-
-    template<typename CustomNullaryOp> EIGEN_DEVICE_FUNC
-    static const CwiseNullaryOp<CustomNullaryOp, PlainObject>
-    NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func);
-    template<typename CustomNullaryOp> EIGEN_DEVICE_FUNC
-    static const CwiseNullaryOp<CustomNullaryOp, PlainObject>
-    NullaryExpr(Index size, const CustomNullaryOp& func);
-    template<typename CustomNullaryOp> EIGEN_DEVICE_FUNC
-    static const CwiseNullaryOp<CustomNullaryOp, PlainObject>
-    NullaryExpr(const CustomNullaryOp& func);
-
-    EIGEN_DEVICE_FUNC static const ConstantReturnType Zero(Index rows, Index cols);
-    EIGEN_DEVICE_FUNC static const ConstantReturnType Zero(Index size);
-    EIGEN_DEVICE_FUNC static const ConstantReturnType Zero();
-    EIGEN_DEVICE_FUNC static const ConstantReturnType Ones(Index rows, Index cols);
-    EIGEN_DEVICE_FUNC static const ConstantReturnType Ones(Index size);
-    EIGEN_DEVICE_FUNC static const ConstantReturnType Ones();
-
-    EIGEN_DEVICE_FUNC void fill(const Scalar& value);
-    EIGEN_DEVICE_FUNC Derived& setConstant(const Scalar& value);
-    EIGEN_DEVICE_FUNC Derived& setLinSpaced(Index size, const Scalar& low, const Scalar& high);
-    EIGEN_DEVICE_FUNC Derived& setLinSpaced(const Scalar& low, const Scalar& high);
-    EIGEN_DEVICE_FUNC Derived& setZero();
-    EIGEN_DEVICE_FUNC Derived& setOnes();
-    EIGEN_DEVICE_FUNC Derived& setRandom();
-
-    template<typename OtherDerived> EIGEN_DEVICE_FUNC
-    bool isApprox(const DenseBase<OtherDerived>& other,
-                  const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
-    EIGEN_DEVICE_FUNC 
-    bool isMuchSmallerThan(const RealScalar& other,
-                           const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
-    template<typename OtherDerived> EIGEN_DEVICE_FUNC
-    bool isMuchSmallerThan(const DenseBase<OtherDerived>& other,
-                           const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
-
-    EIGEN_DEVICE_FUNC bool isApproxToConstant(const Scalar& value, const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
-    EIGEN_DEVICE_FUNC bool isConstant(const Scalar& value, const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
-    EIGEN_DEVICE_FUNC bool isZero(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
-    EIGEN_DEVICE_FUNC bool isOnes(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
-    
-    inline bool hasNaN() const;
-    inline bool allFinite() const;
-
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-    Derived& operator*=(const Scalar& other);
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-    Derived& operator/=(const Scalar& other);
-
-    typedef typename internal::add_const_on_value_type<typename internal::eval<Derived>::type>::type EvalReturnType;
-    /** \returns the matrix or vector obtained by evaluating this expression.
-      *
-      * Notice that in the case of a plain matrix or vector (not an expression) this function just returns
-      * a const reference, in order to avoid a useless copy.
-      * 
-      * \warning Be carefull with eval() and the auto C++ keyword, as detailed in this \link TopicPitfalls_auto_keyword page \endlink.
-      */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE EvalReturnType eval() const
-    {
-      // Even though MSVC does not honor strong inlining when the return type
-      // is a dynamic matrix, we desperately need strong inlining for fixed
-      // size types on MSVC.
-      return typename internal::eval<Derived>::type(derived());
-    }
-    
-    /** swaps *this with the expression \a other.
-      *
-      */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    void swap(const DenseBase<OtherDerived>& other)
-    {
-      EIGEN_STATIC_ASSERT(!OtherDerived::IsPlainObjectBase,THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
-      eigen_assert(rows()==other.rows() && cols()==other.cols());
-      call_assignment(derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
-    }
-
-    /** swaps *this with the matrix or array \a other.
-      *
-      */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    void swap(PlainObjectBase<OtherDerived>& other)
-    {
-      eigen_assert(rows()==other.rows() && cols()==other.cols());
-      call_assignment(derived(), other.derived(), internal::swap_assign_op<Scalar>());
-    }
-
-    EIGEN_DEVICE_FUNC inline const NestByValue<Derived> nestByValue() const;
-    EIGEN_DEVICE_FUNC inline const ForceAlignedAccess<Derived> forceAlignedAccess() const;
-    EIGEN_DEVICE_FUNC inline ForceAlignedAccess<Derived> forceAlignedAccess();
-    template<bool Enable> EIGEN_DEVICE_FUNC
-    inline const typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type forceAlignedAccessIf() const;
-    template<bool Enable> EIGEN_DEVICE_FUNC
-    inline typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type forceAlignedAccessIf();
-
-    EIGEN_DEVICE_FUNC Scalar sum() const;
-    EIGEN_DEVICE_FUNC Scalar mean() const;
-    EIGEN_DEVICE_FUNC Scalar trace() const;
-
-    EIGEN_DEVICE_FUNC Scalar prod() const;
-
-    EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar minCoeff() const;
-    EIGEN_DEVICE_FUNC typename internal::traits<Derived>::Scalar maxCoeff() const;
-
-    template<typename IndexType> EIGEN_DEVICE_FUNC
-    typename internal::traits<Derived>::Scalar minCoeff(IndexType* row, IndexType* col) const;
-    template<typename IndexType> EIGEN_DEVICE_FUNC
-    typename internal::traits<Derived>::Scalar maxCoeff(IndexType* row, IndexType* col) const;
-    template<typename IndexType> EIGEN_DEVICE_FUNC
-    typename internal::traits<Derived>::Scalar minCoeff(IndexType* index) const;
-    template<typename IndexType> EIGEN_DEVICE_FUNC
-    typename internal::traits<Derived>::Scalar maxCoeff(IndexType* index) const;
-
-    template<typename BinaryOp>
-    EIGEN_DEVICE_FUNC
-    Scalar redux(const BinaryOp& func) const;
-
-    template<typename Visitor>
-    EIGEN_DEVICE_FUNC
-    void visit(Visitor& func) const;
-
-    /** \returns a WithFormat proxy object allowing to print a matrix the with given
-      * format \a fmt.
-      *
-      * See class IOFormat for some examples.
-      *
-      * \sa class IOFormat, class WithFormat
-      */
-    inline const WithFormat<Derived> format(const IOFormat& fmt) const
-    {
-      return WithFormat<Derived>(derived(), fmt);
-    }
-
-    /** \returns the unique coefficient of a 1x1 expression */
-    EIGEN_DEVICE_FUNC
-    CoeffReturnType value() const
-    {
-      EIGEN_STATIC_ASSERT_SIZE_1x1(Derived)
-      eigen_assert(this->rows() == 1 && this->cols() == 1);
-      return derived().coeff(0,0);
-    }
-
-    EIGEN_DEVICE_FUNC bool all() const;
-    EIGEN_DEVICE_FUNC bool any() const;
-    EIGEN_DEVICE_FUNC Index count() const;
-
-    typedef VectorwiseOp<Derived, Horizontal> RowwiseReturnType;
-    typedef const VectorwiseOp<const Derived, Horizontal> ConstRowwiseReturnType;
-    typedef VectorwiseOp<Derived, Vertical> ColwiseReturnType;
-    typedef const VectorwiseOp<const Derived, Vertical> ConstColwiseReturnType;
-
-    /** \returns a VectorwiseOp wrapper of *this providing additional partial reduction operations
-    *
-    * Example: \include MatrixBase_rowwise.cpp
-    * Output: \verbinclude MatrixBase_rowwise.out
-    *
-    * \sa colwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting
-    */
-    //Code moved here due to a CUDA compiler bug
-    EIGEN_DEVICE_FUNC inline ConstRowwiseReturnType rowwise() const {
-      return ConstRowwiseReturnType(derived());
-    }
-    EIGEN_DEVICE_FUNC RowwiseReturnType rowwise();
-
-    /** \returns a VectorwiseOp wrapper of *this providing additional partial reduction operations
-    *
-    * Example: \include MatrixBase_colwise.cpp
-    * Output: \verbinclude MatrixBase_colwise.out
-    *
-    * \sa rowwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting
-    */
-    EIGEN_DEVICE_FUNC inline ConstColwiseReturnType colwise() const {
-      return ConstColwiseReturnType(derived());
-    }
-    EIGEN_DEVICE_FUNC ColwiseReturnType colwise();
-
-    typedef CwiseNullaryOp<internal::scalar_random_op<Scalar>,PlainObject> RandomReturnType;
-    static const RandomReturnType Random(Index rows, Index cols);
-    static const RandomReturnType Random(Index size);
-    static const RandomReturnType Random();
-
-    template<typename ThenDerived,typename ElseDerived>
-    const Select<Derived,ThenDerived,ElseDerived>
-    select(const DenseBase<ThenDerived>& thenMatrix,
-           const DenseBase<ElseDerived>& elseMatrix) const;
-
-    template<typename ThenDerived>
-    inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
-    select(const DenseBase<ThenDerived>& thenMatrix, const typename ThenDerived::Scalar& elseScalar) const;
-
-    template<typename ElseDerived>
-    inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
-    select(const typename ElseDerived::Scalar& thenScalar, const DenseBase<ElseDerived>& elseMatrix) const;
-
-    template<int p> RealScalar lpNorm() const;
-
-    template<int RowFactor, int ColFactor>
-    EIGEN_DEVICE_FUNC
-    const Replicate<Derived,RowFactor,ColFactor> replicate() const;
-    /**
-    * \return an expression of the replication of \c *this
-    *
-    * Example: \include MatrixBase_replicate_int_int.cpp
-    * Output: \verbinclude MatrixBase_replicate_int_int.out
-    *
-    * \sa VectorwiseOp::replicate(), DenseBase::replicate<int,int>(), class Replicate
-    */
-    //Code moved here due to a CUDA compiler bug
-    EIGEN_DEVICE_FUNC
-    const Replicate<Derived, Dynamic, Dynamic> replicate(Index rowFactor, Index colFactor) const
-    {
-      return Replicate<Derived, Dynamic, Dynamic>(derived(), rowFactor, colFactor);
-    }
-
-    typedef Reverse<Derived, BothDirections> ReverseReturnType;
-    typedef const Reverse<const Derived, BothDirections> ConstReverseReturnType;
-    EIGEN_DEVICE_FUNC ReverseReturnType reverse();
-    /** This is the const version of reverse(). */
-    //Code moved here due to a CUDA compiler bug
-    EIGEN_DEVICE_FUNC ConstReverseReturnType reverse() const
-    {
-      return ConstReverseReturnType(derived());
-    }
-    EIGEN_DEVICE_FUNC void reverseInPlace();
-
-#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::DenseBase
-#define EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
-#define EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(COND)
-#   include "../plugins/BlockMethods.h"
-#   ifdef EIGEN_DENSEBASE_PLUGIN
-#     include EIGEN_DENSEBASE_PLUGIN
-#   endif
-#undef EIGEN_CURRENT_STORAGE_BASE_CLASS
-#undef EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
-#undef EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF
-
-    // disable the use of evalTo for dense objects with a nice compilation error
-    template<typename Dest>
-    EIGEN_DEVICE_FUNC
-    inline void evalTo(Dest& ) const
-    {
-      EIGEN_STATIC_ASSERT((internal::is_same<Dest,void>::value),THE_EVAL_EVALTO_FUNCTION_SHOULD_NEVER_BE_CALLED_FOR_DENSE_OBJECTS);
-    }
-
-  protected:
-    /** Default constructor. Do nothing. */
-    EIGEN_DEVICE_FUNC DenseBase()
-    {
-      /* Just checks for self-consistency of the flags.
-       * Only do it when debugging Eigen, as this borders on paranoiac and could slow compilation down
-       */
-#ifdef EIGEN_INTERNAL_DEBUGGING
-      EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, int(IsRowMajor))
-                        && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, int(!IsRowMajor))),
-                          INVALID_STORAGE_ORDER_FOR_THIS_VECTOR_EXPRESSION)
-#endif
-    }
-
-  private:
-    EIGEN_DEVICE_FUNC explicit DenseBase(int);
-    EIGEN_DEVICE_FUNC DenseBase(int,int);
-    template<typename OtherDerived> EIGEN_DEVICE_FUNC explicit DenseBase(const DenseBase<OtherDerived>&);
-};
-
-} // end namespace Eigen
-
-#endif // EIGEN_DENSEBASE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/DenseCoeffsBase.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/DenseCoeffsBase.h
deleted file mode 100644
index c4af48a..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/DenseCoeffsBase.h
+++ /dev/null
@@ -1,681 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_DENSECOEFFSBASE_H
-#define EIGEN_DENSECOEFFSBASE_H
-
-namespace Eigen {
-
-namespace internal {
-template<typename T> struct add_const_on_value_type_if_arithmetic
-{
-  typedef typename conditional<is_arithmetic<T>::value, T, typename add_const_on_value_type<T>::type>::type type;
-};
-}
-
-/** \brief Base class providing read-only coefficient access to matrices and arrays.
-  * \ingroup Core_Module
-  * \tparam Derived Type of the derived class
-  * \tparam #ReadOnlyAccessors Constant indicating read-only access
-  *
-  * This class defines the \c operator() \c const function and friends, which can be used to read specific
-  * entries of a matrix or array.
-  * 
-  * \sa DenseCoeffsBase<Derived, WriteAccessors>, DenseCoeffsBase<Derived, DirectAccessors>,
-  *     \ref TopicClassHierarchy
-  */
-template<typename Derived>
-class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
-{
-  public:
-    typedef typename internal::traits<Derived>::StorageKind StorageKind;
-    typedef typename internal::traits<Derived>::Scalar Scalar;
-    typedef typename internal::packet_traits<Scalar>::type PacketScalar;
-
-    // Explanation for this CoeffReturnType typedef.
-    // - This is the return type of the coeff() method.
-    // - The LvalueBit means exactly that we can offer a coeffRef() method, which means exactly that we can get references
-    // to coeffs, which means exactly that we can have coeff() return a const reference (as opposed to returning a value).
-    // - The is_artihmetic check is required since "const int", "const double", etc. will cause warnings on some systems
-    // while the declaration of "const T", where T is a non arithmetic type does not. Always returning "const Scalar&" is
-    // not possible, since the underlying expressions might not offer a valid address the reference could be referring to.
-    typedef typename internal::conditional<bool(internal::traits<Derived>::Flags&LvalueBit),
-                         const Scalar&,
-                         typename internal::conditional<internal::is_arithmetic<Scalar>::value, Scalar, const Scalar>::type
-                     >::type CoeffReturnType;
-
-    typedef typename internal::add_const_on_value_type_if_arithmetic<
-                         typename internal::packet_traits<Scalar>::type
-                     >::type PacketReturnType;
-
-    typedef EigenBase<Derived> Base;
-    using Base::rows;
-    using Base::cols;
-    using Base::size;
-    using Base::derived;
-
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Index rowIndexByOuterInner(Index outer, Index inner) const
-    {
-      return int(Derived::RowsAtCompileTime) == 1 ? 0
-          : int(Derived::ColsAtCompileTime) == 1 ? inner
-          : int(Derived::Flags)&RowMajorBit ? outer
-          : inner;
-    }
-
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Index colIndexByOuterInner(Index outer, Index inner) const
-    {
-      return int(Derived::ColsAtCompileTime) == 1 ? 0
-          : int(Derived::RowsAtCompileTime) == 1 ? inner
-          : int(Derived::Flags)&RowMajorBit ? inner
-          : outer;
-    }
-
-    /** Short version: don't use this function, use
-      * \link operator()(Index,Index) const \endlink instead.
-      *
-      * Long version: this function is similar to
-      * \link operator()(Index,Index) const \endlink, but without the assertion.
-      * Use this for limiting the performance cost of debugging code when doing
-      * repeated coefficient access. Only use this when it is guaranteed that the
-      * parameters \a row and \a col are in range.
-      *
-      * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this
-      * function equivalent to \link operator()(Index,Index) const \endlink.
-      *
-      * \sa operator()(Index,Index) const, coeffRef(Index,Index), coeff(Index) const
-      */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const
-    {
-      eigen_internal_assert(row >= 0 && row < rows()
-                         && col >= 0 && col < cols());
-      return internal::evaluator<Derived>(derived()).coeff(row,col);
-    }
-
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE CoeffReturnType coeffByOuterInner(Index outer, Index inner) const
-    {
-      return coeff(rowIndexByOuterInner(outer, inner),
-                   colIndexByOuterInner(outer, inner));
-    }
-
-    /** \returns the coefficient at given the given row and column.
-      *
-      * \sa operator()(Index,Index), operator[](Index)
-      */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE CoeffReturnType operator()(Index row, Index col) const
-    {
-      eigen_assert(row >= 0 && row < rows()
-          && col >= 0 && col < cols());
-      return coeff(row, col);
-    }
-
-    /** Short version: don't use this function, use
-      * \link operator[](Index) const \endlink instead.
-      *
-      * Long version: this function is similar to
-      * \link operator[](Index) const \endlink, but without the assertion.
-      * Use this for limiting the performance cost of debugging code when doing
-      * repeated coefficient access. Only use this when it is guaranteed that the
-      * parameter \a index is in range.
-      *
-      * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this
-      * function equivalent to \link operator[](Index) const \endlink.
-      *
-      * \sa operator[](Index) const, coeffRef(Index), coeff(Index,Index) const
-      */
-
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE CoeffReturnType
-    coeff(Index index) const
-    {
-      EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit,
-                          THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS)
-      eigen_internal_assert(index >= 0 && index < size());
-      return internal::evaluator<Derived>(derived()).coeff(index);
-    }
-
-
-    /** \returns the coefficient at given index.
-      *
-      * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
-      *
-      * \sa operator[](Index), operator()(Index,Index) const, x() const, y() const,
-      * z() const, w() const
-      */
-
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE CoeffReturnType
-    operator[](Index index) const
-    {
-      EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
-                          THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
-      eigen_assert(index >= 0 && index < size());
-      return coeff(index);
-    }
-
-    /** \returns the coefficient at given index.
-      *
-      * This is synonymous to operator[](Index) const.
-      *
-      * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
-      *
-      * \sa operator[](Index), operator()(Index,Index) const, x() const, y() const,
-      * z() const, w() const
-      */
-
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE CoeffReturnType
-    operator()(Index index) const
-    {
-      eigen_assert(index >= 0 && index < size());
-      return coeff(index);
-    }
-
-    /** equivalent to operator[](0).  */
-
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE CoeffReturnType
-    x() const { return (*this)[0]; }
-
-    /** equivalent to operator[](1).  */
-
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE CoeffReturnType
-    y() const
-    {
-      EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime==-1 || Derived::SizeAtCompileTime>=2, OUT_OF_RANGE_ACCESS);
-      return (*this)[1];
-    }
-
-    /** equivalent to operator[](2).  */
-
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE CoeffReturnType
-    z() const
-    {
-      EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime==-1 || Derived::SizeAtCompileTime>=3, OUT_OF_RANGE_ACCESS);
-      return (*this)[2];
-    }
-
-    /** equivalent to operator[](3).  */
-
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE CoeffReturnType
-    w() const
-    {
-      EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime==-1 || Derived::SizeAtCompileTime>=4, OUT_OF_RANGE_ACCESS);
-      return (*this)[3];
-    }
-
-    /** \internal
-      * \returns the packet of coefficients starting at the given row and column. It is your responsibility
-      * to ensure that a packet really starts there. This method is only available on expressions having the
-      * PacketAccessBit.
-      *
-      * The \a LoadMode parameter may have the value \a #Aligned or \a #Unaligned. Its effect is to select
-      * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
-      * starting at an address which is a multiple of the packet size.
-      */
-
-    template<int LoadMode>
-    EIGEN_STRONG_INLINE PacketReturnType packet(Index row, Index col) const
-    {
-      typedef typename internal::packet_traits<Scalar>::type DefaultPacketType;
-      eigen_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
-      return internal::evaluator<Derived>(derived()).template packet<LoadMode,DefaultPacketType>(row,col);
-    }
-
-
-    /** \internal */
-    template<int LoadMode>
-    EIGEN_STRONG_INLINE PacketReturnType packetByOuterInner(Index outer, Index inner) const
-    {
-      return packet<LoadMode>(rowIndexByOuterInner(outer, inner),
-                              colIndexByOuterInner(outer, inner));
-    }
-
-    /** \internal
-      * \returns the packet of coefficients starting at the given index. It is your responsibility
-      * to ensure that a packet really starts there. This method is only available on expressions having the
-      * PacketAccessBit and the LinearAccessBit.
-      *
-      * The \a LoadMode parameter may have the value \a #Aligned or \a #Unaligned. Its effect is to select
-      * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
-      * starting at an address which is a multiple of the packet size.
-      */
-
-    template<int LoadMode>
-    EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const
-    {
-      EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit,
-                          THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS)
-      typedef typename internal::packet_traits<Scalar>::type DefaultPacketType;
-      eigen_internal_assert(index >= 0 && index < size());
-      return internal::evaluator<Derived>(derived()).template packet<LoadMode,DefaultPacketType>(index);
-    }
-
-  protected:
-    // explanation: DenseBase is doing "using ..." on the methods from DenseCoeffsBase.
-    // But some methods are only available in the DirectAccess case.
-    // So we add dummy methods here with these names, so that "using... " doesn't fail.
-    // It's not private so that the child class DenseBase can access them, and it's not public
-    // either since it's an implementation detail, so has to be protected.
-    void coeffRef();
-    void coeffRefByOuterInner();
-    void writePacket();
-    void writePacketByOuterInner();
-    void copyCoeff();
-    void copyCoeffByOuterInner();
-    void copyPacket();
-    void copyPacketByOuterInner();
-    void stride();
-    void innerStride();
-    void outerStride();
-    void rowStride();
-    void colStride();
-};
-
-/** \brief Base class providing read/write coefficient access to matrices and arrays.
-  * \ingroup Core_Module
-  * \tparam Derived Type of the derived class
-  * \tparam #WriteAccessors Constant indicating read/write access
-  *
-  * This class defines the non-const \c operator() function and friends, which can be used to write specific
-  * entries of a matrix or array. This class inherits DenseCoeffsBase<Derived, ReadOnlyAccessors> which
-  * defines the const variant for reading specific entries.
-  * 
-  * \sa DenseCoeffsBase<Derived, DirectAccessors>, \ref TopicClassHierarchy
-  */
-template<typename Derived>
-class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors>
-{
-  public:
-
-    typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base;
-
-    typedef typename internal::traits<Derived>::StorageKind StorageKind;
-    typedef typename internal::traits<Derived>::Scalar Scalar;
-    typedef typename internal::packet_traits<Scalar>::type PacketScalar;
-    typedef typename NumTraits<Scalar>::Real RealScalar;
-
-    using Base::coeff;
-    using Base::rows;
-    using Base::cols;
-    using Base::size;
-    using Base::derived;
-    using Base::rowIndexByOuterInner;
-    using Base::colIndexByOuterInner;
-    using Base::operator[];
-    using Base::operator();
-    using Base::x;
-    using Base::y;
-    using Base::z;
-    using Base::w;
-
-    /** Short version: don't use this function, use
-      * \link operator()(Index,Index) \endlink instead.
-      *
-      * Long version: this function is similar to
-      * \link operator()(Index,Index) \endlink, but without the assertion.
-      * Use this for limiting the performance cost of debugging code when doing
-      * repeated coefficient access. Only use this when it is guaranteed that the
-      * parameters \a row and \a col are in range.
-      *
-      * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this
-      * function equivalent to \link operator()(Index,Index) \endlink.
-      *
-      * \sa operator()(Index,Index), coeff(Index, Index) const, coeffRef(Index)
-      */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
-    {
-      eigen_internal_assert(row >= 0 && row < rows()
-                         && col >= 0 && col < cols());
-      return internal::evaluator<Derived>(derived()).coeffRef(row,col);
-    }
-
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Scalar&
-    coeffRefByOuterInner(Index outer, Index inner)
-    {
-      return coeffRef(rowIndexByOuterInner(outer, inner),
-                      colIndexByOuterInner(outer, inner));
-    }
-
-    /** \returns a reference to the coefficient at given the given row and column.
-      *
-      * \sa operator[](Index)
-      */
-
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Scalar&
-    operator()(Index row, Index col)
-    {
-      eigen_assert(row >= 0 && row < rows()
-          && col >= 0 && col < cols());
-      return coeffRef(row, col);
-    }
-
-
-    /** Short version: don't use this function, use
-      * \link operator[](Index) \endlink instead.
-      *
-      * Long version: this function is similar to
-      * \link operator[](Index) \endlink, but without the assertion.
-      * Use this for limiting the performance cost of debugging code when doing
-      * repeated coefficient access. Only use this when it is guaranteed that the
-      * parameters \a row and \a col are in range.
-      *
-      * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this
-      * function equivalent to \link operator[](Index) \endlink.
-      *
-      * \sa operator[](Index), coeff(Index) const, coeffRef(Index,Index)
-      */
-
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Scalar&
-    coeffRef(Index index)
-    {
-      EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit,
-                          THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS)
-      eigen_internal_assert(index >= 0 && index < size());
-      return internal::evaluator<Derived>(derived()).coeffRef(index);
-    }
-
-    /** \returns a reference to the coefficient at given index.
-      *
-      * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
-      *
-      * \sa operator[](Index) const, operator()(Index,Index), x(), y(), z(), w()
-      */
-
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Scalar&
-    operator[](Index index)
-    {
-      EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
-                          THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
-      eigen_assert(index >= 0 && index < size());
-      return coeffRef(index);
-    }
-
-    /** \returns a reference to the coefficient at given index.
-      *
-      * This is synonymous to operator[](Index).
-      *
-      * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
-      *
-      * \sa operator[](Index) const, operator()(Index,Index), x(), y(), z(), w()
-      */
-
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Scalar&
-    operator()(Index index)
-    {
-      eigen_assert(index >= 0 && index < size());
-      return coeffRef(index);
-    }
-
-    /** equivalent to operator[](0).  */
-
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Scalar&
-    x() { return (*this)[0]; }
-
-    /** equivalent to operator[](1).  */
-
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Scalar&
-    y()
-    {
-      EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime==-1 || Derived::SizeAtCompileTime>=2, OUT_OF_RANGE_ACCESS);
-      return (*this)[1];
-    }
-
-    /** equivalent to operator[](2).  */
-
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Scalar&
-    z()
-    {
-      EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime==-1 || Derived::SizeAtCompileTime>=3, OUT_OF_RANGE_ACCESS);
-      return (*this)[2];
-    }
-
-    /** equivalent to operator[](3).  */
-
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Scalar&
-    w()
-    {
-      EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime==-1 || Derived::SizeAtCompileTime>=4, OUT_OF_RANGE_ACCESS);
-      return (*this)[3];
-    }
-};
-
-/** \brief Base class providing direct read-only coefficient access to matrices and arrays.
-  * \ingroup Core_Module
-  * \tparam Derived Type of the derived class
-  * \tparam #DirectAccessors Constant indicating direct access
-  *
-  * This class defines functions to work with strides which can be used to access entries directly. This class
-  * inherits DenseCoeffsBase<Derived, ReadOnlyAccessors> which defines functions to access entries read-only using
-  * \c operator() .
-  *
-  * \sa \blank \ref TopicClassHierarchy
-  */
-template<typename Derived>
-class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors>
-{
-  public:
-
-    typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base;
-    typedef typename internal::traits<Derived>::Scalar Scalar;
-    typedef typename NumTraits<Scalar>::Real RealScalar;
-
-    using Base::rows;
-    using Base::cols;
-    using Base::size;
-    using Base::derived;
-
-    /** \returns the pointer increment between two consecutive elements within a slice in the inner direction.
-      *
-      * \sa outerStride(), rowStride(), colStride()
-      */
-    EIGEN_DEVICE_FUNC
-    inline Index innerStride() const
-    {
-      return derived().innerStride();
-    }
-
-    /** \returns the pointer increment between two consecutive inner slices (for example, between two consecutive columns
-      *          in a column-major matrix).
-      *
-      * \sa innerStride(), rowStride(), colStride()
-      */
-    EIGEN_DEVICE_FUNC
-    inline Index outerStride() const
-    {
-      return derived().outerStride();
-    }
-
-    // FIXME shall we remove it ?
-    inline Index stride() const
-    {
-      return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
-    }
-
-    /** \returns the pointer increment between two consecutive rows.
-      *
-      * \sa innerStride(), outerStride(), colStride()
-      */
-    EIGEN_DEVICE_FUNC
-    inline Index rowStride() const
-    {
-      return Derived::IsRowMajor ? outerStride() : innerStride();
-    }
-
-    /** \returns the pointer increment between two consecutive columns.
-      *
-      * \sa innerStride(), outerStride(), rowStride()
-      */
-    EIGEN_DEVICE_FUNC
-    inline Index colStride() const
-    {
-      return Derived::IsRowMajor ? innerStride() : outerStride();
-    }
-};
-
-/** \brief Base class providing direct read/write coefficient access to matrices and arrays.
-  * \ingroup Core_Module
-  * \tparam Derived Type of the derived class
-  * \tparam #DirectWriteAccessors Constant indicating direct access
-  *
-  * This class defines functions to work with strides which can be used to access entries directly. This class
-  * inherits DenseCoeffsBase<Derived, WriteAccessors> which defines functions to access entries read/write using
-  * \c operator().
-  *
-  * \sa \blank \ref TopicClassHierarchy
-  */
-template<typename Derived>
-class DenseCoeffsBase<Derived, DirectWriteAccessors>
-  : public DenseCoeffsBase<Derived, WriteAccessors>
-{
-  public:
-
-    typedef DenseCoeffsBase<Derived, WriteAccessors> Base;
-    typedef typename internal::traits<Derived>::Scalar Scalar;
-    typedef typename NumTraits<Scalar>::Real RealScalar;
-
-    using Base::rows;
-    using Base::cols;
-    using Base::size;
-    using Base::derived;
-
-    /** \returns the pointer increment between two consecutive elements within a slice in the inner direction.
-      *
-      * \sa outerStride(), rowStride(), colStride()
-      */
-    EIGEN_DEVICE_FUNC
-    inline Index innerStride() const
-    {
-      return derived().innerStride();
-    }
-
-    /** \returns the pointer increment between two consecutive inner slices (for example, between two consecutive columns
-      *          in a column-major matrix).
-      *
-      * \sa innerStride(), rowStride(), colStride()
-      */
-    EIGEN_DEVICE_FUNC
-    inline Index outerStride() const
-    {
-      return derived().outerStride();
-    }
-
-    // FIXME shall we remove it ?
-    inline Index stride() const
-    {
-      return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
-    }
-
-    /** \returns the pointer increment between two consecutive rows.
-      *
-      * \sa innerStride(), outerStride(), colStride()
-      */
-    EIGEN_DEVICE_FUNC
-    inline Index rowStride() const
-    {
-      return Derived::IsRowMajor ? outerStride() : innerStride();
-    }
-
-    /** \returns the pointer increment between two consecutive columns.
-      *
-      * \sa innerStride(), outerStride(), rowStride()
-      */
-    EIGEN_DEVICE_FUNC
-    inline Index colStride() const
-    {
-      return Derived::IsRowMajor ? innerStride() : outerStride();
-    }
-};
-
-namespace internal {
-
-template<int Alignment, typename Derived, bool JustReturnZero>
-struct first_aligned_impl
-{
-  static inline Index run(const Derived&)
-  { return 0; }
-};
-
-template<int Alignment, typename Derived>
-struct first_aligned_impl<Alignment, Derived, false>
-{
-  static inline Index run(const Derived& m)
-  {
-    return internal::first_aligned<Alignment>(m.data(), m.size());
-  }
-};
-
-/** \internal \returns the index of the first element of the array stored by \a m that is properly aligned with respect to \a Alignment for vectorization.
-  *
-  * \tparam Alignment requested alignment in Bytes.
-  *
-  * There is also the variant first_aligned(const Scalar*, Integer) defined in Memory.h. See it for more
-  * documentation.
-  */
-template<int Alignment, typename Derived>
-static inline Index first_aligned(const DenseBase<Derived>& m)
-{
-  enum { ReturnZero = (int(evaluator<Derived>::Alignment) >= Alignment) || !(Derived::Flags & DirectAccessBit) };
-  return first_aligned_impl<Alignment, Derived, ReturnZero>::run(m.derived());
-}
-
-template<typename Derived>
-static inline Index first_default_aligned(const DenseBase<Derived>& m)
-{
-  typedef typename Derived::Scalar Scalar;
-  typedef typename packet_traits<Scalar>::type DefaultPacketType;
-  return internal::first_aligned<int(unpacket_traits<DefaultPacketType>::alignment),Derived>(m);
-}
-
-template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
-struct inner_stride_at_compile_time
-{
-  enum { ret = traits<Derived>::InnerStrideAtCompileTime };
-};
-
-template<typename Derived>
-struct inner_stride_at_compile_time<Derived, false>
-{
-  enum { ret = 0 };
-};
-
-template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
-struct outer_stride_at_compile_time
-{
-  enum { ret = traits<Derived>::OuterStrideAtCompileTime };
-};
-
-template<typename Derived>
-struct outer_stride_at_compile_time<Derived, false>
-{
-  enum { ret = 0 };
-};
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_DENSECOEFFSBASE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/DenseStorage.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/DenseStorage.h
deleted file mode 100644
index 7958fee..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/DenseStorage.h
+++ /dev/null
@@ -1,570 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2010-2013 Hauke Heibel <hauke.heibel@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_MATRIXSTORAGE_H
-#define EIGEN_MATRIXSTORAGE_H
-
-#ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
-  #define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(X) X; EIGEN_DENSE_STORAGE_CTOR_PLUGIN;
-#else
-  #define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(X)
-#endif
-
-namespace Eigen {
-
-namespace internal {
-
-struct constructor_without_unaligned_array_assert {};
-
-template<typename T, int Size>
-EIGEN_DEVICE_FUNC
-void check_static_allocation_size()
-{
-  // if EIGEN_STACK_ALLOCATION_LIMIT is defined to 0, then no limit
-  #if EIGEN_STACK_ALLOCATION_LIMIT
-  EIGEN_STATIC_ASSERT(Size * sizeof(T) <= EIGEN_STACK_ALLOCATION_LIMIT, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG);
-  #endif
-}
-
-/** \internal
-  * Static array. If the MatrixOrArrayOptions require auto-alignment, the array will be automatically aligned:
-  * to 16 bytes boundary if the total size is a multiple of 16 bytes.
-  */
-template <typename T, int Size, int MatrixOrArrayOptions,
-          int Alignment = (MatrixOrArrayOptions&DontAlign) ? 0
-                        : compute_default_alignment<T,Size>::value >
-struct plain_array
-{
-  T array[Size];
-
-  EIGEN_DEVICE_FUNC
-  plain_array()
-  { 
-    check_static_allocation_size<T,Size>();
-  }
-
-  EIGEN_DEVICE_FUNC
-  plain_array(constructor_without_unaligned_array_assert)
-  { 
-    check_static_allocation_size<T,Size>();
-  }
-};
-
-#if defined(EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT)
-  #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask)
-#elif EIGEN_GNUC_AT_LEAST(4,7) 
-  // GCC 4.7 is too aggressive in its optimizations and remove the alignement test based on the fact the array is declared to be aligned.
-  // See this bug report: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53900
-  // Hiding the origin of the array pointer behind a function argument seems to do the trick even if the function is inlined:
-  template<typename PtrType>
-  EIGEN_ALWAYS_INLINE PtrType eigen_unaligned_array_assert_workaround_gcc47(PtrType array) { return array; }
-  #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \
-    eigen_assert((internal::UIntPtr(eigen_unaligned_array_assert_workaround_gcc47(array)) & (sizemask)) == 0 \
-              && "this assertion is explained here: " \
-              "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \
-              " **** READ THIS WEB PAGE !!! ****");
-#else
-  #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \
-    eigen_assert((internal::UIntPtr(array) & (sizemask)) == 0 \
-              && "this assertion is explained here: " \
-              "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \
-              " **** READ THIS WEB PAGE !!! ****");
-#endif
-
-template <typename T, int Size, int MatrixOrArrayOptions>
-struct plain_array<T, Size, MatrixOrArrayOptions, 8>
-{
-  EIGEN_ALIGN_TO_BOUNDARY(8) T array[Size];
-
-  EIGEN_DEVICE_FUNC
-  plain_array() 
-  {
-    EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(7);
-    check_static_allocation_size<T,Size>();
-  }
-
-  EIGEN_DEVICE_FUNC
-  plain_array(constructor_without_unaligned_array_assert) 
-  { 
-    check_static_allocation_size<T,Size>();
-  }
-};
-
-template <typename T, int Size, int MatrixOrArrayOptions>
-struct plain_array<T, Size, MatrixOrArrayOptions, 16>
-{
-  EIGEN_ALIGN_TO_BOUNDARY(16) T array[Size];
-
-  EIGEN_DEVICE_FUNC
-  plain_array() 
-  { 
-    EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(15);
-    check_static_allocation_size<T,Size>();
-  }
-
-  EIGEN_DEVICE_FUNC
-  plain_array(constructor_without_unaligned_array_assert) 
-  { 
-    check_static_allocation_size<T,Size>();
-  }
-};
-
-template <typename T, int Size, int MatrixOrArrayOptions>
-struct plain_array<T, Size, MatrixOrArrayOptions, 32>
-{
-  EIGEN_ALIGN_TO_BOUNDARY(32) T array[Size];
-
-  EIGEN_DEVICE_FUNC
-  plain_array() 
-  {
-    EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(31);
-    check_static_allocation_size<T,Size>();
-  }
-
-  EIGEN_DEVICE_FUNC
-  plain_array(constructor_without_unaligned_array_assert) 
-  { 
-    check_static_allocation_size<T,Size>();
-  }
-};
-
-template <typename T, int Size, int MatrixOrArrayOptions>
-struct plain_array<T, Size, MatrixOrArrayOptions, 64>
-{
-  EIGEN_ALIGN_TO_BOUNDARY(64) T array[Size];
-
-  EIGEN_DEVICE_FUNC
-  plain_array() 
-  { 
-    EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(63);
-    check_static_allocation_size<T,Size>();
-  }
-
-  EIGEN_DEVICE_FUNC
-  plain_array(constructor_without_unaligned_array_assert) 
-  { 
-    check_static_allocation_size<T,Size>();
-  }
-};
-
-template <typename T, int MatrixOrArrayOptions, int Alignment>
-struct plain_array<T, 0, MatrixOrArrayOptions, Alignment>
-{
-  T array[1];
-  EIGEN_DEVICE_FUNC plain_array() {}
-  EIGEN_DEVICE_FUNC plain_array(constructor_without_unaligned_array_assert) {}
-};
-
-} // end namespace internal
-
-/** \internal
-  *
-  * \class DenseStorage
-  * \ingroup Core_Module
-  *
-  * \brief Stores the data of a matrix
-  *
-  * This class stores the data of fixed-size, dynamic-size or mixed matrices
-  * in a way as compact as possible.
-  *
-  * \sa Matrix
-  */
-template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseStorage;
-
-// purely fixed-size matrix
-template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseStorage
-{
-    internal::plain_array<T,Size,_Options> m_data;
-  public:
-    EIGEN_DEVICE_FUNC DenseStorage() {
-      EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = Size)
-    }
-    EIGEN_DEVICE_FUNC
-    explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
-      : m_data(internal::constructor_without_unaligned_array_assert()) {}
-    EIGEN_DEVICE_FUNC 
-    DenseStorage(const DenseStorage& other) : m_data(other.m_data) {
-      EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = Size)
-    }
-    EIGEN_DEVICE_FUNC 
-    DenseStorage& operator=(const DenseStorage& other)
-    { 
-      if (this != &other) m_data = other.m_data;
-      return *this; 
-    }
-    EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols) {
-      EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
-      eigen_internal_assert(size==rows*cols && rows==_Rows && cols==_Cols);
-      EIGEN_UNUSED_VARIABLE(size);
-      EIGEN_UNUSED_VARIABLE(rows);
-      EIGEN_UNUSED_VARIABLE(cols);
-    }
-    EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { std::swap(m_data,other.m_data); }
-    EIGEN_DEVICE_FUNC static Index rows(void) {return _Rows;}
-    EIGEN_DEVICE_FUNC static Index cols(void) {return _Cols;}
-    EIGEN_DEVICE_FUNC void conservativeResize(Index,Index,Index) {}
-    EIGEN_DEVICE_FUNC void resize(Index,Index,Index) {}
-    EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
-    EIGEN_DEVICE_FUNC T *data() { return m_data.array; }
-};
-
-// null matrix
-template<typename T, int _Rows, int _Cols, int _Options> class DenseStorage<T, 0, _Rows, _Cols, _Options>
-{
-  public:
-    EIGEN_DEVICE_FUNC DenseStorage() {}
-    EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert) {}
-    EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage&) {}
-    EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage&) { return *this; }
-    EIGEN_DEVICE_FUNC DenseStorage(Index,Index,Index) {}
-    EIGEN_DEVICE_FUNC void swap(DenseStorage& ) {}
-    EIGEN_DEVICE_FUNC static Index rows(void) {return _Rows;}
-    EIGEN_DEVICE_FUNC static Index cols(void) {return _Cols;}
-    EIGEN_DEVICE_FUNC void conservativeResize(Index,Index,Index) {}
-    EIGEN_DEVICE_FUNC void resize(Index,Index,Index) {}
-    EIGEN_DEVICE_FUNC const T *data() const { return 0; }
-    EIGEN_DEVICE_FUNC T *data() { return 0; }
-};
-
-// more specializations for null matrices; these are necessary to resolve ambiguities
-template<typename T, int _Options> class DenseStorage<T, 0, Dynamic, Dynamic, _Options>
-: public DenseStorage<T, 0, 0, 0, _Options> { };
-
-template<typename T, int _Rows, int _Options> class DenseStorage<T, 0, _Rows, Dynamic, _Options>
-: public DenseStorage<T, 0, 0, 0, _Options> { };
-
-template<typename T, int _Cols, int _Options> class DenseStorage<T, 0, Dynamic, _Cols, _Options>
-: public DenseStorage<T, 0, 0, 0, _Options> { };
-
-// dynamic-size matrix with fixed-size storage
-template<typename T, int Size, int _Options> class DenseStorage<T, Size, Dynamic, Dynamic, _Options>
-{
-    internal::plain_array<T,Size,_Options> m_data;
-    Index m_rows;
-    Index m_cols;
-  public:
-    EIGEN_DEVICE_FUNC DenseStorage() : m_rows(0), m_cols(0) {}
-    EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
-      : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {}
-    EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_rows(other.m_rows), m_cols(other.m_cols) {}
-    EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other) 
-    { 
-      if (this != &other)
-      {
-        m_data = other.m_data;
-        m_rows = other.m_rows;
-        m_cols = other.m_cols;
-      }
-      return *this; 
-    }
-    EIGEN_DEVICE_FUNC DenseStorage(Index, Index rows, Index cols) : m_rows(rows), m_cols(cols) {}
-    EIGEN_DEVICE_FUNC void swap(DenseStorage& other)
-    { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
-    EIGEN_DEVICE_FUNC Index rows() const {return m_rows;}
-    EIGEN_DEVICE_FUNC Index cols() const {return m_cols;}
-    EIGEN_DEVICE_FUNC void conservativeResize(Index, Index rows, Index cols) { m_rows = rows; m_cols = cols; }
-    EIGEN_DEVICE_FUNC void resize(Index, Index rows, Index cols) { m_rows = rows; m_cols = cols; }
-    EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
-    EIGEN_DEVICE_FUNC T *data() { return m_data.array; }
-};
-
-// dynamic-size matrix with fixed-size storage and fixed width
-template<typename T, int Size, int _Cols, int _Options> class DenseStorage<T, Size, Dynamic, _Cols, _Options>
-{
-    internal::plain_array<T,Size,_Options> m_data;
-    Index m_rows;
-  public:
-    EIGEN_DEVICE_FUNC DenseStorage() : m_rows(0) {}
-    EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
-      : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {}
-    EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_rows(other.m_rows) {}
-    EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other) 
-    {
-      if (this != &other)
-      {
-        m_data = other.m_data;
-        m_rows = other.m_rows;
-      }
-      return *this; 
-    }
-    EIGEN_DEVICE_FUNC DenseStorage(Index, Index rows, Index) : m_rows(rows) {}
-    EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
-    EIGEN_DEVICE_FUNC Index rows(void) const {return m_rows;}
-    EIGEN_DEVICE_FUNC Index cols(void) const {return _Cols;}
-    EIGEN_DEVICE_FUNC void conservativeResize(Index, Index rows, Index) { m_rows = rows; }
-    EIGEN_DEVICE_FUNC void resize(Index, Index rows, Index) { m_rows = rows; }
-    EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
-    EIGEN_DEVICE_FUNC T *data() { return m_data.array; }
-};
-
-// dynamic-size matrix with fixed-size storage and fixed height
-template<typename T, int Size, int _Rows, int _Options> class DenseStorage<T, Size, _Rows, Dynamic, _Options>
-{
-    internal::plain_array<T,Size,_Options> m_data;
-    Index m_cols;
-  public:
-    EIGEN_DEVICE_FUNC DenseStorage() : m_cols(0) {}
-    EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
-      : m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {}
-    EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_cols(other.m_cols) {}
-    EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
-    {
-      if (this != &other)
-      {
-        m_data = other.m_data;
-        m_cols = other.m_cols;
-      }
-      return *this;
-    }
-    EIGEN_DEVICE_FUNC DenseStorage(Index, Index, Index cols) : m_cols(cols) {}
-    EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
-    EIGEN_DEVICE_FUNC Index rows(void) const {return _Rows;}
-    EIGEN_DEVICE_FUNC Index cols(void) const {return m_cols;}
-    void conservativeResize(Index, Index, Index cols) { m_cols = cols; }
-    void resize(Index, Index, Index cols) { m_cols = cols; }
-    EIGEN_DEVICE_FUNC const T *data() const { return m_data.array; }
-    EIGEN_DEVICE_FUNC T *data() { return m_data.array; }
-};
-
-// purely dynamic matrix.
-template<typename T, int _Options> class DenseStorage<T, Dynamic, Dynamic, Dynamic, _Options>
-{
-    T *m_data;
-    Index m_rows;
-    Index m_cols;
-  public:
-    EIGEN_DEVICE_FUNC DenseStorage() : m_data(0), m_rows(0), m_cols(0) {}
-    EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert)
-       : m_data(0), m_rows(0), m_cols(0) {}
-    EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols)
-      : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(rows), m_cols(cols)
-    {
-      EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
-      eigen_internal_assert(size==rows*cols && rows>=0 && cols >=0);
-    }
-    EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
-      : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(other.m_rows*other.m_cols))
-      , m_rows(other.m_rows)
-      , m_cols(other.m_cols)
-    {
-      EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = m_rows*m_cols)
-      internal::smart_copy(other.m_data, other.m_data+other.m_rows*other.m_cols, m_data);
-    }
-    EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
-    {
-      if (this != &other)
-      {
-        DenseStorage tmp(other);
-        this->swap(tmp);
-      }
-      return *this;
-    }
-#if EIGEN_HAS_RVALUE_REFERENCES
-    EIGEN_DEVICE_FUNC
-    DenseStorage(DenseStorage&& other) EIGEN_NOEXCEPT
-      : m_data(std::move(other.m_data))
-      , m_rows(std::move(other.m_rows))
-      , m_cols(std::move(other.m_cols))
-    {
-      other.m_data = nullptr;
-      other.m_rows = 0;
-      other.m_cols = 0;
-    }
-    EIGEN_DEVICE_FUNC
-    DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT
-    {
-      using std::swap;
-      swap(m_data, other.m_data);
-      swap(m_rows, other.m_rows);
-      swap(m_cols, other.m_cols);
-      return *this;
-    }
-#endif
-    EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols); }
-    EIGEN_DEVICE_FUNC void swap(DenseStorage& other)
-    { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
-    EIGEN_DEVICE_FUNC Index rows(void) const {return m_rows;}
-    EIGEN_DEVICE_FUNC Index cols(void) const {return m_cols;}
-    void conservativeResize(Index size, Index rows, Index cols)
-    {
-      m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*m_cols);
-      m_rows = rows;
-      m_cols = cols;
-    }
-    EIGEN_DEVICE_FUNC void resize(Index size, Index rows, Index cols)
-    {
-      if(size != m_rows*m_cols)
-      {
-        internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols);
-        if (size)
-          m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size);
-        else
-          m_data = 0;
-        EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
-      }
-      m_rows = rows;
-      m_cols = cols;
-    }
-    EIGEN_DEVICE_FUNC const T *data() const { return m_data; }
-    EIGEN_DEVICE_FUNC T *data() { return m_data; }
-};
-
-// matrix with dynamic width and fixed height (so that matrix has dynamic size).
-template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Rows, Dynamic, _Options>
-{
-    T *m_data;
-    Index m_cols;
-  public:
-    EIGEN_DEVICE_FUNC DenseStorage() : m_data(0), m_cols(0) {}
-    explicit DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {}
-    EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_cols(cols)
-    {
-      EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
-      eigen_internal_assert(size==rows*cols && rows==_Rows && cols >=0);
-      EIGEN_UNUSED_VARIABLE(rows);
-    }
-    EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
-      : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(_Rows*other.m_cols))
-      , m_cols(other.m_cols)
-    {
-      EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = m_cols*_Rows)
-      internal::smart_copy(other.m_data, other.m_data+_Rows*m_cols, m_data);
-    }
-    EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
-    {
-      if (this != &other)
-      {
-        DenseStorage tmp(other);
-        this->swap(tmp);
-      }
-      return *this;
-    }    
-#if EIGEN_HAS_RVALUE_REFERENCES
-    EIGEN_DEVICE_FUNC
-    DenseStorage(DenseStorage&& other) EIGEN_NOEXCEPT
-      : m_data(std::move(other.m_data))
-      , m_cols(std::move(other.m_cols))
-    {
-      other.m_data = nullptr;
-      other.m_cols = 0;
-    }
-    EIGEN_DEVICE_FUNC
-    DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT
-    {
-      using std::swap;
-      swap(m_data, other.m_data);
-      swap(m_cols, other.m_cols);
-      return *this;
-    }
-#endif
-    EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols); }
-    EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
-    EIGEN_DEVICE_FUNC static Index rows(void) {return _Rows;}
-    EIGEN_DEVICE_FUNC Index cols(void) const {return m_cols;}
-    EIGEN_DEVICE_FUNC void conservativeResize(Index size, Index, Index cols)
-    {
-      m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, _Rows*m_cols);
-      m_cols = cols;
-    }
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resize(Index size, Index, Index cols)
-    {
-      if(size != _Rows*m_cols)
-      {
-        internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols);
-        if (size)
-          m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size);
-        else
-          m_data = 0;
-        EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
-      }
-      m_cols = cols;
-    }
-    EIGEN_DEVICE_FUNC const T *data() const { return m_data; }
-    EIGEN_DEVICE_FUNC T *data() { return m_data; }
-};
-
-// matrix with dynamic height and fixed width (so that matrix has dynamic size).
-template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dynamic, _Cols, _Options>
-{
-    T *m_data;
-    Index m_rows;
-  public:
-    EIGEN_DEVICE_FUNC DenseStorage() : m_data(0), m_rows(0) {}
-    explicit DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {}
-    EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(rows)
-    {
-      EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
-      eigen_internal_assert(size==rows*cols && rows>=0 && cols == _Cols);
-      EIGEN_UNUSED_VARIABLE(cols);
-    }
-    EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
-      : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(other.m_rows*_Cols))
-      , m_rows(other.m_rows)
-    {
-      EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = m_rows*_Cols)
-      internal::smart_copy(other.m_data, other.m_data+other.m_rows*_Cols, m_data);
-    }
-    EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other)
-    {
-      if (this != &other)
-      {
-        DenseStorage tmp(other);
-        this->swap(tmp);
-      }
-      return *this;
-    }    
-#if EIGEN_HAS_RVALUE_REFERENCES
-    EIGEN_DEVICE_FUNC
-    DenseStorage(DenseStorage&& other) EIGEN_NOEXCEPT
-      : m_data(std::move(other.m_data))
-      , m_rows(std::move(other.m_rows))
-    {
-      other.m_data = nullptr;
-      other.m_rows = 0;
-    }
-    EIGEN_DEVICE_FUNC
-    DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT
-    {
-      using std::swap;
-      swap(m_data, other.m_data);
-      swap(m_rows, other.m_rows);
-      return *this;
-    }
-#endif
-    EIGEN_DEVICE_FUNC ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows); }
-    EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
-    EIGEN_DEVICE_FUNC Index rows(void) const {return m_rows;}
-    EIGEN_DEVICE_FUNC static Index cols(void) {return _Cols;}
-    void conservativeResize(Index size, Index rows, Index)
-    {
-      m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*_Cols);
-      m_rows = rows;
-    }
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resize(Index size, Index rows, Index)
-    {
-      if(size != m_rows*_Cols)
-      {
-        internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows);
-        if (size)
-          m_data = internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size);
-        else
-          m_data = 0;
-        EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
-      }
-      m_rows = rows;
-    }
-    EIGEN_DEVICE_FUNC const T *data() const { return m_data; }
-    EIGEN_DEVICE_FUNC T *data() { return m_data; }
-};
-
-} // end namespace Eigen
-
-#endif // EIGEN_MATRIX_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Diagonal.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Diagonal.h
deleted file mode 100644
index afcaf35..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Diagonal.h
+++ /dev/null
@@ -1,260 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_DIAGONAL_H
-#define EIGEN_DIAGONAL_H
-
-namespace Eigen { 
-
-/** \class Diagonal
-  * \ingroup Core_Module
-  *
-  * \brief Expression of a diagonal/subdiagonal/superdiagonal in a matrix
-  *
-  * \param MatrixType the type of the object in which we are taking a sub/main/super diagonal
-  * \param DiagIndex the index of the sub/super diagonal. The default is 0 and it means the main diagonal.
-  *              A positive value means a superdiagonal, a negative value means a subdiagonal.
-  *              You can also use DynamicIndex so the index can be set at runtime.
-  *
-  * The matrix is not required to be square.
-  *
-  * This class represents an expression of the main diagonal, or any sub/super diagonal
-  * of a square matrix. It is the return type of MatrixBase::diagonal() and MatrixBase::diagonal(Index) and most of the
-  * time this is the only way it is used.
-  *
-  * \sa MatrixBase::diagonal(), MatrixBase::diagonal(Index)
-  */
-
-namespace internal {
-template<typename MatrixType, int DiagIndex>
-struct traits<Diagonal<MatrixType,DiagIndex> >
- : traits<MatrixType>
-{
-  typedef typename ref_selector<MatrixType>::type MatrixTypeNested;
-  typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested;
-  typedef typename MatrixType::StorageKind StorageKind;
-  enum {
-    RowsAtCompileTime = (int(DiagIndex) == DynamicIndex || int(MatrixType::SizeAtCompileTime) == Dynamic) ? Dynamic
-                      : (EIGEN_PLAIN_ENUM_MIN(MatrixType::RowsAtCompileTime - EIGEN_PLAIN_ENUM_MAX(-DiagIndex, 0),
-                                              MatrixType::ColsAtCompileTime - EIGEN_PLAIN_ENUM_MAX( DiagIndex, 0))),
-    ColsAtCompileTime = 1,
-    MaxRowsAtCompileTime = int(MatrixType::MaxSizeAtCompileTime) == Dynamic ? Dynamic
-                         : DiagIndex == DynamicIndex ? EIGEN_SIZE_MIN_PREFER_FIXED(MatrixType::MaxRowsAtCompileTime,
-                                                                              MatrixType::MaxColsAtCompileTime)
-                         : (EIGEN_PLAIN_ENUM_MIN(MatrixType::MaxRowsAtCompileTime - EIGEN_PLAIN_ENUM_MAX(-DiagIndex, 0),
-                                                 MatrixType::MaxColsAtCompileTime - EIGEN_PLAIN_ENUM_MAX( DiagIndex, 0))),
-    MaxColsAtCompileTime = 1,
-    MaskLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
-    Flags = (unsigned int)_MatrixTypeNested::Flags & (RowMajorBit | MaskLvalueBit | DirectAccessBit) & ~RowMajorBit, // FIXME DirectAccessBit should not be handled by expressions
-    MatrixTypeOuterStride = outer_stride_at_compile_time<MatrixType>::ret,
-    InnerStrideAtCompileTime = MatrixTypeOuterStride == Dynamic ? Dynamic : MatrixTypeOuterStride+1,
-    OuterStrideAtCompileTime = 0
-  };
-};
-}
-
-template<typename MatrixType, int _DiagIndex> class Diagonal
-   : public internal::dense_xpr_base< Diagonal<MatrixType,_DiagIndex> >::type
-{
-  public:
-
-    enum { DiagIndex = _DiagIndex };
-    typedef typename internal::dense_xpr_base<Diagonal>::type Base;
-    EIGEN_DENSE_PUBLIC_INTERFACE(Diagonal)
-
-    EIGEN_DEVICE_FUNC
-    explicit inline Diagonal(MatrixType& matrix, Index a_index = DiagIndex) : m_matrix(matrix), m_index(a_index)
-    {
-      eigen_assert( a_index <= m_matrix.cols() && -a_index <= m_matrix.rows() );
-    }
-
-    EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Diagonal)
-
-    EIGEN_DEVICE_FUNC
-    inline Index rows() const
-    {
-      return m_index.value()<0 ? numext::mini<Index>(m_matrix.cols(),m_matrix.rows()+m_index.value())
-                               : numext::mini<Index>(m_matrix.rows(),m_matrix.cols()-m_index.value());
-    }
-
-    EIGEN_DEVICE_FUNC
-    inline Index cols() const { return 1; }
-
-    EIGEN_DEVICE_FUNC
-    inline Index innerStride() const
-    {
-      return m_matrix.outerStride() + 1;
-    }
-
-    EIGEN_DEVICE_FUNC
-    inline Index outerStride() const
-    {
-      return 0;
-    }
-
-    typedef typename internal::conditional<
-                       internal::is_lvalue<MatrixType>::value,
-                       Scalar,
-                       const Scalar
-                     >::type ScalarWithConstIfNotLvalue;
-
-    EIGEN_DEVICE_FUNC
-    inline ScalarWithConstIfNotLvalue* data() { return &(m_matrix.coeffRef(rowOffset(), colOffset())); }
-    EIGEN_DEVICE_FUNC
-    inline const Scalar* data() const { return &(m_matrix.coeffRef(rowOffset(), colOffset())); }
-
-    EIGEN_DEVICE_FUNC
-    inline Scalar& coeffRef(Index row, Index)
-    {
-      EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
-      return m_matrix.coeffRef(row+rowOffset(), row+colOffset());
-    }
-
-    EIGEN_DEVICE_FUNC
-    inline const Scalar& coeffRef(Index row, Index) const
-    {
-      return m_matrix.coeffRef(row+rowOffset(), row+colOffset());
-    }
-
-    EIGEN_DEVICE_FUNC
-    inline CoeffReturnType coeff(Index row, Index) const
-    {
-      return m_matrix.coeff(row+rowOffset(), row+colOffset());
-    }
-
-    EIGEN_DEVICE_FUNC
-    inline Scalar& coeffRef(Index idx)
-    {
-      EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
-      return m_matrix.coeffRef(idx+rowOffset(), idx+colOffset());
-    }
-
-    EIGEN_DEVICE_FUNC
-    inline const Scalar& coeffRef(Index idx) const
-    {
-      return m_matrix.coeffRef(idx+rowOffset(), idx+colOffset());
-    }
-
-    EIGEN_DEVICE_FUNC
-    inline CoeffReturnType coeff(Index idx) const
-    {
-      return m_matrix.coeff(idx+rowOffset(), idx+colOffset());
-    }
-
-    EIGEN_DEVICE_FUNC
-    inline const typename internal::remove_all<typename MatrixType::Nested>::type& 
-    nestedExpression() const 
-    {
-      return m_matrix;
-    }
-
-    EIGEN_DEVICE_FUNC
-    inline Index index() const
-    {
-      return m_index.value();
-    }
-
-  protected:
-    typename internal::ref_selector<MatrixType>::non_const_type m_matrix;
-    const internal::variable_if_dynamicindex<Index, DiagIndex> m_index;
-
-  private:
-    // some compilers may fail to optimize std::max etc in case of compile-time constants...
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Index absDiagIndex() const { return m_index.value()>0 ? m_index.value() : -m_index.value(); }
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Index rowOffset() const { return m_index.value()>0 ? 0 : -m_index.value(); }
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Index colOffset() const { return m_index.value()>0 ? m_index.value() : 0; }
-    // trigger a compile-time error if someone try to call packet
-    template<int LoadMode> typename MatrixType::PacketReturnType packet(Index) const;
-    template<int LoadMode> typename MatrixType::PacketReturnType packet(Index,Index) const;
-};
-
-/** \returns an expression of the main diagonal of the matrix \c *this
-  *
-  * \c *this is not required to be square.
-  *
-  * Example: \include MatrixBase_diagonal.cpp
-  * Output: \verbinclude MatrixBase_diagonal.out
-  *
-  * \sa class Diagonal */
-template<typename Derived>
-inline typename MatrixBase<Derived>::DiagonalReturnType
-MatrixBase<Derived>::diagonal()
-{
-  return DiagonalReturnType(derived());
-}
-
-/** This is the const version of diagonal(). */
-template<typename Derived>
-inline typename MatrixBase<Derived>::ConstDiagonalReturnType
-MatrixBase<Derived>::diagonal() const
-{
-  return ConstDiagonalReturnType(derived());
-}
-
-/** \returns an expression of the \a DiagIndex-th sub or super diagonal of the matrix \c *this
-  *
-  * \c *this is not required to be square.
-  *
-  * The template parameter \a DiagIndex represent a super diagonal if \a DiagIndex > 0
-  * and a sub diagonal otherwise. \a DiagIndex == 0 is equivalent to the main diagonal.
-  *
-  * Example: \include MatrixBase_diagonal_int.cpp
-  * Output: \verbinclude MatrixBase_diagonal_int.out
-  *
-  * \sa MatrixBase::diagonal(), class Diagonal */
-template<typename Derived>
-inline typename MatrixBase<Derived>::DiagonalDynamicIndexReturnType
-MatrixBase<Derived>::diagonal(Index index)
-{
-  return DiagonalDynamicIndexReturnType(derived(), index);
-}
-
-/** This is the const version of diagonal(Index). */
-template<typename Derived>
-inline typename MatrixBase<Derived>::ConstDiagonalDynamicIndexReturnType
-MatrixBase<Derived>::diagonal(Index index) const
-{
-  return ConstDiagonalDynamicIndexReturnType(derived(), index);
-}
-
-/** \returns an expression of the \a DiagIndex-th sub or super diagonal of the matrix \c *this
-  *
-  * \c *this is not required to be square.
-  *
-  * The template parameter \a DiagIndex represent a super diagonal if \a DiagIndex > 0
-  * and a sub diagonal otherwise. \a DiagIndex == 0 is equivalent to the main diagonal.
-  *
-  * Example: \include MatrixBase_diagonal_template_int.cpp
-  * Output: \verbinclude MatrixBase_diagonal_template_int.out
-  *
-  * \sa MatrixBase::diagonal(), class Diagonal */
-template<typename Derived>
-template<int Index_>
-inline typename MatrixBase<Derived>::template DiagonalIndexReturnType<Index_>::Type
-MatrixBase<Derived>::diagonal()
-{
-  return typename DiagonalIndexReturnType<Index_>::Type(derived());
-}
-
-/** This is the const version of diagonal<int>(). */
-template<typename Derived>
-template<int Index_>
-inline typename MatrixBase<Derived>::template ConstDiagonalIndexReturnType<Index_>::Type
-MatrixBase<Derived>::diagonal() const
-{
-  return typename ConstDiagonalIndexReturnType<Index_>::Type(derived());
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_DIAGONAL_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/DiagonalMatrix.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/DiagonalMatrix.h
deleted file mode 100644
index ecfdce8..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/DiagonalMatrix.h
+++ /dev/null
@@ -1,343 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_DIAGONALMATRIX_H
-#define EIGEN_DIAGONALMATRIX_H
-
-namespace Eigen { 
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-template<typename Derived>
-class DiagonalBase : public EigenBase<Derived>
-{
-  public:
-    typedef typename internal::traits<Derived>::DiagonalVectorType DiagonalVectorType;
-    typedef typename DiagonalVectorType::Scalar Scalar;
-    typedef typename DiagonalVectorType::RealScalar RealScalar;
-    typedef typename internal::traits<Derived>::StorageKind StorageKind;
-    typedef typename internal::traits<Derived>::StorageIndex StorageIndex;
-
-    enum {
-      RowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
-      ColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
-      MaxRowsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime,
-      MaxColsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime,
-      IsVectorAtCompileTime = 0,
-      Flags = NoPreferredStorageOrderBit
-    };
-
-    typedef Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime, 0, MaxRowsAtCompileTime, MaxColsAtCompileTime> DenseMatrixType;
-    typedef DenseMatrixType DenseType;
-    typedef DiagonalMatrix<Scalar,DiagonalVectorType::SizeAtCompileTime,DiagonalVectorType::MaxSizeAtCompileTime> PlainObject;
-
-    EIGEN_DEVICE_FUNC
-    inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
-    EIGEN_DEVICE_FUNC
-    inline Derived& derived() { return *static_cast<Derived*>(this); }
-
-    EIGEN_DEVICE_FUNC
-    DenseMatrixType toDenseMatrix() const { return derived(); }
-    
-    EIGEN_DEVICE_FUNC
-    inline const DiagonalVectorType& diagonal() const { return derived().diagonal(); }
-    EIGEN_DEVICE_FUNC
-    inline DiagonalVectorType& diagonal() { return derived().diagonal(); }
-
-    EIGEN_DEVICE_FUNC
-    inline Index rows() const { return diagonal().size(); }
-    EIGEN_DEVICE_FUNC
-    inline Index cols() const { return diagonal().size(); }
-
-    template<typename MatrixDerived>
-    EIGEN_DEVICE_FUNC
-    const Product<Derived,MatrixDerived,LazyProduct>
-    operator*(const MatrixBase<MatrixDerived> &matrix) const
-    {
-      return Product<Derived, MatrixDerived, LazyProduct>(derived(),matrix.derived());
-    }
-
-    typedef DiagonalWrapper<const CwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const DiagonalVectorType> > InverseReturnType;
-    EIGEN_DEVICE_FUNC
-    inline const InverseReturnType
-    inverse() const
-    {
-      return InverseReturnType(diagonal().cwiseInverse());
-    }
-    
-    EIGEN_DEVICE_FUNC
-    inline const DiagonalWrapper<const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DiagonalVectorType,Scalar,product) >
-    operator*(const Scalar& scalar) const
-    {
-      return DiagonalWrapper<const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DiagonalVectorType,Scalar,product) >(diagonal() * scalar);
-    }
-    EIGEN_DEVICE_FUNC
-    friend inline const DiagonalWrapper<const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar,DiagonalVectorType,product) >
-    operator*(const Scalar& scalar, const DiagonalBase& other)
-    {
-      return DiagonalWrapper<const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar,DiagonalVectorType,product) >(scalar * other.diagonal());
-    }
-};
-
-#endif
-
-/** \class DiagonalMatrix
-  * \ingroup Core_Module
-  *
-  * \brief Represents a diagonal matrix with its storage
-  *
-  * \param _Scalar the type of coefficients
-  * \param SizeAtCompileTime the dimension of the matrix, or Dynamic
-  * \param MaxSizeAtCompileTime the dimension of the matrix, or Dynamic. This parameter is optional and defaults
-  *        to SizeAtCompileTime. Most of the time, you do not need to specify it.
-  *
-  * \sa class DiagonalWrapper
-  */
-
-namespace internal {
-template<typename _Scalar, int SizeAtCompileTime, int MaxSizeAtCompileTime>
-struct traits<DiagonalMatrix<_Scalar,SizeAtCompileTime,MaxSizeAtCompileTime> >
- : traits<Matrix<_Scalar,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime> >
-{
-  typedef Matrix<_Scalar,SizeAtCompileTime,1,0,MaxSizeAtCompileTime,1> DiagonalVectorType;
-  typedef DiagonalShape StorageKind;
-  enum {
-    Flags = LvalueBit | NoPreferredStorageOrderBit
-  };
-};
-}
-template<typename _Scalar, int SizeAtCompileTime, int MaxSizeAtCompileTime>
-class DiagonalMatrix
-  : public DiagonalBase<DiagonalMatrix<_Scalar,SizeAtCompileTime,MaxSizeAtCompileTime> >
-{
-  public:
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    typedef typename internal::traits<DiagonalMatrix>::DiagonalVectorType DiagonalVectorType;
-    typedef const DiagonalMatrix& Nested;
-    typedef _Scalar Scalar;
-    typedef typename internal::traits<DiagonalMatrix>::StorageKind StorageKind;
-    typedef typename internal::traits<DiagonalMatrix>::StorageIndex StorageIndex;
-    #endif
-
-  protected:
-
-    DiagonalVectorType m_diagonal;
-
-  public:
-
-    /** const version of diagonal(). */
-    EIGEN_DEVICE_FUNC
-    inline const DiagonalVectorType& diagonal() const { return m_diagonal; }
-    /** \returns a reference to the stored vector of diagonal coefficients. */
-    EIGEN_DEVICE_FUNC
-    inline DiagonalVectorType& diagonal() { return m_diagonal; }
-
-    /** Default constructor without initialization */
-    EIGEN_DEVICE_FUNC
-    inline DiagonalMatrix() {}
-
-    /** Constructs a diagonal matrix with given dimension  */
-    EIGEN_DEVICE_FUNC
-    explicit inline DiagonalMatrix(Index dim) : m_diagonal(dim) {}
-
-    /** 2D constructor. */
-    EIGEN_DEVICE_FUNC
-    inline DiagonalMatrix(const Scalar& x, const Scalar& y) : m_diagonal(x,y) {}
-
-    /** 3D constructor. */
-    EIGEN_DEVICE_FUNC
-    inline DiagonalMatrix(const Scalar& x, const Scalar& y, const Scalar& z) : m_diagonal(x,y,z) {}
-
-    /** Copy constructor. */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    inline DiagonalMatrix(const DiagonalBase<OtherDerived>& other) : m_diagonal(other.diagonal()) {}
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    /** copy constructor. prevent a default copy constructor from hiding the other templated constructor */
-    inline DiagonalMatrix(const DiagonalMatrix& other) : m_diagonal(other.diagonal()) {}
-    #endif
-
-    /** generic constructor from expression of the diagonal coefficients */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    explicit inline DiagonalMatrix(const MatrixBase<OtherDerived>& other) : m_diagonal(other)
-    {}
-
-    /** Copy operator. */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    DiagonalMatrix& operator=(const DiagonalBase<OtherDerived>& other)
-    {
-      m_diagonal = other.diagonal();
-      return *this;
-    }
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    /** This is a special case of the templated operator=. Its purpose is to
-      * prevent a default operator= from hiding the templated operator=.
-      */
-    EIGEN_DEVICE_FUNC
-    DiagonalMatrix& operator=(const DiagonalMatrix& other)
-    {
-      m_diagonal = other.diagonal();
-      return *this;
-    }
-    #endif
-
-    /** Resizes to given size. */
-    EIGEN_DEVICE_FUNC
-    inline void resize(Index size) { m_diagonal.resize(size); }
-    /** Sets all coefficients to zero. */
-    EIGEN_DEVICE_FUNC
-    inline void setZero() { m_diagonal.setZero(); }
-    /** Resizes and sets all coefficients to zero. */
-    EIGEN_DEVICE_FUNC
-    inline void setZero(Index size) { m_diagonal.setZero(size); }
-    /** Sets this matrix to be the identity matrix of the current size. */
-    EIGEN_DEVICE_FUNC
-    inline void setIdentity() { m_diagonal.setOnes(); }
-    /** Sets this matrix to be the identity matrix of the given size. */
-    EIGEN_DEVICE_FUNC
-    inline void setIdentity(Index size) { m_diagonal.setOnes(size); }
-};
-
-/** \class DiagonalWrapper
-  * \ingroup Core_Module
-  *
-  * \brief Expression of a diagonal matrix
-  *
-  * \param _DiagonalVectorType the type of the vector of diagonal coefficients
-  *
-  * This class is an expression of a diagonal matrix, but not storing its own vector of diagonal coefficients,
-  * instead wrapping an existing vector expression. It is the return type of MatrixBase::asDiagonal()
-  * and most of the time this is the only way that it is used.
-  *
-  * \sa class DiagonalMatrix, class DiagonalBase, MatrixBase::asDiagonal()
-  */
-
-namespace internal {
-template<typename _DiagonalVectorType>
-struct traits<DiagonalWrapper<_DiagonalVectorType> >
-{
-  typedef _DiagonalVectorType DiagonalVectorType;
-  typedef typename DiagonalVectorType::Scalar Scalar;
-  typedef typename DiagonalVectorType::StorageIndex StorageIndex;
-  typedef DiagonalShape StorageKind;
-  typedef typename traits<DiagonalVectorType>::XprKind XprKind;
-  enum {
-    RowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
-    ColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
-    MaxRowsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime,
-    MaxColsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime,
-    Flags =  (traits<DiagonalVectorType>::Flags & LvalueBit) | NoPreferredStorageOrderBit
-  };
-};
-}
-
-template<typename _DiagonalVectorType>
-class DiagonalWrapper
-  : public DiagonalBase<DiagonalWrapper<_DiagonalVectorType> >, internal::no_assignment_operator
-{
-  public:
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    typedef _DiagonalVectorType DiagonalVectorType;
-    typedef DiagonalWrapper Nested;
-    #endif
-
-    /** Constructor from expression of diagonal coefficients to wrap. */
-    EIGEN_DEVICE_FUNC
-    explicit inline DiagonalWrapper(DiagonalVectorType& a_diagonal) : m_diagonal(a_diagonal) {}
-
-    /** \returns a const reference to the wrapped expression of diagonal coefficients. */
-    EIGEN_DEVICE_FUNC
-    const DiagonalVectorType& diagonal() const { return m_diagonal; }
-
-  protected:
-    typename DiagonalVectorType::Nested m_diagonal;
-};
-
-/** \returns a pseudo-expression of a diagonal matrix with *this as vector of diagonal coefficients
-  *
-  * \only_for_vectors
-  *
-  * Example: \include MatrixBase_asDiagonal.cpp
-  * Output: \verbinclude MatrixBase_asDiagonal.out
-  *
-  * \sa class DiagonalWrapper, class DiagonalMatrix, diagonal(), isDiagonal()
-  **/
-template<typename Derived>
-inline const DiagonalWrapper<const Derived>
-MatrixBase<Derived>::asDiagonal() const
-{
-  return DiagonalWrapper<const Derived>(derived());
-}
-
-/** \returns true if *this is approximately equal to a diagonal matrix,
-  *          within the precision given by \a prec.
-  *
-  * Example: \include MatrixBase_isDiagonal.cpp
-  * Output: \verbinclude MatrixBase_isDiagonal.out
-  *
-  * \sa asDiagonal()
-  */
-template<typename Derived>
-bool MatrixBase<Derived>::isDiagonal(const RealScalar& prec) const
-{
-  if(cols() != rows()) return false;
-  RealScalar maxAbsOnDiagonal = static_cast<RealScalar>(-1);
-  for(Index j = 0; j < cols(); ++j)
-  {
-    RealScalar absOnDiagonal = numext::abs(coeff(j,j));
-    if(absOnDiagonal > maxAbsOnDiagonal) maxAbsOnDiagonal = absOnDiagonal;
-  }
-  for(Index j = 0; j < cols(); ++j)
-    for(Index i = 0; i < j; ++i)
-    {
-      if(!internal::isMuchSmallerThan(coeff(i, j), maxAbsOnDiagonal, prec)) return false;
-      if(!internal::isMuchSmallerThan(coeff(j, i), maxAbsOnDiagonal, prec)) return false;
-    }
-  return true;
-}
-
-namespace internal {
-
-template<> struct storage_kind_to_shape<DiagonalShape> { typedef DiagonalShape Shape; };
-
-struct Diagonal2Dense {};
-
-template<> struct AssignmentKind<DenseShape,DiagonalShape> { typedef Diagonal2Dense Kind; };
-
-// Diagonal matrix to Dense assignment
-template< typename DstXprType, typename SrcXprType, typename Functor>
-struct Assignment<DstXprType, SrcXprType, Functor, Diagonal2Dense>
-{
-  static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar> &/*func*/)
-  {
-    Index dstRows = src.rows();
-    Index dstCols = src.cols();
-    if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
-      dst.resize(dstRows, dstCols);
-    
-    dst.setZero();
-    dst.diagonal() = src.diagonal();
-  }
-  
-  static void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar> &/*func*/)
-  { dst.diagonal() += src.diagonal(); }
-  
-  static void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar> &/*func*/)
-  { dst.diagonal() -= src.diagonal(); }
-};
-
-} // namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_DIAGONALMATRIX_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/DiagonalProduct.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/DiagonalProduct.h
deleted file mode 100644
index d372b93..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/DiagonalProduct.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_DIAGONALPRODUCT_H
-#define EIGEN_DIAGONALPRODUCT_H
-
-namespace Eigen { 
-
-/** \returns the diagonal matrix product of \c *this by the diagonal matrix \a diagonal.
-  */
-template<typename Derived>
-template<typename DiagonalDerived>
-inline const Product<Derived, DiagonalDerived, LazyProduct>
-MatrixBase<Derived>::operator*(const DiagonalBase<DiagonalDerived> &a_diagonal) const
-{
-  return Product<Derived, DiagonalDerived, LazyProduct>(derived(),a_diagonal.derived());
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_DIAGONALPRODUCT_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Dot.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Dot.h
deleted file mode 100644
index 1fe7a84..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Dot.h
+++ /dev/null
@@ -1,318 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2006-2008, 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_DOT_H
-#define EIGEN_DOT_H
-
-namespace Eigen { 
-
-namespace internal {
-
-// helper function for dot(). The problem is that if we put that in the body of dot(), then upon calling dot
-// with mismatched types, the compiler emits errors about failing to instantiate cwiseProduct BEFORE
-// looking at the static assertions. Thus this is a trick to get better compile errors.
-template<typename T, typename U,
-// the NeedToTranspose condition here is taken straight from Assign.h
-         bool NeedToTranspose = T::IsVectorAtCompileTime
-                && U::IsVectorAtCompileTime
-                && ((int(T::RowsAtCompileTime) == 1 && int(U::ColsAtCompileTime) == 1)
-                      |  // FIXME | instead of || to please GCC 4.4.0 stupid warning "suggest parentheses around &&".
-                         // revert to || as soon as not needed anymore.
-                    (int(T::ColsAtCompileTime) == 1 && int(U::RowsAtCompileTime) == 1))
->
-struct dot_nocheck
-{
-  typedef scalar_conj_product_op<typename traits<T>::Scalar,typename traits<U>::Scalar> conj_prod;
-  typedef typename conj_prod::result_type ResScalar;
-  EIGEN_DEVICE_FUNC
-  EIGEN_STRONG_INLINE
-  static ResScalar run(const MatrixBase<T>& a, const MatrixBase<U>& b)
-  {
-    return a.template binaryExpr<conj_prod>(b).sum();
-  }
-};
-
-template<typename T, typename U>
-struct dot_nocheck<T, U, true>
-{
-  typedef scalar_conj_product_op<typename traits<T>::Scalar,typename traits<U>::Scalar> conj_prod;
-  typedef typename conj_prod::result_type ResScalar;
-  EIGEN_DEVICE_FUNC
-  EIGEN_STRONG_INLINE
-  static ResScalar run(const MatrixBase<T>& a, const MatrixBase<U>& b)
-  {
-    return a.transpose().template binaryExpr<conj_prod>(b).sum();
-  }
-};
-
-} // end namespace internal
-
-/** \fn MatrixBase::dot
-  * \returns the dot product of *this with other.
-  *
-  * \only_for_vectors
-  *
-  * \note If the scalar type is complex numbers, then this function returns the hermitian
-  * (sesquilinear) dot product, conjugate-linear in the first variable and linear in the
-  * second variable.
-  *
-  * \sa squaredNorm(), norm()
-  */
-template<typename Derived>
-template<typename OtherDerived>
-EIGEN_DEVICE_FUNC
-EIGEN_STRONG_INLINE
-typename ScalarBinaryOpTraits<typename internal::traits<Derived>::Scalar,typename internal::traits<OtherDerived>::Scalar>::ReturnType
-MatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const
-{
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
-  EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived)
-#if !(defined(EIGEN_NO_STATIC_ASSERT) && defined(EIGEN_NO_DEBUG))
-  typedef internal::scalar_conj_product_op<Scalar,typename OtherDerived::Scalar> func;
-  EIGEN_CHECK_BINARY_COMPATIBILIY(func,Scalar,typename OtherDerived::Scalar);
-#endif
-  
-  eigen_assert(size() == other.size());
-
-  return internal::dot_nocheck<Derived,OtherDerived>::run(*this, other);
-}
-
-//---------- implementation of L2 norm and related functions ----------
-
-/** \returns, for vectors, the squared \em l2 norm of \c *this, and for matrices the Frobenius norm.
-  * In both cases, it consists in the sum of the square of all the matrix entries.
-  * For vectors, this is also equals to the dot product of \c *this with itself.
-  *
-  * \sa dot(), norm(), lpNorm()
-  */
-template<typename Derived>
-EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::squaredNorm() const
-{
-  return numext::real((*this).cwiseAbs2().sum());
-}
-
-/** \returns, for vectors, the \em l2 norm of \c *this, and for matrices the Frobenius norm.
-  * In both cases, it consists in the square root of the sum of the square of all the matrix entries.
-  * For vectors, this is also equals to the square root of the dot product of \c *this with itself.
-  *
-  * \sa lpNorm(), dot(), squaredNorm()
-  */
-template<typename Derived>
-EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::norm() const
-{
-  return numext::sqrt(squaredNorm());
-}
-
-/** \returns an expression of the quotient of \c *this by its own norm.
-  *
-  * \warning If the input vector is too small (i.e., this->norm()==0),
-  *          then this function returns a copy of the input.
-  *
-  * \only_for_vectors
-  *
-  * \sa norm(), normalize()
-  */
-template<typename Derived>
-EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::PlainObject
-MatrixBase<Derived>::normalized() const
-{
-  typedef typename internal::nested_eval<Derived,2>::type _Nested;
-  _Nested n(derived());
-  RealScalar z = n.squaredNorm();
-  // NOTE: after extensive benchmarking, this conditional does not impact performance, at least on recent x86 CPU
-  if(z>RealScalar(0))
-    return n / numext::sqrt(z);
-  else
-    return n;
-}
-
-/** Normalizes the vector, i.e. divides it by its own norm.
-  *
-  * \only_for_vectors
-  *
-  * \warning If the input vector is too small (i.e., this->norm()==0), then \c *this is left unchanged.
-  *
-  * \sa norm(), normalized()
-  */
-template<typename Derived>
-EIGEN_STRONG_INLINE void MatrixBase<Derived>::normalize()
-{
-  RealScalar z = squaredNorm();
-  // NOTE: after extensive benchmarking, this conditional does not impact performance, at least on recent x86 CPU
-  if(z>RealScalar(0))
-    derived() /= numext::sqrt(z);
-}
-
-/** \returns an expression of the quotient of \c *this by its own norm while avoiding underflow and overflow.
-  *
-  * \only_for_vectors
-  *
-  * This method is analogue to the normalized() method, but it reduces the risk of
-  * underflow and overflow when computing the norm.
-  *
-  * \warning If the input vector is too small (i.e., this->norm()==0),
-  *          then this function returns a copy of the input.
-  *
-  * \sa stableNorm(), stableNormalize(), normalized()
-  */
-template<typename Derived>
-EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::PlainObject
-MatrixBase<Derived>::stableNormalized() const
-{
-  typedef typename internal::nested_eval<Derived,3>::type _Nested;
-  _Nested n(derived());
-  RealScalar w = n.cwiseAbs().maxCoeff();
-  RealScalar z = (n/w).squaredNorm();
-  if(z>RealScalar(0))
-    return n / (numext::sqrt(z)*w);
-  else
-    return n;
-}
-
-/** Normalizes the vector while avoid underflow and overflow
-  *
-  * \only_for_vectors
-  *
-  * This method is analogue to the normalize() method, but it reduces the risk of
-  * underflow and overflow when computing the norm.
-  *
-  * \warning If the input vector is too small (i.e., this->norm()==0), then \c *this is left unchanged.
-  *
-  * \sa stableNorm(), stableNormalized(), normalize()
-  */
-template<typename Derived>
-EIGEN_STRONG_INLINE void MatrixBase<Derived>::stableNormalize()
-{
-  RealScalar w = cwiseAbs().maxCoeff();
-  RealScalar z = (derived()/w).squaredNorm();
-  if(z>RealScalar(0))
-    derived() /= numext::sqrt(z)*w;
-}
-
-//---------- implementation of other norms ----------
-
-namespace internal {
-
-template<typename Derived, int p>
-struct lpNorm_selector
-{
-  typedef typename NumTraits<typename traits<Derived>::Scalar>::Real RealScalar;
-  EIGEN_DEVICE_FUNC
-  static inline RealScalar run(const MatrixBase<Derived>& m)
-  {
-    EIGEN_USING_STD_MATH(pow)
-    return pow(m.cwiseAbs().array().pow(p).sum(), RealScalar(1)/p);
-  }
-};
-
-template<typename Derived>
-struct lpNorm_selector<Derived, 1>
-{
-  EIGEN_DEVICE_FUNC
-  static inline typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
-  {
-    return m.cwiseAbs().sum();
-  }
-};
-
-template<typename Derived>
-struct lpNorm_selector<Derived, 2>
-{
-  EIGEN_DEVICE_FUNC
-  static inline typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
-  {
-    return m.norm();
-  }
-};
-
-template<typename Derived>
-struct lpNorm_selector<Derived, Infinity>
-{
-  typedef typename NumTraits<typename traits<Derived>::Scalar>::Real RealScalar;
-  EIGEN_DEVICE_FUNC
-  static inline RealScalar run(const MatrixBase<Derived>& m)
-  {
-    if(Derived::SizeAtCompileTime==0 || (Derived::SizeAtCompileTime==Dynamic && m.size()==0))
-      return RealScalar(0);
-    return m.cwiseAbs().maxCoeff();
-  }
-};
-
-} // end namespace internal
-
-/** \returns the \b coefficient-wise \f$ \ell^p \f$ norm of \c *this, that is, returns the p-th root of the sum of the p-th powers of the absolute values
-  *          of the coefficients of \c *this. If \a p is the special value \a Eigen::Infinity, this function returns the \f$ \ell^\infty \f$
-  *          norm, that is the maximum of the absolute values of the coefficients of \c *this.
-  *
-  * In all cases, if \c *this is empty, then the value 0 is returned.
-  *
-  * \note For matrices, this function does not compute the <a href="https://en.wikipedia.org/wiki/Operator_norm">operator-norm</a>. That is, if \c *this is a matrix, then its coefficients are interpreted as a 1D vector. Nonetheless, you can easily compute the 1-norm and \f$\infty\f$-norm matrix operator norms using \link TutorialReductionsVisitorsBroadcastingReductionsNorm partial reductions \endlink.
-  *
-  * \sa norm()
-  */
-template<typename Derived>
-template<int p>
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
-#else
-MatrixBase<Derived>::RealScalar
-#endif
-MatrixBase<Derived>::lpNorm() const
-{
-  return internal::lpNorm_selector<Derived, p>::run(*this);
-}
-
-//---------- implementation of isOrthogonal / isUnitary ----------
-
-/** \returns true if *this is approximately orthogonal to \a other,
-  *          within the precision given by \a prec.
-  *
-  * Example: \include MatrixBase_isOrthogonal.cpp
-  * Output: \verbinclude MatrixBase_isOrthogonal.out
-  */
-template<typename Derived>
-template<typename OtherDerived>
-bool MatrixBase<Derived>::isOrthogonal
-(const MatrixBase<OtherDerived>& other, const RealScalar& prec) const
-{
-  typename internal::nested_eval<Derived,2>::type nested(derived());
-  typename internal::nested_eval<OtherDerived,2>::type otherNested(other.derived());
-  return numext::abs2(nested.dot(otherNested)) <= prec * prec * nested.squaredNorm() * otherNested.squaredNorm();
-}
-
-/** \returns true if *this is approximately an unitary matrix,
-  *          within the precision given by \a prec. In the case where the \a Scalar
-  *          type is real numbers, a unitary matrix is an orthogonal matrix, whence the name.
-  *
-  * \note This can be used to check whether a family of vectors forms an orthonormal basis.
-  *       Indeed, \c m.isUnitary() returns true if and only if the columns (equivalently, the rows) of m form an
-  *       orthonormal basis.
-  *
-  * Example: \include MatrixBase_isUnitary.cpp
-  * Output: \verbinclude MatrixBase_isUnitary.out
-  */
-template<typename Derived>
-bool MatrixBase<Derived>::isUnitary(const RealScalar& prec) const
-{
-  typename internal::nested_eval<Derived,1>::type self(derived());
-  for(Index i = 0; i < cols(); ++i)
-  {
-    if(!internal::isApprox(self.col(i).squaredNorm(), static_cast<RealScalar>(1), prec))
-      return false;
-    for(Index j = 0; j < i; ++j)
-      if(!internal::isMuchSmallerThan(self.col(i).dot(self.col(j)), static_cast<Scalar>(1), prec))
-        return false;
-  }
-  return true;
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_DOT_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/EigenBase.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/EigenBase.h
deleted file mode 100644
index b195506..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/EigenBase.h
+++ /dev/null
@@ -1,159 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_EIGENBASE_H
-#define EIGEN_EIGENBASE_H
-
-namespace Eigen {
-
-/** \class EigenBase
-  * \ingroup Core_Module
-  * 
-  * Common base class for all classes T such that MatrixBase has an operator=(T) and a constructor MatrixBase(T).
-  *
-  * In other words, an EigenBase object is an object that can be copied into a MatrixBase.
-  *
-  * Besides MatrixBase-derived classes, this also includes special matrix classes such as diagonal matrices, etc.
-  *
-  * Notice that this class is trivial, it is only used to disambiguate overloaded functions.
-  *
-  * \sa \blank \ref TopicClassHierarchy
-  */
-template<typename Derived> struct EigenBase
-{
-//   typedef typename internal::plain_matrix_type<Derived>::type PlainObject;
-  
-  /** \brief The interface type of indices
-    * \details To change this, \c \#define the preprocessor symbol \c EIGEN_DEFAULT_DENSE_INDEX_TYPE.
-    * \deprecated Since Eigen 3.3, its usage is deprecated. Use Eigen::Index instead.
-    * \sa StorageIndex, \ref TopicPreprocessorDirectives.
-    */
-  typedef Eigen::Index Index;
-
-  // FIXME is it needed?
-  typedef typename internal::traits<Derived>::StorageKind StorageKind;
-
-  /** \returns a reference to the derived object */
-  EIGEN_DEVICE_FUNC
-  Derived& derived() { return *static_cast<Derived*>(this); }
-  /** \returns a const reference to the derived object */
-  EIGEN_DEVICE_FUNC
-  const Derived& derived() const { return *static_cast<const Derived*>(this); }
-
-  EIGEN_DEVICE_FUNC
-  inline Derived& const_cast_derived() const
-  { return *static_cast<Derived*>(const_cast<EigenBase*>(this)); }
-  EIGEN_DEVICE_FUNC
-  inline const Derived& const_derived() const
-  { return *static_cast<const Derived*>(this); }
-
-  /** \returns the number of rows. \sa cols(), RowsAtCompileTime */
-  EIGEN_DEVICE_FUNC
-  inline Index rows() const { return derived().rows(); }
-  /** \returns the number of columns. \sa rows(), ColsAtCompileTime*/
-  EIGEN_DEVICE_FUNC
-  inline Index cols() const { return derived().cols(); }
-  /** \returns the number of coefficients, which is rows()*cols().
-    * \sa rows(), cols(), SizeAtCompileTime. */
-  EIGEN_DEVICE_FUNC
-  inline Index size() const { return rows() * cols(); }
-
-  /** \internal Don't use it, but do the equivalent: \code dst = *this; \endcode */
-  template<typename Dest>
-  EIGEN_DEVICE_FUNC
-  inline void evalTo(Dest& dst) const
-  { derived().evalTo(dst); }
-
-  /** \internal Don't use it, but do the equivalent: \code dst += *this; \endcode */
-  template<typename Dest>
-  EIGEN_DEVICE_FUNC
-  inline void addTo(Dest& dst) const
-  {
-    // This is the default implementation,
-    // derived class can reimplement it in a more optimized way.
-    typename Dest::PlainObject res(rows(),cols());
-    evalTo(res);
-    dst += res;
-  }
-
-  /** \internal Don't use it, but do the equivalent: \code dst -= *this; \endcode */
-  template<typename Dest>
-  EIGEN_DEVICE_FUNC
-  inline void subTo(Dest& dst) const
-  {
-    // This is the default implementation,
-    // derived class can reimplement it in a more optimized way.
-    typename Dest::PlainObject res(rows(),cols());
-    evalTo(res);
-    dst -= res;
-  }
-
-  /** \internal Don't use it, but do the equivalent: \code dst.applyOnTheRight(*this); \endcode */
-  template<typename Dest>
-  EIGEN_DEVICE_FUNC inline void applyThisOnTheRight(Dest& dst) const
-  {
-    // This is the default implementation,
-    // derived class can reimplement it in a more optimized way.
-    dst = dst * this->derived();
-  }
-
-  /** \internal Don't use it, but do the equivalent: \code dst.applyOnTheLeft(*this); \endcode */
-  template<typename Dest>
-  EIGEN_DEVICE_FUNC inline void applyThisOnTheLeft(Dest& dst) const
-  {
-    // This is the default implementation,
-    // derived class can reimplement it in a more optimized way.
-    dst = this->derived() * dst;
-  }
-
-};
-
-/***************************************************************************
-* Implementation of matrix base methods
-***************************************************************************/
-
-/** \brief Copies the generic expression \a other into *this.
-  *
-  * \details The expression must provide a (templated) evalTo(Derived& dst) const
-  * function which does the actual job. In practice, this allows any user to write
-  * its own special matrix without having to modify MatrixBase
-  *
-  * \returns a reference to *this.
-  */
-template<typename Derived>
-template<typename OtherDerived>
-EIGEN_DEVICE_FUNC
-Derived& DenseBase<Derived>::operator=(const EigenBase<OtherDerived> &other)
-{
-  call_assignment(derived(), other.derived());
-  return derived();
-}
-
-template<typename Derived>
-template<typename OtherDerived>
-EIGEN_DEVICE_FUNC
-Derived& DenseBase<Derived>::operator+=(const EigenBase<OtherDerived> &other)
-{
-  call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar,typename OtherDerived::Scalar>());
-  return derived();
-}
-
-template<typename Derived>
-template<typename OtherDerived>
-EIGEN_DEVICE_FUNC
-Derived& DenseBase<Derived>::operator-=(const EigenBase<OtherDerived> &other)
-{
-  call_assignment(derived(), other.derived(), internal::sub_assign_op<Scalar,typename OtherDerived::Scalar>());
-  return derived();
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_EIGENBASE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/ForceAlignedAccess.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/ForceAlignedAccess.h
deleted file mode 100644
index 7b08b45..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/ForceAlignedAccess.h
+++ /dev/null
@@ -1,146 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_FORCEALIGNEDACCESS_H
-#define EIGEN_FORCEALIGNEDACCESS_H
-
-namespace Eigen {
-
-/** \class ForceAlignedAccess
-  * \ingroup Core_Module
-  *
-  * \brief Enforce aligned packet loads and stores regardless of what is requested
-  *
-  * \param ExpressionType the type of the object of which we are forcing aligned packet access
-  *
-  * This class is the return type of MatrixBase::forceAlignedAccess()
-  * and most of the time this is the only way it is used.
-  *
-  * \sa MatrixBase::forceAlignedAccess()
-  */
-
-namespace internal {
-template<typename ExpressionType>
-struct traits<ForceAlignedAccess<ExpressionType> > : public traits<ExpressionType>
-{};
-}
-
-template<typename ExpressionType> class ForceAlignedAccess
-  : public internal::dense_xpr_base< ForceAlignedAccess<ExpressionType> >::type
-{
-  public:
-
-    typedef typename internal::dense_xpr_base<ForceAlignedAccess>::type Base;
-    EIGEN_DENSE_PUBLIC_INTERFACE(ForceAlignedAccess)
-
-    EIGEN_DEVICE_FUNC explicit inline ForceAlignedAccess(const ExpressionType& matrix) : m_expression(matrix) {}
-
-    EIGEN_DEVICE_FUNC inline Index rows() const { return m_expression.rows(); }
-    EIGEN_DEVICE_FUNC inline Index cols() const { return m_expression.cols(); }
-    EIGEN_DEVICE_FUNC inline Index outerStride() const { return m_expression.outerStride(); }
-    EIGEN_DEVICE_FUNC inline Index innerStride() const { return m_expression.innerStride(); }
-
-    EIGEN_DEVICE_FUNC inline const CoeffReturnType coeff(Index row, Index col) const
-    {
-      return m_expression.coeff(row, col);
-    }
-
-    EIGEN_DEVICE_FUNC inline Scalar& coeffRef(Index row, Index col)
-    {
-      return m_expression.const_cast_derived().coeffRef(row, col);
-    }
-
-    EIGEN_DEVICE_FUNC inline const CoeffReturnType coeff(Index index) const
-    {
-      return m_expression.coeff(index);
-    }
-
-    EIGEN_DEVICE_FUNC inline Scalar& coeffRef(Index index)
-    {
-      return m_expression.const_cast_derived().coeffRef(index);
-    }
-
-    template<int LoadMode>
-    inline const PacketScalar packet(Index row, Index col) const
-    {
-      return m_expression.template packet<Aligned>(row, col);
-    }
-
-    template<int LoadMode>
-    inline void writePacket(Index row, Index col, const PacketScalar& x)
-    {
-      m_expression.const_cast_derived().template writePacket<Aligned>(row, col, x);
-    }
-
-    template<int LoadMode>
-    inline const PacketScalar packet(Index index) const
-    {
-      return m_expression.template packet<Aligned>(index);
-    }
-
-    template<int LoadMode>
-    inline void writePacket(Index index, const PacketScalar& x)
-    {
-      m_expression.const_cast_derived().template writePacket<Aligned>(index, x);
-    }
-
-    EIGEN_DEVICE_FUNC operator const ExpressionType&() const { return m_expression; }
-
-  protected:
-    const ExpressionType& m_expression;
-
-  private:
-    ForceAlignedAccess& operator=(const ForceAlignedAccess&);
-};
-
-/** \returns an expression of *this with forced aligned access
-  * \sa forceAlignedAccessIf(),class ForceAlignedAccess
-  */
-template<typename Derived>
-inline const ForceAlignedAccess<Derived>
-MatrixBase<Derived>::forceAlignedAccess() const
-{
-  return ForceAlignedAccess<Derived>(derived());
-}
-
-/** \returns an expression of *this with forced aligned access
-  * \sa forceAlignedAccessIf(), class ForceAlignedAccess
-  */
-template<typename Derived>
-inline ForceAlignedAccess<Derived>
-MatrixBase<Derived>::forceAlignedAccess()
-{
-  return ForceAlignedAccess<Derived>(derived());
-}
-
-/** \returns an expression of *this with forced aligned access if \a Enable is true.
-  * \sa forceAlignedAccess(), class ForceAlignedAccess
-  */
-template<typename Derived>
-template<bool Enable>
-inline typename internal::add_const_on_value_type<typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type>::type
-MatrixBase<Derived>::forceAlignedAccessIf() const
-{
-  return derived();  // FIXME This should not work but apparently is never used
-}
-
-/** \returns an expression of *this with forced aligned access if \a Enable is true.
-  * \sa forceAlignedAccess(), class ForceAlignedAccess
-  */
-template<typename Derived>
-template<bool Enable>
-inline typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type
-MatrixBase<Derived>::forceAlignedAccessIf()
-{
-  return derived();  // FIXME This should not work but apparently is never used
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_FORCEALIGNEDACCESS_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Fuzzy.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Fuzzy.h
deleted file mode 100644
index 3e403a0..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Fuzzy.h
+++ /dev/null
@@ -1,155 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_FUZZY_H
-#define EIGEN_FUZZY_H
-
-namespace Eigen { 
-
-namespace internal
-{
-
-template<typename Derived, typename OtherDerived, bool is_integer = NumTraits<typename Derived::Scalar>::IsInteger>
-struct isApprox_selector
-{
-  EIGEN_DEVICE_FUNC
-  static bool run(const Derived& x, const OtherDerived& y, const typename Derived::RealScalar& prec)
-  {
-    typename internal::nested_eval<Derived,2>::type nested(x);
-    typename internal::nested_eval<OtherDerived,2>::type otherNested(y);
-    return (nested - otherNested).cwiseAbs2().sum() <= prec * prec * numext::mini(nested.cwiseAbs2().sum(), otherNested.cwiseAbs2().sum());
-  }
-};
-
-template<typename Derived, typename OtherDerived>
-struct isApprox_selector<Derived, OtherDerived, true>
-{
-  EIGEN_DEVICE_FUNC
-  static bool run(const Derived& x, const OtherDerived& y, const typename Derived::RealScalar&)
-  {
-    return x.matrix() == y.matrix();
-  }
-};
-
-template<typename Derived, typename OtherDerived, bool is_integer = NumTraits<typename Derived::Scalar>::IsInteger>
-struct isMuchSmallerThan_object_selector
-{
-  EIGEN_DEVICE_FUNC
-  static bool run(const Derived& x, const OtherDerived& y, const typename Derived::RealScalar& prec)
-  {
-    return x.cwiseAbs2().sum() <= numext::abs2(prec) * y.cwiseAbs2().sum();
-  }
-};
-
-template<typename Derived, typename OtherDerived>
-struct isMuchSmallerThan_object_selector<Derived, OtherDerived, true>
-{
-  EIGEN_DEVICE_FUNC
-  static bool run(const Derived& x, const OtherDerived&, const typename Derived::RealScalar&)
-  {
-    return x.matrix() == Derived::Zero(x.rows(), x.cols()).matrix();
-  }
-};
-
-template<typename Derived, bool is_integer = NumTraits<typename Derived::Scalar>::IsInteger>
-struct isMuchSmallerThan_scalar_selector
-{
-  EIGEN_DEVICE_FUNC
-  static bool run(const Derived& x, const typename Derived::RealScalar& y, const typename Derived::RealScalar& prec)
-  {
-    return x.cwiseAbs2().sum() <= numext::abs2(prec * y);
-  }
-};
-
-template<typename Derived>
-struct isMuchSmallerThan_scalar_selector<Derived, true>
-{
-  EIGEN_DEVICE_FUNC
-  static bool run(const Derived& x, const typename Derived::RealScalar&, const typename Derived::RealScalar&)
-  {
-    return x.matrix() == Derived::Zero(x.rows(), x.cols()).matrix();
-  }
-};
-
-} // end namespace internal
-
-
-/** \returns \c true if \c *this is approximately equal to \a other, within the precision
-  * determined by \a prec.
-  *
-  * \note The fuzzy compares are done multiplicatively. Two vectors \f$ v \f$ and \f$ w \f$
-  * are considered to be approximately equal within precision \f$ p \f$ if
-  * \f[ \Vert v - w \Vert \leqslant p\,\min(\Vert v\Vert, \Vert w\Vert). \f]
-  * For matrices, the comparison is done using the Hilbert-Schmidt norm (aka Frobenius norm
-  * L2 norm).
-  *
-  * \note Because of the multiplicativeness of this comparison, one can't use this function
-  * to check whether \c *this is approximately equal to the zero matrix or vector.
-  * Indeed, \c isApprox(zero) returns false unless \c *this itself is exactly the zero matrix
-  * or vector. If you want to test whether \c *this is zero, use internal::isMuchSmallerThan(const
-  * RealScalar&, RealScalar) instead.
-  *
-  * \sa internal::isMuchSmallerThan(const RealScalar&, RealScalar) const
-  */
-template<typename Derived>
-template<typename OtherDerived>
-bool DenseBase<Derived>::isApprox(
-  const DenseBase<OtherDerived>& other,
-  const RealScalar& prec
-) const
-{
-  return internal::isApprox_selector<Derived, OtherDerived>::run(derived(), other.derived(), prec);
-}
-
-/** \returns \c true if the norm of \c *this is much smaller than \a other,
-  * within the precision determined by \a prec.
-  *
-  * \note The fuzzy compares are done multiplicatively. A vector \f$ v \f$ is
-  * considered to be much smaller than \f$ x \f$ within precision \f$ p \f$ if
-  * \f[ \Vert v \Vert \leqslant p\,\vert x\vert. \f]
-  *
-  * For matrices, the comparison is done using the Hilbert-Schmidt norm. For this reason,
-  * the value of the reference scalar \a other should come from the Hilbert-Schmidt norm
-  * of a reference matrix of same dimensions.
-  *
-  * \sa isApprox(), isMuchSmallerThan(const DenseBase<OtherDerived>&, RealScalar) const
-  */
-template<typename Derived>
-bool DenseBase<Derived>::isMuchSmallerThan(
-  const typename NumTraits<Scalar>::Real& other,
-  const RealScalar& prec
-) const
-{
-  return internal::isMuchSmallerThan_scalar_selector<Derived>::run(derived(), other, prec);
-}
-
-/** \returns \c true if the norm of \c *this is much smaller than the norm of \a other,
-  * within the precision determined by \a prec.
-  *
-  * \note The fuzzy compares are done multiplicatively. A vector \f$ v \f$ is
-  * considered to be much smaller than a vector \f$ w \f$ within precision \f$ p \f$ if
-  * \f[ \Vert v \Vert \leqslant p\,\Vert w\Vert. \f]
-  * For matrices, the comparison is done using the Hilbert-Schmidt norm.
-  *
-  * \sa isApprox(), isMuchSmallerThan(const RealScalar&, RealScalar) const
-  */
-template<typename Derived>
-template<typename OtherDerived>
-bool DenseBase<Derived>::isMuchSmallerThan(
-  const DenseBase<OtherDerived>& other,
-  const RealScalar& prec
-) const
-{
-  return internal::isMuchSmallerThan_object_selector<Derived, OtherDerived>::run(derived(), other.derived(), prec);
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_FUZZY_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/GeneralProduct.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/GeneralProduct.h
deleted file mode 100644
index 6f0cc80..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/GeneralProduct.h
+++ /dev/null
@@ -1,455 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_GENERAL_PRODUCT_H
-#define EIGEN_GENERAL_PRODUCT_H
-
-namespace Eigen {
-
-enum {
-  Large = 2,
-  Small = 3
-};
-
-namespace internal {
-
-template<int Rows, int Cols, int Depth> struct product_type_selector;
-
-template<int Size, int MaxSize> struct product_size_category
-{
-  enum {
-    #ifndef EIGEN_CUDA_ARCH
-    is_large = MaxSize == Dynamic ||
-               Size >= EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD ||
-               (Size==Dynamic && MaxSize>=EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD),
-    #else
-    is_large = 0,
-    #endif
-    value = is_large  ? Large
-          : Size == 1 ? 1
-                      : Small
-  };
-};
-
-template<typename Lhs, typename Rhs> struct product_type
-{
-  typedef typename remove_all<Lhs>::type _Lhs;
-  typedef typename remove_all<Rhs>::type _Rhs;
-  enum {
-    MaxRows = traits<_Lhs>::MaxRowsAtCompileTime,
-    Rows    = traits<_Lhs>::RowsAtCompileTime,
-    MaxCols = traits<_Rhs>::MaxColsAtCompileTime,
-    Cols    = traits<_Rhs>::ColsAtCompileTime,
-    MaxDepth = EIGEN_SIZE_MIN_PREFER_FIXED(traits<_Lhs>::MaxColsAtCompileTime,
-                                           traits<_Rhs>::MaxRowsAtCompileTime),
-    Depth = EIGEN_SIZE_MIN_PREFER_FIXED(traits<_Lhs>::ColsAtCompileTime,
-                                        traits<_Rhs>::RowsAtCompileTime)
-  };
-
-  // the splitting into different lines of code here, introducing the _select enums and the typedef below,
-  // is to work around an internal compiler error with gcc 4.1 and 4.2.
-private:
-  enum {
-    rows_select = product_size_category<Rows,MaxRows>::value,
-    cols_select = product_size_category<Cols,MaxCols>::value,
-    depth_select = product_size_category<Depth,MaxDepth>::value
-  };
-  typedef product_type_selector<rows_select, cols_select, depth_select> selector;
-
-public:
-  enum {
-    value = selector::ret,
-    ret = selector::ret
-  };
-#ifdef EIGEN_DEBUG_PRODUCT
-  static void debug()
-  {
-      EIGEN_DEBUG_VAR(Rows);
-      EIGEN_DEBUG_VAR(Cols);
-      EIGEN_DEBUG_VAR(Depth);
-      EIGEN_DEBUG_VAR(rows_select);
-      EIGEN_DEBUG_VAR(cols_select);
-      EIGEN_DEBUG_VAR(depth_select);
-      EIGEN_DEBUG_VAR(value);
-  }
-#endif
-};
-
-/* The following allows to select the kind of product at compile time
- * based on the three dimensions of the product.
- * This is a compile time mapping from {1,Small,Large}^3 -> {product types} */
-// FIXME I'm not sure the current mapping is the ideal one.
-template<int M, int N>  struct product_type_selector<M,N,1>              { enum { ret = OuterProduct }; };
-template<int M>         struct product_type_selector<M, 1, 1>            { enum { ret = LazyCoeffBasedProductMode }; };
-template<int N>         struct product_type_selector<1, N, 1>            { enum { ret = LazyCoeffBasedProductMode }; };
-template<int Depth>     struct product_type_selector<1,    1,    Depth>  { enum { ret = InnerProduct }; };
-template<>              struct product_type_selector<1,    1,    1>      { enum { ret = InnerProduct }; };
-template<>              struct product_type_selector<Small,1,    Small>  { enum { ret = CoeffBasedProductMode }; };
-template<>              struct product_type_selector<1,    Small,Small>  { enum { ret = CoeffBasedProductMode }; };
-template<>              struct product_type_selector<Small,Small,Small>  { enum { ret = CoeffBasedProductMode }; };
-template<>              struct product_type_selector<Small, Small, 1>    { enum { ret = LazyCoeffBasedProductMode }; };
-template<>              struct product_type_selector<Small, Large, 1>    { enum { ret = LazyCoeffBasedProductMode }; };
-template<>              struct product_type_selector<Large, Small, 1>    { enum { ret = LazyCoeffBasedProductMode }; };
-template<>              struct product_type_selector<1,    Large,Small>  { enum { ret = CoeffBasedProductMode }; };
-template<>              struct product_type_selector<1,    Large,Large>  { enum { ret = GemvProduct }; };
-template<>              struct product_type_selector<1,    Small,Large>  { enum { ret = CoeffBasedProductMode }; };
-template<>              struct product_type_selector<Large,1,    Small>  { enum { ret = CoeffBasedProductMode }; };
-template<>              struct product_type_selector<Large,1,    Large>  { enum { ret = GemvProduct }; };
-template<>              struct product_type_selector<Small,1,    Large>  { enum { ret = CoeffBasedProductMode }; };
-template<>              struct product_type_selector<Small,Small,Large>  { enum { ret = GemmProduct }; };
-template<>              struct product_type_selector<Large,Small,Large>  { enum { ret = GemmProduct }; };
-template<>              struct product_type_selector<Small,Large,Large>  { enum { ret = GemmProduct }; };
-template<>              struct product_type_selector<Large,Large,Large>  { enum { ret = GemmProduct }; };
-template<>              struct product_type_selector<Large,Small,Small>  { enum { ret = CoeffBasedProductMode }; };
-template<>              struct product_type_selector<Small,Large,Small>  { enum { ret = CoeffBasedProductMode }; };
-template<>              struct product_type_selector<Large,Large,Small>  { enum { ret = GemmProduct }; };
-
-} // end namespace internal
-
-/***********************************************************************
-*  Implementation of Inner Vector Vector Product
-***********************************************************************/
-
-// FIXME : maybe the "inner product" could return a Scalar
-// instead of a 1x1 matrix ??
-// Pro: more natural for the user
-// Cons: this could be a problem if in a meta unrolled algorithm a matrix-matrix
-// product ends up to a row-vector times col-vector product... To tackle this use
-// case, we could have a specialization for Block<MatrixType,1,1> with: operator=(Scalar x);
-
-/***********************************************************************
-*  Implementation of Outer Vector Vector Product
-***********************************************************************/
-
-/***********************************************************************
-*  Implementation of General Matrix Vector Product
-***********************************************************************/
-
-/*  According to the shape/flags of the matrix we have to distinghish 3 different cases:
- *   1 - the matrix is col-major, BLAS compatible and M is large => call fast BLAS-like colmajor routine
- *   2 - the matrix is row-major, BLAS compatible and N is large => call fast BLAS-like rowmajor routine
- *   3 - all other cases are handled using a simple loop along the outer-storage direction.
- *  Therefore we need a lower level meta selector.
- *  Furthermore, if the matrix is the rhs, then the product has to be transposed.
- */
-namespace internal {
-
-template<int Side, int StorageOrder, bool BlasCompatible>
-struct gemv_dense_selector;
-
-} // end namespace internal
-
-namespace internal {
-
-template<typename Scalar,int Size,int MaxSize,bool Cond> struct gemv_static_vector_if;
-
-template<typename Scalar,int Size,int MaxSize>
-struct gemv_static_vector_if<Scalar,Size,MaxSize,false>
-{
-  EIGEN_STRONG_INLINE  Scalar* data() { eigen_internal_assert(false && "should never be called"); return 0; }
-};
-
-template<typename Scalar,int Size>
-struct gemv_static_vector_if<Scalar,Size,Dynamic,true>
-{
-  EIGEN_STRONG_INLINE Scalar* data() { return 0; }
-};
-
-template<typename Scalar,int Size,int MaxSize>
-struct gemv_static_vector_if<Scalar,Size,MaxSize,true>
-{
-  enum {
-    ForceAlignment  = internal::packet_traits<Scalar>::Vectorizable,
-    PacketSize      = internal::packet_traits<Scalar>::size
-  };
-  #if EIGEN_MAX_STATIC_ALIGN_BYTES!=0
-  internal::plain_array<Scalar,EIGEN_SIZE_MIN_PREFER_FIXED(Size,MaxSize),0,EIGEN_PLAIN_ENUM_MIN(AlignedMax,PacketSize)> m_data;
-  EIGEN_STRONG_INLINE Scalar* data() { return m_data.array; }
-  #else
-  // Some architectures cannot align on the stack,
-  // => let's manually enforce alignment by allocating more data and return the address of the first aligned element.
-  internal::plain_array<Scalar,EIGEN_SIZE_MIN_PREFER_FIXED(Size,MaxSize)+(ForceAlignment?EIGEN_MAX_ALIGN_BYTES:0),0> m_data;
-  EIGEN_STRONG_INLINE Scalar* data() {
-    return ForceAlignment
-            ? reinterpret_cast<Scalar*>((internal::UIntPtr(m_data.array) & ~(std::size_t(EIGEN_MAX_ALIGN_BYTES-1))) + EIGEN_MAX_ALIGN_BYTES)
-            : m_data.array;
-  }
-  #endif
-};
-
-// The vector is on the left => transposition
-template<int StorageOrder, bool BlasCompatible>
-struct gemv_dense_selector<OnTheLeft,StorageOrder,BlasCompatible>
-{
-  template<typename Lhs, typename Rhs, typename Dest>
-  static void run(const Lhs &lhs, const Rhs &rhs, Dest& dest, const typename Dest::Scalar& alpha)
-  {
-    Transpose<Dest> destT(dest);
-    enum { OtherStorageOrder = StorageOrder == RowMajor ? ColMajor : RowMajor };
-    gemv_dense_selector<OnTheRight,OtherStorageOrder,BlasCompatible>
-      ::run(rhs.transpose(), lhs.transpose(), destT, alpha);
-  }
-};
-
-template<> struct gemv_dense_selector<OnTheRight,ColMajor,true>
-{
-  template<typename Lhs, typename Rhs, typename Dest>
-  static inline void run(const Lhs &lhs, const Rhs &rhs, Dest& dest, const typename Dest::Scalar& alpha)
-  {
-    typedef typename Lhs::Scalar   LhsScalar;
-    typedef typename Rhs::Scalar   RhsScalar;
-    typedef typename Dest::Scalar  ResScalar;
-    typedef typename Dest::RealScalar  RealScalar;
-    
-    typedef internal::blas_traits<Lhs> LhsBlasTraits;
-    typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType;
-    typedef internal::blas_traits<Rhs> RhsBlasTraits;
-    typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType;
-  
-    typedef Map<Matrix<ResScalar,Dynamic,1>, EIGEN_PLAIN_ENUM_MIN(AlignedMax,internal::packet_traits<ResScalar>::size)> MappedDest;
-
-    ActualLhsType actualLhs = LhsBlasTraits::extract(lhs);
-    ActualRhsType actualRhs = RhsBlasTraits::extract(rhs);
-
-    ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(lhs)
-                                  * RhsBlasTraits::extractScalarFactor(rhs);
-
-    // make sure Dest is a compile-time vector type (bug 1166)
-    typedef typename conditional<Dest::IsVectorAtCompileTime, Dest, typename Dest::ColXpr>::type ActualDest;
-
-    enum {
-      // FIXME find a way to allow an inner stride on the result if packet_traits<Scalar>::size==1
-      // on, the other hand it is good for the cache to pack the vector anyways...
-      EvalToDestAtCompileTime = (ActualDest::InnerStrideAtCompileTime==1),
-      ComplexByReal = (NumTraits<LhsScalar>::IsComplex) && (!NumTraits<RhsScalar>::IsComplex),
-      MightCannotUseDest = (!EvalToDestAtCompileTime) || ComplexByReal
-    };
-
-    typedef const_blas_data_mapper<LhsScalar,Index,ColMajor> LhsMapper;
-    typedef const_blas_data_mapper<RhsScalar,Index,RowMajor> RhsMapper;
-    RhsScalar compatibleAlpha = get_factor<ResScalar,RhsScalar>::run(actualAlpha);
-
-    if(!MightCannotUseDest)
-    {
-      // shortcut if we are sure to be able to use dest directly,
-      // this ease the compiler to generate cleaner and more optimzized code for most common cases
-      general_matrix_vector_product
-          <Index,LhsScalar,LhsMapper,ColMajor,LhsBlasTraits::NeedToConjugate,RhsScalar,RhsMapper,RhsBlasTraits::NeedToConjugate>::run(
-          actualLhs.rows(), actualLhs.cols(),
-          LhsMapper(actualLhs.data(), actualLhs.outerStride()),
-          RhsMapper(actualRhs.data(), actualRhs.innerStride()),
-          dest.data(), 1,
-          compatibleAlpha);
-    }
-    else
-    {
-      gemv_static_vector_if<ResScalar,ActualDest::SizeAtCompileTime,ActualDest::MaxSizeAtCompileTime,MightCannotUseDest> static_dest;
-
-      const bool alphaIsCompatible = (!ComplexByReal) || (numext::imag(actualAlpha)==RealScalar(0));
-      const bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible;
-
-      ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(),
-                                                    evalToDest ? dest.data() : static_dest.data());
-
-      if(!evalToDest)
-      {
-        #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
-        Index size = dest.size();
-        EIGEN_DENSE_STORAGE_CTOR_PLUGIN
-        #endif
-        if(!alphaIsCompatible)
-        {
-          MappedDest(actualDestPtr, dest.size()).setZero();
-          compatibleAlpha = RhsScalar(1);
-        }
-        else
-          MappedDest(actualDestPtr, dest.size()) = dest;
-      }
-
-      general_matrix_vector_product
-          <Index,LhsScalar,LhsMapper,ColMajor,LhsBlasTraits::NeedToConjugate,RhsScalar,RhsMapper,RhsBlasTraits::NeedToConjugate>::run(
-          actualLhs.rows(), actualLhs.cols(),
-          LhsMapper(actualLhs.data(), actualLhs.outerStride()),
-          RhsMapper(actualRhs.data(), actualRhs.innerStride()),
-          actualDestPtr, 1,
-          compatibleAlpha);
-
-      if (!evalToDest)
-      {
-        if(!alphaIsCompatible)
-          dest.matrix() += actualAlpha * MappedDest(actualDestPtr, dest.size());
-        else
-          dest = MappedDest(actualDestPtr, dest.size());
-      }
-    }
-  }
-};
-
-template<> struct gemv_dense_selector<OnTheRight,RowMajor,true>
-{
-  template<typename Lhs, typename Rhs, typename Dest>
-  static void run(const Lhs &lhs, const Rhs &rhs, Dest& dest, const typename Dest::Scalar& alpha)
-  {
-    typedef typename Lhs::Scalar   LhsScalar;
-    typedef typename Rhs::Scalar   RhsScalar;
-    typedef typename Dest::Scalar  ResScalar;
-    
-    typedef internal::blas_traits<Lhs> LhsBlasTraits;
-    typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType;
-    typedef internal::blas_traits<Rhs> RhsBlasTraits;
-    typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType;
-    typedef typename internal::remove_all<ActualRhsType>::type ActualRhsTypeCleaned;
-
-    typename add_const<ActualLhsType>::type actualLhs = LhsBlasTraits::extract(lhs);
-    typename add_const<ActualRhsType>::type actualRhs = RhsBlasTraits::extract(rhs);
-
-    ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(lhs)
-                                  * RhsBlasTraits::extractScalarFactor(rhs);
-
-    enum {
-      // FIXME find a way to allow an inner stride on the result if packet_traits<Scalar>::size==1
-      // on, the other hand it is good for the cache to pack the vector anyways...
-      DirectlyUseRhs = ActualRhsTypeCleaned::InnerStrideAtCompileTime==1
-    };
-
-    gemv_static_vector_if<RhsScalar,ActualRhsTypeCleaned::SizeAtCompileTime,ActualRhsTypeCleaned::MaxSizeAtCompileTime,!DirectlyUseRhs> static_rhs;
-
-    ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhsPtr,actualRhs.size(),
-        DirectlyUseRhs ? const_cast<RhsScalar*>(actualRhs.data()) : static_rhs.data());
-
-    if(!DirectlyUseRhs)
-    {
-      #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
-      Index size = actualRhs.size();
-      EIGEN_DENSE_STORAGE_CTOR_PLUGIN
-      #endif
-      Map<typename ActualRhsTypeCleaned::PlainObject>(actualRhsPtr, actualRhs.size()) = actualRhs;
-    }
-
-    typedef const_blas_data_mapper<LhsScalar,Index,RowMajor> LhsMapper;
-    typedef const_blas_data_mapper<RhsScalar,Index,ColMajor> RhsMapper;
-    general_matrix_vector_product
-        <Index,LhsScalar,LhsMapper,RowMajor,LhsBlasTraits::NeedToConjugate,RhsScalar,RhsMapper,RhsBlasTraits::NeedToConjugate>::run(
-        actualLhs.rows(), actualLhs.cols(),
-        LhsMapper(actualLhs.data(), actualLhs.outerStride()),
-        RhsMapper(actualRhsPtr, 1),
-        dest.data(), dest.col(0).innerStride(), //NOTE  if dest is not a vector at compile-time, then dest.innerStride() might be wrong. (bug 1166)
-        actualAlpha);
-  }
-};
-
-template<> struct gemv_dense_selector<OnTheRight,ColMajor,false>
-{
-  template<typename Lhs, typename Rhs, typename Dest>
-  static void run(const Lhs &lhs, const Rhs &rhs, Dest& dest, const typename Dest::Scalar& alpha)
-  {
-    EIGEN_STATIC_ASSERT((!nested_eval<Lhs,1>::Evaluate),EIGEN_INTERNAL_COMPILATION_ERROR_OR_YOU_MADE_A_PROGRAMMING_MISTAKE);
-    // TODO if rhs is large enough it might be beneficial to make sure that dest is sequentially stored in memory, otherwise use a temp
-    typename nested_eval<Rhs,1>::type actual_rhs(rhs);
-    const Index size = rhs.rows();
-    for(Index k=0; k<size; ++k)
-      dest += (alpha*actual_rhs.coeff(k)) * lhs.col(k);
-  }
-};
-
-template<> struct gemv_dense_selector<OnTheRight,RowMajor,false>
-{
-  template<typename Lhs, typename Rhs, typename Dest>
-  static void run(const Lhs &lhs, const Rhs &rhs, Dest& dest, const typename Dest::Scalar& alpha)
-  {
-    EIGEN_STATIC_ASSERT((!nested_eval<Lhs,1>::Evaluate),EIGEN_INTERNAL_COMPILATION_ERROR_OR_YOU_MADE_A_PROGRAMMING_MISTAKE);
-    typename nested_eval<Rhs,Lhs::RowsAtCompileTime>::type actual_rhs(rhs);
-    const Index rows = dest.rows();
-    for(Index i=0; i<rows; ++i)
-      dest.coeffRef(i) += alpha * (lhs.row(i).cwiseProduct(actual_rhs.transpose())).sum();
-  }
-};
-
-} // end namespace internal
-
-/***************************************************************************
-* Implementation of matrix base methods
-***************************************************************************/
-
-/** \returns the matrix product of \c *this and \a other.
-  *
-  * \note If instead of the matrix product you want the coefficient-wise product, see Cwise::operator*().
-  *
-  * \sa lazyProduct(), operator*=(const MatrixBase&), Cwise::operator*()
-  */
-template<typename Derived>
-template<typename OtherDerived>
-inline const Product<Derived, OtherDerived>
-MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
-{
-  // A note regarding the function declaration: In MSVC, this function will sometimes
-  // not be inlined since DenseStorage is an unwindable object for dynamic
-  // matrices and product types are holding a member to store the result.
-  // Thus it does not help tagging this function with EIGEN_STRONG_INLINE.
-  enum {
-    ProductIsValid =  Derived::ColsAtCompileTime==Dynamic
-                   || OtherDerived::RowsAtCompileTime==Dynamic
-                   || int(Derived::ColsAtCompileTime)==int(OtherDerived::RowsAtCompileTime),
-    AreVectors = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime,
-    SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(Derived,OtherDerived)
-  };
-  // note to the lost user:
-  //    * for a dot product use: v1.dot(v2)
-  //    * for a coeff-wise product use: v1.cwiseProduct(v2)
-  EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes),
-    INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS)
-  EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors),
-    INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION)
-  EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT)
-#ifdef EIGEN_DEBUG_PRODUCT
-  internal::product_type<Derived,OtherDerived>::debug();
-#endif
-
-  return Product<Derived, OtherDerived>(derived(), other.derived());
-}
-
-/** \returns an expression of the matrix product of \c *this and \a other without implicit evaluation.
-  *
-  * The returned product will behave like any other expressions: the coefficients of the product will be
-  * computed once at a time as requested. This might be useful in some extremely rare cases when only
-  * a small and no coherent fraction of the result's coefficients have to be computed.
-  *
-  * \warning This version of the matrix product can be much much slower. So use it only if you know
-  * what you are doing and that you measured a true speed improvement.
-  *
-  * \sa operator*(const MatrixBase&)
-  */
-template<typename Derived>
-template<typename OtherDerived>
-const Product<Derived,OtherDerived,LazyProduct>
-MatrixBase<Derived>::lazyProduct(const MatrixBase<OtherDerived> &other) const
-{
-  enum {
-    ProductIsValid =  Derived::ColsAtCompileTime==Dynamic
-                   || OtherDerived::RowsAtCompileTime==Dynamic
-                   || int(Derived::ColsAtCompileTime)==int(OtherDerived::RowsAtCompileTime),
-    AreVectors = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime,
-    SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(Derived,OtherDerived)
-  };
-  // note to the lost user:
-  //    * for a dot product use: v1.dot(v2)
-  //    * for a coeff-wise product use: v1.cwiseProduct(v2)
-  EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes),
-    INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS)
-  EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors),
-    INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION)
-  EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT)
-
-  return Product<Derived,OtherDerived,LazyProduct>(derived(), other.derived());
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_PRODUCT_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/GenericPacketMath.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/GenericPacketMath.h
deleted file mode 100644
index 029f8ac..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/GenericPacketMath.h
+++ /dev/null
@@ -1,593 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_GENERIC_PACKET_MATH_H
-#define EIGEN_GENERIC_PACKET_MATH_H
-
-namespace Eigen {
-
-namespace internal {
-
-/** \internal
-  * \file GenericPacketMath.h
-  *
-  * Default implementation for types not supported by the vectorization.
-  * In practice these functions are provided to make easier the writing
-  * of generic vectorized code.
-  */
-
-#ifndef EIGEN_DEBUG_ALIGNED_LOAD
-#define EIGEN_DEBUG_ALIGNED_LOAD
-#endif
-
-#ifndef EIGEN_DEBUG_UNALIGNED_LOAD
-#define EIGEN_DEBUG_UNALIGNED_LOAD
-#endif
-
-#ifndef EIGEN_DEBUG_ALIGNED_STORE
-#define EIGEN_DEBUG_ALIGNED_STORE
-#endif
-
-#ifndef EIGEN_DEBUG_UNALIGNED_STORE
-#define EIGEN_DEBUG_UNALIGNED_STORE
-#endif
-
-struct default_packet_traits
-{
-  enum {
-    HasHalfPacket = 0,
-
-    HasAdd    = 1,
-    HasSub    = 1,
-    HasMul    = 1,
-    HasNegate = 1,
-    HasAbs    = 1,
-    HasArg    = 0,
-    HasAbs2   = 1,
-    HasMin    = 1,
-    HasMax    = 1,
-    HasConj   = 1,
-    HasSetLinear = 1,
-    HasBlend  = 0,
-
-    HasDiv    = 0,
-    HasSqrt   = 0,
-    HasRsqrt  = 0,
-    HasExp    = 0,
-    HasLog    = 0,
-    HasLog1p  = 0,
-    HasLog10  = 0,
-    HasPow    = 0,
-
-    HasSin    = 0,
-    HasCos    = 0,
-    HasTan    = 0,
-    HasASin   = 0,
-    HasACos   = 0,
-    HasATan   = 0,
-    HasSinh   = 0,
-    HasCosh   = 0,
-    HasTanh   = 0,
-    HasLGamma = 0,
-    HasDiGamma = 0,
-    HasZeta = 0,
-    HasPolygamma = 0,
-    HasErf = 0,
-    HasErfc = 0,
-    HasIGamma = 0,
-    HasIGammac = 0,
-    HasBetaInc = 0,
-
-    HasRound  = 0,
-    HasFloor  = 0,
-    HasCeil   = 0,
-
-    HasSign   = 0
-  };
-};
-
-template<typename T> struct packet_traits : default_packet_traits
-{
-  typedef T type;
-  typedef T half;
-  enum {
-    Vectorizable = 0,
-    size = 1,
-    AlignedOnScalar = 0,
-    HasHalfPacket = 0
-  };
-  enum {
-    HasAdd    = 0,
-    HasSub    = 0,
-    HasMul    = 0,
-    HasNegate = 0,
-    HasAbs    = 0,
-    HasAbs2   = 0,
-    HasMin    = 0,
-    HasMax    = 0,
-    HasConj   = 0,
-    HasSetLinear = 0
-  };
-};
-
-template<typename T> struct packet_traits<const T> : packet_traits<T> { };
-
-template <typename Src, typename Tgt> struct type_casting_traits {
-  enum {
-    VectorizedCast = 0,
-    SrcCoeffRatio = 1,
-    TgtCoeffRatio = 1
-  };
-};
-
-
-/** \internal \returns static_cast<TgtType>(a) (coeff-wise) */
-template <typename SrcPacket, typename TgtPacket>
-EIGEN_DEVICE_FUNC inline TgtPacket
-pcast(const SrcPacket& a) {
-  return static_cast<TgtPacket>(a);
-}
-template <typename SrcPacket, typename TgtPacket>
-EIGEN_DEVICE_FUNC inline TgtPacket
-pcast(const SrcPacket& a, const SrcPacket& /*b*/) {
-  return static_cast<TgtPacket>(a);
-}
-
-template <typename SrcPacket, typename TgtPacket>
-EIGEN_DEVICE_FUNC inline TgtPacket
-pcast(const SrcPacket& a, const SrcPacket& /*b*/, const SrcPacket& /*c*/, const SrcPacket& /*d*/) {
-  return static_cast<TgtPacket>(a);
-}
-
-/** \internal \returns a + b (coeff-wise) */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
-padd(const Packet& a,
-        const Packet& b) { return a+b; }
-
-/** \internal \returns a - b (coeff-wise) */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
-psub(const Packet& a,
-        const Packet& b) { return a-b; }
-
-/** \internal \returns -a (coeff-wise) */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
-pnegate(const Packet& a) { return -a; }
-
-/** \internal \returns conj(a) (coeff-wise) */
-
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
-pconj(const Packet& a) { return numext::conj(a); }
-
-/** \internal \returns a * b (coeff-wise) */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
-pmul(const Packet& a,
-        const Packet& b) { return a*b; }
-
-/** \internal \returns a / b (coeff-wise) */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
-pdiv(const Packet& a,
-        const Packet& b) { return a/b; }
-
-/** \internal \returns the min of \a a and \a b  (coeff-wise) */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
-pmin(const Packet& a,
-        const Packet& b) { return numext::mini(a, b); }
-
-/** \internal \returns the max of \a a and \a b  (coeff-wise) */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
-pmax(const Packet& a,
-        const Packet& b) { return numext::maxi(a, b); }
-
-/** \internal \returns the absolute value of \a a */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
-pabs(const Packet& a) { using std::abs; return abs(a); }
-
-/** \internal \returns the phase angle of \a a */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
-parg(const Packet& a) { using numext::arg; return arg(a); }
-
-/** \internal \returns the bitwise and of \a a and \a b */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
-pand(const Packet& a, const Packet& b) { return a & b; }
-
-/** \internal \returns the bitwise or of \a a and \a b */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
-por(const Packet& a, const Packet& b) { return a | b; }
-
-/** \internal \returns the bitwise xor of \a a and \a b */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
-pxor(const Packet& a, const Packet& b) { return a ^ b; }
-
-/** \internal \returns the bitwise andnot of \a a and \a b */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
-pandnot(const Packet& a, const Packet& b) { return a & (!b); }
-
-/** \internal \returns a packet version of \a *from, from must be 16 bytes aligned */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
-pload(const typename unpacket_traits<Packet>::type* from) { return *from; }
-
-/** \internal \returns a packet version of \a *from, (un-aligned load) */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
-ploadu(const typename unpacket_traits<Packet>::type* from) { return *from; }
-
-/** \internal \returns a packet with constant coefficients \a a, e.g.: (a,a,a,a) */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
-pset1(const typename unpacket_traits<Packet>::type& a) { return a; }
-
-/** \internal \returns a packet with constant coefficients \a a[0], e.g.: (a[0],a[0],a[0],a[0]) */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
-pload1(const typename unpacket_traits<Packet>::type  *a) { return pset1<Packet>(*a); }
-
-/** \internal \returns a packet with elements of \a *from duplicated.
-  * For instance, for a packet of 8 elements, 4 scalars will be read from \a *from and
-  * duplicated to form: {from[0],from[0],from[1],from[1],from[2],from[2],from[3],from[3]}
-  * Currently, this function is only used for scalar * complex products.
-  */
-template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet
-ploaddup(const typename unpacket_traits<Packet>::type* from) { return *from; }
-
-/** \internal \returns a packet with elements of \a *from quadrupled.
-  * For instance, for a packet of 8 elements, 2 scalars will be read from \a *from and
-  * replicated to form: {from[0],from[0],from[0],from[0],from[1],from[1],from[1],from[1]}
-  * Currently, this function is only used in matrix products.
-  * For packet-size smaller or equal to 4, this function is equivalent to pload1 
-  */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
-ploadquad(const typename unpacket_traits<Packet>::type* from)
-{ return pload1<Packet>(from); }
-
-/** \internal equivalent to
-  * \code
-  * a0 = pload1(a+0);
-  * a1 = pload1(a+1);
-  * a2 = pload1(a+2);
-  * a3 = pload1(a+3);
-  * \endcode
-  * \sa pset1, pload1, ploaddup, pbroadcast2
-  */
-template<typename Packet> EIGEN_DEVICE_FUNC
-inline void pbroadcast4(const typename unpacket_traits<Packet>::type *a,
-                        Packet& a0, Packet& a1, Packet& a2, Packet& a3)
-{
-  a0 = pload1<Packet>(a+0);
-  a1 = pload1<Packet>(a+1);
-  a2 = pload1<Packet>(a+2);
-  a3 = pload1<Packet>(a+3);
-}
-
-/** \internal equivalent to
-  * \code
-  * a0 = pload1(a+0);
-  * a1 = pload1(a+1);
-  * \endcode
-  * \sa pset1, pload1, ploaddup, pbroadcast4
-  */
-template<typename Packet> EIGEN_DEVICE_FUNC
-inline void pbroadcast2(const typename unpacket_traits<Packet>::type *a,
-                        Packet& a0, Packet& a1)
-{
-  a0 = pload1<Packet>(a+0);
-  a1 = pload1<Packet>(a+1);
-}
-
-/** \internal \brief Returns a packet with coefficients (a,a+1,...,a+packet_size-1). */
-template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet
-plset(const typename unpacket_traits<Packet>::type& a) { return a; }
-
-/** \internal copy the packet \a from to \a *to, \a to must be 16 bytes aligned */
-template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline void pstore(Scalar* to, const Packet& from)
-{ (*to) = from; }
-
-/** \internal copy the packet \a from to \a *to, (un-aligned store) */
-template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline void pstoreu(Scalar* to, const Packet& from)
-{  (*to) = from; }
-
- template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline Packet pgather(const Scalar* from, Index /*stride*/)
- { return ploadu<Packet>(from); }
-
- template<typename Scalar, typename Packet> EIGEN_DEVICE_FUNC inline void pscatter(Scalar* to, const Packet& from, Index /*stride*/)
- { pstore(to, from); }
-
-/** \internal tries to do cache prefetching of \a addr */
-template<typename Scalar> EIGEN_DEVICE_FUNC inline void prefetch(const Scalar* addr)
-{
-#ifdef __CUDA_ARCH__
-#if defined(__LP64__)
-  // 64-bit pointer operand constraint for inlined asm
-  asm(" prefetch.L1 [ %1 ];" : "=l"(addr) : "l"(addr));
-#else
-  // 32-bit pointer operand constraint for inlined asm
-  asm(" prefetch.L1 [ %1 ];" : "=r"(addr) : "r"(addr));
-#endif
-#elif (!EIGEN_COMP_MSVC) && (EIGEN_COMP_GNUC || EIGEN_COMP_CLANG || EIGEN_COMP_ICC)
-  __builtin_prefetch(addr);
-#endif
-}
-
-/** \internal \returns the first element of a packet */
-template<typename Packet> EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type pfirst(const Packet& a)
-{ return a; }
-
-/** \internal \returns a packet where the element i contains the sum of the packet of \a vec[i] */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
-preduxp(const Packet* vecs) { return vecs[0]; }
-
-/** \internal \returns the sum of the elements of \a a*/
-template<typename Packet> EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux(const Packet& a)
-{ return a; }
-
-/** \internal \returns the sum of the elements of \a a by block of 4 elements.
-  * For a packet {a0, a1, a2, a3, a4, a5, a6, a7}, it returns a half packet {a0+a4, a1+a5, a2+a6, a3+a7}
-  * For packet-size smaller or equal to 4, this boils down to a noop.
-  */
-template<typename Packet> EIGEN_DEVICE_FUNC inline
-typename conditional<(unpacket_traits<Packet>::size%8)==0,typename unpacket_traits<Packet>::half,Packet>::type
-predux_downto4(const Packet& a)
-{ return a; }
-
-/** \internal \returns the product of the elements of \a a*/
-template<typename Packet> EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_mul(const Packet& a)
-{ return a; }
-
-/** \internal \returns the min of the elements of \a a*/
-template<typename Packet> EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_min(const Packet& a)
-{ return a; }
-
-/** \internal \returns the max of the elements of \a a*/
-template<typename Packet> EIGEN_DEVICE_FUNC inline typename unpacket_traits<Packet>::type predux_max(const Packet& a)
-{ return a; }
-
-/** \internal \returns the reversed elements of \a a*/
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet preverse(const Packet& a)
-{ return a; }
-
-/** \internal \returns \a a with real and imaginary part flipped (for complex type only) */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet pcplxflip(const Packet& a)
-{
-  // FIXME: uncomment the following in case we drop the internal imag and real functions.
-//   using std::imag;
-//   using std::real;
-  return Packet(imag(a),real(a));
-}
-
-/**************************
-* Special math functions
-***************************/
-
-/** \internal \returns the sine of \a a (coeff-wise) */
-template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet psin(const Packet& a) { using std::sin; return sin(a); }
-
-/** \internal \returns the cosine of \a a (coeff-wise) */
-template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet pcos(const Packet& a) { using std::cos; return cos(a); }
-
-/** \internal \returns the tan of \a a (coeff-wise) */
-template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet ptan(const Packet& a) { using std::tan; return tan(a); }
-
-/** \internal \returns the arc sine of \a a (coeff-wise) */
-template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet pasin(const Packet& a) { using std::asin; return asin(a); }
-
-/** \internal \returns the arc cosine of \a a (coeff-wise) */
-template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet pacos(const Packet& a) { using std::acos; return acos(a); }
-
-/** \internal \returns the arc tangent of \a a (coeff-wise) */
-template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet patan(const Packet& a) { using std::atan; return atan(a); }
-
-/** \internal \returns the hyperbolic sine of \a a (coeff-wise) */
-template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet psinh(const Packet& a) { using std::sinh; return sinh(a); }
-
-/** \internal \returns the hyperbolic cosine of \a a (coeff-wise) */
-template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet pcosh(const Packet& a) { using std::cosh; return cosh(a); }
-
-/** \internal \returns the hyperbolic tan of \a a (coeff-wise) */
-template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet ptanh(const Packet& a) { using std::tanh; return tanh(a); }
-
-/** \internal \returns the exp of \a a (coeff-wise) */
-template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet pexp(const Packet& a) { using std::exp; return exp(a); }
-
-/** \internal \returns the log of \a a (coeff-wise) */
-template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet plog(const Packet& a) { using std::log; return log(a); }
-
-/** \internal \returns the log1p of \a a (coeff-wise) */
-template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet plog1p(const Packet& a) { return numext::log1p(a); }
-
-/** \internal \returns the log10 of \a a (coeff-wise) */
-template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet plog10(const Packet& a) { using std::log10; return log10(a); }
-
-/** \internal \returns the square-root of \a a (coeff-wise) */
-template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet psqrt(const Packet& a) { using std::sqrt; return sqrt(a); }
-
-/** \internal \returns the reciprocal square-root of \a a (coeff-wise) */
-template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet prsqrt(const Packet& a) {
-  return pdiv(pset1<Packet>(1), psqrt(a));
-}
-
-/** \internal \returns the rounded value of \a a (coeff-wise) */
-template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet pround(const Packet& a) { using numext::round; return round(a); }
-
-/** \internal \returns the floor of \a a (coeff-wise) */
-template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet pfloor(const Packet& a) { using numext::floor; return floor(a); }
-
-/** \internal \returns the ceil of \a a (coeff-wise) */
-template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-Packet pceil(const Packet& a) { using numext::ceil; return ceil(a); }
-
-/***************************************************************************
-* The following functions might not have to be overwritten for vectorized types
-***************************************************************************/
-
-/** \internal copy a packet with constant coeficient \a a (e.g., [a,a,a,a]) to \a *to. \a to must be 16 bytes aligned */
-// NOTE: this function must really be templated on the packet type (think about different packet types for the same scalar type)
-template<typename Packet>
-inline void pstore1(typename unpacket_traits<Packet>::type* to, const typename unpacket_traits<Packet>::type& a)
-{
-  pstore(to, pset1<Packet>(a));
-}
-
-/** \internal \returns a * b + c (coeff-wise) */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
-pmadd(const Packet&  a,
-         const Packet&  b,
-         const Packet&  c)
-{ return padd(pmul(a, b),c); }
-
-/** \internal \returns a packet version of \a *from.
-  * The pointer \a from must be aligned on a \a Alignment bytes boundary. */
-template<typename Packet, int Alignment>
-EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet ploadt(const typename unpacket_traits<Packet>::type* from)
-{
-  if(Alignment >= unpacket_traits<Packet>::alignment)
-    return pload<Packet>(from);
-  else
-    return ploadu<Packet>(from);
-}
-
-/** \internal copy the packet \a from to \a *to.
-  * The pointer \a from must be aligned on a \a Alignment bytes boundary. */
-template<typename Scalar, typename Packet, int Alignment>
-EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void pstoret(Scalar* to, const Packet& from)
-{
-  if(Alignment >= unpacket_traits<Packet>::alignment)
-    pstore(to, from);
-  else
-    pstoreu(to, from);
-}
-
-/** \internal \returns a packet version of \a *from.
-  * Unlike ploadt, ploadt_ro takes advantage of the read-only memory path on the
-  * hardware if available to speedup the loading of data that won't be modified
-  * by the current computation.
-  */
-template<typename Packet, int LoadMode>
-EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet ploadt_ro(const typename unpacket_traits<Packet>::type* from)
-{
-  return ploadt<Packet, LoadMode>(from);
-}
-
-/** \internal default implementation of palign() allowing partial specialization */
-template<int Offset,typename PacketType>
-struct palign_impl
-{
-  // by default data are aligned, so there is nothing to be done :)
-  static inline void run(PacketType&, const PacketType&) {}
-};
-
-/** \internal update \a first using the concatenation of the packet_size minus \a Offset last elements
-  * of \a first and \a Offset first elements of \a second.
-  * 
-  * This function is currently only used to optimize matrix-vector products on unligned matrices.
-  * It takes 2 packets that represent a contiguous memory array, and returns a packet starting
-  * at the position \a Offset. For instance, for packets of 4 elements, we have:
-  *  Input:
-  *  - first = {f0,f1,f2,f3}
-  *  - second = {s0,s1,s2,s3}
-  * Output: 
-  *   - if Offset==0 then {f0,f1,f2,f3}
-  *   - if Offset==1 then {f1,f2,f3,s0}
-  *   - if Offset==2 then {f2,f3,s0,s1}
-  *   - if Offset==3 then {f3,s0,s1,s3}
-  */
-template<int Offset,typename PacketType>
-inline void palign(PacketType& first, const PacketType& second)
-{
-  palign_impl<Offset,PacketType>::run(first,second);
-}
-
-/***************************************************************************
-* Fast complex products (GCC generates a function call which is very slow)
-***************************************************************************/
-
-// Eigen+CUDA does not support complexes.
-#ifndef __CUDACC__
-
-template<> inline std::complex<float> pmul(const std::complex<float>& a, const std::complex<float>& b)
-{ return std::complex<float>(real(a)*real(b) - imag(a)*imag(b), imag(a)*real(b) + real(a)*imag(b)); }
-
-template<> inline std::complex<double> pmul(const std::complex<double>& a, const std::complex<double>& b)
-{ return std::complex<double>(real(a)*real(b) - imag(a)*imag(b), imag(a)*real(b) + real(a)*imag(b)); }
-
-#endif
-
-
-/***************************************************************************
- * PacketBlock, that is a collection of N packets where the number of words
- * in the packet is a multiple of N.
-***************************************************************************/
-template <typename Packet,int N=unpacket_traits<Packet>::size> struct PacketBlock {
-  Packet packet[N];
-};
-
-template<typename Packet> EIGEN_DEVICE_FUNC inline void
-ptranspose(PacketBlock<Packet,1>& /*kernel*/) {
-  // Nothing to do in the scalar case, i.e. a 1x1 matrix.
-}
-
-/***************************************************************************
- * Selector, i.e. vector of N boolean values used to select (i.e. blend)
- * words from 2 packets.
-***************************************************************************/
-template <size_t N> struct Selector {
-  bool select[N];
-};
-
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
-pblend(const Selector<unpacket_traits<Packet>::size>& ifPacket, const Packet& thenPacket, const Packet& elsePacket) {
-  return ifPacket.select[0] ? thenPacket : elsePacket;
-}
-
-/** \internal \returns \a a with the first coefficient replaced by the scalar b */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
-pinsertfirst(const Packet& a, typename unpacket_traits<Packet>::type b)
-{
-  // Default implementation based on pblend.
-  // It must be specialized for higher performance.
-  Selector<unpacket_traits<Packet>::size> mask;
-  mask.select[0] = true;
-  // This for loop should be optimized away by the compiler.
-  for(Index i=1; i<unpacket_traits<Packet>::size; ++i)
-    mask.select[i] = false;
-  return pblend(mask, pset1<Packet>(b), a);
-}
-
-/** \internal \returns \a a with the last coefficient replaced by the scalar b */
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
-pinsertlast(const Packet& a, typename unpacket_traits<Packet>::type b)
-{
-  // Default implementation based on pblend.
-  // It must be specialized for higher performance.
-  Selector<unpacket_traits<Packet>::size> mask;
-  // This for loop should be optimized away by the compiler.
-  for(Index i=0; i<unpacket_traits<Packet>::size-1; ++i)
-    mask.select[i] = false;
-  mask.select[unpacket_traits<Packet>::size-1] = true;
-  return pblend(mask, pset1<Packet>(b), a);
-}
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_GENERIC_PACKET_MATH_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/GlobalFunctions.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/GlobalFunctions.h
deleted file mode 100644
index 769dc25..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/GlobalFunctions.h
+++ /dev/null
@@ -1,187 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2010-2016 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_GLOBAL_FUNCTIONS_H
-#define EIGEN_GLOBAL_FUNCTIONS_H
-
-#ifdef EIGEN_PARSED_BY_DOXYGEN
-
-#define EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(NAME,FUNCTOR,DOC_OP,DOC_DETAILS) \
-  /** \returns an expression of the coefficient-wise DOC_OP of \a x
-
-    DOC_DETAILS
-
-    \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_##NAME">Math functions</a>, class CwiseUnaryOp
-    */ \
-  template<typename Derived> \
-  inline const Eigen::CwiseUnaryOp<Eigen::internal::FUNCTOR<typename Derived::Scalar>, const Derived> \
-  NAME(const Eigen::ArrayBase<Derived>& x);
-
-#else
-
-#define EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(NAME,FUNCTOR,DOC_OP,DOC_DETAILS) \
-  template<typename Derived> \
-  inline const Eigen::CwiseUnaryOp<Eigen::internal::FUNCTOR<typename Derived::Scalar>, const Derived> \
-  (NAME)(const Eigen::ArrayBase<Derived>& x) { \
-    return Eigen::CwiseUnaryOp<Eigen::internal::FUNCTOR<typename Derived::Scalar>, const Derived>(x.derived()); \
-  }
-
-#endif // EIGEN_PARSED_BY_DOXYGEN
-
-#define EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(NAME,FUNCTOR) \
-  \
-  template<typename Derived> \
-  struct NAME##_retval<ArrayBase<Derived> > \
-  { \
-    typedef const Eigen::CwiseUnaryOp<Eigen::internal::FUNCTOR<typename Derived::Scalar>, const Derived> type; \
-  }; \
-  template<typename Derived> \
-  struct NAME##_impl<ArrayBase<Derived> > \
-  { \
-    static inline typename NAME##_retval<ArrayBase<Derived> >::type run(const Eigen::ArrayBase<Derived>& x) \
-    { \
-      return typename NAME##_retval<ArrayBase<Derived> >::type(x.derived()); \
-    } \
-  };
-
-namespace Eigen
-{
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(real,scalar_real_op,real part,\sa ArrayBase::real)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(imag,scalar_imag_op,imaginary part,\sa ArrayBase::imag)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(conj,scalar_conjugate_op,complex conjugate,\sa ArrayBase::conjugate)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(inverse,scalar_inverse_op,inverse,\sa ArrayBase::inverse)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sin,scalar_sin_op,sine,\sa ArrayBase::sin)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(cos,scalar_cos_op,cosine,\sa ArrayBase::cos)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(tan,scalar_tan_op,tangent,\sa ArrayBase::tan)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(atan,scalar_atan_op,arc-tangent,\sa ArrayBase::atan)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(asin,scalar_asin_op,arc-sine,\sa ArrayBase::asin)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(acos,scalar_acos_op,arc-consine,\sa ArrayBase::acos)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sinh,scalar_sinh_op,hyperbolic sine,\sa ArrayBase::sinh)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(cosh,scalar_cosh_op,hyperbolic cosine,\sa ArrayBase::cosh)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(tanh,scalar_tanh_op,hyperbolic tangent,\sa ArrayBase::tanh)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(lgamma,scalar_lgamma_op,natural logarithm of the gamma function,\sa ArrayBase::lgamma)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(digamma,scalar_digamma_op,derivative of lgamma,\sa ArrayBase::digamma)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(erf,scalar_erf_op,error function,\sa ArrayBase::erf)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(erfc,scalar_erfc_op,complement error function,\sa ArrayBase::erfc)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(exp,scalar_exp_op,exponential,\sa ArrayBase::exp)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log,scalar_log_op,natural logarithm,\sa Eigen::log10 DOXCOMMA ArrayBase::log)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log1p,scalar_log1p_op,natural logarithm of 1 plus the value,\sa ArrayBase::log1p)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log10,scalar_log10_op,base 10 logarithm,\sa Eigen::log DOXCOMMA ArrayBase::log)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(abs,scalar_abs_op,absolute value,\sa ArrayBase::abs DOXCOMMA MatrixBase::cwiseAbs)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(abs2,scalar_abs2_op,squared absolute value,\sa ArrayBase::abs2 DOXCOMMA MatrixBase::cwiseAbs2)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(arg,scalar_arg_op,complex argument,\sa ArrayBase::arg)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sqrt,scalar_sqrt_op,square root,\sa ArrayBase::sqrt DOXCOMMA MatrixBase::cwiseSqrt)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(rsqrt,scalar_rsqrt_op,reciprocal square root,\sa ArrayBase::rsqrt)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(square,scalar_square_op,square (power 2),\sa Eigen::abs2 DOXCOMMA Eigen::pow DOXCOMMA ArrayBase::square)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(cube,scalar_cube_op,cube (power 3),\sa Eigen::pow DOXCOMMA ArrayBase::cube)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(round,scalar_round_op,nearest integer,\sa Eigen::floor DOXCOMMA Eigen::ceil DOXCOMMA ArrayBase::round)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(floor,scalar_floor_op,nearest integer not greater than the giben value,\sa Eigen::ceil DOXCOMMA ArrayBase::floor)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(ceil,scalar_ceil_op,nearest integer not less than the giben value,\sa Eigen::floor DOXCOMMA ArrayBase::ceil)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(isnan,scalar_isnan_op,not-a-number test,\sa Eigen::isinf DOXCOMMA Eigen::isfinite DOXCOMMA ArrayBase::isnan)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(isinf,scalar_isinf_op,infinite value test,\sa Eigen::isnan DOXCOMMA Eigen::isfinite DOXCOMMA ArrayBase::isinf)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(isfinite,scalar_isfinite_op,finite value test,\sa Eigen::isinf DOXCOMMA Eigen::isnan DOXCOMMA ArrayBase::isfinite)
-  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sign,scalar_sign_op,sign (or 0),\sa ArrayBase::sign)
-  
-  /** \returns an expression of the coefficient-wise power of \a x to the given constant \a exponent.
-    *
-    * \tparam ScalarExponent is the scalar type of \a exponent. It must be compatible with the scalar type of the given expression (\c Derived::Scalar).
-    *
-    * \sa ArrayBase::pow()
-    *
-    * \relates ArrayBase
-    */
-#ifdef EIGEN_PARSED_BY_DOXYGEN
-  template<typename Derived,typename ScalarExponent>
-  inline const CwiseBinaryOp<internal::scalar_pow_op<Derived::Scalar,ScalarExponent>,Derived,Constant<ScalarExponent> >
-  pow(const Eigen::ArrayBase<Derived>& x, const ScalarExponent& exponent);
-#else
-  template<typename Derived,typename ScalarExponent>
-  inline typename internal::enable_if<   !(internal::is_same<typename Derived::Scalar,ScalarExponent>::value) && EIGEN_SCALAR_BINARY_SUPPORTED(pow,typename Derived::Scalar,ScalarExponent),
-          const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(Derived,ScalarExponent,pow) >::type
-  pow(const Eigen::ArrayBase<Derived>& x, const ScalarExponent& exponent) {
-    return x.derived().pow(exponent);
-  }
-
-  template<typename Derived>
-  inline const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(Derived,typename Derived::Scalar,pow)
-  pow(const Eigen::ArrayBase<Derived>& x, const typename Derived::Scalar& exponent) {
-    return x.derived().pow(exponent);
-  }
-#endif
-
-  /** \returns an expression of the coefficient-wise power of \a x to the given array of \a exponents.
-    *
-    * This function computes the coefficient-wise power.
-    *
-    * Example: \include Cwise_array_power_array.cpp
-    * Output: \verbinclude Cwise_array_power_array.out
-    * 
-    * \sa ArrayBase::pow()
-    *
-    * \relates ArrayBase
-    */
-  template<typename Derived,typename ExponentDerived>
-  inline const Eigen::CwiseBinaryOp<Eigen::internal::scalar_pow_op<typename Derived::Scalar, typename ExponentDerived::Scalar>, const Derived, const ExponentDerived>
-  pow(const Eigen::ArrayBase<Derived>& x, const Eigen::ArrayBase<ExponentDerived>& exponents) 
-  {
-    return Eigen::CwiseBinaryOp<Eigen::internal::scalar_pow_op<typename Derived::Scalar, typename ExponentDerived::Scalar>, const Derived, const ExponentDerived>(
-      x.derived(),
-      exponents.derived()
-    );
-  }
-  
-  /** \returns an expression of the coefficient-wise power of the scalar \a x to the given array of \a exponents.
-    *
-    * This function computes the coefficient-wise power between a scalar and an array of exponents.
-    *
-    * \tparam Scalar is the scalar type of \a x. It must be compatible with the scalar type of the given array expression (\c Derived::Scalar).
-    *
-    * Example: \include Cwise_scalar_power_array.cpp
-    * Output: \verbinclude Cwise_scalar_power_array.out
-    * 
-    * \sa ArrayBase::pow()
-    *
-    * \relates ArrayBase
-    */
-#ifdef EIGEN_PARSED_BY_DOXYGEN
-  template<typename Scalar,typename Derived>
-  inline const CwiseBinaryOp<internal::scalar_pow_op<Scalar,Derived::Scalar>,Constant<Scalar>,Derived>
-  pow(const Scalar& x,const Eigen::ArrayBase<Derived>& x);
-#else
-  template<typename Scalar, typename Derived>
-  inline typename internal::enable_if<   !(internal::is_same<typename Derived::Scalar,Scalar>::value) && EIGEN_SCALAR_BINARY_SUPPORTED(pow,Scalar,typename Derived::Scalar),
-          const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar,Derived,pow) >::type
-  pow(const Scalar& x, const Eigen::ArrayBase<Derived>& exponents)
-  {
-    return EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar,Derived,pow)(
-            typename internal::plain_constant_type<Derived,Scalar>::type(exponents.rows(), exponents.cols(), x), exponents.derived() );
-  }
-
-  template<typename Derived>
-  inline const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(typename Derived::Scalar,Derived,pow)
-  pow(const typename Derived::Scalar& x, const Eigen::ArrayBase<Derived>& exponents)
-  {
-    return EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(typename Derived::Scalar,Derived,pow)(
-      typename internal::plain_constant_type<Derived,typename Derived::Scalar>::type(exponents.rows(), exponents.cols(), x), exponents.derived() );
-  }
-#endif
-
-
-  namespace internal
-  {
-    EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(real,scalar_real_op)
-    EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(imag,scalar_imag_op)
-    EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(abs2,scalar_abs2_op)
-  }
-}
-
-// TODO: cleanly disable those functions that are not supported on Array (numext::real_ref, internal::random, internal::isApprox...)
-
-#endif // EIGEN_GLOBAL_FUNCTIONS_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/IO.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/IO.h
deleted file mode 100644
index da7fd6c..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/IO.h
+++ /dev/null
@@ -1,225 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_IO_H
-#define EIGEN_IO_H
-
-namespace Eigen { 
-
-enum { DontAlignCols = 1 };
-enum { StreamPrecision = -1,
-       FullPrecision = -2 };
-
-namespace internal {
-template<typename Derived>
-std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat& fmt);
-}
-
-/** \class IOFormat
-  * \ingroup Core_Module
-  *
-  * \brief Stores a set of parameters controlling the way matrices are printed
-  *
-  * List of available parameters:
-  *  - \b precision number of digits for floating point values, or one of the special constants \c StreamPrecision and \c FullPrecision.
-  *                 The default is the special value \c StreamPrecision which means to use the
-  *                 stream's own precision setting, as set for instance using \c cout.precision(3). The other special value
-  *                 \c FullPrecision means that the number of digits will be computed to match the full precision of each floating-point
-  *                 type.
-  *  - \b flags an OR-ed combination of flags, the default value is 0, the only currently available flag is \c DontAlignCols which
-  *             allows to disable the alignment of columns, resulting in faster code.
-  *  - \b coeffSeparator string printed between two coefficients of the same row
-  *  - \b rowSeparator string printed between two rows
-  *  - \b rowPrefix string printed at the beginning of each row
-  *  - \b rowSuffix string printed at the end of each row
-  *  - \b matPrefix string printed at the beginning of the matrix
-  *  - \b matSuffix string printed at the end of the matrix
-  *
-  * Example: \include IOFormat.cpp
-  * Output: \verbinclude IOFormat.out
-  *
-  * \sa DenseBase::format(), class WithFormat
-  */
-struct IOFormat
-{
-  /** Default constructor, see class IOFormat for the meaning of the parameters */
-  IOFormat(int _precision = StreamPrecision, int _flags = 0,
-    const std::string& _coeffSeparator = " ",
-    const std::string& _rowSeparator = "\n", const std::string& _rowPrefix="", const std::string& _rowSuffix="",
-    const std::string& _matPrefix="", const std::string& _matSuffix="")
-  : matPrefix(_matPrefix), matSuffix(_matSuffix), rowPrefix(_rowPrefix), rowSuffix(_rowSuffix), rowSeparator(_rowSeparator),
-    rowSpacer(""), coeffSeparator(_coeffSeparator), precision(_precision), flags(_flags)
-  {
-    // TODO check if rowPrefix, rowSuffix or rowSeparator contains a newline
-    // don't add rowSpacer if columns are not to be aligned
-    if((flags & DontAlignCols))
-      return;
-    int i = int(matSuffix.length())-1;
-    while (i>=0 && matSuffix[i]!='\n')
-    {
-      rowSpacer += ' ';
-      i--;
-    }
-  }
-  std::string matPrefix, matSuffix;
-  std::string rowPrefix, rowSuffix, rowSeparator, rowSpacer;
-  std::string coeffSeparator;
-  int precision;
-  int flags;
-};
-
-/** \class WithFormat
-  * \ingroup Core_Module
-  *
-  * \brief Pseudo expression providing matrix output with given format
-  *
-  * \tparam ExpressionType the type of the object on which IO stream operations are performed
-  *
-  * This class represents an expression with stream operators controlled by a given IOFormat.
-  * It is the return type of DenseBase::format()
-  * and most of the time this is the only way it is used.
-  *
-  * See class IOFormat for some examples.
-  *
-  * \sa DenseBase::format(), class IOFormat
-  */
-template<typename ExpressionType>
-class WithFormat
-{
-  public:
-
-    WithFormat(const ExpressionType& matrix, const IOFormat& format)
-      : m_matrix(matrix), m_format(format)
-    {}
-
-    friend std::ostream & operator << (std::ostream & s, const WithFormat& wf)
-    {
-      return internal::print_matrix(s, wf.m_matrix.eval(), wf.m_format);
-    }
-
-  protected:
-    typename ExpressionType::Nested m_matrix;
-    IOFormat m_format;
-};
-
-namespace internal {
-
-// NOTE: This helper is kept for backward compatibility with previous code specializing
-//       this internal::significant_decimals_impl structure. In the future we should directly
-//       call digits10() which has been introduced in July 2016 in 3.3.
-template<typename Scalar>
-struct significant_decimals_impl
-{
-  static inline int run()
-  {
-    return NumTraits<Scalar>::digits10();
-  }
-};
-
-/** \internal
-  * print the matrix \a _m to the output stream \a s using the output format \a fmt */
-template<typename Derived>
-std::ostream & print_matrix(std::ostream & s, const Derived& _m, const IOFormat& fmt)
-{
-  if(_m.size() == 0)
-  {
-    s << fmt.matPrefix << fmt.matSuffix;
-    return s;
-  }
-  
-  typename Derived::Nested m = _m;
-  typedef typename Derived::Scalar Scalar;
-
-  Index width = 0;
-
-  std::streamsize explicit_precision;
-  if(fmt.precision == StreamPrecision)
-  {
-    explicit_precision = 0;
-  }
-  else if(fmt.precision == FullPrecision)
-  {
-    if (NumTraits<Scalar>::IsInteger)
-    {
-      explicit_precision = 0;
-    }
-    else
-    {
-      explicit_precision = significant_decimals_impl<Scalar>::run();
-    }
-  }
-  else
-  {
-    explicit_precision = fmt.precision;
-  }
-
-  std::streamsize old_precision = 0;
-  if(explicit_precision) old_precision = s.precision(explicit_precision);
-
-  bool align_cols = !(fmt.flags & DontAlignCols);
-  if(align_cols)
-  {
-    // compute the largest width
-    for(Index j = 0; j < m.cols(); ++j)
-      for(Index i = 0; i < m.rows(); ++i)
-      {
-        std::stringstream sstr;
-        sstr.copyfmt(s);
-        sstr << m.coeff(i,j);
-        width = std::max<Index>(width, Index(sstr.str().length()));
-      }
-  }
-  s << fmt.matPrefix;
-  for(Index i = 0; i < m.rows(); ++i)
-  {
-    if (i)
-      s << fmt.rowSpacer;
-    s << fmt.rowPrefix;
-    if(width) s.width(width);
-    s << m.coeff(i, 0);
-    for(Index j = 1; j < m.cols(); ++j)
-    {
-      s << fmt.coeffSeparator;
-      if (width) s.width(width);
-      s << m.coeff(i, j);
-    }
-    s << fmt.rowSuffix;
-    if( i < m.rows() - 1)
-      s << fmt.rowSeparator;
-  }
-  s << fmt.matSuffix;
-  if(explicit_precision) s.precision(old_precision);
-  return s;
-}
-
-} // end namespace internal
-
-/** \relates DenseBase
-  *
-  * Outputs the matrix, to the given stream.
-  *
-  * If you wish to print the matrix with a format different than the default, use DenseBase::format().
-  *
-  * It is also possible to change the default format by defining EIGEN_DEFAULT_IO_FORMAT before including Eigen headers.
-  * If not defined, this will automatically be defined to Eigen::IOFormat(), that is the Eigen::IOFormat with default parameters.
-  *
-  * \sa DenseBase::format()
-  */
-template<typename Derived>
-std::ostream & operator <<
-(std::ostream & s,
- const DenseBase<Derived> & m)
-{
-  return internal::print_matrix(s, m.eval(), EIGEN_DEFAULT_IO_FORMAT);
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_IO_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Inverse.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Inverse.h
deleted file mode 100644
index b76f043..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Inverse.h
+++ /dev/null
@@ -1,118 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2014 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_INVERSE_H
-#define EIGEN_INVERSE_H
-
-namespace Eigen { 
-
-template<typename XprType,typename StorageKind> class InverseImpl;
-
-namespace internal {
-
-template<typename XprType>
-struct traits<Inverse<XprType> >
-  : traits<typename XprType::PlainObject>
-{
-  typedef typename XprType::PlainObject PlainObject;
-  typedef traits<PlainObject> BaseTraits;
-  enum {
-    Flags = BaseTraits::Flags & RowMajorBit
-  };
-};
-
-} // end namespace internal
-
-/** \class Inverse
-  *
-  * \brief Expression of the inverse of another expression
-  *
-  * \tparam XprType the type of the expression we are taking the inverse
-  *
-  * This class represents an abstract expression of A.inverse()
-  * and most of the time this is the only way it is used.
-  *
-  */
-template<typename XprType>
-class Inverse : public InverseImpl<XprType,typename internal::traits<XprType>::StorageKind>
-{
-public:
-  typedef typename XprType::StorageIndex StorageIndex;
-  typedef typename XprType::PlainObject                       PlainObject;
-  typedef typename XprType::Scalar                            Scalar;
-  typedef typename internal::ref_selector<XprType>::type      XprTypeNested;
-  typedef typename internal::remove_all<XprTypeNested>::type  XprTypeNestedCleaned;
-  typedef typename internal::ref_selector<Inverse>::type Nested;
-  typedef typename internal::remove_all<XprType>::type NestedExpression;
-  
-  explicit EIGEN_DEVICE_FUNC Inverse(const XprType &xpr)
-    : m_xpr(xpr)
-  {}
-
-  EIGEN_DEVICE_FUNC Index rows() const { return m_xpr.rows(); }
-  EIGEN_DEVICE_FUNC Index cols() const { return m_xpr.cols(); }
-
-  EIGEN_DEVICE_FUNC const XprTypeNestedCleaned& nestedExpression() const { return m_xpr; }
-
-protected:
-  XprTypeNested m_xpr;
-};
-
-// Generic API dispatcher
-template<typename XprType, typename StorageKind>
-class InverseImpl
-  : public internal::generic_xpr_base<Inverse<XprType> >::type
-{
-public:
-  typedef typename internal::generic_xpr_base<Inverse<XprType> >::type Base;
-  typedef typename XprType::Scalar Scalar;
-private:
-
-  Scalar coeff(Index row, Index col) const;
-  Scalar coeff(Index i) const;
-};
-
-namespace internal {
-
-/** \internal
-  * \brief Default evaluator for Inverse expression.
-  * 
-  * This default evaluator for Inverse expression simply evaluate the inverse into a temporary
-  * by a call to internal::call_assignment_no_alias.
-  * Therefore, inverse implementers only have to specialize Assignment<Dst,Inverse<...>, ...> for
-  * there own nested expression.
-  *
-  * \sa class Inverse
-  */
-template<typename ArgType>
-struct unary_evaluator<Inverse<ArgType> >
-  : public evaluator<typename Inverse<ArgType>::PlainObject>
-{
-  typedef Inverse<ArgType> InverseType;
-  typedef typename InverseType::PlainObject PlainObject;
-  typedef evaluator<PlainObject> Base;
-  
-  enum { Flags = Base::Flags | EvalBeforeNestingBit };
-
-  unary_evaluator(const InverseType& inv_xpr)
-    : m_result(inv_xpr.rows(), inv_xpr.cols())
-  {
-    ::new (static_cast<Base*>(this)) Base(m_result);
-    internal::call_assignment_no_alias(m_result, inv_xpr);
-  }
-  
-protected:
-  PlainObject m_result;
-};
-  
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_INVERSE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Map.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Map.h
deleted file mode 100644
index 548bf9a..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Map.h
+++ /dev/null
@@ -1,171 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_MAP_H
-#define EIGEN_MAP_H
-
-namespace Eigen { 
-
-namespace internal {
-template<typename PlainObjectType, int MapOptions, typename StrideType>
-struct traits<Map<PlainObjectType, MapOptions, StrideType> >
-  : public traits<PlainObjectType>
-{
-  typedef traits<PlainObjectType> TraitsBase;
-  enum {
-    PlainObjectTypeInnerSize = ((traits<PlainObjectType>::Flags&RowMajorBit)==RowMajorBit)
-                             ? PlainObjectType::ColsAtCompileTime
-                             : PlainObjectType::RowsAtCompileTime,
-
-    InnerStrideAtCompileTime = StrideType::InnerStrideAtCompileTime == 0
-                             ? int(PlainObjectType::InnerStrideAtCompileTime)
-                             : int(StrideType::InnerStrideAtCompileTime),
-    OuterStrideAtCompileTime = StrideType::OuterStrideAtCompileTime == 0
-                             ? (InnerStrideAtCompileTime==Dynamic || PlainObjectTypeInnerSize==Dynamic
-                                ? Dynamic
-                                : int(InnerStrideAtCompileTime) * int(PlainObjectTypeInnerSize))
-                             : int(StrideType::OuterStrideAtCompileTime),
-    Alignment = int(MapOptions)&int(AlignedMask),
-    Flags0 = TraitsBase::Flags & (~NestByRefBit),
-    Flags = is_lvalue<PlainObjectType>::value ? int(Flags0) : (int(Flags0) & ~LvalueBit)
-  };
-private:
-  enum { Options }; // Expressions don't have Options
-};
-}
-
-/** \class Map
-  * \ingroup Core_Module
-  *
-  * \brief A matrix or vector expression mapping an existing array of data.
-  *
-  * \tparam PlainObjectType the equivalent matrix type of the mapped data
-  * \tparam MapOptions specifies the pointer alignment in bytes. It can be: \c #Aligned128, , \c #Aligned64, \c #Aligned32, \c #Aligned16, \c #Aligned8 or \c #Unaligned.
-  *                The default is \c #Unaligned.
-  * \tparam StrideType optionally specifies strides. By default, Map assumes the memory layout
-  *                   of an ordinary, contiguous array. This can be overridden by specifying strides.
-  *                   The type passed here must be a specialization of the Stride template, see examples below.
-  *
-  * This class represents a matrix or vector expression mapping an existing array of data.
-  * It can be used to let Eigen interface without any overhead with non-Eigen data structures,
-  * such as plain C arrays or structures from other libraries. By default, it assumes that the
-  * data is laid out contiguously in memory. You can however override this by explicitly specifying
-  * inner and outer strides.
-  *
-  * Here's an example of simply mapping a contiguous array as a \ref TopicStorageOrders "column-major" matrix:
-  * \include Map_simple.cpp
-  * Output: \verbinclude Map_simple.out
-  *
-  * If you need to map non-contiguous arrays, you can do so by specifying strides:
-  *
-  * Here's an example of mapping an array as a vector, specifying an inner stride, that is, the pointer
-  * increment between two consecutive coefficients. Here, we're specifying the inner stride as a compile-time
-  * fixed value.
-  * \include Map_inner_stride.cpp
-  * Output: \verbinclude Map_inner_stride.out
-  *
-  * Here's an example of mapping an array while specifying an outer stride. Here, since we're mapping
-  * as a column-major matrix, 'outer stride' means the pointer increment between two consecutive columns.
-  * Here, we're specifying the outer stride as a runtime parameter. Note that here \c OuterStride<> is
-  * a short version of \c OuterStride<Dynamic> because the default template parameter of OuterStride
-  * is  \c Dynamic
-  * \include Map_outer_stride.cpp
-  * Output: \verbinclude Map_outer_stride.out
-  *
-  * For more details and for an example of specifying both an inner and an outer stride, see class Stride.
-  *
-  * \b Tip: to change the array of data mapped by a Map object, you can use the C++
-  * placement new syntax:
-  *
-  * Example: \include Map_placement_new.cpp
-  * Output: \verbinclude Map_placement_new.out
-  *
-  * This class is the return type of PlainObjectBase::Map() but can also be used directly.
-  *
-  * \sa PlainObjectBase::Map(), \ref TopicStorageOrders
-  */
-template<typename PlainObjectType, int MapOptions, typename StrideType> class Map
-  : public MapBase<Map<PlainObjectType, MapOptions, StrideType> >
-{
-  public:
-
-    typedef MapBase<Map> Base;
-    EIGEN_DENSE_PUBLIC_INTERFACE(Map)
-
-    typedef typename Base::PointerType PointerType;
-    typedef PointerType PointerArgType;
-    EIGEN_DEVICE_FUNC
-    inline PointerType cast_to_pointer_type(PointerArgType ptr) { return ptr; }
-
-    EIGEN_DEVICE_FUNC
-    inline Index innerStride() const
-    {
-      return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1;
-    }
-
-    EIGEN_DEVICE_FUNC
-    inline Index outerStride() const
-    {
-      return int(StrideType::OuterStrideAtCompileTime) != 0 ? m_stride.outer()
-           : int(internal::traits<Map>::OuterStrideAtCompileTime) != Dynamic ? Index(internal::traits<Map>::OuterStrideAtCompileTime)
-           : IsVectorAtCompileTime ? (this->size() * innerStride())
-           : (int(Flags)&RowMajorBit) ? (this->cols() * innerStride())
-           : (this->rows() * innerStride());
-    }
-
-    /** Constructor in the fixed-size case.
-      *
-      * \param dataPtr pointer to the array to map
-      * \param stride optional Stride object, passing the strides.
-      */
-    EIGEN_DEVICE_FUNC
-    explicit inline Map(PointerArgType dataPtr, const StrideType& stride = StrideType())
-      : Base(cast_to_pointer_type(dataPtr)), m_stride(stride)
-    {
-      PlainObjectType::Base::_check_template_params();
-    }
-
-    /** Constructor in the dynamic-size vector case.
-      *
-      * \param dataPtr pointer to the array to map
-      * \param size the size of the vector expression
-      * \param stride optional Stride object, passing the strides.
-      */
-    EIGEN_DEVICE_FUNC
-    inline Map(PointerArgType dataPtr, Index size, const StrideType& stride = StrideType())
-      : Base(cast_to_pointer_type(dataPtr), size), m_stride(stride)
-    {
-      PlainObjectType::Base::_check_template_params();
-    }
-
-    /** Constructor in the dynamic-size matrix case.
-      *
-      * \param dataPtr pointer to the array to map
-      * \param rows the number of rows of the matrix expression
-      * \param cols the number of columns of the matrix expression
-      * \param stride optional Stride object, passing the strides.
-      */
-    EIGEN_DEVICE_FUNC
-    inline Map(PointerArgType dataPtr, Index rows, Index cols, const StrideType& stride = StrideType())
-      : Base(cast_to_pointer_type(dataPtr), rows, cols), m_stride(stride)
-    {
-      PlainObjectType::Base::_check_template_params();
-    }
-
-    EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Map)
-
-  protected:
-    StrideType m_stride;
-};
-
-
-} // end namespace Eigen
-
-#endif // EIGEN_MAP_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/MapBase.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/MapBase.h
deleted file mode 100644
index 668922f..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/MapBase.h
+++ /dev/null
@@ -1,303 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_MAPBASE_H
-#define EIGEN_MAPBASE_H
-
-#define EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) \
-      EIGEN_STATIC_ASSERT((int(internal::evaluator<Derived>::Flags) & LinearAccessBit) || Derived::IsVectorAtCompileTime, \
-                          YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT)
-
-namespace Eigen { 
-
-/** \ingroup Core_Module
-  *
-  * \brief Base class for dense Map and Block expression with direct access
-  *
-  * This base class provides the const low-level accessors (e.g. coeff, coeffRef) of dense
-  * Map and Block objects with direct access.
-  * Typical users do not have to directly deal with this class.
-  *
-  * This class can be extended by through the macro plugin \c EIGEN_MAPBASE_PLUGIN.
-  * See \link TopicCustomizing_Plugins customizing Eigen \endlink for details.
-  *
-  * The \c Derived class has to provide the following two methods describing the memory layout:
-  *  \code Index innerStride() const; \endcode
-  *  \code Index outerStride() const; \endcode
-  *
-  * \sa class Map, class Block
-  */
-template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
-  : public internal::dense_xpr_base<Derived>::type
-{
-  public:
-
-    typedef typename internal::dense_xpr_base<Derived>::type Base;
-    enum {
-      RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
-      ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
-      InnerStrideAtCompileTime = internal::traits<Derived>::InnerStrideAtCompileTime,
-      SizeAtCompileTime = Base::SizeAtCompileTime
-    };
-
-    typedef typename internal::traits<Derived>::StorageKind StorageKind;
-    typedef typename internal::traits<Derived>::Scalar Scalar;
-    typedef typename internal::packet_traits<Scalar>::type PacketScalar;
-    typedef typename NumTraits<Scalar>::Real RealScalar;
-    typedef typename internal::conditional<
-                         bool(internal::is_lvalue<Derived>::value),
-                         Scalar *,
-                         const Scalar *>::type
-                     PointerType;
-
-    using Base::derived;
-//    using Base::RowsAtCompileTime;
-//    using Base::ColsAtCompileTime;
-//    using Base::SizeAtCompileTime;
-    using Base::MaxRowsAtCompileTime;
-    using Base::MaxColsAtCompileTime;
-    using Base::MaxSizeAtCompileTime;
-    using Base::IsVectorAtCompileTime;
-    using Base::Flags;
-    using Base::IsRowMajor;
-
-    using Base::rows;
-    using Base::cols;
-    using Base::size;
-    using Base::coeff;
-    using Base::coeffRef;
-    using Base::lazyAssign;
-    using Base::eval;
-
-    using Base::innerStride;
-    using Base::outerStride;
-    using Base::rowStride;
-    using Base::colStride;
-
-    // bug 217 - compile error on ICC 11.1
-    using Base::operator=;
-
-    typedef typename Base::CoeffReturnType CoeffReturnType;
-
-    /** \copydoc DenseBase::rows() */
-    EIGEN_DEVICE_FUNC inline Index rows() const { return m_rows.value(); }
-    /** \copydoc DenseBase::cols() */
-    EIGEN_DEVICE_FUNC inline Index cols() const { return m_cols.value(); }
-
-    /** Returns a pointer to the first coefficient of the matrix or vector.
-      *
-      * \note When addressing this data, make sure to honor the strides returned by innerStride() and outerStride().
-      *
-      * \sa innerStride(), outerStride()
-      */
-    EIGEN_DEVICE_FUNC inline const Scalar* data() const { return m_data; }
-
-    /** \copydoc PlainObjectBase::coeff(Index,Index) const */
-    EIGEN_DEVICE_FUNC
-    inline const Scalar& coeff(Index rowId, Index colId) const
-    {
-      return m_data[colId * colStride() + rowId * rowStride()];
-    }
-
-    /** \copydoc PlainObjectBase::coeff(Index) const */
-    EIGEN_DEVICE_FUNC
-    inline const Scalar& coeff(Index index) const
-    {
-      EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
-      return m_data[index * innerStride()];
-    }
-
-    /** \copydoc PlainObjectBase::coeffRef(Index,Index) const */
-    EIGEN_DEVICE_FUNC
-    inline const Scalar& coeffRef(Index rowId, Index colId) const
-    {
-      return this->m_data[colId * colStride() + rowId * rowStride()];
-    }
-
-    /** \copydoc PlainObjectBase::coeffRef(Index) const */
-    EIGEN_DEVICE_FUNC
-    inline const Scalar& coeffRef(Index index) const
-    {
-      EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
-      return this->m_data[index * innerStride()];
-    }
-
-    /** \internal */
-    template<int LoadMode>
-    inline PacketScalar packet(Index rowId, Index colId) const
-    {
-      return internal::ploadt<PacketScalar, LoadMode>
-               (m_data + (colId * colStride() + rowId * rowStride()));
-    }
-
-    /** \internal */
-    template<int LoadMode>
-    inline PacketScalar packet(Index index) const
-    {
-      EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
-      return internal::ploadt<PacketScalar, LoadMode>(m_data + index * innerStride());
-    }
-
-    /** \internal Constructor for fixed size matrices or vectors */
-    EIGEN_DEVICE_FUNC
-    explicit inline MapBase(PointerType dataPtr) : m_data(dataPtr), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime)
-    {
-      EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
-      checkSanity<Derived>();
-    }
-
-    /** \internal Constructor for dynamically sized vectors */
-    EIGEN_DEVICE_FUNC
-    inline MapBase(PointerType dataPtr, Index vecSize)
-            : m_data(dataPtr),
-              m_rows(RowsAtCompileTime == Dynamic ? vecSize : Index(RowsAtCompileTime)),
-              m_cols(ColsAtCompileTime == Dynamic ? vecSize : Index(ColsAtCompileTime))
-    {
-      EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
-      eigen_assert(vecSize >= 0);
-      eigen_assert(dataPtr == 0 || SizeAtCompileTime == Dynamic || SizeAtCompileTime == vecSize);
-      checkSanity<Derived>();
-    }
-
-    /** \internal Constructor for dynamically sized matrices */
-    EIGEN_DEVICE_FUNC
-    inline MapBase(PointerType dataPtr, Index rows, Index cols)
-            : m_data(dataPtr), m_rows(rows), m_cols(cols)
-    {
-      eigen_assert( (dataPtr == 0)
-              || (   rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
-                  && cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)));
-      checkSanity<Derived>();
-    }
-
-    #ifdef EIGEN_MAPBASE_PLUGIN
-    #include EIGEN_MAPBASE_PLUGIN
-    #endif
-
-  protected:
-
-    template<typename T>
-    EIGEN_DEVICE_FUNC
-    void checkSanity(typename internal::enable_if<(internal::traits<T>::Alignment>0),void*>::type = 0) const
-    {
-#if EIGEN_MAX_ALIGN_BYTES>0
-      // innerStride() is not set yet when this function is called, so we optimistically assume the lowest plausible value:
-      const Index minInnerStride = InnerStrideAtCompileTime == Dynamic ? 1 : Index(InnerStrideAtCompileTime);
-      EIGEN_ONLY_USED_FOR_DEBUG(minInnerStride);
-      eigen_assert((   ((internal::UIntPtr(m_data) % internal::traits<Derived>::Alignment) == 0)
-                    || (cols() * rows() * minInnerStride * sizeof(Scalar)) < internal::traits<Derived>::Alignment ) && "data is not aligned");
-#endif
-    }
-
-    template<typename T>
-    EIGEN_DEVICE_FUNC
-    void checkSanity(typename internal::enable_if<internal::traits<T>::Alignment==0,void*>::type = 0) const
-    {}
-
-    PointerType m_data;
-    const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_rows;
-    const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_cols;
-};
-
-/** \ingroup Core_Module
-  *
-  * \brief Base class for non-const dense Map and Block expression with direct access
-  *
-  * This base class provides the non-const low-level accessors (e.g. coeff and coeffRef) of
-  * dense Map and Block objects with direct access.
-  * It inherits MapBase<Derived, ReadOnlyAccessors> which defines the const variant for reading specific entries.
-  *
-  * \sa class Map, class Block
-  */
-template<typename Derived> class MapBase<Derived, WriteAccessors>
-  : public MapBase<Derived, ReadOnlyAccessors>
-{
-    typedef MapBase<Derived, ReadOnlyAccessors> ReadOnlyMapBase;
-  public:
-
-    typedef MapBase<Derived, ReadOnlyAccessors> Base;
-
-    typedef typename Base::Scalar Scalar;
-    typedef typename Base::PacketScalar PacketScalar;
-    typedef typename Base::StorageIndex StorageIndex;
-    typedef typename Base::PointerType PointerType;
-
-    using Base::derived;
-    using Base::rows;
-    using Base::cols;
-    using Base::size;
-    using Base::coeff;
-    using Base::coeffRef;
-
-    using Base::innerStride;
-    using Base::outerStride;
-    using Base::rowStride;
-    using Base::colStride;
-
-    typedef typename internal::conditional<
-                    internal::is_lvalue<Derived>::value,
-                    Scalar,
-                    const Scalar
-                  >::type ScalarWithConstIfNotLvalue;
-
-    EIGEN_DEVICE_FUNC
-    inline const Scalar* data() const { return this->m_data; }
-    EIGEN_DEVICE_FUNC
-    inline ScalarWithConstIfNotLvalue* data() { return this->m_data; } // no const-cast here so non-const-correct code will give a compile error
-
-    EIGEN_DEVICE_FUNC
-    inline ScalarWithConstIfNotLvalue& coeffRef(Index row, Index col)
-    {
-      return this->m_data[col * colStride() + row * rowStride()];
-    }
-
-    EIGEN_DEVICE_FUNC
-    inline ScalarWithConstIfNotLvalue& coeffRef(Index index)
-    {
-      EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
-      return this->m_data[index * innerStride()];
-    }
-
-    template<int StoreMode>
-    inline void writePacket(Index row, Index col, const PacketScalar& val)
-    {
-      internal::pstoret<Scalar, PacketScalar, StoreMode>
-               (this->m_data + (col * colStride() + row * rowStride()), val);
-    }
-
-    template<int StoreMode>
-    inline void writePacket(Index index, const PacketScalar& val)
-    {
-      EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
-      internal::pstoret<Scalar, PacketScalar, StoreMode>
-                (this->m_data + index * innerStride(), val);
-    }
-
-    EIGEN_DEVICE_FUNC explicit inline MapBase(PointerType dataPtr) : Base(dataPtr) {}
-    EIGEN_DEVICE_FUNC inline MapBase(PointerType dataPtr, Index vecSize) : Base(dataPtr, vecSize) {}
-    EIGEN_DEVICE_FUNC inline MapBase(PointerType dataPtr, Index rows, Index cols) : Base(dataPtr, rows, cols) {}
-
-    EIGEN_DEVICE_FUNC
-    Derived& operator=(const MapBase& other)
-    {
-      ReadOnlyMapBase::Base::operator=(other);
-      return derived();
-    }
-
-    // In theory we could simply refer to Base:Base::operator=, but MSVC does not like Base::Base,
-    // see bugs 821 and 920.
-    using ReadOnlyMapBase::Base::operator=;
-};
-
-#undef EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS
-
-} // end namespace Eigen
-
-#endif // EIGEN_MAPBASE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/MathFunctions.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/MathFunctions.h
deleted file mode 100644
index b249ce0..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/MathFunctions.h
+++ /dev/null
@@ -1,1415 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_MATHFUNCTIONS_H
-#define EIGEN_MATHFUNCTIONS_H
-
-// source: http://www.geom.uiuc.edu/~huberty/math5337/groupe/digits.html
-// TODO this should better be moved to NumTraits
-#define EIGEN_PI 3.141592653589793238462643383279502884197169399375105820974944592307816406L
-
-
-namespace Eigen {
-
-// On WINCE, std::abs is defined for int only, so let's defined our own overloads:
-// This issue has been confirmed with MSVC 2008 only, but the issue might exist for more recent versions too.
-#if EIGEN_OS_WINCE && EIGEN_COMP_MSVC && EIGEN_COMP_MSVC<=1500
-long        abs(long        x) { return (labs(x));  }
-double      abs(double      x) { return (fabs(x));  }
-float       abs(float       x) { return (fabsf(x)); }
-long double abs(long double x) { return (fabsl(x)); }
-#endif
-
-namespace internal {
-
-/** \internal \class global_math_functions_filtering_base
-  *
-  * What it does:
-  * Defines a typedef 'type' as follows:
-  * - if type T has a member typedef Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl, then
-  *   global_math_functions_filtering_base<T>::type is a typedef for it.
-  * - otherwise, global_math_functions_filtering_base<T>::type is a typedef for T.
-  *
-  * How it's used:
-  * To allow to defined the global math functions (like sin...) in certain cases, like the Array expressions.
-  * When you do sin(array1+array2), the object array1+array2 has a complicated expression type, all what you want to know
-  * is that it inherits ArrayBase. So we implement a partial specialization of sin_impl for ArrayBase<Derived>.
-  * So we must make sure to use sin_impl<ArrayBase<Derived> > and not sin_impl<Derived>, otherwise our partial specialization
-  * won't be used. How does sin know that? That's exactly what global_math_functions_filtering_base tells it.
-  *
-  * How it's implemented:
-  * SFINAE in the style of enable_if. Highly susceptible of breaking compilers. With GCC, it sure does work, but if you replace
-  * the typename dummy by an integer template parameter, it doesn't work anymore!
-  */
-
-template<typename T, typename dummy = void>
-struct global_math_functions_filtering_base
-{
-  typedef T type;
-};
-
-template<typename T> struct always_void { typedef void type; };
-
-template<typename T>
-struct global_math_functions_filtering_base
-  <T,
-   typename always_void<typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl>::type
-  >
-{
-  typedef typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl type;
-};
-
-#define EIGEN_MATHFUNC_IMPL(func, scalar) Eigen::internal::func##_impl<typename Eigen::internal::global_math_functions_filtering_base<scalar>::type>
-#define EIGEN_MATHFUNC_RETVAL(func, scalar) typename Eigen::internal::func##_retval<typename Eigen::internal::global_math_functions_filtering_base<scalar>::type>::type
-
-/****************************************************************************
-* Implementation of real                                                 *
-****************************************************************************/
-
-template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
-struct real_default_impl
-{
-  typedef typename NumTraits<Scalar>::Real RealScalar;
-  EIGEN_DEVICE_FUNC
-  static inline RealScalar run(const Scalar& x)
-  {
-    return x;
-  }
-};
-
-template<typename Scalar>
-struct real_default_impl<Scalar,true>
-{
-  typedef typename NumTraits<Scalar>::Real RealScalar;
-  EIGEN_DEVICE_FUNC
-  static inline RealScalar run(const Scalar& x)
-  {
-    using std::real;
-    return real(x);
-  }
-};
-
-template<typename Scalar> struct real_impl : real_default_impl<Scalar> {};
-
-#ifdef __CUDA_ARCH__
-template<typename T>
-struct real_impl<std::complex<T> >
-{
-  typedef T RealScalar;
-  EIGEN_DEVICE_FUNC
-  static inline T run(const std::complex<T>& x)
-  {
-    return x.real();
-  }
-};
-#endif
-
-template<typename Scalar>
-struct real_retval
-{
-  typedef typename NumTraits<Scalar>::Real type;
-};
-
-/****************************************************************************
-* Implementation of imag                                                 *
-****************************************************************************/
-
-template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
-struct imag_default_impl
-{
-  typedef typename NumTraits<Scalar>::Real RealScalar;
-  EIGEN_DEVICE_FUNC
-  static inline RealScalar run(const Scalar&)
-  {
-    return RealScalar(0);
-  }
-};
-
-template<typename Scalar>
-struct imag_default_impl<Scalar,true>
-{
-  typedef typename NumTraits<Scalar>::Real RealScalar;
-  EIGEN_DEVICE_FUNC
-  static inline RealScalar run(const Scalar& x)
-  {
-    using std::imag;
-    return imag(x);
-  }
-};
-
-template<typename Scalar> struct imag_impl : imag_default_impl<Scalar> {};
-
-#ifdef __CUDA_ARCH__
-template<typename T>
-struct imag_impl<std::complex<T> >
-{
-  typedef T RealScalar;
-  EIGEN_DEVICE_FUNC
-  static inline T run(const std::complex<T>& x)
-  {
-    return x.imag();
-  }
-};
-#endif
-
-template<typename Scalar>
-struct imag_retval
-{
-  typedef typename NumTraits<Scalar>::Real type;
-};
-
-/****************************************************************************
-* Implementation of real_ref                                             *
-****************************************************************************/
-
-template<typename Scalar>
-struct real_ref_impl
-{
-  typedef typename NumTraits<Scalar>::Real RealScalar;
-  EIGEN_DEVICE_FUNC
-  static inline RealScalar& run(Scalar& x)
-  {
-    return reinterpret_cast<RealScalar*>(&x)[0];
-  }
-  EIGEN_DEVICE_FUNC
-  static inline const RealScalar& run(const Scalar& x)
-  {
-    return reinterpret_cast<const RealScalar*>(&x)[0];
-  }
-};
-
-template<typename Scalar>
-struct real_ref_retval
-{
-  typedef typename NumTraits<Scalar>::Real & type;
-};
-
-/****************************************************************************
-* Implementation of imag_ref                                             *
-****************************************************************************/
-
-template<typename Scalar, bool IsComplex>
-struct imag_ref_default_impl
-{
-  typedef typename NumTraits<Scalar>::Real RealScalar;
-  EIGEN_DEVICE_FUNC
-  static inline RealScalar& run(Scalar& x)
-  {
-    return reinterpret_cast<RealScalar*>(&x)[1];
-  }
-  EIGEN_DEVICE_FUNC
-  static inline const RealScalar& run(const Scalar& x)
-  {
-    return reinterpret_cast<RealScalar*>(&x)[1];
-  }
-};
-
-template<typename Scalar>
-struct imag_ref_default_impl<Scalar, false>
-{
-  EIGEN_DEVICE_FUNC
-  static inline Scalar run(Scalar&)
-  {
-    return Scalar(0);
-  }
-  EIGEN_DEVICE_FUNC
-  static inline const Scalar run(const Scalar&)
-  {
-    return Scalar(0);
-  }
-};
-
-template<typename Scalar>
-struct imag_ref_impl : imag_ref_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
-
-template<typename Scalar>
-struct imag_ref_retval
-{
-  typedef typename NumTraits<Scalar>::Real & type;
-};
-
-/****************************************************************************
-* Implementation of conj                                                 *
-****************************************************************************/
-
-template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
-struct conj_impl
-{
-  EIGEN_DEVICE_FUNC
-  static inline Scalar run(const Scalar& x)
-  {
-    return x;
-  }
-};
-
-template<typename Scalar>
-struct conj_impl<Scalar,true>
-{
-  EIGEN_DEVICE_FUNC
-  static inline Scalar run(const Scalar& x)
-  {
-    using std::conj;
-    return conj(x);
-  }
-};
-
-template<typename Scalar>
-struct conj_retval
-{
-  typedef Scalar type;
-};
-
-/****************************************************************************
-* Implementation of abs2                                                 *
-****************************************************************************/
-
-template<typename Scalar,bool IsComplex>
-struct abs2_impl_default
-{
-  typedef typename NumTraits<Scalar>::Real RealScalar;
-  EIGEN_DEVICE_FUNC
-  static inline RealScalar run(const Scalar& x)
-  {
-    return x*x;
-  }
-};
-
-template<typename Scalar>
-struct abs2_impl_default<Scalar, true> // IsComplex
-{
-  typedef typename NumTraits<Scalar>::Real RealScalar;
-  EIGEN_DEVICE_FUNC
-  static inline RealScalar run(const Scalar& x)
-  {
-    return real(x)*real(x) + imag(x)*imag(x);
-  }
-};
-
-template<typename Scalar>
-struct abs2_impl
-{
-  typedef typename NumTraits<Scalar>::Real RealScalar;
-  EIGEN_DEVICE_FUNC
-  static inline RealScalar run(const Scalar& x)
-  {
-    return abs2_impl_default<Scalar,NumTraits<Scalar>::IsComplex>::run(x);
-  }
-};
-
-template<typename Scalar>
-struct abs2_retval
-{
-  typedef typename NumTraits<Scalar>::Real type;
-};
-
-/****************************************************************************
-* Implementation of norm1                                                *
-****************************************************************************/
-
-template<typename Scalar, bool IsComplex>
-struct norm1_default_impl
-{
-  typedef typename NumTraits<Scalar>::Real RealScalar;
-  EIGEN_DEVICE_FUNC
-  static inline RealScalar run(const Scalar& x)
-  {
-    EIGEN_USING_STD_MATH(abs);
-    return abs(real(x)) + abs(imag(x));
-  }
-};
-
-template<typename Scalar>
-struct norm1_default_impl<Scalar, false>
-{
-  EIGEN_DEVICE_FUNC
-  static inline Scalar run(const Scalar& x)
-  {
-    EIGEN_USING_STD_MATH(abs);
-    return abs(x);
-  }
-};
-
-template<typename Scalar>
-struct norm1_impl : norm1_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
-
-template<typename Scalar>
-struct norm1_retval
-{
-  typedef typename NumTraits<Scalar>::Real type;
-};
-
-/****************************************************************************
-* Implementation of hypot                                                *
-****************************************************************************/
-
-template<typename Scalar> struct hypot_impl;
-
-template<typename Scalar>
-struct hypot_retval
-{
-  typedef typename NumTraits<Scalar>::Real type;
-};
-
-/****************************************************************************
-* Implementation of cast                                                 *
-****************************************************************************/
-
-template<typename OldType, typename NewType>
-struct cast_impl
-{
-  EIGEN_DEVICE_FUNC
-  static inline NewType run(const OldType& x)
-  {
-    return static_cast<NewType>(x);
-  }
-};
-
-// here, for once, we're plainly returning NewType: we don't want cast to do weird things.
-
-template<typename OldType, typename NewType>
-EIGEN_DEVICE_FUNC
-inline NewType cast(const OldType& x)
-{
-  return cast_impl<OldType, NewType>::run(x);
-}
-
-/****************************************************************************
-* Implementation of round                                                   *
-****************************************************************************/
-
-#if EIGEN_HAS_CXX11_MATH
-  template<typename Scalar>
-  struct round_impl {
-    static inline Scalar run(const Scalar& x)
-    {
-      EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
-      using std::round;
-      return round(x);
-    }
-  };
-#else
-  template<typename Scalar>
-  struct round_impl
-  {
-    static inline Scalar run(const Scalar& x)
-    {
-      EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
-      EIGEN_USING_STD_MATH(floor);
-      EIGEN_USING_STD_MATH(ceil);
-      return (x > Scalar(0)) ? floor(x + Scalar(0.5)) : ceil(x - Scalar(0.5));
-    }
-  };
-#endif
-
-template<typename Scalar>
-struct round_retval
-{
-  typedef Scalar type;
-};
-
-/****************************************************************************
-* Implementation of arg                                                     *
-****************************************************************************/
-
-#if EIGEN_HAS_CXX11_MATH
-  template<typename Scalar>
-  struct arg_impl {
-    static inline Scalar run(const Scalar& x)
-    {
-      EIGEN_USING_STD_MATH(arg);
-      return arg(x);
-    }
-  };
-#else
-  template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
-  struct arg_default_impl
-  {
-    typedef typename NumTraits<Scalar>::Real RealScalar;
-    EIGEN_DEVICE_FUNC
-    static inline RealScalar run(const Scalar& x)
-    {
-      return (x < Scalar(0)) ? Scalar(EIGEN_PI) : Scalar(0); }
-  };
-
-  template<typename Scalar>
-  struct arg_default_impl<Scalar,true>
-  {
-    typedef typename NumTraits<Scalar>::Real RealScalar;
-    EIGEN_DEVICE_FUNC
-    static inline RealScalar run(const Scalar& x)
-    {
-      EIGEN_USING_STD_MATH(arg);
-      return arg(x);
-    }
-  };
-
-  template<typename Scalar> struct arg_impl : arg_default_impl<Scalar> {};
-#endif
-
-template<typename Scalar>
-struct arg_retval
-{
-  typedef typename NumTraits<Scalar>::Real type;
-};
-
-/****************************************************************************
-* Implementation of log1p                                                   *
-****************************************************************************/
-
-namespace std_fallback {
-  // fallback log1p implementation in case there is no log1p(Scalar) function in namespace of Scalar,
-  // or that there is no suitable std::log1p function available
-  template<typename Scalar>
-  EIGEN_DEVICE_FUNC inline Scalar log1p(const Scalar& x) {
-    EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
-    typedef typename NumTraits<Scalar>::Real RealScalar;
-    EIGEN_USING_STD_MATH(log);
-    Scalar x1p = RealScalar(1) + x;
-    return numext::equal_strict(x1p, Scalar(1)) ? x : x * ( log(x1p) / (x1p - RealScalar(1)) );
-  }
-}
-
-template<typename Scalar>
-struct log1p_impl {
-  static inline Scalar run(const Scalar& x)
-  {
-    EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
-    #if EIGEN_HAS_CXX11_MATH
-    using std::log1p;
-    #endif
-    using std_fallback::log1p;
-    return log1p(x);
-  }
-};
-
-
-template<typename Scalar>
-struct log1p_retval
-{
-  typedef Scalar type;
-};
-
-/****************************************************************************
-* Implementation of pow                                                  *
-****************************************************************************/
-
-template<typename ScalarX,typename ScalarY, bool IsInteger = NumTraits<ScalarX>::IsInteger&&NumTraits<ScalarY>::IsInteger>
-struct pow_impl
-{
-  //typedef Scalar retval;
-  typedef typename ScalarBinaryOpTraits<ScalarX,ScalarY,internal::scalar_pow_op<ScalarX,ScalarY> >::ReturnType result_type;
-  static EIGEN_DEVICE_FUNC inline result_type run(const ScalarX& x, const ScalarY& y)
-  {
-    EIGEN_USING_STD_MATH(pow);
-    return pow(x, y);
-  }
-};
-
-template<typename ScalarX,typename ScalarY>
-struct pow_impl<ScalarX,ScalarY, true>
-{
-  typedef ScalarX result_type;
-  static EIGEN_DEVICE_FUNC inline ScalarX run(ScalarX x, ScalarY y)
-  {
-    ScalarX res(1);
-    eigen_assert(!NumTraits<ScalarY>::IsSigned || y >= 0);
-    if(y & 1) res *= x;
-    y >>= 1;
-    while(y)
-    {
-      x *= x;
-      if(y&1) res *= x;
-      y >>= 1;
-    }
-    return res;
-  }
-};
-
-/****************************************************************************
-* Implementation of random                                               *
-****************************************************************************/
-
-template<typename Scalar,
-         bool IsComplex,
-         bool IsInteger>
-struct random_default_impl {};
-
-template<typename Scalar>
-struct random_impl : random_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
-
-template<typename Scalar>
-struct random_retval
-{
-  typedef Scalar type;
-};
-
-template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y);
-template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random();
-
-template<typename Scalar>
-struct random_default_impl<Scalar, false, false>
-{
-  static inline Scalar run(const Scalar& x, const Scalar& y)
-  {
-    return x + (y-x) * Scalar(std::rand()) / Scalar(RAND_MAX);
-  }
-  static inline Scalar run()
-  {
-    return run(Scalar(NumTraits<Scalar>::IsSigned ? -1 : 0), Scalar(1));
-  }
-};
-
-enum {
-  meta_floor_log2_terminate,
-  meta_floor_log2_move_up,
-  meta_floor_log2_move_down,
-  meta_floor_log2_bogus
-};
-
-template<unsigned int n, int lower, int upper> struct meta_floor_log2_selector
-{
-  enum { middle = (lower + upper) / 2,
-         value = (upper <= lower + 1) ? int(meta_floor_log2_terminate)
-               : (n < (1 << middle)) ? int(meta_floor_log2_move_down)
-               : (n==0) ? int(meta_floor_log2_bogus)
-               : int(meta_floor_log2_move_up)
-  };
-};
-
-template<unsigned int n,
-         int lower = 0,
-         int upper = sizeof(unsigned int) * CHAR_BIT - 1,
-         int selector = meta_floor_log2_selector<n, lower, upper>::value>
-struct meta_floor_log2 {};
-
-template<unsigned int n, int lower, int upper>
-struct meta_floor_log2<n, lower, upper, meta_floor_log2_move_down>
-{
-  enum { value = meta_floor_log2<n, lower, meta_floor_log2_selector<n, lower, upper>::middle>::value };
-};
-
-template<unsigned int n, int lower, int upper>
-struct meta_floor_log2<n, lower, upper, meta_floor_log2_move_up>
-{
-  enum { value = meta_floor_log2<n, meta_floor_log2_selector<n, lower, upper>::middle, upper>::value };
-};
-
-template<unsigned int n, int lower, int upper>
-struct meta_floor_log2<n, lower, upper, meta_floor_log2_terminate>
-{
-  enum { value = (n >= ((unsigned int)(1) << (lower+1))) ? lower+1 : lower };
-};
-
-template<unsigned int n, int lower, int upper>
-struct meta_floor_log2<n, lower, upper, meta_floor_log2_bogus>
-{
-  // no value, error at compile time
-};
-
-template<typename Scalar>
-struct random_default_impl<Scalar, false, true>
-{
-  static inline Scalar run(const Scalar& x, const Scalar& y)
-  {
-    if (y <= x)
-      return x;
-    // ScalarU is the unsigned counterpart of Scalar, possibly Scalar itself.
-    typedef typename make_unsigned<Scalar>::type ScalarU;
-    // ScalarX is the widest of ScalarU and unsigned int.
-    // We'll deal only with ScalarX and unsigned int below thus avoiding signed
-    // types and arithmetic and signed overflows (which are undefined behavior).
-    typedef typename conditional<(ScalarU(-1) > unsigned(-1)), ScalarU, unsigned>::type ScalarX;
-    // The following difference doesn't overflow, provided our integer types are two's
-    // complement and have the same number of padding bits in signed and unsigned variants.
-    // This is the case in most modern implementations of C++.
-    ScalarX range = ScalarX(y) - ScalarX(x);
-    ScalarX offset = 0;
-    ScalarX divisor = 1;
-    ScalarX multiplier = 1;
-    const unsigned rand_max = RAND_MAX;
-    if (range <= rand_max) divisor = (rand_max + 1) / (range + 1);
-    else                   multiplier = 1 + range / (rand_max + 1);
-    // Rejection sampling.
-    do {
-      offset = (unsigned(std::rand()) * multiplier) / divisor;
-    } while (offset > range);
-    return Scalar(ScalarX(x) + offset);
-  }
-
-  static inline Scalar run()
-  {
-#ifdef EIGEN_MAKING_DOCS
-    return run(Scalar(NumTraits<Scalar>::IsSigned ? -10 : 0), Scalar(10));
-#else
-    enum { rand_bits = meta_floor_log2<(unsigned int)(RAND_MAX)+1>::value,
-           scalar_bits = sizeof(Scalar) * CHAR_BIT,
-           shift = EIGEN_PLAIN_ENUM_MAX(0, int(rand_bits) - int(scalar_bits)),
-           offset = NumTraits<Scalar>::IsSigned ? (1 << (EIGEN_PLAIN_ENUM_MIN(rand_bits,scalar_bits)-1)) : 0
-    };
-    return Scalar((std::rand() >> shift) - offset);
-#endif
-  }
-};
-
-template<typename Scalar>
-struct random_default_impl<Scalar, true, false>
-{
-  static inline Scalar run(const Scalar& x, const Scalar& y)
-  {
-    return Scalar(random(real(x), real(y)),
-                  random(imag(x), imag(y)));
-  }
-  static inline Scalar run()
-  {
-    typedef typename NumTraits<Scalar>::Real RealScalar;
-    return Scalar(random<RealScalar>(), random<RealScalar>());
-  }
-};
-
-template<typename Scalar>
-inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y)
-{
-  return EIGEN_MATHFUNC_IMPL(random, Scalar)::run(x, y);
-}
-
-template<typename Scalar>
-inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random()
-{
-  return EIGEN_MATHFUNC_IMPL(random, Scalar)::run();
-}
-
-// Implementatin of is* functions
-
-// std::is* do not work with fast-math and gcc, std::is* are available on MSVC 2013 and newer, as well as in clang.
-#if (EIGEN_HAS_CXX11_MATH && !(EIGEN_COMP_GNUC_STRICT && __FINITE_MATH_ONLY__)) || (EIGEN_COMP_MSVC>=1800) || (EIGEN_COMP_CLANG)
-#define EIGEN_USE_STD_FPCLASSIFY 1
-#else
-#define EIGEN_USE_STD_FPCLASSIFY 0
-#endif
-
-template<typename T>
-EIGEN_DEVICE_FUNC
-typename internal::enable_if<internal::is_integral<T>::value,bool>::type
-isnan_impl(const T&) { return false; }
-
-template<typename T>
-EIGEN_DEVICE_FUNC
-typename internal::enable_if<internal::is_integral<T>::value,bool>::type
-isinf_impl(const T&) { return false; }
-
-template<typename T>
-EIGEN_DEVICE_FUNC
-typename internal::enable_if<internal::is_integral<T>::value,bool>::type
-isfinite_impl(const T&) { return true; }
-
-template<typename T>
-EIGEN_DEVICE_FUNC
-typename internal::enable_if<(!internal::is_integral<T>::value)&&(!NumTraits<T>::IsComplex),bool>::type
-isfinite_impl(const T& x)
-{
-  #ifdef __CUDA_ARCH__
-    return (::isfinite)(x);
-  #elif EIGEN_USE_STD_FPCLASSIFY
-    using std::isfinite;
-    return isfinite EIGEN_NOT_A_MACRO (x);
-  #else
-    return x<=NumTraits<T>::highest() && x>=NumTraits<T>::lowest();
-  #endif
-}
-
-template<typename T>
-EIGEN_DEVICE_FUNC
-typename internal::enable_if<(!internal::is_integral<T>::value)&&(!NumTraits<T>::IsComplex),bool>::type
-isinf_impl(const T& x)
-{
-  #ifdef __CUDA_ARCH__
-    return (::isinf)(x);
-  #elif EIGEN_USE_STD_FPCLASSIFY
-    using std::isinf;
-    return isinf EIGEN_NOT_A_MACRO (x);
-  #else
-    return x>NumTraits<T>::highest() || x<NumTraits<T>::lowest();
-  #endif
-}
-
-template<typename T>
-EIGEN_DEVICE_FUNC
-typename internal::enable_if<(!internal::is_integral<T>::value)&&(!NumTraits<T>::IsComplex),bool>::type
-isnan_impl(const T& x)
-{
-  #ifdef __CUDA_ARCH__
-    return (::isnan)(x);
-  #elif EIGEN_USE_STD_FPCLASSIFY
-    using std::isnan;
-    return isnan EIGEN_NOT_A_MACRO (x);
-  #else
-    return x != x;
-  #endif
-}
-
-#if (!EIGEN_USE_STD_FPCLASSIFY)
-
-#if EIGEN_COMP_MSVC
-
-template<typename T> EIGEN_DEVICE_FUNC bool isinf_msvc_helper(T x)
-{
-  return _fpclass(x)==_FPCLASS_NINF || _fpclass(x)==_FPCLASS_PINF;
-}
-
-//MSVC defines a _isnan builtin function, but for double only
-EIGEN_DEVICE_FUNC inline bool isnan_impl(const long double& x) { return _isnan(x)!=0; }
-EIGEN_DEVICE_FUNC inline bool isnan_impl(const double& x)      { return _isnan(x)!=0; }
-EIGEN_DEVICE_FUNC inline bool isnan_impl(const float& x)       { return _isnan(x)!=0; }
-
-EIGEN_DEVICE_FUNC inline bool isinf_impl(const long double& x) { return isinf_msvc_helper(x); }
-EIGEN_DEVICE_FUNC inline bool isinf_impl(const double& x)      { return isinf_msvc_helper(x); }
-EIGEN_DEVICE_FUNC inline bool isinf_impl(const float& x)       { return isinf_msvc_helper(x); }
-
-#elif (defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ && EIGEN_COMP_GNUC)
-
-#if EIGEN_GNUC_AT_LEAST(5,0)
-  #define EIGEN_TMP_NOOPT_ATTRIB EIGEN_DEVICE_FUNC inline __attribute__((optimize("no-finite-math-only")))
-#else
-  // NOTE the inline qualifier and noinline attribute are both needed: the former is to avoid linking issue (duplicate symbol),
-  //      while the second prevent too aggressive optimizations in fast-math mode:
-  #define EIGEN_TMP_NOOPT_ATTRIB EIGEN_DEVICE_FUNC inline __attribute__((noinline,optimize("no-finite-math-only")))
-#endif
-
-template<> EIGEN_TMP_NOOPT_ATTRIB bool isnan_impl(const long double& x) { return __builtin_isnan(x); }
-template<> EIGEN_TMP_NOOPT_ATTRIB bool isnan_impl(const double& x)      { return __builtin_isnan(x); }
-template<> EIGEN_TMP_NOOPT_ATTRIB bool isnan_impl(const float& x)       { return __builtin_isnan(x); }
-template<> EIGEN_TMP_NOOPT_ATTRIB bool isinf_impl(const double& x)      { return __builtin_isinf(x); }
-template<> EIGEN_TMP_NOOPT_ATTRIB bool isinf_impl(const float& x)       { return __builtin_isinf(x); }
-template<> EIGEN_TMP_NOOPT_ATTRIB bool isinf_impl(const long double& x) { return __builtin_isinf(x); }
-
-#undef EIGEN_TMP_NOOPT_ATTRIB
-
-#endif
-
-#endif
-
-// The following overload are defined at the end of this file
-template<typename T> EIGEN_DEVICE_FUNC bool isfinite_impl(const std::complex<T>& x);
-template<typename T> EIGEN_DEVICE_FUNC bool isnan_impl(const std::complex<T>& x);
-template<typename T> EIGEN_DEVICE_FUNC bool isinf_impl(const std::complex<T>& x);
-
-template<typename T> T generic_fast_tanh_float(const T& a_x);
-
-} // end namespace internal
-
-/****************************************************************************
-* Generic math functions                                                    *
-****************************************************************************/
-
-namespace numext {
-
-#ifndef __CUDA_ARCH__
-template<typename T>
-EIGEN_DEVICE_FUNC
-EIGEN_ALWAYS_INLINE T mini(const T& x, const T& y)
-{
-  EIGEN_USING_STD_MATH(min);
-  return min EIGEN_NOT_A_MACRO (x,y);
-}
-
-template<typename T>
-EIGEN_DEVICE_FUNC
-EIGEN_ALWAYS_INLINE T maxi(const T& x, const T& y)
-{
-  EIGEN_USING_STD_MATH(max);
-  return max EIGEN_NOT_A_MACRO (x,y);
-}
-#else
-template<typename T>
-EIGEN_DEVICE_FUNC
-EIGEN_ALWAYS_INLINE T mini(const T& x, const T& y)
-{
-  return y < x ? y : x;
-}
-template<>
-EIGEN_DEVICE_FUNC
-EIGEN_ALWAYS_INLINE float mini(const float& x, const float& y)
-{
-  return fminf(x, y);
-}
-template<typename T>
-EIGEN_DEVICE_FUNC
-EIGEN_ALWAYS_INLINE T maxi(const T& x, const T& y)
-{
-  return x < y ? y : x;
-}
-template<>
-EIGEN_DEVICE_FUNC
-EIGEN_ALWAYS_INLINE float maxi(const float& x, const float& y)
-{
-  return fmaxf(x, y);
-}
-#endif
-
-
-template<typename Scalar>
-EIGEN_DEVICE_FUNC
-inline EIGEN_MATHFUNC_RETVAL(real, Scalar) real(const Scalar& x)
-{
-  return EIGEN_MATHFUNC_IMPL(real, Scalar)::run(x);
-}
-
-template<typename Scalar>
-EIGEN_DEVICE_FUNC
-inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) >::type real_ref(const Scalar& x)
-{
-  return internal::real_ref_impl<Scalar>::run(x);
-}
-
-template<typename Scalar>
-EIGEN_DEVICE_FUNC
-inline EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) real_ref(Scalar& x)
-{
-  return EIGEN_MATHFUNC_IMPL(real_ref, Scalar)::run(x);
-}
-
-template<typename Scalar>
-EIGEN_DEVICE_FUNC
-inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x)
-{
-  return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x);
-}
-
-template<typename Scalar>
-EIGEN_DEVICE_FUNC
-inline EIGEN_MATHFUNC_RETVAL(arg, Scalar) arg(const Scalar& x)
-{
-  return EIGEN_MATHFUNC_IMPL(arg, Scalar)::run(x);
-}
-
-template<typename Scalar>
-EIGEN_DEVICE_FUNC
-inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type imag_ref(const Scalar& x)
-{
-  return internal::imag_ref_impl<Scalar>::run(x);
-}
-
-template<typename Scalar>
-EIGEN_DEVICE_FUNC
-inline EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) imag_ref(Scalar& x)
-{
-  return EIGEN_MATHFUNC_IMPL(imag_ref, Scalar)::run(x);
-}
-
-template<typename Scalar>
-EIGEN_DEVICE_FUNC
-inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x)
-{
-  return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x);
-}
-
-template<typename Scalar>
-EIGEN_DEVICE_FUNC
-inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x)
-{
-  return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x);
-}
-
-template<typename Scalar>
-EIGEN_DEVICE_FUNC
-inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(const Scalar& x)
-{
-  return EIGEN_MATHFUNC_IMPL(norm1, Scalar)::run(x);
-}
-
-template<typename Scalar>
-EIGEN_DEVICE_FUNC
-inline EIGEN_MATHFUNC_RETVAL(hypot, Scalar) hypot(const Scalar& x, const Scalar& y)
-{
-  return EIGEN_MATHFUNC_IMPL(hypot, Scalar)::run(x, y);
-}
-
-template<typename Scalar>
-EIGEN_DEVICE_FUNC
-inline EIGEN_MATHFUNC_RETVAL(log1p, Scalar) log1p(const Scalar& x)
-{
-  return EIGEN_MATHFUNC_IMPL(log1p, Scalar)::run(x);
-}
-
-#ifdef __CUDACC__
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-float log1p(const float &x) { return ::log1pf(x); }
-
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-double log1p(const double &x) { return ::log1p(x); }
-#endif
-
-template<typename ScalarX,typename ScalarY>
-EIGEN_DEVICE_FUNC
-inline typename internal::pow_impl<ScalarX,ScalarY>::result_type pow(const ScalarX& x, const ScalarY& y)
-{
-  return internal::pow_impl<ScalarX,ScalarY>::run(x, y);
-}
-
-template<typename T> EIGEN_DEVICE_FUNC bool (isnan)   (const T &x) { return internal::isnan_impl(x); }
-template<typename T> EIGEN_DEVICE_FUNC bool (isinf)   (const T &x) { return internal::isinf_impl(x); }
-template<typename T> EIGEN_DEVICE_FUNC bool (isfinite)(const T &x) { return internal::isfinite_impl(x); }
-
-template<typename Scalar>
-EIGEN_DEVICE_FUNC
-inline EIGEN_MATHFUNC_RETVAL(round, Scalar) round(const Scalar& x)
-{
-  return EIGEN_MATHFUNC_IMPL(round, Scalar)::run(x);
-}
-
-template<typename T>
-EIGEN_DEVICE_FUNC
-T (floor)(const T& x)
-{
-  EIGEN_USING_STD_MATH(floor);
-  return floor(x);
-}
-
-#ifdef __CUDACC__
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-float floor(const float &x) { return ::floorf(x); }
-
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-double floor(const double &x) { return ::floor(x); }
-#endif
-
-template<typename T>
-EIGEN_DEVICE_FUNC
-T (ceil)(const T& x)
-{
-  EIGEN_USING_STD_MATH(ceil);
-  return ceil(x);
-}
-
-#ifdef __CUDACC__
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-float ceil(const float &x) { return ::ceilf(x); }
-
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-double ceil(const double &x) { return ::ceil(x); }
-#endif
-
-
-/** Log base 2 for 32 bits positive integers.
-  * Conveniently returns 0 for x==0. */
-inline int log2(int x)
-{
-  eigen_assert(x>=0);
-  unsigned int v(x);
-  static const int table[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
-  v |= v >> 1;
-  v |= v >> 2;
-  v |= v >> 4;
-  v |= v >> 8;
-  v |= v >> 16;
-  return table[(v * 0x07C4ACDDU) >> 27];
-}
-
-/** \returns the square root of \a x.
-  *
-  * It is essentially equivalent to
-  * \code using std::sqrt; return sqrt(x); \endcode
-  * but slightly faster for float/double and some compilers (e.g., gcc), thanks to
-  * specializations when SSE is enabled.
-  *
-  * It's usage is justified in performance critical functions, like norm/normalize.
-  */
-template<typename T>
-EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-T sqrt(const T &x)
-{
-  EIGEN_USING_STD_MATH(sqrt);
-  return sqrt(x);
-}
-
-template<typename T>
-EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-T log(const T &x) {
-  EIGEN_USING_STD_MATH(log);
-  return log(x);
-}
-
-#ifdef __CUDACC__
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-float log(const float &x) { return ::logf(x); }
-
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-double log(const double &x) { return ::log(x); }
-#endif
-
-template<typename T>
-EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-typename internal::enable_if<NumTraits<T>::IsSigned || NumTraits<T>::IsComplex,typename NumTraits<T>::Real>::type
-abs(const T &x) {
-  EIGEN_USING_STD_MATH(abs);
-  return abs(x);
-}
-
-template<typename T>
-EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-typename internal::enable_if<!(NumTraits<T>::IsSigned || NumTraits<T>::IsComplex),typename NumTraits<T>::Real>::type
-abs(const T &x) {
-  return x;
-}
-
-#if defined(__SYCL_DEVICE_ONLY__)
-EIGEN_ALWAYS_INLINE float   abs(float x) { return cl::sycl::fabs(x); }
-EIGEN_ALWAYS_INLINE double  abs(double x) { return cl::sycl::fabs(x); }
-#endif // defined(__SYCL_DEVICE_ONLY__)
-
-#ifdef __CUDACC__
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-float abs(const float &x) { return ::fabsf(x); }
-
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-double abs(const double &x) { return ::fabs(x); }
-
-template <> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-float abs(const std::complex<float>& x) {
-  return ::hypotf(x.real(), x.imag());
-}
-
-template <> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-double abs(const std::complex<double>& x) {
-  return ::hypot(x.real(), x.imag());
-}
-#endif
-
-template<typename T>
-EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-T exp(const T &x) {
-  EIGEN_USING_STD_MATH(exp);
-  return exp(x);
-}
-
-#ifdef __CUDACC__
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-float exp(const float &x) { return ::expf(x); }
-
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-double exp(const double &x) { return ::exp(x); }
-#endif
-
-template<typename T>
-EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-T cos(const T &x) {
-  EIGEN_USING_STD_MATH(cos);
-  return cos(x);
-}
-
-#ifdef __CUDACC__
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-float cos(const float &x) { return ::cosf(x); }
-
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-double cos(const double &x) { return ::cos(x); }
-#endif
-
-template<typename T>
-EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-T sin(const T &x) {
-  EIGEN_USING_STD_MATH(sin);
-  return sin(x);
-}
-
-#ifdef __CUDACC__
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-float sin(const float &x) { return ::sinf(x); }
-
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-double sin(const double &x) { return ::sin(x); }
-#endif
-
-template<typename T>
-EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-T tan(const T &x) {
-  EIGEN_USING_STD_MATH(tan);
-  return tan(x);
-}
-
-#ifdef __CUDACC__
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-float tan(const float &x) { return ::tanf(x); }
-
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-double tan(const double &x) { return ::tan(x); }
-#endif
-
-template<typename T>
-EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-T acos(const T &x) {
-  EIGEN_USING_STD_MATH(acos);
-  return acos(x);
-}
-
-#ifdef __CUDACC__
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-float acos(const float &x) { return ::acosf(x); }
-
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-double acos(const double &x) { return ::acos(x); }
-#endif
-
-template<typename T>
-EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-T asin(const T &x) {
-  EIGEN_USING_STD_MATH(asin);
-  return asin(x);
-}
-
-#ifdef __CUDACC__
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-float asin(const float &x) { return ::asinf(x); }
-
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-double asin(const double &x) { return ::asin(x); }
-#endif
-
-template<typename T>
-EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-T atan(const T &x) {
-  EIGEN_USING_STD_MATH(atan);
-  return atan(x);
-}
-
-#ifdef __CUDACC__
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-float atan(const float &x) { return ::atanf(x); }
-
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-double atan(const double &x) { return ::atan(x); }
-#endif
-
-
-template<typename T>
-EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-T cosh(const T &x) {
-  EIGEN_USING_STD_MATH(cosh);
-  return cosh(x);
-}
-
-#ifdef __CUDACC__
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-float cosh(const float &x) { return ::coshf(x); }
-
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-double cosh(const double &x) { return ::cosh(x); }
-#endif
-
-template<typename T>
-EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-T sinh(const T &x) {
-  EIGEN_USING_STD_MATH(sinh);
-  return sinh(x);
-}
-
-#ifdef __CUDACC__
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-float sinh(const float &x) { return ::sinhf(x); }
-
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-double sinh(const double &x) { return ::sinh(x); }
-#endif
-
-template<typename T>
-EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-T tanh(const T &x) {
-  EIGEN_USING_STD_MATH(tanh);
-  return tanh(x);
-}
-
-#if (!defined(__CUDACC__)) && EIGEN_FAST_MATH
-EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-float tanh(float x) { return internal::generic_fast_tanh_float(x); }
-#endif
-
-#ifdef __CUDACC__
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-float tanh(const float &x) { return ::tanhf(x); }
-
-template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-double tanh(const double &x) { return ::tanh(x); }
-#endif
-
-template <typename T>
-EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-T fmod(const T& a, const T& b) {
-  EIGEN_USING_STD_MATH(fmod);
-  return fmod(a, b);
-}
-
-#ifdef __CUDACC__
-template <>
-EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-float fmod(const float& a, const float& b) {
-  return ::fmodf(a, b);
-}
-
-template <>
-EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-double fmod(const double& a, const double& b) {
-  return ::fmod(a, b);
-}
-#endif
-
-} // end namespace numext
-
-namespace internal {
-
-template<typename T>
-EIGEN_DEVICE_FUNC bool isfinite_impl(const std::complex<T>& x)
-{
-  return (numext::isfinite)(numext::real(x)) && (numext::isfinite)(numext::imag(x));
-}
-
-template<typename T>
-EIGEN_DEVICE_FUNC bool isnan_impl(const std::complex<T>& x)
-{
-  return (numext::isnan)(numext::real(x)) || (numext::isnan)(numext::imag(x));
-}
-
-template<typename T>
-EIGEN_DEVICE_FUNC bool isinf_impl(const std::complex<T>& x)
-{
-  return ((numext::isinf)(numext::real(x)) || (numext::isinf)(numext::imag(x))) && (!(numext::isnan)(x));
-}
-
-/****************************************************************************
-* Implementation of fuzzy comparisons                                       *
-****************************************************************************/
-
-template<typename Scalar,
-         bool IsComplex,
-         bool IsInteger>
-struct scalar_fuzzy_default_impl {};
-
-template<typename Scalar>
-struct scalar_fuzzy_default_impl<Scalar, false, false>
-{
-  typedef typename NumTraits<Scalar>::Real RealScalar;
-  template<typename OtherScalar> EIGEN_DEVICE_FUNC
-  static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec)
-  {
-    return numext::abs(x) <= numext::abs(y) * prec;
-  }
-  EIGEN_DEVICE_FUNC
-  static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
-  {
-    return numext::abs(x - y) <= numext::mini(numext::abs(x), numext::abs(y)) * prec;
-  }
-  EIGEN_DEVICE_FUNC
-  static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar& prec)
-  {
-    return x <= y || isApprox(x, y, prec);
-  }
-};
-
-template<typename Scalar>
-struct scalar_fuzzy_default_impl<Scalar, false, true>
-{
-  typedef typename NumTraits<Scalar>::Real RealScalar;
-  template<typename OtherScalar> EIGEN_DEVICE_FUNC
-  static inline bool isMuchSmallerThan(const Scalar& x, const Scalar&, const RealScalar&)
-  {
-    return x == Scalar(0);
-  }
-  EIGEN_DEVICE_FUNC
-  static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar&)
-  {
-    return x == y;
-  }
-  EIGEN_DEVICE_FUNC
-  static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar&)
-  {
-    return x <= y;
-  }
-};
-
-template<typename Scalar>
-struct scalar_fuzzy_default_impl<Scalar, true, false>
-{
-  typedef typename NumTraits<Scalar>::Real RealScalar;
-  template<typename OtherScalar> EIGEN_DEVICE_FUNC
-  static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec)
-  {
-    return numext::abs2(x) <= numext::abs2(y) * prec * prec;
-  }
-  EIGEN_DEVICE_FUNC
-  static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
-  {
-    return numext::abs2(x - y) <= numext::mini(numext::abs2(x), numext::abs2(y)) * prec * prec;
-  }
-};
-
-template<typename Scalar>
-struct scalar_fuzzy_impl : scalar_fuzzy_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
-
-template<typename Scalar, typename OtherScalar> EIGEN_DEVICE_FUNC
-inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y,
-                              const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
-{
-  return scalar_fuzzy_impl<Scalar>::template isMuchSmallerThan<OtherScalar>(x, y, precision);
-}
-
-template<typename Scalar> EIGEN_DEVICE_FUNC
-inline bool isApprox(const Scalar& x, const Scalar& y,
-                     const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
-{
-  return scalar_fuzzy_impl<Scalar>::isApprox(x, y, precision);
-}
-
-template<typename Scalar> EIGEN_DEVICE_FUNC
-inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y,
-                               const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
-{
-  return scalar_fuzzy_impl<Scalar>::isApproxOrLessThan(x, y, precision);
-}
-
-/******************************************
-***  The special case of the  bool type ***
-******************************************/
-
-template<> struct random_impl<bool>
-{
-  static inline bool run()
-  {
-    return random<int>(0,1)==0 ? false : true;
-  }
-};
-
-template<> struct scalar_fuzzy_impl<bool>
-{
-  typedef bool RealScalar;
-  
-  template<typename OtherScalar> EIGEN_DEVICE_FUNC
-  static inline bool isMuchSmallerThan(const bool& x, const bool&, const bool&)
-  {
-    return !x;
-  }
-  
-  EIGEN_DEVICE_FUNC
-  static inline bool isApprox(bool x, bool y, bool)
-  {
-    return x == y;
-  }
-
-  EIGEN_DEVICE_FUNC
-  static inline bool isApproxOrLessThan(const bool& x, const bool& y, const bool&)
-  {
-    return (!x) || y;
-  }
-  
-};
-
-  
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_MATHFUNCTIONS_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/MathFunctionsImpl.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/MathFunctionsImpl.h
deleted file mode 100644
index 9c1ceb0..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/MathFunctionsImpl.h
+++ /dev/null
@@ -1,101 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2014 Pedro Gonnet (pedro.gonnet@gmail.com)
-// Copyright (C) 2016 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_MATHFUNCTIONSIMPL_H
-#define EIGEN_MATHFUNCTIONSIMPL_H
-
-namespace Eigen {
-
-namespace internal {
-
-/** \internal \returns the hyperbolic tan of \a a (coeff-wise)
-    Doesn't do anything fancy, just a 13/6-degree rational interpolant which
-    is accurate up to a couple of ulp in the range [-9, 9], outside of which
-    the tanh(x) = +/-1.
-
-    This implementation works on both scalars and packets.
-*/
-template<typename T>
-T generic_fast_tanh_float(const T& a_x)
-{
-  // Clamp the inputs to the range [-9, 9] since anything outside
-  // this range is +/-1.0f in single-precision.
-  const T plus_9 = pset1<T>(9.f);
-  const T minus_9 = pset1<T>(-9.f);
-  // NOTE GCC prior to 6.3 might improperly optimize this max/min
-  //      step such that if a_x is nan, x will be either 9 or -9,
-  //      and tanh will return 1 or -1 instead of nan.
-  //      This is supposed to be fixed in gcc6.3,
-  //      see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72867
-  const T x = pmax(minus_9,pmin(plus_9,a_x));
-  // The monomial coefficients of the numerator polynomial (odd).
-  const T alpha_1 = pset1<T>(4.89352455891786e-03f);
-  const T alpha_3 = pset1<T>(6.37261928875436e-04f);
-  const T alpha_5 = pset1<T>(1.48572235717979e-05f);
-  const T alpha_7 = pset1<T>(5.12229709037114e-08f);
-  const T alpha_9 = pset1<T>(-8.60467152213735e-11f);
-  const T alpha_11 = pset1<T>(2.00018790482477e-13f);
-  const T alpha_13 = pset1<T>(-2.76076847742355e-16f);
-
-  // The monomial coefficients of the denominator polynomial (even).
-  const T beta_0 = pset1<T>(4.89352518554385e-03f);
-  const T beta_2 = pset1<T>(2.26843463243900e-03f);
-  const T beta_4 = pset1<T>(1.18534705686654e-04f);
-  const T beta_6 = pset1<T>(1.19825839466702e-06f);
-
-  // Since the polynomials are odd/even, we need x^2.
-  const T x2 = pmul(x, x);
-
-  // Evaluate the numerator polynomial p.
-  T p = pmadd(x2, alpha_13, alpha_11);
-  p = pmadd(x2, p, alpha_9);
-  p = pmadd(x2, p, alpha_7);
-  p = pmadd(x2, p, alpha_5);
-  p = pmadd(x2, p, alpha_3);
-  p = pmadd(x2, p, alpha_1);
-  p = pmul(x, p);
-
-  // Evaluate the denominator polynomial p.
-  T q = pmadd(x2, beta_6, beta_4);
-  q = pmadd(x2, q, beta_2);
-  q = pmadd(x2, q, beta_0);
-
-  // Divide the numerator by the denominator.
-  return pdiv(p, q);
-}
-
-template<typename RealScalar>
-EIGEN_STRONG_INLINE
-RealScalar positive_real_hypot(const RealScalar& x, const RealScalar& y)
-{
-  EIGEN_USING_STD_MATH(sqrt);
-  RealScalar p, qp;
-  p = numext::maxi(x,y);
-  if(p==RealScalar(0)) return RealScalar(0);
-  qp = numext::mini(y,x) / p;    
-  return p * sqrt(RealScalar(1) + qp*qp);
-}
-
-template<typename Scalar>
-struct hypot_impl
-{
-  typedef typename NumTraits<Scalar>::Real RealScalar;
-  static inline RealScalar run(const Scalar& x, const Scalar& y)
-  {
-    EIGEN_USING_STD_MATH(abs);
-    return positive_real_hypot<RealScalar>(abs(x), abs(y));
-  }
-};
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_MATHFUNCTIONSIMPL_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Matrix.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Matrix.h
deleted file mode 100644
index 7f4a7af..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Matrix.h
+++ /dev/null
@@ -1,459 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_MATRIX_H
-#define EIGEN_MATRIX_H
-
-namespace Eigen {
-
-namespace internal {
-template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
-struct traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
-{
-private:
-  enum { size = internal::size_at_compile_time<_Rows,_Cols>::ret };
-  typedef typename find_best_packet<_Scalar,size>::type PacketScalar;
-  enum {
-      row_major_bit = _Options&RowMajor ? RowMajorBit : 0,
-      is_dynamic_size_storage = _MaxRows==Dynamic || _MaxCols==Dynamic,
-      max_size = is_dynamic_size_storage ? Dynamic : _MaxRows*_MaxCols,
-      default_alignment = compute_default_alignment<_Scalar,max_size>::value,
-      actual_alignment = ((_Options&DontAlign)==0) ? default_alignment : 0,
-      required_alignment = unpacket_traits<PacketScalar>::alignment,
-      packet_access_bit = (packet_traits<_Scalar>::Vectorizable && (EIGEN_UNALIGNED_VECTORIZE || (actual_alignment>=required_alignment))) ? PacketAccessBit : 0
-    };
-    
-public:
-  typedef _Scalar Scalar;
-  typedef Dense StorageKind;
-  typedef Eigen::Index StorageIndex;
-  typedef MatrixXpr XprKind;
-  enum {
-    RowsAtCompileTime = _Rows,
-    ColsAtCompileTime = _Cols,
-    MaxRowsAtCompileTime = _MaxRows,
-    MaxColsAtCompileTime = _MaxCols,
-    Flags = compute_matrix_flags<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::ret,
-    Options = _Options,
-    InnerStrideAtCompileTime = 1,
-    OuterStrideAtCompileTime = (Options&RowMajor) ? ColsAtCompileTime : RowsAtCompileTime,
-    
-    // FIXME, the following flag in only used to define NeedsToAlign in PlainObjectBase
-    EvaluatorFlags = LinearAccessBit | DirectAccessBit | packet_access_bit | row_major_bit,
-    Alignment = actual_alignment
-  };
-};
-}
-
-/** \class Matrix
-  * \ingroup Core_Module
-  *
-  * \brief The matrix class, also used for vectors and row-vectors
-  *
-  * The %Matrix class is the work-horse for all \em dense (\ref dense "note") matrices and vectors within Eigen.
-  * Vectors are matrices with one column, and row-vectors are matrices with one row.
-  *
-  * The %Matrix class encompasses \em both fixed-size and dynamic-size objects (\ref fixedsize "note").
-  *
-  * The first three template parameters are required:
-  * \tparam _Scalar Numeric type, e.g. float, double, int or std::complex<float>.
-  *                 User defined scalar types are supported as well (see \ref user_defined_scalars "here").
-  * \tparam _Rows Number of rows, or \b Dynamic
-  * \tparam _Cols Number of columns, or \b Dynamic
-  *
-  * The remaining template parameters are optional -- in most cases you don't have to worry about them.
-  * \tparam _Options A combination of either \b #RowMajor or \b #ColMajor, and of either
-  *                 \b #AutoAlign or \b #DontAlign.
-  *                 The former controls \ref TopicStorageOrders "storage order", and defaults to column-major. The latter controls alignment, which is required
-  *                 for vectorization. It defaults to aligning matrices except for fixed sizes that aren't a multiple of the packet size.
-  * \tparam _MaxRows Maximum number of rows. Defaults to \a _Rows (\ref maxrows "note").
-  * \tparam _MaxCols Maximum number of columns. Defaults to \a _Cols (\ref maxrows "note").
-  *
-  * Eigen provides a number of typedefs covering the usual cases. Here are some examples:
-  *
-  * \li \c Matrix2d is a 2x2 square matrix of doubles (\c Matrix<double, 2, 2>)
-  * \li \c Vector4f is a vector of 4 floats (\c Matrix<float, 4, 1>)
-  * \li \c RowVector3i is a row-vector of 3 ints (\c Matrix<int, 1, 3>)
-  *
-  * \li \c MatrixXf is a dynamic-size matrix of floats (\c Matrix<float, Dynamic, Dynamic>)
-  * \li \c VectorXf is a dynamic-size vector of floats (\c Matrix<float, Dynamic, 1>)
-  *
-  * \li \c Matrix2Xf is a partially fixed-size (dynamic-size) matrix of floats (\c Matrix<float, 2, Dynamic>)
-  * \li \c MatrixX3d is a partially dynamic-size (fixed-size) matrix of double (\c Matrix<double, Dynamic, 3>)
-  *
-  * See \link matrixtypedefs this page \endlink for a complete list of predefined \em %Matrix and \em Vector typedefs.
-  *
-  * You can access elements of vectors and matrices using normal subscripting:
-  *
-  * \code
-  * Eigen::VectorXd v(10);
-  * v[0] = 0.1;
-  * v[1] = 0.2;
-  * v(0) = 0.3;
-  * v(1) = 0.4;
-  *
-  * Eigen::MatrixXi m(10, 10);
-  * m(0, 1) = 1;
-  * m(0, 2) = 2;
-  * m(0, 3) = 3;
-  * \endcode
-  *
-  * This class can be extended with the help of the plugin mechanism described on the page
-  * \ref TopicCustomizing_Plugins by defining the preprocessor symbol \c EIGEN_MATRIX_PLUGIN.
-  *
-  * <i><b>Some notes:</b></i>
-  *
-  * <dl>
-  * <dt><b>\anchor dense Dense versus sparse:</b></dt>
-  * <dd>This %Matrix class handles dense, not sparse matrices and vectors. For sparse matrices and vectors, see the Sparse module.
-  *
-  * Dense matrices and vectors are plain usual arrays of coefficients. All the coefficients are stored, in an ordinary contiguous array.
-  * This is unlike Sparse matrices and vectors where the coefficients are stored as a list of nonzero coefficients.</dd>
-  *
-  * <dt><b>\anchor fixedsize Fixed-size versus dynamic-size:</b></dt>
-  * <dd>Fixed-size means that the numbers of rows and columns are known are compile-time. In this case, Eigen allocates the array
-  * of coefficients as a fixed-size array, as a class member. This makes sense for very small matrices, typically up to 4x4, sometimes up
-  * to 16x16. Larger matrices should be declared as dynamic-size even if one happens to know their size at compile-time.
-  *
-  * Dynamic-size means that the numbers of rows or columns are not necessarily known at compile-time. In this case they are runtime
-  * variables, and the array of coefficients is allocated dynamically on the heap.
-  *
-  * Note that \em dense matrices, be they Fixed-size or Dynamic-size, <em>do not</em> expand dynamically in the sense of a std::map.
-  * If you want this behavior, see the Sparse module.</dd>
-  *
-  * <dt><b>\anchor maxrows _MaxRows and _MaxCols:</b></dt>
-  * <dd>In most cases, one just leaves these parameters to the default values.
-  * These parameters mean the maximum size of rows and columns that the matrix may have. They are useful in cases
-  * when the exact numbers of rows and columns are not known are compile-time, but it is known at compile-time that they cannot
-  * exceed a certain value. This happens when taking dynamic-size blocks inside fixed-size matrices: in this case _MaxRows and _MaxCols
-  * are the dimensions of the original matrix, while _Rows and _Cols are Dynamic.</dd>
-  * </dl>
-  *
-  * <i><b>ABI and storage layout</b></i>
-  *
-  * The table below summarizes the ABI of some possible Matrix instances which is fixed thorough the lifetime of Eigen 3.
-  * <table  class="manual">
-  * <tr><th>Matrix type</th><th>Equivalent C structure</th></tr>
-  * <tr><td>\code Matrix<T,Dynamic,Dynamic> \endcode</td><td>\code
-  * struct {
-  *   T *data;                  // with (size_t(data)%EIGEN_MAX_ALIGN_BYTES)==0
-  *   Eigen::Index rows, cols;
-  *  };
-  * \endcode</td></tr>
-  * <tr class="alt"><td>\code
-  * Matrix<T,Dynamic,1>
-  * Matrix<T,1,Dynamic> \endcode</td><td>\code
-  * struct {
-  *   T *data;                  // with (size_t(data)%EIGEN_MAX_ALIGN_BYTES)==0
-  *   Eigen::Index size;
-  *  };
-  * \endcode</td></tr>
-  * <tr><td>\code Matrix<T,Rows,Cols> \endcode</td><td>\code
-  * struct {
-  *   T data[Rows*Cols];        // with (size_t(data)%A(Rows*Cols*sizeof(T)))==0
-  *  };
-  * \endcode</td></tr>
-  * <tr class="alt"><td>\code Matrix<T,Dynamic,Dynamic,0,MaxRows,MaxCols> \endcode</td><td>\code
-  * struct {
-  *   T data[MaxRows*MaxCols];  // with (size_t(data)%A(MaxRows*MaxCols*sizeof(T)))==0
-  *   Eigen::Index rows, cols;
-  *  };
-  * \endcode</td></tr>
-  * </table>
-  * Note that in this table Rows, Cols, MaxRows and MaxCols are all positive integers. A(S) is defined to the largest possible power-of-two
-  * smaller to EIGEN_MAX_STATIC_ALIGN_BYTES.
-  *
-  * \see MatrixBase for the majority of the API methods for matrices, \ref TopicClassHierarchy,
-  * \ref TopicStorageOrders
-  */
-
-template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
-class Matrix
-  : public PlainObjectBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
-{
-  public:
-
-    /** \brief Base class typedef.
-      * \sa PlainObjectBase
-      */
-    typedef PlainObjectBase<Matrix> Base;
-
-    enum { Options = _Options };
-
-    EIGEN_DENSE_PUBLIC_INTERFACE(Matrix)
-
-    typedef typename Base::PlainObject PlainObject;
-
-    using Base::base;
-    using Base::coeffRef;
-
-    /**
-      * \brief Assigns matrices to each other.
-      *
-      * \note This is a special case of the templated operator=. Its purpose is
-      * to prevent a default operator= from hiding the templated operator=.
-      *
-      * \callgraph
-      */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Matrix& operator=(const Matrix& other)
-    {
-      return Base::_set(other);
-    }
-
-    /** \internal
-      * \brief Copies the value of the expression \a other into \c *this with automatic resizing.
-      *
-      * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized),
-      * it will be initialized.
-      *
-      * Note that copying a row-vector into a vector (and conversely) is allowed.
-      * The resizing, if any, is then done in the appropriate way so that row-vectors
-      * remain row-vectors and vectors remain vectors.
-      */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Matrix& operator=(const DenseBase<OtherDerived>& other)
-    {
-      return Base::_set(other);
-    }
-
-    /* Here, doxygen failed to copy the brief information when using \copydoc */
-
-    /**
-      * \brief Copies the generic expression \a other into *this.
-      * \copydetails DenseBase::operator=(const EigenBase<OtherDerived> &other)
-      */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Matrix& operator=(const EigenBase<OtherDerived> &other)
-    {
-      return Base::operator=(other);
-    }
-
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Matrix& operator=(const ReturnByValue<OtherDerived>& func)
-    {
-      return Base::operator=(func);
-    }
-
-    /** \brief Default constructor.
-      *
-      * For fixed-size matrices, does nothing.
-      *
-      * For dynamic-size matrices, creates an empty matrix of size 0. Does not allocate any array. Such a matrix
-      * is called a null matrix. This constructor is the unique way to create null matrices: resizing
-      * a matrix to 0 is not supported.
-      *
-      * \sa resize(Index,Index)
-      */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Matrix() : Base()
-    {
-      Base::_check_template_params();
-      EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
-    }
-
-    // FIXME is it still needed
-    EIGEN_DEVICE_FUNC
-    explicit Matrix(internal::constructor_without_unaligned_array_assert)
-      : Base(internal::constructor_without_unaligned_array_assert())
-    { Base::_check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED }
-
-#if EIGEN_HAS_RVALUE_REFERENCES
-    EIGEN_DEVICE_FUNC
-    Matrix(Matrix&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_constructible<Scalar>::value)
-      : Base(std::move(other))
-    {
-      Base::_check_template_params();
-    }
-    EIGEN_DEVICE_FUNC
-    Matrix& operator=(Matrix&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_assignable<Scalar>::value)
-    {
-      other.swap(*this);
-      return *this;
-    }
-#endif
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-
-    // This constructor is for both 1x1 matrices and dynamic vectors
-    template<typename T>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE explicit Matrix(const T& x)
-    {
-      Base::_check_template_params();
-      Base::template _init1<T>(x);
-    }
-
-    template<typename T0, typename T1>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Matrix(const T0& x, const T1& y)
-    {
-      Base::_check_template_params();
-      Base::template _init2<T0,T1>(x, y);
-    }
-    #else
-    /** \brief Constructs a fixed-sized matrix initialized with coefficients starting at \a data */
-    EIGEN_DEVICE_FUNC
-    explicit Matrix(const Scalar *data);
-
-    /** \brief Constructs a vector or row-vector with given dimension. \only_for_vectors
-      *
-      * This is useful for dynamic-size vectors. For fixed-size vectors,
-      * it is redundant to pass these parameters, so one should use the default constructor
-      * Matrix() instead.
-      * 
-      * \warning This constructor is disabled for fixed-size \c 1x1 matrices. For instance,
-      * calling Matrix<double,1,1>(1) will call the initialization constructor: Matrix(const Scalar&).
-      * For fixed-size \c 1x1 matrices it is therefore recommended to use the default
-      * constructor Matrix() instead, especially when using one of the non standard
-      * \c EIGEN_INITIALIZE_MATRICES_BY_{ZERO,\c NAN} macros (see \ref TopicPreprocessorDirectives).
-      */
-    EIGEN_STRONG_INLINE explicit Matrix(Index dim);
-    /** \brief Constructs an initialized 1x1 matrix with the given coefficient */
-    Matrix(const Scalar& x);
-    /** \brief Constructs an uninitialized matrix with \a rows rows and \a cols columns.
-      *
-      * This is useful for dynamic-size matrices. For fixed-size matrices,
-      * it is redundant to pass these parameters, so one should use the default constructor
-      * Matrix() instead.
-      * 
-      * \warning This constructor is disabled for fixed-size \c 1x2 and \c 2x1 vectors. For instance,
-      * calling Matrix2f(2,1) will call the initialization constructor: Matrix(const Scalar& x, const Scalar& y).
-      * For fixed-size \c 1x2 or \c 2x1 vectors it is therefore recommended to use the default
-      * constructor Matrix() instead, especially when using one of the non standard
-      * \c EIGEN_INITIALIZE_MATRICES_BY_{ZERO,\c NAN} macros (see \ref TopicPreprocessorDirectives).
-      */
-    EIGEN_DEVICE_FUNC
-    Matrix(Index rows, Index cols);
-    
-    /** \brief Constructs an initialized 2D vector with given coefficients */
-    Matrix(const Scalar& x, const Scalar& y);
-    #endif
-
-    /** \brief Constructs an initialized 3D vector with given coefficients */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z)
-    {
-      Base::_check_template_params();
-      EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 3)
-      m_storage.data()[0] = x;
-      m_storage.data()[1] = y;
-      m_storage.data()[2] = z;
-    }
-    /** \brief Constructs an initialized 4D vector with given coefficients */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w)
-    {
-      Base::_check_template_params();
-      EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 4)
-      m_storage.data()[0] = x;
-      m_storage.data()[1] = y;
-      m_storage.data()[2] = z;
-      m_storage.data()[3] = w;
-    }
-
-
-    /** \brief Copy constructor */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Matrix(const Matrix& other) : Base(other)
-    { }
-
-    /** \brief Copy constructor for generic expressions.
-      * \sa MatrixBase::operator=(const EigenBase<OtherDerived>&)
-      */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Matrix(const EigenBase<OtherDerived> &other)
-      : Base(other.derived())
-    { }
-
-    EIGEN_DEVICE_FUNC inline Index innerStride() const { return 1; }
-    EIGEN_DEVICE_FUNC inline Index outerStride() const { return this->innerSize(); }
-
-    /////////// Geometry module ///////////
-
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    explicit Matrix(const RotationBase<OtherDerived,ColsAtCompileTime>& r);
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    Matrix& operator=(const RotationBase<OtherDerived,ColsAtCompileTime>& r);
-
-    // allow to extend Matrix outside Eigen
-    #ifdef EIGEN_MATRIX_PLUGIN
-    #include EIGEN_MATRIX_PLUGIN
-    #endif
-
-  protected:
-    template <typename Derived, typename OtherDerived, bool IsVector>
-    friend struct internal::conservative_resize_like_impl;
-
-    using Base::m_storage;
-};
-
-/** \defgroup matrixtypedefs Global matrix typedefs
-  *
-  * \ingroup Core_Module
-  *
-  * Eigen defines several typedef shortcuts for most common matrix and vector types.
-  *
-  * The general patterns are the following:
-  *
-  * \c MatrixSizeType where \c Size can be \c 2,\c 3,\c 4 for fixed size square matrices or \c X for dynamic size,
-  * and where \c Type can be \c i for integer, \c f for float, \c d for double, \c cf for complex float, \c cd
-  * for complex double.
-  *
-  * For example, \c Matrix3d is a fixed-size 3x3 matrix type of doubles, and \c MatrixXf is a dynamic-size matrix of floats.
-  *
-  * There are also \c VectorSizeType and \c RowVectorSizeType which are self-explanatory. For example, \c Vector4cf is
-  * a fixed-size vector of 4 complex floats.
-  *
-  * \sa class Matrix
-  */
-
-#define EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix)   \
-/** \ingroup matrixtypedefs */                                    \
-typedef Matrix<Type, Size, Size> Matrix##SizeSuffix##TypeSuffix;  \
-/** \ingroup matrixtypedefs */                                    \
-typedef Matrix<Type, Size, 1>    Vector##SizeSuffix##TypeSuffix;  \
-/** \ingroup matrixtypedefs */                                    \
-typedef Matrix<Type, 1, Size>    RowVector##SizeSuffix##TypeSuffix;
-
-#define EIGEN_MAKE_FIXED_TYPEDEFS(Type, TypeSuffix, Size)         \
-/** \ingroup matrixtypedefs */                                    \
-typedef Matrix<Type, Size, Dynamic> Matrix##Size##X##TypeSuffix;  \
-/** \ingroup matrixtypedefs */                                    \
-typedef Matrix<Type, Dynamic, Size> Matrix##X##Size##TypeSuffix;
-
-#define EIGEN_MAKE_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \
-EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 2, 2) \
-EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 3, 3) \
-EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 4, 4) \
-EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, Dynamic, X) \
-EIGEN_MAKE_FIXED_TYPEDEFS(Type, TypeSuffix, 2) \
-EIGEN_MAKE_FIXED_TYPEDEFS(Type, TypeSuffix, 3) \
-EIGEN_MAKE_FIXED_TYPEDEFS(Type, TypeSuffix, 4)
-
-EIGEN_MAKE_TYPEDEFS_ALL_SIZES(int,                  i)
-EIGEN_MAKE_TYPEDEFS_ALL_SIZES(float,                f)
-EIGEN_MAKE_TYPEDEFS_ALL_SIZES(double,               d)
-EIGEN_MAKE_TYPEDEFS_ALL_SIZES(std::complex<float>,  cf)
-EIGEN_MAKE_TYPEDEFS_ALL_SIZES(std::complex<double>, cd)
-
-#undef EIGEN_MAKE_TYPEDEFS_ALL_SIZES
-#undef EIGEN_MAKE_TYPEDEFS
-#undef EIGEN_MAKE_FIXED_TYPEDEFS
-
-} // end namespace Eigen
-
-#endif // EIGEN_MATRIX_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/MatrixBase.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/MatrixBase.h
deleted file mode 100644
index e6c3590..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/MatrixBase.h
+++ /dev/null
@@ -1,529 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_MATRIXBASE_H
-#define EIGEN_MATRIXBASE_H
-
-namespace Eigen {
-
-/** \class MatrixBase
-  * \ingroup Core_Module
-  *
-  * \brief Base class for all dense matrices, vectors, and expressions
-  *
-  * This class is the base that is inherited by all matrix, vector, and related expression
-  * types. Most of the Eigen API is contained in this class, and its base classes. Other important
-  * classes for the Eigen API are Matrix, and VectorwiseOp.
-  *
-  * Note that some methods are defined in other modules such as the \ref LU_Module LU module
-  * for all functions related to matrix inversions.
-  *
-  * \tparam Derived is the derived type, e.g. a matrix type, or an expression, etc.
-  *
-  * When writing a function taking Eigen objects as argument, if you want your function
-  * to take as argument any matrix, vector, or expression, just let it take a
-  * MatrixBase argument. As an example, here is a function printFirstRow which, given
-  * a matrix, vector, or expression \a x, prints the first row of \a x.
-  *
-  * \code
-    template<typename Derived>
-    void printFirstRow(const Eigen::MatrixBase<Derived>& x)
-    {
-      cout << x.row(0) << endl;
-    }
-  * \endcode
-  *
-  * This class can be extended with the help of the plugin mechanism described on the page
-  * \ref TopicCustomizing_Plugins by defining the preprocessor symbol \c EIGEN_MATRIXBASE_PLUGIN.
-  *
-  * \sa \blank \ref TopicClassHierarchy
-  */
-template<typename Derived> class MatrixBase
-  : public DenseBase<Derived>
-{
-  public:
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-    typedef MatrixBase StorageBaseType;
-    typedef typename internal::traits<Derived>::StorageKind StorageKind;
-    typedef typename internal::traits<Derived>::StorageIndex StorageIndex;
-    typedef typename internal::traits<Derived>::Scalar Scalar;
-    typedef typename internal::packet_traits<Scalar>::type PacketScalar;
-    typedef typename NumTraits<Scalar>::Real RealScalar;
-
-    typedef DenseBase<Derived> Base;
-    using Base::RowsAtCompileTime;
-    using Base::ColsAtCompileTime;
-    using Base::SizeAtCompileTime;
-    using Base::MaxRowsAtCompileTime;
-    using Base::MaxColsAtCompileTime;
-    using Base::MaxSizeAtCompileTime;
-    using Base::IsVectorAtCompileTime;
-    using Base::Flags;
-
-    using Base::derived;
-    using Base::const_cast_derived;
-    using Base::rows;
-    using Base::cols;
-    using Base::size;
-    using Base::coeff;
-    using Base::coeffRef;
-    using Base::lazyAssign;
-    using Base::eval;
-    using Base::operator+=;
-    using Base::operator-=;
-    using Base::operator*=;
-    using Base::operator/=;
-
-    typedef typename Base::CoeffReturnType CoeffReturnType;
-    typedef typename Base::ConstTransposeReturnType ConstTransposeReturnType;
-    typedef typename Base::RowXpr RowXpr;
-    typedef typename Base::ColXpr ColXpr;
-#endif // not EIGEN_PARSED_BY_DOXYGEN
-
-
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-    /** type of the equivalent square matrix */
-    typedef Matrix<Scalar,EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime),
-                          EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime)> SquareMatrixType;
-#endif // not EIGEN_PARSED_BY_DOXYGEN
-
-    /** \returns the size of the main diagonal, which is min(rows(),cols()).
-      * \sa rows(), cols(), SizeAtCompileTime. */
-    EIGEN_DEVICE_FUNC
-    inline Index diagonalSize() const { return (numext::mini)(rows(),cols()); }
-
-    typedef typename Base::PlainObject PlainObject;
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-    /** \internal Represents a matrix with all coefficients equal to one another*/
-    typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,PlainObject> ConstantReturnType;
-    /** \internal the return type of MatrixBase::adjoint() */
-    typedef typename internal::conditional<NumTraits<Scalar>::IsComplex,
-                        CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, ConstTransposeReturnType>,
-                        ConstTransposeReturnType
-                     >::type AdjointReturnType;
-    /** \internal Return type of eigenvalues() */
-    typedef Matrix<std::complex<RealScalar>, internal::traits<Derived>::ColsAtCompileTime, 1, ColMajor> EigenvaluesReturnType;
-    /** \internal the return type of identity */
-    typedef CwiseNullaryOp<internal::scalar_identity_op<Scalar>,PlainObject> IdentityReturnType;
-    /** \internal the return type of unit vectors */
-    typedef Block<const CwiseNullaryOp<internal::scalar_identity_op<Scalar>, SquareMatrixType>,
-                  internal::traits<Derived>::RowsAtCompileTime,
-                  internal::traits<Derived>::ColsAtCompileTime> BasisReturnType;
-#endif // not EIGEN_PARSED_BY_DOXYGEN
-
-#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::MatrixBase
-#define EIGEN_DOC_UNARY_ADDONS(X,Y)
-#   include "../plugins/CommonCwiseUnaryOps.h"
-#   include "../plugins/CommonCwiseBinaryOps.h"
-#   include "../plugins/MatrixCwiseUnaryOps.h"
-#   include "../plugins/MatrixCwiseBinaryOps.h"
-#   ifdef EIGEN_MATRIXBASE_PLUGIN
-#     include EIGEN_MATRIXBASE_PLUGIN
-#   endif
-#undef EIGEN_CURRENT_STORAGE_BASE_CLASS
-#undef EIGEN_DOC_UNARY_ADDONS
-
-    /** Special case of the template operator=, in order to prevent the compiler
-      * from generating a default operator= (issue hit with g++ 4.1)
-      */
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-    Derived& operator=(const MatrixBase& other);
-
-    // We cannot inherit here via Base::operator= since it is causing
-    // trouble with MSVC.
-
-    template <typename OtherDerived>
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-    Derived& operator=(const DenseBase<OtherDerived>& other);
-
-    template <typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    Derived& operator=(const EigenBase<OtherDerived>& other);
-
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    Derived& operator=(const ReturnByValue<OtherDerived>& other);
-
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-    Derived& operator+=(const MatrixBase<OtherDerived>& other);
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-    Derived& operator-=(const MatrixBase<OtherDerived>& other);
-
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    const Product<Derived,OtherDerived>
-    operator*(const MatrixBase<OtherDerived> &other) const;
-
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    const Product<Derived,OtherDerived,LazyProduct>
-    lazyProduct(const MatrixBase<OtherDerived> &other) const;
-
-    template<typename OtherDerived>
-    Derived& operator*=(const EigenBase<OtherDerived>& other);
-
-    template<typename OtherDerived>
-    void applyOnTheLeft(const EigenBase<OtherDerived>& other);
-
-    template<typename OtherDerived>
-    void applyOnTheRight(const EigenBase<OtherDerived>& other);
-
-    template<typename DiagonalDerived>
-    EIGEN_DEVICE_FUNC
-    const Product<Derived, DiagonalDerived, LazyProduct>
-    operator*(const DiagonalBase<DiagonalDerived> &diagonal) const;
-
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    typename ScalarBinaryOpTraits<typename internal::traits<Derived>::Scalar,typename internal::traits<OtherDerived>::Scalar>::ReturnType
-    dot(const MatrixBase<OtherDerived>& other) const;
-
-    EIGEN_DEVICE_FUNC RealScalar squaredNorm() const;
-    EIGEN_DEVICE_FUNC RealScalar norm() const;
-    RealScalar stableNorm() const;
-    RealScalar blueNorm() const;
-    RealScalar hypotNorm() const;
-    EIGEN_DEVICE_FUNC const PlainObject normalized() const;
-    EIGEN_DEVICE_FUNC const PlainObject stableNormalized() const;
-    EIGEN_DEVICE_FUNC void normalize();
-    EIGEN_DEVICE_FUNC void stableNormalize();
-
-    EIGEN_DEVICE_FUNC const AdjointReturnType adjoint() const;
-    EIGEN_DEVICE_FUNC void adjointInPlace();
-
-    typedef Diagonal<Derived> DiagonalReturnType;
-    EIGEN_DEVICE_FUNC
-    DiagonalReturnType diagonal();
-
-    typedef typename internal::add_const<Diagonal<const Derived> >::type ConstDiagonalReturnType;
-    EIGEN_DEVICE_FUNC
-    ConstDiagonalReturnType diagonal() const;
-
-    template<int Index> struct DiagonalIndexReturnType { typedef Diagonal<Derived,Index> Type; };
-    template<int Index> struct ConstDiagonalIndexReturnType { typedef const Diagonal<const Derived,Index> Type; };
-
-    template<int Index>
-    EIGEN_DEVICE_FUNC
-    typename DiagonalIndexReturnType<Index>::Type diagonal();
-
-    template<int Index>
-    EIGEN_DEVICE_FUNC
-    typename ConstDiagonalIndexReturnType<Index>::Type diagonal() const;
-
-    typedef Diagonal<Derived,DynamicIndex> DiagonalDynamicIndexReturnType;
-    typedef typename internal::add_const<Diagonal<const Derived,DynamicIndex> >::type ConstDiagonalDynamicIndexReturnType;
-
-    EIGEN_DEVICE_FUNC
-    DiagonalDynamicIndexReturnType diagonal(Index index);
-    EIGEN_DEVICE_FUNC
-    ConstDiagonalDynamicIndexReturnType diagonal(Index index) const;
-
-    template<unsigned int Mode> struct TriangularViewReturnType { typedef TriangularView<Derived, Mode> Type; };
-    template<unsigned int Mode> struct ConstTriangularViewReturnType { typedef const TriangularView<const Derived, Mode> Type; };
-
-    template<unsigned int Mode>
-    EIGEN_DEVICE_FUNC
-    typename TriangularViewReturnType<Mode>::Type triangularView();
-    template<unsigned int Mode>
-    EIGEN_DEVICE_FUNC
-    typename ConstTriangularViewReturnType<Mode>::Type triangularView() const;
-
-    template<unsigned int UpLo> struct SelfAdjointViewReturnType { typedef SelfAdjointView<Derived, UpLo> Type; };
-    template<unsigned int UpLo> struct ConstSelfAdjointViewReturnType { typedef const SelfAdjointView<const Derived, UpLo> Type; };
-
-    template<unsigned int UpLo>
-    EIGEN_DEVICE_FUNC
-    typename SelfAdjointViewReturnType<UpLo>::Type selfadjointView();
-    template<unsigned int UpLo>
-    EIGEN_DEVICE_FUNC
-    typename ConstSelfAdjointViewReturnType<UpLo>::Type selfadjointView() const;
-
-    const SparseView<Derived> sparseView(const Scalar& m_reference = Scalar(0),
-                                         const typename NumTraits<Scalar>::Real& m_epsilon = NumTraits<Scalar>::dummy_precision()) const;
-    EIGEN_DEVICE_FUNC static const IdentityReturnType Identity();
-    EIGEN_DEVICE_FUNC static const IdentityReturnType Identity(Index rows, Index cols);
-    EIGEN_DEVICE_FUNC static const BasisReturnType Unit(Index size, Index i);
-    EIGEN_DEVICE_FUNC static const BasisReturnType Unit(Index i);
-    EIGEN_DEVICE_FUNC static const BasisReturnType UnitX();
-    EIGEN_DEVICE_FUNC static const BasisReturnType UnitY();
-    EIGEN_DEVICE_FUNC static const BasisReturnType UnitZ();
-    EIGEN_DEVICE_FUNC static const BasisReturnType UnitW();
-
-    EIGEN_DEVICE_FUNC
-    const DiagonalWrapper<const Derived> asDiagonal() const;
-    const PermutationWrapper<const Derived> asPermutation() const;
-
-    EIGEN_DEVICE_FUNC
-    Derived& setIdentity();
-    EIGEN_DEVICE_FUNC
-    Derived& setIdentity(Index rows, Index cols);
-
-    bool isIdentity(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
-    bool isDiagonal(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
-
-    bool isUpperTriangular(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
-    bool isLowerTriangular(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
-
-    template<typename OtherDerived>
-    bool isOrthogonal(const MatrixBase<OtherDerived>& other,
-                      const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
-    bool isUnitary(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
-
-    /** \returns true if each coefficients of \c *this and \a other are all exactly equal.
-      * \warning When using floating point scalar values you probably should rather use a
-      *          fuzzy comparison such as isApprox()
-      * \sa isApprox(), operator!= */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC inline bool operator==(const MatrixBase<OtherDerived>& other) const
-    { return cwiseEqual(other).all(); }
-
-    /** \returns true if at least one pair of coefficients of \c *this and \a other are not exactly equal to each other.
-      * \warning When using floating point scalar values you probably should rather use a
-      *          fuzzy comparison such as isApprox()
-      * \sa isApprox(), operator== */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC inline bool operator!=(const MatrixBase<OtherDerived>& other) const
-    { return cwiseNotEqual(other).any(); }
-
-    NoAlias<Derived,Eigen::MatrixBase > noalias();
-
-    // TODO forceAlignedAccess is temporarily disabled
-    // Need to find a nicer workaround.
-    inline const Derived& forceAlignedAccess() const { return derived(); }
-    inline Derived& forceAlignedAccess() { return derived(); }
-    template<bool Enable> inline const Derived& forceAlignedAccessIf() const { return derived(); }
-    template<bool Enable> inline Derived& forceAlignedAccessIf() { return derived(); }
-
-    EIGEN_DEVICE_FUNC Scalar trace() const;
-
-    template<int p> EIGEN_DEVICE_FUNC RealScalar lpNorm() const;
-
-    EIGEN_DEVICE_FUNC MatrixBase<Derived>& matrix() { return *this; }
-    EIGEN_DEVICE_FUNC const MatrixBase<Derived>& matrix() const { return *this; }
-
-    /** \returns an \link Eigen::ArrayBase Array \endlink expression of this matrix
-      * \sa ArrayBase::matrix() */
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ArrayWrapper<Derived> array() { return ArrayWrapper<Derived>(derived()); }
-    /** \returns a const \link Eigen::ArrayBase Array \endlink expression of this matrix
-      * \sa ArrayBase::matrix() */
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const ArrayWrapper<const Derived> array() const { return ArrayWrapper<const Derived>(derived()); }
-
-/////////// LU module ///////////
-
-    inline const FullPivLU<PlainObject> fullPivLu() const;
-    inline const PartialPivLU<PlainObject> partialPivLu() const;
-
-    inline const PartialPivLU<PlainObject> lu() const;
-
-    inline const Inverse<Derived> inverse() const;
-
-    template<typename ResultType>
-    inline void computeInverseAndDetWithCheck(
-      ResultType& inverse,
-      typename ResultType::Scalar& determinant,
-      bool& invertible,
-      const RealScalar& absDeterminantThreshold = NumTraits<Scalar>::dummy_precision()
-    ) const;
-    template<typename ResultType>
-    inline void computeInverseWithCheck(
-      ResultType& inverse,
-      bool& invertible,
-      const RealScalar& absDeterminantThreshold = NumTraits<Scalar>::dummy_precision()
-    ) const;
-    Scalar determinant() const;
-
-/////////// Cholesky module ///////////
-
-    inline const LLT<PlainObject>  llt() const;
-    inline const LDLT<PlainObject> ldlt() const;
-
-/////////// QR module ///////////
-
-    inline const HouseholderQR<PlainObject> householderQr() const;
-    inline const ColPivHouseholderQR<PlainObject> colPivHouseholderQr() const;
-    inline const FullPivHouseholderQR<PlainObject> fullPivHouseholderQr() const;
-    inline const CompleteOrthogonalDecomposition<PlainObject> completeOrthogonalDecomposition() const;
-
-/////////// Eigenvalues module ///////////
-
-    inline EigenvaluesReturnType eigenvalues() const;
-    inline RealScalar operatorNorm() const;
-
-/////////// SVD module ///////////
-
-    inline JacobiSVD<PlainObject> jacobiSvd(unsigned int computationOptions = 0) const;
-    inline BDCSVD<PlainObject>    bdcSvd(unsigned int computationOptions = 0) const;
-
-/////////// Geometry module ///////////
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    /// \internal helper struct to form the return type of the cross product
-    template<typename OtherDerived> struct cross_product_return_type {
-      typedef typename ScalarBinaryOpTraits<typename internal::traits<Derived>::Scalar,typename internal::traits<OtherDerived>::Scalar>::ReturnType Scalar;
-      typedef Matrix<Scalar,MatrixBase::RowsAtCompileTime,MatrixBase::ColsAtCompileTime> type;
-    };
-    #endif // EIGEN_PARSED_BY_DOXYGEN
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-    inline typename cross_product_return_type<OtherDerived>::type
-#else
-    inline PlainObject
-#endif
-    cross(const MatrixBase<OtherDerived>& other) const;
-
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    inline PlainObject cross3(const MatrixBase<OtherDerived>& other) const;
-
-    EIGEN_DEVICE_FUNC
-    inline PlainObject unitOrthogonal(void) const;
-
-    EIGEN_DEVICE_FUNC
-    inline Matrix<Scalar,3,1> eulerAngles(Index a0, Index a1, Index a2) const;
-
-    // put this as separate enum value to work around possible GCC 4.3 bug (?)
-    enum { HomogeneousReturnTypeDirection = ColsAtCompileTime==1&&RowsAtCompileTime==1 ? ((internal::traits<Derived>::Flags&RowMajorBit)==RowMajorBit ? Horizontal : Vertical)
-                                          : ColsAtCompileTime==1 ? Vertical : Horizontal };
-    typedef Homogeneous<Derived, HomogeneousReturnTypeDirection> HomogeneousReturnType;
-    EIGEN_DEVICE_FUNC
-    inline HomogeneousReturnType homogeneous() const;
-
-    enum {
-      SizeMinusOne = SizeAtCompileTime==Dynamic ? Dynamic : SizeAtCompileTime-1
-    };
-    typedef Block<const Derived,
-                  internal::traits<Derived>::ColsAtCompileTime==1 ? SizeMinusOne : 1,
-                  internal::traits<Derived>::ColsAtCompileTime==1 ? 1 : SizeMinusOne> ConstStartMinusOne;
-    typedef EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(ConstStartMinusOne,Scalar,quotient) HNormalizedReturnType;
-    EIGEN_DEVICE_FUNC
-    inline const HNormalizedReturnType hnormalized() const;
-
-////////// Householder module ///////////
-
-    void makeHouseholderInPlace(Scalar& tau, RealScalar& beta);
-    template<typename EssentialPart>
-    void makeHouseholder(EssentialPart& essential,
-                         Scalar& tau, RealScalar& beta) const;
-    template<typename EssentialPart>
-    void applyHouseholderOnTheLeft(const EssentialPart& essential,
-                                   const Scalar& tau,
-                                   Scalar* workspace);
-    template<typename EssentialPart>
-    void applyHouseholderOnTheRight(const EssentialPart& essential,
-                                    const Scalar& tau,
-                                    Scalar* workspace);
-
-///////// Jacobi module /////////
-
-    template<typename OtherScalar>
-    void applyOnTheLeft(Index p, Index q, const JacobiRotation<OtherScalar>& j);
-    template<typename OtherScalar>
-    void applyOnTheRight(Index p, Index q, const JacobiRotation<OtherScalar>& j);
-
-///////// SparseCore module /////////
-
-    template<typename OtherDerived>
-    EIGEN_STRONG_INLINE const typename SparseMatrixBase<OtherDerived>::template CwiseProductDenseReturnType<Derived>::Type
-    cwiseProduct(const SparseMatrixBase<OtherDerived> &other) const
-    {
-      return other.cwiseProduct(derived());
-    }
-
-///////// MatrixFunctions module /////////
-
-    typedef typename internal::stem_function<Scalar>::type StemFunction;
-#define EIGEN_MATRIX_FUNCTION(ReturnType, Name, Description) \
-    /** \returns an expression of the matrix Description of \c *this. \brief This function requires the <a href="unsupported/group__MatrixFunctions__Module.html"> unsupported MatrixFunctions module</a>. To compute the coefficient-wise Description use ArrayBase::##Name . */ \
-    const ReturnType<Derived> Name() const;
-#define EIGEN_MATRIX_FUNCTION_1(ReturnType, Name, Description, Argument) \
-    /** \returns an expression of the matrix Description of \c *this. \brief This function requires the <a href="unsupported/group__MatrixFunctions__Module.html"> unsupported MatrixFunctions module</a>. To compute the coefficient-wise Description use ArrayBase::##Name . */ \
-    const ReturnType<Derived> Name(Argument) const;
-
-    EIGEN_MATRIX_FUNCTION(MatrixExponentialReturnValue, exp, exponential)
-    /** \brief Helper function for the <a href="unsupported/group__MatrixFunctions__Module.html"> unsupported MatrixFunctions module</a>.*/
-    const MatrixFunctionReturnValue<Derived> matrixFunction(StemFunction f) const;
-    EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, cosh, hyperbolic cosine)
-    EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, sinh, hyperbolic sine)
-    EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, cos, cosine)
-    EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, sin, sine)
-    EIGEN_MATRIX_FUNCTION(MatrixSquareRootReturnValue, sqrt, square root)
-    EIGEN_MATRIX_FUNCTION(MatrixLogarithmReturnValue, log, logarithm)
-    EIGEN_MATRIX_FUNCTION_1(MatrixPowerReturnValue,        pow, power to \c p, const RealScalar& p)
-    EIGEN_MATRIX_FUNCTION_1(MatrixComplexPowerReturnValue, pow, power to \c p, const std::complex<RealScalar>& p)
-
-  protected:
-    EIGEN_DEVICE_FUNC MatrixBase() : Base() {}
-
-  private:
-    EIGEN_DEVICE_FUNC explicit MatrixBase(int);
-    EIGEN_DEVICE_FUNC MatrixBase(int,int);
-    template<typename OtherDerived> EIGEN_DEVICE_FUNC explicit MatrixBase(const MatrixBase<OtherDerived>&);
-  protected:
-    // mixing arrays and matrices is not legal
-    template<typename OtherDerived> Derived& operator+=(const ArrayBase<OtherDerived>& )
-    {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;}
-    // mixing arrays and matrices is not legal
-    template<typename OtherDerived> Derived& operator-=(const ArrayBase<OtherDerived>& )
-    {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;}
-};
-
-
-/***************************************************************************
-* Implementation of matrix base methods
-***************************************************************************/
-
-/** replaces \c *this by \c *this * \a other.
-  *
-  * \returns a reference to \c *this
-  *
-  * Example: \include MatrixBase_applyOnTheRight.cpp
-  * Output: \verbinclude MatrixBase_applyOnTheRight.out
-  */
-template<typename Derived>
-template<typename OtherDerived>
-inline Derived&
-MatrixBase<Derived>::operator*=(const EigenBase<OtherDerived> &other)
-{
-  other.derived().applyThisOnTheRight(derived());
-  return derived();
-}
-
-/** replaces \c *this by \c *this * \a other. It is equivalent to MatrixBase::operator*=().
-  *
-  * Example: \include MatrixBase_applyOnTheRight.cpp
-  * Output: \verbinclude MatrixBase_applyOnTheRight.out
-  */
-template<typename Derived>
-template<typename OtherDerived>
-inline void MatrixBase<Derived>::applyOnTheRight(const EigenBase<OtherDerived> &other)
-{
-  other.derived().applyThisOnTheRight(derived());
-}
-
-/** replaces \c *this by \a other * \c *this.
-  *
-  * Example: \include MatrixBase_applyOnTheLeft.cpp
-  * Output: \verbinclude MatrixBase_applyOnTheLeft.out
-  */
-template<typename Derived>
-template<typename OtherDerived>
-inline void MatrixBase<Derived>::applyOnTheLeft(const EigenBase<OtherDerived> &other)
-{
-  other.derived().applyThisOnTheLeft(derived());
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_MATRIXBASE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/NestByValue.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/NestByValue.h
deleted file mode 100644
index 13adf07..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/NestByValue.h
+++ /dev/null
@@ -1,110 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_NESTBYVALUE_H
-#define EIGEN_NESTBYVALUE_H
-
-namespace Eigen {
-
-namespace internal {
-template<typename ExpressionType>
-struct traits<NestByValue<ExpressionType> > : public traits<ExpressionType>
-{};
-}
-
-/** \class NestByValue
-  * \ingroup Core_Module
-  *
-  * \brief Expression which must be nested by value
-  *
-  * \tparam ExpressionType the type of the object of which we are requiring nesting-by-value
-  *
-  * This class is the return type of MatrixBase::nestByValue()
-  * and most of the time this is the only way it is used.
-  *
-  * \sa MatrixBase::nestByValue()
-  */
-template<typename ExpressionType> class NestByValue
-  : public internal::dense_xpr_base< NestByValue<ExpressionType> >::type
-{
-  public:
-
-    typedef typename internal::dense_xpr_base<NestByValue>::type Base;
-    EIGEN_DENSE_PUBLIC_INTERFACE(NestByValue)
-
-    EIGEN_DEVICE_FUNC explicit inline NestByValue(const ExpressionType& matrix) : m_expression(matrix) {}
-
-    EIGEN_DEVICE_FUNC inline Index rows() const { return m_expression.rows(); }
-    EIGEN_DEVICE_FUNC inline Index cols() const { return m_expression.cols(); }
-    EIGEN_DEVICE_FUNC inline Index outerStride() const { return m_expression.outerStride(); }
-    EIGEN_DEVICE_FUNC inline Index innerStride() const { return m_expression.innerStride(); }
-
-    EIGEN_DEVICE_FUNC inline const CoeffReturnType coeff(Index row, Index col) const
-    {
-      return m_expression.coeff(row, col);
-    }
-
-    EIGEN_DEVICE_FUNC inline Scalar& coeffRef(Index row, Index col)
-    {
-      return m_expression.const_cast_derived().coeffRef(row, col);
-    }
-
-    EIGEN_DEVICE_FUNC inline const CoeffReturnType coeff(Index index) const
-    {
-      return m_expression.coeff(index);
-    }
-
-    EIGEN_DEVICE_FUNC inline Scalar& coeffRef(Index index)
-    {
-      return m_expression.const_cast_derived().coeffRef(index);
-    }
-
-    template<int LoadMode>
-    inline const PacketScalar packet(Index row, Index col) const
-    {
-      return m_expression.template packet<LoadMode>(row, col);
-    }
-
-    template<int LoadMode>
-    inline void writePacket(Index row, Index col, const PacketScalar& x)
-    {
-      m_expression.const_cast_derived().template writePacket<LoadMode>(row, col, x);
-    }
-
-    template<int LoadMode>
-    inline const PacketScalar packet(Index index) const
-    {
-      return m_expression.template packet<LoadMode>(index);
-    }
-
-    template<int LoadMode>
-    inline void writePacket(Index index, const PacketScalar& x)
-    {
-      m_expression.const_cast_derived().template writePacket<LoadMode>(index, x);
-    }
-
-    EIGEN_DEVICE_FUNC operator const ExpressionType&() const { return m_expression; }
-
-  protected:
-    const ExpressionType m_expression;
-};
-
-/** \returns an expression of the temporary version of *this.
-  */
-template<typename Derived>
-inline const NestByValue<Derived>
-DenseBase<Derived>::nestByValue() const
-{
-  return NestByValue<Derived>(derived());
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_NESTBYVALUE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/NoAlias.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/NoAlias.h
deleted file mode 100644
index 3390801..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/NoAlias.h
+++ /dev/null
@@ -1,108 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_NOALIAS_H
-#define EIGEN_NOALIAS_H
-
-namespace Eigen {
-
-/** \class NoAlias
-  * \ingroup Core_Module
-  *
-  * \brief Pseudo expression providing an operator = assuming no aliasing
-  *
-  * \tparam ExpressionType the type of the object on which to do the lazy assignment
-  *
-  * This class represents an expression with special assignment operators
-  * assuming no aliasing between the target expression and the source expression.
-  * More precisely it alloas to bypass the EvalBeforeAssignBit flag of the source expression.
-  * It is the return type of MatrixBase::noalias()
-  * and most of the time this is the only way it is used.
-  *
-  * \sa MatrixBase::noalias()
-  */
-template<typename ExpressionType, template <typename> class StorageBase>
-class NoAlias
-{
-  public:
-    typedef typename ExpressionType::Scalar Scalar;
-    
-    explicit NoAlias(ExpressionType& expression) : m_expression(expression) {}
-    
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE ExpressionType& operator=(const StorageBase<OtherDerived>& other)
-    {
-      call_assignment_no_alias(m_expression, other.derived(), internal::assign_op<Scalar,typename OtherDerived::Scalar>());
-      return m_expression;
-    }
-    
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE ExpressionType& operator+=(const StorageBase<OtherDerived>& other)
-    {
-      call_assignment_no_alias(m_expression, other.derived(), internal::add_assign_op<Scalar,typename OtherDerived::Scalar>());
-      return m_expression;
-    }
-    
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE ExpressionType& operator-=(const StorageBase<OtherDerived>& other)
-    {
-      call_assignment_no_alias(m_expression, other.derived(), internal::sub_assign_op<Scalar,typename OtherDerived::Scalar>());
-      return m_expression;
-    }
-
-    EIGEN_DEVICE_FUNC
-    ExpressionType& expression() const
-    {
-      return m_expression;
-    }
-
-  protected:
-    ExpressionType& m_expression;
-};
-
-/** \returns a pseudo expression of \c *this with an operator= assuming
-  * no aliasing between \c *this and the source expression.
-  *
-  * More precisely, noalias() allows to bypass the EvalBeforeAssignBit flag.
-  * Currently, even though several expressions may alias, only product
-  * expressions have this flag. Therefore, noalias() is only usefull when
-  * the source expression contains a matrix product.
-  *
-  * Here are some examples where noalias is usefull:
-  * \code
-  * D.noalias()  = A * B;
-  * D.noalias() += A.transpose() * B;
-  * D.noalias() -= 2 * A * B.adjoint();
-  * \endcode
-  *
-  * On the other hand the following example will lead to a \b wrong result:
-  * \code
-  * A.noalias() = A * B;
-  * \endcode
-  * because the result matrix A is also an operand of the matrix product. Therefore,
-  * there is no alternative than evaluating A * B in a temporary, that is the default
-  * behavior when you write:
-  * \code
-  * A = A * B;
-  * \endcode
-  *
-  * \sa class NoAlias
-  */
-template<typename Derived>
-NoAlias<Derived,MatrixBase> MatrixBase<Derived>::noalias()
-{
-  return NoAlias<Derived, Eigen::MatrixBase >(derived());
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_NOALIAS_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/NumTraits.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/NumTraits.h
deleted file mode 100644
index daf4898..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/NumTraits.h
+++ /dev/null
@@ -1,248 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_NUMTRAITS_H
-#define EIGEN_NUMTRAITS_H
-
-namespace Eigen {
-
-namespace internal {
-
-// default implementation of digits10(), based on numeric_limits if specialized,
-// 0 for integer types, and log10(epsilon()) otherwise.
-template< typename T,
-          bool use_numeric_limits = std::numeric_limits<T>::is_specialized,
-          bool is_integer = NumTraits<T>::IsInteger>
-struct default_digits10_impl
-{
-  static int run() { return std::numeric_limits<T>::digits10; }
-};
-
-template<typename T>
-struct default_digits10_impl<T,false,false> // Floating point
-{
-  static int run() {
-    using std::log10;
-    using std::ceil;
-    typedef typename NumTraits<T>::Real Real;
-    return int(ceil(-log10(NumTraits<Real>::epsilon())));
-  }
-};
-
-template<typename T>
-struct default_digits10_impl<T,false,true> // Integer
-{
-  static int run() { return 0; }
-};
-
-} // end namespace internal
-
-/** \class NumTraits
-  * \ingroup Core_Module
-  *
-  * \brief Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
-  *
-  * \tparam T the numeric type at hand
-  *
-  * This class stores enums, typedefs and static methods giving information about a numeric type.
-  *
-  * The provided data consists of:
-  * \li A typedef \c Real, giving the "real part" type of \a T. If \a T is already real,
-  *     then \c Real is just a typedef to \a T. If \a T is \c std::complex<U> then \c Real
-  *     is a typedef to \a U.
-  * \li A typedef \c NonInteger, giving the type that should be used for operations producing non-integral values,
-  *     such as quotients, square roots, etc. If \a T is a floating-point type, then this typedef just gives
-  *     \a T again. Note however that many Eigen functions such as internal::sqrt simply refuse to
-  *     take integers. Outside of a few cases, Eigen doesn't do automatic type promotion. Thus, this typedef is
-  *     only intended as a helper for code that needs to explicitly promote types.
-  * \li A typedef \c Literal giving the type to use for numeric literals such as "2" or "0.5". For instance, for \c std::complex<U>, Literal is defined as \c U.
-  *     Of course, this type must be fully compatible with \a T. In doubt, just use \a T here.
-  * \li A typedef \a Nested giving the type to use to nest a value inside of the expression tree. If you don't know what
-  *     this means, just use \a T here.
-  * \li An enum value \a IsComplex. It is equal to 1 if \a T is a \c std::complex
-  *     type, and to 0 otherwise.
-  * \li An enum value \a IsInteger. It is equal to \c 1 if \a T is an integer type such as \c int,
-  *     and to \c 0 otherwise.
-  * \li Enum values ReadCost, AddCost and MulCost representing a rough estimate of the number of CPU cycles needed
-  *     to by move / add / mul instructions respectively, assuming the data is already stored in CPU registers.
-  *     Stay vague here. No need to do architecture-specific stuff.
-  * \li An enum value \a IsSigned. It is equal to \c 1 if \a T is a signed type and to 0 if \a T is unsigned.
-  * \li An enum value \a RequireInitialization. It is equal to \c 1 if the constructor of the numeric type \a T must
-  *     be called, and to 0 if it is safe not to call it. Default is 0 if \a T is an arithmetic type, and 1 otherwise.
-  * \li An epsilon() function which, unlike <a href="http://en.cppreference.com/w/cpp/types/numeric_limits/epsilon">std::numeric_limits::epsilon()</a>,
-  *     it returns a \a Real instead of a \a T.
-  * \li A dummy_precision() function returning a weak epsilon value. It is mainly used as a default
-  *     value by the fuzzy comparison operators.
-  * \li highest() and lowest() functions returning the highest and lowest possible values respectively.
-  * \li digits10() function returning the number of decimal digits that can be represented without change. This is
-  *     the analogue of <a href="http://en.cppreference.com/w/cpp/types/numeric_limits/digits10">std::numeric_limits<T>::digits10</a>
-  *     which is used as the default implementation if specialized.
-  */
-
-template<typename T> struct GenericNumTraits
-{
-  enum {
-    IsInteger = std::numeric_limits<T>::is_integer,
-    IsSigned = std::numeric_limits<T>::is_signed,
-    IsComplex = 0,
-    RequireInitialization = internal::is_arithmetic<T>::value ? 0 : 1,
-    ReadCost = 1,
-    AddCost = 1,
-    MulCost = 1
-  };
-
-  typedef T Real;
-  typedef typename internal::conditional<
-                     IsInteger,
-                     typename internal::conditional<sizeof(T)<=2, float, double>::type,
-                     T
-                   >::type NonInteger;
-  typedef T Nested;
-  typedef T Literal;
-
-  EIGEN_DEVICE_FUNC
-  static inline Real epsilon()
-  {
-    return numext::numeric_limits<T>::epsilon();
-  }
-
-  EIGEN_DEVICE_FUNC
-  static inline int digits10()
-  {
-    return internal::default_digits10_impl<T>::run();
-  }
-
-  EIGEN_DEVICE_FUNC
-  static inline Real dummy_precision()
-  {
-    // make sure to override this for floating-point types
-    return Real(0);
-  }
-
-
-  EIGEN_DEVICE_FUNC
-  static inline T highest() {
-    return (numext::numeric_limits<T>::max)();
-  }
-
-  EIGEN_DEVICE_FUNC
-  static inline T lowest()  {
-    return IsInteger ? (numext::numeric_limits<T>::min)() : (-(numext::numeric_limits<T>::max)());
-  }
-
-  EIGEN_DEVICE_FUNC
-  static inline T infinity() {
-    return numext::numeric_limits<T>::infinity();
-  }
-
-  EIGEN_DEVICE_FUNC
-  static inline T quiet_NaN() {
-    return numext::numeric_limits<T>::quiet_NaN();
-  }
-};
-
-template<typename T> struct NumTraits : GenericNumTraits<T>
-{};
-
-template<> struct NumTraits<float>
-  : GenericNumTraits<float>
-{
-  EIGEN_DEVICE_FUNC
-  static inline float dummy_precision() { return 1e-5f; }
-};
-
-template<> struct NumTraits<double> : GenericNumTraits<double>
-{
-  EIGEN_DEVICE_FUNC
-  static inline double dummy_precision() { return 1e-12; }
-};
-
-template<> struct NumTraits<long double>
-  : GenericNumTraits<long double>
-{
-  static inline long double dummy_precision() { return 1e-15l; }
-};
-
-template<typename _Real> struct NumTraits<std::complex<_Real> >
-  : GenericNumTraits<std::complex<_Real> >
-{
-  typedef _Real Real;
-  typedef typename NumTraits<_Real>::Literal Literal;
-  enum {
-    IsComplex = 1,
-    RequireInitialization = NumTraits<_Real>::RequireInitialization,
-    ReadCost = 2 * NumTraits<_Real>::ReadCost,
-    AddCost = 2 * NumTraits<Real>::AddCost,
-    MulCost = 4 * NumTraits<Real>::MulCost + 2 * NumTraits<Real>::AddCost
-  };
-
-  EIGEN_DEVICE_FUNC
-  static inline Real epsilon() { return NumTraits<Real>::epsilon(); }
-  EIGEN_DEVICE_FUNC
-  static inline Real dummy_precision() { return NumTraits<Real>::dummy_precision(); }
-  EIGEN_DEVICE_FUNC
-  static inline int digits10() { return NumTraits<Real>::digits10(); }
-};
-
-template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
-struct NumTraits<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
-{
-  typedef Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> ArrayType;
-  typedef typename NumTraits<Scalar>::Real RealScalar;
-  typedef Array<RealScalar, Rows, Cols, Options, MaxRows, MaxCols> Real;
-  typedef typename NumTraits<Scalar>::NonInteger NonIntegerScalar;
-  typedef Array<NonIntegerScalar, Rows, Cols, Options, MaxRows, MaxCols> NonInteger;
-  typedef ArrayType & Nested;
-  typedef typename NumTraits<Scalar>::Literal Literal;
-
-  enum {
-    IsComplex = NumTraits<Scalar>::IsComplex,
-    IsInteger = NumTraits<Scalar>::IsInteger,
-    IsSigned  = NumTraits<Scalar>::IsSigned,
-    RequireInitialization = 1,
-    ReadCost = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * NumTraits<Scalar>::ReadCost,
-    AddCost  = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * NumTraits<Scalar>::AddCost,
-    MulCost  = ArrayType::SizeAtCompileTime==Dynamic ? HugeCost : ArrayType::SizeAtCompileTime * NumTraits<Scalar>::MulCost
-  };
-
-  EIGEN_DEVICE_FUNC
-  static inline RealScalar epsilon() { return NumTraits<RealScalar>::epsilon(); }
-  EIGEN_DEVICE_FUNC
-  static inline RealScalar dummy_precision() { return NumTraits<RealScalar>::dummy_precision(); }
-
-  static inline int digits10() { return NumTraits<Scalar>::digits10(); }
-};
-
-template<> struct NumTraits<std::string>
-  : GenericNumTraits<std::string>
-{
-  enum {
-    RequireInitialization = 1,
-    ReadCost = HugeCost,
-    AddCost  = HugeCost,
-    MulCost  = HugeCost
-  };
-
-  static inline int digits10() { return 0; }
-
-private:
-  static inline std::string epsilon();
-  static inline std::string dummy_precision();
-  static inline std::string lowest();
-  static inline std::string highest();
-  static inline std::string infinity();
-  static inline std::string quiet_NaN();
-};
-
-// Empty specialization for void to allow template specialization based on NumTraits<T>::Real with T==void and SFINAE.
-template<> struct NumTraits<void> {};
-
-} // end namespace Eigen
-
-#endif // EIGEN_NUMTRAITS_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/PermutationMatrix.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/PermutationMatrix.h
deleted file mode 100644
index b1fb455..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/PermutationMatrix.h
+++ /dev/null
@@ -1,633 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2009-2015 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_PERMUTATIONMATRIX_H
-#define EIGEN_PERMUTATIONMATRIX_H
-
-namespace Eigen { 
-
-namespace internal {
-
-enum PermPermProduct_t {PermPermProduct};
-
-} // end namespace internal
-
-/** \class PermutationBase
-  * \ingroup Core_Module
-  *
-  * \brief Base class for permutations
-  *
-  * \tparam Derived the derived class
-  *
-  * This class is the base class for all expressions representing a permutation matrix,
-  * internally stored as a vector of integers.
-  * The convention followed here is that if \f$ \sigma \f$ is a permutation, the corresponding permutation matrix
-  * \f$ P_\sigma \f$ is such that if \f$ (e_1,\ldots,e_p) \f$ is the canonical basis, we have:
-  *  \f[ P_\sigma(e_i) = e_{\sigma(i)}. \f]
-  * This convention ensures that for any two permutations \f$ \sigma, \tau \f$, we have:
-  *  \f[ P_{\sigma\circ\tau} = P_\sigma P_\tau. \f]
-  *
-  * Permutation matrices are square and invertible.
-  *
-  * Notice that in addition to the member functions and operators listed here, there also are non-member
-  * operator* to multiply any kind of permutation object with any kind of matrix expression (MatrixBase)
-  * on either side.
-  *
-  * \sa class PermutationMatrix, class PermutationWrapper
-  */
-template<typename Derived>
-class PermutationBase : public EigenBase<Derived>
-{
-    typedef internal::traits<Derived> Traits;
-    typedef EigenBase<Derived> Base;
-  public:
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    typedef typename Traits::IndicesType IndicesType;
-    enum {
-      Flags = Traits::Flags,
-      RowsAtCompileTime = Traits::RowsAtCompileTime,
-      ColsAtCompileTime = Traits::ColsAtCompileTime,
-      MaxRowsAtCompileTime = Traits::MaxRowsAtCompileTime,
-      MaxColsAtCompileTime = Traits::MaxColsAtCompileTime
-    };
-    typedef typename Traits::StorageIndex StorageIndex;
-    typedef Matrix<StorageIndex,RowsAtCompileTime,ColsAtCompileTime,0,MaxRowsAtCompileTime,MaxColsAtCompileTime>
-            DenseMatrixType;
-    typedef PermutationMatrix<IndicesType::SizeAtCompileTime,IndicesType::MaxSizeAtCompileTime,StorageIndex>
-            PlainPermutationType;
-    typedef PlainPermutationType PlainObject;
-    using Base::derived;
-    typedef Inverse<Derived> InverseReturnType;
-    typedef void Scalar;
-    #endif
-
-    /** Copies the other permutation into *this */
-    template<typename OtherDerived>
-    Derived& operator=(const PermutationBase<OtherDerived>& other)
-    {
-      indices() = other.indices();
-      return derived();
-    }
-
-    /** Assignment from the Transpositions \a tr */
-    template<typename OtherDerived>
-    Derived& operator=(const TranspositionsBase<OtherDerived>& tr)
-    {
-      setIdentity(tr.size());
-      for(Index k=size()-1; k>=0; --k)
-        applyTranspositionOnTheRight(k,tr.coeff(k));
-      return derived();
-    }
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    /** This is a special case of the templated operator=. Its purpose is to
-      * prevent a default operator= from hiding the templated operator=.
-      */
-    Derived& operator=(const PermutationBase& other)
-    {
-      indices() = other.indices();
-      return derived();
-    }
-    #endif
-
-    /** \returns the number of rows */
-    inline Index rows() const { return Index(indices().size()); }
-
-    /** \returns the number of columns */
-    inline Index cols() const { return Index(indices().size()); }
-
-    /** \returns the size of a side of the respective square matrix, i.e., the number of indices */
-    inline Index size() const { return Index(indices().size()); }
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    template<typename DenseDerived>
-    void evalTo(MatrixBase<DenseDerived>& other) const
-    {
-      other.setZero();
-      for (Index i=0; i<rows(); ++i)
-        other.coeffRef(indices().coeff(i),i) = typename DenseDerived::Scalar(1);
-    }
-    #endif
-
-    /** \returns a Matrix object initialized from this permutation matrix. Notice that it
-      * is inefficient to return this Matrix object by value. For efficiency, favor using
-      * the Matrix constructor taking EigenBase objects.
-      */
-    DenseMatrixType toDenseMatrix() const
-    {
-      return derived();
-    }
-
-    /** const version of indices(). */
-    const IndicesType& indices() const { return derived().indices(); }
-    /** \returns a reference to the stored array representing the permutation. */
-    IndicesType& indices() { return derived().indices(); }
-
-    /** Resizes to given size.
-      */
-    inline void resize(Index newSize)
-    {
-      indices().resize(newSize);
-    }
-
-    /** Sets *this to be the identity permutation matrix */
-    void setIdentity()
-    {
-      StorageIndex n = StorageIndex(size());
-      for(StorageIndex i = 0; i < n; ++i)
-        indices().coeffRef(i) = i;
-    }
-
-    /** Sets *this to be the identity permutation matrix of given size.
-      */
-    void setIdentity(Index newSize)
-    {
-      resize(newSize);
-      setIdentity();
-    }
-
-    /** Multiplies *this by the transposition \f$(ij)\f$ on the left.
-      *
-      * \returns a reference to *this.
-      *
-      * \warning This is much slower than applyTranspositionOnTheRight(Index,Index):
-      * this has linear complexity and requires a lot of branching.
-      *
-      * \sa applyTranspositionOnTheRight(Index,Index)
-      */
-    Derived& applyTranspositionOnTheLeft(Index i, Index j)
-    {
-      eigen_assert(i>=0 && j>=0 && i<size() && j<size());
-      for(Index k = 0; k < size(); ++k)
-      {
-        if(indices().coeff(k) == i) indices().coeffRef(k) = StorageIndex(j);
-        else if(indices().coeff(k) == j) indices().coeffRef(k) = StorageIndex(i);
-      }
-      return derived();
-    }
-
-    /** Multiplies *this by the transposition \f$(ij)\f$ on the right.
-      *
-      * \returns a reference to *this.
-      *
-      * This is a fast operation, it only consists in swapping two indices.
-      *
-      * \sa applyTranspositionOnTheLeft(Index,Index)
-      */
-    Derived& applyTranspositionOnTheRight(Index i, Index j)
-    {
-      eigen_assert(i>=0 && j>=0 && i<size() && j<size());
-      std::swap(indices().coeffRef(i), indices().coeffRef(j));
-      return derived();
-    }
-
-    /** \returns the inverse permutation matrix.
-      *
-      * \note \blank \note_try_to_help_rvo
-      */
-    inline InverseReturnType inverse() const
-    { return InverseReturnType(derived()); }
-    /** \returns the tranpose permutation matrix.
-      *
-      * \note \blank \note_try_to_help_rvo
-      */
-    inline InverseReturnType transpose() const
-    { return InverseReturnType(derived()); }
-
-    /**** multiplication helpers to hopefully get RVO ****/
-
-  
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-  protected:
-    template<typename OtherDerived>
-    void assignTranspose(const PermutationBase<OtherDerived>& other)
-    {
-      for (Index i=0; i<rows();++i) indices().coeffRef(other.indices().coeff(i)) = i;
-    }
-    template<typename Lhs,typename Rhs>
-    void assignProduct(const Lhs& lhs, const Rhs& rhs)
-    {
-      eigen_assert(lhs.cols() == rhs.rows());
-      for (Index i=0; i<rows();++i) indices().coeffRef(i) = lhs.indices().coeff(rhs.indices().coeff(i));
-    }
-#endif
-
-  public:
-
-    /** \returns the product permutation matrix.
-      *
-      * \note \blank \note_try_to_help_rvo
-      */
-    template<typename Other>
-    inline PlainPermutationType operator*(const PermutationBase<Other>& other) const
-    { return PlainPermutationType(internal::PermPermProduct, derived(), other.derived()); }
-
-    /** \returns the product of a permutation with another inverse permutation.
-      *
-      * \note \blank \note_try_to_help_rvo
-      */
-    template<typename Other>
-    inline PlainPermutationType operator*(const InverseImpl<Other,PermutationStorage>& other) const
-    { return PlainPermutationType(internal::PermPermProduct, *this, other.eval()); }
-
-    /** \returns the product of an inverse permutation with another permutation.
-      *
-      * \note \blank \note_try_to_help_rvo
-      */
-    template<typename Other> friend
-    inline PlainPermutationType operator*(const InverseImpl<Other, PermutationStorage>& other, const PermutationBase& perm)
-    { return PlainPermutationType(internal::PermPermProduct, other.eval(), perm); }
-    
-    /** \returns the determinant of the permutation matrix, which is either 1 or -1 depending on the parity of the permutation.
-      *
-      * This function is O(\c n) procedure allocating a buffer of \c n booleans.
-      */
-    Index determinant() const
-    {
-      Index res = 1;
-      Index n = size();
-      Matrix<bool,RowsAtCompileTime,1,0,MaxRowsAtCompileTime> mask(n);
-      mask.fill(false);
-      Index r = 0;
-      while(r < n)
-      {
-        // search for the next seed
-        while(r<n && mask[r]) r++;
-        if(r>=n)
-          break;
-        // we got one, let's follow it until we are back to the seed
-        Index k0 = r++;
-        mask.coeffRef(k0) = true;
-        for(Index k=indices().coeff(k0); k!=k0; k=indices().coeff(k))
-        {
-          mask.coeffRef(k) = true;
-          res = -res;
-        }
-      }
-      return res;
-    }
-
-  protected:
-
-};
-
-namespace internal {
-template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename _StorageIndex>
-struct traits<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, _StorageIndex> >
- : traits<Matrix<_StorageIndex,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime> >
-{
-  typedef PermutationStorage StorageKind;
-  typedef Matrix<_StorageIndex, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1> IndicesType;
-  typedef _StorageIndex StorageIndex;
-  typedef void Scalar;
-};
-}
-
-/** \class PermutationMatrix
-  * \ingroup Core_Module
-  *
-  * \brief Permutation matrix
-  *
-  * \tparam SizeAtCompileTime the number of rows/cols, or Dynamic
-  * \tparam MaxSizeAtCompileTime the maximum number of rows/cols, or Dynamic. This optional parameter defaults to SizeAtCompileTime. Most of the time, you should not have to specify it.
-  * \tparam _StorageIndex the integer type of the indices
-  *
-  * This class represents a permutation matrix, internally stored as a vector of integers.
-  *
-  * \sa class PermutationBase, class PermutationWrapper, class DiagonalMatrix
-  */
-template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename _StorageIndex>
-class PermutationMatrix : public PermutationBase<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, _StorageIndex> >
-{
-    typedef PermutationBase<PermutationMatrix> Base;
-    typedef internal::traits<PermutationMatrix> Traits;
-  public:
-
-    typedef const PermutationMatrix& Nested;
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    typedef typename Traits::IndicesType IndicesType;
-    typedef typename Traits::StorageIndex StorageIndex;
-    #endif
-
-    inline PermutationMatrix()
-    {}
-
-    /** Constructs an uninitialized permutation matrix of given size.
-      */
-    explicit inline PermutationMatrix(Index size) : m_indices(size)
-    {
-      eigen_internal_assert(size <= NumTraits<StorageIndex>::highest());
-    }
-
-    /** Copy constructor. */
-    template<typename OtherDerived>
-    inline PermutationMatrix(const PermutationBase<OtherDerived>& other)
-      : m_indices(other.indices()) {}
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    /** Standard copy constructor. Defined only to prevent a default copy constructor
-      * from hiding the other templated constructor */
-    inline PermutationMatrix(const PermutationMatrix& other) : m_indices(other.indices()) {}
-    #endif
-
-    /** Generic constructor from expression of the indices. The indices
-      * array has the meaning that the permutations sends each integer i to indices[i].
-      *
-      * \warning It is your responsibility to check that the indices array that you passes actually
-      * describes a permutation, i.e., each value between 0 and n-1 occurs exactly once, where n is the
-      * array's size.
-      */
-    template<typename Other>
-    explicit inline PermutationMatrix(const MatrixBase<Other>& indices) : m_indices(indices)
-    {}
-
-    /** Convert the Transpositions \a tr to a permutation matrix */
-    template<typename Other>
-    explicit PermutationMatrix(const TranspositionsBase<Other>& tr)
-      : m_indices(tr.size())
-    {
-      *this = tr;
-    }
-
-    /** Copies the other permutation into *this */
-    template<typename Other>
-    PermutationMatrix& operator=(const PermutationBase<Other>& other)
-    {
-      m_indices = other.indices();
-      return *this;
-    }
-
-    /** Assignment from the Transpositions \a tr */
-    template<typename Other>
-    PermutationMatrix& operator=(const TranspositionsBase<Other>& tr)
-    {
-      return Base::operator=(tr.derived());
-    }
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    /** This is a special case of the templated operator=. Its purpose is to
-      * prevent a default operator= from hiding the templated operator=.
-      */
-    PermutationMatrix& operator=(const PermutationMatrix& other)
-    {
-      m_indices = other.m_indices;
-      return *this;
-    }
-    #endif
-
-    /** const version of indices(). */
-    const IndicesType& indices() const { return m_indices; }
-    /** \returns a reference to the stored array representing the permutation. */
-    IndicesType& indices() { return m_indices; }
-
-
-    /**** multiplication helpers to hopefully get RVO ****/
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-    template<typename Other>
-    PermutationMatrix(const InverseImpl<Other,PermutationStorage>& other)
-      : m_indices(other.derived().nestedExpression().size())
-    {
-      eigen_internal_assert(m_indices.size() <= NumTraits<StorageIndex>::highest());
-      StorageIndex end = StorageIndex(m_indices.size());
-      for (StorageIndex i=0; i<end;++i)
-        m_indices.coeffRef(other.derived().nestedExpression().indices().coeff(i)) = i;
-    }
-    template<typename Lhs,typename Rhs>
-    PermutationMatrix(internal::PermPermProduct_t, const Lhs& lhs, const Rhs& rhs)
-      : m_indices(lhs.indices().size())
-    {
-      Base::assignProduct(lhs,rhs);
-    }
-#endif
-
-  protected:
-
-    IndicesType m_indices;
-};
-
-
-namespace internal {
-template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename _StorageIndex, int _PacketAccess>
-struct traits<Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, _StorageIndex>,_PacketAccess> >
- : traits<Matrix<_StorageIndex,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime> >
-{
-  typedef PermutationStorage StorageKind;
-  typedef Map<const Matrix<_StorageIndex, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1>, _PacketAccess> IndicesType;
-  typedef _StorageIndex StorageIndex;
-  typedef void Scalar;
-};
-}
-
-template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename _StorageIndex, int _PacketAccess>
-class Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, _StorageIndex>,_PacketAccess>
-  : public PermutationBase<Map<PermutationMatrix<SizeAtCompileTime, MaxSizeAtCompileTime, _StorageIndex>,_PacketAccess> >
-{
-    typedef PermutationBase<Map> Base;
-    typedef internal::traits<Map> Traits;
-  public:
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    typedef typename Traits::IndicesType IndicesType;
-    typedef typename IndicesType::Scalar StorageIndex;
-    #endif
-
-    inline Map(const StorageIndex* indicesPtr)
-      : m_indices(indicesPtr)
-    {}
-
-    inline Map(const StorageIndex* indicesPtr, Index size)
-      : m_indices(indicesPtr,size)
-    {}
-
-    /** Copies the other permutation into *this */
-    template<typename Other>
-    Map& operator=(const PermutationBase<Other>& other)
-    { return Base::operator=(other.derived()); }
-
-    /** Assignment from the Transpositions \a tr */
-    template<typename Other>
-    Map& operator=(const TranspositionsBase<Other>& tr)
-    { return Base::operator=(tr.derived()); }
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    /** This is a special case of the templated operator=. Its purpose is to
-      * prevent a default operator= from hiding the templated operator=.
-      */
-    Map& operator=(const Map& other)
-    {
-      m_indices = other.m_indices;
-      return *this;
-    }
-    #endif
-
-    /** const version of indices(). */
-    const IndicesType& indices() const { return m_indices; }
-    /** \returns a reference to the stored array representing the permutation. */
-    IndicesType& indices() { return m_indices; }
-
-  protected:
-
-    IndicesType m_indices;
-};
-
-template<typename _IndicesType> class TranspositionsWrapper;
-namespace internal {
-template<typename _IndicesType>
-struct traits<PermutationWrapper<_IndicesType> >
-{
-  typedef PermutationStorage StorageKind;
-  typedef void Scalar;
-  typedef typename _IndicesType::Scalar StorageIndex;
-  typedef _IndicesType IndicesType;
-  enum {
-    RowsAtCompileTime = _IndicesType::SizeAtCompileTime,
-    ColsAtCompileTime = _IndicesType::SizeAtCompileTime,
-    MaxRowsAtCompileTime = IndicesType::MaxSizeAtCompileTime,
-    MaxColsAtCompileTime = IndicesType::MaxSizeAtCompileTime,
-    Flags = 0
-  };
-};
-}
-
-/** \class PermutationWrapper
-  * \ingroup Core_Module
-  *
-  * \brief Class to view a vector of integers as a permutation matrix
-  *
-  * \tparam _IndicesType the type of the vector of integer (can be any compatible expression)
-  *
-  * This class allows to view any vector expression of integers as a permutation matrix.
-  *
-  * \sa class PermutationBase, class PermutationMatrix
-  */
-template<typename _IndicesType>
-class PermutationWrapper : public PermutationBase<PermutationWrapper<_IndicesType> >
-{
-    typedef PermutationBase<PermutationWrapper> Base;
-    typedef internal::traits<PermutationWrapper> Traits;
-  public:
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    typedef typename Traits::IndicesType IndicesType;
-    #endif
-
-    inline PermutationWrapper(const IndicesType& indices)
-      : m_indices(indices)
-    {}
-
-    /** const version of indices(). */
-    const typename internal::remove_all<typename IndicesType::Nested>::type&
-    indices() const { return m_indices; }
-
-  protected:
-
-    typename IndicesType::Nested m_indices;
-};
-
-
-/** \returns the matrix with the permutation applied to the columns.
-  */
-template<typename MatrixDerived, typename PermutationDerived>
-EIGEN_DEVICE_FUNC
-const Product<MatrixDerived, PermutationDerived, AliasFreeProduct>
-operator*(const MatrixBase<MatrixDerived> &matrix,
-          const PermutationBase<PermutationDerived>& permutation)
-{
-  return Product<MatrixDerived, PermutationDerived, AliasFreeProduct>
-            (matrix.derived(), permutation.derived());
-}
-
-/** \returns the matrix with the permutation applied to the rows.
-  */
-template<typename PermutationDerived, typename MatrixDerived>
-EIGEN_DEVICE_FUNC
-const Product<PermutationDerived, MatrixDerived, AliasFreeProduct>
-operator*(const PermutationBase<PermutationDerived> &permutation,
-          const MatrixBase<MatrixDerived>& matrix)
-{
-  return Product<PermutationDerived, MatrixDerived, AliasFreeProduct>
-            (permutation.derived(), matrix.derived());
-}
-
-
-template<typename PermutationType>
-class InverseImpl<PermutationType, PermutationStorage>
-  : public EigenBase<Inverse<PermutationType> >
-{
-    typedef typename PermutationType::PlainPermutationType PlainPermutationType;
-    typedef internal::traits<PermutationType> PermTraits;
-  protected:
-    InverseImpl() {}
-  public:
-    typedef Inverse<PermutationType> InverseType;
-    using EigenBase<Inverse<PermutationType> >::derived;
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    typedef typename PermutationType::DenseMatrixType DenseMatrixType;
-    enum {
-      RowsAtCompileTime = PermTraits::RowsAtCompileTime,
-      ColsAtCompileTime = PermTraits::ColsAtCompileTime,
-      MaxRowsAtCompileTime = PermTraits::MaxRowsAtCompileTime,
-      MaxColsAtCompileTime = PermTraits::MaxColsAtCompileTime
-    };
-    #endif
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    template<typename DenseDerived>
-    void evalTo(MatrixBase<DenseDerived>& other) const
-    {
-      other.setZero();
-      for (Index i=0; i<derived().rows();++i)
-        other.coeffRef(i, derived().nestedExpression().indices().coeff(i)) = typename DenseDerived::Scalar(1);
-    }
-    #endif
-
-    /** \return the equivalent permutation matrix */
-    PlainPermutationType eval() const { return derived(); }
-
-    DenseMatrixType toDenseMatrix() const { return derived(); }
-
-    /** \returns the matrix with the inverse permutation applied to the columns.
-      */
-    template<typename OtherDerived> friend
-    const Product<OtherDerived, InverseType, AliasFreeProduct>
-    operator*(const MatrixBase<OtherDerived>& matrix, const InverseType& trPerm)
-    {
-      return Product<OtherDerived, InverseType, AliasFreeProduct>(matrix.derived(), trPerm.derived());
-    }
-
-    /** \returns the matrix with the inverse permutation applied to the rows.
-      */
-    template<typename OtherDerived>
-    const Product<InverseType, OtherDerived, AliasFreeProduct>
-    operator*(const MatrixBase<OtherDerived>& matrix) const
-    {
-      return Product<InverseType, OtherDerived, AliasFreeProduct>(derived(), matrix.derived());
-    }
-};
-
-template<typename Derived>
-const PermutationWrapper<const Derived> MatrixBase<Derived>::asPermutation() const
-{
-  return derived();
-}
-
-namespace internal {
-
-template<> struct AssignmentKind<DenseShape,PermutationShape> { typedef EigenBase2EigenBase Kind; };
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_PERMUTATIONMATRIX_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/PlainObjectBase.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/PlainObjectBase.h
deleted file mode 100644
index 1dc7e22..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/PlainObjectBase.h
+++ /dev/null
@@ -1,1035 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_DENSESTORAGEBASE_H
-#define EIGEN_DENSESTORAGEBASE_H
-
-#if defined(EIGEN_INITIALIZE_MATRICES_BY_ZERO)
-# define EIGEN_INITIALIZE_COEFFS
-# define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED for(int i=0;i<base().size();++i) coeffRef(i)=Scalar(0);
-#elif defined(EIGEN_INITIALIZE_MATRICES_BY_NAN)
-# define EIGEN_INITIALIZE_COEFFS
-# define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED for(int i=0;i<base().size();++i) coeffRef(i)=std::numeric_limits<Scalar>::quiet_NaN();
-#else
-# undef EIGEN_INITIALIZE_COEFFS
-# define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
-#endif
-
-namespace Eigen {
-
-namespace internal {
-
-template<int MaxSizeAtCompileTime> struct check_rows_cols_for_overflow {
-  template<typename Index>
-  EIGEN_DEVICE_FUNC
-  static EIGEN_ALWAYS_INLINE void run(Index, Index)
-  {
-  }
-};
-
-template<> struct check_rows_cols_for_overflow<Dynamic> {
-  template<typename Index>
-  EIGEN_DEVICE_FUNC
-  static EIGEN_ALWAYS_INLINE void run(Index rows, Index cols)
-  {
-    // http://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242
-    // we assume Index is signed
-    Index max_index = (std::size_t(1) << (8 * sizeof(Index) - 1)) - 1; // assume Index is signed
-    bool error = (rows == 0 || cols == 0) ? false
-               : (rows > max_index / cols);
-    if (error)
-      throw_std_bad_alloc();
-  }
-};
-
-template <typename Derived,
-          typename OtherDerived = Derived,
-          bool IsVector = bool(Derived::IsVectorAtCompileTime) && bool(OtherDerived::IsVectorAtCompileTime)>
-struct conservative_resize_like_impl;
-
-template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct matrix_swap_impl;
-
-} // end namespace internal
-
-#ifdef EIGEN_PARSED_BY_DOXYGEN
-namespace doxygen {
-
-// This is a workaround to doxygen not being able to understand the inheritance logic
-// when it is hidden by the dense_xpr_base helper struct.
-// Moreover, doxygen fails to include members that are not documented in the declaration body of
-// MatrixBase if we inherits MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >,
-// this is why we simply inherits MatrixBase, though this does not make sense.
-
-/** This class is just a workaround for Doxygen and it does not not actually exist. */
-template<typename Derived> struct dense_xpr_base_dispatcher;
-/** This class is just a workaround for Doxygen and it does not not actually exist. */
-template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
-struct dense_xpr_base_dispatcher<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
-    : public MatrixBase {};
-/** This class is just a workaround for Doxygen and it does not not actually exist. */
-template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
-struct dense_xpr_base_dispatcher<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
-    : public ArrayBase {};
-
-} // namespace doxygen
-
-/** \class PlainObjectBase
-  * \ingroup Core_Module
-  * \brief %Dense storage base class for matrices and arrays.
-  *
-  * This class can be extended with the help of the plugin mechanism described on the page
-  * \ref TopicCustomizing_Plugins by defining the preprocessor symbol \c EIGEN_PLAINOBJECTBASE_PLUGIN.
-  *
-  * \tparam Derived is the derived type, e.g., a Matrix or Array
-  *
-  * \sa \ref TopicClassHierarchy
-  */
-template<typename Derived>
-class PlainObjectBase : public doxygen::dense_xpr_base_dispatcher<Derived>
-#else
-template<typename Derived>
-class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
-#endif
-{
-  public:
-    enum { Options = internal::traits<Derived>::Options };
-    typedef typename internal::dense_xpr_base<Derived>::type Base;
-
-    typedef typename internal::traits<Derived>::StorageKind StorageKind;
-    typedef typename internal::traits<Derived>::Scalar Scalar;
-    
-    typedef typename internal::packet_traits<Scalar>::type PacketScalar;
-    typedef typename NumTraits<Scalar>::Real RealScalar;
-    typedef Derived DenseType;
-
-    using Base::RowsAtCompileTime;
-    using Base::ColsAtCompileTime;
-    using Base::SizeAtCompileTime;
-    using Base::MaxRowsAtCompileTime;
-    using Base::MaxColsAtCompileTime;
-    using Base::MaxSizeAtCompileTime;
-    using Base::IsVectorAtCompileTime;
-    using Base::Flags;
-
-    template<typename PlainObjectType, int MapOptions, typename StrideType> friend class Eigen::Map;
-    friend  class Eigen::Map<Derived, Unaligned>;
-    typedef Eigen::Map<Derived, Unaligned>  MapType;
-    friend  class Eigen::Map<const Derived, Unaligned>;
-    typedef const Eigen::Map<const Derived, Unaligned> ConstMapType;
-#if EIGEN_MAX_ALIGN_BYTES>0
-    // for EIGEN_MAX_ALIGN_BYTES==0, AlignedMax==Unaligned, and many compilers generate warnings for friend-ing a class twice.
-    friend  class Eigen::Map<Derived, AlignedMax>;
-    friend  class Eigen::Map<const Derived, AlignedMax>;
-#endif
-    typedef Eigen::Map<Derived, AlignedMax> AlignedMapType;
-    typedef const Eigen::Map<const Derived, AlignedMax> ConstAlignedMapType;
-    template<typename StrideType> struct StridedMapType { typedef Eigen::Map<Derived, Unaligned, StrideType> type; };
-    template<typename StrideType> struct StridedConstMapType { typedef Eigen::Map<const Derived, Unaligned, StrideType> type; };
-    template<typename StrideType> struct StridedAlignedMapType { typedef Eigen::Map<Derived, AlignedMax, StrideType> type; };
-    template<typename StrideType> struct StridedConstAlignedMapType { typedef Eigen::Map<const Derived, AlignedMax, StrideType> type; };
-
-  protected:
-    DenseStorage<Scalar, Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime, Base::ColsAtCompileTime, Options> m_storage;
-
-  public:
-    enum { NeedsToAlign = (SizeAtCompileTime != Dynamic) && (internal::traits<Derived>::Alignment>0) };
-    EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
-
-    EIGEN_DEVICE_FUNC
-    Base& base() { return *static_cast<Base*>(this); }
-    EIGEN_DEVICE_FUNC
-    const Base& base() const { return *static_cast<const Base*>(this); }
-
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Index rows() const { return m_storage.rows(); }
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Index cols() const { return m_storage.cols(); }
-
-    /** This is an overloaded version of DenseCoeffsBase<Derived,ReadOnlyAccessors>::coeff(Index,Index) const
-      * provided to by-pass the creation of an evaluator of the expression, thus saving compilation efforts.
-      *
-      * See DenseCoeffsBase<Derived,ReadOnlyAccessors>::coeff(Index) const for details. */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE const Scalar& coeff(Index rowId, Index colId) const
-    {
-      if(Flags & RowMajorBit)
-        return m_storage.data()[colId + rowId * m_storage.cols()];
-      else // column-major
-        return m_storage.data()[rowId + colId * m_storage.rows()];
-    }
-
-    /** This is an overloaded version of DenseCoeffsBase<Derived,ReadOnlyAccessors>::coeff(Index) const
-      * provided to by-pass the creation of an evaluator of the expression, thus saving compilation efforts.
-      *
-      * See DenseCoeffsBase<Derived,ReadOnlyAccessors>::coeff(Index) const for details. */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const
-    {
-      return m_storage.data()[index];
-    }
-
-    /** This is an overloaded version of DenseCoeffsBase<Derived,WriteAccessors>::coeffRef(Index,Index) const
-      * provided to by-pass the creation of an evaluator of the expression, thus saving compilation efforts.
-      *
-      * See DenseCoeffsBase<Derived,WriteAccessors>::coeffRef(Index,Index) const for details. */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Scalar& coeffRef(Index rowId, Index colId)
-    {
-      if(Flags & RowMajorBit)
-        return m_storage.data()[colId + rowId * m_storage.cols()];
-      else // column-major
-        return m_storage.data()[rowId + colId * m_storage.rows()];
-    }
-
-    /** This is an overloaded version of DenseCoeffsBase<Derived,WriteAccessors>::coeffRef(Index) const
-      * provided to by-pass the creation of an evaluator of the expression, thus saving compilation efforts.
-      *
-      * See DenseCoeffsBase<Derived,WriteAccessors>::coeffRef(Index) const for details. */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
-    {
-      return m_storage.data()[index];
-    }
-
-    /** This is the const version of coeffRef(Index,Index) which is thus synonym of coeff(Index,Index).
-      * It is provided for convenience. */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE const Scalar& coeffRef(Index rowId, Index colId) const
-    {
-      if(Flags & RowMajorBit)
-        return m_storage.data()[colId + rowId * m_storage.cols()];
-      else // column-major
-        return m_storage.data()[rowId + colId * m_storage.rows()];
-    }
-
-    /** This is the const version of coeffRef(Index) which is thus synonym of coeff(Index).
-      * It is provided for convenience. */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE const Scalar& coeffRef(Index index) const
-    {
-      return m_storage.data()[index];
-    }
-
-    /** \internal */
-    template<int LoadMode>
-    EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const
-    {
-      return internal::ploadt<PacketScalar, LoadMode>
-               (m_storage.data() + (Flags & RowMajorBit
-                                   ? colId + rowId * m_storage.cols()
-                                   : rowId + colId * m_storage.rows()));
-    }
-
-    /** \internal */
-    template<int LoadMode>
-    EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
-    {
-      return internal::ploadt<PacketScalar, LoadMode>(m_storage.data() + index);
-    }
-
-    /** \internal */
-    template<int StoreMode>
-    EIGEN_STRONG_INLINE void writePacket(Index rowId, Index colId, const PacketScalar& val)
-    {
-      internal::pstoret<Scalar, PacketScalar, StoreMode>
-              (m_storage.data() + (Flags & RowMajorBit
-                                   ? colId + rowId * m_storage.cols()
-                                   : rowId + colId * m_storage.rows()), val);
-    }
-
-    /** \internal */
-    template<int StoreMode>
-    EIGEN_STRONG_INLINE void writePacket(Index index, const PacketScalar& val)
-    {
-      internal::pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, val);
-    }
-
-    /** \returns a const pointer to the data array of this matrix */
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar *data() const
-    { return m_storage.data(); }
-
-    /** \returns a pointer to the data array of this matrix */
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar *data()
-    { return m_storage.data(); }
-
-    /** Resizes \c *this to a \a rows x \a cols matrix.
-      *
-      * This method is intended for dynamic-size matrices, although it is legal to call it on any
-      * matrix as long as fixed dimensions are left unchanged. If you only want to change the number
-      * of rows and/or of columns, you can use resize(NoChange_t, Index), resize(Index, NoChange_t).
-      *
-      * If the current number of coefficients of \c *this exactly matches the
-      * product \a rows * \a cols, then no memory allocation is performed and
-      * the current values are left unchanged. In all other cases, including
-      * shrinking, the data is reallocated and all previous values are lost.
-      *
-      * Example: \include Matrix_resize_int_int.cpp
-      * Output: \verbinclude Matrix_resize_int_int.out
-      *
-      * \sa resize(Index) for vectors, resize(NoChange_t, Index), resize(Index, NoChange_t)
-      */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
-    {
-      eigen_assert(   EIGEN_IMPLIES(RowsAtCompileTime!=Dynamic,rows==RowsAtCompileTime)
-                   && EIGEN_IMPLIES(ColsAtCompileTime!=Dynamic,cols==ColsAtCompileTime)
-                   && EIGEN_IMPLIES(RowsAtCompileTime==Dynamic && MaxRowsAtCompileTime!=Dynamic,rows<=MaxRowsAtCompileTime)
-                   && EIGEN_IMPLIES(ColsAtCompileTime==Dynamic && MaxColsAtCompileTime!=Dynamic,cols<=MaxColsAtCompileTime)
-                   && rows>=0 && cols>=0 && "Invalid sizes when resizing a matrix or array.");
-      internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(rows, cols);
-      #ifdef EIGEN_INITIALIZE_COEFFS
-        Index size = rows*cols;
-        bool size_changed = size != this->size();
-        m_storage.resize(size, rows, cols);
-        if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
-      #else
-        m_storage.resize(rows*cols, rows, cols);
-      #endif
-    }
-
-    /** Resizes \c *this to a vector of length \a size
-      *
-      * \only_for_vectors. This method does not work for
-      * partially dynamic matrices when the static dimension is anything other
-      * than 1. For example it will not work with Matrix<double, 2, Dynamic>.
-      *
-      * Example: \include Matrix_resize_int.cpp
-      * Output: \verbinclude Matrix_resize_int.out
-      *
-      * \sa resize(Index,Index), resize(NoChange_t, Index), resize(Index, NoChange_t)
-      */
-    EIGEN_DEVICE_FUNC
-    inline void resize(Index size)
-    {
-      EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase)
-      eigen_assert(((SizeAtCompileTime == Dynamic && (MaxSizeAtCompileTime==Dynamic || size<=MaxSizeAtCompileTime)) || SizeAtCompileTime == size) && size>=0);
-      #ifdef EIGEN_INITIALIZE_COEFFS
-        bool size_changed = size != this->size();
-      #endif
-      if(RowsAtCompileTime == 1)
-        m_storage.resize(size, 1, size);
-      else
-        m_storage.resize(size, size, 1);
-      #ifdef EIGEN_INITIALIZE_COEFFS
-        if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
-      #endif
-    }
-
-    /** Resizes the matrix, changing only the number of columns. For the parameter of type NoChange_t, just pass the special value \c NoChange
-      * as in the example below.
-      *
-      * Example: \include Matrix_resize_NoChange_int.cpp
-      * Output: \verbinclude Matrix_resize_NoChange_int.out
-      *
-      * \sa resize(Index,Index)
-      */
-    EIGEN_DEVICE_FUNC
-    inline void resize(NoChange_t, Index cols)
-    {
-      resize(rows(), cols);
-    }
-
-    /** Resizes the matrix, changing only the number of rows. For the parameter of type NoChange_t, just pass the special value \c NoChange
-      * as in the example below.
-      *
-      * Example: \include Matrix_resize_int_NoChange.cpp
-      * Output: \verbinclude Matrix_resize_int_NoChange.out
-      *
-      * \sa resize(Index,Index)
-      */
-    EIGEN_DEVICE_FUNC
-    inline void resize(Index rows, NoChange_t)
-    {
-      resize(rows, cols());
-    }
-
-    /** Resizes \c *this to have the same dimensions as \a other.
-      * Takes care of doing all the checking that's needed.
-      *
-      * Note that copying a row-vector into a vector (and conversely) is allowed.
-      * The resizing, if any, is then done in the appropriate way so that row-vectors
-      * remain row-vectors and vectors remain vectors.
-      */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC 
-    EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other)
-    {
-      const OtherDerived& other = _other.derived();
-      internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(other.rows(), other.cols());
-      const Index othersize = other.rows()*other.cols();
-      if(RowsAtCompileTime == 1)
-      {
-        eigen_assert(other.rows() == 1 || other.cols() == 1);
-        resize(1, othersize);
-      }
-      else if(ColsAtCompileTime == 1)
-      {
-        eigen_assert(other.rows() == 1 || other.cols() == 1);
-        resize(othersize, 1);
-      }
-      else resize(other.rows(), other.cols());
-    }
-
-    /** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
-      *
-      * The method is intended for matrices of dynamic size. If you only want to change the number
-      * of rows and/or of columns, you can use conservativeResize(NoChange_t, Index) or
-      * conservativeResize(Index, NoChange_t).
-      *
-      * Matrices are resized relative to the top-left element. In case values need to be 
-      * appended to the matrix they will be uninitialized.
-      */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE void conservativeResize(Index rows, Index cols)
-    {
-      internal::conservative_resize_like_impl<Derived>::run(*this, rows, cols);
-    }
-
-    /** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
-      *
-      * As opposed to conservativeResize(Index rows, Index cols), this version leaves
-      * the number of columns unchanged.
-      *
-      * In case the matrix is growing, new rows will be uninitialized.
-      */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE void conservativeResize(Index rows, NoChange_t)
-    {
-      // Note: see the comment in conservativeResize(Index,Index)
-      conservativeResize(rows, cols());
-    }
-
-    /** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
-      *
-      * As opposed to conservativeResize(Index rows, Index cols), this version leaves
-      * the number of rows unchanged.
-      *
-      * In case the matrix is growing, new columns will be uninitialized.
-      */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index cols)
-    {
-      // Note: see the comment in conservativeResize(Index,Index)
-      conservativeResize(rows(), cols);
-    }
-
-    /** Resizes the vector to \a size while retaining old values.
-      *
-      * \only_for_vectors. This method does not work for
-      * partially dynamic matrices when the static dimension is anything other
-      * than 1. For example it will not work with Matrix<double, 2, Dynamic>.
-      *
-      * When values are appended, they will be uninitialized.
-      */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE void conservativeResize(Index size)
-    {
-      internal::conservative_resize_like_impl<Derived>::run(*this, size);
-    }
-
-    /** Resizes the matrix to \a rows x \a cols of \c other, while leaving old values untouched.
-      *
-      * The method is intended for matrices of dynamic size. If you only want to change the number
-      * of rows and/or of columns, you can use conservativeResize(NoChange_t, Index) or
-      * conservativeResize(Index, NoChange_t).
-      *
-      * Matrices are resized relative to the top-left element. In case values need to be 
-      * appended to the matrix they will copied from \c other.
-      */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase<OtherDerived>& other)
-    {
-      internal::conservative_resize_like_impl<Derived,OtherDerived>::run(*this, other);
-    }
-
-    /** This is a special case of the templated operator=. Its purpose is to
-      * prevent a default operator= from hiding the templated operator=.
-      */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Derived& operator=(const PlainObjectBase& other)
-    {
-      return _set(other);
-    }
-
-    /** \sa MatrixBase::lazyAssign() */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Derived& lazyAssign(const DenseBase<OtherDerived>& other)
-    {
-      _resize_to_match(other);
-      return Base::lazyAssign(other.derived());
-    }
-
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE Derived& operator=(const ReturnByValue<OtherDerived>& func)
-    {
-      resize(func.rows(), func.cols());
-      return Base::operator=(func);
-    }
-
-    // Prevent user from trying to instantiate PlainObjectBase objects
-    // by making all its constructor protected. See bug 1074.
-  protected:
-
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE PlainObjectBase() : m_storage()
-    {
-//       _check_template_params();
-//       EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
-    }
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-    // FIXME is it still needed ?
-    /** \internal */
-    EIGEN_DEVICE_FUNC
-    explicit PlainObjectBase(internal::constructor_without_unaligned_array_assert)
-      : m_storage(internal::constructor_without_unaligned_array_assert())
-    {
-//       _check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
-    }
-#endif
-
-#if EIGEN_HAS_RVALUE_REFERENCES
-    EIGEN_DEVICE_FUNC
-    PlainObjectBase(PlainObjectBase&& other) EIGEN_NOEXCEPT
-      : m_storage( std::move(other.m_storage) )
-    {
-    }
-
-    EIGEN_DEVICE_FUNC
-    PlainObjectBase& operator=(PlainObjectBase&& other) EIGEN_NOEXCEPT
-    {
-      using std::swap;
-      swap(m_storage, other.m_storage);
-      return *this;
-    }
-#endif
-
-    /** Copy constructor */
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE PlainObjectBase(const PlainObjectBase& other)
-      : Base(), m_storage(other.m_storage) { }
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE PlainObjectBase(Index size, Index rows, Index cols)
-      : m_storage(size, rows, cols)
-    {
-//       _check_template_params();
-//       EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
-    }
-
-    /** \sa PlainObjectBase::operator=(const EigenBase<OtherDerived>&) */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE PlainObjectBase(const DenseBase<OtherDerived> &other)
-      : m_storage()
-    {
-      _check_template_params();
-      resizeLike(other);
-      _set_noalias(other);
-    }
-
-    /** \sa PlainObjectBase::operator=(const EigenBase<OtherDerived>&) */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase<OtherDerived> &other)
-      : m_storage()
-    {
-      _check_template_params();
-      resizeLike(other);
-      *this = other.derived();
-    }
-    /** \brief Copy constructor with in-place evaluation */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE PlainObjectBase(const ReturnByValue<OtherDerived>& other)
-    {
-      _check_template_params();
-      // FIXME this does not automatically transpose vectors if necessary
-      resize(other.rows(), other.cols());
-      other.evalTo(this->derived());
-    }
-
-  public:
-
-    /** \brief Copies the generic expression \a other into *this.
-      * \copydetails DenseBase::operator=(const EigenBase<OtherDerived> &other)
-      */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC 
-    EIGEN_STRONG_INLINE Derived& operator=(const EigenBase<OtherDerived> &other)
-    {
-      _resize_to_match(other);
-      Base::operator=(other.derived());
-      return this->derived();
-    }
-
-    /** \name Map
-      * These are convenience functions returning Map objects. The Map() static functions return unaligned Map objects,
-      * while the AlignedMap() functions return aligned Map objects and thus should be called only with 16-byte-aligned
-      * \a data pointers.
-      *
-      * Here is an example using strides:
-      * \include Matrix_Map_stride.cpp
-      * Output: \verbinclude Matrix_Map_stride.out
-      *
-      * \see class Map
-      */
-    //@{
-    static inline ConstMapType Map(const Scalar* data)
-    { return ConstMapType(data); }
-    static inline MapType Map(Scalar* data)
-    { return MapType(data); }
-    static inline ConstMapType Map(const Scalar* data, Index size)
-    { return ConstMapType(data, size); }
-    static inline MapType Map(Scalar* data, Index size)
-    { return MapType(data, size); }
-    static inline ConstMapType Map(const Scalar* data, Index rows, Index cols)
-    { return ConstMapType(data, rows, cols); }
-    static inline MapType Map(Scalar* data, Index rows, Index cols)
-    { return MapType(data, rows, cols); }
-
-    static inline ConstAlignedMapType MapAligned(const Scalar* data)
-    { return ConstAlignedMapType(data); }
-    static inline AlignedMapType MapAligned(Scalar* data)
-    { return AlignedMapType(data); }
-    static inline ConstAlignedMapType MapAligned(const Scalar* data, Index size)
-    { return ConstAlignedMapType(data, size); }
-    static inline AlignedMapType MapAligned(Scalar* data, Index size)
-    { return AlignedMapType(data, size); }
-    static inline ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols)
-    { return ConstAlignedMapType(data, rows, cols); }
-    static inline AlignedMapType MapAligned(Scalar* data, Index rows, Index cols)
-    { return AlignedMapType(data, rows, cols); }
-
-    template<int Outer, int Inner>
-    static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, const Stride<Outer, Inner>& stride)
-    { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, stride); }
-    template<int Outer, int Inner>
-    static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, const Stride<Outer, Inner>& stride)
-    { return typename StridedMapType<Stride<Outer, Inner> >::type(data, stride); }
-    template<int Outer, int Inner>
-    static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
-    { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, size, stride); }
-    template<int Outer, int Inner>
-    static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
-    { return typename StridedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
-    template<int Outer, int Inner>
-    static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
-    { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
-    template<int Outer, int Inner>
-    static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
-    { return typename StridedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
-
-    template<int Outer, int Inner>
-    static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, const Stride<Outer, Inner>& stride)
-    { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
-    template<int Outer, int Inner>
-    static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, const Stride<Outer, Inner>& stride)
-    { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
-    template<int Outer, int Inner>
-    static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
-    { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
-    template<int Outer, int Inner>
-    static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
-    { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
-    template<int Outer, int Inner>
-    static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
-    { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
-    template<int Outer, int Inner>
-    static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
-    { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
-    //@}
-
-    using Base::setConstant;
-    EIGEN_DEVICE_FUNC Derived& setConstant(Index size, const Scalar& val);
-    EIGEN_DEVICE_FUNC Derived& setConstant(Index rows, Index cols, const Scalar& val);
-
-    using Base::setZero;
-    EIGEN_DEVICE_FUNC Derived& setZero(Index size);
-    EIGEN_DEVICE_FUNC Derived& setZero(Index rows, Index cols);
-
-    using Base::setOnes;
-    EIGEN_DEVICE_FUNC Derived& setOnes(Index size);
-    EIGEN_DEVICE_FUNC Derived& setOnes(Index rows, Index cols);
-
-    using Base::setRandom;
-    Derived& setRandom(Index size);
-    Derived& setRandom(Index rows, Index cols);
-
-    #ifdef EIGEN_PLAINOBJECTBASE_PLUGIN
-    #include EIGEN_PLAINOBJECTBASE_PLUGIN
-    #endif
-
-  protected:
-    /** \internal Resizes *this in preparation for assigning \a other to it.
-      * Takes care of doing all the checking that's needed.
-      *
-      * Note that copying a row-vector into a vector (and conversely) is allowed.
-      * The resizing, if any, is then done in the appropriate way so that row-vectors
-      * remain row-vectors and vectors remain vectors.
-      */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC 
-    EIGEN_STRONG_INLINE void _resize_to_match(const EigenBase<OtherDerived>& other)
-    {
-      #ifdef EIGEN_NO_AUTOMATIC_RESIZING
-      eigen_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size())
-                 : (rows() == other.rows() && cols() == other.cols())))
-        && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined");
-      EIGEN_ONLY_USED_FOR_DEBUG(other);
-      #else
-      resizeLike(other);
-      #endif
-    }
-
-    /**
-      * \brief Copies the value of the expression \a other into \c *this with automatic resizing.
-      *
-      * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized),
-      * it will be initialized.
-      *
-      * Note that copying a row-vector into a vector (and conversely) is allowed.
-      * The resizing, if any, is then done in the appropriate way so that row-vectors
-      * remain row-vectors and vectors remain vectors.
-      *
-      * \sa operator=(const MatrixBase<OtherDerived>&), _set_noalias()
-      *
-      * \internal
-      */
-    // aliasing is dealt once in internall::call_assignment
-    // so at this stage we have to assume aliasing... and resising has to be done later.
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC 
-    EIGEN_STRONG_INLINE Derived& _set(const DenseBase<OtherDerived>& other)
-    {
-      internal::call_assignment(this->derived(), other.derived());
-      return this->derived();
-    }
-
-    /** \internal Like _set() but additionally makes the assumption that no aliasing effect can happen (which
-      * is the case when creating a new matrix) so one can enforce lazy evaluation.
-      *
-      * \sa operator=(const MatrixBase<OtherDerived>&), _set()
-      */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC 
-    EIGEN_STRONG_INLINE Derived& _set_noalias(const DenseBase<OtherDerived>& other)
-    {
-      // I don't think we need this resize call since the lazyAssign will anyways resize
-      // and lazyAssign will be called by the assign selector.
-      //_resize_to_match(other);
-      // the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because
-      // it wouldn't allow to copy a row-vector into a column-vector.
-      internal::call_assignment_no_alias(this->derived(), other.derived(), internal::assign_op<Scalar,typename OtherDerived::Scalar>());
-      return this->derived();
-    }
-
-    template<typename T0, typename T1>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, typename internal::enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0)
-    {
-      EIGEN_STATIC_ASSERT(bool(NumTraits<T0>::IsInteger) &&
-                          bool(NumTraits<T1>::IsInteger),
-                          FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
-      resize(rows,cols);
-    }
-    
-    template<typename T0, typename T1>
-    EIGEN_DEVICE_FUNC 
-    EIGEN_STRONG_INLINE void _init2(const T0& val0, const T1& val1, typename internal::enable_if<Base::SizeAtCompileTime==2,T0>::type* = 0)
-    {
-      EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
-      m_storage.data()[0] = Scalar(val0);
-      m_storage.data()[1] = Scalar(val1);
-    }
-    
-    template<typename T0, typename T1>
-    EIGEN_DEVICE_FUNC 
-    EIGEN_STRONG_INLINE void _init2(const Index& val0, const Index& val1,
-                                    typename internal::enable_if<    (!internal::is_same<Index,Scalar>::value)
-                                                                  && (internal::is_same<T0,Index>::value)
-                                                                  && (internal::is_same<T1,Index>::value)
-                                                                  && Base::SizeAtCompileTime==2,T1>::type* = 0)
-    {
-      EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
-      m_storage.data()[0] = Scalar(val0);
-      m_storage.data()[1] = Scalar(val1);
-    }
-
-    // The argument is convertible to the Index type and we either have a non 1x1 Matrix, or a dynamic-sized Array,
-    // then the argument is meant to be the size of the object.
-    template<typename T>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE void _init1(Index size, typename internal::enable_if<    (Base::SizeAtCompileTime!=1 || !internal::is_convertible<T, Scalar>::value)
-                                                                              && ((!internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value || Base::SizeAtCompileTime==Dynamic)),T>::type* = 0)
-    {
-      // NOTE MSVC 2008 complains if we directly put bool(NumTraits<T>::IsInteger) as the EIGEN_STATIC_ASSERT argument.
-      const bool is_integer = NumTraits<T>::IsInteger;
-      EIGEN_UNUSED_VARIABLE(is_integer);
-      EIGEN_STATIC_ASSERT(is_integer,
-                          FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
-      resize(size);
-    }
-    
-    // We have a 1x1 matrix/array => the argument is interpreted as the value of the unique coefficient (case where scalar type can be implicitely converted)
-    template<typename T>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE void _init1(const Scalar& val0, typename internal::enable_if<Base::SizeAtCompileTime==1 && internal::is_convertible<T, Scalar>::value,T>::type* = 0)
-    {
-      EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 1)
-      m_storage.data()[0] = val0;
-    }
-    
-    // We have a 1x1 matrix/array => the argument is interpreted as the value of the unique coefficient (case where scalar type match the index type)
-    template<typename T>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE void _init1(const Index& val0,
-                                    typename internal::enable_if<    (!internal::is_same<Index,Scalar>::value)
-                                                                  && (internal::is_same<Index,T>::value)
-                                                                  && Base::SizeAtCompileTime==1
-                                                                  && internal::is_convertible<T, Scalar>::value,T*>::type* = 0)
-    {
-      EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 1)
-      m_storage.data()[0] = Scalar(val0);
-    }
-
-    // Initialize a fixed size matrix from a pointer to raw data
-    template<typename T>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE void _init1(const Scalar* data){
-      this->_set_noalias(ConstMapType(data));
-    }
-
-    // Initialize an arbitrary matrix from a dense expression
-    template<typename T, typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE void _init1(const DenseBase<OtherDerived>& other){
-      this->_set_noalias(other);
-    }
-
-    // Initialize an arbitrary matrix from an object convertible to the Derived type.
-    template<typename T>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE void _init1(const Derived& other){
-      this->_set_noalias(other);
-    }
-
-    // Initialize an arbitrary matrix from a generic Eigen expression
-    template<typename T, typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE void _init1(const EigenBase<OtherDerived>& other){
-      this->derived() = other;
-    }
-
-    template<typename T, typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE void _init1(const ReturnByValue<OtherDerived>& other)
-    {
-      resize(other.rows(), other.cols());
-      other.evalTo(this->derived());
-    }
-
-    template<typename T, typename OtherDerived, int ColsAtCompileTime>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE void _init1(const RotationBase<OtherDerived,ColsAtCompileTime>& r)
-    {
-      this->derived() = r;
-    }
-    
-    // For fixed-size Array<Scalar,...>
-    template<typename T>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE void _init1(const Scalar& val0,
-                                    typename internal::enable_if<    Base::SizeAtCompileTime!=Dynamic
-                                                                  && Base::SizeAtCompileTime!=1
-                                                                  && internal::is_convertible<T, Scalar>::value
-                                                                  && internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value,T>::type* = 0)
-    {
-      Base::setConstant(val0);
-    }
-    
-    // For fixed-size Array<Index,...>
-    template<typename T>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE void _init1(const Index& val0,
-                                    typename internal::enable_if<    (!internal::is_same<Index,Scalar>::value)
-                                                                  && (internal::is_same<Index,T>::value)
-                                                                  && Base::SizeAtCompileTime!=Dynamic
-                                                                  && Base::SizeAtCompileTime!=1
-                                                                  && internal::is_convertible<T, Scalar>::value
-                                                                  && internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value,T*>::type* = 0)
-    {
-      Base::setConstant(val0);
-    }
-    
-    template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
-    friend struct internal::matrix_swap_impl;
-
-  public:
-    
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-    /** \internal
-      * \brief Override DenseBase::swap() since for dynamic-sized matrices
-      * of same type it is enough to swap the data pointers.
-      */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    void swap(DenseBase<OtherDerived> & other)
-    {
-      enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic };
-      internal::matrix_swap_impl<Derived, OtherDerived, bool(SwapPointers)>::run(this->derived(), other.derived());
-    }
-    
-    /** \internal
-      * \brief const version forwarded to DenseBase::swap
-      */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    void swap(DenseBase<OtherDerived> const & other)
-    { Base::swap(other.derived()); }
-    
-    EIGEN_DEVICE_FUNC 
-    static EIGEN_STRONG_INLINE void _check_template_params()
-    {
-      EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor)
-                        && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0)
-                        && ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0))
-                        && ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0))
-                        && ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0))
-                        && ((MaxColsAtCompileTime == Dynamic) || (MaxColsAtCompileTime >= 0))
-                        && (MaxRowsAtCompileTime == RowsAtCompileTime || RowsAtCompileTime==Dynamic)
-                        && (MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime==Dynamic)
-                        && (Options & (DontAlign|RowMajor)) == Options),
-        INVALID_MATRIX_TEMPLATE_PARAMETERS)
-    }
-
-    enum { IsPlainObjectBase = 1 };
-#endif
-};
-
-namespace internal {
-
-template <typename Derived, typename OtherDerived, bool IsVector>
-struct conservative_resize_like_impl
-{
-  static void run(DenseBase<Derived>& _this, Index rows, Index cols)
-  {
-    if (_this.rows() == rows && _this.cols() == cols) return;
-    EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
-
-    if ( ( Derived::IsRowMajor && _this.cols() == cols) || // row-major and we change only the number of rows
-         (!Derived::IsRowMajor && _this.rows() == rows) )  // column-major and we change only the number of columns
-    {
-      internal::check_rows_cols_for_overflow<Derived::MaxSizeAtCompileTime>::run(rows, cols);
-      _this.derived().m_storage.conservativeResize(rows*cols,rows,cols);
-    }
-    else
-    {
-      // The storage order does not allow us to use reallocation.
-      typename Derived::PlainObject tmp(rows,cols);
-      const Index common_rows = numext::mini(rows, _this.rows());
-      const Index common_cols = numext::mini(cols, _this.cols());
-      tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
-      _this.derived().swap(tmp);
-    }
-  }
-
-  static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
-  {
-    if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
-
-    // Note: Here is space for improvement. Basically, for conservativeResize(Index,Index),
-    // neither RowsAtCompileTime or ColsAtCompileTime must be Dynamic. If only one of the
-    // dimensions is dynamic, one could use either conservativeResize(Index rows, NoChange_t) or
-    // conservativeResize(NoChange_t, Index cols). For these methods new static asserts like
-    // EIGEN_STATIC_ASSERT_DYNAMIC_ROWS and EIGEN_STATIC_ASSERT_DYNAMIC_COLS would be good.
-    EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
-    EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived)
-
-    if ( ( Derived::IsRowMajor && _this.cols() == other.cols()) || // row-major and we change only the number of rows
-         (!Derived::IsRowMajor && _this.rows() == other.rows()) )  // column-major and we change only the number of columns
-    {
-      const Index new_rows = other.rows() - _this.rows();
-      const Index new_cols = other.cols() - _this.cols();
-      _this.derived().m_storage.conservativeResize(other.size(),other.rows(),other.cols());
-      if (new_rows>0)
-        _this.bottomRightCorner(new_rows, other.cols()) = other.bottomRows(new_rows);
-      else if (new_cols>0)
-        _this.bottomRightCorner(other.rows(), new_cols) = other.rightCols(new_cols);
-    }
-    else
-    {
-      // The storage order does not allow us to use reallocation.
-      typename Derived::PlainObject tmp(other);
-      const Index common_rows = numext::mini(tmp.rows(), _this.rows());
-      const Index common_cols = numext::mini(tmp.cols(), _this.cols());
-      tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
-      _this.derived().swap(tmp);
-    }
-  }
-};
-
-// Here, the specialization for vectors inherits from the general matrix case
-// to allow calling .conservativeResize(rows,cols) on vectors.
-template <typename Derived, typename OtherDerived>
-struct conservative_resize_like_impl<Derived,OtherDerived,true>
-  : conservative_resize_like_impl<Derived,OtherDerived,false>
-{
-  using conservative_resize_like_impl<Derived,OtherDerived,false>::run;
-  
-  static void run(DenseBase<Derived>& _this, Index size)
-  {
-    const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size;
-    const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1;
-    _this.derived().m_storage.conservativeResize(size,new_rows,new_cols);
-  }
-
-  static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
-  {
-    if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
-
-    const Index num_new_elements = other.size() - _this.size();
-
-    const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows();
-    const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1;
-    _this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols);
-
-    if (num_new_elements > 0)
-      _this.tail(num_new_elements) = other.tail(num_new_elements);
-  }
-};
-
-template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
-struct matrix_swap_impl
-{
-  EIGEN_DEVICE_FUNC
-  static inline void run(MatrixTypeA& a, MatrixTypeB& b)
-  {
-    a.base().swap(b);
-  }
-};
-
-template<typename MatrixTypeA, typename MatrixTypeB>
-struct matrix_swap_impl<MatrixTypeA, MatrixTypeB, true>
-{
-  EIGEN_DEVICE_FUNC
-  static inline void run(MatrixTypeA& a, MatrixTypeB& b)
-  {
-    static_cast<typename MatrixTypeA::Base&>(a).m_storage.swap(static_cast<typename MatrixTypeB::Base&>(b).m_storage);
-  }
-};
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_DENSESTORAGEBASE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Product.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Product.h
deleted file mode 100644
index 676c480..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Product.h
+++ /dev/null
@@ -1,186 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_PRODUCT_H
-#define EIGEN_PRODUCT_H
-
-namespace Eigen {
-
-template<typename Lhs, typename Rhs, int Option, typename StorageKind> class ProductImpl;
-
-namespace internal {
-
-template<typename Lhs, typename Rhs, int Option>
-struct traits<Product<Lhs, Rhs, Option> >
-{
-  typedef typename remove_all<Lhs>::type LhsCleaned;
-  typedef typename remove_all<Rhs>::type RhsCleaned;
-  typedef traits<LhsCleaned> LhsTraits;
-  typedef traits<RhsCleaned> RhsTraits;
-  
-  typedef MatrixXpr XprKind;
-  
-  typedef typename ScalarBinaryOpTraits<typename traits<LhsCleaned>::Scalar, typename traits<RhsCleaned>::Scalar>::ReturnType Scalar;
-  typedef typename product_promote_storage_type<typename LhsTraits::StorageKind,
-                                                typename RhsTraits::StorageKind,
-                                                internal::product_type<Lhs,Rhs>::ret>::ret StorageKind;
-  typedef typename promote_index_type<typename LhsTraits::StorageIndex,
-                                      typename RhsTraits::StorageIndex>::type StorageIndex;
-  
-  enum {
-    RowsAtCompileTime    = LhsTraits::RowsAtCompileTime,
-    ColsAtCompileTime    = RhsTraits::ColsAtCompileTime,
-    MaxRowsAtCompileTime = LhsTraits::MaxRowsAtCompileTime,
-    MaxColsAtCompileTime = RhsTraits::MaxColsAtCompileTime,
-    
-    // FIXME: only needed by GeneralMatrixMatrixTriangular
-    InnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(LhsTraits::ColsAtCompileTime, RhsTraits::RowsAtCompileTime),
-    
-    // The storage order is somewhat arbitrary here. The correct one will be determined through the evaluator.
-    Flags = (MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1) ? RowMajorBit
-          : (MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1) ? 0
-          : (   ((LhsTraits::Flags&NoPreferredStorageOrderBit) && (RhsTraits::Flags&RowMajorBit))
-             || ((RhsTraits::Flags&NoPreferredStorageOrderBit) && (LhsTraits::Flags&RowMajorBit)) ) ? RowMajorBit
-          : NoPreferredStorageOrderBit
-  };
-};
-
-} // end namespace internal
-
-/** \class Product
-  * \ingroup Core_Module
-  *
-  * \brief Expression of the product of two arbitrary matrices or vectors
-  *
-  * \tparam _Lhs the type of the left-hand side expression
-  * \tparam _Rhs the type of the right-hand side expression
-  *
-  * This class represents an expression of the product of two arbitrary matrices.
-  *
-  * The other template parameters are:
-  * \tparam Option     can be DefaultProduct, AliasFreeProduct, or LazyProduct
-  *
-  */
-template<typename _Lhs, typename _Rhs, int Option>
-class Product : public ProductImpl<_Lhs,_Rhs,Option,
-                                   typename internal::product_promote_storage_type<typename internal::traits<_Lhs>::StorageKind,
-                                                                                   typename internal::traits<_Rhs>::StorageKind,
-                                                                                   internal::product_type<_Lhs,_Rhs>::ret>::ret>
-{
-  public:
-    
-    typedef _Lhs Lhs;
-    typedef _Rhs Rhs;
-    
-    typedef typename ProductImpl<
-        Lhs, Rhs, Option,
-        typename internal::product_promote_storage_type<typename internal::traits<Lhs>::StorageKind,
-                                                        typename internal::traits<Rhs>::StorageKind,
-                                                        internal::product_type<Lhs,Rhs>::ret>::ret>::Base Base;
-    EIGEN_GENERIC_PUBLIC_INTERFACE(Product)
-
-    typedef typename internal::ref_selector<Lhs>::type LhsNested;
-    typedef typename internal::ref_selector<Rhs>::type RhsNested;
-    typedef typename internal::remove_all<LhsNested>::type LhsNestedCleaned;
-    typedef typename internal::remove_all<RhsNested>::type RhsNestedCleaned;
-
-    EIGEN_DEVICE_FUNC Product(const Lhs& lhs, const Rhs& rhs) : m_lhs(lhs), m_rhs(rhs)
-    {
-      eigen_assert(lhs.cols() == rhs.rows()
-        && "invalid matrix product"
-        && "if you wanted a coeff-wise or a dot product use the respective explicit functions");
-    }
-
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rows() const { return m_lhs.rows(); }
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index cols() const { return m_rhs.cols(); }
-
-    EIGEN_DEVICE_FUNC const LhsNestedCleaned& lhs() const { return m_lhs; }
-    EIGEN_DEVICE_FUNC const RhsNestedCleaned& rhs() const { return m_rhs; }
-
-  protected:
-
-    LhsNested m_lhs;
-    RhsNested m_rhs;
-};
-
-namespace internal {
-  
-template<typename Lhs, typename Rhs, int Option, int ProductTag = internal::product_type<Lhs,Rhs>::ret>
-class dense_product_base
- : public internal::dense_xpr_base<Product<Lhs,Rhs,Option> >::type
-{};
-
-/** Convertion to scalar for inner-products */
-template<typename Lhs, typename Rhs, int Option>
-class dense_product_base<Lhs, Rhs, Option, InnerProduct>
- : public internal::dense_xpr_base<Product<Lhs,Rhs,Option> >::type
-{
-  typedef Product<Lhs,Rhs,Option> ProductXpr;
-  typedef typename internal::dense_xpr_base<ProductXpr>::type Base;
-public:
-  using Base::derived;
-  typedef typename Base::Scalar Scalar;
-  
-  EIGEN_STRONG_INLINE operator const Scalar() const
-  {
-    return internal::evaluator<ProductXpr>(derived()).coeff(0,0);
-  }
-};
-
-} // namespace internal
-
-// Generic API dispatcher
-template<typename Lhs, typename Rhs, int Option, typename StorageKind>
-class ProductImpl : public internal::generic_xpr_base<Product<Lhs,Rhs,Option>, MatrixXpr, StorageKind>::type
-{
-  public:
-    typedef typename internal::generic_xpr_base<Product<Lhs,Rhs,Option>, MatrixXpr, StorageKind>::type Base;
-};
-
-template<typename Lhs, typename Rhs, int Option>
-class ProductImpl<Lhs,Rhs,Option,Dense>
-  : public internal::dense_product_base<Lhs,Rhs,Option>
-{
-    typedef Product<Lhs, Rhs, Option> Derived;
-    
-  public:
-    
-    typedef typename internal::dense_product_base<Lhs, Rhs, Option> Base;
-    EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
-  protected:
-    enum {
-      IsOneByOne = (RowsAtCompileTime == 1 || RowsAtCompileTime == Dynamic) && 
-                   (ColsAtCompileTime == 1 || ColsAtCompileTime == Dynamic),
-      EnableCoeff = IsOneByOne || Option==LazyProduct
-    };
-    
-  public:
-  
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar coeff(Index row, Index col) const
-    {
-      EIGEN_STATIC_ASSERT(EnableCoeff, THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS);
-      eigen_assert( (Option==LazyProduct) || (this->rows() == 1 && this->cols() == 1) );
-      
-      return internal::evaluator<Derived>(derived()).coeff(row,col);
-    }
-
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar coeff(Index i) const
-    {
-      EIGEN_STATIC_ASSERT(EnableCoeff, THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS);
-      eigen_assert( (Option==LazyProduct) || (this->rows() == 1 && this->cols() == 1) );
-      
-      return internal::evaluator<Derived>(derived()).coeff(i);
-    }
-    
-  
-};
-
-} // end namespace Eigen
-
-#endif // EIGEN_PRODUCT_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/ProductEvaluators.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/ProductEvaluators.h
deleted file mode 100644
index 9b99bd7..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/ProductEvaluators.h
+++ /dev/null
@@ -1,1112 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2011 Jitse Niesen <jitse@maths.leeds.ac.uk>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-
-#ifndef EIGEN_PRODUCTEVALUATORS_H
-#define EIGEN_PRODUCTEVALUATORS_H
-
-namespace Eigen {
-  
-namespace internal {
-
-/** \internal
-  * Evaluator of a product expression.
-  * Since products require special treatments to handle all possible cases,
-  * we simply deffer the evaluation logic to a product_evaluator class
-  * which offers more partial specialization possibilities.
-  * 
-  * \sa class product_evaluator
-  */
-template<typename Lhs, typename Rhs, int Options>
-struct evaluator<Product<Lhs, Rhs, Options> > 
- : public product_evaluator<Product<Lhs, Rhs, Options> >
-{
-  typedef Product<Lhs, Rhs, Options> XprType;
-  typedef product_evaluator<XprType> Base;
-  
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit evaluator(const XprType& xpr) : Base(xpr) {}
-};
- 
-// Catch "scalar * ( A * B )" and transform it to "(A*scalar) * B"
-// TODO we should apply that rule only if that's really helpful
-template<typename Lhs, typename Rhs, typename Scalar1, typename Scalar2, typename Plain1>
-struct evaluator_assume_aliasing<CwiseBinaryOp<internal::scalar_product_op<Scalar1,Scalar2>,
-                                               const CwiseNullaryOp<internal::scalar_constant_op<Scalar1>, Plain1>,
-                                               const Product<Lhs, Rhs, DefaultProduct> > >
-{
-  static const bool value = true;
-};
-template<typename Lhs, typename Rhs, typename Scalar1, typename Scalar2, typename Plain1>
-struct evaluator<CwiseBinaryOp<internal::scalar_product_op<Scalar1,Scalar2>,
-                               const CwiseNullaryOp<internal::scalar_constant_op<Scalar1>, Plain1>,
-                               const Product<Lhs, Rhs, DefaultProduct> > >
- : public evaluator<Product<EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar1,Lhs,product), Rhs, DefaultProduct> >
-{
-  typedef CwiseBinaryOp<internal::scalar_product_op<Scalar1,Scalar2>,
-                               const CwiseNullaryOp<internal::scalar_constant_op<Scalar1>, Plain1>,
-                               const Product<Lhs, Rhs, DefaultProduct> > XprType;
-  typedef evaluator<Product<EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar1,Lhs,product), Rhs, DefaultProduct> > Base;
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit evaluator(const XprType& xpr)
-    : Base(xpr.lhs().functor().m_other * xpr.rhs().lhs() * xpr.rhs().rhs())
-  {}
-};
-
-
-template<typename Lhs, typename Rhs, int DiagIndex>
-struct evaluator<Diagonal<const Product<Lhs, Rhs, DefaultProduct>, DiagIndex> > 
- : public evaluator<Diagonal<const Product<Lhs, Rhs, LazyProduct>, DiagIndex> >
-{
-  typedef Diagonal<const Product<Lhs, Rhs, DefaultProduct>, DiagIndex> XprType;
-  typedef evaluator<Diagonal<const Product<Lhs, Rhs, LazyProduct>, DiagIndex> > Base;
-  
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit evaluator(const XprType& xpr)
-    : Base(Diagonal<const Product<Lhs, Rhs, LazyProduct>, DiagIndex>(
-        Product<Lhs, Rhs, LazyProduct>(xpr.nestedExpression().lhs(), xpr.nestedExpression().rhs()),
-        xpr.index() ))
-  {}
-};
-
-
-// Helper class to perform a matrix product with the destination at hand.
-// Depending on the sizes of the factors, there are different evaluation strategies
-// as controlled by internal::product_type.
-template< typename Lhs, typename Rhs,
-          typename LhsShape = typename evaluator_traits<Lhs>::Shape,
-          typename RhsShape = typename evaluator_traits<Rhs>::Shape,
-          int ProductType = internal::product_type<Lhs,Rhs>::value>
-struct generic_product_impl;
-
-template<typename Lhs, typename Rhs>
-struct evaluator_assume_aliasing<Product<Lhs, Rhs, DefaultProduct> > {
-  static const bool value = true;
-};
-
-// This is the default evaluator implementation for products:
-// It creates a temporary and call generic_product_impl
-template<typename Lhs, typename Rhs, int Options, int ProductTag, typename LhsShape, typename RhsShape>
-struct product_evaluator<Product<Lhs, Rhs, Options>, ProductTag, LhsShape, RhsShape>
-  : public evaluator<typename Product<Lhs, Rhs, Options>::PlainObject>
-{
-  typedef Product<Lhs, Rhs, Options> XprType;
-  typedef typename XprType::PlainObject PlainObject;
-  typedef evaluator<PlainObject> Base;
-  enum {
-    Flags = Base::Flags | EvalBeforeNestingBit
-  };
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  explicit product_evaluator(const XprType& xpr)
-    : m_result(xpr.rows(), xpr.cols())
-  {
-    ::new (static_cast<Base*>(this)) Base(m_result);
-    
-// FIXME shall we handle nested_eval here?,
-// if so, then we must take care at removing the call to nested_eval in the specializations (e.g., in permutation_matrix_product, transposition_matrix_product, etc.)
-//     typedef typename internal::nested_eval<Lhs,Rhs::ColsAtCompileTime>::type LhsNested;
-//     typedef typename internal::nested_eval<Rhs,Lhs::RowsAtCompileTime>::type RhsNested;
-//     typedef typename internal::remove_all<LhsNested>::type LhsNestedCleaned;
-//     typedef typename internal::remove_all<RhsNested>::type RhsNestedCleaned;
-//     
-//     const LhsNested lhs(xpr.lhs());
-//     const RhsNested rhs(xpr.rhs());
-//   
-//     generic_product_impl<LhsNestedCleaned, RhsNestedCleaned>::evalTo(m_result, lhs, rhs);
-
-    generic_product_impl<Lhs, Rhs, LhsShape, RhsShape, ProductTag>::evalTo(m_result, xpr.lhs(), xpr.rhs());
-  }
-  
-protected:  
-  PlainObject m_result;
-};
-
-// The following three shortcuts are enabled only if the scalar types match excatly.
-// TODO: we could enable them for different scalar types when the product is not vectorized.
-
-// Dense = Product
-template< typename DstXprType, typename Lhs, typename Rhs, int Options, typename Scalar>
-struct Assignment<DstXprType, Product<Lhs,Rhs,Options>, internal::assign_op<Scalar,Scalar>, Dense2Dense,
-  typename enable_if<(Options==DefaultProduct || Options==AliasFreeProduct)>::type>
-{
-  typedef Product<Lhs,Rhs,Options> SrcXprType;
-  static EIGEN_STRONG_INLINE
-  void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,Scalar> &)
-  {
-    Index dstRows = src.rows();
-    Index dstCols = src.cols();
-    if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
-      dst.resize(dstRows, dstCols);
-    // FIXME shall we handle nested_eval here?
-    generic_product_impl<Lhs, Rhs>::evalTo(dst, src.lhs(), src.rhs());
-  }
-};
-
-// Dense += Product
-template< typename DstXprType, typename Lhs, typename Rhs, int Options, typename Scalar>
-struct Assignment<DstXprType, Product<Lhs,Rhs,Options>, internal::add_assign_op<Scalar,Scalar>, Dense2Dense,
-  typename enable_if<(Options==DefaultProduct || Options==AliasFreeProduct)>::type>
-{
-  typedef Product<Lhs,Rhs,Options> SrcXprType;
-  static EIGEN_STRONG_INLINE
-  void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<Scalar,Scalar> &)
-  {
-    eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
-    // FIXME shall we handle nested_eval here?
-    generic_product_impl<Lhs, Rhs>::addTo(dst, src.lhs(), src.rhs());
-  }
-};
-
-// Dense -= Product
-template< typename DstXprType, typename Lhs, typename Rhs, int Options, typename Scalar>
-struct Assignment<DstXprType, Product<Lhs,Rhs,Options>, internal::sub_assign_op<Scalar,Scalar>, Dense2Dense,
-  typename enable_if<(Options==DefaultProduct || Options==AliasFreeProduct)>::type>
-{
-  typedef Product<Lhs,Rhs,Options> SrcXprType;
-  static EIGEN_STRONG_INLINE
-  void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<Scalar,Scalar> &)
-  {
-    eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
-    // FIXME shall we handle nested_eval here?
-    generic_product_impl<Lhs, Rhs>::subTo(dst, src.lhs(), src.rhs());
-  }
-};
-
-
-// Dense ?= scalar * Product
-// TODO we should apply that rule if that's really helpful
-// for instance, this is not good for inner products
-template< typename DstXprType, typename Lhs, typename Rhs, typename AssignFunc, typename Scalar, typename ScalarBis, typename Plain>
-struct Assignment<DstXprType, CwiseBinaryOp<internal::scalar_product_op<ScalarBis,Scalar>, const CwiseNullaryOp<internal::scalar_constant_op<ScalarBis>,Plain>,
-                                           const Product<Lhs,Rhs,DefaultProduct> >, AssignFunc, Dense2Dense>
-{
-  typedef CwiseBinaryOp<internal::scalar_product_op<ScalarBis,Scalar>,
-                        const CwiseNullaryOp<internal::scalar_constant_op<ScalarBis>,Plain>,
-                        const Product<Lhs,Rhs,DefaultProduct> > SrcXprType;
-  static EIGEN_STRONG_INLINE
-  void run(DstXprType &dst, const SrcXprType &src, const AssignFunc& func)
-  {
-    call_assignment_no_alias(dst, (src.lhs().functor().m_other * src.rhs().lhs())*src.rhs().rhs(), func);
-  }
-};
-
-//----------------------------------------
-// Catch "Dense ?= xpr + Product<>" expression to save one temporary
-// FIXME we could probably enable these rules for any product, i.e., not only Dense and DefaultProduct
-
-template<typename OtherXpr, typename Lhs, typename Rhs>
-struct evaluator_assume_aliasing<CwiseBinaryOp<internal::scalar_sum_op<typename OtherXpr::Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, const OtherXpr,
-                                               const Product<Lhs,Rhs,DefaultProduct> >, DenseShape > {
-  static const bool value = true;
-};
-
-template<typename OtherXpr, typename Lhs, typename Rhs>
-struct evaluator_assume_aliasing<CwiseBinaryOp<internal::scalar_difference_op<typename OtherXpr::Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, const OtherXpr,
-                                               const Product<Lhs,Rhs,DefaultProduct> >, DenseShape > {
-  static const bool value = true;
-};
-
-template<typename DstXprType, typename OtherXpr, typename ProductType, typename Func1, typename Func2>
-struct assignment_from_xpr_op_product
-{
-  template<typename SrcXprType, typename InitialFunc>
-  static EIGEN_STRONG_INLINE
-  void run(DstXprType &dst, const SrcXprType &src, const InitialFunc& /*func*/)
-  {
-    call_assignment_no_alias(dst, src.lhs(), Func1());
-    call_assignment_no_alias(dst, src.rhs(), Func2());
-  }
-};
-
-#define EIGEN_CATCH_ASSIGN_XPR_OP_PRODUCT(ASSIGN_OP,BINOP,ASSIGN_OP2) \
-  template< typename DstXprType, typename OtherXpr, typename Lhs, typename Rhs, typename DstScalar, typename SrcScalar, typename OtherScalar,typename ProdScalar> \
-  struct Assignment<DstXprType, CwiseBinaryOp<internal::BINOP<OtherScalar,ProdScalar>, const OtherXpr, \
-                                            const Product<Lhs,Rhs,DefaultProduct> >, internal::ASSIGN_OP<DstScalar,SrcScalar>, Dense2Dense> \
-    : assignment_from_xpr_op_product<DstXprType, OtherXpr, Product<Lhs,Rhs,DefaultProduct>, internal::ASSIGN_OP<DstScalar,OtherScalar>, internal::ASSIGN_OP2<DstScalar,ProdScalar> > \
-  {}
-
-EIGEN_CATCH_ASSIGN_XPR_OP_PRODUCT(assign_op,    scalar_sum_op,add_assign_op);
-EIGEN_CATCH_ASSIGN_XPR_OP_PRODUCT(add_assign_op,scalar_sum_op,add_assign_op);
-EIGEN_CATCH_ASSIGN_XPR_OP_PRODUCT(sub_assign_op,scalar_sum_op,sub_assign_op);
-
-EIGEN_CATCH_ASSIGN_XPR_OP_PRODUCT(assign_op,    scalar_difference_op,sub_assign_op);
-EIGEN_CATCH_ASSIGN_XPR_OP_PRODUCT(add_assign_op,scalar_difference_op,sub_assign_op);
-EIGEN_CATCH_ASSIGN_XPR_OP_PRODUCT(sub_assign_op,scalar_difference_op,add_assign_op);
-
-//----------------------------------------
-
-template<typename Lhs, typename Rhs>
-struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,InnerProduct>
-{
-  template<typename Dst>
-  static EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
-  {
-    dst.coeffRef(0,0) = (lhs.transpose().cwiseProduct(rhs)).sum();
-  }
-  
-  template<typename Dst>
-  static EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
-  {
-    dst.coeffRef(0,0) += (lhs.transpose().cwiseProduct(rhs)).sum();
-  }
-  
-  template<typename Dst>
-  static EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
-  { dst.coeffRef(0,0) -= (lhs.transpose().cwiseProduct(rhs)).sum(); }
-};
-
-
-/***********************************************************************
-*  Implementation of outer dense * dense vector product
-***********************************************************************/
-
-// Column major result
-template<typename Dst, typename Lhs, typename Rhs, typename Func>
-void outer_product_selector_run(Dst& dst, const Lhs &lhs, const Rhs &rhs, const Func& func, const false_type&)
-{
-  evaluator<Rhs> rhsEval(rhs);
-  typename nested_eval<Lhs,Rhs::SizeAtCompileTime>::type actual_lhs(lhs);
-  // FIXME if cols is large enough, then it might be useful to make sure that lhs is sequentially stored
-  // FIXME not very good if rhs is real and lhs complex while alpha is real too
-  const Index cols = dst.cols();
-  for (Index j=0; j<cols; ++j)
-    func(dst.col(j), rhsEval.coeff(Index(0),j) * actual_lhs);
-}
-
-// Row major result
-template<typename Dst, typename Lhs, typename Rhs, typename Func>
-void outer_product_selector_run(Dst& dst, const Lhs &lhs, const Rhs &rhs, const Func& func, const true_type&)
-{
-  evaluator<Lhs> lhsEval(lhs);
-  typename nested_eval<Rhs,Lhs::SizeAtCompileTime>::type actual_rhs(rhs);
-  // FIXME if rows is large enough, then it might be useful to make sure that rhs is sequentially stored
-  // FIXME not very good if lhs is real and rhs complex while alpha is real too
-  const Index rows = dst.rows();
-  for (Index i=0; i<rows; ++i)
-    func(dst.row(i), lhsEval.coeff(i,Index(0)) * actual_rhs);
-}
-
-template<typename Lhs, typename Rhs>
-struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,OuterProduct>
-{
-  template<typename T> struct is_row_major : internal::conditional<(int(T::Flags)&RowMajorBit), internal::true_type, internal::false_type>::type {};
-  typedef typename Product<Lhs,Rhs>::Scalar Scalar;
-  
-  // TODO it would be nice to be able to exploit our *_assign_op functors for that purpose
-  struct set  { template<typename Dst, typename Src> void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived()  = src; } };
-  struct add  { template<typename Dst, typename Src> void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() += src; } };
-  struct sub  { template<typename Dst, typename Src> void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() -= src; } };
-  struct adds {
-    Scalar m_scale;
-    explicit adds(const Scalar& s) : m_scale(s) {}
-    template<typename Dst, typename Src> void operator()(const Dst& dst, const Src& src) const {
-      dst.const_cast_derived() += m_scale * src;
-    }
-  };
-  
-  template<typename Dst>
-  static EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
-  {
-    internal::outer_product_selector_run(dst, lhs, rhs, set(), is_row_major<Dst>());
-  }
-  
-  template<typename Dst>
-  static EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
-  {
-    internal::outer_product_selector_run(dst, lhs, rhs, add(), is_row_major<Dst>());
-  }
-  
-  template<typename Dst>
-  static EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
-  {
-    internal::outer_product_selector_run(dst, lhs, rhs, sub(), is_row_major<Dst>());
-  }
-  
-  template<typename Dst>
-  static EIGEN_STRONG_INLINE void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
-  {
-    internal::outer_product_selector_run(dst, lhs, rhs, adds(alpha), is_row_major<Dst>());
-  }
-  
-};
-
-
-// This base class provides default implementations for evalTo, addTo, subTo, in terms of scaleAndAddTo
-template<typename Lhs, typename Rhs, typename Derived>
-struct generic_product_impl_base
-{
-  typedef typename Product<Lhs,Rhs>::Scalar Scalar;
-  
-  template<typename Dst>
-  static EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
-  { dst.setZero(); scaleAndAddTo(dst, lhs, rhs, Scalar(1)); }
-
-  template<typename Dst>
-  static EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
-  { scaleAndAddTo(dst,lhs, rhs, Scalar(1)); }
-
-  template<typename Dst>
-  static EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
-  { scaleAndAddTo(dst, lhs, rhs, Scalar(-1)); }
-  
-  template<typename Dst>
-  static EIGEN_STRONG_INLINE void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
-  { Derived::scaleAndAddTo(dst,lhs,rhs,alpha); }
-
-};
-
-template<typename Lhs, typename Rhs>
-struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,GemvProduct>
-  : generic_product_impl_base<Lhs,Rhs,generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,GemvProduct> >
-{
-  typedef typename nested_eval<Lhs,1>::type LhsNested;
-  typedef typename nested_eval<Rhs,1>::type RhsNested;
-  typedef typename Product<Lhs,Rhs>::Scalar Scalar;
-  enum { Side = Lhs::IsVectorAtCompileTime ? OnTheLeft : OnTheRight };
-  typedef typename internal::remove_all<typename internal::conditional<int(Side)==OnTheRight,LhsNested,RhsNested>::type>::type MatrixType;
-
-  template<typename Dest>
-  static EIGEN_STRONG_INLINE void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
-  {
-    LhsNested actual_lhs(lhs);
-    RhsNested actual_rhs(rhs);
-    internal::gemv_dense_selector<Side,
-                            (int(MatrixType::Flags)&RowMajorBit) ? RowMajor : ColMajor,
-                            bool(internal::blas_traits<MatrixType>::HasUsableDirectAccess)
-                           >::run(actual_lhs, actual_rhs, dst, alpha);
-  }
-};
-
-template<typename Lhs, typename Rhs>
-struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,CoeffBasedProductMode> 
-{
-  typedef typename Product<Lhs,Rhs>::Scalar Scalar;
-  
-  template<typename Dst>
-  static EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
-  {
-    // Same as: dst.noalias() = lhs.lazyProduct(rhs);
-    // but easier on the compiler side
-    call_assignment_no_alias(dst, lhs.lazyProduct(rhs), internal::assign_op<typename Dst::Scalar,Scalar>());
-  }
-  
-  template<typename Dst>
-  static EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
-  {
-    // dst.noalias() += lhs.lazyProduct(rhs);
-    call_assignment_no_alias(dst, lhs.lazyProduct(rhs), internal::add_assign_op<typename Dst::Scalar,Scalar>());
-  }
-  
-  template<typename Dst>
-  static EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
-  {
-    // dst.noalias() -= lhs.lazyProduct(rhs);
-    call_assignment_no_alias(dst, lhs.lazyProduct(rhs), internal::sub_assign_op<typename Dst::Scalar,Scalar>());
-  }
-  
-//   template<typename Dst>
-//   static inline void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
-//   { dst.noalias() += alpha * lhs.lazyProduct(rhs); }
-};
-
-// This specialization enforces the use of a coefficient-based evaluation strategy
-template<typename Lhs, typename Rhs>
-struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,LazyCoeffBasedProductMode>
-  : generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,CoeffBasedProductMode> {};
-
-// Case 2: Evaluate coeff by coeff
-//
-// This is mostly taken from CoeffBasedProduct.h
-// The main difference is that we add an extra argument to the etor_product_*_impl::run() function
-// for the inner dimension of the product, because evaluator object do not know their size.
-
-template<int Traversal, int UnrollingIndex, typename Lhs, typename Rhs, typename RetScalar>
-struct etor_product_coeff_impl;
-
-template<int StorageOrder, int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int LoadMode>
-struct etor_product_packet_impl;
-
-template<typename Lhs, typename Rhs, int ProductTag>
-struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, DenseShape, DenseShape>
-    : evaluator_base<Product<Lhs, Rhs, LazyProduct> >
-{
-  typedef Product<Lhs, Rhs, LazyProduct> XprType;
-  typedef typename XprType::Scalar Scalar;
-  typedef typename XprType::CoeffReturnType CoeffReturnType;
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  explicit product_evaluator(const XprType& xpr)
-    : m_lhs(xpr.lhs()),
-      m_rhs(xpr.rhs()),
-      m_lhsImpl(m_lhs),     // FIXME the creation of the evaluator objects should result in a no-op, but check that!
-      m_rhsImpl(m_rhs),     //       Moreover, they are only useful for the packet path, so we could completely disable them when not needed,
-                            //       or perhaps declare them on the fly on the packet method... We have experiment to check what's best.
-      m_innerDim(xpr.lhs().cols())
-  {
-    EIGEN_INTERNAL_CHECK_COST_VALUE(NumTraits<Scalar>::MulCost);
-    EIGEN_INTERNAL_CHECK_COST_VALUE(NumTraits<Scalar>::AddCost);
-    EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
-#if 0
-    std::cerr << "LhsOuterStrideBytes=  " << LhsOuterStrideBytes << "\n";
-    std::cerr << "RhsOuterStrideBytes=  " << RhsOuterStrideBytes << "\n";
-    std::cerr << "LhsAlignment=         " << LhsAlignment << "\n";
-    std::cerr << "RhsAlignment=         " << RhsAlignment << "\n";
-    std::cerr << "CanVectorizeLhs=      " << CanVectorizeLhs << "\n";
-    std::cerr << "CanVectorizeRhs=      " << CanVectorizeRhs << "\n";
-    std::cerr << "CanVectorizeInner=    " << CanVectorizeInner << "\n";
-    std::cerr << "EvalToRowMajor=       " << EvalToRowMajor << "\n";
-    std::cerr << "Alignment=            " << Alignment << "\n";
-    std::cerr << "Flags=                " << Flags << "\n";
-#endif
-  }
-
-  // Everything below here is taken from CoeffBasedProduct.h
-
-  typedef typename internal::nested_eval<Lhs,Rhs::ColsAtCompileTime>::type LhsNested;
-  typedef typename internal::nested_eval<Rhs,Lhs::RowsAtCompileTime>::type RhsNested;
-  
-  typedef typename internal::remove_all<LhsNested>::type LhsNestedCleaned;
-  typedef typename internal::remove_all<RhsNested>::type RhsNestedCleaned;
-
-  typedef evaluator<LhsNestedCleaned> LhsEtorType;
-  typedef evaluator<RhsNestedCleaned> RhsEtorType;
-
-  enum {
-    RowsAtCompileTime = LhsNestedCleaned::RowsAtCompileTime,
-    ColsAtCompileTime = RhsNestedCleaned::ColsAtCompileTime,
-    InnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(LhsNestedCleaned::ColsAtCompileTime, RhsNestedCleaned::RowsAtCompileTime),
-    MaxRowsAtCompileTime = LhsNestedCleaned::MaxRowsAtCompileTime,
-    MaxColsAtCompileTime = RhsNestedCleaned::MaxColsAtCompileTime
-  };
-
-  typedef typename find_best_packet<Scalar,RowsAtCompileTime>::type LhsVecPacketType;
-  typedef typename find_best_packet<Scalar,ColsAtCompileTime>::type RhsVecPacketType;
-
-  enum {
-      
-    LhsCoeffReadCost = LhsEtorType::CoeffReadCost,
-    RhsCoeffReadCost = RhsEtorType::CoeffReadCost,
-    CoeffReadCost = InnerSize==0 ? NumTraits<Scalar>::ReadCost
-                  : InnerSize == Dynamic ? HugeCost
-                  : InnerSize * (NumTraits<Scalar>::MulCost + LhsCoeffReadCost + RhsCoeffReadCost)
-                    + (InnerSize - 1) * NumTraits<Scalar>::AddCost,
-
-    Unroll = CoeffReadCost <= EIGEN_UNROLLING_LIMIT,
-    
-    LhsFlags = LhsEtorType::Flags,
-    RhsFlags = RhsEtorType::Flags,
-    
-    LhsRowMajor = LhsFlags & RowMajorBit,
-    RhsRowMajor = RhsFlags & RowMajorBit,
-
-    LhsVecPacketSize = unpacket_traits<LhsVecPacketType>::size,
-    RhsVecPacketSize = unpacket_traits<RhsVecPacketType>::size,
-
-    // Here, we don't care about alignment larger than the usable packet size.
-    LhsAlignment = EIGEN_PLAIN_ENUM_MIN(LhsEtorType::Alignment,LhsVecPacketSize*int(sizeof(typename LhsNestedCleaned::Scalar))),
-    RhsAlignment = EIGEN_PLAIN_ENUM_MIN(RhsEtorType::Alignment,RhsVecPacketSize*int(sizeof(typename RhsNestedCleaned::Scalar))),
-      
-    SameType = is_same<typename LhsNestedCleaned::Scalar,typename RhsNestedCleaned::Scalar>::value,
-
-    CanVectorizeRhs = bool(RhsRowMajor) && (RhsFlags & PacketAccessBit) && (ColsAtCompileTime!=1),
-    CanVectorizeLhs = (!LhsRowMajor) && (LhsFlags & PacketAccessBit) && (RowsAtCompileTime!=1),
-
-    EvalToRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1
-                    : (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
-                    : (bool(RhsRowMajor) && !CanVectorizeLhs),
-
-    Flags = ((unsigned int)(LhsFlags | RhsFlags) & HereditaryBits & ~RowMajorBit)
-          | (EvalToRowMajor ? RowMajorBit : 0)
-          // TODO enable vectorization for mixed types
-          | (SameType && (CanVectorizeLhs || CanVectorizeRhs) ? PacketAccessBit : 0)
-          | (XprType::IsVectorAtCompileTime ? LinearAccessBit : 0),
-          
-    LhsOuterStrideBytes = int(LhsNestedCleaned::OuterStrideAtCompileTime) * int(sizeof(typename LhsNestedCleaned::Scalar)),
-    RhsOuterStrideBytes = int(RhsNestedCleaned::OuterStrideAtCompileTime) * int(sizeof(typename RhsNestedCleaned::Scalar)),
-
-    Alignment = bool(CanVectorizeLhs) ? (LhsOuterStrideBytes<=0 || (int(LhsOuterStrideBytes) % EIGEN_PLAIN_ENUM_MAX(1,LhsAlignment))!=0 ? 0 : LhsAlignment)
-              : bool(CanVectorizeRhs) ? (RhsOuterStrideBytes<=0 || (int(RhsOuterStrideBytes) % EIGEN_PLAIN_ENUM_MAX(1,RhsAlignment))!=0 ? 0 : RhsAlignment)
-              : 0,
-
-    /* CanVectorizeInner deserves special explanation. It does not affect the product flags. It is not used outside
-     * of Product. If the Product itself is not a packet-access expression, there is still a chance that the inner
-     * loop of the product might be vectorized. This is the meaning of CanVectorizeInner. Since it doesn't affect
-     * the Flags, it is safe to make this value depend on ActualPacketAccessBit, that doesn't affect the ABI.
-     */
-    CanVectorizeInner =    SameType
-                        && LhsRowMajor
-                        && (!RhsRowMajor)
-                        && (LhsFlags & RhsFlags & ActualPacketAccessBit)
-                        && (InnerSize % packet_traits<Scalar>::size == 0)
-  };
-  
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index row, Index col) const
-  {
-    return (m_lhs.row(row).transpose().cwiseProduct( m_rhs.col(col) )).sum();
-  }
-
-  /* Allow index-based non-packet access. It is impossible though to allow index-based packed access,
-   * which is why we don't set the LinearAccessBit.
-   * TODO: this seems possible when the result is a vector
-   */
-  EIGEN_DEVICE_FUNC const CoeffReturnType coeff(Index index) const
-  {
-    const Index row = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? 0 : index;
-    const Index col = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? index : 0;
-    return (m_lhs.row(row).transpose().cwiseProduct( m_rhs.col(col) )).sum();
-  }
-
-  template<int LoadMode, typename PacketType>
-  const PacketType packet(Index row, Index col) const
-  {
-    PacketType res;
-    typedef etor_product_packet_impl<bool(int(Flags)&RowMajorBit) ? RowMajor : ColMajor,
-                                     Unroll ? int(InnerSize) : Dynamic,
-                                     LhsEtorType, RhsEtorType, PacketType, LoadMode> PacketImpl;
-    PacketImpl::run(row, col, m_lhsImpl, m_rhsImpl, m_innerDim, res);
-    return res;
-  }
-
-  template<int LoadMode, typename PacketType>
-  const PacketType packet(Index index) const
-  {
-    const Index row = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? 0 : index;
-    const Index col = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? index : 0;
-    return packet<LoadMode,PacketType>(row,col);
-  }
-
-protected:
-  typename internal::add_const_on_value_type<LhsNested>::type m_lhs;
-  typename internal::add_const_on_value_type<RhsNested>::type m_rhs;
-  
-  LhsEtorType m_lhsImpl;
-  RhsEtorType m_rhsImpl;
-
-  // TODO: Get rid of m_innerDim if known at compile time
-  Index m_innerDim;
-};
-
-template<typename Lhs, typename Rhs>
-struct product_evaluator<Product<Lhs, Rhs, DefaultProduct>, LazyCoeffBasedProductMode, DenseShape, DenseShape>
-  : product_evaluator<Product<Lhs, Rhs, LazyProduct>, CoeffBasedProductMode, DenseShape, DenseShape>
-{
-  typedef Product<Lhs, Rhs, DefaultProduct> XprType;
-  typedef Product<Lhs, Rhs, LazyProduct> BaseProduct;
-  typedef product_evaluator<BaseProduct, CoeffBasedProductMode, DenseShape, DenseShape> Base;
-  enum {
-    Flags = Base::Flags | EvalBeforeNestingBit
-  };
-  EIGEN_DEVICE_FUNC explicit product_evaluator(const XprType& xpr)
-    : Base(BaseProduct(xpr.lhs(),xpr.rhs()))
-  {}
-};
-
-/****************************************
-*** Coeff based product, Packet path  ***
-****************************************/
-
-template<int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int LoadMode>
-struct etor_product_packet_impl<RowMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode>
-{
-  static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet &res)
-  {
-    etor_product_packet_impl<RowMajor, UnrollingIndex-1, Lhs, Rhs, Packet, LoadMode>::run(row, col, lhs, rhs, innerDim, res);
-    res =  pmadd(pset1<Packet>(lhs.coeff(row, Index(UnrollingIndex-1))), rhs.template packet<LoadMode,Packet>(Index(UnrollingIndex-1), col), res);
-  }
-};
-
-template<int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int LoadMode>
-struct etor_product_packet_impl<ColMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode>
-{
-  static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet &res)
-  {
-    etor_product_packet_impl<ColMajor, UnrollingIndex-1, Lhs, Rhs, Packet, LoadMode>::run(row, col, lhs, rhs, innerDim, res);
-    res =  pmadd(lhs.template packet<LoadMode,Packet>(row, Index(UnrollingIndex-1)), pset1<Packet>(rhs.coeff(Index(UnrollingIndex-1), col)), res);
-  }
-};
-
-template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
-struct etor_product_packet_impl<RowMajor, 1, Lhs, Rhs, Packet, LoadMode>
-{
-  static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index /*innerDim*/, Packet &res)
-  {
-    res = pmul(pset1<Packet>(lhs.coeff(row, Index(0))),rhs.template packet<LoadMode,Packet>(Index(0), col));
-  }
-};
-
-template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
-struct etor_product_packet_impl<ColMajor, 1, Lhs, Rhs, Packet, LoadMode>
-{
-  static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index /*innerDim*/, Packet &res)
-  {
-    res = pmul(lhs.template packet<LoadMode,Packet>(row, Index(0)), pset1<Packet>(rhs.coeff(Index(0), col)));
-  }
-};
-
-template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
-struct etor_product_packet_impl<RowMajor, 0, Lhs, Rhs, Packet, LoadMode>
-{
-  static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, Index /*innerDim*/, Packet &res)
-  {
-    res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
-  }
-};
-
-template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
-struct etor_product_packet_impl<ColMajor, 0, Lhs, Rhs, Packet, LoadMode>
-{
-  static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, Index /*innerDim*/, Packet &res)
-  {
-    res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
-  }
-};
-
-template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
-struct etor_product_packet_impl<RowMajor, Dynamic, Lhs, Rhs, Packet, LoadMode>
-{
-  static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet& res)
-  {
-    res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
-    for(Index i = 0; i < innerDim; ++i)
-      res =  pmadd(pset1<Packet>(lhs.coeff(row, i)), rhs.template packet<LoadMode,Packet>(i, col), res);
-  }
-};
-
-template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
-struct etor_product_packet_impl<ColMajor, Dynamic, Lhs, Rhs, Packet, LoadMode>
-{
-  static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet& res)
-  {
-    res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
-    for(Index i = 0; i < innerDim; ++i)
-      res =  pmadd(lhs.template packet<LoadMode,Packet>(row, i), pset1<Packet>(rhs.coeff(i, col)), res);
-  }
-};
-
-
-/***************************************************************************
-* Triangular products
-***************************************************************************/
-template<int Mode, bool LhsIsTriangular,
-         typename Lhs, bool LhsIsVector,
-         typename Rhs, bool RhsIsVector>
-struct triangular_product_impl;
-
-template<typename Lhs, typename Rhs, int ProductTag>
-struct generic_product_impl<Lhs,Rhs,TriangularShape,DenseShape,ProductTag>
-  : generic_product_impl_base<Lhs,Rhs,generic_product_impl<Lhs,Rhs,TriangularShape,DenseShape,ProductTag> >
-{
-  typedef typename Product<Lhs,Rhs>::Scalar Scalar;
-  
-  template<typename Dest>
-  static void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
-  {
-    triangular_product_impl<Lhs::Mode,true,typename Lhs::MatrixType,false,Rhs, Rhs::ColsAtCompileTime==1>
-        ::run(dst, lhs.nestedExpression(), rhs, alpha);
-  }
-};
-
-template<typename Lhs, typename Rhs, int ProductTag>
-struct generic_product_impl<Lhs,Rhs,DenseShape,TriangularShape,ProductTag>
-: generic_product_impl_base<Lhs,Rhs,generic_product_impl<Lhs,Rhs,DenseShape,TriangularShape,ProductTag> >
-{
-  typedef typename Product<Lhs,Rhs>::Scalar Scalar;
-  
-  template<typename Dest>
-  static void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
-  {
-    triangular_product_impl<Rhs::Mode,false,Lhs,Lhs::RowsAtCompileTime==1, typename Rhs::MatrixType, false>::run(dst, lhs, rhs.nestedExpression(), alpha);
-  }
-};
-
-
-/***************************************************************************
-* SelfAdjoint products
-***************************************************************************/
-template <typename Lhs, int LhsMode, bool LhsIsVector,
-          typename Rhs, int RhsMode, bool RhsIsVector>
-struct selfadjoint_product_impl;
-
-template<typename Lhs, typename Rhs, int ProductTag>
-struct generic_product_impl<Lhs,Rhs,SelfAdjointShape,DenseShape,ProductTag>
-  : generic_product_impl_base<Lhs,Rhs,generic_product_impl<Lhs,Rhs,SelfAdjointShape,DenseShape,ProductTag> >
-{
-  typedef typename Product<Lhs,Rhs>::Scalar Scalar;
-  
-  template<typename Dest>
-  static void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
-  {
-    selfadjoint_product_impl<typename Lhs::MatrixType,Lhs::Mode,false,Rhs,0,Rhs::IsVectorAtCompileTime>::run(dst, lhs.nestedExpression(), rhs, alpha);
-  }
-};
-
-template<typename Lhs, typename Rhs, int ProductTag>
-struct generic_product_impl<Lhs,Rhs,DenseShape,SelfAdjointShape,ProductTag>
-: generic_product_impl_base<Lhs,Rhs,generic_product_impl<Lhs,Rhs,DenseShape,SelfAdjointShape,ProductTag> >
-{
-  typedef typename Product<Lhs,Rhs>::Scalar Scalar;
-  
-  template<typename Dest>
-  static void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
-  {
-    selfadjoint_product_impl<Lhs,0,Lhs::IsVectorAtCompileTime,typename Rhs::MatrixType,Rhs::Mode,false>::run(dst, lhs, rhs.nestedExpression(), alpha);
-  }
-};
-
-
-/***************************************************************************
-* Diagonal products
-***************************************************************************/
-  
-template<typename MatrixType, typename DiagonalType, typename Derived, int ProductOrder>
-struct diagonal_product_evaluator_base
-  : evaluator_base<Derived>
-{
-   typedef typename ScalarBinaryOpTraits<typename MatrixType::Scalar, typename DiagonalType::Scalar>::ReturnType Scalar;
-public:
-  enum {
-    CoeffReadCost = NumTraits<Scalar>::MulCost + evaluator<MatrixType>::CoeffReadCost + evaluator<DiagonalType>::CoeffReadCost,
-    
-    MatrixFlags = evaluator<MatrixType>::Flags,
-    DiagFlags = evaluator<DiagonalType>::Flags,
-    _StorageOrder = MatrixFlags & RowMajorBit ? RowMajor : ColMajor,
-    _ScalarAccessOnDiag =  !((int(_StorageOrder) == ColMajor && int(ProductOrder) == OnTheLeft)
-                           ||(int(_StorageOrder) == RowMajor && int(ProductOrder) == OnTheRight)),
-    _SameTypes = is_same<typename MatrixType::Scalar, typename DiagonalType::Scalar>::value,
-    // FIXME currently we need same types, but in the future the next rule should be the one
-    //_Vectorizable = bool(int(MatrixFlags)&PacketAccessBit) && ((!_PacketOnDiag) || (_SameTypes && bool(int(DiagFlags)&PacketAccessBit))),
-    _Vectorizable = bool(int(MatrixFlags)&PacketAccessBit) && _SameTypes && (_ScalarAccessOnDiag || (bool(int(DiagFlags)&PacketAccessBit))),
-    _LinearAccessMask = (MatrixType::RowsAtCompileTime==1 || MatrixType::ColsAtCompileTime==1) ? LinearAccessBit : 0,
-    Flags = ((HereditaryBits|_LinearAccessMask) & (unsigned int)(MatrixFlags)) | (_Vectorizable ? PacketAccessBit : 0),
-    Alignment = evaluator<MatrixType>::Alignment,
-
-    AsScalarProduct =     (DiagonalType::SizeAtCompileTime==1)
-                      ||  (DiagonalType::SizeAtCompileTime==Dynamic && MatrixType::RowsAtCompileTime==1 && ProductOrder==OnTheLeft)
-                      ||  (DiagonalType::SizeAtCompileTime==Dynamic && MatrixType::ColsAtCompileTime==1 && ProductOrder==OnTheRight)
-  };
-  
-  diagonal_product_evaluator_base(const MatrixType &mat, const DiagonalType &diag)
-    : m_diagImpl(diag), m_matImpl(mat)
-  {
-    EIGEN_INTERNAL_CHECK_COST_VALUE(NumTraits<Scalar>::MulCost);
-    EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
-  }
-  
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar coeff(Index idx) const
-  {
-    if(AsScalarProduct)
-      return m_diagImpl.coeff(0) * m_matImpl.coeff(idx);
-    else
-      return m_diagImpl.coeff(idx) * m_matImpl.coeff(idx);
-  }
-  
-protected:
-  template<int LoadMode,typename PacketType>
-  EIGEN_STRONG_INLINE PacketType packet_impl(Index row, Index col, Index id, internal::true_type) const
-  {
-    return internal::pmul(m_matImpl.template packet<LoadMode,PacketType>(row, col),
-                          internal::pset1<PacketType>(m_diagImpl.coeff(id)));
-  }
-  
-  template<int LoadMode,typename PacketType>
-  EIGEN_STRONG_INLINE PacketType packet_impl(Index row, Index col, Index id, internal::false_type) const
-  {
-    enum {
-      InnerSize = (MatrixType::Flags & RowMajorBit) ? MatrixType::ColsAtCompileTime : MatrixType::RowsAtCompileTime,
-      DiagonalPacketLoadMode = EIGEN_PLAIN_ENUM_MIN(LoadMode,((InnerSize%16) == 0) ? int(Aligned16) : int(evaluator<DiagonalType>::Alignment)) // FIXME hardcoded 16!!
-    };
-    return internal::pmul(m_matImpl.template packet<LoadMode,PacketType>(row, col),
-                          m_diagImpl.template packet<DiagonalPacketLoadMode,PacketType>(id));
-  }
-  
-  evaluator<DiagonalType> m_diagImpl;
-  evaluator<MatrixType>   m_matImpl;
-};
-
-// diagonal * dense
-template<typename Lhs, typename Rhs, int ProductKind, int ProductTag>
-struct product_evaluator<Product<Lhs, Rhs, ProductKind>, ProductTag, DiagonalShape, DenseShape>
-  : diagonal_product_evaluator_base<Rhs, typename Lhs::DiagonalVectorType, Product<Lhs, Rhs, LazyProduct>, OnTheLeft>
-{
-  typedef diagonal_product_evaluator_base<Rhs, typename Lhs::DiagonalVectorType, Product<Lhs, Rhs, LazyProduct>, OnTheLeft> Base;
-  using Base::m_diagImpl;
-  using Base::m_matImpl;
-  using Base::coeff;
-  typedef typename Base::Scalar Scalar;
-  
-  typedef Product<Lhs, Rhs, ProductKind> XprType;
-  typedef typename XprType::PlainObject PlainObject;
-  
-  enum {
-    StorageOrder = int(Rhs::Flags) & RowMajorBit ? RowMajor : ColMajor
-  };
-
-  EIGEN_DEVICE_FUNC explicit product_evaluator(const XprType& xpr)
-    : Base(xpr.rhs(), xpr.lhs().diagonal())
-  {
-  }
-  
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const
-  {
-    return m_diagImpl.coeff(row) * m_matImpl.coeff(row, col);
-  }
-  
-#ifndef __CUDACC__
-  template<int LoadMode,typename PacketType>
-  EIGEN_STRONG_INLINE PacketType packet(Index row, Index col) const
-  {
-    // FIXME: NVCC used to complain about the template keyword, but we have to check whether this is still the case.
-    // See also similar calls below.
-    return this->template packet_impl<LoadMode,PacketType>(row,col, row,
-                                 typename internal::conditional<int(StorageOrder)==RowMajor, internal::true_type, internal::false_type>::type());
-  }
-  
-  template<int LoadMode,typename PacketType>
-  EIGEN_STRONG_INLINE PacketType packet(Index idx) const
-  {
-    return packet<LoadMode,PacketType>(int(StorageOrder)==ColMajor?idx:0,int(StorageOrder)==ColMajor?0:idx);
-  }
-#endif
-};
-
-// dense * diagonal
-template<typename Lhs, typename Rhs, int ProductKind, int ProductTag>
-struct product_evaluator<Product<Lhs, Rhs, ProductKind>, ProductTag, DenseShape, DiagonalShape>
-  : diagonal_product_evaluator_base<Lhs, typename Rhs::DiagonalVectorType, Product<Lhs, Rhs, LazyProduct>, OnTheRight>
-{
-  typedef diagonal_product_evaluator_base<Lhs, typename Rhs::DiagonalVectorType, Product<Lhs, Rhs, LazyProduct>, OnTheRight> Base;
-  using Base::m_diagImpl;
-  using Base::m_matImpl;
-  using Base::coeff;
-  typedef typename Base::Scalar Scalar;
-  
-  typedef Product<Lhs, Rhs, ProductKind> XprType;
-  typedef typename XprType::PlainObject PlainObject;
-  
-  enum { StorageOrder = int(Lhs::Flags) & RowMajorBit ? RowMajor : ColMajor };
-
-  EIGEN_DEVICE_FUNC explicit product_evaluator(const XprType& xpr)
-    : Base(xpr.lhs(), xpr.rhs().diagonal())
-  {
-  }
-  
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const
-  {
-    return m_matImpl.coeff(row, col) * m_diagImpl.coeff(col);
-  }
-  
-#ifndef __CUDACC__
-  template<int LoadMode,typename PacketType>
-  EIGEN_STRONG_INLINE PacketType packet(Index row, Index col) const
-  {
-    return this->template packet_impl<LoadMode,PacketType>(row,col, col,
-                                 typename internal::conditional<int(StorageOrder)==ColMajor, internal::true_type, internal::false_type>::type());
-  }
-  
-  template<int LoadMode,typename PacketType>
-  EIGEN_STRONG_INLINE PacketType packet(Index idx) const
-  {
-    return packet<LoadMode,PacketType>(int(StorageOrder)==ColMajor?idx:0,int(StorageOrder)==ColMajor?0:idx);
-  }
-#endif
-};
-
-/***************************************************************************
-* Products with permutation matrices
-***************************************************************************/
-
-/** \internal
-  * \class permutation_matrix_product
-  * Internal helper class implementing the product between a permutation matrix and a matrix.
-  * This class is specialized for DenseShape below and for SparseShape in SparseCore/SparsePermutation.h
-  */
-template<typename ExpressionType, int Side, bool Transposed, typename ExpressionShape>
-struct permutation_matrix_product;
-
-template<typename ExpressionType, int Side, bool Transposed>
-struct permutation_matrix_product<ExpressionType, Side, Transposed, DenseShape>
-{
-    typedef typename nested_eval<ExpressionType, 1>::type MatrixType;
-    typedef typename remove_all<MatrixType>::type MatrixTypeCleaned;
-
-    template<typename Dest, typename PermutationType>
-    static inline void run(Dest& dst, const PermutationType& perm, const ExpressionType& xpr)
-    {
-      MatrixType mat(xpr);
-      const Index n = Side==OnTheLeft ? mat.rows() : mat.cols();
-      // FIXME we need an is_same for expression that is not sensitive to constness. For instance
-      // is_same_xpr<Block<const Matrix>, Block<Matrix> >::value should be true.
-      //if(is_same<MatrixTypeCleaned,Dest>::value && extract_data(dst) == extract_data(mat))
-      if(is_same_dense(dst, mat))
-      {
-        // apply the permutation inplace
-        Matrix<bool,PermutationType::RowsAtCompileTime,1,0,PermutationType::MaxRowsAtCompileTime> mask(perm.size());
-        mask.fill(false);
-        Index r = 0;
-        while(r < perm.size())
-        {
-          // search for the next seed
-          while(r<perm.size() && mask[r]) r++;
-          if(r>=perm.size())
-            break;
-          // we got one, let's follow it until we are back to the seed
-          Index k0 = r++;
-          Index kPrev = k0;
-          mask.coeffRef(k0) = true;
-          for(Index k=perm.indices().coeff(k0); k!=k0; k=perm.indices().coeff(k))
-          {
-                  Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>(dst, k)
-            .swap(Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>
-                       (dst,((Side==OnTheLeft) ^ Transposed) ? k0 : kPrev));
-
-            mask.coeffRef(k) = true;
-            kPrev = k;
-          }
-        }
-      }
-      else
-      {
-        for(Index i = 0; i < n; ++i)
-        {
-          Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>
-               (dst, ((Side==OnTheLeft) ^ Transposed) ? perm.indices().coeff(i) : i)
-
-          =
-
-          Block<const MatrixTypeCleaned,Side==OnTheLeft ? 1 : MatrixTypeCleaned::RowsAtCompileTime,Side==OnTheRight ? 1 : MatrixTypeCleaned::ColsAtCompileTime>
-               (mat, ((Side==OnTheRight) ^ Transposed) ? perm.indices().coeff(i) : i);
-        }
-      }
-    }
-};
-
-template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
-struct generic_product_impl<Lhs, Rhs, PermutationShape, MatrixShape, ProductTag>
-{
-  template<typename Dest>
-  static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
-  {
-    permutation_matrix_product<Rhs, OnTheLeft, false, MatrixShape>::run(dst, lhs, rhs);
-  }
-};
-
-template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
-struct generic_product_impl<Lhs, Rhs, MatrixShape, PermutationShape, ProductTag>
-{
-  template<typename Dest>
-  static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
-  {
-    permutation_matrix_product<Lhs, OnTheRight, false, MatrixShape>::run(dst, rhs, lhs);
-  }
-};
-
-template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
-struct generic_product_impl<Inverse<Lhs>, Rhs, PermutationShape, MatrixShape, ProductTag>
-{
-  template<typename Dest>
-  static void evalTo(Dest& dst, const Inverse<Lhs>& lhs, const Rhs& rhs)
-  {
-    permutation_matrix_product<Rhs, OnTheLeft, true, MatrixShape>::run(dst, lhs.nestedExpression(), rhs);
-  }
-};
-
-template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
-struct generic_product_impl<Lhs, Inverse<Rhs>, MatrixShape, PermutationShape, ProductTag>
-{
-  template<typename Dest>
-  static void evalTo(Dest& dst, const Lhs& lhs, const Inverse<Rhs>& rhs)
-  {
-    permutation_matrix_product<Lhs, OnTheRight, true, MatrixShape>::run(dst, rhs.nestedExpression(), lhs);
-  }
-};
-
-
-/***************************************************************************
-* Products with transpositions matrices
-***************************************************************************/
-
-// FIXME could we unify Transpositions and Permutation into a single "shape"??
-
-/** \internal
-  * \class transposition_matrix_product
-  * Internal helper class implementing the product between a permutation matrix and a matrix.
-  */
-template<typename ExpressionType, int Side, bool Transposed, typename ExpressionShape>
-struct transposition_matrix_product
-{
-  typedef typename nested_eval<ExpressionType, 1>::type MatrixType;
-  typedef typename remove_all<MatrixType>::type MatrixTypeCleaned;
-  
-  template<typename Dest, typename TranspositionType>
-  static inline void run(Dest& dst, const TranspositionType& tr, const ExpressionType& xpr)
-  {
-    MatrixType mat(xpr);
-    typedef typename TranspositionType::StorageIndex StorageIndex;
-    const Index size = tr.size();
-    StorageIndex j = 0;
-
-    if(!is_same_dense(dst,mat))
-      dst = mat;
-
-    for(Index k=(Transposed?size-1:0) ; Transposed?k>=0:k<size ; Transposed?--k:++k)
-      if(Index(j=tr.coeff(k))!=k)
-      {
-        if(Side==OnTheLeft)        dst.row(k).swap(dst.row(j));
-        else if(Side==OnTheRight)  dst.col(k).swap(dst.col(j));
-      }
-  }
-};
-
-template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
-struct generic_product_impl<Lhs, Rhs, TranspositionsShape, MatrixShape, ProductTag>
-{
-  template<typename Dest>
-  static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
-  {
-    transposition_matrix_product<Rhs, OnTheLeft, false, MatrixShape>::run(dst, lhs, rhs);
-  }
-};
-
-template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
-struct generic_product_impl<Lhs, Rhs, MatrixShape, TranspositionsShape, ProductTag>
-{
-  template<typename Dest>
-  static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
-  {
-    transposition_matrix_product<Lhs, OnTheRight, false, MatrixShape>::run(dst, rhs, lhs);
-  }
-};
-
-
-template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
-struct generic_product_impl<Transpose<Lhs>, Rhs, TranspositionsShape, MatrixShape, ProductTag>
-{
-  template<typename Dest>
-  static void evalTo(Dest& dst, const Transpose<Lhs>& lhs, const Rhs& rhs)
-  {
-    transposition_matrix_product<Rhs, OnTheLeft, true, MatrixShape>::run(dst, lhs.nestedExpression(), rhs);
-  }
-};
-
-template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
-struct generic_product_impl<Lhs, Transpose<Rhs>, MatrixShape, TranspositionsShape, ProductTag>
-{
-  template<typename Dest>
-  static void evalTo(Dest& dst, const Lhs& lhs, const Transpose<Rhs>& rhs)
-  {
-    transposition_matrix_product<Lhs, OnTheRight, true, MatrixShape>::run(dst, rhs.nestedExpression(), lhs);
-  }
-};
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_PRODUCT_EVALUATORS_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Random.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Random.h
deleted file mode 100644
index 6faf789..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Random.h
+++ /dev/null
@@ -1,182 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_RANDOM_H
-#define EIGEN_RANDOM_H
-
-namespace Eigen { 
-
-namespace internal {
-
-template<typename Scalar> struct scalar_random_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_random_op)
-  inline const Scalar operator() () const { return random<Scalar>(); }
-};
-
-template<typename Scalar>
-struct functor_traits<scalar_random_op<Scalar> >
-{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false, IsRepeatable = false }; };
-
-} // end namespace internal
-
-/** \returns a random matrix expression
-  *
-  * Numbers are uniformly spread through their whole definition range for integer types,
-  * and in the [-1:1] range for floating point scalar types.
-  * 
-  * The parameters \a rows and \a cols are the number of rows and of columns of
-  * the returned matrix. Must be compatible with this MatrixBase type.
-  *
-  * \not_reentrant
-  * 
-  * This variant is meant to be used for dynamic-size matrix types. For fixed-size types,
-  * it is redundant to pass \a rows and \a cols as arguments, so Random() should be used
-  * instead.
-  * 
-  *
-  * Example: \include MatrixBase_random_int_int.cpp
-  * Output: \verbinclude MatrixBase_random_int_int.out
-  *
-  * This expression has the "evaluate before nesting" flag so that it will be evaluated into
-  * a temporary matrix whenever it is nested in a larger expression. This prevents unexpected
-  * behavior with expressions involving random matrices.
-  * 
-  * See DenseBase::NullaryExpr(Index, const CustomNullaryOp&) for an example using C++11 random generators.
-  *
-  * \sa DenseBase::setRandom(), DenseBase::Random(Index), DenseBase::Random()
-  */
-template<typename Derived>
-inline const typename DenseBase<Derived>::RandomReturnType
-DenseBase<Derived>::Random(Index rows, Index cols)
-{
-  return NullaryExpr(rows, cols, internal::scalar_random_op<Scalar>());
-}
-
-/** \returns a random vector expression
-  *
-  * Numbers are uniformly spread through their whole definition range for integer types,
-  * and in the [-1:1] range for floating point scalar types.
-  *
-  * The parameter \a size is the size of the returned vector.
-  * Must be compatible with this MatrixBase type.
-  *
-  * \only_for_vectors
-  * \not_reentrant
-  *
-  * This variant is meant to be used for dynamic-size vector types. For fixed-size types,
-  * it is redundant to pass \a size as argument, so Random() should be used
-  * instead.
-  *
-  * Example: \include MatrixBase_random_int.cpp
-  * Output: \verbinclude MatrixBase_random_int.out
-  *
-  * This expression has the "evaluate before nesting" flag so that it will be evaluated into
-  * a temporary vector whenever it is nested in a larger expression. This prevents unexpected
-  * behavior with expressions involving random matrices.
-  *
-  * \sa DenseBase::setRandom(), DenseBase::Random(Index,Index), DenseBase::Random()
-  */
-template<typename Derived>
-inline const typename DenseBase<Derived>::RandomReturnType
-DenseBase<Derived>::Random(Index size)
-{
-  return NullaryExpr(size, internal::scalar_random_op<Scalar>());
-}
-
-/** \returns a fixed-size random matrix or vector expression
-  *
-  * Numbers are uniformly spread through their whole definition range for integer types,
-  * and in the [-1:1] range for floating point scalar types.
-  * 
-  * This variant is only for fixed-size MatrixBase types. For dynamic-size types, you
-  * need to use the variants taking size arguments.
-  *
-  * Example: \include MatrixBase_random.cpp
-  * Output: \verbinclude MatrixBase_random.out
-  *
-  * This expression has the "evaluate before nesting" flag so that it will be evaluated into
-  * a temporary matrix whenever it is nested in a larger expression. This prevents unexpected
-  * behavior with expressions involving random matrices.
-  * 
-  * \not_reentrant
-  *
-  * \sa DenseBase::setRandom(), DenseBase::Random(Index,Index), DenseBase::Random(Index)
-  */
-template<typename Derived>
-inline const typename DenseBase<Derived>::RandomReturnType
-DenseBase<Derived>::Random()
-{
-  return NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, internal::scalar_random_op<Scalar>());
-}
-
-/** Sets all coefficients in this expression to random values.
-  *
-  * Numbers are uniformly spread through their whole definition range for integer types,
-  * and in the [-1:1] range for floating point scalar types.
-  * 
-  * \not_reentrant
-  * 
-  * Example: \include MatrixBase_setRandom.cpp
-  * Output: \verbinclude MatrixBase_setRandom.out
-  *
-  * \sa class CwiseNullaryOp, setRandom(Index), setRandom(Index,Index)
-  */
-template<typename Derived>
-inline Derived& DenseBase<Derived>::setRandom()
-{
-  return *this = Random(rows(), cols());
-}
-
-/** Resizes to the given \a newSize, and sets all coefficients in this expression to random values.
-  *
-  * Numbers are uniformly spread through their whole definition range for integer types,
-  * and in the [-1:1] range for floating point scalar types.
-  * 
-  * \only_for_vectors
-  * \not_reentrant
-  *
-  * Example: \include Matrix_setRandom_int.cpp
-  * Output: \verbinclude Matrix_setRandom_int.out
-  *
-  * \sa DenseBase::setRandom(), setRandom(Index,Index), class CwiseNullaryOp, DenseBase::Random()
-  */
-template<typename Derived>
-EIGEN_STRONG_INLINE Derived&
-PlainObjectBase<Derived>::setRandom(Index newSize)
-{
-  resize(newSize);
-  return setRandom();
-}
-
-/** Resizes to the given size, and sets all coefficients in this expression to random values.
-  *
-  * Numbers are uniformly spread through their whole definition range for integer types,
-  * and in the [-1:1] range for floating point scalar types.
-  *
-  * \not_reentrant
-  * 
-  * \param rows the new number of rows
-  * \param cols the new number of columns
-  *
-  * Example: \include Matrix_setRandom_int_int.cpp
-  * Output: \verbinclude Matrix_setRandom_int_int.out
-  *
-  * \sa DenseBase::setRandom(), setRandom(Index), class CwiseNullaryOp, DenseBase::Random()
-  */
-template<typename Derived>
-EIGEN_STRONG_INLINE Derived&
-PlainObjectBase<Derived>::setRandom(Index rows, Index cols)
-{
-  resize(rows, cols);
-  return setRandom();
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_RANDOM_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Redux.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Redux.h
deleted file mode 100644
index 760e9f8..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Redux.h
+++ /dev/null
@@ -1,505 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_REDUX_H
-#define EIGEN_REDUX_H
-
-namespace Eigen { 
-
-namespace internal {
-
-// TODO
-//  * implement other kind of vectorization
-//  * factorize code
-
-/***************************************************************************
-* Part 1 : the logic deciding a strategy for vectorization and unrolling
-***************************************************************************/
-
-template<typename Func, typename Derived>
-struct redux_traits
-{
-public:
-    typedef typename find_best_packet<typename Derived::Scalar,Derived::SizeAtCompileTime>::type PacketType;
-  enum {
-    PacketSize = unpacket_traits<PacketType>::size,
-    InnerMaxSize = int(Derived::IsRowMajor)
-                 ? Derived::MaxColsAtCompileTime
-                 : Derived::MaxRowsAtCompileTime
-  };
-
-  enum {
-    MightVectorize = (int(Derived::Flags)&ActualPacketAccessBit)
-                  && (functor_traits<Func>::PacketAccess),
-    MayLinearVectorize = bool(MightVectorize) && (int(Derived::Flags)&LinearAccessBit),
-    MaySliceVectorize  = bool(MightVectorize) && int(InnerMaxSize)>=3*PacketSize
-  };
-
-public:
-  enum {
-    Traversal = int(MayLinearVectorize) ? int(LinearVectorizedTraversal)
-              : int(MaySliceVectorize)  ? int(SliceVectorizedTraversal)
-                                        : int(DefaultTraversal)
-  };
-
-public:
-  enum {
-    Cost = Derived::SizeAtCompileTime == Dynamic ? HugeCost
-         : Derived::SizeAtCompileTime * Derived::CoeffReadCost + (Derived::SizeAtCompileTime-1) * functor_traits<Func>::Cost,
-    UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Traversal) == int(DefaultTraversal) ? 1 : int(PacketSize))
-  };
-
-public:
-  enum {
-    Unrolling = Cost <= UnrollingLimit ? CompleteUnrolling : NoUnrolling
-  };
-  
-#ifdef EIGEN_DEBUG_ASSIGN
-  static void debug()
-  {
-    std::cerr << "Xpr: " << typeid(typename Derived::XprType).name() << std::endl;
-    std::cerr.setf(std::ios::hex, std::ios::basefield);
-    EIGEN_DEBUG_VAR(Derived::Flags)
-    std::cerr.unsetf(std::ios::hex);
-    EIGEN_DEBUG_VAR(InnerMaxSize)
-    EIGEN_DEBUG_VAR(PacketSize)
-    EIGEN_DEBUG_VAR(MightVectorize)
-    EIGEN_DEBUG_VAR(MayLinearVectorize)
-    EIGEN_DEBUG_VAR(MaySliceVectorize)
-    EIGEN_DEBUG_VAR(Traversal)
-    EIGEN_DEBUG_VAR(UnrollingLimit)
-    EIGEN_DEBUG_VAR(Unrolling)
-    std::cerr << std::endl;
-  }
-#endif
-};
-
-/***************************************************************************
-* Part 2 : unrollers
-***************************************************************************/
-
-/*** no vectorization ***/
-
-template<typename Func, typename Derived, int Start, int Length>
-struct redux_novec_unroller
-{
-  enum {
-    HalfLength = Length/2
-  };
-
-  typedef typename Derived::Scalar Scalar;
-
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func& func)
-  {
-    return func(redux_novec_unroller<Func, Derived, Start, HalfLength>::run(mat,func),
-                redux_novec_unroller<Func, Derived, Start+HalfLength, Length-HalfLength>::run(mat,func));
-  }
-};
-
-template<typename Func, typename Derived, int Start>
-struct redux_novec_unroller<Func, Derived, Start, 1>
-{
-  enum {
-    outer = Start / Derived::InnerSizeAtCompileTime,
-    inner = Start % Derived::InnerSizeAtCompileTime
-  };
-
-  typedef typename Derived::Scalar Scalar;
-
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func&)
-  {
-    return mat.coeffByOuterInner(outer, inner);
-  }
-};
-
-// This is actually dead code and will never be called. It is required
-// to prevent false warnings regarding failed inlining though
-// for 0 length run() will never be called at all.
-template<typename Func, typename Derived, int Start>
-struct redux_novec_unroller<Func, Derived, Start, 0>
-{
-  typedef typename Derived::Scalar Scalar;
-  EIGEN_DEVICE_FUNC 
-  static EIGEN_STRONG_INLINE Scalar run(const Derived&, const Func&) { return Scalar(); }
-};
-
-/*** vectorization ***/
-
-template<typename Func, typename Derived, int Start, int Length>
-struct redux_vec_unroller
-{
-  enum {
-    PacketSize = redux_traits<Func, Derived>::PacketSize,
-    HalfLength = Length/2
-  };
-
-  typedef typename Derived::Scalar Scalar;
-  typedef typename redux_traits<Func, Derived>::PacketType PacketScalar;
-
-  static EIGEN_STRONG_INLINE PacketScalar run(const Derived &mat, const Func& func)
-  {
-    return func.packetOp(
-            redux_vec_unroller<Func, Derived, Start, HalfLength>::run(mat,func),
-            redux_vec_unroller<Func, Derived, Start+HalfLength, Length-HalfLength>::run(mat,func) );
-  }
-};
-
-template<typename Func, typename Derived, int Start>
-struct redux_vec_unroller<Func, Derived, Start, 1>
-{
-  enum {
-    index = Start * redux_traits<Func, Derived>::PacketSize,
-    outer = index / int(Derived::InnerSizeAtCompileTime),
-    inner = index % int(Derived::InnerSizeAtCompileTime),
-    alignment = Derived::Alignment
-  };
-
-  typedef typename Derived::Scalar Scalar;
-  typedef typename redux_traits<Func, Derived>::PacketType PacketScalar;
-
-  static EIGEN_STRONG_INLINE PacketScalar run(const Derived &mat, const Func&)
-  {
-    return mat.template packetByOuterInner<alignment,PacketScalar>(outer, inner);
-  }
-};
-
-/***************************************************************************
-* Part 3 : implementation of all cases
-***************************************************************************/
-
-template<typename Func, typename Derived,
-         int Traversal = redux_traits<Func, Derived>::Traversal,
-         int Unrolling = redux_traits<Func, Derived>::Unrolling
->
-struct redux_impl;
-
-template<typename Func, typename Derived>
-struct redux_impl<Func, Derived, DefaultTraversal, NoUnrolling>
-{
-  typedef typename Derived::Scalar Scalar;
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func& func)
-  {
-    eigen_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix");
-    Scalar res;
-    res = mat.coeffByOuterInner(0, 0);
-    for(Index i = 1; i < mat.innerSize(); ++i)
-      res = func(res, mat.coeffByOuterInner(0, i));
-    for(Index i = 1; i < mat.outerSize(); ++i)
-      for(Index j = 0; j < mat.innerSize(); ++j)
-        res = func(res, mat.coeffByOuterInner(i, j));
-    return res;
-  }
-};
-
-template<typename Func, typename Derived>
-struct redux_impl<Func,Derived, DefaultTraversal, CompleteUnrolling>
-  : public redux_novec_unroller<Func,Derived, 0, Derived::SizeAtCompileTime>
-{};
-
-template<typename Func, typename Derived>
-struct redux_impl<Func, Derived, LinearVectorizedTraversal, NoUnrolling>
-{
-  typedef typename Derived::Scalar Scalar;
-  typedef typename redux_traits<Func, Derived>::PacketType PacketScalar;
-
-  static Scalar run(const Derived &mat, const Func& func)
-  {
-    const Index size = mat.size();
-    
-    const Index packetSize = redux_traits<Func, Derived>::PacketSize;
-    const int packetAlignment = unpacket_traits<PacketScalar>::alignment;
-    enum {
-      alignment0 = (bool(Derived::Flags & DirectAccessBit) && bool(packet_traits<Scalar>::AlignedOnScalar)) ? int(packetAlignment) : int(Unaligned),
-      alignment = EIGEN_PLAIN_ENUM_MAX(alignment0, Derived::Alignment)
-    };
-    const Index alignedStart = internal::first_default_aligned(mat.nestedExpression());
-    const Index alignedSize2 = ((size-alignedStart)/(2*packetSize))*(2*packetSize);
-    const Index alignedSize = ((size-alignedStart)/(packetSize))*(packetSize);
-    const Index alignedEnd2 = alignedStart + alignedSize2;
-    const Index alignedEnd  = alignedStart + alignedSize;
-    Scalar res;
-    if(alignedSize)
-    {
-      PacketScalar packet_res0 = mat.template packet<alignment,PacketScalar>(alignedStart);
-      if(alignedSize>packetSize) // we have at least two packets to partly unroll the loop
-      {
-        PacketScalar packet_res1 = mat.template packet<alignment,PacketScalar>(alignedStart+packetSize);
-        for(Index index = alignedStart + 2*packetSize; index < alignedEnd2; index += 2*packetSize)
-        {
-          packet_res0 = func.packetOp(packet_res0, mat.template packet<alignment,PacketScalar>(index));
-          packet_res1 = func.packetOp(packet_res1, mat.template packet<alignment,PacketScalar>(index+packetSize));
-        }
-
-        packet_res0 = func.packetOp(packet_res0,packet_res1);
-        if(alignedEnd>alignedEnd2)
-          packet_res0 = func.packetOp(packet_res0, mat.template packet<alignment,PacketScalar>(alignedEnd2));
-      }
-      res = func.predux(packet_res0);
-
-      for(Index index = 0; index < alignedStart; ++index)
-        res = func(res,mat.coeff(index));
-
-      for(Index index = alignedEnd; index < size; ++index)
-        res = func(res,mat.coeff(index));
-    }
-    else // too small to vectorize anything.
-         // since this is dynamic-size hence inefficient anyway for such small sizes, don't try to optimize.
-    {
-      res = mat.coeff(0);
-      for(Index index = 1; index < size; ++index)
-        res = func(res,mat.coeff(index));
-    }
-
-    return res;
-  }
-};
-
-// NOTE: for SliceVectorizedTraversal we simply bypass unrolling
-template<typename Func, typename Derived, int Unrolling>
-struct redux_impl<Func, Derived, SliceVectorizedTraversal, Unrolling>
-{
-  typedef typename Derived::Scalar Scalar;
-  typedef typename redux_traits<Func, Derived>::PacketType PacketType;
-
-  EIGEN_DEVICE_FUNC static Scalar run(const Derived &mat, const Func& func)
-  {
-    eigen_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix");
-    const Index innerSize = mat.innerSize();
-    const Index outerSize = mat.outerSize();
-    enum {
-      packetSize = redux_traits<Func, Derived>::PacketSize
-    };
-    const Index packetedInnerSize = ((innerSize)/packetSize)*packetSize;
-    Scalar res;
-    if(packetedInnerSize)
-    {
-      PacketType packet_res = mat.template packet<Unaligned,PacketType>(0,0);
-      for(Index j=0; j<outerSize; ++j)
-        for(Index i=(j==0?packetSize:0); i<packetedInnerSize; i+=Index(packetSize))
-          packet_res = func.packetOp(packet_res, mat.template packetByOuterInner<Unaligned,PacketType>(j,i));
-
-      res = func.predux(packet_res);
-      for(Index j=0; j<outerSize; ++j)
-        for(Index i=packetedInnerSize; i<innerSize; ++i)
-          res = func(res, mat.coeffByOuterInner(j,i));
-    }
-    else // too small to vectorize anything.
-         // since this is dynamic-size hence inefficient anyway for such small sizes, don't try to optimize.
-    {
-      res = redux_impl<Func, Derived, DefaultTraversal, NoUnrolling>::run(mat, func);
-    }
-
-    return res;
-  }
-};
-
-template<typename Func, typename Derived>
-struct redux_impl<Func, Derived, LinearVectorizedTraversal, CompleteUnrolling>
-{
-  typedef typename Derived::Scalar Scalar;
-
-  typedef typename redux_traits<Func, Derived>::PacketType PacketScalar;
-  enum {
-    PacketSize = redux_traits<Func, Derived>::PacketSize,
-    Size = Derived::SizeAtCompileTime,
-    VectorizedSize = (Size / PacketSize) * PacketSize
-  };
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Scalar run(const Derived &mat, const Func& func)
-  {
-    eigen_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix");
-    if (VectorizedSize > 0) {
-      Scalar res = func.predux(redux_vec_unroller<Func, Derived, 0, Size / PacketSize>::run(mat,func));
-      if (VectorizedSize != Size)
-        res = func(res,redux_novec_unroller<Func, Derived, VectorizedSize, Size-VectorizedSize>::run(mat,func));
-      return res;
-    }
-    else {
-      return redux_novec_unroller<Func, Derived, 0, Size>::run(mat,func);
-    }
-  }
-};
-
-// evaluator adaptor
-template<typename _XprType>
-class redux_evaluator
-{
-public:
-  typedef _XprType XprType;
-  EIGEN_DEVICE_FUNC explicit redux_evaluator(const XprType &xpr) : m_evaluator(xpr), m_xpr(xpr) {}
-  
-  typedef typename XprType::Scalar Scalar;
-  typedef typename XprType::CoeffReturnType CoeffReturnType;
-  typedef typename XprType::PacketScalar PacketScalar;
-  typedef typename XprType::PacketReturnType PacketReturnType;
-  
-  enum {
-    MaxRowsAtCompileTime = XprType::MaxRowsAtCompileTime,
-    MaxColsAtCompileTime = XprType::MaxColsAtCompileTime,
-    // TODO we should not remove DirectAccessBit and rather find an elegant way to query the alignment offset at runtime from the evaluator
-    Flags = evaluator<XprType>::Flags & ~DirectAccessBit,
-    IsRowMajor = XprType::IsRowMajor,
-    SizeAtCompileTime = XprType::SizeAtCompileTime,
-    InnerSizeAtCompileTime = XprType::InnerSizeAtCompileTime,
-    CoeffReadCost = evaluator<XprType>::CoeffReadCost,
-    Alignment = evaluator<XprType>::Alignment
-  };
-  
-  EIGEN_DEVICE_FUNC Index rows() const { return m_xpr.rows(); }
-  EIGEN_DEVICE_FUNC Index cols() const { return m_xpr.cols(); }
-  EIGEN_DEVICE_FUNC Index size() const { return m_xpr.size(); }
-  EIGEN_DEVICE_FUNC Index innerSize() const { return m_xpr.innerSize(); }
-  EIGEN_DEVICE_FUNC Index outerSize() const { return m_xpr.outerSize(); }
-
-  EIGEN_DEVICE_FUNC
-  CoeffReturnType coeff(Index row, Index col) const
-  { return m_evaluator.coeff(row, col); }
-
-  EIGEN_DEVICE_FUNC
-  CoeffReturnType coeff(Index index) const
-  { return m_evaluator.coeff(index); }
-
-  template<int LoadMode, typename PacketType>
-  PacketType packet(Index row, Index col) const
-  { return m_evaluator.template packet<LoadMode,PacketType>(row, col); }
-
-  template<int LoadMode, typename PacketType>
-  PacketType packet(Index index) const
-  { return m_evaluator.template packet<LoadMode,PacketType>(index); }
-  
-  EIGEN_DEVICE_FUNC
-  CoeffReturnType coeffByOuterInner(Index outer, Index inner) const
-  { return m_evaluator.coeff(IsRowMajor ? outer : inner, IsRowMajor ? inner : outer); }
-  
-  template<int LoadMode, typename PacketType>
-  PacketType packetByOuterInner(Index outer, Index inner) const
-  { return m_evaluator.template packet<LoadMode,PacketType>(IsRowMajor ? outer : inner, IsRowMajor ? inner : outer); }
-  
-  const XprType & nestedExpression() const { return m_xpr; }
-  
-protected:
-  internal::evaluator<XprType> m_evaluator;
-  const XprType &m_xpr;
-};
-
-} // end namespace internal
-
-/***************************************************************************
-* Part 4 : public API
-***************************************************************************/
-
-
-/** \returns the result of a full redux operation on the whole matrix or vector using \a func
-  *
-  * The template parameter \a BinaryOp is the type of the functor \a func which must be
-  * an associative operator. Both current C++98 and C++11 functor styles are handled.
-  *
-  * \sa DenseBase::sum(), DenseBase::minCoeff(), DenseBase::maxCoeff(), MatrixBase::colwise(), MatrixBase::rowwise()
-  */
-template<typename Derived>
-template<typename Func>
-EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
-DenseBase<Derived>::redux(const Func& func) const
-{
-  eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
-
-  typedef typename internal::redux_evaluator<Derived> ThisEvaluator;
-  ThisEvaluator thisEval(derived());
-  
-  return internal::redux_impl<Func, ThisEvaluator>::run(thisEval, func);
-}
-
-/** \returns the minimum of all coefficients of \c *this.
-  * \warning the result is undefined if \c *this contains NaN.
-  */
-template<typename Derived>
-EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
-DenseBase<Derived>::minCoeff() const
-{
-  return derived().redux(Eigen::internal::scalar_min_op<Scalar,Scalar>());
-}
-
-/** \returns the maximum of all coefficients of \c *this.
-  * \warning the result is undefined if \c *this contains NaN.
-  */
-template<typename Derived>
-EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
-DenseBase<Derived>::maxCoeff() const
-{
-  return derived().redux(Eigen::internal::scalar_max_op<Scalar,Scalar>());
-}
-
-/** \returns the sum of all coefficients of \c *this
-  *
-  * If \c *this is empty, then the value 0 is returned.
-  *
-  * \sa trace(), prod(), mean()
-  */
-template<typename Derived>
-EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
-DenseBase<Derived>::sum() const
-{
-  if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0))
-    return Scalar(0);
-  return derived().redux(Eigen::internal::scalar_sum_op<Scalar,Scalar>());
-}
-
-/** \returns the mean of all coefficients of *this
-*
-* \sa trace(), prod(), sum()
-*/
-template<typename Derived>
-EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
-DenseBase<Derived>::mean() const
-{
-#ifdef __INTEL_COMPILER
-  #pragma warning push
-  #pragma warning ( disable : 2259 )
-#endif
-  return Scalar(derived().redux(Eigen::internal::scalar_sum_op<Scalar,Scalar>())) / Scalar(this->size());
-#ifdef __INTEL_COMPILER
-  #pragma warning pop
-#endif
-}
-
-/** \returns the product of all coefficients of *this
-  *
-  * Example: \include MatrixBase_prod.cpp
-  * Output: \verbinclude MatrixBase_prod.out
-  *
-  * \sa sum(), mean(), trace()
-  */
-template<typename Derived>
-EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
-DenseBase<Derived>::prod() const
-{
-  if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0))
-    return Scalar(1);
-  return derived().redux(Eigen::internal::scalar_product_op<Scalar>());
-}
-
-/** \returns the trace of \c *this, i.e. the sum of the coefficients on the main diagonal.
-  *
-  * \c *this can be any matrix, not necessarily square.
-  *
-  * \sa diagonal(), sum()
-  */
-template<typename Derived>
-EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
-MatrixBase<Derived>::trace() const
-{
-  return derived().diagonal().sum();
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_REDUX_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Ref.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Ref.h
deleted file mode 100644
index 9c6e3c5..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Ref.h
+++ /dev/null
@@ -1,283 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2012 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_REF_H
-#define EIGEN_REF_H
-
-namespace Eigen { 
-
-namespace internal {
-
-template<typename _PlainObjectType, int _Options, typename _StrideType>
-struct traits<Ref<_PlainObjectType, _Options, _StrideType> >
-  : public traits<Map<_PlainObjectType, _Options, _StrideType> >
-{
-  typedef _PlainObjectType PlainObjectType;
-  typedef _StrideType StrideType;
-  enum {
-    Options = _Options,
-    Flags = traits<Map<_PlainObjectType, _Options, _StrideType> >::Flags | NestByRefBit,
-    Alignment = traits<Map<_PlainObjectType, _Options, _StrideType> >::Alignment
-  };
-
-  template<typename Derived> struct match {
-    enum {
-      HasDirectAccess = internal::has_direct_access<Derived>::ret,
-      StorageOrderMatch = PlainObjectType::IsVectorAtCompileTime || Derived::IsVectorAtCompileTime || ((PlainObjectType::Flags&RowMajorBit)==(Derived::Flags&RowMajorBit)),
-      InnerStrideMatch = int(StrideType::InnerStrideAtCompileTime)==int(Dynamic)
-                      || int(StrideType::InnerStrideAtCompileTime)==int(Derived::InnerStrideAtCompileTime)
-                      || (int(StrideType::InnerStrideAtCompileTime)==0 && int(Derived::InnerStrideAtCompileTime)==1),
-      OuterStrideMatch = Derived::IsVectorAtCompileTime
-                      || int(StrideType::OuterStrideAtCompileTime)==int(Dynamic) || int(StrideType::OuterStrideAtCompileTime)==int(Derived::OuterStrideAtCompileTime),
-      // NOTE, this indirection of evaluator<Derived>::Alignment is needed
-      // to workaround a very strange bug in MSVC related to the instantiation
-      // of has_*ary_operator in evaluator<CwiseNullaryOp>.
-      // This line is surprisingly very sensitive. For instance, simply adding parenthesis
-      // as "DerivedAlignment = (int(evaluator<Derived>::Alignment))," will make MSVC fail...
-      DerivedAlignment = int(evaluator<Derived>::Alignment),
-      AlignmentMatch = (int(traits<PlainObjectType>::Alignment)==int(Unaligned)) || (DerivedAlignment >= int(Alignment)), // FIXME the first condition is not very clear, it should be replaced by the required alignment
-      ScalarTypeMatch = internal::is_same<typename PlainObjectType::Scalar, typename Derived::Scalar>::value,
-      MatchAtCompileTime = HasDirectAccess && StorageOrderMatch && InnerStrideMatch && OuterStrideMatch && AlignmentMatch && ScalarTypeMatch
-    };
-    typedef typename internal::conditional<MatchAtCompileTime,internal::true_type,internal::false_type>::type type;
-  };
-  
-};
-
-template<typename Derived>
-struct traits<RefBase<Derived> > : public traits<Derived> {};
-
-}
-
-template<typename Derived> class RefBase
- : public MapBase<Derived>
-{
-  typedef typename internal::traits<Derived>::PlainObjectType PlainObjectType;
-  typedef typename internal::traits<Derived>::StrideType StrideType;
-
-public:
-
-  typedef MapBase<Derived> Base;
-  EIGEN_DENSE_PUBLIC_INTERFACE(RefBase)
-
-  EIGEN_DEVICE_FUNC inline Index innerStride() const
-  {
-    return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1;
-  }
-
-  EIGEN_DEVICE_FUNC inline Index outerStride() const
-  {
-    return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer()
-         : IsVectorAtCompileTime ? this->size()
-         : int(Flags)&RowMajorBit ? this->cols()
-         : this->rows();
-  }
-
-  EIGEN_DEVICE_FUNC RefBase()
-    : Base(0,RowsAtCompileTime==Dynamic?0:RowsAtCompileTime,ColsAtCompileTime==Dynamic?0:ColsAtCompileTime),
-      // Stride<> does not allow default ctor for Dynamic strides, so let' initialize it with dummy values:
-      m_stride(StrideType::OuterStrideAtCompileTime==Dynamic?0:StrideType::OuterStrideAtCompileTime,
-               StrideType::InnerStrideAtCompileTime==Dynamic?0:StrideType::InnerStrideAtCompileTime)
-  {}
-  
-  EIGEN_INHERIT_ASSIGNMENT_OPERATORS(RefBase)
-
-protected:
-
-  typedef Stride<StrideType::OuterStrideAtCompileTime,StrideType::InnerStrideAtCompileTime> StrideBase;
-
-  template<typename Expression>
-  EIGEN_DEVICE_FUNC void construct(Expression& expr)
-  {
-    EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(PlainObjectType,Expression);
-
-    if(PlainObjectType::RowsAtCompileTime==1)
-    {
-      eigen_assert(expr.rows()==1 || expr.cols()==1);
-      ::new (static_cast<Base*>(this)) Base(expr.data(), 1, expr.size());
-    }
-    else if(PlainObjectType::ColsAtCompileTime==1)
-    {
-      eigen_assert(expr.rows()==1 || expr.cols()==1);
-      ::new (static_cast<Base*>(this)) Base(expr.data(), expr.size(), 1);
-    }
-    else
-      ::new (static_cast<Base*>(this)) Base(expr.data(), expr.rows(), expr.cols());
-    
-    if(Expression::IsVectorAtCompileTime && (!PlainObjectType::IsVectorAtCompileTime) && ((Expression::Flags&RowMajorBit)!=(PlainObjectType::Flags&RowMajorBit)))
-      ::new (&m_stride) StrideBase(expr.innerStride(), StrideType::InnerStrideAtCompileTime==0?0:1);
-    else
-      ::new (&m_stride) StrideBase(StrideType::OuterStrideAtCompileTime==0?0:expr.outerStride(),
-                                   StrideType::InnerStrideAtCompileTime==0?0:expr.innerStride());    
-  }
-
-  StrideBase m_stride;
-};
-
-/** \class Ref
-  * \ingroup Core_Module
-  *
-  * \brief A matrix or vector expression mapping an existing expression
-  *
-  * \tparam PlainObjectType the equivalent matrix type of the mapped data
-  * \tparam Options specifies the pointer alignment in bytes. It can be: \c #Aligned128, , \c #Aligned64, \c #Aligned32, \c #Aligned16, \c #Aligned8 or \c #Unaligned.
-  *                 The default is \c #Unaligned.
-  * \tparam StrideType optionally specifies strides. By default, Ref implies a contiguous storage along the inner dimension (inner stride==1),
-  *                   but accepts a variable outer stride (leading dimension).
-  *                   This can be overridden by specifying strides.
-  *                   The type passed here must be a specialization of the Stride template, see examples below.
-  *
-  * This class provides a way to write non-template functions taking Eigen objects as parameters while limiting the number of copies.
-  * A Ref<> object can represent either a const expression or a l-value:
-  * \code
-  * // in-out argument:
-  * void foo1(Ref<VectorXf> x);
-  *
-  * // read-only const argument:
-  * void foo2(const Ref<const VectorXf>& x);
-  * \endcode
-  *
-  * In the in-out case, the input argument must satisfy the constraints of the actual Ref<> type, otherwise a compilation issue will be triggered.
-  * By default, a Ref<VectorXf> can reference any dense vector expression of float having a contiguous memory layout.
-  * Likewise, a Ref<MatrixXf> can reference any column-major dense matrix expression of float whose column's elements are contiguously stored with
-  * the possibility to have a constant space in-between each column, i.e. the inner stride must be equal to 1, but the outer stride (or leading dimension)
-  * can be greater than the number of rows.
-  *
-  * In the const case, if the input expression does not match the above requirement, then it is evaluated into a temporary before being passed to the function.
-  * Here are some examples:
-  * \code
-  * MatrixXf A;
-  * VectorXf a;
-  * foo1(a.head());             // OK
-  * foo1(A.col());              // OK
-  * foo1(A.row());              // Compilation error because here innerstride!=1
-  * foo2(A.row());              // Compilation error because A.row() is a 1xN object while foo2 is expecting a Nx1 object
-  * foo2(A.row().transpose());  // The row is copied into a contiguous temporary
-  * foo2(2*a);                  // The expression is evaluated into a temporary
-  * foo2(A.col().segment(2,4)); // No temporary
-  * \endcode
-  *
-  * The range of inputs that can be referenced without temporary can be enlarged using the last two template parameters.
-  * Here is an example accepting an innerstride!=1:
-  * \code
-  * // in-out argument:
-  * void foo3(Ref<VectorXf,0,InnerStride<> > x);
-  * foo3(A.row());              // OK
-  * \endcode
-  * The downside here is that the function foo3 might be significantly slower than foo1 because it won't be able to exploit vectorization, and will involve more
-  * expensive address computations even if the input is contiguously stored in memory. To overcome this issue, one might propose to overload internally calling a
-  * template function, e.g.:
-  * \code
-  * // in the .h:
-  * void foo(const Ref<MatrixXf>& A);
-  * void foo(const Ref<MatrixXf,0,Stride<> >& A);
-  *
-  * // in the .cpp:
-  * template<typename TypeOfA> void foo_impl(const TypeOfA& A) {
-  *     ... // crazy code goes here
-  * }
-  * void foo(const Ref<MatrixXf>& A) { foo_impl(A); }
-  * void foo(const Ref<MatrixXf,0,Stride<> >& A) { foo_impl(A); }
-  * \endcode
-  *
-  *
-  * \sa PlainObjectBase::Map(), \ref TopicStorageOrders
-  */
-template<typename PlainObjectType, int Options, typename StrideType> class Ref
-  : public RefBase<Ref<PlainObjectType, Options, StrideType> >
-{
-  private:
-    typedef internal::traits<Ref> Traits;
-    template<typename Derived>
-    EIGEN_DEVICE_FUNC inline Ref(const PlainObjectBase<Derived>& expr,
-                                 typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0);
-  public:
-
-    typedef RefBase<Ref> Base;
-    EIGEN_DENSE_PUBLIC_INTERFACE(Ref)
-
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    template<typename Derived>
-    EIGEN_DEVICE_FUNC inline Ref(PlainObjectBase<Derived>& expr,
-                                 typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
-    {
-      EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
-      Base::construct(expr.derived());
-    }
-    template<typename Derived>
-    EIGEN_DEVICE_FUNC inline Ref(const DenseBase<Derived>& expr,
-                                 typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
-    #else
-    /** Implicit constructor from any dense expression */
-    template<typename Derived>
-    inline Ref(DenseBase<Derived>& expr)
-    #endif
-    {
-      EIGEN_STATIC_ASSERT(bool(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
-      EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
-      EIGEN_STATIC_ASSERT(!Derived::IsPlainObjectBase,THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
-      Base::construct(expr.const_cast_derived());
-    }
-
-    EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Ref)
-
-};
-
-// this is the const ref version
-template<typename TPlainObjectType, int Options, typename StrideType> class Ref<const TPlainObjectType, Options, StrideType>
-  : public RefBase<Ref<const TPlainObjectType, Options, StrideType> >
-{
-    typedef internal::traits<Ref> Traits;
-  public:
-
-    typedef RefBase<Ref> Base;
-    EIGEN_DENSE_PUBLIC_INTERFACE(Ref)
-
-    template<typename Derived>
-    EIGEN_DEVICE_FUNC inline Ref(const DenseBase<Derived>& expr,
-                                 typename internal::enable_if<bool(Traits::template match<Derived>::ScalarTypeMatch),Derived>::type* = 0)
-    {
-//      std::cout << match_helper<Derived>::HasDirectAccess << "," << match_helper<Derived>::OuterStrideMatch << "," << match_helper<Derived>::InnerStrideMatch << "\n";
-//      std::cout << int(StrideType::OuterStrideAtCompileTime) << " - " << int(Derived::OuterStrideAtCompileTime) << "\n";
-//      std::cout << int(StrideType::InnerStrideAtCompileTime) << " - " << int(Derived::InnerStrideAtCompileTime) << "\n";
-      construct(expr.derived(), typename Traits::template match<Derived>::type());
-    }
-
-    EIGEN_DEVICE_FUNC inline Ref(const Ref& other) : Base(other) {
-      // copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy
-    }
-
-    template<typename OtherRef>
-    EIGEN_DEVICE_FUNC inline Ref(const RefBase<OtherRef>& other) {
-      construct(other.derived(), typename Traits::template match<OtherRef>::type());
-    }
-
-  protected:
-
-    template<typename Expression>
-    EIGEN_DEVICE_FUNC void construct(const Expression& expr,internal::true_type)
-    {
-      Base::construct(expr);
-    }
-
-    template<typename Expression>
-    EIGEN_DEVICE_FUNC void construct(const Expression& expr, internal::false_type)
-    {
-      internal::call_assignment_no_alias(m_object,expr,internal::assign_op<Scalar,Scalar>());
-      Base::construct(m_object);
-    }
-
-  protected:
-    TPlainObjectType m_object;
-};
-
-} // end namespace Eigen
-
-#endif // EIGEN_REF_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Replicate.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Replicate.h
deleted file mode 100644
index 9960ef8..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Replicate.h
+++ /dev/null
@@ -1,142 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_REPLICATE_H
-#define EIGEN_REPLICATE_H
-
-namespace Eigen { 
-
-namespace internal {
-template<typename MatrixType,int RowFactor,int ColFactor>
-struct traits<Replicate<MatrixType,RowFactor,ColFactor> >
- : traits<MatrixType>
-{
-  typedef typename MatrixType::Scalar Scalar;
-  typedef typename traits<MatrixType>::StorageKind StorageKind;
-  typedef typename traits<MatrixType>::XprKind XprKind;
-  typedef typename ref_selector<MatrixType>::type MatrixTypeNested;
-  typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested;
-  enum {
-    RowsAtCompileTime = RowFactor==Dynamic || int(MatrixType::RowsAtCompileTime)==Dynamic
-                      ? Dynamic
-                      : RowFactor * MatrixType::RowsAtCompileTime,
-    ColsAtCompileTime = ColFactor==Dynamic || int(MatrixType::ColsAtCompileTime)==Dynamic
-                      ? Dynamic
-                      : ColFactor * MatrixType::ColsAtCompileTime,
-   //FIXME we don't propagate the max sizes !!!
-    MaxRowsAtCompileTime = RowsAtCompileTime,
-    MaxColsAtCompileTime = ColsAtCompileTime,
-    IsRowMajor = MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1 ? 1
-               : MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1 ? 0
-               : (MatrixType::Flags & RowMajorBit) ? 1 : 0,
-    
-    // FIXME enable DirectAccess with negative strides?
-    Flags = IsRowMajor ? RowMajorBit : 0
-  };
-};
-}
-
-/**
-  * \class Replicate
-  * \ingroup Core_Module
-  *
-  * \brief Expression of the multiple replication of a matrix or vector
-  *
-  * \tparam MatrixType the type of the object we are replicating
-  * \tparam RowFactor number of repetitions at compile time along the vertical direction, can be Dynamic.
-  * \tparam ColFactor number of repetitions at compile time along the horizontal direction, can be Dynamic.
-  *
-  * This class represents an expression of the multiple replication of a matrix or vector.
-  * It is the return type of DenseBase::replicate() and most of the time
-  * this is the only way it is used.
-  *
-  * \sa DenseBase::replicate()
-  */
-template<typename MatrixType,int RowFactor,int ColFactor> class Replicate
-  : public internal::dense_xpr_base< Replicate<MatrixType,RowFactor,ColFactor> >::type
-{
-    typedef typename internal::traits<Replicate>::MatrixTypeNested MatrixTypeNested;
-    typedef typename internal::traits<Replicate>::_MatrixTypeNested _MatrixTypeNested;
-  public:
-
-    typedef typename internal::dense_xpr_base<Replicate>::type Base;
-    EIGEN_DENSE_PUBLIC_INTERFACE(Replicate)
-    typedef typename internal::remove_all<MatrixType>::type NestedExpression;
-
-    template<typename OriginalMatrixType>
-    EIGEN_DEVICE_FUNC
-    inline explicit Replicate(const OriginalMatrixType& matrix)
-      : m_matrix(matrix), m_rowFactor(RowFactor), m_colFactor(ColFactor)
-    {
-      EIGEN_STATIC_ASSERT((internal::is_same<typename internal::remove_const<MatrixType>::type,OriginalMatrixType>::value),
-                          THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE)
-      eigen_assert(RowFactor!=Dynamic && ColFactor!=Dynamic);
-    }
-
-    template<typename OriginalMatrixType>
-    EIGEN_DEVICE_FUNC
-    inline Replicate(const OriginalMatrixType& matrix, Index rowFactor, Index colFactor)
-      : m_matrix(matrix), m_rowFactor(rowFactor), m_colFactor(colFactor)
-    {
-      EIGEN_STATIC_ASSERT((internal::is_same<typename internal::remove_const<MatrixType>::type,OriginalMatrixType>::value),
-                          THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE)
-    }
-
-    EIGEN_DEVICE_FUNC
-    inline Index rows() const { return m_matrix.rows() * m_rowFactor.value(); }
-    EIGEN_DEVICE_FUNC
-    inline Index cols() const { return m_matrix.cols() * m_colFactor.value(); }
-
-    EIGEN_DEVICE_FUNC
-    const _MatrixTypeNested& nestedExpression() const
-    { 
-      return m_matrix; 
-    }
-
-  protected:
-    MatrixTypeNested m_matrix;
-    const internal::variable_if_dynamic<Index, RowFactor> m_rowFactor;
-    const internal::variable_if_dynamic<Index, ColFactor> m_colFactor;
-};
-
-/**
-  * \return an expression of the replication of \c *this
-  *
-  * Example: \include MatrixBase_replicate.cpp
-  * Output: \verbinclude MatrixBase_replicate.out
-  *
-  * \sa VectorwiseOp::replicate(), DenseBase::replicate(Index,Index), class Replicate
-  */
-template<typename Derived>
-template<int RowFactor, int ColFactor>
-const Replicate<Derived,RowFactor,ColFactor>
-DenseBase<Derived>::replicate() const
-{
-  return Replicate<Derived,RowFactor,ColFactor>(derived());
-}
-
-/**
-  * \return an expression of the replication of each column (or row) of \c *this
-  *
-  * Example: \include DirectionWise_replicate_int.cpp
-  * Output: \verbinclude DirectionWise_replicate_int.out
-  *
-  * \sa VectorwiseOp::replicate(), DenseBase::replicate(), class Replicate
-  */
-template<typename ExpressionType, int Direction>
-const typename VectorwiseOp<ExpressionType,Direction>::ReplicateReturnType
-VectorwiseOp<ExpressionType,Direction>::replicate(Index factor) const
-{
-  return typename VectorwiseOp<ExpressionType,Direction>::ReplicateReturnType
-          (_expression(),Direction==Vertical?factor:1,Direction==Horizontal?factor:1);
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_REPLICATE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/ReturnByValue.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/ReturnByValue.h
deleted file mode 100644
index c44b767..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/ReturnByValue.h
+++ /dev/null
@@ -1,117 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2009-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_RETURNBYVALUE_H
-#define EIGEN_RETURNBYVALUE_H
-
-namespace Eigen {
-
-namespace internal {
-
-template<typename Derived>
-struct traits<ReturnByValue<Derived> >
-  : public traits<typename traits<Derived>::ReturnType>
-{
-  enum {
-    // We're disabling the DirectAccess because e.g. the constructor of
-    // the Block-with-DirectAccess expression requires to have a coeffRef method.
-    // Also, we don't want to have to implement the stride stuff.
-    Flags = (traits<typename traits<Derived>::ReturnType>::Flags
-             | EvalBeforeNestingBit) & ~DirectAccessBit
-  };
-};
-
-/* The ReturnByValue object doesn't even have a coeff() method.
- * So the only way that nesting it in an expression can work, is by evaluating it into a plain matrix.
- * So internal::nested always gives the plain return matrix type.
- *
- * FIXME: I don't understand why we need this specialization: isn't this taken care of by the EvalBeforeNestingBit ??
- * Answer: EvalBeforeNestingBit should be deprecated since we have the evaluators
- */
-template<typename Derived,int n,typename PlainObject>
-struct nested_eval<ReturnByValue<Derived>, n, PlainObject>
-{
-  typedef typename traits<Derived>::ReturnType type;
-};
-
-} // end namespace internal
-
-/** \class ReturnByValue
-  * \ingroup Core_Module
-  *
-  */
-template<typename Derived> class ReturnByValue
-  : public internal::dense_xpr_base< ReturnByValue<Derived> >::type, internal::no_assignment_operator
-{
-  public:
-    typedef typename internal::traits<Derived>::ReturnType ReturnType;
-
-    typedef typename internal::dense_xpr_base<ReturnByValue>::type Base;
-    EIGEN_DENSE_PUBLIC_INTERFACE(ReturnByValue)
-
-    template<typename Dest>
-    EIGEN_DEVICE_FUNC
-    inline void evalTo(Dest& dst) const
-    { static_cast<const Derived*>(this)->evalTo(dst); }
-    EIGEN_DEVICE_FUNC inline Index rows() const { return static_cast<const Derived*>(this)->rows(); }
-    EIGEN_DEVICE_FUNC inline Index cols() const { return static_cast<const Derived*>(this)->cols(); }
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-#define Unusable YOU_ARE_TRYING_TO_ACCESS_A_SINGLE_COEFFICIENT_IN_A_SPECIAL_EXPRESSION_WHERE_THAT_IS_NOT_ALLOWED_BECAUSE_THAT_WOULD_BE_INEFFICIENT
-    class Unusable{
-      Unusable(const Unusable&) {}
-      Unusable& operator=(const Unusable&) {return *this;}
-    };
-    const Unusable& coeff(Index) const { return *reinterpret_cast<const Unusable*>(this); }
-    const Unusable& coeff(Index,Index) const { return *reinterpret_cast<const Unusable*>(this); }
-    Unusable& coeffRef(Index) { return *reinterpret_cast<Unusable*>(this); }
-    Unusable& coeffRef(Index,Index) { return *reinterpret_cast<Unusable*>(this); }
-#undef Unusable
-#endif
-};
-
-template<typename Derived>
-template<typename OtherDerived>
-Derived& DenseBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other)
-{
-  other.evalTo(derived());
-  return derived();
-}
-
-namespace internal {
-
-// Expression is evaluated in a temporary; default implementation of Assignment is bypassed so that
-// when a ReturnByValue expression is assigned, the evaluator is not constructed.
-// TODO: Finalize port to new regime; ReturnByValue should not exist in the expression world
-  
-template<typename Derived>
-struct evaluator<ReturnByValue<Derived> >
-  : public evaluator<typename internal::traits<Derived>::ReturnType>
-{
-  typedef ReturnByValue<Derived> XprType;
-  typedef typename internal::traits<Derived>::ReturnType PlainObject;
-  typedef evaluator<PlainObject> Base;
-  
-  EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr)
-    : m_result(xpr.rows(), xpr.cols())
-  {
-    ::new (static_cast<Base*>(this)) Base(m_result);
-    xpr.evalTo(m_result);
-  }
-
-protected:
-  PlainObject m_result;
-};
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_RETURNBYVALUE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Reverse.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Reverse.h
deleted file mode 100644
index 0640cda..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Reverse.h
+++ /dev/null
@@ -1,211 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2009 Ricard Marxer <email@ricardmarxer.com>
-// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_REVERSE_H
-#define EIGEN_REVERSE_H
-
-namespace Eigen { 
-
-namespace internal {
-
-template<typename MatrixType, int Direction>
-struct traits<Reverse<MatrixType, Direction> >
- : traits<MatrixType>
-{
-  typedef typename MatrixType::Scalar Scalar;
-  typedef typename traits<MatrixType>::StorageKind StorageKind;
-  typedef typename traits<MatrixType>::XprKind XprKind;
-  typedef typename ref_selector<MatrixType>::type MatrixTypeNested;
-  typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested;
-  enum {
-    RowsAtCompileTime = MatrixType::RowsAtCompileTime,
-    ColsAtCompileTime = MatrixType::ColsAtCompileTime,
-    MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
-    MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
-    Flags = _MatrixTypeNested::Flags & (RowMajorBit | LvalueBit)
-  };
-};
-
-template<typename PacketType, bool ReversePacket> struct reverse_packet_cond
-{
-  static inline PacketType run(const PacketType& x) { return preverse(x); }
-};
-
-template<typename PacketType> struct reverse_packet_cond<PacketType,false>
-{
-  static inline PacketType run(const PacketType& x) { return x; }
-};
-
-} // end namespace internal 
-
-/** \class Reverse
-  * \ingroup Core_Module
-  *
-  * \brief Expression of the reverse of a vector or matrix
-  *
-  * \tparam MatrixType the type of the object of which we are taking the reverse
-  * \tparam Direction defines the direction of the reverse operation, can be Vertical, Horizontal, or BothDirections
-  *
-  * This class represents an expression of the reverse of a vector.
-  * It is the return type of MatrixBase::reverse() and VectorwiseOp::reverse()
-  * and most of the time this is the only way it is used.
-  *
-  * \sa MatrixBase::reverse(), VectorwiseOp::reverse()
-  */
-template<typename MatrixType, int Direction> class Reverse
-  : public internal::dense_xpr_base< Reverse<MatrixType, Direction> >::type
-{
-  public:
-
-    typedef typename internal::dense_xpr_base<Reverse>::type Base;
-    EIGEN_DENSE_PUBLIC_INTERFACE(Reverse)
-    typedef typename internal::remove_all<MatrixType>::type NestedExpression;
-    using Base::IsRowMajor;
-
-  protected:
-    enum {
-      PacketSize = internal::packet_traits<Scalar>::size,
-      IsColMajor = !IsRowMajor,
-      ReverseRow = (Direction == Vertical)   || (Direction == BothDirections),
-      ReverseCol = (Direction == Horizontal) || (Direction == BothDirections),
-      OffsetRow  = ReverseRow && IsColMajor ? PacketSize : 1,
-      OffsetCol  = ReverseCol && IsRowMajor ? PacketSize : 1,
-      ReversePacket = (Direction == BothDirections)
-                    || ((Direction == Vertical)   && IsColMajor)
-                    || ((Direction == Horizontal) && IsRowMajor)
-    };
-    typedef internal::reverse_packet_cond<PacketScalar,ReversePacket> reverse_packet;
-  public:
-
-    EIGEN_DEVICE_FUNC explicit inline Reverse(const MatrixType& matrix) : m_matrix(matrix) { }
-
-    EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Reverse)
-
-    EIGEN_DEVICE_FUNC inline Index rows() const { return m_matrix.rows(); }
-    EIGEN_DEVICE_FUNC inline Index cols() const { return m_matrix.cols(); }
-
-    EIGEN_DEVICE_FUNC inline Index innerStride() const
-    {
-      return -m_matrix.innerStride();
-    }
-
-    EIGEN_DEVICE_FUNC const typename internal::remove_all<typename MatrixType::Nested>::type&
-    nestedExpression() const 
-    {
-      return m_matrix;
-    }
-
-  protected:
-    typename MatrixType::Nested m_matrix;
-};
-
-/** \returns an expression of the reverse of *this.
-  *
-  * Example: \include MatrixBase_reverse.cpp
-  * Output: \verbinclude MatrixBase_reverse.out
-  *
-  */
-template<typename Derived>
-inline typename DenseBase<Derived>::ReverseReturnType
-DenseBase<Derived>::reverse()
-{
-  return ReverseReturnType(derived());
-}
-
-
-//reverse const overload moved DenseBase.h due to a CUDA compiler bug
-
-/** This is the "in place" version of reverse: it reverses \c *this.
-  *
-  * In most cases it is probably better to simply use the reversed expression
-  * of a matrix. However, when reversing the matrix data itself is really needed,
-  * then this "in-place" version is probably the right choice because it provides
-  * the following additional benefits:
-  *  - less error prone: doing the same operation with .reverse() requires special care:
-  *    \code m = m.reverse().eval(); \endcode
-  *  - this API enables reverse operations without the need for a temporary
-  *  - it allows future optimizations (cache friendliness, etc.)
-  *
-  * \sa VectorwiseOp::reverseInPlace(), reverse() */
-template<typename Derived>
-inline void DenseBase<Derived>::reverseInPlace()
-{
-  if(cols()>rows())
-  {
-    Index half = cols()/2;
-    leftCols(half).swap(rightCols(half).reverse());
-    if((cols()%2)==1)
-    {
-      Index half2 = rows()/2;
-      col(half).head(half2).swap(col(half).tail(half2).reverse());
-    }
-  }
-  else
-  {
-    Index half = rows()/2;
-    topRows(half).swap(bottomRows(half).reverse());
-    if((rows()%2)==1)
-    {
-      Index half2 = cols()/2;
-      row(half).head(half2).swap(row(half).tail(half2).reverse());
-    }
-  }
-}
-
-namespace internal {
-  
-template<int Direction>
-struct vectorwise_reverse_inplace_impl;
-
-template<>
-struct vectorwise_reverse_inplace_impl<Vertical>
-{
-  template<typename ExpressionType>
-  static void run(ExpressionType &xpr)
-  {
-    Index half = xpr.rows()/2;
-    xpr.topRows(half).swap(xpr.bottomRows(half).colwise().reverse());
-  }
-};
-
-template<>
-struct vectorwise_reverse_inplace_impl<Horizontal>
-{
-  template<typename ExpressionType>
-  static void run(ExpressionType &xpr)
-  {
-    Index half = xpr.cols()/2;
-    xpr.leftCols(half).swap(xpr.rightCols(half).rowwise().reverse());
-  }
-};
-
-} // end namespace internal
-
-/** This is the "in place" version of VectorwiseOp::reverse: it reverses each column or row of \c *this.
-  *
-  * In most cases it is probably better to simply use the reversed expression
-  * of a matrix. However, when reversing the matrix data itself is really needed,
-  * then this "in-place" version is probably the right choice because it provides
-  * the following additional benefits:
-  *  - less error prone: doing the same operation with .reverse() requires special care:
-  *    \code m = m.reverse().eval(); \endcode
-  *  - this API enables reverse operations without the need for a temporary
-  *
-  * \sa DenseBase::reverseInPlace(), reverse() */
-template<typename ExpressionType, int Direction>
-void VectorwiseOp<ExpressionType,Direction>::reverseInPlace()
-{
-  internal::vectorwise_reverse_inplace_impl<Direction>::run(_expression().const_cast_derived());
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_REVERSE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Select.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Select.h
deleted file mode 100644
index 79eec1b..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Select.h
+++ /dev/null
@@ -1,162 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_SELECT_H
-#define EIGEN_SELECT_H
-
-namespace Eigen { 
-
-/** \class Select
-  * \ingroup Core_Module
-  *
-  * \brief Expression of a coefficient wise version of the C++ ternary operator ?:
-  *
-  * \param ConditionMatrixType the type of the \em condition expression which must be a boolean matrix
-  * \param ThenMatrixType the type of the \em then expression
-  * \param ElseMatrixType the type of the \em else expression
-  *
-  * This class represents an expression of a coefficient wise version of the C++ ternary operator ?:.
-  * It is the return type of DenseBase::select() and most of the time this is the only way it is used.
-  *
-  * \sa DenseBase::select(const DenseBase<ThenDerived>&, const DenseBase<ElseDerived>&) const
-  */
-
-namespace internal {
-template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType>
-struct traits<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >
- : traits<ThenMatrixType>
-{
-  typedef typename traits<ThenMatrixType>::Scalar Scalar;
-  typedef Dense StorageKind;
-  typedef typename traits<ThenMatrixType>::XprKind XprKind;
-  typedef typename ConditionMatrixType::Nested ConditionMatrixNested;
-  typedef typename ThenMatrixType::Nested ThenMatrixNested;
-  typedef typename ElseMatrixType::Nested ElseMatrixNested;
-  enum {
-    RowsAtCompileTime = ConditionMatrixType::RowsAtCompileTime,
-    ColsAtCompileTime = ConditionMatrixType::ColsAtCompileTime,
-    MaxRowsAtCompileTime = ConditionMatrixType::MaxRowsAtCompileTime,
-    MaxColsAtCompileTime = ConditionMatrixType::MaxColsAtCompileTime,
-    Flags = (unsigned int)ThenMatrixType::Flags & ElseMatrixType::Flags & RowMajorBit
-  };
-};
-}
-
-template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType>
-class Select : public internal::dense_xpr_base< Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >::type,
-               internal::no_assignment_operator
-{
-  public:
-
-    typedef typename internal::dense_xpr_base<Select>::type Base;
-    EIGEN_DENSE_PUBLIC_INTERFACE(Select)
-
-    inline EIGEN_DEVICE_FUNC
-    Select(const ConditionMatrixType& a_conditionMatrix,
-           const ThenMatrixType& a_thenMatrix,
-           const ElseMatrixType& a_elseMatrix)
-      : m_condition(a_conditionMatrix), m_then(a_thenMatrix), m_else(a_elseMatrix)
-    {
-      eigen_assert(m_condition.rows() == m_then.rows() && m_condition.rows() == m_else.rows());
-      eigen_assert(m_condition.cols() == m_then.cols() && m_condition.cols() == m_else.cols());
-    }
-
-    inline EIGEN_DEVICE_FUNC Index rows() const { return m_condition.rows(); }
-    inline EIGEN_DEVICE_FUNC Index cols() const { return m_condition.cols(); }
-
-    inline EIGEN_DEVICE_FUNC
-    const Scalar coeff(Index i, Index j) const
-    {
-      if (m_condition.coeff(i,j))
-        return m_then.coeff(i,j);
-      else
-        return m_else.coeff(i,j);
-    }
-
-    inline EIGEN_DEVICE_FUNC
-    const Scalar coeff(Index i) const
-    {
-      if (m_condition.coeff(i))
-        return m_then.coeff(i);
-      else
-        return m_else.coeff(i);
-    }
-
-    inline EIGEN_DEVICE_FUNC const ConditionMatrixType& conditionMatrix() const
-    {
-      return m_condition;
-    }
-
-    inline EIGEN_DEVICE_FUNC const ThenMatrixType& thenMatrix() const
-    {
-      return m_then;
-    }
-
-    inline EIGEN_DEVICE_FUNC const ElseMatrixType& elseMatrix() const
-    {
-      return m_else;
-    }
-
-  protected:
-    typename ConditionMatrixType::Nested m_condition;
-    typename ThenMatrixType::Nested m_then;
-    typename ElseMatrixType::Nested m_else;
-};
-
-
-/** \returns a matrix where each coefficient (i,j) is equal to \a thenMatrix(i,j)
-  * if \c *this(i,j), and \a elseMatrix(i,j) otherwise.
-  *
-  * Example: \include MatrixBase_select.cpp
-  * Output: \verbinclude MatrixBase_select.out
-  *
-  * \sa class Select
-  */
-template<typename Derived>
-template<typename ThenDerived,typename ElseDerived>
-inline const Select<Derived,ThenDerived,ElseDerived>
-DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
-                            const DenseBase<ElseDerived>& elseMatrix) const
-{
-  return Select<Derived,ThenDerived,ElseDerived>(derived(), thenMatrix.derived(), elseMatrix.derived());
-}
-
-/** Version of DenseBase::select(const DenseBase&, const DenseBase&) with
-  * the \em else expression being a scalar value.
-  *
-  * \sa DenseBase::select(const DenseBase<ThenDerived>&, const DenseBase<ElseDerived>&) const, class Select
-  */
-template<typename Derived>
-template<typename ThenDerived>
-inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
-DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
-                           const typename ThenDerived::Scalar& elseScalar) const
-{
-  return Select<Derived,ThenDerived,typename ThenDerived::ConstantReturnType>(
-    derived(), thenMatrix.derived(), ThenDerived::Constant(rows(),cols(),elseScalar));
-}
-
-/** Version of DenseBase::select(const DenseBase&, const DenseBase&) with
-  * the \em then expression being a scalar value.
-  *
-  * \sa DenseBase::select(const DenseBase<ThenDerived>&, const DenseBase<ElseDerived>&) const, class Select
-  */
-template<typename Derived>
-template<typename ElseDerived>
-inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
-DenseBase<Derived>::select(const typename ElseDerived::Scalar& thenScalar,
-                           const DenseBase<ElseDerived>& elseMatrix) const
-{
-  return Select<Derived,typename ElseDerived::ConstantReturnType,ElseDerived>(
-    derived(), ElseDerived::Constant(rows(),cols(),thenScalar), elseMatrix.derived());
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_SELECT_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/SelfAdjointView.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/SelfAdjointView.h
deleted file mode 100644
index b2e51f3..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/SelfAdjointView.h
+++ /dev/null
@@ -1,352 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_SELFADJOINTMATRIX_H
-#define EIGEN_SELFADJOINTMATRIX_H
-
-namespace Eigen { 
-
-/** \class SelfAdjointView
-  * \ingroup Core_Module
-  *
-  *
-  * \brief Expression of a selfadjoint matrix from a triangular part of a dense matrix
-  *
-  * \param MatrixType the type of the dense matrix storing the coefficients
-  * \param TriangularPart can be either \c #Lower or \c #Upper
-  *
-  * This class is an expression of a sefladjoint matrix from a triangular part of a matrix
-  * with given dense storage of the coefficients. It is the return type of MatrixBase::selfadjointView()
-  * and most of the time this is the only way that it is used.
-  *
-  * \sa class TriangularBase, MatrixBase::selfadjointView()
-  */
-
-namespace internal {
-template<typename MatrixType, unsigned int UpLo>
-struct traits<SelfAdjointView<MatrixType, UpLo> > : traits<MatrixType>
-{
-  typedef typename ref_selector<MatrixType>::non_const_type MatrixTypeNested;
-  typedef typename remove_all<MatrixTypeNested>::type MatrixTypeNestedCleaned;
-  typedef MatrixType ExpressionType;
-  typedef typename MatrixType::PlainObject FullMatrixType;
-  enum {
-    Mode = UpLo | SelfAdjoint,
-    FlagsLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
-    Flags =  MatrixTypeNestedCleaned::Flags & (HereditaryBits|FlagsLvalueBit)
-           & (~(PacketAccessBit | DirectAccessBit | LinearAccessBit)) // FIXME these flags should be preserved
-  };
-};
-}
-
-
-template<typename _MatrixType, unsigned int UpLo> class SelfAdjointView
-  : public TriangularBase<SelfAdjointView<_MatrixType, UpLo> >
-{
-  public:
-
-    typedef _MatrixType MatrixType;
-    typedef TriangularBase<SelfAdjointView> Base;
-    typedef typename internal::traits<SelfAdjointView>::MatrixTypeNested MatrixTypeNested;
-    typedef typename internal::traits<SelfAdjointView>::MatrixTypeNestedCleaned MatrixTypeNestedCleaned;
-    typedef MatrixTypeNestedCleaned NestedExpression;
-
-    /** \brief The type of coefficients in this matrix */
-    typedef typename internal::traits<SelfAdjointView>::Scalar Scalar; 
-    typedef typename MatrixType::StorageIndex StorageIndex;
-    typedef typename internal::remove_all<typename MatrixType::ConjugateReturnType>::type MatrixConjugateReturnType;
-
-    enum {
-      Mode = internal::traits<SelfAdjointView>::Mode,
-      Flags = internal::traits<SelfAdjointView>::Flags,
-      TransposeMode = ((Mode & Upper) ? Lower : 0) | ((Mode & Lower) ? Upper : 0)
-    };
-    typedef typename MatrixType::PlainObject PlainObject;
-
-    EIGEN_DEVICE_FUNC
-    explicit inline SelfAdjointView(MatrixType& matrix) : m_matrix(matrix)
-    {
-      EIGEN_STATIC_ASSERT(UpLo==Lower || UpLo==Upper,SELFADJOINTVIEW_ACCEPTS_UPPER_AND_LOWER_MODE_ONLY);
-    }
-
-    EIGEN_DEVICE_FUNC
-    inline Index rows() const { return m_matrix.rows(); }
-    EIGEN_DEVICE_FUNC
-    inline Index cols() const { return m_matrix.cols(); }
-    EIGEN_DEVICE_FUNC
-    inline Index outerStride() const { return m_matrix.outerStride(); }
-    EIGEN_DEVICE_FUNC
-    inline Index innerStride() const { return m_matrix.innerStride(); }
-
-    /** \sa MatrixBase::coeff()
-      * \warning the coordinates must fit into the referenced triangular part
-      */
-    EIGEN_DEVICE_FUNC
-    inline Scalar coeff(Index row, Index col) const
-    {
-      Base::check_coordinates_internal(row, col);
-      return m_matrix.coeff(row, col);
-    }
-
-    /** \sa MatrixBase::coeffRef()
-      * \warning the coordinates must fit into the referenced triangular part
-      */
-    EIGEN_DEVICE_FUNC
-    inline Scalar& coeffRef(Index row, Index col)
-    {
-      EIGEN_STATIC_ASSERT_LVALUE(SelfAdjointView);
-      Base::check_coordinates_internal(row, col);
-      return m_matrix.coeffRef(row, col);
-    }
-
-    /** \internal */
-    EIGEN_DEVICE_FUNC
-    const MatrixTypeNestedCleaned& _expression() const { return m_matrix; }
-
-    EIGEN_DEVICE_FUNC
-    const MatrixTypeNestedCleaned& nestedExpression() const { return m_matrix; }
-    EIGEN_DEVICE_FUNC
-    MatrixTypeNestedCleaned& nestedExpression() { return m_matrix; }
-
-    /** Efficient triangular matrix times vector/matrix product */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    const Product<SelfAdjointView,OtherDerived>
-    operator*(const MatrixBase<OtherDerived>& rhs) const
-    {
-      return Product<SelfAdjointView,OtherDerived>(*this, rhs.derived());
-    }
-
-    /** Efficient vector/matrix times triangular matrix product */
-    template<typename OtherDerived> friend
-    EIGEN_DEVICE_FUNC
-    const Product<OtherDerived,SelfAdjointView>
-    operator*(const MatrixBase<OtherDerived>& lhs, const SelfAdjointView& rhs)
-    {
-      return Product<OtherDerived,SelfAdjointView>(lhs.derived(),rhs);
-    }
-    
-    friend EIGEN_DEVICE_FUNC
-    const SelfAdjointView<const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar,MatrixType,product),UpLo>
-    operator*(const Scalar& s, const SelfAdjointView& mat)
-    {
-      return (s*mat.nestedExpression()).template selfadjointView<UpLo>();
-    }
-
-    /** Perform a symmetric rank 2 update of the selfadjoint matrix \c *this:
-      * \f$ this = this + \alpha u v^* + conj(\alpha) v u^* \f$
-      * \returns a reference to \c *this
-      *
-      * The vectors \a u and \c v \b must be column vectors, however they can be
-      * a adjoint expression without any overhead. Only the meaningful triangular
-      * part of the matrix is updated, the rest is left unchanged.
-      *
-      * \sa rankUpdate(const MatrixBase<DerivedU>&, Scalar)
-      */
-    template<typename DerivedU, typename DerivedV>
-    EIGEN_DEVICE_FUNC
-    SelfAdjointView& rankUpdate(const MatrixBase<DerivedU>& u, const MatrixBase<DerivedV>& v, const Scalar& alpha = Scalar(1));
-
-    /** Perform a symmetric rank K update of the selfadjoint matrix \c *this:
-      * \f$ this = this + \alpha ( u u^* ) \f$ where \a u is a vector or matrix.
-      *
-      * \returns a reference to \c *this
-      *
-      * Note that to perform \f$ this = this + \alpha ( u^* u ) \f$ you can simply
-      * call this function with u.adjoint().
-      *
-      * \sa rankUpdate(const MatrixBase<DerivedU>&, const MatrixBase<DerivedV>&, Scalar)
-      */
-    template<typename DerivedU>
-    EIGEN_DEVICE_FUNC
-    SelfAdjointView& rankUpdate(const MatrixBase<DerivedU>& u, const Scalar& alpha = Scalar(1));
-
-    /** \returns an expression of a triangular view extracted from the current selfadjoint view of a given triangular part
-      *
-      * The parameter \a TriMode can have the following values: \c #Upper, \c #StrictlyUpper, \c #UnitUpper,
-      * \c #Lower, \c #StrictlyLower, \c #UnitLower.
-      *
-      * If \c TriMode references the same triangular part than \c *this, then this method simply return a \c TriangularView of the nested expression,
-      * otherwise, the nested expression is first transposed, thus returning a \c TriangularView<Transpose<MatrixType>> object.
-      *
-      * \sa MatrixBase::triangularView(), class TriangularView
-      */
-    template<unsigned int TriMode>
-    EIGEN_DEVICE_FUNC
-    typename internal::conditional<(TriMode&(Upper|Lower))==(UpLo&(Upper|Lower)),
-                                   TriangularView<MatrixType,TriMode>,
-                                   TriangularView<typename MatrixType::AdjointReturnType,TriMode> >::type
-    triangularView() const
-    {
-      typename internal::conditional<(TriMode&(Upper|Lower))==(UpLo&(Upper|Lower)), MatrixType&, typename MatrixType::ConstTransposeReturnType>::type tmp1(m_matrix);
-      typename internal::conditional<(TriMode&(Upper|Lower))==(UpLo&(Upper|Lower)), MatrixType&, typename MatrixType::AdjointReturnType>::type tmp2(tmp1);
-      return typename internal::conditional<(TriMode&(Upper|Lower))==(UpLo&(Upper|Lower)),
-                                   TriangularView<MatrixType,TriMode>,
-                                   TriangularView<typename MatrixType::AdjointReturnType,TriMode> >::type(tmp2);
-    }
-
-    typedef SelfAdjointView<const MatrixConjugateReturnType,UpLo> ConjugateReturnType;
-    /** \sa MatrixBase::conjugate() const */
-    EIGEN_DEVICE_FUNC
-    inline const ConjugateReturnType conjugate() const
-    { return ConjugateReturnType(m_matrix.conjugate()); }
-
-    typedef SelfAdjointView<const typename MatrixType::AdjointReturnType,TransposeMode> AdjointReturnType;
-    /** \sa MatrixBase::adjoint() const */
-    EIGEN_DEVICE_FUNC
-    inline const AdjointReturnType adjoint() const
-    { return AdjointReturnType(m_matrix.adjoint()); }
-
-    typedef SelfAdjointView<typename MatrixType::TransposeReturnType,TransposeMode> TransposeReturnType;
-     /** \sa MatrixBase::transpose() */
-    EIGEN_DEVICE_FUNC
-    inline TransposeReturnType transpose()
-    {
-      EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
-      typename MatrixType::TransposeReturnType tmp(m_matrix);
-      return TransposeReturnType(tmp);
-    }
-
-    typedef SelfAdjointView<const typename MatrixType::ConstTransposeReturnType,TransposeMode> ConstTransposeReturnType;
-    /** \sa MatrixBase::transpose() const */
-    EIGEN_DEVICE_FUNC
-    inline const ConstTransposeReturnType transpose() const
-    {
-      return ConstTransposeReturnType(m_matrix.transpose());
-    }
-
-    /** \returns a const expression of the main diagonal of the matrix \c *this
-      *
-      * This method simply returns the diagonal of the nested expression, thus by-passing the SelfAdjointView decorator.
-      *
-      * \sa MatrixBase::diagonal(), class Diagonal */
-    EIGEN_DEVICE_FUNC
-    typename MatrixType::ConstDiagonalReturnType diagonal() const
-    {
-      return typename MatrixType::ConstDiagonalReturnType(m_matrix);
-    }
-
-/////////// Cholesky module ///////////
-
-    const LLT<PlainObject, UpLo> llt() const;
-    const LDLT<PlainObject, UpLo> ldlt() const;
-
-/////////// Eigenvalue module ///////////
-
-    /** Real part of #Scalar */
-    typedef typename NumTraits<Scalar>::Real RealScalar;
-    /** Return type of eigenvalues() */
-    typedef Matrix<RealScalar, internal::traits<MatrixType>::ColsAtCompileTime, 1> EigenvaluesReturnType;
-
-    EIGEN_DEVICE_FUNC
-    EigenvaluesReturnType eigenvalues() const;
-    EIGEN_DEVICE_FUNC
-    RealScalar operatorNorm() const;
-
-  protected:
-    MatrixTypeNested m_matrix;
-};
-
-
-// template<typename OtherDerived, typename MatrixType, unsigned int UpLo>
-// internal::selfadjoint_matrix_product_returntype<OtherDerived,SelfAdjointView<MatrixType,UpLo> >
-// operator*(const MatrixBase<OtherDerived>& lhs, const SelfAdjointView<MatrixType,UpLo>& rhs)
-// {
-//   return internal::matrix_selfadjoint_product_returntype<OtherDerived,SelfAdjointView<MatrixType,UpLo> >(lhs.derived(),rhs);
-// }
-
-// selfadjoint to dense matrix
-
-namespace internal {
-
-// TODO currently a selfadjoint expression has the form SelfAdjointView<.,.>
-//      in the future selfadjoint-ness should be defined by the expression traits
-//      such that Transpose<SelfAdjointView<.,.> > is valid. (currently TriangularBase::transpose() is overloaded to make it work)
-template<typename MatrixType, unsigned int Mode>
-struct evaluator_traits<SelfAdjointView<MatrixType,Mode> >
-{
-  typedef typename storage_kind_to_evaluator_kind<typename MatrixType::StorageKind>::Kind Kind;
-  typedef SelfAdjointShape Shape;
-};
-
-template<int UpLo, int SetOpposite, typename DstEvaluatorTypeT, typename SrcEvaluatorTypeT, typename Functor, int Version>
-class triangular_dense_assignment_kernel<UpLo,SelfAdjoint,SetOpposite,DstEvaluatorTypeT,SrcEvaluatorTypeT,Functor,Version>
-  : public generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, Version>
-{
-protected:
-  typedef generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, Version> Base;
-  typedef typename Base::DstXprType DstXprType;
-  typedef typename Base::SrcXprType SrcXprType;
-  using Base::m_dst;
-  using Base::m_src;
-  using Base::m_functor;
-public:
-  
-  typedef typename Base::DstEvaluatorType DstEvaluatorType;
-  typedef typename Base::SrcEvaluatorType SrcEvaluatorType;
-  typedef typename Base::Scalar Scalar;
-  typedef typename Base::AssignmentTraits AssignmentTraits;
-  
-  
-  EIGEN_DEVICE_FUNC triangular_dense_assignment_kernel(DstEvaluatorType &dst, const SrcEvaluatorType &src, const Functor &func, DstXprType& dstExpr)
-    : Base(dst, src, func, dstExpr)
-  {}
-  
-  EIGEN_DEVICE_FUNC void assignCoeff(Index row, Index col)
-  {
-    eigen_internal_assert(row!=col);
-    Scalar tmp = m_src.coeff(row,col);
-    m_functor.assignCoeff(m_dst.coeffRef(row,col), tmp);
-    m_functor.assignCoeff(m_dst.coeffRef(col,row), numext::conj(tmp));
-  }
-  
-  EIGEN_DEVICE_FUNC void assignDiagonalCoeff(Index id)
-  {
-    Base::assignCoeff(id,id);
-  }
-  
-  EIGEN_DEVICE_FUNC void assignOppositeCoeff(Index, Index)
-  { eigen_internal_assert(false && "should never be called"); }
-};
-
-} // end namespace internal
-
-/***************************************************************************
-* Implementation of MatrixBase methods
-***************************************************************************/
-
-/** This is the const version of MatrixBase::selfadjointView() */
-template<typename Derived>
-template<unsigned int UpLo>
-typename MatrixBase<Derived>::template ConstSelfAdjointViewReturnType<UpLo>::Type
-MatrixBase<Derived>::selfadjointView() const
-{
-  return typename ConstSelfAdjointViewReturnType<UpLo>::Type(derived());
-}
-
-/** \returns an expression of a symmetric/self-adjoint view extracted from the upper or lower triangular part of the current matrix
-  *
-  * The parameter \a UpLo can be either \c #Upper or \c #Lower
-  *
-  * Example: \include MatrixBase_selfadjointView.cpp
-  * Output: \verbinclude MatrixBase_selfadjointView.out
-  *
-  * \sa class SelfAdjointView
-  */
-template<typename Derived>
-template<unsigned int UpLo>
-typename MatrixBase<Derived>::template SelfAdjointViewReturnType<UpLo>::Type
-MatrixBase<Derived>::selfadjointView()
-{
-  return typename SelfAdjointViewReturnType<UpLo>::Type(derived());
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_SELFADJOINTMATRIX_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/SelfCwiseBinaryOp.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/SelfCwiseBinaryOp.h
deleted file mode 100644
index 7c89c2e..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/SelfCwiseBinaryOp.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_SELFCWISEBINARYOP_H
-#define EIGEN_SELFCWISEBINARYOP_H
-
-namespace Eigen { 
-
-// TODO generalize the scalar type of 'other'
-
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator*=(const Scalar& other)
-{
-  internal::call_assignment(this->derived(), PlainObject::Constant(rows(),cols(),other), internal::mul_assign_op<Scalar,Scalar>());
-  return derived();
-}
-
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& ArrayBase<Derived>::operator+=(const Scalar& other)
-{
-  internal::call_assignment(this->derived(), PlainObject::Constant(rows(),cols(),other), internal::add_assign_op<Scalar,Scalar>());
-  return derived();
-}
-
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& ArrayBase<Derived>::operator-=(const Scalar& other)
-{
-  internal::call_assignment(this->derived(), PlainObject::Constant(rows(),cols(),other), internal::sub_assign_op<Scalar,Scalar>());
-  return derived();
-}
-
-template<typename Derived>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator/=(const Scalar& other)
-{
-  internal::call_assignment(this->derived(), PlainObject::Constant(rows(),cols(),other), internal::div_assign_op<Scalar,Scalar>());
-  return derived();
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_SELFCWISEBINARYOP_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Solve.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Solve.h
deleted file mode 100644
index a8daea5..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Solve.h
+++ /dev/null
@@ -1,188 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2014 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_SOLVE_H
-#define EIGEN_SOLVE_H
-
-namespace Eigen {
-
-template<typename Decomposition, typename RhsType, typename StorageKind> class SolveImpl;
-  
-/** \class Solve
-  * \ingroup Core_Module
-  *
-  * \brief Pseudo expression representing a solving operation
-  *
-  * \tparam Decomposition the type of the matrix or decomposion object
-  * \tparam Rhstype the type of the right-hand side
-  *
-  * This class represents an expression of A.solve(B)
-  * and most of the time this is the only way it is used.
-  *
-  */
-namespace internal {
-
-// this solve_traits class permits to determine the evaluation type with respect to storage kind (Dense vs Sparse)
-template<typename Decomposition, typename RhsType,typename StorageKind> struct solve_traits;
-
-template<typename Decomposition, typename RhsType>
-struct solve_traits<Decomposition,RhsType,Dense>
-{
-  typedef typename make_proper_matrix_type<typename RhsType::Scalar,
-                 Decomposition::ColsAtCompileTime,
-                 RhsType::ColsAtCompileTime,
-                 RhsType::PlainObject::Options,
-                 Decomposition::MaxColsAtCompileTime,
-                 RhsType::MaxColsAtCompileTime>::type PlainObject;
-};
-
-template<typename Decomposition, typename RhsType>
-struct traits<Solve<Decomposition, RhsType> >
-  : traits<typename solve_traits<Decomposition,RhsType,typename internal::traits<RhsType>::StorageKind>::PlainObject>
-{
-  typedef typename solve_traits<Decomposition,RhsType,typename internal::traits<RhsType>::StorageKind>::PlainObject PlainObject;
-  typedef typename promote_index_type<typename Decomposition::StorageIndex, typename RhsType::StorageIndex>::type StorageIndex;
-  typedef traits<PlainObject> BaseTraits;
-  enum {
-    Flags = BaseTraits::Flags & RowMajorBit,
-    CoeffReadCost = HugeCost
-  };
-};
-
-}
-
-
-template<typename Decomposition, typename RhsType>
-class Solve : public SolveImpl<Decomposition,RhsType,typename internal::traits<RhsType>::StorageKind>
-{
-public:
-  typedef typename internal::traits<Solve>::PlainObject PlainObject;
-  typedef typename internal::traits<Solve>::StorageIndex StorageIndex;
-  
-  Solve(const Decomposition &dec, const RhsType &rhs)
-    : m_dec(dec), m_rhs(rhs)
-  {}
-  
-  EIGEN_DEVICE_FUNC Index rows() const { return m_dec.cols(); }
-  EIGEN_DEVICE_FUNC Index cols() const { return m_rhs.cols(); }
-
-  EIGEN_DEVICE_FUNC const Decomposition& dec() const { return m_dec; }
-  EIGEN_DEVICE_FUNC const RhsType&       rhs() const { return m_rhs; }
-
-protected:
-  const Decomposition &m_dec;
-  const RhsType       &m_rhs;
-};
-
-
-// Specialization of the Solve expression for dense results
-template<typename Decomposition, typename RhsType>
-class SolveImpl<Decomposition,RhsType,Dense>
-  : public MatrixBase<Solve<Decomposition,RhsType> >
-{
-  typedef Solve<Decomposition,RhsType> Derived;
-  
-public:
-  
-  typedef MatrixBase<Solve<Decomposition,RhsType> > Base;
-  EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
-
-private:
-  
-  Scalar coeff(Index row, Index col) const;
-  Scalar coeff(Index i) const;
-};
-
-// Generic API dispatcher
-template<typename Decomposition, typename RhsType, typename StorageKind>
-class SolveImpl : public internal::generic_xpr_base<Solve<Decomposition,RhsType>, MatrixXpr, StorageKind>::type
-{
-  public:
-    typedef typename internal::generic_xpr_base<Solve<Decomposition,RhsType>, MatrixXpr, StorageKind>::type Base;
-};
-
-namespace internal {
-
-// Evaluator of Solve -> eval into a temporary
-template<typename Decomposition, typename RhsType>
-struct evaluator<Solve<Decomposition,RhsType> >
-  : public evaluator<typename Solve<Decomposition,RhsType>::PlainObject>
-{
-  typedef Solve<Decomposition,RhsType> SolveType;
-  typedef typename SolveType::PlainObject PlainObject;
-  typedef evaluator<PlainObject> Base;
-
-  enum { Flags = Base::Flags | EvalBeforeNestingBit };
-  
-  EIGEN_DEVICE_FUNC explicit evaluator(const SolveType& solve)
-    : m_result(solve.rows(), solve.cols())
-  {
-    ::new (static_cast<Base*>(this)) Base(m_result);
-    solve.dec()._solve_impl(solve.rhs(), m_result);
-  }
-  
-protected:  
-  PlainObject m_result;
-};
-
-// Specialization for "dst = dec.solve(rhs)"
-// NOTE we need to specialize it for Dense2Dense to avoid ambiguous specialization error and a Sparse2Sparse specialization must exist somewhere
-template<typename DstXprType, typename DecType, typename RhsType, typename Scalar>
-struct Assignment<DstXprType, Solve<DecType,RhsType>, internal::assign_op<Scalar,Scalar>, Dense2Dense>
-{
-  typedef Solve<DecType,RhsType> SrcXprType;
-  static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,Scalar> &)
-  {
-    Index dstRows = src.rows();
-    Index dstCols = src.cols();
-    if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
-      dst.resize(dstRows, dstCols);
-
-    src.dec()._solve_impl(src.rhs(), dst);
-  }
-};
-
-// Specialization for "dst = dec.transpose().solve(rhs)"
-template<typename DstXprType, typename DecType, typename RhsType, typename Scalar>
-struct Assignment<DstXprType, Solve<Transpose<const DecType>,RhsType>, internal::assign_op<Scalar,Scalar>, Dense2Dense>
-{
-  typedef Solve<Transpose<const DecType>,RhsType> SrcXprType;
-  static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,Scalar> &)
-  {
-    Index dstRows = src.rows();
-    Index dstCols = src.cols();
-    if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
-      dst.resize(dstRows, dstCols);
-
-    src.dec().nestedExpression().template _solve_impl_transposed<false>(src.rhs(), dst);
-  }
-};
-
-// Specialization for "dst = dec.adjoint().solve(rhs)"
-template<typename DstXprType, typename DecType, typename RhsType, typename Scalar>
-struct Assignment<DstXprType, Solve<CwiseUnaryOp<internal::scalar_conjugate_op<typename DecType::Scalar>, const Transpose<const DecType> >,RhsType>,
-                  internal::assign_op<Scalar,Scalar>, Dense2Dense>
-{
-  typedef Solve<CwiseUnaryOp<internal::scalar_conjugate_op<typename DecType::Scalar>, const Transpose<const DecType> >,RhsType> SrcXprType;
-  static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,Scalar> &)
-  {
-    Index dstRows = src.rows();
-    Index dstCols = src.cols();
-    if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
-      dst.resize(dstRows, dstCols);
-    
-    src.dec().nestedExpression().nestedExpression().template _solve_impl_transposed<true>(src.rhs(), dst);
-  }
-};
-
-} // end namepsace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_SOLVE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/SolveTriangular.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/SolveTriangular.h
deleted file mode 100644
index 4652e2e..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/SolveTriangular.h
+++ /dev/null
@@ -1,235 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_SOLVETRIANGULAR_H
-#define EIGEN_SOLVETRIANGULAR_H
-
-namespace Eigen { 
-
-namespace internal {
-
-// Forward declarations:
-// The following two routines are implemented in the products/TriangularSolver*.h files
-template<typename LhsScalar, typename RhsScalar, typename Index, int Side, int Mode, bool Conjugate, int StorageOrder>
-struct triangular_solve_vector;
-
-template <typename Scalar, typename Index, int Side, int Mode, bool Conjugate, int TriStorageOrder, int OtherStorageOrder>
-struct triangular_solve_matrix;
-
-// small helper struct extracting some traits on the underlying solver operation
-template<typename Lhs, typename Rhs, int Side>
-class trsolve_traits
-{
-  private:
-    enum {
-      RhsIsVectorAtCompileTime = (Side==OnTheLeft ? Rhs::ColsAtCompileTime : Rhs::RowsAtCompileTime)==1
-    };
-  public:
-    enum {
-      Unrolling   = (RhsIsVectorAtCompileTime && Rhs::SizeAtCompileTime != Dynamic && Rhs::SizeAtCompileTime <= 8)
-                  ? CompleteUnrolling : NoUnrolling,
-      RhsVectors  = RhsIsVectorAtCompileTime ? 1 : Dynamic
-    };
-};
-
-template<typename Lhs, typename Rhs,
-  int Side, // can be OnTheLeft/OnTheRight
-  int Mode, // can be Upper/Lower | UnitDiag
-  int Unrolling = trsolve_traits<Lhs,Rhs,Side>::Unrolling,
-  int RhsVectors = trsolve_traits<Lhs,Rhs,Side>::RhsVectors
-  >
-struct triangular_solver_selector;
-
-template<typename Lhs, typename Rhs, int Side, int Mode>
-struct triangular_solver_selector<Lhs,Rhs,Side,Mode,NoUnrolling,1>
-{
-  typedef typename Lhs::Scalar LhsScalar;
-  typedef typename Rhs::Scalar RhsScalar;
-  typedef blas_traits<Lhs> LhsProductTraits;
-  typedef typename LhsProductTraits::ExtractType ActualLhsType;
-  typedef Map<Matrix<RhsScalar,Dynamic,1>, Aligned> MappedRhs;
-  static void run(const Lhs& lhs, Rhs& rhs)
-  {
-    ActualLhsType actualLhs = LhsProductTraits::extract(lhs);
-
-    // FIXME find a way to allow an inner stride if packet_traits<Scalar>::size==1
-
-    bool useRhsDirectly = Rhs::InnerStrideAtCompileTime==1 || rhs.innerStride()==1;
-
-    ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhs,rhs.size(),
-                                                  (useRhsDirectly ? rhs.data() : 0));
-                                                  
-    if(!useRhsDirectly)
-      MappedRhs(actualRhs,rhs.size()) = rhs;
-
-    triangular_solve_vector<LhsScalar, RhsScalar, Index, Side, Mode, LhsProductTraits::NeedToConjugate,
-                            (int(Lhs::Flags) & RowMajorBit) ? RowMajor : ColMajor>
-      ::run(actualLhs.cols(), actualLhs.data(), actualLhs.outerStride(), actualRhs);
-
-    if(!useRhsDirectly)
-      rhs = MappedRhs(actualRhs, rhs.size());
-  }
-};
-
-// the rhs is a matrix
-template<typename Lhs, typename Rhs, int Side, int Mode>
-struct triangular_solver_selector<Lhs,Rhs,Side,Mode,NoUnrolling,Dynamic>
-{
-  typedef typename Rhs::Scalar Scalar;
-  typedef blas_traits<Lhs> LhsProductTraits;
-  typedef typename LhsProductTraits::DirectLinearAccessType ActualLhsType;
-
-  static void run(const Lhs& lhs, Rhs& rhs)
-  {
-    typename internal::add_const_on_value_type<ActualLhsType>::type actualLhs = LhsProductTraits::extract(lhs);
-
-    const Index size = lhs.rows();
-    const Index othersize = Side==OnTheLeft? rhs.cols() : rhs.rows();
-
-    typedef internal::gemm_blocking_space<(Rhs::Flags&RowMajorBit) ? RowMajor : ColMajor,Scalar,Scalar,
-              Rhs::MaxRowsAtCompileTime, Rhs::MaxColsAtCompileTime, Lhs::MaxRowsAtCompileTime,4> BlockingType;
-
-    BlockingType blocking(rhs.rows(), rhs.cols(), size, 1, false);
-
-    triangular_solve_matrix<Scalar,Index,Side,Mode,LhsProductTraits::NeedToConjugate,(int(Lhs::Flags) & RowMajorBit) ? RowMajor : ColMajor,
-                               (Rhs::Flags&RowMajorBit) ? RowMajor : ColMajor>
-      ::run(size, othersize, &actualLhs.coeffRef(0,0), actualLhs.outerStride(), &rhs.coeffRef(0,0), rhs.outerStride(), blocking);
-  }
-};
-
-/***************************************************************************
-* meta-unrolling implementation
-***************************************************************************/
-
-template<typename Lhs, typename Rhs, int Mode, int LoopIndex, int Size,
-         bool Stop = LoopIndex==Size>
-struct triangular_solver_unroller;
-
-template<typename Lhs, typename Rhs, int Mode, int LoopIndex, int Size>
-struct triangular_solver_unroller<Lhs,Rhs,Mode,LoopIndex,Size,false> {
-  enum {
-    IsLower = ((Mode&Lower)==Lower),
-    DiagIndex  = IsLower ? LoopIndex : Size - LoopIndex - 1,
-    StartIndex = IsLower ? 0         : DiagIndex+1
-  };
-  static void run(const Lhs& lhs, Rhs& rhs)
-  {
-    if (LoopIndex>0)
-      rhs.coeffRef(DiagIndex) -= lhs.row(DiagIndex).template segment<LoopIndex>(StartIndex).transpose()
-                                .cwiseProduct(rhs.template segment<LoopIndex>(StartIndex)).sum();
-
-    if(!(Mode & UnitDiag))
-      rhs.coeffRef(DiagIndex) /= lhs.coeff(DiagIndex,DiagIndex);
-
-    triangular_solver_unroller<Lhs,Rhs,Mode,LoopIndex+1,Size>::run(lhs,rhs);
-  }
-};
-
-template<typename Lhs, typename Rhs, int Mode, int LoopIndex, int Size>
-struct triangular_solver_unroller<Lhs,Rhs,Mode,LoopIndex,Size,true> {
-  static void run(const Lhs&, Rhs&) {}
-};
-
-template<typename Lhs, typename Rhs, int Mode>
-struct triangular_solver_selector<Lhs,Rhs,OnTheLeft,Mode,CompleteUnrolling,1> {
-  static void run(const Lhs& lhs, Rhs& rhs)
-  { triangular_solver_unroller<Lhs,Rhs,Mode,0,Rhs::SizeAtCompileTime>::run(lhs,rhs); }
-};
-
-template<typename Lhs, typename Rhs, int Mode>
-struct triangular_solver_selector<Lhs,Rhs,OnTheRight,Mode,CompleteUnrolling,1> {
-  static void run(const Lhs& lhs, Rhs& rhs)
-  {
-    Transpose<const Lhs> trLhs(lhs);
-    Transpose<Rhs> trRhs(rhs);
-    
-    triangular_solver_unroller<Transpose<const Lhs>,Transpose<Rhs>,
-                              ((Mode&Upper)==Upper ? Lower : Upper) | (Mode&UnitDiag),
-                              0,Rhs::SizeAtCompileTime>::run(trLhs,trRhs);
-  }
-};
-
-} // end namespace internal
-
-/***************************************************************************
-* TriangularView methods
-***************************************************************************/
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-template<typename MatrixType, unsigned int Mode>
-template<int Side, typename OtherDerived>
-void TriangularViewImpl<MatrixType,Mode,Dense>::solveInPlace(const MatrixBase<OtherDerived>& _other) const
-{
-  OtherDerived& other = _other.const_cast_derived();
-  eigen_assert( derived().cols() == derived().rows() && ((Side==OnTheLeft && derived().cols() == other.rows()) || (Side==OnTheRight && derived().cols() == other.cols())) );
-  eigen_assert((!(Mode & ZeroDiag)) && bool(Mode & (Upper|Lower)));
-  // If solving for a 0x0 matrix, nothing to do, simply return.
-  if (derived().cols() == 0)
-    return;
-
-  enum { copy = (internal::traits<OtherDerived>::Flags & RowMajorBit)  && OtherDerived::IsVectorAtCompileTime && OtherDerived::SizeAtCompileTime!=1};
-  typedef typename internal::conditional<copy,
-    typename internal::plain_matrix_type_column_major<OtherDerived>::type, OtherDerived&>::type OtherCopy;
-  OtherCopy otherCopy(other);
-
-  internal::triangular_solver_selector<MatrixType, typename internal::remove_reference<OtherCopy>::type,
-    Side, Mode>::run(derived().nestedExpression(), otherCopy);
-
-  if (copy)
-    other = otherCopy;
-}
-
-template<typename Derived, unsigned int Mode>
-template<int Side, typename Other>
-const internal::triangular_solve_retval<Side,TriangularView<Derived,Mode>,Other>
-TriangularViewImpl<Derived,Mode,Dense>::solve(const MatrixBase<Other>& other) const
-{
-  return internal::triangular_solve_retval<Side,TriangularViewType,Other>(derived(), other.derived());
-}
-#endif
-
-namespace internal {
-
-
-template<int Side, typename TriangularType, typename Rhs>
-struct traits<triangular_solve_retval<Side, TriangularType, Rhs> >
-{
-  typedef typename internal::plain_matrix_type_column_major<Rhs>::type ReturnType;
-};
-
-template<int Side, typename TriangularType, typename Rhs> struct triangular_solve_retval
- : public ReturnByValue<triangular_solve_retval<Side, TriangularType, Rhs> >
-{
-  typedef typename remove_all<typename Rhs::Nested>::type RhsNestedCleaned;
-  typedef ReturnByValue<triangular_solve_retval> Base;
-
-  triangular_solve_retval(const TriangularType& tri, const Rhs& rhs)
-    : m_triangularMatrix(tri), m_rhs(rhs)
-  {}
-
-  inline Index rows() const { return m_rhs.rows(); }
-  inline Index cols() const { return m_rhs.cols(); }
-
-  template<typename Dest> inline void evalTo(Dest& dst) const
-  {
-    if(!is_same_dense(dst,m_rhs))
-      dst = m_rhs;
-    m_triangularMatrix.template solveInPlace<Side>(dst);
-  }
-
-  protected:
-    const TriangularType& m_triangularMatrix;
-    typename Rhs::Nested m_rhs;
-};
-
-} // namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_SOLVETRIANGULAR_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/SolverBase.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/SolverBase.h
deleted file mode 100644
index 8a4adc2..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/SolverBase.h
+++ /dev/null
@@ -1,130 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2015 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_SOLVERBASE_H
-#define EIGEN_SOLVERBASE_H
-
-namespace Eigen {
-
-namespace internal {
-
-
-
-} // end namespace internal
-
-/** \class SolverBase
-  * \brief A base class for matrix decomposition and solvers
-  *
-  * \tparam Derived the actual type of the decomposition/solver.
-  *
-  * Any matrix decomposition inheriting this base class provide the following API:
-  *
-  * \code
-  * MatrixType A, b, x;
-  * DecompositionType dec(A);
-  * x = dec.solve(b);             // solve A   * x = b
-  * x = dec.transpose().solve(b); // solve A^T * x = b
-  * x = dec.adjoint().solve(b);   // solve A'  * x = b
-  * \endcode
-  *
-  * \warning Currently, any other usage of transpose() and adjoint() are not supported and will produce compilation errors.
-  *
-  * \sa class PartialPivLU, class FullPivLU
-  */
-template<typename Derived>
-class SolverBase : public EigenBase<Derived>
-{
-  public:
-
-    typedef EigenBase<Derived> Base;
-    typedef typename internal::traits<Derived>::Scalar Scalar;
-    typedef Scalar CoeffReturnType;
-
-    enum {
-      RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
-      ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
-      SizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::RowsAtCompileTime,
-                                                          internal::traits<Derived>::ColsAtCompileTime>::ret),
-      MaxRowsAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime,
-      MaxColsAtCompileTime = internal::traits<Derived>::MaxColsAtCompileTime,
-      MaxSizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::MaxRowsAtCompileTime,
-                                                             internal::traits<Derived>::MaxColsAtCompileTime>::ret),
-      IsVectorAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime == 1
-                           || internal::traits<Derived>::MaxColsAtCompileTime == 1
-    };
-
-    /** Default constructor */
-    SolverBase()
-    {}
-
-    ~SolverBase()
-    {}
-
-    using Base::derived;
-
-    /** \returns an expression of the solution x of \f$ A x = b \f$ using the current decomposition of A.
-      */
-    template<typename Rhs>
-    inline const Solve<Derived, Rhs>
-    solve(const MatrixBase<Rhs>& b) const
-    {
-      eigen_assert(derived().rows()==b.rows() && "solve(): invalid number of rows of the right hand side matrix b");
-      return Solve<Derived, Rhs>(derived(), b.derived());
-    }
-
-    /** \internal the return type of transpose() */
-    typedef typename internal::add_const<Transpose<const Derived> >::type ConstTransposeReturnType;
-    /** \returns an expression of the transposed of the factored matrix.
-      *
-      * A typical usage is to solve for the transposed problem A^T x = b:
-      * \code x = dec.transpose().solve(b); \endcode
-      *
-      * \sa adjoint(), solve()
-      */
-    inline ConstTransposeReturnType transpose() const
-    {
-      return ConstTransposeReturnType(derived());
-    }
-
-    /** \internal the return type of adjoint() */
-    typedef typename internal::conditional<NumTraits<Scalar>::IsComplex,
-                        CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, ConstTransposeReturnType>,
-                        ConstTransposeReturnType
-                     >::type AdjointReturnType;
-    /** \returns an expression of the adjoint of the factored matrix
-      *
-      * A typical usage is to solve for the adjoint problem A' x = b:
-      * \code x = dec.adjoint().solve(b); \endcode
-      *
-      * For real scalar types, this function is equivalent to transpose().
-      *
-      * \sa transpose(), solve()
-      */
-    inline AdjointReturnType adjoint() const
-    {
-      return AdjointReturnType(derived().transpose());
-    }
-
-  protected:
-};
-
-namespace internal {
-
-template<typename Derived>
-struct generic_xpr_base<Derived, MatrixXpr, SolverStorage>
-{
-  typedef SolverBase<Derived> type;
-
-};
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_SOLVERBASE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/StableNorm.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/StableNorm.h
deleted file mode 100644
index 88c8d98..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/StableNorm.h
+++ /dev/null
@@ -1,221 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_STABLENORM_H
-#define EIGEN_STABLENORM_H
-
-namespace Eigen { 
-
-namespace internal {
-
-template<typename ExpressionType, typename Scalar>
-inline void stable_norm_kernel(const ExpressionType& bl, Scalar& ssq, Scalar& scale, Scalar& invScale)
-{
-  Scalar maxCoeff = bl.cwiseAbs().maxCoeff();
-  
-  if(maxCoeff>scale)
-  {
-    ssq = ssq * numext::abs2(scale/maxCoeff);
-    Scalar tmp = Scalar(1)/maxCoeff;
-    if(tmp > NumTraits<Scalar>::highest())
-    {
-      invScale = NumTraits<Scalar>::highest();
-      scale = Scalar(1)/invScale;
-    }
-    else if(maxCoeff>NumTraits<Scalar>::highest()) // we got a INF
-    {
-      invScale = Scalar(1);
-      scale = maxCoeff;
-    }
-    else
-    {
-      scale = maxCoeff;
-      invScale = tmp;
-    }
-  }
-  else if(maxCoeff!=maxCoeff) // we got a NaN
-  {
-    scale = maxCoeff;
-  }
-  
-  // TODO if the maxCoeff is much much smaller than the current scale,
-  // then we can neglect this sub vector
-  if(scale>Scalar(0)) // if scale==0, then bl is 0 
-    ssq += (bl*invScale).squaredNorm();
-}
-
-template<typename Derived>
-inline typename NumTraits<typename traits<Derived>::Scalar>::Real
-blueNorm_impl(const EigenBase<Derived>& _vec)
-{
-  typedef typename Derived::RealScalar RealScalar;  
-  using std::pow;
-  using std::sqrt;
-  using std::abs;
-  const Derived& vec(_vec.derived());
-  static bool initialized = false;
-  static RealScalar b1, b2, s1m, s2m, rbig, relerr;
-  if(!initialized)
-  {
-    int ibeta, it, iemin, iemax, iexp;
-    RealScalar eps;
-    // This program calculates the machine-dependent constants
-    // bl, b2, slm, s2m, relerr overfl
-    // from the "basic" machine-dependent numbers
-    // nbig, ibeta, it, iemin, iemax, rbig.
-    // The following define the basic machine-dependent constants.
-    // For portability, the PORT subprograms "ilmaeh" and "rlmach"
-    // are used. For any specific computer, each of the assignment
-    // statements can be replaced
-    ibeta = std::numeric_limits<RealScalar>::radix;                 // base for floating-point numbers
-    it    = std::numeric_limits<RealScalar>::digits;                // number of base-beta digits in mantissa
-    iemin = std::numeric_limits<RealScalar>::min_exponent;          // minimum exponent
-    iemax = std::numeric_limits<RealScalar>::max_exponent;          // maximum exponent
-    rbig  = (std::numeric_limits<RealScalar>::max)();               // largest floating-point number
-
-    iexp  = -((1-iemin)/2);
-    b1    = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp)));    // lower boundary of midrange
-    iexp  = (iemax + 1 - it)/2;
-    b2    = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp)));    // upper boundary of midrange
-
-    iexp  = (2-iemin)/2;
-    s1m   = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp)));    // scaling factor for lower range
-    iexp  = - ((iemax+it)/2);
-    s2m   = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp)));    // scaling factor for upper range
-
-    eps     = RealScalar(pow(double(ibeta), 1-it));
-    relerr  = sqrt(eps);                                            // tolerance for neglecting asml
-    initialized = true;
-  }
-  Index n = vec.size();
-  RealScalar ab2 = b2 / RealScalar(n);
-  RealScalar asml = RealScalar(0);
-  RealScalar amed = RealScalar(0);
-  RealScalar abig = RealScalar(0);
-  for(typename Derived::InnerIterator it(vec, 0); it; ++it)
-  {
-    RealScalar ax = abs(it.value());
-    if(ax > ab2)     abig += numext::abs2(ax*s2m);
-    else if(ax < b1) asml += numext::abs2(ax*s1m);
-    else             amed += numext::abs2(ax);
-  }
-  if(amed!=amed)
-    return amed;  // we got a NaN
-  if(abig > RealScalar(0))
-  {
-    abig = sqrt(abig);
-    if(abig > rbig) // overflow, or *this contains INF values
-      return abig;  // return INF
-    if(amed > RealScalar(0))
-    {
-      abig = abig/s2m;
-      amed = sqrt(amed);
-    }
-    else
-      return abig/s2m;
-  }
-  else if(asml > RealScalar(0))
-  {
-    if (amed > RealScalar(0))
-    {
-      abig = sqrt(amed);
-      amed = sqrt(asml) / s1m;
-    }
-    else
-      return sqrt(asml)/s1m;
-  }
-  else
-    return sqrt(amed);
-  asml = numext::mini(abig, amed);
-  abig = numext::maxi(abig, amed);
-  if(asml <= abig*relerr)
-    return abig;
-  else
-    return abig * sqrt(RealScalar(1) + numext::abs2(asml/abig));
-}
-
-} // end namespace internal
-
-/** \returns the \em l2 norm of \c *this avoiding underflow and overflow.
-  * This version use a blockwise two passes algorithm:
-  *  1 - find the absolute largest coefficient \c s
-  *  2 - compute \f$ s \Vert \frac{*this}{s} \Vert \f$ in a standard way
-  *
-  * For architecture/scalar types supporting vectorization, this version
-  * is faster than blueNorm(). Otherwise the blueNorm() is much faster.
-  *
-  * \sa norm(), blueNorm(), hypotNorm()
-  */
-template<typename Derived>
-inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
-MatrixBase<Derived>::stableNorm() const
-{
-  using std::sqrt;
-  using std::abs;
-  const Index blockSize = 4096;
-  RealScalar scale(0);
-  RealScalar invScale(1);
-  RealScalar ssq(0); // sum of square
-  
-  typedef typename internal::nested_eval<Derived,2>::type DerivedCopy;
-  typedef typename internal::remove_all<DerivedCopy>::type DerivedCopyClean;
-  const DerivedCopy copy(derived());
-  
-  enum {
-    CanAlign = (   (int(DerivedCopyClean::Flags)&DirectAccessBit)
-                || (int(internal::evaluator<DerivedCopyClean>::Alignment)>0) // FIXME Alignment)>0 might not be enough
-               ) && (blockSize*sizeof(Scalar)*2<EIGEN_STACK_ALLOCATION_LIMIT)
-                 && (EIGEN_MAX_STATIC_ALIGN_BYTES>0) // if we cannot allocate on the stack, then let's not bother about this optimization
-  };
-  typedef typename internal::conditional<CanAlign, Ref<const Matrix<Scalar,Dynamic,1,0,blockSize,1>, internal::evaluator<DerivedCopyClean>::Alignment>,
-                                                   typename DerivedCopyClean::ConstSegmentReturnType>::type SegmentWrapper;
-  Index n = size();
-  
-  if(n==1)
-    return abs(this->coeff(0));
-  
-  Index bi = internal::first_default_aligned(copy);
-  if (bi>0)
-    internal::stable_norm_kernel(copy.head(bi), ssq, scale, invScale);
-  for (; bi<n; bi+=blockSize)
-    internal::stable_norm_kernel(SegmentWrapper(copy.segment(bi,numext::mini(blockSize, n - bi))), ssq, scale, invScale);
-  return scale * sqrt(ssq);
-}
-
-/** \returns the \em l2 norm of \c *this using the Blue's algorithm.
-  * A Portable Fortran Program to Find the Euclidean Norm of a Vector,
-  * ACM TOMS, Vol 4, Issue 1, 1978.
-  *
-  * For architecture/scalar types without vectorization, this version
-  * is much faster than stableNorm(). Otherwise the stableNorm() is faster.
-  *
-  * \sa norm(), stableNorm(), hypotNorm()
-  */
-template<typename Derived>
-inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
-MatrixBase<Derived>::blueNorm() const
-{
-  return internal::blueNorm_impl(*this);
-}
-
-/** \returns the \em l2 norm of \c *this avoiding undeflow and overflow.
-  * This version use a concatenation of hypot() calls, and it is very slow.
-  *
-  * \sa norm(), stableNorm()
-  */
-template<typename Derived>
-inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
-MatrixBase<Derived>::hypotNorm() const
-{
-  return this->cwiseAbs().redux(internal::scalar_hypot_op<RealScalar>());
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_STABLENORM_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Stride.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Stride.h
deleted file mode 100644
index 513742f..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Stride.h
+++ /dev/null
@@ -1,111 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_STRIDE_H
-#define EIGEN_STRIDE_H
-
-namespace Eigen { 
-
-/** \class Stride
-  * \ingroup Core_Module
-  *
-  * \brief Holds strides information for Map
-  *
-  * This class holds the strides information for mapping arrays with strides with class Map.
-  *
-  * It holds two values: the inner stride and the outer stride.
-  *
-  * The inner stride is the pointer increment between two consecutive entries within a given row of a
-  * row-major matrix or within a given column of a column-major matrix.
-  *
-  * The outer stride is the pointer increment between two consecutive rows of a row-major matrix or
-  * between two consecutive columns of a column-major matrix.
-  *
-  * These two values can be passed either at compile-time as template parameters, or at runtime as
-  * arguments to the constructor.
-  *
-  * Indeed, this class takes two template parameters:
-  *  \tparam _OuterStrideAtCompileTime the outer stride, or Dynamic if you want to specify it at runtime.
-  *  \tparam _InnerStrideAtCompileTime the inner stride, or Dynamic if you want to specify it at runtime.
-  *
-  * Here is an example:
-  * \include Map_general_stride.cpp
-  * Output: \verbinclude Map_general_stride.out
-  *
-  * \sa class InnerStride, class OuterStride, \ref TopicStorageOrders
-  */
-template<int _OuterStrideAtCompileTime, int _InnerStrideAtCompileTime>
-class Stride
-{
-  public:
-    typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
-    enum {
-      InnerStrideAtCompileTime = _InnerStrideAtCompileTime,
-      OuterStrideAtCompileTime = _OuterStrideAtCompileTime
-    };
-
-    /** Default constructor, for use when strides are fixed at compile time */
-    EIGEN_DEVICE_FUNC
-    Stride()
-      : m_outer(OuterStrideAtCompileTime), m_inner(InnerStrideAtCompileTime)
-    {
-      eigen_assert(InnerStrideAtCompileTime != Dynamic && OuterStrideAtCompileTime != Dynamic);
-    }
-
-    /** Constructor allowing to pass the strides at runtime */
-    EIGEN_DEVICE_FUNC
-    Stride(Index outerStride, Index innerStride)
-      : m_outer(outerStride), m_inner(innerStride)
-    {
-      eigen_assert(innerStride>=0 && outerStride>=0);
-    }
-
-    /** Copy constructor */
-    EIGEN_DEVICE_FUNC
-    Stride(const Stride& other)
-      : m_outer(other.outer()), m_inner(other.inner())
-    {}
-
-    /** \returns the outer stride */
-    EIGEN_DEVICE_FUNC
-    inline Index outer() const { return m_outer.value(); }
-    /** \returns the inner stride */
-    EIGEN_DEVICE_FUNC
-    inline Index inner() const { return m_inner.value(); }
-
-  protected:
-    internal::variable_if_dynamic<Index, OuterStrideAtCompileTime> m_outer;
-    internal::variable_if_dynamic<Index, InnerStrideAtCompileTime> m_inner;
-};
-
-/** \brief Convenience specialization of Stride to specify only an inner stride
-  * See class Map for some examples */
-template<int Value>
-class InnerStride : public Stride<0, Value>
-{
-    typedef Stride<0, Value> Base;
-  public:
-    EIGEN_DEVICE_FUNC InnerStride() : Base() {}
-    EIGEN_DEVICE_FUNC InnerStride(Index v) : Base(0, v) {} // FIXME making this explicit could break valid code
-};
-
-/** \brief Convenience specialization of Stride to specify only an outer stride
-  * See class Map for some examples */
-template<int Value>
-class OuterStride : public Stride<Value, 0>
-{
-    typedef Stride<Value, 0> Base;
-  public:
-    EIGEN_DEVICE_FUNC OuterStride() : Base() {}
-    EIGEN_DEVICE_FUNC OuterStride(Index v) : Base(v,0) {} // FIXME making this explicit could break valid code
-};
-
-} // end namespace Eigen
-
-#endif // EIGEN_STRIDE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Swap.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Swap.h
deleted file mode 100644
index d702009..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Swap.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_SWAP_H
-#define EIGEN_SWAP_H
-
-namespace Eigen { 
-
-namespace internal {
-
-// Overload default assignPacket behavior for swapping them
-template<typename DstEvaluatorTypeT, typename SrcEvaluatorTypeT>
-class generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, swap_assign_op<typename DstEvaluatorTypeT::Scalar>, Specialized>
- : public generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, swap_assign_op<typename DstEvaluatorTypeT::Scalar>, BuiltIn>
-{
-protected:
-  typedef generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, swap_assign_op<typename DstEvaluatorTypeT::Scalar>, BuiltIn> Base;
-  using Base::m_dst;
-  using Base::m_src;
-  using Base::m_functor;
-  
-public:
-  typedef typename Base::Scalar Scalar;
-  typedef typename Base::DstXprType DstXprType;
-  typedef swap_assign_op<Scalar> Functor;
-  
-  EIGEN_DEVICE_FUNC generic_dense_assignment_kernel(DstEvaluatorTypeT &dst, const SrcEvaluatorTypeT &src, const Functor &func, DstXprType& dstExpr)
-    : Base(dst, src, func, dstExpr)
-  {}
-  
-  template<int StoreMode, int LoadMode, typename PacketType>
-  void assignPacket(Index row, Index col)
-  {
-    PacketType tmp = m_src.template packet<LoadMode,PacketType>(row,col);
-    const_cast<SrcEvaluatorTypeT&>(m_src).template writePacket<LoadMode>(row,col, m_dst.template packet<StoreMode,PacketType>(row,col));
-    m_dst.template writePacket<StoreMode>(row,col,tmp);
-  }
-  
-  template<int StoreMode, int LoadMode, typename PacketType>
-  void assignPacket(Index index)
-  {
-    PacketType tmp = m_src.template packet<LoadMode,PacketType>(index);
-    const_cast<SrcEvaluatorTypeT&>(m_src).template writePacket<LoadMode>(index, m_dst.template packet<StoreMode,PacketType>(index));
-    m_dst.template writePacket<StoreMode>(index,tmp);
-  }
-  
-  // TODO find a simple way not to have to copy/paste this function from generic_dense_assignment_kernel, by simple I mean no CRTP (Gael)
-  template<int StoreMode, int LoadMode, typename PacketType>
-  void assignPacketByOuterInner(Index outer, Index inner)
-  {
-    Index row = Base::rowIndexByOuterInner(outer, inner); 
-    Index col = Base::colIndexByOuterInner(outer, inner);
-    assignPacket<StoreMode,LoadMode,PacketType>(row, col);
-  }
-};
-
-} // namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_SWAP_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Transpose.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Transpose.h
deleted file mode 100644
index 79b767b..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Transpose.h
+++ /dev/null
@@ -1,403 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2009-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_TRANSPOSE_H
-#define EIGEN_TRANSPOSE_H
-
-namespace Eigen { 
-
-namespace internal {
-template<typename MatrixType>
-struct traits<Transpose<MatrixType> > : public traits<MatrixType>
-{
-  typedef typename ref_selector<MatrixType>::type MatrixTypeNested;
-  typedef typename remove_reference<MatrixTypeNested>::type MatrixTypeNestedPlain;
-  enum {
-    RowsAtCompileTime = MatrixType::ColsAtCompileTime,
-    ColsAtCompileTime = MatrixType::RowsAtCompileTime,
-    MaxRowsAtCompileTime = MatrixType::MaxColsAtCompileTime,
-    MaxColsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
-    FlagsLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
-    Flags0 = traits<MatrixTypeNestedPlain>::Flags & ~(LvalueBit | NestByRefBit),
-    Flags1 = Flags0 | FlagsLvalueBit,
-    Flags = Flags1 ^ RowMajorBit,
-    InnerStrideAtCompileTime = inner_stride_at_compile_time<MatrixType>::ret,
-    OuterStrideAtCompileTime = outer_stride_at_compile_time<MatrixType>::ret
-  };
-};
-}
-
-template<typename MatrixType, typename StorageKind> class TransposeImpl;
-
-/** \class Transpose
-  * \ingroup Core_Module
-  *
-  * \brief Expression of the transpose of a matrix
-  *
-  * \tparam MatrixType the type of the object of which we are taking the transpose
-  *
-  * This class represents an expression of the transpose of a matrix.
-  * It is the return type of MatrixBase::transpose() and MatrixBase::adjoint()
-  * and most of the time this is the only way it is used.
-  *
-  * \sa MatrixBase::transpose(), MatrixBase::adjoint()
-  */
-template<typename MatrixType> class Transpose
-  : public TransposeImpl<MatrixType,typename internal::traits<MatrixType>::StorageKind>
-{
-  public:
-
-    typedef typename internal::ref_selector<MatrixType>::non_const_type MatrixTypeNested;
-
-    typedef typename TransposeImpl<MatrixType,typename internal::traits<MatrixType>::StorageKind>::Base Base;
-    EIGEN_GENERIC_PUBLIC_INTERFACE(Transpose)
-    typedef typename internal::remove_all<MatrixType>::type NestedExpression;
-
-    EIGEN_DEVICE_FUNC
-    explicit inline Transpose(MatrixType& matrix) : m_matrix(matrix) {}
-
-    EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Transpose)
-
-    EIGEN_DEVICE_FUNC inline Index rows() const { return m_matrix.cols(); }
-    EIGEN_DEVICE_FUNC inline Index cols() const { return m_matrix.rows(); }
-
-    /** \returns the nested expression */
-    EIGEN_DEVICE_FUNC
-    const typename internal::remove_all<MatrixTypeNested>::type&
-    nestedExpression() const { return m_matrix; }
-
-    /** \returns the nested expression */
-    EIGEN_DEVICE_FUNC
-    typename internal::remove_reference<MatrixTypeNested>::type&
-    nestedExpression() { return m_matrix; }
-
-    /** \internal */
-    void resize(Index nrows, Index ncols) {
-      m_matrix.resize(ncols,nrows);
-    }
-
-  protected:
-    typename internal::ref_selector<MatrixType>::non_const_type m_matrix;
-};
-
-namespace internal {
-
-template<typename MatrixType, bool HasDirectAccess = has_direct_access<MatrixType>::ret>
-struct TransposeImpl_base
-{
-  typedef typename dense_xpr_base<Transpose<MatrixType> >::type type;
-};
-
-template<typename MatrixType>
-struct TransposeImpl_base<MatrixType, false>
-{
-  typedef typename dense_xpr_base<Transpose<MatrixType> >::type type;
-};
-
-} // end namespace internal
-
-// Generic API dispatcher
-template<typename XprType, typename StorageKind>
-class TransposeImpl
-  : public internal::generic_xpr_base<Transpose<XprType> >::type
-{
-public:
-  typedef typename internal::generic_xpr_base<Transpose<XprType> >::type Base;
-};
-
-template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
-  : public internal::TransposeImpl_base<MatrixType>::type
-{
-  public:
-
-    typedef typename internal::TransposeImpl_base<MatrixType>::type Base;
-    using Base::coeffRef;
-    EIGEN_DENSE_PUBLIC_INTERFACE(Transpose<MatrixType>)
-    EIGEN_INHERIT_ASSIGNMENT_OPERATORS(TransposeImpl)
-
-    EIGEN_DEVICE_FUNC inline Index innerStride() const { return derived().nestedExpression().innerStride(); }
-    EIGEN_DEVICE_FUNC inline Index outerStride() const { return derived().nestedExpression().outerStride(); }
-
-    typedef typename internal::conditional<
-                       internal::is_lvalue<MatrixType>::value,
-                       Scalar,
-                       const Scalar
-                     >::type ScalarWithConstIfNotLvalue;
-
-    EIGEN_DEVICE_FUNC inline ScalarWithConstIfNotLvalue* data() { return derived().nestedExpression().data(); }
-    EIGEN_DEVICE_FUNC inline const Scalar* data() const { return derived().nestedExpression().data(); }
-
-    // FIXME: shall we keep the const version of coeffRef?
-    EIGEN_DEVICE_FUNC
-    inline const Scalar& coeffRef(Index rowId, Index colId) const
-    {
-      return derived().nestedExpression().coeffRef(colId, rowId);
-    }
-
-    EIGEN_DEVICE_FUNC
-    inline const Scalar& coeffRef(Index index) const
-    {
-      return derived().nestedExpression().coeffRef(index);
-    }
-};
-
-/** \returns an expression of the transpose of *this.
-  *
-  * Example: \include MatrixBase_transpose.cpp
-  * Output: \verbinclude MatrixBase_transpose.out
-  *
-  * \warning If you want to replace a matrix by its own transpose, do \b NOT do this:
-  * \code
-  * m = m.transpose(); // bug!!! caused by aliasing effect
-  * \endcode
-  * Instead, use the transposeInPlace() method:
-  * \code
-  * m.transposeInPlace();
-  * \endcode
-  * which gives Eigen good opportunities for optimization, or alternatively you can also do:
-  * \code
-  * m = m.transpose().eval();
-  * \endcode
-  *
-  * \sa transposeInPlace(), adjoint() */
-template<typename Derived>
-inline Transpose<Derived>
-DenseBase<Derived>::transpose()
-{
-  return TransposeReturnType(derived());
-}
-
-/** This is the const version of transpose().
-  *
-  * Make sure you read the warning for transpose() !
-  *
-  * \sa transposeInPlace(), adjoint() */
-template<typename Derived>
-inline typename DenseBase<Derived>::ConstTransposeReturnType
-DenseBase<Derived>::transpose() const
-{
-  return ConstTransposeReturnType(derived());
-}
-
-/** \returns an expression of the adjoint (i.e. conjugate transpose) of *this.
-  *
-  * Example: \include MatrixBase_adjoint.cpp
-  * Output: \verbinclude MatrixBase_adjoint.out
-  *
-  * \warning If you want to replace a matrix by its own adjoint, do \b NOT do this:
-  * \code
-  * m = m.adjoint(); // bug!!! caused by aliasing effect
-  * \endcode
-  * Instead, use the adjointInPlace() method:
-  * \code
-  * m.adjointInPlace();
-  * \endcode
-  * which gives Eigen good opportunities for optimization, or alternatively you can also do:
-  * \code
-  * m = m.adjoint().eval();
-  * \endcode
-  *
-  * \sa adjointInPlace(), transpose(), conjugate(), class Transpose, class internal::scalar_conjugate_op */
-template<typename Derived>
-inline const typename MatrixBase<Derived>::AdjointReturnType
-MatrixBase<Derived>::adjoint() const
-{
-  return AdjointReturnType(this->transpose());
-}
-
-/***************************************************************************
-* "in place" transpose implementation
-***************************************************************************/
-
-namespace internal {
-
-template<typename MatrixType,
-  bool IsSquare = (MatrixType::RowsAtCompileTime == MatrixType::ColsAtCompileTime) && MatrixType::RowsAtCompileTime!=Dynamic,
-  bool MatchPacketSize =
-        (int(MatrixType::RowsAtCompileTime) == int(internal::packet_traits<typename MatrixType::Scalar>::size))
-    &&  (internal::evaluator<MatrixType>::Flags&PacketAccessBit) >
-struct inplace_transpose_selector;
-
-template<typename MatrixType>
-struct inplace_transpose_selector<MatrixType,true,false> { // square matrix
-  static void run(MatrixType& m) {
-    m.matrix().template triangularView<StrictlyUpper>().swap(m.matrix().transpose());
-  }
-};
-
-// TODO: vectorized path is currently limited to LargestPacketSize x LargestPacketSize cases only.
-template<typename MatrixType>
-struct inplace_transpose_selector<MatrixType,true,true> { // PacketSize x PacketSize
-  static void run(MatrixType& m) {
-    typedef typename MatrixType::Scalar Scalar;
-    typedef typename internal::packet_traits<typename MatrixType::Scalar>::type Packet;
-    const Index PacketSize = internal::packet_traits<Scalar>::size;
-    const Index Alignment = internal::evaluator<MatrixType>::Alignment;
-    PacketBlock<Packet> A;
-    for (Index i=0; i<PacketSize; ++i)
-      A.packet[i] = m.template packetByOuterInner<Alignment>(i,0);
-    internal::ptranspose(A);
-    for (Index i=0; i<PacketSize; ++i)
-      m.template writePacket<Alignment>(m.rowIndexByOuterInner(i,0), m.colIndexByOuterInner(i,0), A.packet[i]);
-  }
-};
-
-template<typename MatrixType,bool MatchPacketSize>
-struct inplace_transpose_selector<MatrixType,false,MatchPacketSize> { // non square matrix
-  static void run(MatrixType& m) {
-    if (m.rows()==m.cols())
-      m.matrix().template triangularView<StrictlyUpper>().swap(m.matrix().transpose());
-    else
-      m = m.transpose().eval();
-  }
-};
-
-} // end namespace internal
-
-/** This is the "in place" version of transpose(): it replaces \c *this by its own transpose.
-  * Thus, doing
-  * \code
-  * m.transposeInPlace();
-  * \endcode
-  * has the same effect on m as doing
-  * \code
-  * m = m.transpose().eval();
-  * \endcode
-  * and is faster and also safer because in the latter line of code, forgetting the eval() results
-  * in a bug caused by \ref TopicAliasing "aliasing".
-  *
-  * Notice however that this method is only useful if you want to replace a matrix by its own transpose.
-  * If you just need the transpose of a matrix, use transpose().
-  *
-  * \note if the matrix is not square, then \c *this must be a resizable matrix. 
-  * This excludes (non-square) fixed-size matrices, block-expressions and maps.
-  *
-  * \sa transpose(), adjoint(), adjointInPlace() */
-template<typename Derived>
-inline void DenseBase<Derived>::transposeInPlace()
-{
-  eigen_assert((rows() == cols() || (RowsAtCompileTime == Dynamic && ColsAtCompileTime == Dynamic))
-               && "transposeInPlace() called on a non-square non-resizable matrix");
-  internal::inplace_transpose_selector<Derived>::run(derived());
-}
-
-/***************************************************************************
-* "in place" adjoint implementation
-***************************************************************************/
-
-/** This is the "in place" version of adjoint(): it replaces \c *this by its own transpose.
-  * Thus, doing
-  * \code
-  * m.adjointInPlace();
-  * \endcode
-  * has the same effect on m as doing
-  * \code
-  * m = m.adjoint().eval();
-  * \endcode
-  * and is faster and also safer because in the latter line of code, forgetting the eval() results
-  * in a bug caused by aliasing.
-  *
-  * Notice however that this method is only useful if you want to replace a matrix by its own adjoint.
-  * If you just need the adjoint of a matrix, use adjoint().
-  *
-  * \note if the matrix is not square, then \c *this must be a resizable matrix.
-  * This excludes (non-square) fixed-size matrices, block-expressions and maps.
-  *
-  * \sa transpose(), adjoint(), transposeInPlace() */
-template<typename Derived>
-inline void MatrixBase<Derived>::adjointInPlace()
-{
-  derived() = adjoint().eval();
-}
-
-#ifndef EIGEN_NO_DEBUG
-
-// The following is to detect aliasing problems in most common cases.
-
-namespace internal {
-
-template<bool DestIsTransposed, typename OtherDerived>
-struct check_transpose_aliasing_compile_time_selector
-{
-  enum { ret = bool(blas_traits<OtherDerived>::IsTransposed) != DestIsTransposed };
-};
-
-template<bool DestIsTransposed, typename BinOp, typename DerivedA, typename DerivedB>
-struct check_transpose_aliasing_compile_time_selector<DestIsTransposed,CwiseBinaryOp<BinOp,DerivedA,DerivedB> >
-{
-  enum { ret =    bool(blas_traits<DerivedA>::IsTransposed) != DestIsTransposed
-               || bool(blas_traits<DerivedB>::IsTransposed) != DestIsTransposed
-  };
-};
-
-template<typename Scalar, bool DestIsTransposed, typename OtherDerived>
-struct check_transpose_aliasing_run_time_selector
-{
-  static bool run(const Scalar* dest, const OtherDerived& src)
-  {
-    return (bool(blas_traits<OtherDerived>::IsTransposed) != DestIsTransposed) && (dest!=0 && dest==(const Scalar*)extract_data(src));
-  }
-};
-
-template<typename Scalar, bool DestIsTransposed, typename BinOp, typename DerivedA, typename DerivedB>
-struct check_transpose_aliasing_run_time_selector<Scalar,DestIsTransposed,CwiseBinaryOp<BinOp,DerivedA,DerivedB> >
-{
-  static bool run(const Scalar* dest, const CwiseBinaryOp<BinOp,DerivedA,DerivedB>& src)
-  {
-    return ((blas_traits<DerivedA>::IsTransposed != DestIsTransposed) && (dest!=0 && dest==(const Scalar*)extract_data(src.lhs())))
-        || ((blas_traits<DerivedB>::IsTransposed != DestIsTransposed) && (dest!=0 && dest==(const Scalar*)extract_data(src.rhs())));
-  }
-};
-
-// the following selector, checkTransposeAliasing_impl, based on MightHaveTransposeAliasing,
-// is because when the condition controlling the assert is known at compile time, ICC emits a warning.
-// This is actually a good warning: in expressions that don't have any transposing, the condition is
-// known at compile time to be false, and using that, we can avoid generating the code of the assert again
-// and again for all these expressions that don't need it.
-
-template<typename Derived, typename OtherDerived,
-         bool MightHaveTransposeAliasing
-                 = check_transpose_aliasing_compile_time_selector
-                     <blas_traits<Derived>::IsTransposed,OtherDerived>::ret
-        >
-struct checkTransposeAliasing_impl
-{
-    static void run(const Derived& dst, const OtherDerived& other)
-    {
-        eigen_assert((!check_transpose_aliasing_run_time_selector
-                      <typename Derived::Scalar,blas_traits<Derived>::IsTransposed,OtherDerived>
-                      ::run(extract_data(dst), other))
-          && "aliasing detected during transposition, use transposeInPlace() "
-             "or evaluate the rhs into a temporary using .eval()");
-
-    }
-};
-
-template<typename Derived, typename OtherDerived>
-struct checkTransposeAliasing_impl<Derived, OtherDerived, false>
-{
-    static void run(const Derived&, const OtherDerived&)
-    {
-    }
-};
-
-template<typename Dst, typename Src>
-void check_for_aliasing(const Dst &dst, const Src &src)
-{
-  internal::checkTransposeAliasing_impl<Dst, Src>::run(dst, src);
-}
-
-} // end namespace internal
-
-#endif // EIGEN_NO_DEBUG
-
-} // end namespace Eigen
-
-#endif // EIGEN_TRANSPOSE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Transpositions.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Transpositions.h
deleted file mode 100644
index 86da5af..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Transpositions.h
+++ /dev/null
@@ -1,407 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2010-2011 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_TRANSPOSITIONS_H
-#define EIGEN_TRANSPOSITIONS_H
-
-namespace Eigen { 
-
-template<typename Derived>
-class TranspositionsBase
-{
-    typedef internal::traits<Derived> Traits;
-    
-  public:
-
-    typedef typename Traits::IndicesType IndicesType;
-    typedef typename IndicesType::Scalar StorageIndex;
-    typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
-
-    Derived& derived() { return *static_cast<Derived*>(this); }
-    const Derived& derived() const { return *static_cast<const Derived*>(this); }
-
-    /** Copies the \a other transpositions into \c *this */
-    template<typename OtherDerived>
-    Derived& operator=(const TranspositionsBase<OtherDerived>& other)
-    {
-      indices() = other.indices();
-      return derived();
-    }
-    
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    /** This is a special case of the templated operator=. Its purpose is to
-      * prevent a default operator= from hiding the templated operator=.
-      */
-    Derived& operator=(const TranspositionsBase& other)
-    {
-      indices() = other.indices();
-      return derived();
-    }
-    #endif
-
-    /** \returns the number of transpositions */
-    Index size() const { return indices().size(); }
-    /** \returns the number of rows of the equivalent permutation matrix */
-    Index rows() const { return indices().size(); }
-    /** \returns the number of columns of the equivalent permutation matrix */
-    Index cols() const { return indices().size(); }
-
-    /** Direct access to the underlying index vector */
-    inline const StorageIndex& coeff(Index i) const { return indices().coeff(i); }
-    /** Direct access to the underlying index vector */
-    inline StorageIndex& coeffRef(Index i) { return indices().coeffRef(i); }
-    /** Direct access to the underlying index vector */
-    inline const StorageIndex& operator()(Index i) const { return indices()(i); }
-    /** Direct access to the underlying index vector */
-    inline StorageIndex& operator()(Index i) { return indices()(i); }
-    /** Direct access to the underlying index vector */
-    inline const StorageIndex& operator[](Index i) const { return indices()(i); }
-    /** Direct access to the underlying index vector */
-    inline StorageIndex& operator[](Index i) { return indices()(i); }
-
-    /** const version of indices(). */
-    const IndicesType& indices() const { return derived().indices(); }
-    /** \returns a reference to the stored array representing the transpositions. */
-    IndicesType& indices() { return derived().indices(); }
-
-    /** Resizes to given size. */
-    inline void resize(Index newSize)
-    {
-      indices().resize(newSize);
-    }
-
-    /** Sets \c *this to represents an identity transformation */
-    void setIdentity()
-    {
-      for(StorageIndex i = 0; i < indices().size(); ++i)
-        coeffRef(i) = i;
-    }
-
-    // FIXME: do we want such methods ?
-    // might be usefull when the target matrix expression is complex, e.g.:
-    // object.matrix().block(..,..,..,..) = trans * object.matrix().block(..,..,..,..);
-    /*
-    template<typename MatrixType>
-    void applyForwardToRows(MatrixType& mat) const
-    {
-      for(Index k=0 ; k<size() ; ++k)
-        if(m_indices(k)!=k)
-          mat.row(k).swap(mat.row(m_indices(k)));
-    }
-
-    template<typename MatrixType>
-    void applyBackwardToRows(MatrixType& mat) const
-    {
-      for(Index k=size()-1 ; k>=0 ; --k)
-        if(m_indices(k)!=k)
-          mat.row(k).swap(mat.row(m_indices(k)));
-    }
-    */
-
-    /** \returns the inverse transformation */
-    inline Transpose<TranspositionsBase> inverse() const
-    { return Transpose<TranspositionsBase>(derived()); }
-
-    /** \returns the tranpose transformation */
-    inline Transpose<TranspositionsBase> transpose() const
-    { return Transpose<TranspositionsBase>(derived()); }
-
-  protected:
-};
-
-namespace internal {
-template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename _StorageIndex>
-struct traits<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,_StorageIndex> >
- : traits<PermutationMatrix<SizeAtCompileTime,MaxSizeAtCompileTime,_StorageIndex> >
-{
-  typedef Matrix<_StorageIndex, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1> IndicesType;
-  typedef TranspositionsStorage StorageKind;
-};
-}
-
-/** \class Transpositions
-  * \ingroup Core_Module
-  *
-  * \brief Represents a sequence of transpositions (row/column interchange)
-  *
-  * \tparam SizeAtCompileTime the number of transpositions, or Dynamic
-  * \tparam MaxSizeAtCompileTime the maximum number of transpositions, or Dynamic. This optional parameter defaults to SizeAtCompileTime. Most of the time, you should not have to specify it.
-  *
-  * This class represents a permutation transformation as a sequence of \em n transpositions
-  * \f$[T_{n-1} \ldots T_{i} \ldots T_{0}]\f$. It is internally stored as a vector of integers \c indices.
-  * Each transposition \f$ T_{i} \f$ applied on the left of a matrix (\f$ T_{i} M\f$) interchanges
-  * the rows \c i and \c indices[i] of the matrix \c M.
-  * A transposition applied on the right (e.g., \f$ M T_{i}\f$) yields a column interchange.
-  *
-  * Compared to the class PermutationMatrix, such a sequence of transpositions is what is
-  * computed during a decomposition with pivoting, and it is faster when applying the permutation in-place.
-  *
-  * To apply a sequence of transpositions to a matrix, simply use the operator * as in the following example:
-  * \code
-  * Transpositions tr;
-  * MatrixXf mat;
-  * mat = tr * mat;
-  * \endcode
-  * In this example, we detect that the matrix appears on both side, and so the transpositions
-  * are applied in-place without any temporary or extra copy.
-  *
-  * \sa class PermutationMatrix
-  */
-
-template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename _StorageIndex>
-class Transpositions : public TranspositionsBase<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,_StorageIndex> >
-{
-    typedef internal::traits<Transpositions> Traits;
-  public:
-
-    typedef TranspositionsBase<Transpositions> Base;
-    typedef typename Traits::IndicesType IndicesType;
-    typedef typename IndicesType::Scalar StorageIndex;
-
-    inline Transpositions() {}
-
-    /** Copy constructor. */
-    template<typename OtherDerived>
-    inline Transpositions(const TranspositionsBase<OtherDerived>& other)
-      : m_indices(other.indices()) {}
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    /** Standard copy constructor. Defined only to prevent a default copy constructor
-      * from hiding the other templated constructor */
-    inline Transpositions(const Transpositions& other) : m_indices(other.indices()) {}
-    #endif
-
-    /** Generic constructor from expression of the transposition indices. */
-    template<typename Other>
-    explicit inline Transpositions(const MatrixBase<Other>& indices) : m_indices(indices)
-    {}
-
-    /** Copies the \a other transpositions into \c *this */
-    template<typename OtherDerived>
-    Transpositions& operator=(const TranspositionsBase<OtherDerived>& other)
-    {
-      return Base::operator=(other);
-    }
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    /** This is a special case of the templated operator=. Its purpose is to
-      * prevent a default operator= from hiding the templated operator=.
-      */
-    Transpositions& operator=(const Transpositions& other)
-    {
-      m_indices = other.m_indices;
-      return *this;
-    }
-    #endif
-
-    /** Constructs an uninitialized permutation matrix of given size.
-      */
-    inline Transpositions(Index size) : m_indices(size)
-    {}
-
-    /** const version of indices(). */
-    const IndicesType& indices() const { return m_indices; }
-    /** \returns a reference to the stored array representing the transpositions. */
-    IndicesType& indices() { return m_indices; }
-
-  protected:
-
-    IndicesType m_indices;
-};
-
-
-namespace internal {
-template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename _StorageIndex, int _PacketAccess>
-struct traits<Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,_StorageIndex>,_PacketAccess> >
- : traits<PermutationMatrix<SizeAtCompileTime,MaxSizeAtCompileTime,_StorageIndex> >
-{
-  typedef Map<const Matrix<_StorageIndex,SizeAtCompileTime,1,0,MaxSizeAtCompileTime,1>, _PacketAccess> IndicesType;
-  typedef _StorageIndex StorageIndex;
-  typedef TranspositionsStorage StorageKind;
-};
-}
-
-template<int SizeAtCompileTime, int MaxSizeAtCompileTime, typename _StorageIndex, int PacketAccess>
-class Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,_StorageIndex>,PacketAccess>
- : public TranspositionsBase<Map<Transpositions<SizeAtCompileTime,MaxSizeAtCompileTime,_StorageIndex>,PacketAccess> >
-{
-    typedef internal::traits<Map> Traits;
-  public:
-
-    typedef TranspositionsBase<Map> Base;
-    typedef typename Traits::IndicesType IndicesType;
-    typedef typename IndicesType::Scalar StorageIndex;
-
-    explicit inline Map(const StorageIndex* indicesPtr)
-      : m_indices(indicesPtr)
-    {}
-
-    inline Map(const StorageIndex* indicesPtr, Index size)
-      : m_indices(indicesPtr,size)
-    {}
-
-    /** Copies the \a other transpositions into \c *this */
-    template<typename OtherDerived>
-    Map& operator=(const TranspositionsBase<OtherDerived>& other)
-    {
-      return Base::operator=(other);
-    }
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    /** This is a special case of the templated operator=. Its purpose is to
-      * prevent a default operator= from hiding the templated operator=.
-      */
-    Map& operator=(const Map& other)
-    {
-      m_indices = other.m_indices;
-      return *this;
-    }
-    #endif
-
-    /** const version of indices(). */
-    const IndicesType& indices() const { return m_indices; }
-    
-    /** \returns a reference to the stored array representing the transpositions. */
-    IndicesType& indices() { return m_indices; }
-
-  protected:
-
-    IndicesType m_indices;
-};
-
-namespace internal {
-template<typename _IndicesType>
-struct traits<TranspositionsWrapper<_IndicesType> >
- : traits<PermutationWrapper<_IndicesType> >
-{
-  typedef TranspositionsStorage StorageKind;
-};
-}
-
-template<typename _IndicesType>
-class TranspositionsWrapper
- : public TranspositionsBase<TranspositionsWrapper<_IndicesType> >
-{
-    typedef internal::traits<TranspositionsWrapper> Traits;
-  public:
-
-    typedef TranspositionsBase<TranspositionsWrapper> Base;
-    typedef typename Traits::IndicesType IndicesType;
-    typedef typename IndicesType::Scalar StorageIndex;
-
-    explicit inline TranspositionsWrapper(IndicesType& indices)
-      : m_indices(indices)
-    {}
-
-    /** Copies the \a other transpositions into \c *this */
-    template<typename OtherDerived>
-    TranspositionsWrapper& operator=(const TranspositionsBase<OtherDerived>& other)
-    {
-      return Base::operator=(other);
-    }
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    /** This is a special case of the templated operator=. Its purpose is to
-      * prevent a default operator= from hiding the templated operator=.
-      */
-    TranspositionsWrapper& operator=(const TranspositionsWrapper& other)
-    {
-      m_indices = other.m_indices;
-      return *this;
-    }
-    #endif
-
-    /** const version of indices(). */
-    const IndicesType& indices() const { return m_indices; }
-
-    /** \returns a reference to the stored array representing the transpositions. */
-    IndicesType& indices() { return m_indices; }
-
-  protected:
-
-    typename IndicesType::Nested m_indices;
-};
-
-
-
-/** \returns the \a matrix with the \a transpositions applied to the columns.
-  */
-template<typename MatrixDerived, typename TranspositionsDerived>
-EIGEN_DEVICE_FUNC
-const Product<MatrixDerived, TranspositionsDerived, AliasFreeProduct>
-operator*(const MatrixBase<MatrixDerived> &matrix,
-          const TranspositionsBase<TranspositionsDerived>& transpositions)
-{
-  return Product<MatrixDerived, TranspositionsDerived, AliasFreeProduct>
-            (matrix.derived(), transpositions.derived());
-}
-
-/** \returns the \a matrix with the \a transpositions applied to the rows.
-  */
-template<typename TranspositionsDerived, typename MatrixDerived>
-EIGEN_DEVICE_FUNC
-const Product<TranspositionsDerived, MatrixDerived, AliasFreeProduct>
-operator*(const TranspositionsBase<TranspositionsDerived> &transpositions,
-          const MatrixBase<MatrixDerived>& matrix)
-{
-  return Product<TranspositionsDerived, MatrixDerived, AliasFreeProduct>
-            (transpositions.derived(), matrix.derived());
-}
-
-// Template partial specialization for transposed/inverse transpositions
-
-namespace internal {
-
-template<typename Derived>
-struct traits<Transpose<TranspositionsBase<Derived> > >
- : traits<Derived>
-{};
-
-} // end namespace internal
-
-template<typename TranspositionsDerived>
-class Transpose<TranspositionsBase<TranspositionsDerived> >
-{
-    typedef TranspositionsDerived TranspositionType;
-    typedef typename TranspositionType::IndicesType IndicesType;
-  public:
-
-    explicit Transpose(const TranspositionType& t) : m_transpositions(t) {}
-
-    Index size() const { return m_transpositions.size(); }
-    Index rows() const { return m_transpositions.size(); }
-    Index cols() const { return m_transpositions.size(); }
-
-    /** \returns the \a matrix with the inverse transpositions applied to the columns.
-      */
-    template<typename OtherDerived> friend
-    const Product<OtherDerived, Transpose, AliasFreeProduct>
-    operator*(const MatrixBase<OtherDerived>& matrix, const Transpose& trt)
-    {
-      return Product<OtherDerived, Transpose, AliasFreeProduct>(matrix.derived(), trt);
-    }
-
-    /** \returns the \a matrix with the inverse transpositions applied to the rows.
-      */
-    template<typename OtherDerived>
-    const Product<Transpose, OtherDerived, AliasFreeProduct>
-    operator*(const MatrixBase<OtherDerived>& matrix) const
-    {
-      return Product<Transpose, OtherDerived, AliasFreeProduct>(*this, matrix.derived());
-    }
-    
-    const TranspositionType& nestedExpression() const { return m_transpositions; }
-
-  protected:
-    const TranspositionType& m_transpositions;
-};
-
-} // end namespace Eigen
-
-#endif // EIGEN_TRANSPOSITIONS_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/TriangularMatrix.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/TriangularMatrix.h
deleted file mode 100644
index 667ef09..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/TriangularMatrix.h
+++ /dev/null
@@ -1,983 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_TRIANGULARMATRIX_H
-#define EIGEN_TRIANGULARMATRIX_H
-
-namespace Eigen { 
-
-namespace internal {
-  
-template<int Side, typename TriangularType, typename Rhs> struct triangular_solve_retval;
-  
-}
-
-/** \class TriangularBase
-  * \ingroup Core_Module
-  *
-  * \brief Base class for triangular part in a matrix
-  */
-template<typename Derived> class TriangularBase : public EigenBase<Derived>
-{
-  public:
-
-    enum {
-      Mode = internal::traits<Derived>::Mode,
-      RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
-      ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
-      MaxRowsAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime,
-      MaxColsAtCompileTime = internal::traits<Derived>::MaxColsAtCompileTime,
-      
-      SizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::RowsAtCompileTime,
-                                                   internal::traits<Derived>::ColsAtCompileTime>::ret),
-      /**< This is equal to the number of coefficients, i.e. the number of
-          * rows times the number of columns, or to \a Dynamic if this is not
-          * known at compile-time. \sa RowsAtCompileTime, ColsAtCompileTime */
-      
-      MaxSizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::MaxRowsAtCompileTime,
-                                                   internal::traits<Derived>::MaxColsAtCompileTime>::ret)
-        
-    };
-    typedef typename internal::traits<Derived>::Scalar Scalar;
-    typedef typename internal::traits<Derived>::StorageKind StorageKind;
-    typedef typename internal::traits<Derived>::StorageIndex StorageIndex;
-    typedef typename internal::traits<Derived>::FullMatrixType DenseMatrixType;
-    typedef DenseMatrixType DenseType;
-    typedef Derived const& Nested;
-
-    EIGEN_DEVICE_FUNC
-    inline TriangularBase() { eigen_assert(!((Mode&UnitDiag) && (Mode&ZeroDiag))); }
-
-    EIGEN_DEVICE_FUNC
-    inline Index rows() const { return derived().rows(); }
-    EIGEN_DEVICE_FUNC
-    inline Index cols() const { return derived().cols(); }
-    EIGEN_DEVICE_FUNC
-    inline Index outerStride() const { return derived().outerStride(); }
-    EIGEN_DEVICE_FUNC
-    inline Index innerStride() const { return derived().innerStride(); }
-    
-    // dummy resize function
-    void resize(Index rows, Index cols)
-    {
-      EIGEN_UNUSED_VARIABLE(rows);
-      EIGEN_UNUSED_VARIABLE(cols);
-      eigen_assert(rows==this->rows() && cols==this->cols());
-    }
-
-    EIGEN_DEVICE_FUNC
-    inline Scalar coeff(Index row, Index col) const  { return derived().coeff(row,col); }
-    EIGEN_DEVICE_FUNC
-    inline Scalar& coeffRef(Index row, Index col) { return derived().coeffRef(row,col); }
-
-    /** \see MatrixBase::copyCoeff(row,col)
-      */
-    template<typename Other>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE void copyCoeff(Index row, Index col, Other& other)
-    {
-      derived().coeffRef(row, col) = other.coeff(row, col);
-    }
-
-    EIGEN_DEVICE_FUNC
-    inline Scalar operator()(Index row, Index col) const
-    {
-      check_coordinates(row, col);
-      return coeff(row,col);
-    }
-    EIGEN_DEVICE_FUNC
-    inline Scalar& operator()(Index row, Index col)
-    {
-      check_coordinates(row, col);
-      return coeffRef(row,col);
-    }
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    EIGEN_DEVICE_FUNC
-    inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
-    EIGEN_DEVICE_FUNC
-    inline Derived& derived() { return *static_cast<Derived*>(this); }
-    #endif // not EIGEN_PARSED_BY_DOXYGEN
-
-    template<typename DenseDerived>
-    EIGEN_DEVICE_FUNC
-    void evalTo(MatrixBase<DenseDerived> &other) const;
-    template<typename DenseDerived>
-    EIGEN_DEVICE_FUNC
-    void evalToLazy(MatrixBase<DenseDerived> &other) const;
-
-    EIGEN_DEVICE_FUNC
-    DenseMatrixType toDenseMatrix() const
-    {
-      DenseMatrixType res(rows(), cols());
-      evalToLazy(res);
-      return res;
-    }
-
-  protected:
-
-    void check_coordinates(Index row, Index col) const
-    {
-      EIGEN_ONLY_USED_FOR_DEBUG(row);
-      EIGEN_ONLY_USED_FOR_DEBUG(col);
-      eigen_assert(col>=0 && col<cols() && row>=0 && row<rows());
-      const int mode = int(Mode) & ~SelfAdjoint;
-      EIGEN_ONLY_USED_FOR_DEBUG(mode);
-      eigen_assert((mode==Upper && col>=row)
-                || (mode==Lower && col<=row)
-                || ((mode==StrictlyUpper || mode==UnitUpper) && col>row)
-                || ((mode==StrictlyLower || mode==UnitLower) && col<row));
-    }
-
-    #ifdef EIGEN_INTERNAL_DEBUGGING
-    void check_coordinates_internal(Index row, Index col) const
-    {
-      check_coordinates(row, col);
-    }
-    #else
-    void check_coordinates_internal(Index , Index ) const {}
-    #endif
-
-};
-
-/** \class TriangularView
-  * \ingroup Core_Module
-  *
-  * \brief Expression of a triangular part in a matrix
-  *
-  * \param MatrixType the type of the object in which we are taking the triangular part
-  * \param Mode the kind of triangular matrix expression to construct. Can be #Upper,
-  *             #Lower, #UnitUpper, #UnitLower, #StrictlyUpper, or #StrictlyLower.
-  *             This is in fact a bit field; it must have either #Upper or #Lower, 
-  *             and additionally it may have #UnitDiag or #ZeroDiag or neither.
-  *
-  * This class represents a triangular part of a matrix, not necessarily square. Strictly speaking, for rectangular
-  * matrices one should speak of "trapezoid" parts. This class is the return type
-  * of MatrixBase::triangularView() and SparseMatrixBase::triangularView(), and most of the time this is the only way it is used.
-  *
-  * \sa MatrixBase::triangularView()
-  */
-namespace internal {
-template<typename MatrixType, unsigned int _Mode>
-struct traits<TriangularView<MatrixType, _Mode> > : traits<MatrixType>
-{
-  typedef typename ref_selector<MatrixType>::non_const_type MatrixTypeNested;
-  typedef typename remove_reference<MatrixTypeNested>::type MatrixTypeNestedNonRef;
-  typedef typename remove_all<MatrixTypeNested>::type MatrixTypeNestedCleaned;
-  typedef typename MatrixType::PlainObject FullMatrixType;
-  typedef MatrixType ExpressionType;
-  enum {
-    Mode = _Mode,
-    FlagsLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
-    Flags = (MatrixTypeNestedCleaned::Flags & (HereditaryBits | FlagsLvalueBit) & (~(PacketAccessBit | DirectAccessBit | LinearAccessBit)))
-  };
-};
-}
-
-template<typename _MatrixType, unsigned int _Mode, typename StorageKind> class TriangularViewImpl;
-
-template<typename _MatrixType, unsigned int _Mode> class TriangularView
-  : public TriangularViewImpl<_MatrixType, _Mode, typename internal::traits<_MatrixType>::StorageKind >
-{
-  public:
-
-    typedef TriangularViewImpl<_MatrixType, _Mode, typename internal::traits<_MatrixType>::StorageKind > Base;
-    typedef typename internal::traits<TriangularView>::Scalar Scalar;
-    typedef _MatrixType MatrixType;
-
-  protected:
-    typedef typename internal::traits<TriangularView>::MatrixTypeNested MatrixTypeNested;
-    typedef typename internal::traits<TriangularView>::MatrixTypeNestedNonRef MatrixTypeNestedNonRef;
-
-    typedef typename internal::remove_all<typename MatrixType::ConjugateReturnType>::type MatrixConjugateReturnType;
-    
-  public:
-
-    typedef typename internal::traits<TriangularView>::StorageKind StorageKind;
-    typedef typename internal::traits<TriangularView>::MatrixTypeNestedCleaned NestedExpression;
-
-    enum {
-      Mode = _Mode,
-      Flags = internal::traits<TriangularView>::Flags,
-      TransposeMode = (Mode & Upper ? Lower : 0)
-                    | (Mode & Lower ? Upper : 0)
-                    | (Mode & (UnitDiag))
-                    | (Mode & (ZeroDiag)),
-      IsVectorAtCompileTime = false
-    };
-
-    EIGEN_DEVICE_FUNC
-    explicit inline TriangularView(MatrixType& matrix) : m_matrix(matrix)
-    {}
-    
-    using Base::operator=;
-    TriangularView& operator=(const TriangularView &other)
-    { return Base::operator=(other); }
-
-    /** \copydoc EigenBase::rows() */
-    EIGEN_DEVICE_FUNC
-    inline Index rows() const { return m_matrix.rows(); }
-    /** \copydoc EigenBase::cols() */
-    EIGEN_DEVICE_FUNC
-    inline Index cols() const { return m_matrix.cols(); }
-
-    /** \returns a const reference to the nested expression */
-    EIGEN_DEVICE_FUNC
-    const NestedExpression& nestedExpression() const { return m_matrix; }
-
-    /** \returns a reference to the nested expression */
-    EIGEN_DEVICE_FUNC
-    NestedExpression& nestedExpression() { return m_matrix; }
-    
-    typedef TriangularView<const MatrixConjugateReturnType,Mode> ConjugateReturnType;
-    /** \sa MatrixBase::conjugate() const */
-    EIGEN_DEVICE_FUNC
-    inline const ConjugateReturnType conjugate() const
-    { return ConjugateReturnType(m_matrix.conjugate()); }
-
-    typedef TriangularView<const typename MatrixType::AdjointReturnType,TransposeMode> AdjointReturnType;
-    /** \sa MatrixBase::adjoint() const */
-    EIGEN_DEVICE_FUNC
-    inline const AdjointReturnType adjoint() const
-    { return AdjointReturnType(m_matrix.adjoint()); }
-
-    typedef TriangularView<typename MatrixType::TransposeReturnType,TransposeMode> TransposeReturnType;
-     /** \sa MatrixBase::transpose() */
-    EIGEN_DEVICE_FUNC
-    inline TransposeReturnType transpose()
-    {
-      EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
-      typename MatrixType::TransposeReturnType tmp(m_matrix);
-      return TransposeReturnType(tmp);
-    }
-    
-    typedef TriangularView<const typename MatrixType::ConstTransposeReturnType,TransposeMode> ConstTransposeReturnType;
-    /** \sa MatrixBase::transpose() const */
-    EIGEN_DEVICE_FUNC
-    inline const ConstTransposeReturnType transpose() const
-    {
-      return ConstTransposeReturnType(m_matrix.transpose());
-    }
-
-    template<typename Other>
-    EIGEN_DEVICE_FUNC
-    inline const Solve<TriangularView, Other> 
-    solve(const MatrixBase<Other>& other) const
-    { return Solve<TriangularView, Other>(*this, other.derived()); }
-    
-  // workaround MSVC ICE
-  #if EIGEN_COMP_MSVC
-    template<int Side, typename Other>
-    EIGEN_DEVICE_FUNC
-    inline const internal::triangular_solve_retval<Side,TriangularView, Other>
-    solve(const MatrixBase<Other>& other) const
-    { return Base::template solve<Side>(other); }
-  #else
-    using Base::solve;
-  #endif
-
-    /** \returns a selfadjoint view of the referenced triangular part which must be either \c #Upper or \c #Lower.
-      *
-      * This is a shortcut for \code this->nestedExpression().selfadjointView<(*this)::Mode>() \endcode
-      * \sa MatrixBase::selfadjointView() */
-    EIGEN_DEVICE_FUNC
-    SelfAdjointView<MatrixTypeNestedNonRef,Mode> selfadjointView()
-    {
-      EIGEN_STATIC_ASSERT((Mode&(UnitDiag|ZeroDiag))==0,PROGRAMMING_ERROR);
-      return SelfAdjointView<MatrixTypeNestedNonRef,Mode>(m_matrix);
-    }
-
-    /** This is the const version of selfadjointView() */
-    EIGEN_DEVICE_FUNC
-    const SelfAdjointView<MatrixTypeNestedNonRef,Mode> selfadjointView() const
-    {
-      EIGEN_STATIC_ASSERT((Mode&(UnitDiag|ZeroDiag))==0,PROGRAMMING_ERROR);
-      return SelfAdjointView<MatrixTypeNestedNonRef,Mode>(m_matrix);
-    }
-
-
-    /** \returns the determinant of the triangular matrix
-      * \sa MatrixBase::determinant() */
-    EIGEN_DEVICE_FUNC
-    Scalar determinant() const
-    {
-      if (Mode & UnitDiag)
-        return 1;
-      else if (Mode & ZeroDiag)
-        return 0;
-      else
-        return m_matrix.diagonal().prod();
-    }
-      
-  protected:
-
-    MatrixTypeNested m_matrix;
-};
-
-/** \ingroup Core_Module
-  *
-  * \brief Base class for a triangular part in a \b dense matrix
-  *
-  * This class is an abstract base class of class TriangularView, and objects of type TriangularViewImpl cannot be instantiated.
-  * It extends class TriangularView with additional methods which available for dense expressions only.
-  *
-  * \sa class TriangularView, MatrixBase::triangularView()
-  */
-template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_MatrixType,_Mode,Dense>
-  : public TriangularBase<TriangularView<_MatrixType, _Mode> >
-{
-  public:
-
-    typedef TriangularView<_MatrixType, _Mode> TriangularViewType;
-    typedef TriangularBase<TriangularViewType> Base;
-    typedef typename internal::traits<TriangularViewType>::Scalar Scalar;
-
-    typedef _MatrixType MatrixType;
-    typedef typename MatrixType::PlainObject DenseMatrixType;
-    typedef DenseMatrixType PlainObject;
-
-  public:
-    using Base::evalToLazy;
-    using Base::derived;
-
-    typedef typename internal::traits<TriangularViewType>::StorageKind StorageKind;
-
-    enum {
-      Mode = _Mode,
-      Flags = internal::traits<TriangularViewType>::Flags
-    };
-
-    /** \returns the outer-stride of the underlying dense matrix
-      * \sa DenseCoeffsBase::outerStride() */
-    EIGEN_DEVICE_FUNC
-    inline Index outerStride() const { return derived().nestedExpression().outerStride(); }
-    /** \returns the inner-stride of the underlying dense matrix
-      * \sa DenseCoeffsBase::innerStride() */
-    EIGEN_DEVICE_FUNC
-    inline Index innerStride() const { return derived().nestedExpression().innerStride(); }
-
-    /** \sa MatrixBase::operator+=() */
-    template<typename Other>
-    EIGEN_DEVICE_FUNC
-    TriangularViewType&  operator+=(const DenseBase<Other>& other) {
-      internal::call_assignment_no_alias(derived(), other.derived(), internal::add_assign_op<Scalar,typename Other::Scalar>());
-      return derived();
-    }
-    /** \sa MatrixBase::operator-=() */
-    template<typename Other>
-    EIGEN_DEVICE_FUNC
-    TriangularViewType&  operator-=(const DenseBase<Other>& other) {
-      internal::call_assignment_no_alias(derived(), other.derived(), internal::sub_assign_op<Scalar,typename Other::Scalar>());
-      return derived();
-    }
-    
-    /** \sa MatrixBase::operator*=() */
-    EIGEN_DEVICE_FUNC
-    TriangularViewType&  operator*=(const typename internal::traits<MatrixType>::Scalar& other) { return *this = derived().nestedExpression() * other; }
-    /** \sa DenseBase::operator/=() */
-    EIGEN_DEVICE_FUNC
-    TriangularViewType&  operator/=(const typename internal::traits<MatrixType>::Scalar& other) { return *this = derived().nestedExpression() / other; }
-
-    /** \sa MatrixBase::fill() */
-    EIGEN_DEVICE_FUNC
-    void fill(const Scalar& value) { setConstant(value); }
-    /** \sa MatrixBase::setConstant() */
-    EIGEN_DEVICE_FUNC
-    TriangularViewType& setConstant(const Scalar& value)
-    { return *this = MatrixType::Constant(derived().rows(), derived().cols(), value); }
-    /** \sa MatrixBase::setZero() */
-    EIGEN_DEVICE_FUNC
-    TriangularViewType& setZero() { return setConstant(Scalar(0)); }
-    /** \sa MatrixBase::setOnes() */
-    EIGEN_DEVICE_FUNC
-    TriangularViewType& setOnes() { return setConstant(Scalar(1)); }
-
-    /** \sa MatrixBase::coeff()
-      * \warning the coordinates must fit into the referenced triangular part
-      */
-    EIGEN_DEVICE_FUNC
-    inline Scalar coeff(Index row, Index col) const
-    {
-      Base::check_coordinates_internal(row, col);
-      return derived().nestedExpression().coeff(row, col);
-    }
-
-    /** \sa MatrixBase::coeffRef()
-      * \warning the coordinates must fit into the referenced triangular part
-      */
-    EIGEN_DEVICE_FUNC
-    inline Scalar& coeffRef(Index row, Index col)
-    {
-      EIGEN_STATIC_ASSERT_LVALUE(TriangularViewType);
-      Base::check_coordinates_internal(row, col);
-      return derived().nestedExpression().coeffRef(row, col);
-    }
-
-    /** Assigns a triangular matrix to a triangular part of a dense matrix */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    TriangularViewType& operator=(const TriangularBase<OtherDerived>& other);
-
-    /** Shortcut for\code *this = other.other.triangularView<(*this)::Mode>() \endcode */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    TriangularViewType& operator=(const MatrixBase<OtherDerived>& other);
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-    EIGEN_DEVICE_FUNC
-    TriangularViewType& operator=(const TriangularViewImpl& other)
-    { return *this = other.derived().nestedExpression(); }
-
-    /** \deprecated */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    void lazyAssign(const TriangularBase<OtherDerived>& other);
-
-    /** \deprecated */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    void lazyAssign(const MatrixBase<OtherDerived>& other);
-#endif
-
-    /** Efficient triangular matrix times vector/matrix product */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    const Product<TriangularViewType,OtherDerived>
-    operator*(const MatrixBase<OtherDerived>& rhs) const
-    {
-      return Product<TriangularViewType,OtherDerived>(derived(), rhs.derived());
-    }
-
-    /** Efficient vector/matrix times triangular matrix product */
-    template<typename OtherDerived> friend
-    EIGEN_DEVICE_FUNC
-    const Product<OtherDerived,TriangularViewType>
-    operator*(const MatrixBase<OtherDerived>& lhs, const TriangularViewImpl& rhs)
-    {
-      return Product<OtherDerived,TriangularViewType>(lhs.derived(),rhs.derived());
-    }
-
-    /** \returns the product of the inverse of \c *this with \a other, \a *this being triangular.
-      *
-      * This function computes the inverse-matrix matrix product inverse(\c *this) * \a other if
-      * \a Side==OnTheLeft (the default), or the right-inverse-multiply  \a other * inverse(\c *this) if
-      * \a Side==OnTheRight.
-      *
-      * Note that the template parameter \c Side can be ommitted, in which case \c Side==OnTheLeft
-      *
-      * The matrix \c *this must be triangular and invertible (i.e., all the coefficients of the
-      * diagonal must be non zero). It works as a forward (resp. backward) substitution if \c *this
-      * is an upper (resp. lower) triangular matrix.
-      *
-      * Example: \include Triangular_solve.cpp
-      * Output: \verbinclude Triangular_solve.out
-      *
-      * This function returns an expression of the inverse-multiply and can works in-place if it is assigned
-      * to the same matrix or vector \a other.
-      *
-      * For users coming from BLAS, this function (and more specifically solveInPlace()) offer
-      * all the operations supported by the \c *TRSV and \c *TRSM BLAS routines.
-      *
-      * \sa TriangularView::solveInPlace()
-      */
-    template<int Side, typename Other>
-    EIGEN_DEVICE_FUNC
-    inline const internal::triangular_solve_retval<Side,TriangularViewType, Other>
-    solve(const MatrixBase<Other>& other) const;
-
-    /** "in-place" version of TriangularView::solve() where the result is written in \a other
-      *
-      * \warning The parameter is only marked 'const' to make the C++ compiler accept a temporary expression here.
-      * This function will const_cast it, so constness isn't honored here.
-      *
-      * Note that the template parameter \c Side can be ommitted, in which case \c Side==OnTheLeft
-      *
-      * See TriangularView:solve() for the details.
-      */
-    template<int Side, typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    void solveInPlace(const MatrixBase<OtherDerived>& other) const;
-
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    void solveInPlace(const MatrixBase<OtherDerived>& other) const
-    { return solveInPlace<OnTheLeft>(other); }
-
-    /** Swaps the coefficients of the common triangular parts of two matrices */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-#ifdef EIGEN_PARSED_BY_DOXYGEN
-    void swap(TriangularBase<OtherDerived> &other)
-#else
-    void swap(TriangularBase<OtherDerived> const & other)
-#endif
-    {
-      EIGEN_STATIC_ASSERT_LVALUE(OtherDerived);
-      call_assignment(derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
-    }
-
-    /** \deprecated
-      * Shortcut for \code (*this).swap(other.triangularView<(*this)::Mode>()) \endcode */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    void swap(MatrixBase<OtherDerived> const & other)
-    {
-      EIGEN_STATIC_ASSERT_LVALUE(OtherDerived);
-      call_assignment(derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
-    }
-
-    template<typename RhsType, typename DstType>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE void _solve_impl(const RhsType &rhs, DstType &dst) const {
-      if(!internal::is_same_dense(dst,rhs))
-        dst = rhs;
-      this->solveInPlace(dst);
-    }
-
-    template<typename ProductType>
-    EIGEN_DEVICE_FUNC
-    EIGEN_STRONG_INLINE TriangularViewType& _assignProduct(const ProductType& prod, const Scalar& alpha, bool beta);
-};
-
-/***************************************************************************
-* Implementation of triangular evaluation/assignment
-***************************************************************************/
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-// FIXME should we keep that possibility
-template<typename MatrixType, unsigned int Mode>
-template<typename OtherDerived>
-inline TriangularView<MatrixType, Mode>&
-TriangularViewImpl<MatrixType, Mode, Dense>::operator=(const MatrixBase<OtherDerived>& other)
-{
-  internal::call_assignment_no_alias(derived(), other.derived(), internal::assign_op<Scalar,typename OtherDerived::Scalar>());
-  return derived();
-}
-
-// FIXME should we keep that possibility
-template<typename MatrixType, unsigned int Mode>
-template<typename OtherDerived>
-void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(const MatrixBase<OtherDerived>& other)
-{
-  internal::call_assignment_no_alias(derived(), other.template triangularView<Mode>());
-}
-
-
-
-template<typename MatrixType, unsigned int Mode>
-template<typename OtherDerived>
-inline TriangularView<MatrixType, Mode>&
-TriangularViewImpl<MatrixType, Mode, Dense>::operator=(const TriangularBase<OtherDerived>& other)
-{
-  eigen_assert(Mode == int(OtherDerived::Mode));
-  internal::call_assignment(derived(), other.derived());
-  return derived();
-}
-
-template<typename MatrixType, unsigned int Mode>
-template<typename OtherDerived>
-void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(const TriangularBase<OtherDerived>& other)
-{
-  eigen_assert(Mode == int(OtherDerived::Mode));
-  internal::call_assignment_no_alias(derived(), other.derived());
-}
-#endif
-
-/***************************************************************************
-* Implementation of TriangularBase methods
-***************************************************************************/
-
-/** Assigns a triangular or selfadjoint matrix to a dense matrix.
-  * If the matrix is triangular, the opposite part is set to zero. */
-template<typename Derived>
-template<typename DenseDerived>
-void TriangularBase<Derived>::evalTo(MatrixBase<DenseDerived> &other) const
-{
-  evalToLazy(other.derived());
-}
-
-/***************************************************************************
-* Implementation of TriangularView methods
-***************************************************************************/
-
-/***************************************************************************
-* Implementation of MatrixBase methods
-***************************************************************************/
-
-/**
-  * \returns an expression of a triangular view extracted from the current matrix
-  *
-  * The parameter \a Mode can have the following values: \c #Upper, \c #StrictlyUpper, \c #UnitUpper,
-  * \c #Lower, \c #StrictlyLower, \c #UnitLower.
-  *
-  * Example: \include MatrixBase_triangularView.cpp
-  * Output: \verbinclude MatrixBase_triangularView.out
-  *
-  * \sa class TriangularView
-  */
-template<typename Derived>
-template<unsigned int Mode>
-typename MatrixBase<Derived>::template TriangularViewReturnType<Mode>::Type
-MatrixBase<Derived>::triangularView()
-{
-  return typename TriangularViewReturnType<Mode>::Type(derived());
-}
-
-/** This is the const version of MatrixBase::triangularView() */
-template<typename Derived>
-template<unsigned int Mode>
-typename MatrixBase<Derived>::template ConstTriangularViewReturnType<Mode>::Type
-MatrixBase<Derived>::triangularView() const
-{
-  return typename ConstTriangularViewReturnType<Mode>::Type(derived());
-}
-
-/** \returns true if *this is approximately equal to an upper triangular matrix,
-  *          within the precision given by \a prec.
-  *
-  * \sa isLowerTriangular()
-  */
-template<typename Derived>
-bool MatrixBase<Derived>::isUpperTriangular(const RealScalar& prec) const
-{
-  RealScalar maxAbsOnUpperPart = static_cast<RealScalar>(-1);
-  for(Index j = 0; j < cols(); ++j)
-  {
-    Index maxi = numext::mini(j, rows()-1);
-    for(Index i = 0; i <= maxi; ++i)
-    {
-      RealScalar absValue = numext::abs(coeff(i,j));
-      if(absValue > maxAbsOnUpperPart) maxAbsOnUpperPart = absValue;
-    }
-  }
-  RealScalar threshold = maxAbsOnUpperPart * prec;
-  for(Index j = 0; j < cols(); ++j)
-    for(Index i = j+1; i < rows(); ++i)
-      if(numext::abs(coeff(i, j)) > threshold) return false;
-  return true;
-}
-
-/** \returns true if *this is approximately equal to a lower triangular matrix,
-  *          within the precision given by \a prec.
-  *
-  * \sa isUpperTriangular()
-  */
-template<typename Derived>
-bool MatrixBase<Derived>::isLowerTriangular(const RealScalar& prec) const
-{
-  RealScalar maxAbsOnLowerPart = static_cast<RealScalar>(-1);
-  for(Index j = 0; j < cols(); ++j)
-    for(Index i = j; i < rows(); ++i)
-    {
-      RealScalar absValue = numext::abs(coeff(i,j));
-      if(absValue > maxAbsOnLowerPart) maxAbsOnLowerPart = absValue;
-    }
-  RealScalar threshold = maxAbsOnLowerPart * prec;
-  for(Index j = 1; j < cols(); ++j)
-  {
-    Index maxi = numext::mini(j, rows()-1);
-    for(Index i = 0; i < maxi; ++i)
-      if(numext::abs(coeff(i, j)) > threshold) return false;
-  }
-  return true;
-}
-
-
-/***************************************************************************
-****************************************************************************
-* Evaluators and Assignment of triangular expressions
-***************************************************************************
-***************************************************************************/
-
-namespace internal {
-
-  
-// TODO currently a triangular expression has the form TriangularView<.,.>
-//      in the future triangular-ness should be defined by the expression traits
-//      such that Transpose<TriangularView<.,.> > is valid. (currently TriangularBase::transpose() is overloaded to make it work)
-template<typename MatrixType, unsigned int Mode>
-struct evaluator_traits<TriangularView<MatrixType,Mode> >
-{
-  typedef typename storage_kind_to_evaluator_kind<typename MatrixType::StorageKind>::Kind Kind;
-  typedef typename glue_shapes<typename evaluator_traits<MatrixType>::Shape, TriangularShape>::type Shape;
-};
-
-template<typename MatrixType, unsigned int Mode>
-struct unary_evaluator<TriangularView<MatrixType,Mode>, IndexBased>
- : evaluator<typename internal::remove_all<MatrixType>::type>
-{
-  typedef TriangularView<MatrixType,Mode> XprType;
-  typedef evaluator<typename internal::remove_all<MatrixType>::type> Base;
-  unary_evaluator(const XprType &xpr) : Base(xpr.nestedExpression()) {}
-};
-
-// Additional assignment kinds:
-struct Triangular2Triangular    {};
-struct Triangular2Dense         {};
-struct Dense2Triangular         {};
-
-
-template<typename Kernel, unsigned int Mode, int UnrollCount, bool ClearOpposite> struct triangular_assignment_loop;
-
- 
-/** \internal Specialization of the dense assignment kernel for triangular matrices.
-  * The main difference is that the triangular, diagonal, and opposite parts are processed through three different functions.
-  * \tparam UpLo must be either Lower or Upper
-  * \tparam Mode must be either 0, UnitDiag, ZeroDiag, or SelfAdjoint
-  */
-template<int UpLo, int Mode, int SetOpposite, typename DstEvaluatorTypeT, typename SrcEvaluatorTypeT, typename Functor, int Version = Specialized>
-class triangular_dense_assignment_kernel : public generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, Version>
-{
-protected:
-  typedef generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, Version> Base;
-  typedef typename Base::DstXprType DstXprType;
-  typedef typename Base::SrcXprType SrcXprType;
-  using Base::m_dst;
-  using Base::m_src;
-  using Base::m_functor;
-public:
-  
-  typedef typename Base::DstEvaluatorType DstEvaluatorType;
-  typedef typename Base::SrcEvaluatorType SrcEvaluatorType;
-  typedef typename Base::Scalar Scalar;
-  typedef typename Base::AssignmentTraits AssignmentTraits;
-  
-  
-  EIGEN_DEVICE_FUNC triangular_dense_assignment_kernel(DstEvaluatorType &dst, const SrcEvaluatorType &src, const Functor &func, DstXprType& dstExpr)
-    : Base(dst, src, func, dstExpr)
-  {}
-  
-#ifdef EIGEN_INTERNAL_DEBUGGING
-  EIGEN_DEVICE_FUNC void assignCoeff(Index row, Index col)
-  {
-    eigen_internal_assert(row!=col);
-    Base::assignCoeff(row,col);
-  }
-#else
-  using Base::assignCoeff;
-#endif
-  
-  EIGEN_DEVICE_FUNC void assignDiagonalCoeff(Index id)
-  {
-         if(Mode==UnitDiag && SetOpposite) m_functor.assignCoeff(m_dst.coeffRef(id,id), Scalar(1));
-    else if(Mode==ZeroDiag && SetOpposite) m_functor.assignCoeff(m_dst.coeffRef(id,id), Scalar(0));
-    else if(Mode==0)                       Base::assignCoeff(id,id);
-  }
-  
-  EIGEN_DEVICE_FUNC void assignOppositeCoeff(Index row, Index col)
-  { 
-    eigen_internal_assert(row!=col);
-    if(SetOpposite)
-      m_functor.assignCoeff(m_dst.coeffRef(row,col), Scalar(0));
-  }
-};
-
-template<int Mode, bool SetOpposite, typename DstXprType, typename SrcXprType, typename Functor>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-void call_triangular_assignment_loop(DstXprType& dst, const SrcXprType& src, const Functor &func)
-{
-  typedef evaluator<DstXprType> DstEvaluatorType;
-  typedef evaluator<SrcXprType> SrcEvaluatorType;
-
-  SrcEvaluatorType srcEvaluator(src);
-
-  Index dstRows = src.rows();
-  Index dstCols = src.cols();
-  if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
-    dst.resize(dstRows, dstCols);
-  DstEvaluatorType dstEvaluator(dst);
-    
-  typedef triangular_dense_assignment_kernel< Mode&(Lower|Upper),Mode&(UnitDiag|ZeroDiag|SelfAdjoint),SetOpposite,
-                                              DstEvaluatorType,SrcEvaluatorType,Functor> Kernel;
-  Kernel kernel(dstEvaluator, srcEvaluator, func, dst.const_cast_derived());
-  
-  enum {
-      unroll = DstXprType::SizeAtCompileTime != Dynamic
-            && SrcEvaluatorType::CoeffReadCost < HugeCost
-            && DstXprType::SizeAtCompileTime * (DstEvaluatorType::CoeffReadCost+SrcEvaluatorType::CoeffReadCost) / 2 <= EIGEN_UNROLLING_LIMIT
-    };
-  
-  triangular_assignment_loop<Kernel, Mode, unroll ? int(DstXprType::SizeAtCompileTime) : Dynamic, SetOpposite>::run(kernel);
-}
-
-template<int Mode, bool SetOpposite, typename DstXprType, typename SrcXprType>
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-void call_triangular_assignment_loop(DstXprType& dst, const SrcXprType& src)
-{
-  call_triangular_assignment_loop<Mode,SetOpposite>(dst, src, internal::assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar>());
-}
-
-template<> struct AssignmentKind<TriangularShape,TriangularShape> { typedef Triangular2Triangular Kind; };
-template<> struct AssignmentKind<DenseShape,TriangularShape>      { typedef Triangular2Dense      Kind; };
-template<> struct AssignmentKind<TriangularShape,DenseShape>      { typedef Dense2Triangular      Kind; };
-
-
-template< typename DstXprType, typename SrcXprType, typename Functor>
-struct Assignment<DstXprType, SrcXprType, Functor, Triangular2Triangular>
-{
-  EIGEN_DEVICE_FUNC static void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
-  {
-    eigen_assert(int(DstXprType::Mode) == int(SrcXprType::Mode));
-    
-    call_triangular_assignment_loop<DstXprType::Mode, false>(dst, src, func);  
-  }
-};
-
-template< typename DstXprType, typename SrcXprType, typename Functor>
-struct Assignment<DstXprType, SrcXprType, Functor, Triangular2Dense>
-{
-  EIGEN_DEVICE_FUNC static void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
-  {
-    call_triangular_assignment_loop<SrcXprType::Mode, (SrcXprType::Mode&SelfAdjoint)==0>(dst, src, func);  
-  }
-};
-
-template< typename DstXprType, typename SrcXprType, typename Functor>
-struct Assignment<DstXprType, SrcXprType, Functor, Dense2Triangular>
-{
-  EIGEN_DEVICE_FUNC static void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
-  {
-    call_triangular_assignment_loop<DstXprType::Mode, false>(dst, src, func);  
-  }
-};
-
-
-template<typename Kernel, unsigned int Mode, int UnrollCount, bool SetOpposite>
-struct triangular_assignment_loop
-{
-  // FIXME: this is not very clean, perhaps this information should be provided by the kernel?
-  typedef typename Kernel::DstEvaluatorType DstEvaluatorType;
-  typedef typename DstEvaluatorType::XprType DstXprType;
-  
-  enum {
-    col = (UnrollCount-1) / DstXprType::RowsAtCompileTime,
-    row = (UnrollCount-1) % DstXprType::RowsAtCompileTime
-  };
-  
-  typedef typename Kernel::Scalar Scalar;
-
-  EIGEN_DEVICE_FUNC
-  static inline void run(Kernel &kernel)
-  {
-    triangular_assignment_loop<Kernel, Mode, UnrollCount-1, SetOpposite>::run(kernel);
-    
-    if(row==col)
-      kernel.assignDiagonalCoeff(row);
-    else if( ((Mode&Lower) && row>col) || ((Mode&Upper) && row<col) )
-      kernel.assignCoeff(row,col);
-    else if(SetOpposite)
-      kernel.assignOppositeCoeff(row,col);
-  }
-};
-
-// prevent buggy user code from causing an infinite recursion
-template<typename Kernel, unsigned int Mode, bool SetOpposite>
-struct triangular_assignment_loop<Kernel, Mode, 0, SetOpposite>
-{
-  EIGEN_DEVICE_FUNC
-  static inline void run(Kernel &) {}
-};
-
-
-
-// TODO: experiment with a recursive assignment procedure splitting the current
-//       triangular part into one rectangular and two triangular parts.
-
-
-template<typename Kernel, unsigned int Mode, bool SetOpposite>
-struct triangular_assignment_loop<Kernel, Mode, Dynamic, SetOpposite>
-{
-  typedef typename Kernel::Scalar Scalar;
-  EIGEN_DEVICE_FUNC
-  static inline void run(Kernel &kernel)
-  {
-    for(Index j = 0; j < kernel.cols(); ++j)
-    {
-      Index maxi = numext::mini(j, kernel.rows());
-      Index i = 0;
-      if (((Mode&Lower) && SetOpposite) || (Mode&Upper))
-      {
-        for(; i < maxi; ++i)
-          if(Mode&Upper) kernel.assignCoeff(i, j);
-          else           kernel.assignOppositeCoeff(i, j);
-      }
-      else
-        i = maxi;
-      
-      if(i<kernel.rows()) // then i==j
-        kernel.assignDiagonalCoeff(i++);
-      
-      if (((Mode&Upper) && SetOpposite) || (Mode&Lower))
-      {
-        for(; i < kernel.rows(); ++i)
-          if(Mode&Lower) kernel.assignCoeff(i, j);
-          else           kernel.assignOppositeCoeff(i, j);
-      }
-    }
-  }
-};
-
-} // end namespace internal
-
-/** Assigns a triangular or selfadjoint matrix to a dense matrix.
-  * If the matrix is triangular, the opposite part is set to zero. */
-template<typename Derived>
-template<typename DenseDerived>
-void TriangularBase<Derived>::evalToLazy(MatrixBase<DenseDerived> &other) const
-{
-  other.derived().resize(this->rows(), this->cols());
-  internal::call_triangular_assignment_loop<Derived::Mode,(Derived::Mode&SelfAdjoint)==0 /* SetOpposite */>(other.derived(), derived().nestedExpression());
-}
-
-namespace internal {
-  
-// Triangular = Product
-template< typename DstXprType, typename Lhs, typename Rhs, typename Scalar>
-struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::assign_op<Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, Dense2Triangular>
-{
-  typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
-  static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,typename SrcXprType::Scalar> &)
-  {
-    Index dstRows = src.rows();
-    Index dstCols = src.cols();
-    if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
-      dst.resize(dstRows, dstCols);
-
-    dst._assignProduct(src, 1, 0);
-  }
-};
-
-// Triangular += Product
-template< typename DstXprType, typename Lhs, typename Rhs, typename Scalar>
-struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::add_assign_op<Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, Dense2Triangular>
-{
-  typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
-  static void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<Scalar,typename SrcXprType::Scalar> &)
-  {
-    dst._assignProduct(src, 1, 1);
-  }
-};
-
-// Triangular -= Product
-template< typename DstXprType, typename Lhs, typename Rhs, typename Scalar>
-struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::sub_assign_op<Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, Dense2Triangular>
-{
-  typedef Product<Lhs,Rhs,DefaultProduct> SrcXprType;
-  static void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<Scalar,typename SrcXprType::Scalar> &)
-  {
-    dst._assignProduct(src, -1, 1);
-  }
-};
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_TRIANGULARMATRIX_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/VectorBlock.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/VectorBlock.h
deleted file mode 100644
index d72fbf7..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/VectorBlock.h
+++ /dev/null
@@ -1,96 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_VECTORBLOCK_H
-#define EIGEN_VECTORBLOCK_H
-
-namespace Eigen { 
-
-namespace internal {
-template<typename VectorType, int Size>
-struct traits<VectorBlock<VectorType, Size> >
-  : public traits<Block<VectorType,
-                     traits<VectorType>::Flags & RowMajorBit ? 1 : Size,
-                     traits<VectorType>::Flags & RowMajorBit ? Size : 1> >
-{
-};
-}
-
-/** \class VectorBlock
-  * \ingroup Core_Module
-  *
-  * \brief Expression of a fixed-size or dynamic-size sub-vector
-  *
-  * \tparam VectorType the type of the object in which we are taking a sub-vector
-  * \tparam Size size of the sub-vector we are taking at compile time (optional)
-  *
-  * This class represents an expression of either a fixed-size or dynamic-size sub-vector.
-  * It is the return type of DenseBase::segment(Index,Index) and DenseBase::segment<int>(Index) and
-  * most of the time this is the only way it is used.
-  *
-  * However, if you want to directly maniputate sub-vector expressions,
-  * for instance if you want to write a function returning such an expression, you
-  * will need to use this class.
-  *
-  * Here is an example illustrating the dynamic case:
-  * \include class_VectorBlock.cpp
-  * Output: \verbinclude class_VectorBlock.out
-  *
-  * \note Even though this expression has dynamic size, in the case where \a VectorType
-  * has fixed size, this expression inherits a fixed maximal size which means that evaluating
-  * it does not cause a dynamic memory allocation.
-  *
-  * Here is an example illustrating the fixed-size case:
-  * \include class_FixedVectorBlock.cpp
-  * Output: \verbinclude class_FixedVectorBlock.out
-  *
-  * \sa class Block, DenseBase::segment(Index,Index,Index,Index), DenseBase::segment(Index,Index)
-  */
-template<typename VectorType, int Size> class VectorBlock
-  : public Block<VectorType,
-                     internal::traits<VectorType>::Flags & RowMajorBit ? 1 : Size,
-                     internal::traits<VectorType>::Flags & RowMajorBit ? Size : 1>
-{
-    typedef Block<VectorType,
-                     internal::traits<VectorType>::Flags & RowMajorBit ? 1 : Size,
-                     internal::traits<VectorType>::Flags & RowMajorBit ? Size : 1> Base;
-    enum {
-      IsColVector = !(internal::traits<VectorType>::Flags & RowMajorBit)
-    };
-  public:
-    EIGEN_DENSE_PUBLIC_INTERFACE(VectorBlock)
-
-    using Base::operator=;
-
-    /** Dynamic-size constructor
-      */
-    EIGEN_DEVICE_FUNC
-    inline VectorBlock(VectorType& vector, Index start, Index size)
-      : Base(vector,
-             IsColVector ? start : 0, IsColVector ? 0 : start,
-             IsColVector ? size  : 1, IsColVector ? 1 : size)
-    {
-      EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorBlock);
-    }
-
-    /** Fixed-size constructor
-      */
-    EIGEN_DEVICE_FUNC
-    inline VectorBlock(VectorType& vector, Index start)
-      : Base(vector, IsColVector ? start : 0, IsColVector ? 0 : start)
-    {
-      EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorBlock);
-    }
-};
-
-
-} // end namespace Eigen
-
-#endif // EIGEN_VECTORBLOCK_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/VectorwiseOp.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/VectorwiseOp.h
deleted file mode 100644
index 4fe267e..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/VectorwiseOp.h
+++ /dev/null
@@ -1,695 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_PARTIAL_REDUX_H
-#define EIGEN_PARTIAL_REDUX_H
-
-namespace Eigen {
-
-/** \class PartialReduxExpr
-  * \ingroup Core_Module
-  *
-  * \brief Generic expression of a partially reduxed matrix
-  *
-  * \tparam MatrixType the type of the matrix we are applying the redux operation
-  * \tparam MemberOp type of the member functor
-  * \tparam Direction indicates the direction of the redux (#Vertical or #Horizontal)
-  *
-  * This class represents an expression of a partial redux operator of a matrix.
-  * It is the return type of some VectorwiseOp functions,
-  * and most of the time this is the only way it is used.
-  *
-  * \sa class VectorwiseOp
-  */
-
-template< typename MatrixType, typename MemberOp, int Direction>
-class PartialReduxExpr;
-
-namespace internal {
-template<typename MatrixType, typename MemberOp, int Direction>
-struct traits<PartialReduxExpr<MatrixType, MemberOp, Direction> >
- : traits<MatrixType>
-{
-  typedef typename MemberOp::result_type Scalar;
-  typedef typename traits<MatrixType>::StorageKind StorageKind;
-  typedef typename traits<MatrixType>::XprKind XprKind;
-  typedef typename MatrixType::Scalar InputScalar;
-  enum {
-    RowsAtCompileTime = Direction==Vertical   ? 1 : MatrixType::RowsAtCompileTime,
-    ColsAtCompileTime = Direction==Horizontal ? 1 : MatrixType::ColsAtCompileTime,
-    MaxRowsAtCompileTime = Direction==Vertical   ? 1 : MatrixType::MaxRowsAtCompileTime,
-    MaxColsAtCompileTime = Direction==Horizontal ? 1 : MatrixType::MaxColsAtCompileTime,
-    Flags = RowsAtCompileTime == 1 ? RowMajorBit : 0,
-    TraversalSize = Direction==Vertical ? MatrixType::RowsAtCompileTime :  MatrixType::ColsAtCompileTime
-  };
-};
-}
-
-template< typename MatrixType, typename MemberOp, int Direction>
-class PartialReduxExpr : public internal::dense_xpr_base< PartialReduxExpr<MatrixType, MemberOp, Direction> >::type,
-                         internal::no_assignment_operator
-{
-  public:
-
-    typedef typename internal::dense_xpr_base<PartialReduxExpr>::type Base;
-    EIGEN_DENSE_PUBLIC_INTERFACE(PartialReduxExpr)
-
-    EIGEN_DEVICE_FUNC
-    explicit PartialReduxExpr(const MatrixType& mat, const MemberOp& func = MemberOp())
-      : m_matrix(mat), m_functor(func) {}
-
-    EIGEN_DEVICE_FUNC
-    Index rows() const { return (Direction==Vertical   ? 1 : m_matrix.rows()); }
-    EIGEN_DEVICE_FUNC
-    Index cols() const { return (Direction==Horizontal ? 1 : m_matrix.cols()); }
-
-    EIGEN_DEVICE_FUNC
-    typename MatrixType::Nested nestedExpression() const { return m_matrix; }
-
-    EIGEN_DEVICE_FUNC
-    const MemberOp& functor() const { return m_functor; }
-
-  protected:
-    typename MatrixType::Nested m_matrix;
-    const MemberOp m_functor;
-};
-
-#define EIGEN_MEMBER_FUNCTOR(MEMBER,COST)                               \
-  template <typename ResultType>                                        \
-  struct member_##MEMBER {                                              \
-    EIGEN_EMPTY_STRUCT_CTOR(member_##MEMBER)                            \
-    typedef ResultType result_type;                                     \
-    template<typename Scalar, int Size> struct Cost                     \
-    { enum { value = COST }; };                                         \
-    template<typename XprType>                                          \
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE                               \
-    ResultType operator()(const XprType& mat) const                     \
-    { return mat.MEMBER(); } \
-  }
-
-namespace internal {
-
-EIGEN_MEMBER_FUNCTOR(squaredNorm, Size * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
-EIGEN_MEMBER_FUNCTOR(norm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
-EIGEN_MEMBER_FUNCTOR(stableNorm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
-EIGEN_MEMBER_FUNCTOR(blueNorm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
-EIGEN_MEMBER_FUNCTOR(hypotNorm, (Size-1) * functor_traits<scalar_hypot_op<Scalar> >::Cost );
-EIGEN_MEMBER_FUNCTOR(sum, (Size-1)*NumTraits<Scalar>::AddCost);
-EIGEN_MEMBER_FUNCTOR(mean, (Size-1)*NumTraits<Scalar>::AddCost + NumTraits<Scalar>::MulCost);
-EIGEN_MEMBER_FUNCTOR(minCoeff, (Size-1)*NumTraits<Scalar>::AddCost);
-EIGEN_MEMBER_FUNCTOR(maxCoeff, (Size-1)*NumTraits<Scalar>::AddCost);
-EIGEN_MEMBER_FUNCTOR(all, (Size-1)*NumTraits<Scalar>::AddCost);
-EIGEN_MEMBER_FUNCTOR(any, (Size-1)*NumTraits<Scalar>::AddCost);
-EIGEN_MEMBER_FUNCTOR(count, (Size-1)*NumTraits<Scalar>::AddCost);
-EIGEN_MEMBER_FUNCTOR(prod, (Size-1)*NumTraits<Scalar>::MulCost);
-
-template <int p, typename ResultType>
-struct member_lpnorm {
-  typedef ResultType result_type;
-  template<typename Scalar, int Size> struct Cost
-  { enum { value = (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost }; };
-  EIGEN_DEVICE_FUNC member_lpnorm() {}
-  template<typename XprType>
-  EIGEN_DEVICE_FUNC inline ResultType operator()(const XprType& mat) const
-  { return mat.template lpNorm<p>(); }
-};
-
-template <typename BinaryOp, typename Scalar>
-struct member_redux {
-  typedef typename result_of<
-                     BinaryOp(const Scalar&,const Scalar&)
-                   >::type  result_type;
-  template<typename _Scalar, int Size> struct Cost
-  { enum { value = (Size-1) * functor_traits<BinaryOp>::Cost }; };
-  EIGEN_DEVICE_FUNC explicit member_redux(const BinaryOp func) : m_functor(func) {}
-  template<typename Derived>
-  EIGEN_DEVICE_FUNC inline result_type operator()(const DenseBase<Derived>& mat) const
-  { return mat.redux(m_functor); }
-  const BinaryOp m_functor;
-};
-}
-
-/** \class VectorwiseOp
-  * \ingroup Core_Module
-  *
-  * \brief Pseudo expression providing partial reduction operations
-  *
-  * \tparam ExpressionType the type of the object on which to do partial reductions
-  * \tparam Direction indicates the direction of the redux (#Vertical or #Horizontal)
-  *
-  * This class represents a pseudo expression with partial reduction features.
-  * It is the return type of DenseBase::colwise() and DenseBase::rowwise()
-  * and most of the time this is the only way it is used.
-  *
-  * Example: \include MatrixBase_colwise.cpp
-  * Output: \verbinclude MatrixBase_colwise.out
-  *
-  * \sa DenseBase::colwise(), DenseBase::rowwise(), class PartialReduxExpr
-  */
-template<typename ExpressionType, int Direction> class VectorwiseOp
-{
-  public:
-
-    typedef typename ExpressionType::Scalar Scalar;
-    typedef typename ExpressionType::RealScalar RealScalar;
-    typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
-    typedef typename internal::ref_selector<ExpressionType>::non_const_type ExpressionTypeNested;
-    typedef typename internal::remove_all<ExpressionTypeNested>::type ExpressionTypeNestedCleaned;
-
-    template<template<typename _Scalar> class Functor,
-                      typename Scalar_=Scalar> struct ReturnType
-    {
-      typedef PartialReduxExpr<ExpressionType,
-                               Functor<Scalar_>,
-                               Direction
-                              > Type;
-    };
-
-    template<typename BinaryOp> struct ReduxReturnType
-    {
-      typedef PartialReduxExpr<ExpressionType,
-                               internal::member_redux<BinaryOp,Scalar>,
-                               Direction
-                              > Type;
-    };
-
-    enum {
-      isVertical   = (Direction==Vertical) ? 1 : 0,
-      isHorizontal = (Direction==Horizontal) ? 1 : 0
-    };
-
-  protected:
-
-    typedef typename internal::conditional<isVertical,
-                               typename ExpressionType::ColXpr,
-                               typename ExpressionType::RowXpr>::type SubVector;
-    /** \internal
-      * \returns the i-th subvector according to the \c Direction */
-    EIGEN_DEVICE_FUNC
-    SubVector subVector(Index i)
-    {
-      return SubVector(m_matrix.derived(),i);
-    }
-
-    /** \internal
-      * \returns the number of subvectors in the direction \c Direction */
-    EIGEN_DEVICE_FUNC
-    Index subVectors() const
-    { return isVertical?m_matrix.cols():m_matrix.rows(); }
-
-    template<typename OtherDerived> struct ExtendedType {
-      typedef Replicate<OtherDerived,
-                        isVertical   ? 1 : ExpressionType::RowsAtCompileTime,
-                        isHorizontal ? 1 : ExpressionType::ColsAtCompileTime> Type;
-    };
-
-    /** \internal
-      * Replicates a vector to match the size of \c *this */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    typename ExtendedType<OtherDerived>::Type
-    extendedTo(const DenseBase<OtherDerived>& other) const
-    {
-      EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(isVertical, OtherDerived::MaxColsAtCompileTime==1),
-                          YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED)
-      EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(isHorizontal, OtherDerived::MaxRowsAtCompileTime==1),
-                          YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED)
-      return typename ExtendedType<OtherDerived>::Type
-                      (other.derived(),
-                       isVertical   ? 1 : m_matrix.rows(),
-                       isHorizontal ? 1 : m_matrix.cols());
-    }
-
-    template<typename OtherDerived> struct OppositeExtendedType {
-      typedef Replicate<OtherDerived,
-                        isHorizontal ? 1 : ExpressionType::RowsAtCompileTime,
-                        isVertical   ? 1 : ExpressionType::ColsAtCompileTime> Type;
-    };
-
-    /** \internal
-      * Replicates a vector in the opposite direction to match the size of \c *this */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    typename OppositeExtendedType<OtherDerived>::Type
-    extendedToOpposite(const DenseBase<OtherDerived>& other) const
-    {
-      EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(isHorizontal, OtherDerived::MaxColsAtCompileTime==1),
-                          YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED)
-      EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(isVertical, OtherDerived::MaxRowsAtCompileTime==1),
-                          YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED)
-      return typename OppositeExtendedType<OtherDerived>::Type
-                      (other.derived(),
-                       isHorizontal  ? 1 : m_matrix.rows(),
-                       isVertical    ? 1 : m_matrix.cols());
-    }
-
-  public:
-    EIGEN_DEVICE_FUNC
-    explicit inline VectorwiseOp(ExpressionType& matrix) : m_matrix(matrix) {}
-
-    /** \internal */
-    EIGEN_DEVICE_FUNC
-    inline const ExpressionType& _expression() const { return m_matrix; }
-
-    /** \returns a row or column vector expression of \c *this reduxed by \a func
-      *
-      * The template parameter \a BinaryOp is the type of the functor
-      * of the custom redux operator. Note that func must be an associative operator.
-      *
-      * \sa class VectorwiseOp, DenseBase::colwise(), DenseBase::rowwise()
-      */
-    template<typename BinaryOp>
-    EIGEN_DEVICE_FUNC
-    const typename ReduxReturnType<BinaryOp>::Type
-    redux(const BinaryOp& func = BinaryOp()) const
-    { return typename ReduxReturnType<BinaryOp>::Type(_expression(), internal::member_redux<BinaryOp,Scalar>(func)); }
-
-    typedef typename ReturnType<internal::member_minCoeff>::Type MinCoeffReturnType;
-    typedef typename ReturnType<internal::member_maxCoeff>::Type MaxCoeffReturnType;
-    typedef typename ReturnType<internal::member_squaredNorm,RealScalar>::Type SquaredNormReturnType;
-    typedef typename ReturnType<internal::member_norm,RealScalar>::Type NormReturnType;
-    typedef typename ReturnType<internal::member_blueNorm,RealScalar>::Type BlueNormReturnType;
-    typedef typename ReturnType<internal::member_stableNorm,RealScalar>::Type StableNormReturnType;
-    typedef typename ReturnType<internal::member_hypotNorm,RealScalar>::Type HypotNormReturnType;
-    typedef typename ReturnType<internal::member_sum>::Type SumReturnType;
-    typedef typename ReturnType<internal::member_mean>::Type MeanReturnType;
-    typedef typename ReturnType<internal::member_all>::Type AllReturnType;
-    typedef typename ReturnType<internal::member_any>::Type AnyReturnType;
-    typedef PartialReduxExpr<ExpressionType, internal::member_count<Index>, Direction> CountReturnType;
-    typedef typename ReturnType<internal::member_prod>::Type ProdReturnType;
-    typedef Reverse<const ExpressionType, Direction> ConstReverseReturnType;
-    typedef Reverse<ExpressionType, Direction> ReverseReturnType;
-
-    template<int p> struct LpNormReturnType {
-      typedef PartialReduxExpr<ExpressionType, internal::member_lpnorm<p,RealScalar>,Direction> Type;
-    };
-
-    /** \returns a row (or column) vector expression of the smallest coefficient
-      * of each column (or row) of the referenced expression.
-      *
-      * \warning the result is undefined if \c *this contains NaN.
-      *
-      * Example: \include PartialRedux_minCoeff.cpp
-      * Output: \verbinclude PartialRedux_minCoeff.out
-      *
-      * \sa DenseBase::minCoeff() */
-    EIGEN_DEVICE_FUNC
-    const MinCoeffReturnType minCoeff() const
-    { return MinCoeffReturnType(_expression()); }
-
-    /** \returns a row (or column) vector expression of the largest coefficient
-      * of each column (or row) of the referenced expression.
-      *
-      * \warning the result is undefined if \c *this contains NaN.
-      *
-      * Example: \include PartialRedux_maxCoeff.cpp
-      * Output: \verbinclude PartialRedux_maxCoeff.out
-      *
-      * \sa DenseBase::maxCoeff() */
-    EIGEN_DEVICE_FUNC
-    const MaxCoeffReturnType maxCoeff() const
-    { return MaxCoeffReturnType(_expression()); }
-
-    /** \returns a row (or column) vector expression of the squared norm
-      * of each column (or row) of the referenced expression.
-      * This is a vector with real entries, even if the original matrix has complex entries.
-      *
-      * Example: \include PartialRedux_squaredNorm.cpp
-      * Output: \verbinclude PartialRedux_squaredNorm.out
-      *
-      * \sa DenseBase::squaredNorm() */
-    EIGEN_DEVICE_FUNC
-    const SquaredNormReturnType squaredNorm() const
-    { return SquaredNormReturnType(_expression()); }
-
-    /** \returns a row (or column) vector expression of the norm
-      * of each column (or row) of the referenced expression.
-      * This is a vector with real entries, even if the original matrix has complex entries.
-      *
-      * Example: \include PartialRedux_norm.cpp
-      * Output: \verbinclude PartialRedux_norm.out
-      *
-      * \sa DenseBase::norm() */
-    EIGEN_DEVICE_FUNC
-    const NormReturnType norm() const
-    { return NormReturnType(_expression()); }
-
-    /** \returns a row (or column) vector expression of the norm
-      * of each column (or row) of the referenced expression.
-      * This is a vector with real entries, even if the original matrix has complex entries.
-      *
-      * Example: \include PartialRedux_norm.cpp
-      * Output: \verbinclude PartialRedux_norm.out
-      *
-      * \sa DenseBase::norm() */
-    template<int p>
-    EIGEN_DEVICE_FUNC
-    const typename LpNormReturnType<p>::Type lpNorm() const
-    { return typename LpNormReturnType<p>::Type(_expression()); }
-
-
-    /** \returns a row (or column) vector expression of the norm
-      * of each column (or row) of the referenced expression, using
-      * Blue's algorithm.
-      * This is a vector with real entries, even if the original matrix has complex entries.
-      *
-      * \sa DenseBase::blueNorm() */
-    EIGEN_DEVICE_FUNC
-    const BlueNormReturnType blueNorm() const
-    { return BlueNormReturnType(_expression()); }
-
-
-    /** \returns a row (or column) vector expression of the norm
-      * of each column (or row) of the referenced expression, avoiding
-      * underflow and overflow.
-      * This is a vector with real entries, even if the original matrix has complex entries.
-      *
-      * \sa DenseBase::stableNorm() */
-    EIGEN_DEVICE_FUNC
-    const StableNormReturnType stableNorm() const
-    { return StableNormReturnType(_expression()); }
-
-
-    /** \returns a row (or column) vector expression of the norm
-      * of each column (or row) of the referenced expression, avoiding
-      * underflow and overflow using a concatenation of hypot() calls.
-      * This is a vector with real entries, even if the original matrix has complex entries.
-      *
-      * \sa DenseBase::hypotNorm() */
-    EIGEN_DEVICE_FUNC
-    const HypotNormReturnType hypotNorm() const
-    { return HypotNormReturnType(_expression()); }
-
-    /** \returns a row (or column) vector expression of the sum
-      * of each column (or row) of the referenced expression.
-      *
-      * Example: \include PartialRedux_sum.cpp
-      * Output: \verbinclude PartialRedux_sum.out
-      *
-      * \sa DenseBase::sum() */
-    EIGEN_DEVICE_FUNC
-    const SumReturnType sum() const
-    { return SumReturnType(_expression()); }
-
-    /** \returns a row (or column) vector expression of the mean
-    * of each column (or row) of the referenced expression.
-    *
-    * \sa DenseBase::mean() */
-    EIGEN_DEVICE_FUNC
-    const MeanReturnType mean() const
-    { return MeanReturnType(_expression()); }
-
-    /** \returns a row (or column) vector expression representing
-      * whether \b all coefficients of each respective column (or row) are \c true.
-      * This expression can be assigned to a vector with entries of type \c bool.
-      *
-      * \sa DenseBase::all() */
-    EIGEN_DEVICE_FUNC
-    const AllReturnType all() const
-    { return AllReturnType(_expression()); }
-
-    /** \returns a row (or column) vector expression representing
-      * whether \b at \b least one coefficient of each respective column (or row) is \c true.
-      * This expression can be assigned to a vector with entries of type \c bool.
-      *
-      * \sa DenseBase::any() */
-    EIGEN_DEVICE_FUNC
-    const AnyReturnType any() const
-    { return AnyReturnType(_expression()); }
-
-    /** \returns a row (or column) vector expression representing
-      * the number of \c true coefficients of each respective column (or row).
-      * This expression can be assigned to a vector whose entries have the same type as is used to
-      * index entries of the original matrix; for dense matrices, this is \c std::ptrdiff_t .
-      *
-      * Example: \include PartialRedux_count.cpp
-      * Output: \verbinclude PartialRedux_count.out
-      *
-      * \sa DenseBase::count() */
-    EIGEN_DEVICE_FUNC
-    const CountReturnType count() const
-    { return CountReturnType(_expression()); }
-
-    /** \returns a row (or column) vector expression of the product
-      * of each column (or row) of the referenced expression.
-      *
-      * Example: \include PartialRedux_prod.cpp
-      * Output: \verbinclude PartialRedux_prod.out
-      *
-      * \sa DenseBase::prod() */
-    EIGEN_DEVICE_FUNC
-    const ProdReturnType prod() const
-    { return ProdReturnType(_expression()); }
-
-
-    /** \returns a matrix expression
-      * where each column (or row) are reversed.
-      *
-      * Example: \include Vectorwise_reverse.cpp
-      * Output: \verbinclude Vectorwise_reverse.out
-      *
-      * \sa DenseBase::reverse() */
-    EIGEN_DEVICE_FUNC
-    const ConstReverseReturnType reverse() const
-    { return ConstReverseReturnType( _expression() ); }
-
-    /** \returns a writable matrix expression
-      * where each column (or row) are reversed.
-      *
-      * \sa reverse() const */
-    EIGEN_DEVICE_FUNC
-    ReverseReturnType reverse()
-    { return ReverseReturnType( _expression() ); }
-
-    typedef Replicate<ExpressionType,(isVertical?Dynamic:1),(isHorizontal?Dynamic:1)> ReplicateReturnType;
-    EIGEN_DEVICE_FUNC
-    const ReplicateReturnType replicate(Index factor) const;
-
-    /**
-      * \return an expression of the replication of each column (or row) of \c *this
-      *
-      * Example: \include DirectionWise_replicate.cpp
-      * Output: \verbinclude DirectionWise_replicate.out
-      *
-      * \sa VectorwiseOp::replicate(Index), DenseBase::replicate(), class Replicate
-      */
-    // NOTE implemented here because of sunstudio's compilation errors
-    // isVertical*Factor+isHorizontal instead of (isVertical?Factor:1) to handle CUDA bug with ternary operator
-    template<int Factor> const Replicate<ExpressionType,isVertical*Factor+isHorizontal,isHorizontal*Factor+isVertical>
-    EIGEN_DEVICE_FUNC
-    replicate(Index factor = Factor) const
-    {
-      return Replicate<ExpressionType,(isVertical?Factor:1),(isHorizontal?Factor:1)>
-          (_expression(),isVertical?factor:1,isHorizontal?factor:1);
-    }
-
-/////////// Artithmetic operators ///////////
-
-    /** Copies the vector \a other to each subvector of \c *this */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    ExpressionType& operator=(const DenseBase<OtherDerived>& other)
-    {
-      EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
-      EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
-      //eigen_assert((m_matrix.isNull()) == (other.isNull())); FIXME
-      return const_cast<ExpressionType&>(m_matrix = extendedTo(other.derived()));
-    }
-
-    /** Adds the vector \a other to each subvector of \c *this */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    ExpressionType& operator+=(const DenseBase<OtherDerived>& other)
-    {
-      EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
-      EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
-      return const_cast<ExpressionType&>(m_matrix += extendedTo(other.derived()));
-    }
-
-    /** Substracts the vector \a other to each subvector of \c *this */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    ExpressionType& operator-=(const DenseBase<OtherDerived>& other)
-    {
-      EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
-      EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
-      return const_cast<ExpressionType&>(m_matrix -= extendedTo(other.derived()));
-    }
-
-    /** Multiples each subvector of \c *this by the vector \a other */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    ExpressionType& operator*=(const DenseBase<OtherDerived>& other)
-    {
-      EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
-      EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType)
-      EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
-      m_matrix *= extendedTo(other.derived());
-      return const_cast<ExpressionType&>(m_matrix);
-    }
-
-    /** Divides each subvector of \c *this by the vector \a other */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    ExpressionType& operator/=(const DenseBase<OtherDerived>& other)
-    {
-      EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
-      EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType)
-      EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
-      m_matrix /= extendedTo(other.derived());
-      return const_cast<ExpressionType&>(m_matrix);
-    }
-
-    /** Returns the expression of the sum of the vector \a other to each subvector of \c *this */
-    template<typename OtherDerived> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
-    CwiseBinaryOp<internal::scalar_sum_op<Scalar,typename OtherDerived::Scalar>,
-                  const ExpressionTypeNestedCleaned,
-                  const typename ExtendedType<OtherDerived>::Type>
-    operator+(const DenseBase<OtherDerived>& other) const
-    {
-      EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
-      EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
-      return m_matrix + extendedTo(other.derived());
-    }
-
-    /** Returns the expression of the difference between each subvector of \c *this and the vector \a other */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    CwiseBinaryOp<internal::scalar_difference_op<Scalar,typename OtherDerived::Scalar>,
-                  const ExpressionTypeNestedCleaned,
-                  const typename ExtendedType<OtherDerived>::Type>
-    operator-(const DenseBase<OtherDerived>& other) const
-    {
-      EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
-      EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
-      return m_matrix - extendedTo(other.derived());
-    }
-
-    /** Returns the expression where each subvector is the product of the vector \a other
-      * by the corresponding subvector of \c *this */
-    template<typename OtherDerived> EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC
-    CwiseBinaryOp<internal::scalar_product_op<Scalar>,
-                  const ExpressionTypeNestedCleaned,
-                  const typename ExtendedType<OtherDerived>::Type>
-    EIGEN_DEVICE_FUNC
-    operator*(const DenseBase<OtherDerived>& other) const
-    {
-      EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
-      EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType)
-      EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
-      return m_matrix * extendedTo(other.derived());
-    }
-
-    /** Returns the expression where each subvector is the quotient of the corresponding
-      * subvector of \c *this by the vector \a other */
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    CwiseBinaryOp<internal::scalar_quotient_op<Scalar>,
-                  const ExpressionTypeNestedCleaned,
-                  const typename ExtendedType<OtherDerived>::Type>
-    operator/(const DenseBase<OtherDerived>& other) const
-    {
-      EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
-      EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType)
-      EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
-      return m_matrix / extendedTo(other.derived());
-    }
-
-    /** \returns an expression where each column (or row) of the referenced matrix are normalized.
-      * The referenced matrix is \b not modified.
-      * \sa MatrixBase::normalized(), normalize()
-      */
-    EIGEN_DEVICE_FUNC
-    CwiseBinaryOp<internal::scalar_quotient_op<Scalar>,
-                  const ExpressionTypeNestedCleaned,
-                  const typename OppositeExtendedType<typename ReturnType<internal::member_norm,RealScalar>::Type>::Type>
-    normalized() const { return m_matrix.cwiseQuotient(extendedToOpposite(this->norm())); }
-
-
-    /** Normalize in-place each row or columns of the referenced matrix.
-      * \sa MatrixBase::normalize(), normalized()
-      */
-    EIGEN_DEVICE_FUNC void normalize() {
-      m_matrix = this->normalized();
-    }
-
-    EIGEN_DEVICE_FUNC inline void reverseInPlace();
-
-/////////// Geometry module ///////////
-
-    typedef Homogeneous<ExpressionType,Direction> HomogeneousReturnType;
-    EIGEN_DEVICE_FUNC
-    HomogeneousReturnType homogeneous() const;
-
-    typedef typename ExpressionType::PlainObject CrossReturnType;
-    template<typename OtherDerived>
-    EIGEN_DEVICE_FUNC
-    const CrossReturnType cross(const MatrixBase<OtherDerived>& other) const;
-
-    enum {
-      HNormalized_Size = Direction==Vertical ? internal::traits<ExpressionType>::RowsAtCompileTime
-                                             : internal::traits<ExpressionType>::ColsAtCompileTime,
-      HNormalized_SizeMinusOne = HNormalized_Size==Dynamic ? Dynamic : HNormalized_Size-1
-    };
-    typedef Block<const ExpressionType,
-                  Direction==Vertical   ? int(HNormalized_SizeMinusOne)
-                                        : int(internal::traits<ExpressionType>::RowsAtCompileTime),
-                  Direction==Horizontal ? int(HNormalized_SizeMinusOne)
-                                        : int(internal::traits<ExpressionType>::ColsAtCompileTime)>
-            HNormalized_Block;
-    typedef Block<const ExpressionType,
-                  Direction==Vertical   ? 1 : int(internal::traits<ExpressionType>::RowsAtCompileTime),
-                  Direction==Horizontal ? 1 : int(internal::traits<ExpressionType>::ColsAtCompileTime)>
-            HNormalized_Factors;
-    typedef CwiseBinaryOp<internal::scalar_quotient_op<typename internal::traits<ExpressionType>::Scalar>,
-                const HNormalized_Block,
-                const Replicate<HNormalized_Factors,
-                  Direction==Vertical   ? HNormalized_SizeMinusOne : 1,
-                  Direction==Horizontal ? HNormalized_SizeMinusOne : 1> >
-            HNormalizedReturnType;
-
-    EIGEN_DEVICE_FUNC
-    const HNormalizedReturnType hnormalized() const;
-
-  protected:
-    ExpressionTypeNested m_matrix;
-};
-
-//const colwise moved to DenseBase.h due to CUDA compiler bug
-
-
-/** \returns a writable VectorwiseOp wrapper of *this providing additional partial reduction operations
-  *
-  * \sa rowwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting
-  */
-template<typename Derived>
-inline typename DenseBase<Derived>::ColwiseReturnType
-DenseBase<Derived>::colwise()
-{
-  return ColwiseReturnType(derived());
-}
-
-//const rowwise moved to DenseBase.h due to CUDA compiler bug
-
-
-/** \returns a writable VectorwiseOp wrapper of *this providing additional partial reduction operations
-  *
-  * \sa colwise(), class VectorwiseOp, \ref TutorialReductionsVisitorsBroadcasting
-  */
-template<typename Derived>
-inline typename DenseBase<Derived>::RowwiseReturnType
-DenseBase<Derived>::rowwise()
-{
-  return RowwiseReturnType(derived());
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_PARTIAL_REDUX_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Visitor.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Visitor.h
deleted file mode 100644
index 54c1883..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/Visitor.h
+++ /dev/null
@@ -1,273 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_VISITOR_H
-#define EIGEN_VISITOR_H
-
-namespace Eigen { 
-
-namespace internal {
-
-template<typename Visitor, typename Derived, int UnrollCount>
-struct visitor_impl
-{
-  enum {
-    col = (UnrollCount-1) / Derived::RowsAtCompileTime,
-    row = (UnrollCount-1) % Derived::RowsAtCompileTime
-  };
-
-  EIGEN_DEVICE_FUNC
-  static inline void run(const Derived &mat, Visitor& visitor)
-  {
-    visitor_impl<Visitor, Derived, UnrollCount-1>::run(mat, visitor);
-    visitor(mat.coeff(row, col), row, col);
-  }
-};
-
-template<typename Visitor, typename Derived>
-struct visitor_impl<Visitor, Derived, 1>
-{
-  EIGEN_DEVICE_FUNC
-  static inline void run(const Derived &mat, Visitor& visitor)
-  {
-    return visitor.init(mat.coeff(0, 0), 0, 0);
-  }
-};
-
-template<typename Visitor, typename Derived>
-struct visitor_impl<Visitor, Derived, Dynamic>
-{
-  EIGEN_DEVICE_FUNC
-  static inline void run(const Derived& mat, Visitor& visitor)
-  {
-    visitor.init(mat.coeff(0,0), 0, 0);
-    for(Index i = 1; i < mat.rows(); ++i)
-      visitor(mat.coeff(i, 0), i, 0);
-    for(Index j = 1; j < mat.cols(); ++j)
-      for(Index i = 0; i < mat.rows(); ++i)
-        visitor(mat.coeff(i, j), i, j);
-  }
-};
-
-// evaluator adaptor
-template<typename XprType>
-class visitor_evaluator
-{
-public:
-  EIGEN_DEVICE_FUNC
-  explicit visitor_evaluator(const XprType &xpr) : m_evaluator(xpr), m_xpr(xpr) {}
-  
-  typedef typename XprType::Scalar Scalar;
-  typedef typename XprType::CoeffReturnType CoeffReturnType;
-  
-  enum {
-    RowsAtCompileTime = XprType::RowsAtCompileTime,
-    CoeffReadCost = internal::evaluator<XprType>::CoeffReadCost
-  };
-  
-  EIGEN_DEVICE_FUNC Index rows() const { return m_xpr.rows(); }
-  EIGEN_DEVICE_FUNC Index cols() const { return m_xpr.cols(); }
-  EIGEN_DEVICE_FUNC Index size() const { return m_xpr.size(); }
-
-  EIGEN_DEVICE_FUNC CoeffReturnType coeff(Index row, Index col) const
-  { return m_evaluator.coeff(row, col); }
-  
-protected:
-  internal::evaluator<XprType> m_evaluator;
-  const XprType &m_xpr;
-};
-} // end namespace internal
-
-/** Applies the visitor \a visitor to the whole coefficients of the matrix or vector.
-  *
-  * The template parameter \a Visitor is the type of the visitor and provides the following interface:
-  * \code
-  * struct MyVisitor {
-  *   // called for the first coefficient
-  *   void init(const Scalar& value, Index i, Index j);
-  *   // called for all other coefficients
-  *   void operator() (const Scalar& value, Index i, Index j);
-  * };
-  * \endcode
-  *
-  * \note compared to one or two \em for \em loops, visitors offer automatic
-  * unrolling for small fixed size matrix.
-  *
-  * \sa minCoeff(Index*,Index*), maxCoeff(Index*,Index*), DenseBase::redux()
-  */
-template<typename Derived>
-template<typename Visitor>
-EIGEN_DEVICE_FUNC
-void DenseBase<Derived>::visit(Visitor& visitor) const
-{
-  typedef typename internal::visitor_evaluator<Derived> ThisEvaluator;
-  ThisEvaluator thisEval(derived());
-  
-  enum {
-    unroll =  SizeAtCompileTime != Dynamic
-           && SizeAtCompileTime * ThisEvaluator::CoeffReadCost + (SizeAtCompileTime-1) * internal::functor_traits<Visitor>::Cost <= EIGEN_UNROLLING_LIMIT
-  };
-  return internal::visitor_impl<Visitor, ThisEvaluator, unroll ? int(SizeAtCompileTime) : Dynamic>::run(thisEval, visitor);
-}
-
-namespace internal {
-
-/** \internal
-  * \brief Base class to implement min and max visitors
-  */
-template <typename Derived>
-struct coeff_visitor
-{
-  typedef typename Derived::Scalar Scalar;
-  Index row, col;
-  Scalar res;
-  EIGEN_DEVICE_FUNC
-  inline void init(const Scalar& value, Index i, Index j)
-  {
-    res = value;
-    row = i;
-    col = j;
-  }
-};
-
-/** \internal
-  * \brief Visitor computing the min coefficient with its value and coordinates
-  *
-  * \sa DenseBase::minCoeff(Index*, Index*)
-  */
-template <typename Derived>
-struct min_coeff_visitor : coeff_visitor<Derived>
-{
-  typedef typename Derived::Scalar Scalar;
-  EIGEN_DEVICE_FUNC
-  void operator() (const Scalar& value, Index i, Index j)
-  {
-    if(value < this->res)
-    {
-      this->res = value;
-      this->row = i;
-      this->col = j;
-    }
-  }
-};
-
-template<typename Scalar>
-struct functor_traits<min_coeff_visitor<Scalar> > {
-  enum {
-    Cost = NumTraits<Scalar>::AddCost
-  };
-};
-
-/** \internal
-  * \brief Visitor computing the max coefficient with its value and coordinates
-  *
-  * \sa DenseBase::maxCoeff(Index*, Index*)
-  */
-template <typename Derived>
-struct max_coeff_visitor : coeff_visitor<Derived>
-{
-  typedef typename Derived::Scalar Scalar; 
-  EIGEN_DEVICE_FUNC
-  void operator() (const Scalar& value, Index i, Index j)
-  {
-    if(value > this->res)
-    {
-      this->res = value;
-      this->row = i;
-      this->col = j;
-    }
-  }
-};
-
-template<typename Scalar>
-struct functor_traits<max_coeff_visitor<Scalar> > {
-  enum {
-    Cost = NumTraits<Scalar>::AddCost
-  };
-};
-
-} // end namespace internal
-
-/** \fn DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const
-  * \returns the minimum of all coefficients of *this and puts in *row and *col its location.
-  * \warning the result is undefined if \c *this contains NaN.
-  *
-  * \sa DenseBase::minCoeff(Index*), DenseBase::maxCoeff(Index*,Index*), DenseBase::visit(), DenseBase::minCoeff()
-  */
-template<typename Derived>
-template<typename IndexType>
-EIGEN_DEVICE_FUNC
-typename internal::traits<Derived>::Scalar
-DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const
-{
-  internal::min_coeff_visitor<Derived> minVisitor;
-  this->visit(minVisitor);
-  *rowId = minVisitor.row;
-  if (colId) *colId = minVisitor.col;
-  return minVisitor.res;
-}
-
-/** \returns the minimum of all coefficients of *this and puts in *index its location.
-  * \warning the result is undefined if \c *this contains NaN. 
-  *
-  * \sa DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::maxCoeff(IndexType*,IndexType*), DenseBase::visit(), DenseBase::minCoeff()
-  */
-template<typename Derived>
-template<typename IndexType>
-EIGEN_DEVICE_FUNC
-typename internal::traits<Derived>::Scalar
-DenseBase<Derived>::minCoeff(IndexType* index) const
-{
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
-  internal::min_coeff_visitor<Derived> minVisitor;
-  this->visit(minVisitor);
-  *index = IndexType((RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row);
-  return minVisitor.res;
-}
-
-/** \fn DenseBase<Derived>::maxCoeff(IndexType* rowId, IndexType* colId) const
-  * \returns the maximum of all coefficients of *this and puts in *row and *col its location.
-  * \warning the result is undefined if \c *this contains NaN. 
-  *
-  * \sa DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::visit(), DenseBase::maxCoeff()
-  */
-template<typename Derived>
-template<typename IndexType>
-EIGEN_DEVICE_FUNC
-typename internal::traits<Derived>::Scalar
-DenseBase<Derived>::maxCoeff(IndexType* rowPtr, IndexType* colPtr) const
-{
-  internal::max_coeff_visitor<Derived> maxVisitor;
-  this->visit(maxVisitor);
-  *rowPtr = maxVisitor.row;
-  if (colPtr) *colPtr = maxVisitor.col;
-  return maxVisitor.res;
-}
-
-/** \returns the maximum of all coefficients of *this and puts in *index its location.
-  * \warning the result is undefined if \c *this contains NaN.
-  *
-  * \sa DenseBase::maxCoeff(IndexType*,IndexType*), DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::visitor(), DenseBase::maxCoeff()
-  */
-template<typename Derived>
-template<typename IndexType>
-EIGEN_DEVICE_FUNC
-typename internal::traits<Derived>::Scalar
-DenseBase<Derived>::maxCoeff(IndexType* index) const
-{
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
-  internal::max_coeff_visitor<Derived> maxVisitor;
-  this->visit(maxVisitor);
-  *index = (RowsAtCompileTime==1) ? maxVisitor.col : maxVisitor.row;
-  return maxVisitor.res;
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_VISITOR_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/AVX/Complex.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/AVX/Complex.h
deleted file mode 100644
index 7fa6196..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/AVX/Complex.h
+++ /dev/null
@@ -1,451 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2014 Benoit Steiner (benoit.steiner.goog@gmail.com)
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_COMPLEX_AVX_H
-#define EIGEN_COMPLEX_AVX_H
-
-namespace Eigen {
-
-namespace internal {
-
-//---------- float ----------
-struct Packet4cf
-{
-  EIGEN_STRONG_INLINE Packet4cf() {}
-  EIGEN_STRONG_INLINE explicit Packet4cf(const __m256& a) : v(a) {}
-  __m256  v;
-};
-
-template<> struct packet_traits<std::complex<float> >  : default_packet_traits
-{
-  typedef Packet4cf type;
-  typedef Packet2cf half;
-  enum {
-    Vectorizable = 1,
-    AlignedOnScalar = 1,
-    size = 4,
-    HasHalfPacket = 1,
-
-    HasAdd    = 1,
-    HasSub    = 1,
-    HasMul    = 1,
-    HasDiv    = 1,
-    HasNegate = 1,
-    HasAbs    = 0,
-    HasAbs2   = 0,
-    HasMin    = 0,
-    HasMax    = 0,
-    HasSetLinear = 0
-  };
-};
-
-template<> struct unpacket_traits<Packet4cf> { typedef std::complex<float> type; enum {size=4, alignment=Aligned32}; typedef Packet2cf half; };
-
-template<> EIGEN_STRONG_INLINE Packet4cf padd<Packet4cf>(const Packet4cf& a, const Packet4cf& b) { return Packet4cf(_mm256_add_ps(a.v,b.v)); }
-template<> EIGEN_STRONG_INLINE Packet4cf psub<Packet4cf>(const Packet4cf& a, const Packet4cf& b) { return Packet4cf(_mm256_sub_ps(a.v,b.v)); }
-template<> EIGEN_STRONG_INLINE Packet4cf pnegate(const Packet4cf& a)
-{
-  return Packet4cf(pnegate(a.v));
-}
-template<> EIGEN_STRONG_INLINE Packet4cf pconj(const Packet4cf& a)
-{
-  const __m256 mask = _mm256_castsi256_ps(_mm256_setr_epi32(0x00000000,0x80000000,0x00000000,0x80000000,0x00000000,0x80000000,0x00000000,0x80000000));
-  return Packet4cf(_mm256_xor_ps(a.v,mask));
-}
-
-template<> EIGEN_STRONG_INLINE Packet4cf pmul<Packet4cf>(const Packet4cf& a, const Packet4cf& b)
-{
-  __m256 tmp1 = _mm256_mul_ps(_mm256_moveldup_ps(a.v), b.v);
-  __m256 tmp2 = _mm256_mul_ps(_mm256_movehdup_ps(a.v), _mm256_permute_ps(b.v, _MM_SHUFFLE(2,3,0,1)));
-  __m256 result = _mm256_addsub_ps(tmp1, tmp2);
-  return Packet4cf(result);
-}
-
-template<> EIGEN_STRONG_INLINE Packet4cf pand   <Packet4cf>(const Packet4cf& a, const Packet4cf& b) { return Packet4cf(_mm256_and_ps(a.v,b.v)); }
-template<> EIGEN_STRONG_INLINE Packet4cf por    <Packet4cf>(const Packet4cf& a, const Packet4cf& b) { return Packet4cf(_mm256_or_ps(a.v,b.v)); }
-template<> EIGEN_STRONG_INLINE Packet4cf pxor   <Packet4cf>(const Packet4cf& a, const Packet4cf& b) { return Packet4cf(_mm256_xor_ps(a.v,b.v)); }
-template<> EIGEN_STRONG_INLINE Packet4cf pandnot<Packet4cf>(const Packet4cf& a, const Packet4cf& b) { return Packet4cf(_mm256_andnot_ps(a.v,b.v)); }
-
-template<> EIGEN_STRONG_INLINE Packet4cf pload <Packet4cf>(const std::complex<float>* from) { EIGEN_DEBUG_ALIGNED_LOAD return Packet4cf(pload<Packet8f>(&numext::real_ref(*from))); }
-template<> EIGEN_STRONG_INLINE Packet4cf ploadu<Packet4cf>(const std::complex<float>* from) { EIGEN_DEBUG_UNALIGNED_LOAD return Packet4cf(ploadu<Packet8f>(&numext::real_ref(*from))); }
-
-
-template<> EIGEN_STRONG_INLINE Packet4cf pset1<Packet4cf>(const std::complex<float>& from)
-{
-  return Packet4cf(_mm256_castpd_ps(_mm256_broadcast_sd((const double*)(const void*)&from)));
-}
-
-template<> EIGEN_STRONG_INLINE Packet4cf ploaddup<Packet4cf>(const std::complex<float>* from)
-{
-  // FIXME The following might be optimized using _mm256_movedup_pd
-  Packet2cf a = ploaddup<Packet2cf>(from);
-  Packet2cf b = ploaddup<Packet2cf>(from+1);
-  return  Packet4cf(_mm256_insertf128_ps(_mm256_castps128_ps256(a.v), b.v, 1));
-}
-
-template<> EIGEN_STRONG_INLINE void pstore <std::complex<float> >(std::complex<float>* to, const Packet4cf& from) { EIGEN_DEBUG_ALIGNED_STORE pstore(&numext::real_ref(*to), from.v); }
-template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<float> >(std::complex<float>* to, const Packet4cf& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu(&numext::real_ref(*to), from.v); }
-
-template<> EIGEN_DEVICE_FUNC inline Packet4cf pgather<std::complex<float>, Packet4cf>(const std::complex<float>* from, Index stride)
-{
-  return Packet4cf(_mm256_set_ps(std::imag(from[3*stride]), std::real(from[3*stride]),
-                                 std::imag(from[2*stride]), std::real(from[2*stride]),
-                                 std::imag(from[1*stride]), std::real(from[1*stride]),
-                                 std::imag(from[0*stride]), std::real(from[0*stride])));
-}
-
-template<> EIGEN_DEVICE_FUNC inline void pscatter<std::complex<float>, Packet4cf>(std::complex<float>* to, const Packet4cf& from, Index stride)
-{
-  __m128 low = _mm256_extractf128_ps(from.v, 0);
-  to[stride*0] = std::complex<float>(_mm_cvtss_f32(_mm_shuffle_ps(low, low, 0)),
-                                     _mm_cvtss_f32(_mm_shuffle_ps(low, low, 1)));
-  to[stride*1] = std::complex<float>(_mm_cvtss_f32(_mm_shuffle_ps(low, low, 2)),
-                                     _mm_cvtss_f32(_mm_shuffle_ps(low, low, 3)));
-
-  __m128 high = _mm256_extractf128_ps(from.v, 1);
-  to[stride*2] = std::complex<float>(_mm_cvtss_f32(_mm_shuffle_ps(high, high, 0)),
-                                     _mm_cvtss_f32(_mm_shuffle_ps(high, high, 1)));
-  to[stride*3] = std::complex<float>(_mm_cvtss_f32(_mm_shuffle_ps(high, high, 2)),
-                                     _mm_cvtss_f32(_mm_shuffle_ps(high, high, 3)));
-
-}
-
-template<> EIGEN_STRONG_INLINE std::complex<float>  pfirst<Packet4cf>(const Packet4cf& a)
-{
-  return pfirst(Packet2cf(_mm256_castps256_ps128(a.v)));
-}
-
-template<> EIGEN_STRONG_INLINE Packet4cf preverse(const Packet4cf& a) {
-  __m128 low  = _mm256_extractf128_ps(a.v, 0);
-  __m128 high = _mm256_extractf128_ps(a.v, 1);
-  __m128d lowd  = _mm_castps_pd(low);
-  __m128d highd = _mm_castps_pd(high);
-  low  = _mm_castpd_ps(_mm_shuffle_pd(lowd,lowd,0x1));
-  high = _mm_castpd_ps(_mm_shuffle_pd(highd,highd,0x1));
-  __m256 result = _mm256_setzero_ps();
-  result = _mm256_insertf128_ps(result, low, 1);
-  result = _mm256_insertf128_ps(result, high, 0);
-  return Packet4cf(result);
-}
-
-template<> EIGEN_STRONG_INLINE std::complex<float> predux<Packet4cf>(const Packet4cf& a)
-{
-  return predux(padd(Packet2cf(_mm256_extractf128_ps(a.v,0)),
-                     Packet2cf(_mm256_extractf128_ps(a.v,1))));
-}
-
-template<> EIGEN_STRONG_INLINE Packet4cf preduxp<Packet4cf>(const Packet4cf* vecs)
-{
-  Packet8f t0 = _mm256_shuffle_ps(vecs[0].v, vecs[0].v, _MM_SHUFFLE(3, 1, 2 ,0));
-  Packet8f t1 = _mm256_shuffle_ps(vecs[1].v, vecs[1].v, _MM_SHUFFLE(3, 1, 2 ,0));
-  t0 = _mm256_hadd_ps(t0,t1);
-  Packet8f t2 = _mm256_shuffle_ps(vecs[2].v, vecs[2].v, _MM_SHUFFLE(3, 1, 2 ,0));
-  Packet8f t3 = _mm256_shuffle_ps(vecs[3].v, vecs[3].v, _MM_SHUFFLE(3, 1, 2 ,0));
-  t2 = _mm256_hadd_ps(t2,t3);
-  
-  t1 = _mm256_permute2f128_ps(t0,t2, 0 + (2<<4));
-  t3 = _mm256_permute2f128_ps(t0,t2, 1 + (3<<4));
-
-  return Packet4cf(_mm256_add_ps(t1,t3));
-}
-
-template<> EIGEN_STRONG_INLINE std::complex<float> predux_mul<Packet4cf>(const Packet4cf& a)
-{
-  return predux_mul(pmul(Packet2cf(_mm256_extractf128_ps(a.v, 0)),
-                         Packet2cf(_mm256_extractf128_ps(a.v, 1))));
-}
-
-template<int Offset>
-struct palign_impl<Offset,Packet4cf>
-{
-  static EIGEN_STRONG_INLINE void run(Packet4cf& first, const Packet4cf& second)
-  {
-    if (Offset==0) return;
-    palign_impl<Offset*2,Packet8f>::run(first.v, second.v);
-  }
-};
-
-template<> struct conj_helper<Packet4cf, Packet4cf, false,true>
-{
-  EIGEN_STRONG_INLINE Packet4cf pmadd(const Packet4cf& x, const Packet4cf& y, const Packet4cf& c) const
-  { return padd(pmul(x,y),c); }
-
-  EIGEN_STRONG_INLINE Packet4cf pmul(const Packet4cf& a, const Packet4cf& b) const
-  {
-    return internal::pmul(a, pconj(b));
-  }
-};
-
-template<> struct conj_helper<Packet4cf, Packet4cf, true,false>
-{
-  EIGEN_STRONG_INLINE Packet4cf pmadd(const Packet4cf& x, const Packet4cf& y, const Packet4cf& c) const
-  { return padd(pmul(x,y),c); }
-
-  EIGEN_STRONG_INLINE Packet4cf pmul(const Packet4cf& a, const Packet4cf& b) const
-  {
-    return internal::pmul(pconj(a), b);
-  }
-};
-
-template<> struct conj_helper<Packet4cf, Packet4cf, true,true>
-{
-  EIGEN_STRONG_INLINE Packet4cf pmadd(const Packet4cf& x, const Packet4cf& y, const Packet4cf& c) const
-  { return padd(pmul(x,y),c); }
-
-  EIGEN_STRONG_INLINE Packet4cf pmul(const Packet4cf& a, const Packet4cf& b) const
-  {
-    return pconj(internal::pmul(a, b));
-  }
-};
-
-EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet4cf,Packet8f)
-
-template<> EIGEN_STRONG_INLINE Packet4cf pdiv<Packet4cf>(const Packet4cf& a, const Packet4cf& b)
-{
-  Packet4cf num = pmul(a, pconj(b));
-  __m256 tmp = _mm256_mul_ps(b.v, b.v);
-  __m256 tmp2    = _mm256_shuffle_ps(tmp,tmp,0xB1);
-  __m256 denom = _mm256_add_ps(tmp, tmp2);
-  return Packet4cf(_mm256_div_ps(num.v, denom));
-}
-
-template<> EIGEN_STRONG_INLINE Packet4cf pcplxflip<Packet4cf>(const Packet4cf& x)
-{
-  return Packet4cf(_mm256_shuffle_ps(x.v, x.v, _MM_SHUFFLE(2, 3, 0 ,1)));
-}
-
-//---------- double ----------
-struct Packet2cd
-{
-  EIGEN_STRONG_INLINE Packet2cd() {}
-  EIGEN_STRONG_INLINE explicit Packet2cd(const __m256d& a) : v(a) {}
-  __m256d  v;
-};
-
-template<> struct packet_traits<std::complex<double> >  : default_packet_traits
-{
-  typedef Packet2cd type;
-  typedef Packet1cd half;
-  enum {
-    Vectorizable = 1,
-    AlignedOnScalar = 0,
-    size = 2,
-    HasHalfPacket = 1,
-
-    HasAdd    = 1,
-    HasSub    = 1,
-    HasMul    = 1,
-    HasDiv    = 1,
-    HasNegate = 1,
-    HasAbs    = 0,
-    HasAbs2   = 0,
-    HasMin    = 0,
-    HasMax    = 0,
-    HasSetLinear = 0
-  };
-};
-
-template<> struct unpacket_traits<Packet2cd> { typedef std::complex<double> type; enum {size=2, alignment=Aligned32}; typedef Packet1cd half; };
-
-template<> EIGEN_STRONG_INLINE Packet2cd padd<Packet2cd>(const Packet2cd& a, const Packet2cd& b) { return Packet2cd(_mm256_add_pd(a.v,b.v)); }
-template<> EIGEN_STRONG_INLINE Packet2cd psub<Packet2cd>(const Packet2cd& a, const Packet2cd& b) { return Packet2cd(_mm256_sub_pd(a.v,b.v)); }
-template<> EIGEN_STRONG_INLINE Packet2cd pnegate(const Packet2cd& a) { return Packet2cd(pnegate(a.v)); }
-template<> EIGEN_STRONG_INLINE Packet2cd pconj(const Packet2cd& a)
-{
-  const __m256d mask = _mm256_castsi256_pd(_mm256_set_epi32(0x80000000,0x0,0x0,0x0,0x80000000,0x0,0x0,0x0));
-  return Packet2cd(_mm256_xor_pd(a.v,mask));
-}
-
-template<> EIGEN_STRONG_INLINE Packet2cd pmul<Packet2cd>(const Packet2cd& a, const Packet2cd& b)
-{
-  __m256d tmp1 = _mm256_shuffle_pd(a.v,a.v,0x0);
-  __m256d even = _mm256_mul_pd(tmp1, b.v);
-  __m256d tmp2 = _mm256_shuffle_pd(a.v,a.v,0xF);
-  __m256d tmp3 = _mm256_shuffle_pd(b.v,b.v,0x5);
-  __m256d odd  = _mm256_mul_pd(tmp2, tmp3);
-  return Packet2cd(_mm256_addsub_pd(even, odd));
-}
-
-template<> EIGEN_STRONG_INLINE Packet2cd pand   <Packet2cd>(const Packet2cd& a, const Packet2cd& b) { return Packet2cd(_mm256_and_pd(a.v,b.v)); }
-template<> EIGEN_STRONG_INLINE Packet2cd por    <Packet2cd>(const Packet2cd& a, const Packet2cd& b) { return Packet2cd(_mm256_or_pd(a.v,b.v)); }
-template<> EIGEN_STRONG_INLINE Packet2cd pxor   <Packet2cd>(const Packet2cd& a, const Packet2cd& b) { return Packet2cd(_mm256_xor_pd(a.v,b.v)); }
-template<> EIGEN_STRONG_INLINE Packet2cd pandnot<Packet2cd>(const Packet2cd& a, const Packet2cd& b) { return Packet2cd(_mm256_andnot_pd(a.v,b.v)); }
-
-template<> EIGEN_STRONG_INLINE Packet2cd pload <Packet2cd>(const std::complex<double>* from)
-{ EIGEN_DEBUG_ALIGNED_LOAD return Packet2cd(pload<Packet4d>((const double*)from)); }
-template<> EIGEN_STRONG_INLINE Packet2cd ploadu<Packet2cd>(const std::complex<double>* from)
-{ EIGEN_DEBUG_UNALIGNED_LOAD return Packet2cd(ploadu<Packet4d>((const double*)from)); }
-
-template<> EIGEN_STRONG_INLINE Packet2cd pset1<Packet2cd>(const std::complex<double>& from)
-{
-  // in case casting to a __m128d* is really not safe, then we can still fallback to this version: (much slower though)
-//   return Packet2cd(_mm256_loadu2_m128d((const double*)&from,(const double*)&from));
-    return Packet2cd(_mm256_broadcast_pd((const __m128d*)(const void*)&from));
-}
-
-template<> EIGEN_STRONG_INLINE Packet2cd ploaddup<Packet2cd>(const std::complex<double>* from) { return pset1<Packet2cd>(*from); }
-
-template<> EIGEN_STRONG_INLINE void pstore <std::complex<double> >(std::complex<double> *   to, const Packet2cd& from) { EIGEN_DEBUG_ALIGNED_STORE pstore((double*)to, from.v); }
-template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<double> >(std::complex<double> *   to, const Packet2cd& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((double*)to, from.v); }
-
-template<> EIGEN_DEVICE_FUNC inline Packet2cd pgather<std::complex<double>, Packet2cd>(const std::complex<double>* from, Index stride)
-{
-  return Packet2cd(_mm256_set_pd(std::imag(from[1*stride]), std::real(from[1*stride]),
-				 std::imag(from[0*stride]), std::real(from[0*stride])));
-}
-
-template<> EIGEN_DEVICE_FUNC inline void pscatter<std::complex<double>, Packet2cd>(std::complex<double>* to, const Packet2cd& from, Index stride)
-{
-  __m128d low = _mm256_extractf128_pd(from.v, 0);
-  to[stride*0] = std::complex<double>(_mm_cvtsd_f64(low), _mm_cvtsd_f64(_mm_shuffle_pd(low, low, 1)));
-  __m128d high = _mm256_extractf128_pd(from.v, 1);
-  to[stride*1] = std::complex<double>(_mm_cvtsd_f64(high), _mm_cvtsd_f64(_mm_shuffle_pd(high, high, 1)));
-}
-
-template<> EIGEN_STRONG_INLINE std::complex<double> pfirst<Packet2cd>(const Packet2cd& a)
-{
-  __m128d low = _mm256_extractf128_pd(a.v, 0);
-  EIGEN_ALIGN16 double res[2];
-  _mm_store_pd(res, low);
-  return std::complex<double>(res[0],res[1]);
-}
-
-template<> EIGEN_STRONG_INLINE Packet2cd preverse(const Packet2cd& a) {
-  __m256d result = _mm256_permute2f128_pd(a.v, a.v, 1);
-  return Packet2cd(result);
-}
-
-template<> EIGEN_STRONG_INLINE std::complex<double> predux<Packet2cd>(const Packet2cd& a)
-{
-  return predux(padd(Packet1cd(_mm256_extractf128_pd(a.v,0)),
-                     Packet1cd(_mm256_extractf128_pd(a.v,1))));
-}
-
-template<> EIGEN_STRONG_INLINE Packet2cd preduxp<Packet2cd>(const Packet2cd* vecs)
-{
-  Packet4d t0 = _mm256_permute2f128_pd(vecs[0].v,vecs[1].v, 0 + (2<<4));
-  Packet4d t1 = _mm256_permute2f128_pd(vecs[0].v,vecs[1].v, 1 + (3<<4));
-
-  return Packet2cd(_mm256_add_pd(t0,t1));
-}
-
-template<> EIGEN_STRONG_INLINE std::complex<double> predux_mul<Packet2cd>(const Packet2cd& a)
-{
-  return predux(pmul(Packet1cd(_mm256_extractf128_pd(a.v,0)),
-                     Packet1cd(_mm256_extractf128_pd(a.v,1))));
-}
-
-template<int Offset>
-struct palign_impl<Offset,Packet2cd>
-{
-  static EIGEN_STRONG_INLINE void run(Packet2cd& first, const Packet2cd& second)
-  {
-    if (Offset==0) return;
-    palign_impl<Offset*2,Packet4d>::run(first.v, second.v);
-  }
-};
-
-template<> struct conj_helper<Packet2cd, Packet2cd, false,true>
-{
-  EIGEN_STRONG_INLINE Packet2cd pmadd(const Packet2cd& x, const Packet2cd& y, const Packet2cd& c) const
-  { return padd(pmul(x,y),c); }
-
-  EIGEN_STRONG_INLINE Packet2cd pmul(const Packet2cd& a, const Packet2cd& b) const
-  {
-    return internal::pmul(a, pconj(b));
-  }
-};
-
-template<> struct conj_helper<Packet2cd, Packet2cd, true,false>
-{
-  EIGEN_STRONG_INLINE Packet2cd pmadd(const Packet2cd& x, const Packet2cd& y, const Packet2cd& c) const
-  { return padd(pmul(x,y),c); }
-
-  EIGEN_STRONG_INLINE Packet2cd pmul(const Packet2cd& a, const Packet2cd& b) const
-  {
-    return internal::pmul(pconj(a), b);
-  }
-};
-
-template<> struct conj_helper<Packet2cd, Packet2cd, true,true>
-{
-  EIGEN_STRONG_INLINE Packet2cd pmadd(const Packet2cd& x, const Packet2cd& y, const Packet2cd& c) const
-  { return padd(pmul(x,y),c); }
-
-  EIGEN_STRONG_INLINE Packet2cd pmul(const Packet2cd& a, const Packet2cd& b) const
-  {
-    return pconj(internal::pmul(a, b));
-  }
-};
-
-EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cd,Packet4d)
-
-template<> EIGEN_STRONG_INLINE Packet2cd pdiv<Packet2cd>(const Packet2cd& a, const Packet2cd& b)
-{
-  Packet2cd num = pmul(a, pconj(b));
-  __m256d tmp = _mm256_mul_pd(b.v, b.v);
-  __m256d denom = _mm256_hadd_pd(tmp, tmp);
-  return Packet2cd(_mm256_div_pd(num.v, denom));
-}
-
-template<> EIGEN_STRONG_INLINE Packet2cd pcplxflip<Packet2cd>(const Packet2cd& x)
-{
-  return Packet2cd(_mm256_shuffle_pd(x.v, x.v, 0x5));
-}
-
-EIGEN_DEVICE_FUNC inline void
-ptranspose(PacketBlock<Packet4cf,4>& kernel) {
-  __m256d P0 = _mm256_castps_pd(kernel.packet[0].v);
-  __m256d P1 = _mm256_castps_pd(kernel.packet[1].v);
-  __m256d P2 = _mm256_castps_pd(kernel.packet[2].v);
-  __m256d P3 = _mm256_castps_pd(kernel.packet[3].v);
-
-  __m256d T0 = _mm256_shuffle_pd(P0, P1, 15);
-  __m256d T1 = _mm256_shuffle_pd(P0, P1, 0);
-  __m256d T2 = _mm256_shuffle_pd(P2, P3, 15);
-  __m256d T3 = _mm256_shuffle_pd(P2, P3, 0);
-
-  kernel.packet[1].v = _mm256_castpd_ps(_mm256_permute2f128_pd(T0, T2, 32));
-  kernel.packet[3].v = _mm256_castpd_ps(_mm256_permute2f128_pd(T0, T2, 49));
-  kernel.packet[0].v = _mm256_castpd_ps(_mm256_permute2f128_pd(T1, T3, 32));
-  kernel.packet[2].v = _mm256_castpd_ps(_mm256_permute2f128_pd(T1, T3, 49));
-}
-
-EIGEN_DEVICE_FUNC inline void
-ptranspose(PacketBlock<Packet2cd,2>& kernel) {
-  __m256d tmp = _mm256_permute2f128_pd(kernel.packet[0].v, kernel.packet[1].v, 0+(2<<4));
-  kernel.packet[1].v = _mm256_permute2f128_pd(kernel.packet[0].v, kernel.packet[1].v, 1+(3<<4));
- kernel.packet[0].v = tmp;
-}
-
-template<> EIGEN_STRONG_INLINE Packet4cf pinsertfirst(const Packet4cf& a, std::complex<float> b)
-{
-  return Packet4cf(_mm256_blend_ps(a.v,pset1<Packet4cf>(b).v,1|2));
-}
-
-template<> EIGEN_STRONG_INLINE Packet2cd pinsertfirst(const Packet2cd& a, std::complex<double> b)
-{
-  return Packet2cd(_mm256_blend_pd(a.v,pset1<Packet2cd>(b).v,1|2));
-}
-
-template<> EIGEN_STRONG_INLINE Packet4cf pinsertlast(const Packet4cf& a, std::complex<float> b)
-{
-  return Packet4cf(_mm256_blend_ps(a.v,pset1<Packet4cf>(b).v,(1<<7)|(1<<6)));
-}
-
-template<> EIGEN_STRONG_INLINE Packet2cd pinsertlast(const Packet2cd& a, std::complex<double> b)
-{
-  return Packet2cd(_mm256_blend_pd(a.v,pset1<Packet2cd>(b).v,(1<<3)|(1<<2)));
-}
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_COMPLEX_AVX_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/AVX/MathFunctions.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/AVX/MathFunctions.h
deleted file mode 100644
index 6af67ce..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/AVX/MathFunctions.h
+++ /dev/null
@@ -1,439 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2014 Pedro Gonnet (pedro.gonnet@gmail.com)
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_MATH_FUNCTIONS_AVX_H
-#define EIGEN_MATH_FUNCTIONS_AVX_H
-
-/* The sin, cos, exp, and log functions of this file are loosely derived from
- * Julien Pommier's sse math library: http://gruntthepeon.free.fr/ssemath/
- */
-
-namespace Eigen {
-
-namespace internal {
-
-inline Packet8i pshiftleft(Packet8i v, int n)
-{
-#ifdef EIGEN_VECTORIZE_AVX2
-  return _mm256_slli_epi32(v, n);
-#else
-  __m128i lo = _mm_slli_epi32(_mm256_extractf128_si256(v, 0), n);
-  __m128i hi = _mm_slli_epi32(_mm256_extractf128_si256(v, 1), n);
-  return _mm256_insertf128_si256(_mm256_castsi128_si256(lo), (hi), 1);
-#endif
-}
-
-inline Packet8f pshiftright(Packet8f v, int n)
-{
-#ifdef EIGEN_VECTORIZE_AVX2
-  return _mm256_cvtepi32_ps(_mm256_srli_epi32(_mm256_castps_si256(v), n));
-#else
-  __m128i lo = _mm_srli_epi32(_mm256_extractf128_si256(_mm256_castps_si256(v), 0), n);
-  __m128i hi = _mm_srli_epi32(_mm256_extractf128_si256(_mm256_castps_si256(v), 1), n);
-  return _mm256_cvtepi32_ps(_mm256_insertf128_si256(_mm256_castsi128_si256(lo), (hi), 1));
-#endif
-}
-
-// Sine function
-// Computes sin(x) by wrapping x to the interval [-Pi/4,3*Pi/4] and
-// evaluating interpolants in [-Pi/4,Pi/4] or [Pi/4,3*Pi/4]. The interpolants
-// are (anti-)symmetric and thus have only odd/even coefficients
-template <>
-EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet8f
-psin<Packet8f>(const Packet8f& _x) {
-  Packet8f x = _x;
-
-  // Some useful values.
-  _EIGEN_DECLARE_CONST_Packet8i(one, 1);
-  _EIGEN_DECLARE_CONST_Packet8f(one, 1.0f);
-  _EIGEN_DECLARE_CONST_Packet8f(two, 2.0f);
-  _EIGEN_DECLARE_CONST_Packet8f(one_over_four, 0.25f);
-  _EIGEN_DECLARE_CONST_Packet8f(one_over_pi, 3.183098861837907e-01f);
-  _EIGEN_DECLARE_CONST_Packet8f(neg_pi_first, -3.140625000000000e+00f);
-  _EIGEN_DECLARE_CONST_Packet8f(neg_pi_second, -9.670257568359375e-04f);
-  _EIGEN_DECLARE_CONST_Packet8f(neg_pi_third, -6.278329571784980e-07f);
-  _EIGEN_DECLARE_CONST_Packet8f(four_over_pi, 1.273239544735163e+00f);
-
-  // Map x from [-Pi/4,3*Pi/4] to z in [-1,3] and subtract the shifted period.
-  Packet8f z = pmul(x, p8f_one_over_pi);
-  Packet8f shift = _mm256_floor_ps(padd(z, p8f_one_over_four));
-  x = pmadd(shift, p8f_neg_pi_first, x);
-  x = pmadd(shift, p8f_neg_pi_second, x);
-  x = pmadd(shift, p8f_neg_pi_third, x);
-  z = pmul(x, p8f_four_over_pi);
-
-  // Make a mask for the entries that need flipping, i.e. wherever the shift
-  // is odd.
-  Packet8i shift_ints = _mm256_cvtps_epi32(shift);
-  Packet8i shift_isodd = _mm256_castps_si256(_mm256_and_ps(_mm256_castsi256_ps(shift_ints), _mm256_castsi256_ps(p8i_one)));
-  Packet8i sign_flip_mask = pshiftleft(shift_isodd, 31);
-
-  // Create a mask for which interpolant to use, i.e. if z > 1, then the mask
-  // is set to ones for that entry.
-  Packet8f ival_mask = _mm256_cmp_ps(z, p8f_one, _CMP_GT_OQ);
-
-  // Evaluate the polynomial for the interval [1,3] in z.
-  _EIGEN_DECLARE_CONST_Packet8f(coeff_right_0, 9.999999724233232e-01f);
-  _EIGEN_DECLARE_CONST_Packet8f(coeff_right_2, -3.084242535619928e-01f);
-  _EIGEN_DECLARE_CONST_Packet8f(coeff_right_4, 1.584991525700324e-02f);
-  _EIGEN_DECLARE_CONST_Packet8f(coeff_right_6, -3.188805084631342e-04f);
-  Packet8f z_minus_two = psub(z, p8f_two);
-  Packet8f z_minus_two2 = pmul(z_minus_two, z_minus_two);
-  Packet8f right = pmadd(p8f_coeff_right_6, z_minus_two2, p8f_coeff_right_4);
-  right = pmadd(right, z_minus_two2, p8f_coeff_right_2);
-  right = pmadd(right, z_minus_two2, p8f_coeff_right_0);
-
-  // Evaluate the polynomial for the interval [-1,1] in z.
-  _EIGEN_DECLARE_CONST_Packet8f(coeff_left_1, 7.853981525427295e-01f);
-  _EIGEN_DECLARE_CONST_Packet8f(coeff_left_3, -8.074536727092352e-02f);
-  _EIGEN_DECLARE_CONST_Packet8f(coeff_left_5, 2.489871967827018e-03f);
-  _EIGEN_DECLARE_CONST_Packet8f(coeff_left_7, -3.587725841214251e-05f);
-  Packet8f z2 = pmul(z, z);
-  Packet8f left = pmadd(p8f_coeff_left_7, z2, p8f_coeff_left_5);
-  left = pmadd(left, z2, p8f_coeff_left_3);
-  left = pmadd(left, z2, p8f_coeff_left_1);
-  left = pmul(left, z);
-
-  // Assemble the results, i.e. select the left and right polynomials.
-  left = _mm256_andnot_ps(ival_mask, left);
-  right = _mm256_and_ps(ival_mask, right);
-  Packet8f res = _mm256_or_ps(left, right);
-
-  // Flip the sign on the odd intervals and return the result.
-  res = _mm256_xor_ps(res, _mm256_castsi256_ps(sign_flip_mask));
-  return res;
-}
-
-// Natural logarithm
-// Computes log(x) as log(2^e * m) = C*e + log(m), where the constant C =log(2)
-// and m is in the range [sqrt(1/2),sqrt(2)). In this range, the logarithm can
-// be easily approximated by a polynomial centered on m=1 for stability.
-// TODO(gonnet): Further reduce the interval allowing for lower-degree
-//               polynomial interpolants -> ... -> profit!
-template <>
-EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet8f
-plog<Packet8f>(const Packet8f& _x) {
-  Packet8f x = _x;
-  _EIGEN_DECLARE_CONST_Packet8f(1, 1.0f);
-  _EIGEN_DECLARE_CONST_Packet8f(half, 0.5f);
-  _EIGEN_DECLARE_CONST_Packet8f(126f, 126.0f);
-
-  _EIGEN_DECLARE_CONST_Packet8f_FROM_INT(inv_mant_mask, ~0x7f800000);
-
-  // The smallest non denormalized float number.
-  _EIGEN_DECLARE_CONST_Packet8f_FROM_INT(min_norm_pos, 0x00800000);
-  _EIGEN_DECLARE_CONST_Packet8f_FROM_INT(minus_inf, 0xff800000);
-
-  // Polynomial coefficients.
-  _EIGEN_DECLARE_CONST_Packet8f(cephes_SQRTHF, 0.707106781186547524f);
-  _EIGEN_DECLARE_CONST_Packet8f(cephes_log_p0, 7.0376836292E-2f);
-  _EIGEN_DECLARE_CONST_Packet8f(cephes_log_p1, -1.1514610310E-1f);
-  _EIGEN_DECLARE_CONST_Packet8f(cephes_log_p2, 1.1676998740E-1f);
-  _EIGEN_DECLARE_CONST_Packet8f(cephes_log_p3, -1.2420140846E-1f);
-  _EIGEN_DECLARE_CONST_Packet8f(cephes_log_p4, +1.4249322787E-1f);
-  _EIGEN_DECLARE_CONST_Packet8f(cephes_log_p5, -1.6668057665E-1f);
-  _EIGEN_DECLARE_CONST_Packet8f(cephes_log_p6, +2.0000714765E-1f);
-  _EIGEN_DECLARE_CONST_Packet8f(cephes_log_p7, -2.4999993993E-1f);
-  _EIGEN_DECLARE_CONST_Packet8f(cephes_log_p8, +3.3333331174E-1f);
-  _EIGEN_DECLARE_CONST_Packet8f(cephes_log_q1, -2.12194440e-4f);
-  _EIGEN_DECLARE_CONST_Packet8f(cephes_log_q2, 0.693359375f);
-
-  Packet8f invalid_mask = _mm256_cmp_ps(x, _mm256_setzero_ps(), _CMP_NGE_UQ); // not greater equal is true if x is NaN
-  Packet8f iszero_mask = _mm256_cmp_ps(x, _mm256_setzero_ps(), _CMP_EQ_OQ);
-
-  // Truncate input values to the minimum positive normal.
-  x = pmax(x, p8f_min_norm_pos);
-
-  Packet8f emm0 = pshiftright(x,23);
-  Packet8f e = _mm256_sub_ps(emm0, p8f_126f);
-
-  // Set the exponents to -1, i.e. x are in the range [0.5,1).
-  x = _mm256_and_ps(x, p8f_inv_mant_mask);
-  x = _mm256_or_ps(x, p8f_half);
-
-  // part2: Shift the inputs from the range [0.5,1) to [sqrt(1/2),sqrt(2))
-  // and shift by -1. The values are then centered around 0, which improves
-  // the stability of the polynomial evaluation.
-  //   if( x < SQRTHF ) {
-  //     e -= 1;
-  //     x = x + x - 1.0;
-  //   } else { x = x - 1.0; }
-  Packet8f mask = _mm256_cmp_ps(x, p8f_cephes_SQRTHF, _CMP_LT_OQ);
-  Packet8f tmp = _mm256_and_ps(x, mask);
-  x = psub(x, p8f_1);
-  e = psub(e, _mm256_and_ps(p8f_1, mask));
-  x = padd(x, tmp);
-
-  Packet8f x2 = pmul(x, x);
-  Packet8f x3 = pmul(x2, x);
-
-  // Evaluate the polynomial approximant of degree 8 in three parts, probably
-  // to improve instruction-level parallelism.
-  Packet8f y, y1, y2;
-  y = pmadd(p8f_cephes_log_p0, x, p8f_cephes_log_p1);
-  y1 = pmadd(p8f_cephes_log_p3, x, p8f_cephes_log_p4);
-  y2 = pmadd(p8f_cephes_log_p6, x, p8f_cephes_log_p7);
-  y = pmadd(y, x, p8f_cephes_log_p2);
-  y1 = pmadd(y1, x, p8f_cephes_log_p5);
-  y2 = pmadd(y2, x, p8f_cephes_log_p8);
-  y = pmadd(y, x3, y1);
-  y = pmadd(y, x3, y2);
-  y = pmul(y, x3);
-
-  // Add the logarithm of the exponent back to the result of the interpolation.
-  y1 = pmul(e, p8f_cephes_log_q1);
-  tmp = pmul(x2, p8f_half);
-  y = padd(y, y1);
-  x = psub(x, tmp);
-  y2 = pmul(e, p8f_cephes_log_q2);
-  x = padd(x, y);
-  x = padd(x, y2);
-
-  // Filter out invalid inputs, i.e. negative arg will be NAN, 0 will be -INF.
-  return _mm256_or_ps(
-      _mm256_andnot_ps(iszero_mask, _mm256_or_ps(x, invalid_mask)),
-      _mm256_and_ps(iszero_mask, p8f_minus_inf));
-}
-
-// Exponential function. Works by writing "x = m*log(2) + r" where
-// "m = floor(x/log(2)+1/2)" and "r" is the remainder. The result is then
-// "exp(x) = 2^m*exp(r)" where exp(r) is in the range [-1,1).
-template <>
-EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet8f
-pexp<Packet8f>(const Packet8f& _x) {
-  _EIGEN_DECLARE_CONST_Packet8f(1, 1.0f);
-  _EIGEN_DECLARE_CONST_Packet8f(half, 0.5f);
-  _EIGEN_DECLARE_CONST_Packet8f(127, 127.0f);
-
-  _EIGEN_DECLARE_CONST_Packet8f(exp_hi, 88.3762626647950f);
-  _EIGEN_DECLARE_CONST_Packet8f(exp_lo, -88.3762626647949f);
-
-  _EIGEN_DECLARE_CONST_Packet8f(cephes_LOG2EF, 1.44269504088896341f);
-
-  _EIGEN_DECLARE_CONST_Packet8f(cephes_exp_p0, 1.9875691500E-4f);
-  _EIGEN_DECLARE_CONST_Packet8f(cephes_exp_p1, 1.3981999507E-3f);
-  _EIGEN_DECLARE_CONST_Packet8f(cephes_exp_p2, 8.3334519073E-3f);
-  _EIGEN_DECLARE_CONST_Packet8f(cephes_exp_p3, 4.1665795894E-2f);
-  _EIGEN_DECLARE_CONST_Packet8f(cephes_exp_p4, 1.6666665459E-1f);
-  _EIGEN_DECLARE_CONST_Packet8f(cephes_exp_p5, 5.0000001201E-1f);
-
-  // Clamp x.
-  Packet8f x = pmax(pmin(_x, p8f_exp_hi), p8f_exp_lo);
-
-  // Express exp(x) as exp(m*ln(2) + r), start by extracting
-  // m = floor(x/ln(2) + 0.5).
-  Packet8f m = _mm256_floor_ps(pmadd(x, p8f_cephes_LOG2EF, p8f_half));
-
-// Get r = x - m*ln(2). If no FMA instructions are available, m*ln(2) is
-// subtracted out in two parts, m*C1+m*C2 = m*ln(2), to avoid accumulating
-// truncation errors. Note that we don't use the "pmadd" function here to
-// ensure that a precision-preserving FMA instruction is used.
-#ifdef EIGEN_VECTORIZE_FMA
-  _EIGEN_DECLARE_CONST_Packet8f(nln2, -0.6931471805599453f);
-  Packet8f r = _mm256_fmadd_ps(m, p8f_nln2, x);
-#else
-  _EIGEN_DECLARE_CONST_Packet8f(cephes_exp_C1, 0.693359375f);
-  _EIGEN_DECLARE_CONST_Packet8f(cephes_exp_C2, -2.12194440e-4f);
-  Packet8f r = psub(x, pmul(m, p8f_cephes_exp_C1));
-  r = psub(r, pmul(m, p8f_cephes_exp_C2));
-#endif
-
-  Packet8f r2 = pmul(r, r);
-
-  // TODO(gonnet): Split into odd/even polynomials and try to exploit
-  //               instruction-level parallelism.
-  Packet8f y = p8f_cephes_exp_p0;
-  y = pmadd(y, r, p8f_cephes_exp_p1);
-  y = pmadd(y, r, p8f_cephes_exp_p2);
-  y = pmadd(y, r, p8f_cephes_exp_p3);
-  y = pmadd(y, r, p8f_cephes_exp_p4);
-  y = pmadd(y, r, p8f_cephes_exp_p5);
-  y = pmadd(y, r2, r);
-  y = padd(y, p8f_1);
-
-  // Build emm0 = 2^m.
-  Packet8i emm0 = _mm256_cvttps_epi32(padd(m, p8f_127));
-  emm0 = pshiftleft(emm0, 23);
-
-  // Return 2^m * exp(r).
-  return pmax(pmul(y, _mm256_castsi256_ps(emm0)), _x);
-}
-
-// Hyperbolic Tangent function.
-template <>
-EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet8f
-ptanh<Packet8f>(const Packet8f& x) {
-  return internal::generic_fast_tanh_float(x);
-}
-
-template <>
-EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet4d
-pexp<Packet4d>(const Packet4d& _x) {
-  Packet4d x = _x;
-
-  _EIGEN_DECLARE_CONST_Packet4d(1, 1.0);
-  _EIGEN_DECLARE_CONST_Packet4d(2, 2.0);
-  _EIGEN_DECLARE_CONST_Packet4d(half, 0.5);
-
-  _EIGEN_DECLARE_CONST_Packet4d(exp_hi, 709.437);
-  _EIGEN_DECLARE_CONST_Packet4d(exp_lo, -709.436139303);
-
-  _EIGEN_DECLARE_CONST_Packet4d(cephes_LOG2EF, 1.4426950408889634073599);
-
-  _EIGEN_DECLARE_CONST_Packet4d(cephes_exp_p0, 1.26177193074810590878e-4);
-  _EIGEN_DECLARE_CONST_Packet4d(cephes_exp_p1, 3.02994407707441961300e-2);
-  _EIGEN_DECLARE_CONST_Packet4d(cephes_exp_p2, 9.99999999999999999910e-1);
-
-  _EIGEN_DECLARE_CONST_Packet4d(cephes_exp_q0, 3.00198505138664455042e-6);
-  _EIGEN_DECLARE_CONST_Packet4d(cephes_exp_q1, 2.52448340349684104192e-3);
-  _EIGEN_DECLARE_CONST_Packet4d(cephes_exp_q2, 2.27265548208155028766e-1);
-  _EIGEN_DECLARE_CONST_Packet4d(cephes_exp_q3, 2.00000000000000000009e0);
-
-  _EIGEN_DECLARE_CONST_Packet4d(cephes_exp_C1, 0.693145751953125);
-  _EIGEN_DECLARE_CONST_Packet4d(cephes_exp_C2, 1.42860682030941723212e-6);
-  _EIGEN_DECLARE_CONST_Packet4i(1023, 1023);
-
-  Packet4d tmp, fx;
-
-  // clamp x
-  x = pmax(pmin(x, p4d_exp_hi), p4d_exp_lo);
-  // Express exp(x) as exp(g + n*log(2)).
-  fx = pmadd(p4d_cephes_LOG2EF, x, p4d_half);
-
-  // Get the integer modulus of log(2), i.e. the "n" described above.
-  fx = _mm256_floor_pd(fx);
-
-  // Get the remainder modulo log(2), i.e. the "g" described above. Subtract
-  // n*log(2) out in two steps, i.e. n*C1 + n*C2, C1+C2=log2 to get the last
-  // digits right.
-  tmp = pmul(fx, p4d_cephes_exp_C1);
-  Packet4d z = pmul(fx, p4d_cephes_exp_C2);
-  x = psub(x, tmp);
-  x = psub(x, z);
-
-  Packet4d x2 = pmul(x, x);
-
-  // Evaluate the numerator polynomial of the rational interpolant.
-  Packet4d px = p4d_cephes_exp_p0;
-  px = pmadd(px, x2, p4d_cephes_exp_p1);
-  px = pmadd(px, x2, p4d_cephes_exp_p2);
-  px = pmul(px, x);
-
-  // Evaluate the denominator polynomial of the rational interpolant.
-  Packet4d qx = p4d_cephes_exp_q0;
-  qx = pmadd(qx, x2, p4d_cephes_exp_q1);
-  qx = pmadd(qx, x2, p4d_cephes_exp_q2);
-  qx = pmadd(qx, x2, p4d_cephes_exp_q3);
-
-  // I don't really get this bit, copied from the SSE2 routines, so...
-  // TODO(gonnet): Figure out what is going on here, perhaps find a better
-  // rational interpolant?
-  x = _mm256_div_pd(px, psub(qx, px));
-  x = pmadd(p4d_2, x, p4d_1);
-
-  // Build e=2^n by constructing the exponents in a 128-bit vector and
-  // shifting them to where they belong in double-precision values.
-  __m128i emm0 = _mm256_cvtpd_epi32(fx);
-  emm0 = _mm_add_epi32(emm0, p4i_1023);
-  emm0 = _mm_shuffle_epi32(emm0, _MM_SHUFFLE(3, 1, 2, 0));
-  __m128i lo = _mm_slli_epi64(emm0, 52);
-  __m128i hi = _mm_slli_epi64(_mm_srli_epi64(emm0, 32), 52);
-  __m256i e = _mm256_insertf128_si256(_mm256_setzero_si256(), lo, 0);
-  e = _mm256_insertf128_si256(e, hi, 1);
-
-  // Construct the result 2^n * exp(g) = e * x. The max is used to catch
-  // non-finite values in the input.
-  return pmax(pmul(x, _mm256_castsi256_pd(e)), _x);
-}
-
-// Functions for sqrt.
-// The EIGEN_FAST_MATH version uses the _mm_rsqrt_ps approximation and one step
-// of Newton's method, at a cost of 1-2 bits of precision as opposed to the
-// exact solution. It does not handle +inf, or denormalized numbers correctly.
-// The main advantage of this approach is not just speed, but also the fact that
-// it can be inlined and pipelined with other computations, further reducing its
-// effective latency. This is similar to Quake3's fast inverse square root.
-// For detail see here: http://www.beyond3d.com/content/articles/8/
-#if EIGEN_FAST_MATH
-template <>
-EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet8f
-psqrt<Packet8f>(const Packet8f& _x) {
-  Packet8f half = pmul(_x, pset1<Packet8f>(.5f));
-  Packet8f denormal_mask = _mm256_and_ps(
-      _mm256_cmp_ps(_x, pset1<Packet8f>((std::numeric_limits<float>::min)()),
-                    _CMP_LT_OQ),
-      _mm256_cmp_ps(_x, _mm256_setzero_ps(), _CMP_GE_OQ));
-
-  // Compute approximate reciprocal sqrt.
-  Packet8f x = _mm256_rsqrt_ps(_x);
-  // Do a single step of Newton's iteration.
-  x = pmul(x, psub(pset1<Packet8f>(1.5f), pmul(half, pmul(x,x))));
-  // Flush results for denormals to zero.
-  return _mm256_andnot_ps(denormal_mask, pmul(_x,x));
-}
-#else
-template <> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
-Packet8f psqrt<Packet8f>(const Packet8f& x) {
-  return _mm256_sqrt_ps(x);
-}
-#endif
-template <> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
-Packet4d psqrt<Packet4d>(const Packet4d& x) {
-  return _mm256_sqrt_pd(x);
-}
-#if EIGEN_FAST_MATH
-
-template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
-Packet8f prsqrt<Packet8f>(const Packet8f& _x) {
-  _EIGEN_DECLARE_CONST_Packet8f_FROM_INT(inf, 0x7f800000);
-  _EIGEN_DECLARE_CONST_Packet8f_FROM_INT(nan, 0x7fc00000);
-  _EIGEN_DECLARE_CONST_Packet8f(one_point_five, 1.5f);
-  _EIGEN_DECLARE_CONST_Packet8f(minus_half, -0.5f);
-  _EIGEN_DECLARE_CONST_Packet8f_FROM_INT(flt_min, 0x00800000);
-
-  Packet8f neg_half = pmul(_x, p8f_minus_half);
-
-  // select only the inverse sqrt of positive normal inputs (denormals are
-  // flushed to zero and cause infs as well).
-  Packet8f le_zero_mask = _mm256_cmp_ps(_x, p8f_flt_min, _CMP_LT_OQ);
-  Packet8f x = _mm256_andnot_ps(le_zero_mask, _mm256_rsqrt_ps(_x));
-
-  // Fill in NaNs and Infs for the negative/zero entries.
-  Packet8f neg_mask = _mm256_cmp_ps(_x, _mm256_setzero_ps(), _CMP_LT_OQ);
-  Packet8f zero_mask = _mm256_andnot_ps(neg_mask, le_zero_mask);
-  Packet8f infs_and_nans = _mm256_or_ps(_mm256_and_ps(neg_mask, p8f_nan),
-                                        _mm256_and_ps(zero_mask, p8f_inf));
-
-  // Do a single step of Newton's iteration.
-  x = pmul(x, pmadd(neg_half, pmul(x, x), p8f_one_point_five));
-
-  // Insert NaNs and Infs in all the right places.
-  return _mm256_or_ps(x, infs_and_nans);
-}
-
-#else
-template <> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
-Packet8f prsqrt<Packet8f>(const Packet8f& x) {
-  _EIGEN_DECLARE_CONST_Packet8f(one, 1.0f);
-  return _mm256_div_ps(p8f_one, _mm256_sqrt_ps(x));
-}
-#endif
-
-template <> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
-Packet4d prsqrt<Packet4d>(const Packet4d& x) {
-  _EIGEN_DECLARE_CONST_Packet4d(one, 1.0);
-  return _mm256_div_pd(p4d_one, _mm256_sqrt_pd(x));
-}
-
-
-}  // end namespace internal
-
-}  // end namespace Eigen
-
-#endif  // EIGEN_MATH_FUNCTIONS_AVX_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/AVX/PacketMath.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/AVX/PacketMath.h
deleted file mode 100644
index 923a124..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/AVX/PacketMath.h
+++ /dev/null
@@ -1,637 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2014 Benoit Steiner (benoit.steiner.goog@gmail.com)
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_PACKET_MATH_AVX_H
-#define EIGEN_PACKET_MATH_AVX_H
-
-namespace Eigen {
-
-namespace internal {
-
-#ifndef EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD
-#define EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD 8
-#endif
-
-#ifndef EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS
-#define EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS (2*sizeof(void*))
-#endif
-
-#ifdef __FMA__
-#ifndef EIGEN_HAS_SINGLE_INSTRUCTION_MADD
-#define EIGEN_HAS_SINGLE_INSTRUCTION_MADD
-#endif
-#endif
-
-typedef __m256  Packet8f;
-typedef __m256i Packet8i;
-typedef __m256d Packet4d;
-
-template<> struct is_arithmetic<__m256>  { enum { value = true }; };
-template<> struct is_arithmetic<__m256i> { enum { value = true }; };
-template<> struct is_arithmetic<__m256d> { enum { value = true }; };
-
-#define _EIGEN_DECLARE_CONST_Packet8f(NAME,X) \
-  const Packet8f p8f_##NAME = pset1<Packet8f>(X)
-
-#define _EIGEN_DECLARE_CONST_Packet4d(NAME,X) \
-  const Packet4d p4d_##NAME = pset1<Packet4d>(X)
-
-#define _EIGEN_DECLARE_CONST_Packet8f_FROM_INT(NAME,X) \
-  const Packet8f p8f_##NAME = _mm256_castsi256_ps(pset1<Packet8i>(X))
-
-#define _EIGEN_DECLARE_CONST_Packet8i(NAME,X) \
-  const Packet8i p8i_##NAME = pset1<Packet8i>(X)
-
-// Use the packet_traits defined in AVX512/PacketMath.h instead if we're going
-// to leverage AVX512 instructions.
-#ifndef EIGEN_VECTORIZE_AVX512
-template<> struct packet_traits<float>  : default_packet_traits
-{
-  typedef Packet8f type;
-  typedef Packet4f half;
-  enum {
-    Vectorizable = 1,
-    AlignedOnScalar = 1,
-    size=8,
-    HasHalfPacket = 1,
-
-    HasDiv  = 1,
-    HasSin  = EIGEN_FAST_MATH,
-    HasCos  = 0,
-    HasLog  = 1,
-    HasExp  = 1,
-    HasSqrt = 1,
-    HasRsqrt = 1,
-    HasTanh  = EIGEN_FAST_MATH,
-    HasBlend = 1,
-    HasRound = 1,
-    HasFloor = 1,
-    HasCeil = 1
-  };
-};
-template<> struct packet_traits<double> : default_packet_traits
-{
-  typedef Packet4d type;
-  typedef Packet2d half;
-  enum {
-    Vectorizable = 1,
-    AlignedOnScalar = 1,
-    size=4,
-    HasHalfPacket = 1,
-
-    HasDiv  = 1,
-    HasExp  = 1,
-    HasSqrt = 1,
-    HasRsqrt = 1,
-    HasBlend = 1,
-    HasRound = 1,
-    HasFloor = 1,
-    HasCeil = 1
-  };
-};
-#endif
-
-template<> struct scalar_div_cost<float,true> { enum { value = 14 }; };
-template<> struct scalar_div_cost<double,true> { enum { value = 16 }; };
-
-/* Proper support for integers is only provided by AVX2. In the meantime, we'll
-   use SSE instructions and packets to deal with integers.
-template<> struct packet_traits<int>    : default_packet_traits
-{
-  typedef Packet8i type;
-  enum {
-    Vectorizable = 1,
-    AlignedOnScalar = 1,
-    size=8
-  };
-};
-*/
-
-template<> struct unpacket_traits<Packet8f> { typedef float  type; typedef Packet4f half; enum {size=8, alignment=Aligned32}; };
-template<> struct unpacket_traits<Packet4d> { typedef double type; typedef Packet2d half; enum {size=4, alignment=Aligned32}; };
-template<> struct unpacket_traits<Packet8i> { typedef int    type; typedef Packet4i half; enum {size=8, alignment=Aligned32}; };
-
-template<> EIGEN_STRONG_INLINE Packet8f pset1<Packet8f>(const float&  from) { return _mm256_set1_ps(from); }
-template<> EIGEN_STRONG_INLINE Packet4d pset1<Packet4d>(const double& from) { return _mm256_set1_pd(from); }
-template<> EIGEN_STRONG_INLINE Packet8i pset1<Packet8i>(const int&    from) { return _mm256_set1_epi32(from); }
-
-template<> EIGEN_STRONG_INLINE Packet8f pload1<Packet8f>(const float*  from) { return _mm256_broadcast_ss(from); }
-template<> EIGEN_STRONG_INLINE Packet4d pload1<Packet4d>(const double* from) { return _mm256_broadcast_sd(from); }
-
-template<> EIGEN_STRONG_INLINE Packet8f plset<Packet8f>(const float& a) { return _mm256_add_ps(_mm256_set1_ps(a), _mm256_set_ps(7.0,6.0,5.0,4.0,3.0,2.0,1.0,0.0)); }
-template<> EIGEN_STRONG_INLINE Packet4d plset<Packet4d>(const double& a) { return _mm256_add_pd(_mm256_set1_pd(a), _mm256_set_pd(3.0,2.0,1.0,0.0)); }
-
-template<> EIGEN_STRONG_INLINE Packet8f padd<Packet8f>(const Packet8f& a, const Packet8f& b) { return _mm256_add_ps(a,b); }
-template<> EIGEN_STRONG_INLINE Packet4d padd<Packet4d>(const Packet4d& a, const Packet4d& b) { return _mm256_add_pd(a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet8f psub<Packet8f>(const Packet8f& a, const Packet8f& b) { return _mm256_sub_ps(a,b); }
-template<> EIGEN_STRONG_INLINE Packet4d psub<Packet4d>(const Packet4d& a, const Packet4d& b) { return _mm256_sub_pd(a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet8f pnegate(const Packet8f& a)
-{
-  return _mm256_sub_ps(_mm256_set1_ps(0.0),a);
-}
-template<> EIGEN_STRONG_INLINE Packet4d pnegate(const Packet4d& a)
-{
-  return _mm256_sub_pd(_mm256_set1_pd(0.0),a);
-}
-
-template<> EIGEN_STRONG_INLINE Packet8f pconj(const Packet8f& a) { return a; }
-template<> EIGEN_STRONG_INLINE Packet4d pconj(const Packet4d& a) { return a; }
-template<> EIGEN_STRONG_INLINE Packet8i pconj(const Packet8i& a) { return a; }
-
-template<> EIGEN_STRONG_INLINE Packet8f pmul<Packet8f>(const Packet8f& a, const Packet8f& b) { return _mm256_mul_ps(a,b); }
-template<> EIGEN_STRONG_INLINE Packet4d pmul<Packet4d>(const Packet4d& a, const Packet4d& b) { return _mm256_mul_pd(a,b); }
-
-
-template<> EIGEN_STRONG_INLINE Packet8f pdiv<Packet8f>(const Packet8f& a, const Packet8f& b) { return _mm256_div_ps(a,b); }
-template<> EIGEN_STRONG_INLINE Packet4d pdiv<Packet4d>(const Packet4d& a, const Packet4d& b) { return _mm256_div_pd(a,b); }
-template<> EIGEN_STRONG_INLINE Packet8i pdiv<Packet8i>(const Packet8i& /*a*/, const Packet8i& /*b*/)
-{ eigen_assert(false && "packet integer division are not supported by AVX");
-  return pset1<Packet8i>(0);
-}
-
-#ifdef __FMA__
-template<> EIGEN_STRONG_INLINE Packet8f pmadd(const Packet8f& a, const Packet8f& b, const Packet8f& c) {
-#if ( (EIGEN_COMP_GNUC_STRICT && EIGEN_COMP_GNUC<80) || (EIGEN_COMP_CLANG) )
-  // Clang stupidly generates a vfmadd213ps instruction plus some vmovaps on registers,
-  //  and even register spilling with clang>=6.0 (bug 1637).
-  // Gcc stupidly generates a vfmadd132ps instruction.
-  // So let's enforce it to generate a vfmadd231ps instruction since the most common use
-  //  case is to accumulate the result of the product.
-  Packet8f res = c;
-  __asm__("vfmadd231ps %[a], %[b], %[c]" : [c] "+x" (res) : [a] "x" (a), [b] "x" (b));
-  return res;
-#else
-  return _mm256_fmadd_ps(a,b,c);
-#endif
-}
-template<> EIGEN_STRONG_INLINE Packet4d pmadd(const Packet4d& a, const Packet4d& b, const Packet4d& c) {
-#if ( (EIGEN_COMP_GNUC_STRICT && EIGEN_COMP_GNUC<80) || (EIGEN_COMP_CLANG) )
-  // see above
-  Packet4d res = c;
-  __asm__("vfmadd231pd %[a], %[b], %[c]" : [c] "+x" (res) : [a] "x" (a), [b] "x" (b));
-  return res;
-#else
-  return _mm256_fmadd_pd(a,b,c);
-#endif
-}
-#endif
-
-template<> EIGEN_STRONG_INLINE Packet8f pmin<Packet8f>(const Packet8f& a, const Packet8f& b) { return _mm256_min_ps(a,b); }
-template<> EIGEN_STRONG_INLINE Packet4d pmin<Packet4d>(const Packet4d& a, const Packet4d& b) { return _mm256_min_pd(a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet8f pmax<Packet8f>(const Packet8f& a, const Packet8f& b) { return _mm256_max_ps(a,b); }
-template<> EIGEN_STRONG_INLINE Packet4d pmax<Packet4d>(const Packet4d& a, const Packet4d& b) { return _mm256_max_pd(a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet8f pround<Packet8f>(const Packet8f& a) { return _mm256_round_ps(a, _MM_FROUND_CUR_DIRECTION); }
-template<> EIGEN_STRONG_INLINE Packet4d pround<Packet4d>(const Packet4d& a) { return _mm256_round_pd(a, _MM_FROUND_CUR_DIRECTION); }
-
-template<> EIGEN_STRONG_INLINE Packet8f pceil<Packet8f>(const Packet8f& a) { return _mm256_ceil_ps(a); }
-template<> EIGEN_STRONG_INLINE Packet4d pceil<Packet4d>(const Packet4d& a) { return _mm256_ceil_pd(a); }
-
-template<> EIGEN_STRONG_INLINE Packet8f pfloor<Packet8f>(const Packet8f& a) { return _mm256_floor_ps(a); }
-template<> EIGEN_STRONG_INLINE Packet4d pfloor<Packet4d>(const Packet4d& a) { return _mm256_floor_pd(a); }
-
-template<> EIGEN_STRONG_INLINE Packet8f pand<Packet8f>(const Packet8f& a, const Packet8f& b) { return _mm256_and_ps(a,b); }
-template<> EIGEN_STRONG_INLINE Packet4d pand<Packet4d>(const Packet4d& a, const Packet4d& b) { return _mm256_and_pd(a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet8f por<Packet8f>(const Packet8f& a, const Packet8f& b) { return _mm256_or_ps(a,b); }
-template<> EIGEN_STRONG_INLINE Packet4d por<Packet4d>(const Packet4d& a, const Packet4d& b) { return _mm256_or_pd(a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet8f pxor<Packet8f>(const Packet8f& a, const Packet8f& b) { return _mm256_xor_ps(a,b); }
-template<> EIGEN_STRONG_INLINE Packet4d pxor<Packet4d>(const Packet4d& a, const Packet4d& b) { return _mm256_xor_pd(a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet8f pandnot<Packet8f>(const Packet8f& a, const Packet8f& b) { return _mm256_andnot_ps(a,b); }
-template<> EIGEN_STRONG_INLINE Packet4d pandnot<Packet4d>(const Packet4d& a, const Packet4d& b) { return _mm256_andnot_pd(a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet8f pload<Packet8f>(const float*   from) { EIGEN_DEBUG_ALIGNED_LOAD return _mm256_load_ps(from); }
-template<> EIGEN_STRONG_INLINE Packet4d pload<Packet4d>(const double*  from) { EIGEN_DEBUG_ALIGNED_LOAD return _mm256_load_pd(from); }
-template<> EIGEN_STRONG_INLINE Packet8i pload<Packet8i>(const int*     from) { EIGEN_DEBUG_ALIGNED_LOAD return _mm256_load_si256(reinterpret_cast<const __m256i*>(from)); }
-
-template<> EIGEN_STRONG_INLINE Packet8f ploadu<Packet8f>(const float* from) { EIGEN_DEBUG_UNALIGNED_LOAD return _mm256_loadu_ps(from); }
-template<> EIGEN_STRONG_INLINE Packet4d ploadu<Packet4d>(const double* from) { EIGEN_DEBUG_UNALIGNED_LOAD return _mm256_loadu_pd(from); }
-template<> EIGEN_STRONG_INLINE Packet8i ploadu<Packet8i>(const int* from) { EIGEN_DEBUG_UNALIGNED_LOAD return _mm256_loadu_si256(reinterpret_cast<const __m256i*>(from)); }
-
-// Loads 4 floats from memory a returns the packet {a0, a0  a1, a1, a2, a2, a3, a3}
-template<> EIGEN_STRONG_INLINE Packet8f ploaddup<Packet8f>(const float* from)
-{
-  // TODO try to find a way to avoid the need of a temporary register
-//   Packet8f tmp  = _mm256_castps128_ps256(_mm_loadu_ps(from));
-//   tmp = _mm256_insertf128_ps(tmp, _mm_movehl_ps(_mm256_castps256_ps128(tmp),_mm256_castps256_ps128(tmp)), 1);
-//   return _mm256_unpacklo_ps(tmp,tmp);
-  
-  // _mm256_insertf128_ps is very slow on Haswell, thus:
-  Packet8f tmp = _mm256_broadcast_ps((const __m128*)(const void*)from);
-  // mimic an "inplace" permutation of the lower 128bits using a blend
-  tmp = _mm256_blend_ps(tmp,_mm256_castps128_ps256(_mm_permute_ps( _mm256_castps256_ps128(tmp), _MM_SHUFFLE(1,0,1,0))), 15);
-  // then we can perform a consistent permutation on the global register to get everything in shape:
-  return  _mm256_permute_ps(tmp, _MM_SHUFFLE(3,3,2,2));
-}
-// Loads 2 doubles from memory a returns the packet {a0, a0  a1, a1}
-template<> EIGEN_STRONG_INLINE Packet4d ploaddup<Packet4d>(const double* from)
-{
-  Packet4d tmp = _mm256_broadcast_pd((const __m128d*)(const void*)from);
-  return  _mm256_permute_pd(tmp, 3<<2);
-}
-
-// Loads 2 floats from memory a returns the packet {a0, a0  a0, a0, a1, a1, a1, a1}
-template<> EIGEN_STRONG_INLINE Packet8f ploadquad<Packet8f>(const float* from)
-{
-  Packet8f tmp = _mm256_castps128_ps256(_mm_broadcast_ss(from));
-  return _mm256_insertf128_ps(tmp, _mm_broadcast_ss(from+1), 1);
-}
-
-template<> EIGEN_STRONG_INLINE void pstore<float>(float*   to, const Packet8f& from) { EIGEN_DEBUG_ALIGNED_STORE _mm256_store_ps(to, from); }
-template<> EIGEN_STRONG_INLINE void pstore<double>(double* to, const Packet4d& from) { EIGEN_DEBUG_ALIGNED_STORE _mm256_store_pd(to, from); }
-template<> EIGEN_STRONG_INLINE void pstore<int>(int*       to, const Packet8i& from) { EIGEN_DEBUG_ALIGNED_STORE _mm256_storeu_si256(reinterpret_cast<__m256i*>(to), from); }
-
-template<> EIGEN_STRONG_INLINE void pstoreu<float>(float*   to, const Packet8f& from) { EIGEN_DEBUG_UNALIGNED_STORE _mm256_storeu_ps(to, from); }
-template<> EIGEN_STRONG_INLINE void pstoreu<double>(double* to, const Packet4d& from) { EIGEN_DEBUG_UNALIGNED_STORE _mm256_storeu_pd(to, from); }
-template<> EIGEN_STRONG_INLINE void pstoreu<int>(int*       to, const Packet8i& from) { EIGEN_DEBUG_UNALIGNED_STORE _mm256_storeu_si256(reinterpret_cast<__m256i*>(to), from); }
-
-// NOTE: leverage _mm256_i32gather_ps and _mm256_i32gather_pd if AVX2 instructions are available
-// NOTE: for the record the following seems to be slower: return _mm256_i32gather_ps(from, _mm256_set1_epi32(stride), 4);
-template<> EIGEN_DEVICE_FUNC inline Packet8f pgather<float, Packet8f>(const float* from, Index stride)
-{
-  return _mm256_set_ps(from[7*stride], from[6*stride], from[5*stride], from[4*stride],
-                       from[3*stride], from[2*stride], from[1*stride], from[0*stride]);
-}
-template<> EIGEN_DEVICE_FUNC inline Packet4d pgather<double, Packet4d>(const double* from, Index stride)
-{
-  return _mm256_set_pd(from[3*stride], from[2*stride], from[1*stride], from[0*stride]);
-}
-
-template<> EIGEN_DEVICE_FUNC inline void pscatter<float, Packet8f>(float* to, const Packet8f& from, Index stride)
-{
-  __m128 low = _mm256_extractf128_ps(from, 0);
-  to[stride*0] = _mm_cvtss_f32(low);
-  to[stride*1] = _mm_cvtss_f32(_mm_shuffle_ps(low, low, 1));
-  to[stride*2] = _mm_cvtss_f32(_mm_shuffle_ps(low, low, 2));
-  to[stride*3] = _mm_cvtss_f32(_mm_shuffle_ps(low, low, 3));
-
-  __m128 high = _mm256_extractf128_ps(from, 1);
-  to[stride*4] = _mm_cvtss_f32(high);
-  to[stride*5] = _mm_cvtss_f32(_mm_shuffle_ps(high, high, 1));
-  to[stride*6] = _mm_cvtss_f32(_mm_shuffle_ps(high, high, 2));
-  to[stride*7] = _mm_cvtss_f32(_mm_shuffle_ps(high, high, 3));
-}
-template<> EIGEN_DEVICE_FUNC inline void pscatter<double, Packet4d>(double* to, const Packet4d& from, Index stride)
-{
-  __m128d low = _mm256_extractf128_pd(from, 0);
-  to[stride*0] = _mm_cvtsd_f64(low);
-  to[stride*1] = _mm_cvtsd_f64(_mm_shuffle_pd(low, low, 1));
-  __m128d high = _mm256_extractf128_pd(from, 1);
-  to[stride*2] = _mm_cvtsd_f64(high);
-  to[stride*3] = _mm_cvtsd_f64(_mm_shuffle_pd(high, high, 1));
-}
-
-template<> EIGEN_STRONG_INLINE void pstore1<Packet8f>(float* to, const float& a)
-{
-  Packet8f pa = pset1<Packet8f>(a);
-  pstore(to, pa);
-}
-template<> EIGEN_STRONG_INLINE void pstore1<Packet4d>(double* to, const double& a)
-{
-  Packet4d pa = pset1<Packet4d>(a);
-  pstore(to, pa);
-}
-template<> EIGEN_STRONG_INLINE void pstore1<Packet8i>(int* to, const int& a)
-{
-  Packet8i pa = pset1<Packet8i>(a);
-  pstore(to, pa);
-}
-
-#ifndef EIGEN_VECTORIZE_AVX512
-template<> EIGEN_STRONG_INLINE void prefetch<float>(const float*   addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); }
-template<> EIGEN_STRONG_INLINE void prefetch<double>(const double* addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); }
-template<> EIGEN_STRONG_INLINE void prefetch<int>(const int*       addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); }
-#endif
-
-template<> EIGEN_STRONG_INLINE float  pfirst<Packet8f>(const Packet8f& a) {
-  return _mm_cvtss_f32(_mm256_castps256_ps128(a));
-}
-template<> EIGEN_STRONG_INLINE double pfirst<Packet4d>(const Packet4d& a) {
-  return _mm_cvtsd_f64(_mm256_castpd256_pd128(a));
-}
-template<> EIGEN_STRONG_INLINE int    pfirst<Packet8i>(const Packet8i& a) {
-  return _mm_cvtsi128_si32(_mm256_castsi256_si128(a));
-}
-
-
-template<> EIGEN_STRONG_INLINE Packet8f preverse(const Packet8f& a)
-{
-  __m256 tmp = _mm256_shuffle_ps(a,a,0x1b);
-  return _mm256_permute2f128_ps(tmp, tmp, 1);
-}
-template<> EIGEN_STRONG_INLINE Packet4d preverse(const Packet4d& a)
-{
-   __m256d tmp = _mm256_shuffle_pd(a,a,5);
-  return _mm256_permute2f128_pd(tmp, tmp, 1);
-  #if 0
-  // This version is unlikely to be faster as _mm256_shuffle_ps and _mm256_permute_pd
-  // exhibit the same latency/throughput, but it is here for future reference/benchmarking...
-  __m256d swap_halves = _mm256_permute2f128_pd(a,a,1);
-    return _mm256_permute_pd(swap_halves,5);
-  #endif
-}
-
-// pabs should be ok
-template<> EIGEN_STRONG_INLINE Packet8f pabs(const Packet8f& a)
-{
-  const Packet8f mask = _mm256_castsi256_ps(_mm256_setr_epi32(0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF));
-  return _mm256_and_ps(a,mask);
-}
-template<> EIGEN_STRONG_INLINE Packet4d pabs(const Packet4d& a)
-{
-  const Packet4d mask = _mm256_castsi256_pd(_mm256_setr_epi32(0xFFFFFFFF,0x7FFFFFFF,0xFFFFFFFF,0x7FFFFFFF,0xFFFFFFFF,0x7FFFFFFF,0xFFFFFFFF,0x7FFFFFFF));
-  return _mm256_and_pd(a,mask);
-}
-
-// preduxp should be ok
-// FIXME: why is this ok? why isn't the simply implementation working as expected?
-template<> EIGEN_STRONG_INLINE Packet8f preduxp<Packet8f>(const Packet8f* vecs)
-{
-    __m256 hsum1 = _mm256_hadd_ps(vecs[0], vecs[1]);
-    __m256 hsum2 = _mm256_hadd_ps(vecs[2], vecs[3]);
-    __m256 hsum3 = _mm256_hadd_ps(vecs[4], vecs[5]);
-    __m256 hsum4 = _mm256_hadd_ps(vecs[6], vecs[7]);
-
-    __m256 hsum5 = _mm256_hadd_ps(hsum1, hsum1);
-    __m256 hsum6 = _mm256_hadd_ps(hsum2, hsum2);
-    __m256 hsum7 = _mm256_hadd_ps(hsum3, hsum3);
-    __m256 hsum8 = _mm256_hadd_ps(hsum4, hsum4);
-
-    __m256 perm1 =  _mm256_permute2f128_ps(hsum5, hsum5, 0x23);
-    __m256 perm2 =  _mm256_permute2f128_ps(hsum6, hsum6, 0x23);
-    __m256 perm3 =  _mm256_permute2f128_ps(hsum7, hsum7, 0x23);
-    __m256 perm4 =  _mm256_permute2f128_ps(hsum8, hsum8, 0x23);
-
-    __m256 sum1 = _mm256_add_ps(perm1, hsum5);
-    __m256 sum2 = _mm256_add_ps(perm2, hsum6);
-    __m256 sum3 = _mm256_add_ps(perm3, hsum7);
-    __m256 sum4 = _mm256_add_ps(perm4, hsum8);
-
-    __m256 blend1 = _mm256_blend_ps(sum1, sum2, 0xcc);
-    __m256 blend2 = _mm256_blend_ps(sum3, sum4, 0xcc);
-
-    __m256 final = _mm256_blend_ps(blend1, blend2, 0xf0);
-    return final;
-}
-template<> EIGEN_STRONG_INLINE Packet4d preduxp<Packet4d>(const Packet4d* vecs)
-{
- Packet4d tmp0, tmp1;
-
-  tmp0 = _mm256_hadd_pd(vecs[0], vecs[1]);
-  tmp0 = _mm256_add_pd(tmp0, _mm256_permute2f128_pd(tmp0, tmp0, 1));
-
-  tmp1 = _mm256_hadd_pd(vecs[2], vecs[3]);
-  tmp1 = _mm256_add_pd(tmp1, _mm256_permute2f128_pd(tmp1, tmp1, 1));
-
-  return _mm256_blend_pd(tmp0, tmp1, 0xC);
-}
-
-template<> EIGEN_STRONG_INLINE float predux<Packet8f>(const Packet8f& a)
-{
-  return predux(Packet4f(_mm_add_ps(_mm256_castps256_ps128(a),_mm256_extractf128_ps(a,1))));
-}
-template<> EIGEN_STRONG_INLINE double predux<Packet4d>(const Packet4d& a)
-{
-  return predux(Packet2d(_mm_add_pd(_mm256_castpd256_pd128(a),_mm256_extractf128_pd(a,1))));
-}
-
-template<> EIGEN_STRONG_INLINE Packet4f predux_downto4<Packet8f>(const Packet8f& a)
-{
-  return _mm_add_ps(_mm256_castps256_ps128(a),_mm256_extractf128_ps(a,1));
-}
-
-template<> EIGEN_STRONG_INLINE float predux_mul<Packet8f>(const Packet8f& a)
-{
-  Packet8f tmp;
-  tmp = _mm256_mul_ps(a, _mm256_permute2f128_ps(a,a,1));
-  tmp = _mm256_mul_ps(tmp, _mm256_shuffle_ps(tmp,tmp,_MM_SHUFFLE(1,0,3,2)));
-  return pfirst(_mm256_mul_ps(tmp, _mm256_shuffle_ps(tmp,tmp,1)));
-}
-template<> EIGEN_STRONG_INLINE double predux_mul<Packet4d>(const Packet4d& a)
-{
-  Packet4d tmp;
-  tmp = _mm256_mul_pd(a, _mm256_permute2f128_pd(a,a,1));
-  return pfirst(_mm256_mul_pd(tmp, _mm256_shuffle_pd(tmp,tmp,1)));
-}
-
-template<> EIGEN_STRONG_INLINE float predux_min<Packet8f>(const Packet8f& a)
-{
-  Packet8f tmp = _mm256_min_ps(a, _mm256_permute2f128_ps(a,a,1));
-  tmp = _mm256_min_ps(tmp, _mm256_shuffle_ps(tmp,tmp,_MM_SHUFFLE(1,0,3,2)));
-  return pfirst(_mm256_min_ps(tmp, _mm256_shuffle_ps(tmp,tmp,1)));
-}
-template<> EIGEN_STRONG_INLINE double predux_min<Packet4d>(const Packet4d& a)
-{
-  Packet4d tmp = _mm256_min_pd(a, _mm256_permute2f128_pd(a,a,1));
-  return pfirst(_mm256_min_pd(tmp, _mm256_shuffle_pd(tmp, tmp, 1)));
-}
-
-template<> EIGEN_STRONG_INLINE float predux_max<Packet8f>(const Packet8f& a)
-{
-  Packet8f tmp = _mm256_max_ps(a, _mm256_permute2f128_ps(a,a,1));
-  tmp = _mm256_max_ps(tmp, _mm256_shuffle_ps(tmp,tmp,_MM_SHUFFLE(1,0,3,2)));
-  return pfirst(_mm256_max_ps(tmp, _mm256_shuffle_ps(tmp,tmp,1)));
-}
-
-template<> EIGEN_STRONG_INLINE double predux_max<Packet4d>(const Packet4d& a)
-{
-  Packet4d tmp = _mm256_max_pd(a, _mm256_permute2f128_pd(a,a,1));
-  return pfirst(_mm256_max_pd(tmp, _mm256_shuffle_pd(tmp, tmp, 1)));
-}
-
-
-template<int Offset>
-struct palign_impl<Offset,Packet8f>
-{
-  static EIGEN_STRONG_INLINE void run(Packet8f& first, const Packet8f& second)
-  {
-    if (Offset==1)
-    {
-      first = _mm256_blend_ps(first, second, 1);
-      Packet8f tmp1 = _mm256_permute_ps (first, _MM_SHUFFLE(0,3,2,1));
-      Packet8f tmp2 = _mm256_permute2f128_ps (tmp1, tmp1, 1);
-      first = _mm256_blend_ps(tmp1, tmp2, 0x88);
-    }
-    else if (Offset==2)
-    {
-      first = _mm256_blend_ps(first, second, 3);
-      Packet8f tmp1 = _mm256_permute_ps (first, _MM_SHUFFLE(1,0,3,2));
-      Packet8f tmp2 = _mm256_permute2f128_ps (tmp1, tmp1, 1);
-      first = _mm256_blend_ps(tmp1, tmp2, 0xcc);
-    }
-    else if (Offset==3)
-    {
-      first = _mm256_blend_ps(first, second, 7);
-      Packet8f tmp1 = _mm256_permute_ps (first, _MM_SHUFFLE(2,1,0,3));
-      Packet8f tmp2 = _mm256_permute2f128_ps (tmp1, tmp1, 1);
-      first = _mm256_blend_ps(tmp1, tmp2, 0xee);
-    }
-    else if (Offset==4)
-    {
-      first = _mm256_blend_ps(first, second, 15);
-      Packet8f tmp1 = _mm256_permute_ps (first, _MM_SHUFFLE(3,2,1,0));
-      Packet8f tmp2 = _mm256_permute2f128_ps (tmp1, tmp1, 1);
-      first = _mm256_permute_ps(tmp2, _MM_SHUFFLE(3,2,1,0));
-    }
-    else if (Offset==5)
-    {
-      first = _mm256_blend_ps(first, second, 31);
-      first = _mm256_permute2f128_ps(first, first, 1);
-      Packet8f tmp = _mm256_permute_ps (first, _MM_SHUFFLE(0,3,2,1));
-      first = _mm256_permute2f128_ps(tmp, tmp, 1);
-      first = _mm256_blend_ps(tmp, first, 0x88);
-    }
-    else if (Offset==6)
-    {
-      first = _mm256_blend_ps(first, second, 63);
-      first = _mm256_permute2f128_ps(first, first, 1);
-      Packet8f tmp = _mm256_permute_ps (first, _MM_SHUFFLE(1,0,3,2));
-      first = _mm256_permute2f128_ps(tmp, tmp, 1);
-      first = _mm256_blend_ps(tmp, first, 0xcc);
-    }
-    else if (Offset==7)
-    {
-      first = _mm256_blend_ps(first, second, 127);
-      first = _mm256_permute2f128_ps(first, first, 1);
-      Packet8f tmp = _mm256_permute_ps (first, _MM_SHUFFLE(2,1,0,3));
-      first = _mm256_permute2f128_ps(tmp, tmp, 1);
-      first = _mm256_blend_ps(tmp, first, 0xee);
-    }
-  }
-};
-
-template<int Offset>
-struct palign_impl<Offset,Packet4d>
-{
-  static EIGEN_STRONG_INLINE void run(Packet4d& first, const Packet4d& second)
-  {
-    if (Offset==1)
-    {
-      first = _mm256_blend_pd(first, second, 1);
-      __m256d tmp = _mm256_permute_pd(first, 5);
-      first = _mm256_permute2f128_pd(tmp, tmp, 1);
-      first = _mm256_blend_pd(tmp, first, 0xA);
-    }
-    else if (Offset==2)
-    {
-      first = _mm256_blend_pd(first, second, 3);
-      first = _mm256_permute2f128_pd(first, first, 1);
-    }
-    else if (Offset==3)
-    {
-      first = _mm256_blend_pd(first, second, 7);
-      __m256d tmp = _mm256_permute_pd(first, 5);
-      first = _mm256_permute2f128_pd(tmp, tmp, 1);
-      first = _mm256_blend_pd(tmp, first, 5);
-    }
-  }
-};
-
-EIGEN_DEVICE_FUNC inline void
-ptranspose(PacketBlock<Packet8f,8>& kernel) {
-  __m256 T0 = _mm256_unpacklo_ps(kernel.packet[0], kernel.packet[1]);
-  __m256 T1 = _mm256_unpackhi_ps(kernel.packet[0], kernel.packet[1]);
-  __m256 T2 = _mm256_unpacklo_ps(kernel.packet[2], kernel.packet[3]);
-  __m256 T3 = _mm256_unpackhi_ps(kernel.packet[2], kernel.packet[3]);
-  __m256 T4 = _mm256_unpacklo_ps(kernel.packet[4], kernel.packet[5]);
-  __m256 T5 = _mm256_unpackhi_ps(kernel.packet[4], kernel.packet[5]);
-  __m256 T6 = _mm256_unpacklo_ps(kernel.packet[6], kernel.packet[7]);
-  __m256 T7 = _mm256_unpackhi_ps(kernel.packet[6], kernel.packet[7]);
-  __m256 S0 = _mm256_shuffle_ps(T0,T2,_MM_SHUFFLE(1,0,1,0));
-  __m256 S1 = _mm256_shuffle_ps(T0,T2,_MM_SHUFFLE(3,2,3,2));
-  __m256 S2 = _mm256_shuffle_ps(T1,T3,_MM_SHUFFLE(1,0,1,0));
-  __m256 S3 = _mm256_shuffle_ps(T1,T3,_MM_SHUFFLE(3,2,3,2));
-  __m256 S4 = _mm256_shuffle_ps(T4,T6,_MM_SHUFFLE(1,0,1,0));
-  __m256 S5 = _mm256_shuffle_ps(T4,T6,_MM_SHUFFLE(3,2,3,2));
-  __m256 S6 = _mm256_shuffle_ps(T5,T7,_MM_SHUFFLE(1,0,1,0));
-  __m256 S7 = _mm256_shuffle_ps(T5,T7,_MM_SHUFFLE(3,2,3,2));
-  kernel.packet[0] = _mm256_permute2f128_ps(S0, S4, 0x20);
-  kernel.packet[1] = _mm256_permute2f128_ps(S1, S5, 0x20);
-  kernel.packet[2] = _mm256_permute2f128_ps(S2, S6, 0x20);
-  kernel.packet[3] = _mm256_permute2f128_ps(S3, S7, 0x20);
-  kernel.packet[4] = _mm256_permute2f128_ps(S0, S4, 0x31);
-  kernel.packet[5] = _mm256_permute2f128_ps(S1, S5, 0x31);
-  kernel.packet[6] = _mm256_permute2f128_ps(S2, S6, 0x31);
-  kernel.packet[7] = _mm256_permute2f128_ps(S3, S7, 0x31);
-}
-
-EIGEN_DEVICE_FUNC inline void
-ptranspose(PacketBlock<Packet8f,4>& kernel) {
-  __m256 T0 = _mm256_unpacklo_ps(kernel.packet[0], kernel.packet[1]);
-  __m256 T1 = _mm256_unpackhi_ps(kernel.packet[0], kernel.packet[1]);
-  __m256 T2 = _mm256_unpacklo_ps(kernel.packet[2], kernel.packet[3]);
-  __m256 T3 = _mm256_unpackhi_ps(kernel.packet[2], kernel.packet[3]);
-
-  __m256 S0 = _mm256_shuffle_ps(T0,T2,_MM_SHUFFLE(1,0,1,0));
-  __m256 S1 = _mm256_shuffle_ps(T0,T2,_MM_SHUFFLE(3,2,3,2));
-  __m256 S2 = _mm256_shuffle_ps(T1,T3,_MM_SHUFFLE(1,0,1,0));
-  __m256 S3 = _mm256_shuffle_ps(T1,T3,_MM_SHUFFLE(3,2,3,2));
-
-  kernel.packet[0] = _mm256_permute2f128_ps(S0, S1, 0x20);
-  kernel.packet[1] = _mm256_permute2f128_ps(S2, S3, 0x20);
-  kernel.packet[2] = _mm256_permute2f128_ps(S0, S1, 0x31);
-  kernel.packet[3] = _mm256_permute2f128_ps(S2, S3, 0x31);
-}
-
-EIGEN_DEVICE_FUNC inline void
-ptranspose(PacketBlock<Packet4d,4>& kernel) {
-  __m256d T0 = _mm256_shuffle_pd(kernel.packet[0], kernel.packet[1], 15);
-  __m256d T1 = _mm256_shuffle_pd(kernel.packet[0], kernel.packet[1], 0);
-  __m256d T2 = _mm256_shuffle_pd(kernel.packet[2], kernel.packet[3], 15);
-  __m256d T3 = _mm256_shuffle_pd(kernel.packet[2], kernel.packet[3], 0);
-
-  kernel.packet[1] = _mm256_permute2f128_pd(T0, T2, 32);
-  kernel.packet[3] = _mm256_permute2f128_pd(T0, T2, 49);
-  kernel.packet[0] = _mm256_permute2f128_pd(T1, T3, 32);
-  kernel.packet[2] = _mm256_permute2f128_pd(T1, T3, 49);
-}
-
-template<> EIGEN_STRONG_INLINE Packet8f pblend(const Selector<8>& ifPacket, const Packet8f& thenPacket, const Packet8f& elsePacket) {
-  const __m256 zero = _mm256_setzero_ps();
-  const __m256 select = _mm256_set_ps(ifPacket.select[7], ifPacket.select[6], ifPacket.select[5], ifPacket.select[4], ifPacket.select[3], ifPacket.select[2], ifPacket.select[1], ifPacket.select[0]);
-  __m256 false_mask = _mm256_cmp_ps(select, zero, _CMP_EQ_UQ);
-  return _mm256_blendv_ps(thenPacket, elsePacket, false_mask);
-}
-template<> EIGEN_STRONG_INLINE Packet4d pblend(const Selector<4>& ifPacket, const Packet4d& thenPacket, const Packet4d& elsePacket) {
-  const __m256d zero = _mm256_setzero_pd();
-  const __m256d select = _mm256_set_pd(ifPacket.select[3], ifPacket.select[2], ifPacket.select[1], ifPacket.select[0]);
-  __m256d false_mask = _mm256_cmp_pd(select, zero, _CMP_EQ_UQ);
-  return _mm256_blendv_pd(thenPacket, elsePacket, false_mask);
-}
-
-template<> EIGEN_STRONG_INLINE Packet8f pinsertfirst(const Packet8f& a, float b)
-{
-  return _mm256_blend_ps(a,pset1<Packet8f>(b),1);
-}
-
-template<> EIGEN_STRONG_INLINE Packet4d pinsertfirst(const Packet4d& a, double b)
-{
-  return _mm256_blend_pd(a,pset1<Packet4d>(b),1);
-}
-
-template<> EIGEN_STRONG_INLINE Packet8f pinsertlast(const Packet8f& a, float b)
-{
-  return _mm256_blend_ps(a,pset1<Packet8f>(b),(1<<7));
-}
-
-template<> EIGEN_STRONG_INLINE Packet4d pinsertlast(const Packet4d& a, double b)
-{
-  return _mm256_blend_pd(a,pset1<Packet4d>(b),(1<<3));
-}
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_PACKET_MATH_AVX_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/AVX/TypeCasting.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/AVX/TypeCasting.h
deleted file mode 100644
index 83bfdc6..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/AVX/TypeCasting.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2015 Benoit Steiner <benoit.steiner.goog@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_TYPE_CASTING_AVX_H
-#define EIGEN_TYPE_CASTING_AVX_H
-
-namespace Eigen {
-
-namespace internal {
-
-// For now we use SSE to handle integers, so we can't use AVX instructions to cast
-// from int to float
-template <>
-struct type_casting_traits<float, int> {
-  enum {
-    VectorizedCast = 0,
-    SrcCoeffRatio = 1,
-    TgtCoeffRatio = 1
-  };
-};
-
-template <>
-struct type_casting_traits<int, float> {
-  enum {
-    VectorizedCast = 0,
-    SrcCoeffRatio = 1,
-    TgtCoeffRatio = 1
-  };
-};
-
-
-
-template<> EIGEN_STRONG_INLINE Packet8i pcast<Packet8f, Packet8i>(const Packet8f& a) {
-  return _mm256_cvtps_epi32(a);
-}
-
-template<> EIGEN_STRONG_INLINE Packet8f pcast<Packet8i, Packet8f>(const Packet8i& a) {
-  return _mm256_cvtepi32_ps(a);
-}
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_TYPE_CASTING_AVX_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/Default/ConjHelper.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/Default/ConjHelper.h
deleted file mode 100644
index 4cfe34e..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/Default/ConjHelper.h
+++ /dev/null
@@ -1,29 +0,0 @@
-
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2017 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_ARCH_CONJ_HELPER_H
-#define EIGEN_ARCH_CONJ_HELPER_H
-
-#define EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(PACKET_CPLX, PACKET_REAL)                                                          \
-  template<> struct conj_helper<PACKET_REAL, PACKET_CPLX, false,false> {                                          \
-    EIGEN_STRONG_INLINE PACKET_CPLX pmadd(const PACKET_REAL& x, const PACKET_CPLX& y, const PACKET_CPLX& c) const \
-    { return padd(c, pmul(x,y)); }                                                                                \
-    EIGEN_STRONG_INLINE PACKET_CPLX pmul(const PACKET_REAL& x, const PACKET_CPLX& y) const                        \
-    { return PACKET_CPLX(Eigen::internal::pmul<PACKET_REAL>(x, y.v)); }                                           \
-  };                                                                                                              \
-                                                                                                                  \
-  template<> struct conj_helper<PACKET_CPLX, PACKET_REAL, false,false> {                                          \
-    EIGEN_STRONG_INLINE PACKET_CPLX pmadd(const PACKET_CPLX& x, const PACKET_REAL& y, const PACKET_CPLX& c) const \
-    { return padd(c, pmul(x,y)); }                                                                                \
-    EIGEN_STRONG_INLINE PACKET_CPLX pmul(const PACKET_CPLX& x, const PACKET_REAL& y) const                        \
-    { return PACKET_CPLX(Eigen::internal::pmul<PACKET_REAL>(x.v, y)); }                                           \
-  };
-
-#endif // EIGEN_ARCH_CONJ_HELPER_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/Default/Settings.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/Default/Settings.h
deleted file mode 100644
index 097373c..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/Default/Settings.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-
-/* All the parameters defined in this file can be specialized in the
- * architecture specific files, and/or by the user.
- * More to come... */
-
-#ifndef EIGEN_DEFAULT_SETTINGS_H
-#define EIGEN_DEFAULT_SETTINGS_H
-
-/** Defines the maximal loop size to enable meta unrolling of loops.
-  * Note that the value here is expressed in Eigen's own notion of "number of FLOPS",
-  * it does not correspond to the number of iterations or the number of instructions
-  */
-#ifndef EIGEN_UNROLLING_LIMIT
-#define EIGEN_UNROLLING_LIMIT 100
-#endif
-
-/** Defines the threshold between a "small" and a "large" matrix.
-  * This threshold is mainly used to select the proper product implementation.
-  */
-#ifndef EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD
-#define EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD 8
-#endif
-
-/** Defines the maximal width of the blocks used in the triangular product and solver
-  * for vectors (level 2 blas xTRMV and xTRSV). The default is 8.
-  */
-#ifndef EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH
-#define EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH 8
-#endif
-
-
-/** Defines the default number of registers available for that architecture.
-  * Currently it must be 8 or 16. Other values will fail.
-  */
-#ifndef EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS
-#define EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS 8
-#endif
-
-#endif // EIGEN_DEFAULT_SETTINGS_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/NEON/Complex.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/NEON/Complex.h
deleted file mode 100644
index 306a309..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/NEON/Complex.h
+++ /dev/null
@@ -1,490 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2010 Konstantinos Margaritis <markos@freevec.org>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_COMPLEX_NEON_H
-#define EIGEN_COMPLEX_NEON_H
-
-namespace Eigen {
-
-namespace internal {
-
-inline uint32x4_t p4ui_CONJ_XOR() {
-// See bug 1325, clang fails to call vld1q_u64.
-#if EIGEN_COMP_CLANG
-  uint32x4_t ret = { 0x00000000, 0x80000000, 0x00000000, 0x80000000 };
-  return ret;
-#else
-  static const uint32_t conj_XOR_DATA[] = { 0x00000000, 0x80000000, 0x00000000, 0x80000000 };
-  return vld1q_u32( conj_XOR_DATA );
-#endif
-}
-
-inline uint32x2_t p2ui_CONJ_XOR() {
-  static const uint32_t conj_XOR_DATA[] = { 0x00000000, 0x80000000 };
-  return vld1_u32( conj_XOR_DATA );
-}
-
-//---------- float ----------
-struct Packet2cf
-{
-  EIGEN_STRONG_INLINE Packet2cf() {}
-  EIGEN_STRONG_INLINE explicit Packet2cf(const Packet4f& a) : v(a) {}
-  Packet4f  v;
-};
-
-template<> struct packet_traits<std::complex<float> >  : default_packet_traits
-{
-  typedef Packet2cf type;
-  typedef Packet2cf half;
-  enum {
-    Vectorizable = 1,
-    AlignedOnScalar = 1,
-    size = 2,
-    HasHalfPacket = 0,
-
-    HasAdd    = 1,
-    HasSub    = 1,
-    HasMul    = 1,
-    HasDiv    = 1,
-    HasNegate = 1,
-    HasAbs    = 0,
-    HasAbs2   = 0,
-    HasMin    = 0,
-    HasMax    = 0,
-    HasSetLinear = 0
-  };
-};
-
-template<> struct unpacket_traits<Packet2cf> { typedef std::complex<float> type; enum {size=2, alignment=Aligned16}; typedef Packet2cf half; };
-
-template<> EIGEN_STRONG_INLINE Packet2cf pset1<Packet2cf>(const std::complex<float>&  from)
-{
-  float32x2_t r64;
-  r64 = vld1_f32((const float *)&from);
-
-  return Packet2cf(vcombine_f32(r64, r64));
-}
-
-template<> EIGEN_STRONG_INLINE Packet2cf padd<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(padd<Packet4f>(a.v,b.v)); }
-template<> EIGEN_STRONG_INLINE Packet2cf psub<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(psub<Packet4f>(a.v,b.v)); }
-template<> EIGEN_STRONG_INLINE Packet2cf pnegate(const Packet2cf& a) { return Packet2cf(pnegate<Packet4f>(a.v)); }
-template<> EIGEN_STRONG_INLINE Packet2cf pconj(const Packet2cf& a)
-{
-  Packet4ui b = vreinterpretq_u32_f32(a.v);
-  return Packet2cf(vreinterpretq_f32_u32(veorq_u32(b, p4ui_CONJ_XOR())));
-}
-
-template<> EIGEN_STRONG_INLINE Packet2cf pmul<Packet2cf>(const Packet2cf& a, const Packet2cf& b)
-{
-  Packet4f v1, v2;
-
-  // Get the real values of a | a1_re | a1_re | a2_re | a2_re |
-  v1 = vcombine_f32(vdup_lane_f32(vget_low_f32(a.v), 0), vdup_lane_f32(vget_high_f32(a.v), 0));
-  // Get the imag values of a | a1_im | a1_im | a2_im | a2_im |
-  v2 = vcombine_f32(vdup_lane_f32(vget_low_f32(a.v), 1), vdup_lane_f32(vget_high_f32(a.v), 1));
-  // Multiply the real a with b
-  v1 = vmulq_f32(v1, b.v);
-  // Multiply the imag a with b
-  v2 = vmulq_f32(v2, b.v);
-  // Conjugate v2 
-  v2 = vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(v2), p4ui_CONJ_XOR()));
-  // Swap real/imag elements in v2.
-  v2 = vrev64q_f32(v2);
-  // Add and return the result
-  return Packet2cf(vaddq_f32(v1, v2));
-}
-
-template<> EIGEN_STRONG_INLINE Packet2cf pand   <Packet2cf>(const Packet2cf& a, const Packet2cf& b)
-{
-  return Packet2cf(vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(a.v),vreinterpretq_u32_f32(b.v))));
-}
-template<> EIGEN_STRONG_INLINE Packet2cf por    <Packet2cf>(const Packet2cf& a, const Packet2cf& b)
-{
-  return Packet2cf(vreinterpretq_f32_u32(vorrq_u32(vreinterpretq_u32_f32(a.v),vreinterpretq_u32_f32(b.v))));
-}
-template<> EIGEN_STRONG_INLINE Packet2cf pxor   <Packet2cf>(const Packet2cf& a, const Packet2cf& b)
-{
-  return Packet2cf(vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(a.v),vreinterpretq_u32_f32(b.v))));
-}
-template<> EIGEN_STRONG_INLINE Packet2cf pandnot<Packet2cf>(const Packet2cf& a, const Packet2cf& b)
-{
-  return Packet2cf(vreinterpretq_f32_u32(vbicq_u32(vreinterpretq_u32_f32(a.v),vreinterpretq_u32_f32(b.v))));
-}
-
-template<> EIGEN_STRONG_INLINE Packet2cf pload<Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_ALIGNED_LOAD return Packet2cf(pload<Packet4f>((const float*)from)); }
-template<> EIGEN_STRONG_INLINE Packet2cf ploadu<Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_UNALIGNED_LOAD return Packet2cf(ploadu<Packet4f>((const float*)from)); }
-
-template<> EIGEN_STRONG_INLINE Packet2cf ploaddup<Packet2cf>(const std::complex<float>* from) { return pset1<Packet2cf>(*from); }
-
-template<> EIGEN_STRONG_INLINE void pstore <std::complex<float> >(std::complex<float> *   to, const Packet2cf& from) { EIGEN_DEBUG_ALIGNED_STORE pstore((float*)to, from.v); }
-template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<float> >(std::complex<float> *   to, const Packet2cf& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((float*)to, from.v); }
-
-template<> EIGEN_DEVICE_FUNC inline Packet2cf pgather<std::complex<float>, Packet2cf>(const std::complex<float>* from, Index stride)
-{
-  Packet4f res = pset1<Packet4f>(0.f);
-  res = vsetq_lane_f32(std::real(from[0*stride]), res, 0);
-  res = vsetq_lane_f32(std::imag(from[0*stride]), res, 1);
-  res = vsetq_lane_f32(std::real(from[1*stride]), res, 2);
-  res = vsetq_lane_f32(std::imag(from[1*stride]), res, 3);
-  return Packet2cf(res);
-}
-
-template<> EIGEN_DEVICE_FUNC inline void pscatter<std::complex<float>, Packet2cf>(std::complex<float>* to, const Packet2cf& from, Index stride)
-{
-  to[stride*0] = std::complex<float>(vgetq_lane_f32(from.v, 0), vgetq_lane_f32(from.v, 1));
-  to[stride*1] = std::complex<float>(vgetq_lane_f32(from.v, 2), vgetq_lane_f32(from.v, 3));
-}
-
-template<> EIGEN_STRONG_INLINE void prefetch<std::complex<float> >(const std::complex<float> *   addr) { EIGEN_ARM_PREFETCH((const float *)addr); }
-
-template<> EIGEN_STRONG_INLINE std::complex<float>  pfirst<Packet2cf>(const Packet2cf& a)
-{
-  std::complex<float> EIGEN_ALIGN16 x[2];
-  vst1q_f32((float *)x, a.v);
-  return x[0];
-}
-
-template<> EIGEN_STRONG_INLINE Packet2cf preverse(const Packet2cf& a)
-{
-  float32x2_t a_lo, a_hi;
-  Packet4f a_r128;
-
-  a_lo = vget_low_f32(a.v);
-  a_hi = vget_high_f32(a.v);
-  a_r128 = vcombine_f32(a_hi, a_lo);
-
-  return Packet2cf(a_r128);
-}
-
-template<> EIGEN_STRONG_INLINE Packet2cf pcplxflip<Packet2cf>(const Packet2cf& a)
-{
-  return Packet2cf(vrev64q_f32(a.v));
-}
-
-template<> EIGEN_STRONG_INLINE std::complex<float> predux<Packet2cf>(const Packet2cf& a)
-{
-  float32x2_t a1, a2;
-  std::complex<float> s;
-
-  a1 = vget_low_f32(a.v);
-  a2 = vget_high_f32(a.v);
-  a2 = vadd_f32(a1, a2);
-  vst1_f32((float *)&s, a2);
-
-  return s;
-}
-
-template<> EIGEN_STRONG_INLINE Packet2cf preduxp<Packet2cf>(const Packet2cf* vecs)
-{
-  Packet4f sum1, sum2, sum;
-
-  // Add the first two 64-bit float32x2_t of vecs[0]
-  sum1 = vcombine_f32(vget_low_f32(vecs[0].v), vget_low_f32(vecs[1].v));
-  sum2 = vcombine_f32(vget_high_f32(vecs[0].v), vget_high_f32(vecs[1].v));
-  sum = vaddq_f32(sum1, sum2);
-
-  return Packet2cf(sum);
-}
-
-template<> EIGEN_STRONG_INLINE std::complex<float> predux_mul<Packet2cf>(const Packet2cf& a)
-{
-  float32x2_t a1, a2, v1, v2, prod;
-  std::complex<float> s;
-
-  a1 = vget_low_f32(a.v);
-  a2 = vget_high_f32(a.v);
-   // Get the real values of a | a1_re | a1_re | a2_re | a2_re |
-  v1 = vdup_lane_f32(a1, 0);
-  // Get the real values of a | a1_im | a1_im | a2_im | a2_im |
-  v2 = vdup_lane_f32(a1, 1);
-  // Multiply the real a with b
-  v1 = vmul_f32(v1, a2);
-  // Multiply the imag a with b
-  v2 = vmul_f32(v2, a2);
-  // Conjugate v2 
-  v2 = vreinterpret_f32_u32(veor_u32(vreinterpret_u32_f32(v2), p2ui_CONJ_XOR()));
-  // Swap real/imag elements in v2.
-  v2 = vrev64_f32(v2);
-  // Add v1, v2
-  prod = vadd_f32(v1, v2);
-
-  vst1_f32((float *)&s, prod);
-
-  return s;
-}
-
-template<int Offset>
-struct palign_impl<Offset,Packet2cf>
-{
-  EIGEN_STRONG_INLINE static void run(Packet2cf& first, const Packet2cf& second)
-  {
-    if (Offset==1)
-    {
-      first.v = vextq_f32(first.v, second.v, 2);
-    }
-  }
-};
-
-template<> struct conj_helper<Packet2cf, Packet2cf, false,true>
-{
-  EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const
-  { return padd(pmul(x,y),c); }
-
-  EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const
-  {
-    return internal::pmul(a, pconj(b));
-  }
-};
-
-template<> struct conj_helper<Packet2cf, Packet2cf, true,false>
-{
-  EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const
-  { return padd(pmul(x,y),c); }
-
-  EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const
-  {
-    return internal::pmul(pconj(a), b);
-  }
-};
-
-template<> struct conj_helper<Packet2cf, Packet2cf, true,true>
-{
-  EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const
-  { return padd(pmul(x,y),c); }
-
-  EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const
-  {
-    return pconj(internal::pmul(a, b));
-  }
-};
-
-EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cf,Packet4f)
-
-template<> EIGEN_STRONG_INLINE Packet2cf pdiv<Packet2cf>(const Packet2cf& a, const Packet2cf& b)
-{
-  // TODO optimize it for NEON
-  Packet2cf res = conj_helper<Packet2cf,Packet2cf,false,true>().pmul(a,b);
-  Packet4f s, rev_s;
-
-  // this computes the norm
-  s = vmulq_f32(b.v, b.v);
-  rev_s = vrev64q_f32(s);
-
-  return Packet2cf(pdiv<Packet4f>(res.v, vaddq_f32(s,rev_s)));
-}
-
-EIGEN_DEVICE_FUNC inline void
-ptranspose(PacketBlock<Packet2cf,2>& kernel) {
-  Packet4f tmp = vcombine_f32(vget_high_f32(kernel.packet[0].v), vget_high_f32(kernel.packet[1].v));
-  kernel.packet[0].v = vcombine_f32(vget_low_f32(kernel.packet[0].v), vget_low_f32(kernel.packet[1].v));
-  kernel.packet[1].v = tmp;
-}
-
-//---------- double ----------
-#if EIGEN_ARCH_ARM64 && !EIGEN_APPLE_DOUBLE_NEON_BUG
-
-// See bug 1325, clang fails to call vld1q_u64.
-#if EIGEN_COMP_CLANG
-  static uint64x2_t p2ul_CONJ_XOR = {0x0, 0x8000000000000000};
-#else
-  const uint64_t  p2ul_conj_XOR_DATA[] = { 0x0, 0x8000000000000000 };
-  static uint64x2_t p2ul_CONJ_XOR = vld1q_u64( p2ul_conj_XOR_DATA );
-#endif
-
-struct Packet1cd
-{
-  EIGEN_STRONG_INLINE Packet1cd() {}
-  EIGEN_STRONG_INLINE explicit Packet1cd(const Packet2d& a) : v(a) {}
-  Packet2d v;
-};
-
-template<> struct packet_traits<std::complex<double> >  : default_packet_traits
-{
-  typedef Packet1cd type;
-  typedef Packet1cd half;
-  enum {
-    Vectorizable = 1,
-    AlignedOnScalar = 0,
-    size = 1,
-    HasHalfPacket = 0,
-
-    HasAdd    = 1,
-    HasSub    = 1,
-    HasMul    = 1,
-    HasDiv    = 1,
-    HasNegate = 1,
-    HasAbs    = 0,
-    HasAbs2   = 0,
-    HasMin    = 0,
-    HasMax    = 0,
-    HasSetLinear = 0
-  };
-};
-
-template<> struct unpacket_traits<Packet1cd> { typedef std::complex<double> type; enum {size=1, alignment=Aligned16}; typedef Packet1cd half; };
-
-template<> EIGEN_STRONG_INLINE Packet1cd pload<Packet1cd>(const std::complex<double>* from) { EIGEN_DEBUG_ALIGNED_LOAD return Packet1cd(pload<Packet2d>((const double*)from)); }
-template<> EIGEN_STRONG_INLINE Packet1cd ploadu<Packet1cd>(const std::complex<double>* from) { EIGEN_DEBUG_UNALIGNED_LOAD return Packet1cd(ploadu<Packet2d>((const double*)from)); }
-
-template<> EIGEN_STRONG_INLINE Packet1cd pset1<Packet1cd>(const std::complex<double>&  from)
-{ /* here we really have to use unaligned loads :( */ return ploadu<Packet1cd>(&from); }
-
-template<> EIGEN_STRONG_INLINE Packet1cd padd<Packet1cd>(const Packet1cd& a, const Packet1cd& b) { return Packet1cd(padd<Packet2d>(a.v,b.v)); }
-template<> EIGEN_STRONG_INLINE Packet1cd psub<Packet1cd>(const Packet1cd& a, const Packet1cd& b) { return Packet1cd(psub<Packet2d>(a.v,b.v)); }
-template<> EIGEN_STRONG_INLINE Packet1cd pnegate(const Packet1cd& a) { return Packet1cd(pnegate<Packet2d>(a.v)); }
-template<> EIGEN_STRONG_INLINE Packet1cd pconj(const Packet1cd& a) { return Packet1cd(vreinterpretq_f64_u64(veorq_u64(vreinterpretq_u64_f64(a.v), p2ul_CONJ_XOR))); }
-
-template<> EIGEN_STRONG_INLINE Packet1cd pmul<Packet1cd>(const Packet1cd& a, const Packet1cd& b)
-{
-  Packet2d v1, v2;
-
-  // Get the real values of a 
-  v1 = vdupq_lane_f64(vget_low_f64(a.v), 0);
-  // Get the imag values of a
-  v2 = vdupq_lane_f64(vget_high_f64(a.v), 0);
-  // Multiply the real a with b
-  v1 = vmulq_f64(v1, b.v);
-  // Multiply the imag a with b
-  v2 = vmulq_f64(v2, b.v);
-  // Conjugate v2 
-  v2 = vreinterpretq_f64_u64(veorq_u64(vreinterpretq_u64_f64(v2), p2ul_CONJ_XOR));
-  // Swap real/imag elements in v2.
-  v2 = preverse<Packet2d>(v2);
-  // Add and return the result
-  return Packet1cd(vaddq_f64(v1, v2));
-}
-
-template<> EIGEN_STRONG_INLINE Packet1cd pand   <Packet1cd>(const Packet1cd& a, const Packet1cd& b)
-{
-  return Packet1cd(vreinterpretq_f64_u64(vandq_u64(vreinterpretq_u64_f64(a.v),vreinterpretq_u64_f64(b.v))));
-}
-template<> EIGEN_STRONG_INLINE Packet1cd por    <Packet1cd>(const Packet1cd& a, const Packet1cd& b)
-{
-  return Packet1cd(vreinterpretq_f64_u64(vorrq_u64(vreinterpretq_u64_f64(a.v),vreinterpretq_u64_f64(b.v))));
-}
-template<> EIGEN_STRONG_INLINE Packet1cd pxor   <Packet1cd>(const Packet1cd& a, const Packet1cd& b)
-{
-  return Packet1cd(vreinterpretq_f64_u64(veorq_u64(vreinterpretq_u64_f64(a.v),vreinterpretq_u64_f64(b.v))));
-}
-template<> EIGEN_STRONG_INLINE Packet1cd pandnot<Packet1cd>(const Packet1cd& a, const Packet1cd& b)
-{
-  return Packet1cd(vreinterpretq_f64_u64(vbicq_u64(vreinterpretq_u64_f64(a.v),vreinterpretq_u64_f64(b.v))));
-}
-
-template<> EIGEN_STRONG_INLINE Packet1cd ploaddup<Packet1cd>(const std::complex<double>* from) { return pset1<Packet1cd>(*from); }
-
-template<> EIGEN_STRONG_INLINE void pstore <std::complex<double> >(std::complex<double> *   to, const Packet1cd& from) { EIGEN_DEBUG_ALIGNED_STORE pstore((double*)to, from.v); }
-template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<double> >(std::complex<double> *   to, const Packet1cd& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((double*)to, from.v); }
-
-template<> EIGEN_STRONG_INLINE void prefetch<std::complex<double> >(const std::complex<double> *   addr) { EIGEN_ARM_PREFETCH((const double *)addr); }
-
-template<> EIGEN_DEVICE_FUNC inline Packet1cd pgather<std::complex<double>, Packet1cd>(const std::complex<double>* from, Index stride)
-{
-  Packet2d res = pset1<Packet2d>(0.0);
-  res = vsetq_lane_f64(std::real(from[0*stride]), res, 0);
-  res = vsetq_lane_f64(std::imag(from[0*stride]), res, 1);
-  return Packet1cd(res);
-}
-
-template<> EIGEN_DEVICE_FUNC inline void pscatter<std::complex<double>, Packet1cd>(std::complex<double>* to, const Packet1cd& from, Index stride)
-{
-  to[stride*0] = std::complex<double>(vgetq_lane_f64(from.v, 0), vgetq_lane_f64(from.v, 1));
-}
-
-
-template<> EIGEN_STRONG_INLINE std::complex<double>  pfirst<Packet1cd>(const Packet1cd& a)
-{
-  std::complex<double> EIGEN_ALIGN16 res;
-  pstore<std::complex<double> >(&res, a);
-
-  return res;
-}
-
-template<> EIGEN_STRONG_INLINE Packet1cd preverse(const Packet1cd& a) { return a; }
-
-template<> EIGEN_STRONG_INLINE std::complex<double> predux<Packet1cd>(const Packet1cd& a) { return pfirst(a); }
-
-template<> EIGEN_STRONG_INLINE Packet1cd preduxp<Packet1cd>(const Packet1cd* vecs) { return vecs[0]; }
-
-template<> EIGEN_STRONG_INLINE std::complex<double> predux_mul<Packet1cd>(const Packet1cd& a) { return pfirst(a); }
-
-template<int Offset>
-struct palign_impl<Offset,Packet1cd>
-{
-  static EIGEN_STRONG_INLINE void run(Packet1cd& /*first*/, const Packet1cd& /*second*/)
-  {
-    // FIXME is it sure we never have to align a Packet1cd?
-    // Even though a std::complex<double> has 16 bytes, it is not necessarily aligned on a 16 bytes boundary...
-  }
-};
-
-template<> struct conj_helper<Packet1cd, Packet1cd, false,true>
-{
-  EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet1cd& x, const Packet1cd& y, const Packet1cd& c) const
-  { return padd(pmul(x,y),c); }
-
-  EIGEN_STRONG_INLINE Packet1cd pmul(const Packet1cd& a, const Packet1cd& b) const
-  {
-    return internal::pmul(a, pconj(b));
-  }
-};
-
-template<> struct conj_helper<Packet1cd, Packet1cd, true,false>
-{
-  EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet1cd& x, const Packet1cd& y, const Packet1cd& c) const
-  { return padd(pmul(x,y),c); }
-
-  EIGEN_STRONG_INLINE Packet1cd pmul(const Packet1cd& a, const Packet1cd& b) const
-  {
-    return internal::pmul(pconj(a), b);
-  }
-};
-
-template<> struct conj_helper<Packet1cd, Packet1cd, true,true>
-{
-  EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet1cd& x, const Packet1cd& y, const Packet1cd& c) const
-  { return padd(pmul(x,y),c); }
-
-  EIGEN_STRONG_INLINE Packet1cd pmul(const Packet1cd& a, const Packet1cd& b) const
-  {
-    return pconj(internal::pmul(a, b));
-  }
-};
-
-EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet1cd,Packet2d)
-
-template<> EIGEN_STRONG_INLINE Packet1cd pdiv<Packet1cd>(const Packet1cd& a, const Packet1cd& b)
-{
-  // TODO optimize it for NEON
-  Packet1cd res = conj_helper<Packet1cd,Packet1cd,false,true>().pmul(a,b);
-  Packet2d s = pmul<Packet2d>(b.v, b.v);
-  Packet2d rev_s = preverse<Packet2d>(s);
-
-  return Packet1cd(pdiv(res.v, padd<Packet2d>(s,rev_s)));
-}
-
-EIGEN_STRONG_INLINE Packet1cd pcplxflip/*<Packet1cd>*/(const Packet1cd& x)
-{
-  return Packet1cd(preverse(Packet2d(x.v)));
-}
-
-EIGEN_STRONG_INLINE void ptranspose(PacketBlock<Packet1cd,2>& kernel)
-{
-  Packet2d tmp = vcombine_f64(vget_high_f64(kernel.packet[0].v), vget_high_f64(kernel.packet[1].v));
-  kernel.packet[0].v = vcombine_f64(vget_low_f64(kernel.packet[0].v), vget_low_f64(kernel.packet[1].v));
-  kernel.packet[1].v = tmp;
-}
-#endif // EIGEN_ARCH_ARM64
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_COMPLEX_NEON_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/NEON/MathFunctions.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/NEON/MathFunctions.h
deleted file mode 100644
index 6bb05bb..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/NEON/MathFunctions.h
+++ /dev/null
@@ -1,91 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-/* The sin, cos, exp, and log functions of this file come from
- * Julien Pommier's sse math library: http://gruntthepeon.free.fr/ssemath/
- */
-
-#ifndef EIGEN_MATH_FUNCTIONS_NEON_H
-#define EIGEN_MATH_FUNCTIONS_NEON_H
-
-namespace Eigen {
-
-namespace internal {
-
-template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
-Packet4f pexp<Packet4f>(const Packet4f& _x)
-{
-  Packet4f x = _x;
-  Packet4f tmp, fx;
-
-  _EIGEN_DECLARE_CONST_Packet4f(1 , 1.0f);
-  _EIGEN_DECLARE_CONST_Packet4f(half, 0.5f);
-  _EIGEN_DECLARE_CONST_Packet4i(0x7f, 0x7f);
-  _EIGEN_DECLARE_CONST_Packet4f(exp_hi,  88.3762626647950f);
-  _EIGEN_DECLARE_CONST_Packet4f(exp_lo, -88.3762626647949f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_LOG2EF, 1.44269504088896341f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_C1, 0.693359375f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_C2, -2.12194440e-4f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p0, 1.9875691500E-4f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p1, 1.3981999507E-3f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p2, 8.3334519073E-3f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p3, 4.1665795894E-2f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p4, 1.6666665459E-1f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p5, 5.0000001201E-1f);
-
-  x = vminq_f32(x, p4f_exp_hi);
-  x = vmaxq_f32(x, p4f_exp_lo);
-
-  /* express exp(x) as exp(g + n*log(2)) */
-  fx = vmlaq_f32(p4f_half, x, p4f_cephes_LOG2EF);
-
-  /* perform a floorf */
-  tmp = vcvtq_f32_s32(vcvtq_s32_f32(fx));
-
-  /* if greater, substract 1 */
-  Packet4ui mask = vcgtq_f32(tmp, fx);
-  mask = vandq_u32(mask, vreinterpretq_u32_f32(p4f_1));
-
-  fx = vsubq_f32(tmp, vreinterpretq_f32_u32(mask));
-
-  tmp = vmulq_f32(fx, p4f_cephes_exp_C1);
-  Packet4f z = vmulq_f32(fx, p4f_cephes_exp_C2);
-  x = vsubq_f32(x, tmp);
-  x = vsubq_f32(x, z);
-
-  Packet4f y = vmulq_f32(p4f_cephes_exp_p0, x);
-  z = vmulq_f32(x, x);
-  y = vaddq_f32(y, p4f_cephes_exp_p1);
-  y = vmulq_f32(y, x);
-  y = vaddq_f32(y, p4f_cephes_exp_p2);
-  y = vmulq_f32(y, x);
-  y = vaddq_f32(y, p4f_cephes_exp_p3);
-  y = vmulq_f32(y, x);
-  y = vaddq_f32(y, p4f_cephes_exp_p4);
-  y = vmulq_f32(y, x);
-  y = vaddq_f32(y, p4f_cephes_exp_p5);
-
-  y = vmulq_f32(y, z);
-  y = vaddq_f32(y, x);
-  y = vaddq_f32(y, p4f_1);
-
-  /* build 2^n */
-  int32x4_t mm;
-  mm = vcvtq_s32_f32(fx);
-  mm = vaddq_s32(mm, p4i_0x7f);
-  mm = vshlq_n_s32(mm, 23);
-  Packet4f pow2n = vreinterpretq_f32_s32(mm);
-
-  y = vmulq_f32(y, pow2n);
-  return y;
-}
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_MATH_FUNCTIONS_NEON_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/NEON/PacketMath.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/NEON/PacketMath.h
deleted file mode 100644
index 3d5ed0d..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/NEON/PacketMath.h
+++ /dev/null
@@ -1,760 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2010 Konstantinos Margaritis <markos@freevec.org>
-// Heavily based on Gael's SSE version.
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_PACKET_MATH_NEON_H
-#define EIGEN_PACKET_MATH_NEON_H
-
-namespace Eigen {
-
-namespace internal {
-
-#ifndef EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD
-#define EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD 8
-#endif
-
-#ifndef EIGEN_HAS_SINGLE_INSTRUCTION_MADD
-#define EIGEN_HAS_SINGLE_INSTRUCTION_MADD
-#endif
-
-#ifndef EIGEN_HAS_SINGLE_INSTRUCTION_CJMADD
-#define EIGEN_HAS_SINGLE_INSTRUCTION_CJMADD
-#endif
-
-#ifndef EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS
-#if EIGEN_ARCH_ARM64
-#define EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS 32
-#else
-#define EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS 16 
-#endif
-#endif
-
-#if EIGEN_COMP_MSVC
-
-// In MSVC's arm_neon.h header file, all NEON vector types
-// are aliases to the same underlying type __n128.
-// We thus have to wrap them to make them different C++ types.
-// (See also bug 1428)
-
-template<typename T,int unique_id>
-struct eigen_packet_wrapper
-{
-  operator T&() { return m_val; }
-  operator const T&() const { return m_val; }
-  eigen_packet_wrapper() {}
-  eigen_packet_wrapper(const T &v) : m_val(v) {}
-  eigen_packet_wrapper& operator=(const T &v) {
-    m_val = v;
-    return *this;
-  }
-
-  T m_val;
-};
-typedef eigen_packet_wrapper<float32x2_t,0> Packet2f;
-typedef eigen_packet_wrapper<float32x4_t,1> Packet4f;
-typedef eigen_packet_wrapper<int32x4_t  ,2> Packet4i;
-typedef eigen_packet_wrapper<int32x2_t  ,3> Packet2i;
-typedef eigen_packet_wrapper<uint32x4_t ,4> Packet4ui;
-
-#else
-
-typedef float32x2_t Packet2f;
-typedef float32x4_t Packet4f;
-typedef int32x4_t   Packet4i;
-typedef int32x2_t   Packet2i;
-typedef uint32x4_t  Packet4ui;
-
-#endif // EIGEN_COMP_MSVC
-
-#define _EIGEN_DECLARE_CONST_Packet4f(NAME,X) \
-  const Packet4f p4f_##NAME = pset1<Packet4f>(X)
-
-#define _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(NAME,X) \
-  const Packet4f p4f_##NAME = vreinterpretq_f32_u32(pset1<int32_t>(X))
-
-#define _EIGEN_DECLARE_CONST_Packet4i(NAME,X) \
-  const Packet4i p4i_##NAME = pset1<Packet4i>(X)
-
-#if EIGEN_ARCH_ARM64
-  // __builtin_prefetch tends to do nothing on ARM64 compilers because the
-  // prefetch instructions there are too detailed for __builtin_prefetch to map
-  // meaningfully to them.
-  #define EIGEN_ARM_PREFETCH(ADDR)  __asm__ __volatile__("prfm pldl1keep, [%[addr]]\n" ::[addr] "r"(ADDR) : );
-#elif EIGEN_HAS_BUILTIN(__builtin_prefetch) || EIGEN_COMP_GNUC
-  #define EIGEN_ARM_PREFETCH(ADDR) __builtin_prefetch(ADDR);
-#elif defined __pld
-  #define EIGEN_ARM_PREFETCH(ADDR) __pld(ADDR)
-#elif EIGEN_ARCH_ARM32
-  #define EIGEN_ARM_PREFETCH(ADDR) __asm__ __volatile__ ("pld [%[addr]]\n" :: [addr] "r" (ADDR) : );
-#else
-  // by default no explicit prefetching
-  #define EIGEN_ARM_PREFETCH(ADDR)
-#endif
-
-template<> struct packet_traits<float>  : default_packet_traits
-{
-  typedef Packet4f type;
-  typedef Packet4f half; // Packet2f intrinsics not implemented yet
-  enum {
-    Vectorizable = 1,
-    AlignedOnScalar = 1,
-    size = 4,
-    HasHalfPacket=0, // Packet2f intrinsics not implemented yet
-   
-    HasDiv  = 1,
-    // FIXME check the Has*
-    HasSin  = 0,
-    HasCos  = 0,
-    HasLog  = 0,
-    HasExp  = 1,
-    HasSqrt = 0
-  };
-};
-template<> struct packet_traits<int32_t>    : default_packet_traits
-{
-  typedef Packet4i type;
-  typedef Packet4i half; // Packet2i intrinsics not implemented yet
-  enum {
-    Vectorizable = 1,
-    AlignedOnScalar = 1,
-    size=4,
-    HasHalfPacket=0 // Packet2i intrinsics not implemented yet
-    // FIXME check the Has*
-  };
-};
-
-#if EIGEN_GNUC_AT_MOST(4,4) && !EIGEN_COMP_LLVM
-// workaround gcc 4.2, 4.3 and 4.4 compilatin issue
-EIGEN_STRONG_INLINE float32x4_t vld1q_f32(const float* x) { return ::vld1q_f32((const float32_t*)x); }
-EIGEN_STRONG_INLINE float32x2_t vld1_f32 (const float* x) { return ::vld1_f32 ((const float32_t*)x); }
-EIGEN_STRONG_INLINE float32x2_t vld1_dup_f32 (const float* x) { return ::vld1_dup_f32 ((const float32_t*)x); }
-EIGEN_STRONG_INLINE void        vst1q_f32(float* to, float32x4_t from) { ::vst1q_f32((float32_t*)to,from); }
-EIGEN_STRONG_INLINE void        vst1_f32 (float* to, float32x2_t from) { ::vst1_f32 ((float32_t*)to,from); }
-#endif
-
-template<> struct unpacket_traits<Packet4f> { typedef float   type; enum {size=4, alignment=Aligned16}; typedef Packet4f half; };
-template<> struct unpacket_traits<Packet4i> { typedef int32_t type; enum {size=4, alignment=Aligned16}; typedef Packet4i half; };
-
-template<> EIGEN_STRONG_INLINE Packet4f pset1<Packet4f>(const float&  from) { return vdupq_n_f32(from); }
-template<> EIGEN_STRONG_INLINE Packet4i pset1<Packet4i>(const int32_t&    from)   { return vdupq_n_s32(from); }
-
-template<> EIGEN_STRONG_INLINE Packet4f plset<Packet4f>(const float& a)
-{
-  const float f[] = {0, 1, 2, 3};
-  Packet4f countdown = vld1q_f32(f);
-  return vaddq_f32(pset1<Packet4f>(a), countdown);
-}
-template<> EIGEN_STRONG_INLINE Packet4i plset<Packet4i>(const int32_t& a)
-{
-  const int32_t i[] = {0, 1, 2, 3};
-  Packet4i countdown = vld1q_s32(i);
-  return vaddq_s32(pset1<Packet4i>(a), countdown);
-}
-
-template<> EIGEN_STRONG_INLINE Packet4f padd<Packet4f>(const Packet4f& a, const Packet4f& b) { return vaddq_f32(a,b); }
-template<> EIGEN_STRONG_INLINE Packet4i padd<Packet4i>(const Packet4i& a, const Packet4i& b) { return vaddq_s32(a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet4f psub<Packet4f>(const Packet4f& a, const Packet4f& b) { return vsubq_f32(a,b); }
-template<> EIGEN_STRONG_INLINE Packet4i psub<Packet4i>(const Packet4i& a, const Packet4i& b) { return vsubq_s32(a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet4f pnegate(const Packet4f& a) { return vnegq_f32(a); }
-template<> EIGEN_STRONG_INLINE Packet4i pnegate(const Packet4i& a) { return vnegq_s32(a); }
-
-template<> EIGEN_STRONG_INLINE Packet4f pconj(const Packet4f& a) { return a; }
-template<> EIGEN_STRONG_INLINE Packet4i pconj(const Packet4i& a) { return a; }
-
-template<> EIGEN_STRONG_INLINE Packet4f pmul<Packet4f>(const Packet4f& a, const Packet4f& b) { return vmulq_f32(a,b); }
-template<> EIGEN_STRONG_INLINE Packet4i pmul<Packet4i>(const Packet4i& a, const Packet4i& b) { return vmulq_s32(a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet4f pdiv<Packet4f>(const Packet4f& a, const Packet4f& b)
-{
-#if EIGEN_ARCH_ARM64
-  return vdivq_f32(a,b);
-#else
-  Packet4f inv, restep, div;
-
-  // NEON does not offer a divide instruction, we have to do a reciprocal approximation
-  // However NEON in contrast to other SIMD engines (AltiVec/SSE), offers
-  // a reciprocal estimate AND a reciprocal step -which saves a few instructions
-  // vrecpeq_f32() returns an estimate to 1/b, which we will finetune with
-  // Newton-Raphson and vrecpsq_f32()
-  inv = vrecpeq_f32(b);
-
-  // This returns a differential, by which we will have to multiply inv to get a better
-  // approximation of 1/b.
-  restep = vrecpsq_f32(b, inv);
-  inv = vmulq_f32(restep, inv);
-
-  // Finally, multiply a by 1/b and get the wanted result of the division.
-  div = vmulq_f32(a, inv);
-
-  return div;
-#endif
-}
-
-template<> EIGEN_STRONG_INLINE Packet4i pdiv<Packet4i>(const Packet4i& /*a*/, const Packet4i& /*b*/)
-{ eigen_assert(false && "packet integer division are not supported by NEON");
-  return pset1<Packet4i>(0);
-}
-
-// Clang/ARM wrongly advertises __ARM_FEATURE_FMA even when it's not available,
-// then implements a slow software scalar fallback calling fmaf()!
-// Filed LLVM bug:
-//     https://llvm.org/bugs/show_bug.cgi?id=27216
-#if (defined __ARM_FEATURE_FMA) && !(EIGEN_COMP_CLANG && EIGEN_ARCH_ARM)
-// See bug 936.
-// FMA is available on VFPv4 i.e. when compiling with -mfpu=neon-vfpv4.
-// FMA is a true fused multiply-add i.e. only 1 rounding at the end, no intermediate rounding.
-// MLA is not fused i.e. does 2 roundings.
-// In addition to giving better accuracy, FMA also gives better performance here on a Krait (Nexus 4):
-// MLA: 10 GFlop/s ; FMA: 12 GFlops/s.
-template<> EIGEN_STRONG_INLINE Packet4f pmadd(const Packet4f& a, const Packet4f& b, const Packet4f& c) { return vfmaq_f32(c,a,b); }
-#else
-template<> EIGEN_STRONG_INLINE Packet4f pmadd(const Packet4f& a, const Packet4f& b, const Packet4f& c) {
-#if EIGEN_COMP_CLANG && EIGEN_ARCH_ARM
-  // Clang/ARM will replace VMLA by VMUL+VADD at least for some values of -mcpu,
-  // at least -mcpu=cortex-a8 and -mcpu=cortex-a7. Since the former is the default on
-  // -march=armv7-a, that is a very common case.
-  // See e.g. this thread:
-  //     http://lists.llvm.org/pipermail/llvm-dev/2013-December/068806.html
-  // Filed LLVM bug:
-  //     https://llvm.org/bugs/show_bug.cgi?id=27219
-  Packet4f r = c;
-  asm volatile(
-    "vmla.f32 %q[r], %q[a], %q[b]"
-    : [r] "+w" (r)
-    : [a] "w" (a),
-      [b] "w" (b)
-    : );
-  return r;
-#else
-  return vmlaq_f32(c,a,b);
-#endif
-}
-#endif
-
-// No FMA instruction for int, so use MLA unconditionally.
-template<> EIGEN_STRONG_INLINE Packet4i pmadd(const Packet4i& a, const Packet4i& b, const Packet4i& c) { return vmlaq_s32(c,a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet4f pmin<Packet4f>(const Packet4f& a, const Packet4f& b) { return vminq_f32(a,b); }
-template<> EIGEN_STRONG_INLINE Packet4i pmin<Packet4i>(const Packet4i& a, const Packet4i& b) { return vminq_s32(a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet4f pmax<Packet4f>(const Packet4f& a, const Packet4f& b) { return vmaxq_f32(a,b); }
-template<> EIGEN_STRONG_INLINE Packet4i pmax<Packet4i>(const Packet4i& a, const Packet4i& b) { return vmaxq_s32(a,b); }
-
-// Logical Operations are not supported for float, so we have to reinterpret casts using NEON intrinsics
-template<> EIGEN_STRONG_INLINE Packet4f pand<Packet4f>(const Packet4f& a, const Packet4f& b)
-{
-  return vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(a),vreinterpretq_u32_f32(b)));
-}
-template<> EIGEN_STRONG_INLINE Packet4i pand<Packet4i>(const Packet4i& a, const Packet4i& b) { return vandq_s32(a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet4f por<Packet4f>(const Packet4f& a, const Packet4f& b)
-{
-  return vreinterpretq_f32_u32(vorrq_u32(vreinterpretq_u32_f32(a),vreinterpretq_u32_f32(b)));
-}
-template<> EIGEN_STRONG_INLINE Packet4i por<Packet4i>(const Packet4i& a, const Packet4i& b) { return vorrq_s32(a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet4f pxor<Packet4f>(const Packet4f& a, const Packet4f& b)
-{
-  return vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(a),vreinterpretq_u32_f32(b)));
-}
-template<> EIGEN_STRONG_INLINE Packet4i pxor<Packet4i>(const Packet4i& a, const Packet4i& b) { return veorq_s32(a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet4f pandnot<Packet4f>(const Packet4f& a, const Packet4f& b)
-{
-  return vreinterpretq_f32_u32(vbicq_u32(vreinterpretq_u32_f32(a),vreinterpretq_u32_f32(b)));
-}
-template<> EIGEN_STRONG_INLINE Packet4i pandnot<Packet4i>(const Packet4i& a, const Packet4i& b) { return vbicq_s32(a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet4f pload<Packet4f>(const float*    from) { EIGEN_DEBUG_ALIGNED_LOAD return vld1q_f32(from); }
-template<> EIGEN_STRONG_INLINE Packet4i pload<Packet4i>(const int32_t*  from) { EIGEN_DEBUG_ALIGNED_LOAD return vld1q_s32(from); }
-
-template<> EIGEN_STRONG_INLINE Packet4f ploadu<Packet4f>(const float*   from) { EIGEN_DEBUG_UNALIGNED_LOAD return vld1q_f32(from); }
-template<> EIGEN_STRONG_INLINE Packet4i ploadu<Packet4i>(const int32_t* from) { EIGEN_DEBUG_UNALIGNED_LOAD return vld1q_s32(from); }
-
-template<> EIGEN_STRONG_INLINE Packet4f ploaddup<Packet4f>(const float* from)
-{
-  float32x2_t lo, hi;
-  lo = vld1_dup_f32(from);
-  hi = vld1_dup_f32(from+1);
-  return vcombine_f32(lo, hi);
-}
-template<> EIGEN_STRONG_INLINE Packet4i ploaddup<Packet4i>(const int32_t* from)
-{
-  int32x2_t lo, hi;
-  lo = vld1_dup_s32(from);
-  hi = vld1_dup_s32(from+1);
-  return vcombine_s32(lo, hi);
-}
-
-template<> EIGEN_STRONG_INLINE void pstore<float>  (float*    to, const Packet4f& from) { EIGEN_DEBUG_ALIGNED_STORE vst1q_f32(to, from); }
-template<> EIGEN_STRONG_INLINE void pstore<int32_t>(int32_t*  to, const Packet4i& from) { EIGEN_DEBUG_ALIGNED_STORE vst1q_s32(to, from); }
-
-template<> EIGEN_STRONG_INLINE void pstoreu<float>  (float*   to, const Packet4f& from) { EIGEN_DEBUG_UNALIGNED_STORE vst1q_f32(to, from); }
-template<> EIGEN_STRONG_INLINE void pstoreu<int32_t>(int32_t* to, const Packet4i& from) { EIGEN_DEBUG_UNALIGNED_STORE vst1q_s32(to, from); }
-
-template<> EIGEN_DEVICE_FUNC inline Packet4f pgather<float, Packet4f>(const float* from, Index stride)
-{
-  Packet4f res = pset1<Packet4f>(0.f);
-  res = vsetq_lane_f32(from[0*stride], res, 0);
-  res = vsetq_lane_f32(from[1*stride], res, 1);
-  res = vsetq_lane_f32(from[2*stride], res, 2);
-  res = vsetq_lane_f32(from[3*stride], res, 3);
-  return res;
-}
-template<> EIGEN_DEVICE_FUNC inline Packet4i pgather<int32_t, Packet4i>(const int32_t* from, Index stride)
-{
-  Packet4i res = pset1<Packet4i>(0);
-  res = vsetq_lane_s32(from[0*stride], res, 0);
-  res = vsetq_lane_s32(from[1*stride], res, 1);
-  res = vsetq_lane_s32(from[2*stride], res, 2);
-  res = vsetq_lane_s32(from[3*stride], res, 3);
-  return res;
-}
-
-template<> EIGEN_DEVICE_FUNC inline void pscatter<float, Packet4f>(float* to, const Packet4f& from, Index stride)
-{
-  to[stride*0] = vgetq_lane_f32(from, 0);
-  to[stride*1] = vgetq_lane_f32(from, 1);
-  to[stride*2] = vgetq_lane_f32(from, 2);
-  to[stride*3] = vgetq_lane_f32(from, 3);
-}
-template<> EIGEN_DEVICE_FUNC inline void pscatter<int32_t, Packet4i>(int32_t* to, const Packet4i& from, Index stride)
-{
-  to[stride*0] = vgetq_lane_s32(from, 0);
-  to[stride*1] = vgetq_lane_s32(from, 1);
-  to[stride*2] = vgetq_lane_s32(from, 2);
-  to[stride*3] = vgetq_lane_s32(from, 3);
-}
-
-template<> EIGEN_STRONG_INLINE void prefetch<float>  (const float*    addr) { EIGEN_ARM_PREFETCH(addr); }
-template<> EIGEN_STRONG_INLINE void prefetch<int32_t>(const int32_t*  addr) { EIGEN_ARM_PREFETCH(addr); }
-
-// FIXME only store the 2 first elements ?
-template<> EIGEN_STRONG_INLINE float   pfirst<Packet4f>(const Packet4f& a) { float   EIGEN_ALIGN16 x[4]; vst1q_f32(x, a); return x[0]; }
-template<> EIGEN_STRONG_INLINE int32_t pfirst<Packet4i>(const Packet4i& a) { int32_t EIGEN_ALIGN16 x[4]; vst1q_s32(x, a); return x[0]; }
-
-template<> EIGEN_STRONG_INLINE Packet4f preverse(const Packet4f& a) {
-  float32x2_t a_lo, a_hi;
-  Packet4f a_r64;
-
-  a_r64 = vrev64q_f32(a);
-  a_lo = vget_low_f32(a_r64);
-  a_hi = vget_high_f32(a_r64);
-  return vcombine_f32(a_hi, a_lo);
-}
-template<> EIGEN_STRONG_INLINE Packet4i preverse(const Packet4i& a) {
-  int32x2_t a_lo, a_hi;
-  Packet4i a_r64;
-
-  a_r64 = vrev64q_s32(a);
-  a_lo = vget_low_s32(a_r64);
-  a_hi = vget_high_s32(a_r64);
-  return vcombine_s32(a_hi, a_lo);
-}
-
-template<> EIGEN_STRONG_INLINE Packet4f pabs(const Packet4f& a) { return vabsq_f32(a); }
-template<> EIGEN_STRONG_INLINE Packet4i pabs(const Packet4i& a) { return vabsq_s32(a); }
-
-template<> EIGEN_STRONG_INLINE float predux<Packet4f>(const Packet4f& a)
-{
-  float32x2_t a_lo, a_hi, sum;
-
-  a_lo = vget_low_f32(a);
-  a_hi = vget_high_f32(a);
-  sum = vpadd_f32(a_lo, a_hi);
-  sum = vpadd_f32(sum, sum);
-  return vget_lane_f32(sum, 0);
-}
-
-template<> EIGEN_STRONG_INLINE Packet4f preduxp<Packet4f>(const Packet4f* vecs)
-{
-  float32x4x2_t vtrn1, vtrn2, res1, res2;
-  Packet4f sum1, sum2, sum;
-
-  // NEON zip performs interleaving of the supplied vectors.
-  // We perform two interleaves in a row to acquire the transposed vector
-  vtrn1 = vzipq_f32(vecs[0], vecs[2]);
-  vtrn2 = vzipq_f32(vecs[1], vecs[3]);
-  res1 = vzipq_f32(vtrn1.val[0], vtrn2.val[0]);
-  res2 = vzipq_f32(vtrn1.val[1], vtrn2.val[1]);
-
-  // Do the addition of the resulting vectors
-  sum1 = vaddq_f32(res1.val[0], res1.val[1]);
-  sum2 = vaddq_f32(res2.val[0], res2.val[1]);
-  sum = vaddq_f32(sum1, sum2);
-
-  return sum;
-}
-
-template<> EIGEN_STRONG_INLINE int32_t predux<Packet4i>(const Packet4i& a)
-{
-  int32x2_t a_lo, a_hi, sum;
-
-  a_lo = vget_low_s32(a);
-  a_hi = vget_high_s32(a);
-  sum = vpadd_s32(a_lo, a_hi);
-  sum = vpadd_s32(sum, sum);
-  return vget_lane_s32(sum, 0);
-}
-
-template<> EIGEN_STRONG_INLINE Packet4i preduxp<Packet4i>(const Packet4i* vecs)
-{
-  int32x4x2_t vtrn1, vtrn2, res1, res2;
-  Packet4i sum1, sum2, sum;
-
-  // NEON zip performs interleaving of the supplied vectors.
-  // We perform two interleaves in a row to acquire the transposed vector
-  vtrn1 = vzipq_s32(vecs[0], vecs[2]);
-  vtrn2 = vzipq_s32(vecs[1], vecs[3]);
-  res1 = vzipq_s32(vtrn1.val[0], vtrn2.val[0]);
-  res2 = vzipq_s32(vtrn1.val[1], vtrn2.val[1]);
-
-  // Do the addition of the resulting vectors
-  sum1 = vaddq_s32(res1.val[0], res1.val[1]);
-  sum2 = vaddq_s32(res2.val[0], res2.val[1]);
-  sum = vaddq_s32(sum1, sum2);
-
-  return sum;
-}
-
-// Other reduction functions:
-// mul
-template<> EIGEN_STRONG_INLINE float predux_mul<Packet4f>(const Packet4f& a)
-{
-  float32x2_t a_lo, a_hi, prod;
-
-  // Get a_lo = |a1|a2| and a_hi = |a3|a4|
-  a_lo = vget_low_f32(a);
-  a_hi = vget_high_f32(a);
-  // Get the product of a_lo * a_hi -> |a1*a3|a2*a4|
-  prod = vmul_f32(a_lo, a_hi);
-  // Multiply prod with its swapped value |a2*a4|a1*a3|
-  prod = vmul_f32(prod, vrev64_f32(prod));
-
-  return vget_lane_f32(prod, 0);
-}
-template<> EIGEN_STRONG_INLINE int32_t predux_mul<Packet4i>(const Packet4i& a)
-{
-  int32x2_t a_lo, a_hi, prod;
-
-  // Get a_lo = |a1|a2| and a_hi = |a3|a4|
-  a_lo = vget_low_s32(a);
-  a_hi = vget_high_s32(a);
-  // Get the product of a_lo * a_hi -> |a1*a3|a2*a4|
-  prod = vmul_s32(a_lo, a_hi);
-  // Multiply prod with its swapped value |a2*a4|a1*a3|
-  prod = vmul_s32(prod, vrev64_s32(prod));
-
-  return vget_lane_s32(prod, 0);
-}
-
-// min
-template<> EIGEN_STRONG_INLINE float predux_min<Packet4f>(const Packet4f& a)
-{
-  float32x2_t a_lo, a_hi, min;
-
-  a_lo = vget_low_f32(a);
-  a_hi = vget_high_f32(a);
-  min = vpmin_f32(a_lo, a_hi);
-  min = vpmin_f32(min, min);
-
-  return vget_lane_f32(min, 0);
-}
-
-template<> EIGEN_STRONG_INLINE int32_t predux_min<Packet4i>(const Packet4i& a)
-{
-  int32x2_t a_lo, a_hi, min;
-
-  a_lo = vget_low_s32(a);
-  a_hi = vget_high_s32(a);
-  min = vpmin_s32(a_lo, a_hi);
-  min = vpmin_s32(min, min);
-  
-  return vget_lane_s32(min, 0);
-}
-
-// max
-template<> EIGEN_STRONG_INLINE float predux_max<Packet4f>(const Packet4f& a)
-{
-  float32x2_t a_lo, a_hi, max;
-
-  a_lo = vget_low_f32(a);
-  a_hi = vget_high_f32(a);
-  max = vpmax_f32(a_lo, a_hi);
-  max = vpmax_f32(max, max);
-
-  return vget_lane_f32(max, 0);
-}
-
-template<> EIGEN_STRONG_INLINE int32_t predux_max<Packet4i>(const Packet4i& a)
-{
-  int32x2_t a_lo, a_hi, max;
-
-  a_lo = vget_low_s32(a);
-  a_hi = vget_high_s32(a);
-  max = vpmax_s32(a_lo, a_hi);
-  max = vpmax_s32(max, max);
-
-  return vget_lane_s32(max, 0);
-}
-
-// this PALIGN_NEON business is to work around a bug in LLVM Clang 3.0 causing incorrect compilation errors,
-// see bug 347 and this LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=11074
-#define PALIGN_NEON(Offset,Type,Command) \
-template<>\
-struct palign_impl<Offset,Type>\
-{\
-    EIGEN_STRONG_INLINE static void run(Type& first, const Type& second)\
-    {\
-        if (Offset!=0)\
-            first = Command(first, second, Offset);\
-    }\
-};\
-
-PALIGN_NEON(0,Packet4f,vextq_f32)
-PALIGN_NEON(1,Packet4f,vextq_f32)
-PALIGN_NEON(2,Packet4f,vextq_f32)
-PALIGN_NEON(3,Packet4f,vextq_f32)
-PALIGN_NEON(0,Packet4i,vextq_s32)
-PALIGN_NEON(1,Packet4i,vextq_s32)
-PALIGN_NEON(2,Packet4i,vextq_s32)
-PALIGN_NEON(3,Packet4i,vextq_s32)
-
-#undef PALIGN_NEON
-
-EIGEN_DEVICE_FUNC inline void
-ptranspose(PacketBlock<Packet4f,4>& kernel) {
-  float32x4x2_t tmp1 = vzipq_f32(kernel.packet[0], kernel.packet[1]);
-  float32x4x2_t tmp2 = vzipq_f32(kernel.packet[2], kernel.packet[3]);
-
-  kernel.packet[0] = vcombine_f32(vget_low_f32(tmp1.val[0]), vget_low_f32(tmp2.val[0]));
-  kernel.packet[1] = vcombine_f32(vget_high_f32(tmp1.val[0]), vget_high_f32(tmp2.val[0]));
-  kernel.packet[2] = vcombine_f32(vget_low_f32(tmp1.val[1]), vget_low_f32(tmp2.val[1]));
-  kernel.packet[3] = vcombine_f32(vget_high_f32(tmp1.val[1]), vget_high_f32(tmp2.val[1]));
-}
-
-EIGEN_DEVICE_FUNC inline void
-ptranspose(PacketBlock<Packet4i,4>& kernel) {
-  int32x4x2_t tmp1 = vzipq_s32(kernel.packet[0], kernel.packet[1]);
-  int32x4x2_t tmp2 = vzipq_s32(kernel.packet[2], kernel.packet[3]);
-  kernel.packet[0] = vcombine_s32(vget_low_s32(tmp1.val[0]), vget_low_s32(tmp2.val[0]));
-  kernel.packet[1] = vcombine_s32(vget_high_s32(tmp1.val[0]), vget_high_s32(tmp2.val[0]));
-  kernel.packet[2] = vcombine_s32(vget_low_s32(tmp1.val[1]), vget_low_s32(tmp2.val[1]));
-  kernel.packet[3] = vcombine_s32(vget_high_s32(tmp1.val[1]), vget_high_s32(tmp2.val[1]));
-}
-
-//---------- double ----------
-
-// Clang 3.5 in the iOS toolchain has an ICE triggered by NEON intrisics for double.
-// Confirmed at least with __apple_build_version__ = 6000054.
-#ifdef __apple_build_version__
-// Let's hope that by the time __apple_build_version__ hits the 601* range, the bug will be fixed.
-// https://gist.github.com/yamaya/2924292 suggests that the 3 first digits are only updated with
-// major toolchain updates.
-#define EIGEN_APPLE_DOUBLE_NEON_BUG (__apple_build_version__ < 6010000)
-#else
-#define EIGEN_APPLE_DOUBLE_NEON_BUG 0
-#endif
-
-#if EIGEN_ARCH_ARM64 && !EIGEN_APPLE_DOUBLE_NEON_BUG
-
-// Bug 907: workaround missing declarations of the following two functions in the ADK
-// Defining these functions as templates ensures that if these intrinsics are
-// already defined in arm_neon.h, then our workaround doesn't cause a conflict
-// and has lower priority in overload resolution.
-template <typename T>
-uint64x2_t vreinterpretq_u64_f64(T a)
-{
-  return (uint64x2_t) a;
-}
-
-template <typename T>
-float64x2_t vreinterpretq_f64_u64(T a)
-{
-  return (float64x2_t) a;
-}
-
-typedef float64x2_t Packet2d;
-typedef float64x1_t Packet1d;
-
-template<> struct packet_traits<double>  : default_packet_traits
-{
-  typedef Packet2d type;
-  typedef Packet2d half;
-  enum {
-    Vectorizable = 1,
-    AlignedOnScalar = 1,
-    size = 2,
-    HasHalfPacket=0,
-   
-    HasDiv  = 1,
-    // FIXME check the Has*
-    HasSin  = 0,
-    HasCos  = 0,
-    HasLog  = 0,
-    HasExp  = 0,
-    HasSqrt = 0
-  };
-};
-
-template<> struct unpacket_traits<Packet2d> { typedef double  type; enum {size=2, alignment=Aligned16}; typedef Packet2d half; };
-
-template<> EIGEN_STRONG_INLINE Packet2d pset1<Packet2d>(const double&  from) { return vdupq_n_f64(from); }
-
-template<> EIGEN_STRONG_INLINE Packet2d plset<Packet2d>(const double& a)
-{
-  const double countdown_raw[] = {0.0,1.0};
-  const Packet2d countdown = vld1q_f64(countdown_raw);
-  return vaddq_f64(pset1<Packet2d>(a), countdown);
-}
-template<> EIGEN_STRONG_INLINE Packet2d padd<Packet2d>(const Packet2d& a, const Packet2d& b) { return vaddq_f64(a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet2d psub<Packet2d>(const Packet2d& a, const Packet2d& b) { return vsubq_f64(a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet2d pnegate(const Packet2d& a) { return vnegq_f64(a); }
-
-template<> EIGEN_STRONG_INLINE Packet2d pconj(const Packet2d& a) { return a; }
-
-template<> EIGEN_STRONG_INLINE Packet2d pmul<Packet2d>(const Packet2d& a, const Packet2d& b) { return vmulq_f64(a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet2d pdiv<Packet2d>(const Packet2d& a, const Packet2d& b) { return vdivq_f64(a,b); }
-
-#ifdef __ARM_FEATURE_FMA
-// See bug 936. See above comment about FMA for float.
-template<> EIGEN_STRONG_INLINE Packet2d pmadd(const Packet2d& a, const Packet2d& b, const Packet2d& c) { return vfmaq_f64(c,a,b); }
-#else
-template<> EIGEN_STRONG_INLINE Packet2d pmadd(const Packet2d& a, const Packet2d& b, const Packet2d& c) { return vmlaq_f64(c,a,b); }
-#endif
-
-template<> EIGEN_STRONG_INLINE Packet2d pmin<Packet2d>(const Packet2d& a, const Packet2d& b) { return vminq_f64(a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet2d pmax<Packet2d>(const Packet2d& a, const Packet2d& b) { return vmaxq_f64(a,b); }
-
-// Logical Operations are not supported for float, so we have to reinterpret casts using NEON intrinsics
-template<> EIGEN_STRONG_INLINE Packet2d pand<Packet2d>(const Packet2d& a, const Packet2d& b)
-{
-  return vreinterpretq_f64_u64(vandq_u64(vreinterpretq_u64_f64(a),vreinterpretq_u64_f64(b)));
-}
-
-template<> EIGEN_STRONG_INLINE Packet2d por<Packet2d>(const Packet2d& a, const Packet2d& b)
-{
-  return vreinterpretq_f64_u64(vorrq_u64(vreinterpretq_u64_f64(a),vreinterpretq_u64_f64(b)));
-}
-
-template<> EIGEN_STRONG_INLINE Packet2d pxor<Packet2d>(const Packet2d& a, const Packet2d& b)
-{
-  return vreinterpretq_f64_u64(veorq_u64(vreinterpretq_u64_f64(a),vreinterpretq_u64_f64(b)));
-}
-
-template<> EIGEN_STRONG_INLINE Packet2d pandnot<Packet2d>(const Packet2d& a, const Packet2d& b)
-{
-  return vreinterpretq_f64_u64(vbicq_u64(vreinterpretq_u64_f64(a),vreinterpretq_u64_f64(b)));
-}
-
-template<> EIGEN_STRONG_INLINE Packet2d pload<Packet2d>(const double* from) { EIGEN_DEBUG_ALIGNED_LOAD return vld1q_f64(from); }
-
-template<> EIGEN_STRONG_INLINE Packet2d ploadu<Packet2d>(const double* from) { EIGEN_DEBUG_UNALIGNED_LOAD return vld1q_f64(from); }
-
-template<> EIGEN_STRONG_INLINE Packet2d ploaddup<Packet2d>(const double*   from)
-{
-  return vld1q_dup_f64(from);
-}
-template<> EIGEN_STRONG_INLINE void pstore<double>(double*   to, const Packet2d& from) { EIGEN_DEBUG_ALIGNED_STORE vst1q_f64(to, from); }
-
-template<> EIGEN_STRONG_INLINE void pstoreu<double>(double*  to, const Packet2d& from) { EIGEN_DEBUG_UNALIGNED_STORE vst1q_f64(to, from); }
-
-template<> EIGEN_DEVICE_FUNC inline Packet2d pgather<double, Packet2d>(const double* from, Index stride)
-{
-  Packet2d res = pset1<Packet2d>(0.0);
-  res = vsetq_lane_f64(from[0*stride], res, 0);
-  res = vsetq_lane_f64(from[1*stride], res, 1);
-  return res;
-}
-template<> EIGEN_DEVICE_FUNC inline void pscatter<double, Packet2d>(double* to, const Packet2d& from, Index stride)
-{
-  to[stride*0] = vgetq_lane_f64(from, 0);
-  to[stride*1] = vgetq_lane_f64(from, 1);
-}
-template<> EIGEN_STRONG_INLINE void prefetch<double>(const double* addr) { EIGEN_ARM_PREFETCH(addr); }
-
-// FIXME only store the 2 first elements ?
-template<> EIGEN_STRONG_INLINE double pfirst<Packet2d>(const Packet2d& a) { return vgetq_lane_f64(a, 0); }
-
-template<> EIGEN_STRONG_INLINE Packet2d preverse(const Packet2d& a) { return vcombine_f64(vget_high_f64(a), vget_low_f64(a)); }
-
-template<> EIGEN_STRONG_INLINE Packet2d pabs(const Packet2d& a) { return vabsq_f64(a); }
-
-#if EIGEN_COMP_CLANG && defined(__apple_build_version__)
-// workaround ICE, see bug 907
-template<> EIGEN_STRONG_INLINE double predux<Packet2d>(const Packet2d& a) { return (vget_low_f64(a) + vget_high_f64(a))[0]; }
-#else
-template<> EIGEN_STRONG_INLINE double predux<Packet2d>(const Packet2d& a) { return vget_lane_f64(vget_low_f64(a) + vget_high_f64(a), 0); }
-#endif
-
-template<> EIGEN_STRONG_INLINE Packet2d preduxp<Packet2d>(const Packet2d* vecs)
-{
-  float64x2_t trn1, trn2;
-
-  // NEON zip performs interleaving of the supplied vectors.
-  // We perform two interleaves in a row to acquire the transposed vector
-  trn1 = vzip1q_f64(vecs[0], vecs[1]);
-  trn2 = vzip2q_f64(vecs[0], vecs[1]);
-
-  // Do the addition of the resulting vectors
-  return vaddq_f64(trn1, trn2);
-}
-// Other reduction functions:
-// mul
-#if EIGEN_COMP_CLANG && defined(__apple_build_version__)
-template<> EIGEN_STRONG_INLINE double predux_mul<Packet2d>(const Packet2d& a) { return (vget_low_f64(a) * vget_high_f64(a))[0]; }
-#else
-template<> EIGEN_STRONG_INLINE double predux_mul<Packet2d>(const Packet2d& a) { return vget_lane_f64(vget_low_f64(a) * vget_high_f64(a), 0); }
-#endif
-
-// min
-template<> EIGEN_STRONG_INLINE double predux_min<Packet2d>(const Packet2d& a) { return vgetq_lane_f64(vpminq_f64(a, a), 0); }
-
-// max
-template<> EIGEN_STRONG_INLINE double predux_max<Packet2d>(const Packet2d& a) { return vgetq_lane_f64(vpmaxq_f64(a, a), 0); }
-
-// this PALIGN_NEON business is to work around a bug in LLVM Clang 3.0 causing incorrect compilation errors,
-// see bug 347 and this LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=11074
-#define PALIGN_NEON(Offset,Type,Command) \
-template<>\
-struct palign_impl<Offset,Type>\
-{\
-    EIGEN_STRONG_INLINE static void run(Type& first, const Type& second)\
-    {\
-        if (Offset!=0)\
-            first = Command(first, second, Offset);\
-    }\
-};\
-
-PALIGN_NEON(0,Packet2d,vextq_f64)
-PALIGN_NEON(1,Packet2d,vextq_f64)
-#undef PALIGN_NEON
-
-EIGEN_DEVICE_FUNC inline void
-ptranspose(PacketBlock<Packet2d,2>& kernel) {
-  float64x2_t trn1 = vzip1q_f64(kernel.packet[0], kernel.packet[1]);
-  float64x2_t trn2 = vzip2q_f64(kernel.packet[0], kernel.packet[1]);
-
-  kernel.packet[0] = trn1;
-  kernel.packet[1] = trn2;
-}
-#endif // EIGEN_ARCH_ARM64 
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_PACKET_MATH_NEON_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/SSE/Complex.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/SSE/Complex.h
deleted file mode 100644
index d075043..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/SSE/Complex.h
+++ /dev/null
@@ -1,471 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_COMPLEX_SSE_H
-#define EIGEN_COMPLEX_SSE_H
-
-namespace Eigen {
-
-namespace internal {
-
-//---------- float ----------
-struct Packet2cf
-{
-  EIGEN_STRONG_INLINE Packet2cf() {}
-  EIGEN_STRONG_INLINE explicit Packet2cf(const __m128& a) : v(a) {}
-  __m128  v;
-};
-
-// Use the packet_traits defined in AVX/PacketMath.h instead if we're going
-// to leverage AVX instructions.
-#ifndef EIGEN_VECTORIZE_AVX
-template<> struct packet_traits<std::complex<float> >  : default_packet_traits
-{
-  typedef Packet2cf type;
-  typedef Packet2cf half;
-  enum {
-    Vectorizable = 1,
-    AlignedOnScalar = 1,
-    size = 2,
-    HasHalfPacket = 0,
-
-    HasAdd    = 1,
-    HasSub    = 1,
-    HasMul    = 1,
-    HasDiv    = 1,
-    HasNegate = 1,
-    HasAbs    = 0,
-    HasAbs2   = 0,
-    HasMin    = 0,
-    HasMax    = 0,
-    HasSetLinear = 0,
-    HasBlend = 1
-  };
-};
-#endif
-
-template<> struct unpacket_traits<Packet2cf> { typedef std::complex<float> type; enum {size=2, alignment=Aligned16}; typedef Packet2cf half; };
-
-template<> EIGEN_STRONG_INLINE Packet2cf padd<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(_mm_add_ps(a.v,b.v)); }
-template<> EIGEN_STRONG_INLINE Packet2cf psub<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(_mm_sub_ps(a.v,b.v)); }
-template<> EIGEN_STRONG_INLINE Packet2cf pnegate(const Packet2cf& a)
-{
-  const __m128 mask = _mm_castsi128_ps(_mm_setr_epi32(0x80000000,0x80000000,0x80000000,0x80000000));
-  return Packet2cf(_mm_xor_ps(a.v,mask));
-}
-template<> EIGEN_STRONG_INLINE Packet2cf pconj(const Packet2cf& a)
-{
-  const __m128 mask = _mm_castsi128_ps(_mm_setr_epi32(0x00000000,0x80000000,0x00000000,0x80000000));
-  return Packet2cf(_mm_xor_ps(a.v,mask));
-}
-
-template<> EIGEN_STRONG_INLINE Packet2cf pmul<Packet2cf>(const Packet2cf& a, const Packet2cf& b)
-{
-  #ifdef EIGEN_VECTORIZE_SSE3
-  return Packet2cf(_mm_addsub_ps(_mm_mul_ps(_mm_moveldup_ps(a.v), b.v),
-                                 _mm_mul_ps(_mm_movehdup_ps(a.v),
-                                            vec4f_swizzle1(b.v, 1, 0, 3, 2))));
-//   return Packet2cf(_mm_addsub_ps(_mm_mul_ps(vec4f_swizzle1(a.v, 0, 0, 2, 2), b.v),
-//                                  _mm_mul_ps(vec4f_swizzle1(a.v, 1, 1, 3, 3),
-//                                             vec4f_swizzle1(b.v, 1, 0, 3, 2))));
-  #else
-  const __m128 mask = _mm_castsi128_ps(_mm_setr_epi32(0x80000000,0x00000000,0x80000000,0x00000000));
-  return Packet2cf(_mm_add_ps(_mm_mul_ps(vec4f_swizzle1(a.v, 0, 0, 2, 2), b.v),
-                              _mm_xor_ps(_mm_mul_ps(vec4f_swizzle1(a.v, 1, 1, 3, 3),
-                                                    vec4f_swizzle1(b.v, 1, 0, 3, 2)), mask)));
-  #endif
-}
-
-template<> EIGEN_STRONG_INLINE Packet2cf pand   <Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(_mm_and_ps(a.v,b.v)); }
-template<> EIGEN_STRONG_INLINE Packet2cf por    <Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(_mm_or_ps(a.v,b.v)); }
-template<> EIGEN_STRONG_INLINE Packet2cf pxor   <Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(_mm_xor_ps(a.v,b.v)); }
-template<> EIGEN_STRONG_INLINE Packet2cf pandnot<Packet2cf>(const Packet2cf& a, const Packet2cf& b) { return Packet2cf(_mm_andnot_ps(a.v,b.v)); }
-
-template<> EIGEN_STRONG_INLINE Packet2cf pload <Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_ALIGNED_LOAD return Packet2cf(pload<Packet4f>(&numext::real_ref(*from))); }
-template<> EIGEN_STRONG_INLINE Packet2cf ploadu<Packet2cf>(const std::complex<float>* from) { EIGEN_DEBUG_UNALIGNED_LOAD return Packet2cf(ploadu<Packet4f>(&numext::real_ref(*from))); }
-
-template<> EIGEN_STRONG_INLINE Packet2cf pset1<Packet2cf>(const std::complex<float>&  from)
-{
-  Packet2cf res;
-#if EIGEN_GNUC_AT_MOST(4,2)
-  // Workaround annoying "may be used uninitialized in this function" warning with gcc 4.2
-  res.v = _mm_loadl_pi(_mm_set1_ps(0.0f), reinterpret_cast<const __m64*>(&from));
-#elif EIGEN_GNUC_AT_LEAST(4,6)
-  // Suppress annoying "may be used uninitialized in this function" warning with gcc >= 4.6
-  #pragma GCC diagnostic push
-  #pragma GCC diagnostic ignored "-Wuninitialized"
-  res.v = _mm_loadl_pi(res.v, (const __m64*)&from);
-  #pragma GCC diagnostic pop
-#else
-  res.v = _mm_loadl_pi(res.v, (const __m64*)&from);
-#endif
-  return Packet2cf(_mm_movelh_ps(res.v,res.v));
-}
-
-template<> EIGEN_STRONG_INLINE Packet2cf ploaddup<Packet2cf>(const std::complex<float>* from) { return pset1<Packet2cf>(*from); }
-
-template<> EIGEN_STRONG_INLINE void pstore <std::complex<float> >(std::complex<float> *   to, const Packet2cf& from) { EIGEN_DEBUG_ALIGNED_STORE pstore(&numext::real_ref(*to), Packet4f(from.v)); }
-template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<float> >(std::complex<float> *   to, const Packet2cf& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu(&numext::real_ref(*to), Packet4f(from.v)); }
-
-
-template<> EIGEN_DEVICE_FUNC inline Packet2cf pgather<std::complex<float>, Packet2cf>(const std::complex<float>* from, Index stride)
-{
-  return Packet2cf(_mm_set_ps(std::imag(from[1*stride]), std::real(from[1*stride]),
-                              std::imag(from[0*stride]), std::real(from[0*stride])));
-}
-
-template<> EIGEN_DEVICE_FUNC inline void pscatter<std::complex<float>, Packet2cf>(std::complex<float>* to, const Packet2cf& from, Index stride)
-{
-  to[stride*0] = std::complex<float>(_mm_cvtss_f32(_mm_shuffle_ps(from.v, from.v, 0)),
-                                     _mm_cvtss_f32(_mm_shuffle_ps(from.v, from.v, 1)));
-  to[stride*1] = std::complex<float>(_mm_cvtss_f32(_mm_shuffle_ps(from.v, from.v, 2)),
-                                     _mm_cvtss_f32(_mm_shuffle_ps(from.v, from.v, 3)));
-}
-
-template<> EIGEN_STRONG_INLINE void prefetch<std::complex<float> >(const std::complex<float> *   addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); }
-
-template<> EIGEN_STRONG_INLINE std::complex<float>  pfirst<Packet2cf>(const Packet2cf& a)
-{
-  #if EIGEN_GNUC_AT_MOST(4,3)
-  // Workaround gcc 4.2 ICE - this is not performance wise ideal, but who cares...
-  // This workaround also fix invalid code generation with gcc 4.3
-  EIGEN_ALIGN16 std::complex<float> res[2];
-  _mm_store_ps((float*)res, a.v);
-  return res[0];
-  #else
-  std::complex<float> res;
-  _mm_storel_pi((__m64*)&res, a.v);
-  return res;
-  #endif
-}
-
-template<> EIGEN_STRONG_INLINE Packet2cf preverse(const Packet2cf& a) { return Packet2cf(_mm_castpd_ps(preverse(Packet2d(_mm_castps_pd(a.v))))); }
-
-template<> EIGEN_STRONG_INLINE std::complex<float> predux<Packet2cf>(const Packet2cf& a)
-{
-  return pfirst(Packet2cf(_mm_add_ps(a.v, _mm_movehl_ps(a.v,a.v))));
-}
-
-template<> EIGEN_STRONG_INLINE Packet2cf preduxp<Packet2cf>(const Packet2cf* vecs)
-{
-  return Packet2cf(_mm_add_ps(_mm_movelh_ps(vecs[0].v,vecs[1].v), _mm_movehl_ps(vecs[1].v,vecs[0].v)));
-}
-
-template<> EIGEN_STRONG_INLINE std::complex<float> predux_mul<Packet2cf>(const Packet2cf& a)
-{
-  return pfirst(pmul(a, Packet2cf(_mm_movehl_ps(a.v,a.v))));
-}
-
-template<int Offset>
-struct palign_impl<Offset,Packet2cf>
-{
-  static EIGEN_STRONG_INLINE void run(Packet2cf& first, const Packet2cf& second)
-  {
-    if (Offset==1)
-    {
-      first.v = _mm_movehl_ps(first.v, first.v);
-      first.v = _mm_movelh_ps(first.v, second.v);
-    }
-  }
-};
-
-template<> struct conj_helper<Packet2cf, Packet2cf, false,true>
-{
-  EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const
-  { return padd(pmul(x,y),c); }
-
-  EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const
-  {
-    #ifdef EIGEN_VECTORIZE_SSE3
-    return internal::pmul(a, pconj(b));
-    #else
-    const __m128 mask = _mm_castsi128_ps(_mm_setr_epi32(0x00000000,0x80000000,0x00000000,0x80000000));
-    return Packet2cf(_mm_add_ps(_mm_xor_ps(_mm_mul_ps(vec4f_swizzle1(a.v, 0, 0, 2, 2), b.v), mask),
-                                _mm_mul_ps(vec4f_swizzle1(a.v, 1, 1, 3, 3),
-                                           vec4f_swizzle1(b.v, 1, 0, 3, 2))));
-    #endif
-  }
-};
-
-template<> struct conj_helper<Packet2cf, Packet2cf, true,false>
-{
-  EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const
-  { return padd(pmul(x,y),c); }
-
-  EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const
-  {
-    #ifdef EIGEN_VECTORIZE_SSE3
-    return internal::pmul(pconj(a), b);
-    #else
-    const __m128 mask = _mm_castsi128_ps(_mm_setr_epi32(0x00000000,0x80000000,0x00000000,0x80000000));
-    return Packet2cf(_mm_add_ps(_mm_mul_ps(vec4f_swizzle1(a.v, 0, 0, 2, 2), b.v),
-                                _mm_xor_ps(_mm_mul_ps(vec4f_swizzle1(a.v, 1, 1, 3, 3),
-                                                      vec4f_swizzle1(b.v, 1, 0, 3, 2)), mask)));
-    #endif
-  }
-};
-
-template<> struct conj_helper<Packet2cf, Packet2cf, true,true>
-{
-  EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet2cf& y, const Packet2cf& c) const
-  { return padd(pmul(x,y),c); }
-
-  EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& a, const Packet2cf& b) const
-  {
-    #ifdef EIGEN_VECTORIZE_SSE3
-    return pconj(internal::pmul(a, b));
-    #else
-    const __m128 mask = _mm_castsi128_ps(_mm_setr_epi32(0x00000000,0x80000000,0x00000000,0x80000000));
-    return Packet2cf(_mm_sub_ps(_mm_xor_ps(_mm_mul_ps(vec4f_swizzle1(a.v, 0, 0, 2, 2), b.v), mask),
-                                _mm_mul_ps(vec4f_swizzle1(a.v, 1, 1, 3, 3),
-                                           vec4f_swizzle1(b.v, 1, 0, 3, 2))));
-    #endif
-  }
-};
-
-EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cf,Packet4f)
-
-template<> EIGEN_STRONG_INLINE Packet2cf pdiv<Packet2cf>(const Packet2cf& a, const Packet2cf& b)
-{
-  // TODO optimize it for SSE3 and 4
-  Packet2cf res = conj_helper<Packet2cf,Packet2cf,false,true>().pmul(a,b);
-  __m128 s = _mm_mul_ps(b.v,b.v);
-  return Packet2cf(_mm_div_ps(res.v,_mm_add_ps(s,_mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(s), 0xb1)))));
-}
-
-EIGEN_STRONG_INLINE Packet2cf pcplxflip/* <Packet2cf> */(const Packet2cf& x)
-{
-  return Packet2cf(vec4f_swizzle1(x.v, 1, 0, 3, 2));
-}
-
-
-//---------- double ----------
-struct Packet1cd
-{
-  EIGEN_STRONG_INLINE Packet1cd() {}
-  EIGEN_STRONG_INLINE explicit Packet1cd(const __m128d& a) : v(a) {}
-  __m128d  v;
-};
-
-// Use the packet_traits defined in AVX/PacketMath.h instead if we're going
-// to leverage AVX instructions.
-#ifndef EIGEN_VECTORIZE_AVX
-template<> struct packet_traits<std::complex<double> >  : default_packet_traits
-{
-  typedef Packet1cd type;
-  typedef Packet1cd half;
-  enum {
-    Vectorizable = 1,
-    AlignedOnScalar = 0,
-    size = 1,
-    HasHalfPacket = 0,
-
-    HasAdd    = 1,
-    HasSub    = 1,
-    HasMul    = 1,
-    HasDiv    = 1,
-    HasNegate = 1,
-    HasAbs    = 0,
-    HasAbs2   = 0,
-    HasMin    = 0,
-    HasMax    = 0,
-    HasSetLinear = 0
-  };
-};
-#endif
-
-template<> struct unpacket_traits<Packet1cd> { typedef std::complex<double> type; enum {size=1, alignment=Aligned16}; typedef Packet1cd half; };
-
-template<> EIGEN_STRONG_INLINE Packet1cd padd<Packet1cd>(const Packet1cd& a, const Packet1cd& b) { return Packet1cd(_mm_add_pd(a.v,b.v)); }
-template<> EIGEN_STRONG_INLINE Packet1cd psub<Packet1cd>(const Packet1cd& a, const Packet1cd& b) { return Packet1cd(_mm_sub_pd(a.v,b.v)); }
-template<> EIGEN_STRONG_INLINE Packet1cd pnegate(const Packet1cd& a) { return Packet1cd(pnegate(Packet2d(a.v))); }
-template<> EIGEN_STRONG_INLINE Packet1cd pconj(const Packet1cd& a)
-{
-  const __m128d mask = _mm_castsi128_pd(_mm_set_epi32(0x80000000,0x0,0x0,0x0));
-  return Packet1cd(_mm_xor_pd(a.v,mask));
-}
-
-template<> EIGEN_STRONG_INLINE Packet1cd pmul<Packet1cd>(const Packet1cd& a, const Packet1cd& b)
-{
-  #ifdef EIGEN_VECTORIZE_SSE3
-  return Packet1cd(_mm_addsub_pd(_mm_mul_pd(_mm_movedup_pd(a.v), b.v),
-                                 _mm_mul_pd(vec2d_swizzle1(a.v, 1, 1),
-                                            vec2d_swizzle1(b.v, 1, 0))));
-  #else
-  const __m128d mask = _mm_castsi128_pd(_mm_set_epi32(0x0,0x0,0x80000000,0x0));
-  return Packet1cd(_mm_add_pd(_mm_mul_pd(vec2d_swizzle1(a.v, 0, 0), b.v),
-                              _mm_xor_pd(_mm_mul_pd(vec2d_swizzle1(a.v, 1, 1),
-                                                    vec2d_swizzle1(b.v, 1, 0)), mask)));
-  #endif
-}
-
-template<> EIGEN_STRONG_INLINE Packet1cd pand   <Packet1cd>(const Packet1cd& a, const Packet1cd& b) { return Packet1cd(_mm_and_pd(a.v,b.v)); }
-template<> EIGEN_STRONG_INLINE Packet1cd por    <Packet1cd>(const Packet1cd& a, const Packet1cd& b) { return Packet1cd(_mm_or_pd(a.v,b.v)); }
-template<> EIGEN_STRONG_INLINE Packet1cd pxor   <Packet1cd>(const Packet1cd& a, const Packet1cd& b) { return Packet1cd(_mm_xor_pd(a.v,b.v)); }
-template<> EIGEN_STRONG_INLINE Packet1cd pandnot<Packet1cd>(const Packet1cd& a, const Packet1cd& b) { return Packet1cd(_mm_andnot_pd(a.v,b.v)); }
-
-// FIXME force unaligned load, this is a temporary fix
-template<> EIGEN_STRONG_INLINE Packet1cd pload <Packet1cd>(const std::complex<double>* from)
-{ EIGEN_DEBUG_ALIGNED_LOAD return Packet1cd(pload<Packet2d>((const double*)from)); }
-template<> EIGEN_STRONG_INLINE Packet1cd ploadu<Packet1cd>(const std::complex<double>* from)
-{ EIGEN_DEBUG_UNALIGNED_LOAD return Packet1cd(ploadu<Packet2d>((const double*)from)); }
-template<> EIGEN_STRONG_INLINE Packet1cd pset1<Packet1cd>(const std::complex<double>&  from)
-{ /* here we really have to use unaligned loads :( */ return ploadu<Packet1cd>(&from); }
-
-template<> EIGEN_STRONG_INLINE Packet1cd ploaddup<Packet1cd>(const std::complex<double>* from) { return pset1<Packet1cd>(*from); }
-
-// FIXME force unaligned store, this is a temporary fix
-template<> EIGEN_STRONG_INLINE void pstore <std::complex<double> >(std::complex<double> *   to, const Packet1cd& from) { EIGEN_DEBUG_ALIGNED_STORE pstore((double*)to, Packet2d(from.v)); }
-template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<double> >(std::complex<double> *   to, const Packet1cd& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((double*)to, Packet2d(from.v)); }
-
-template<> EIGEN_STRONG_INLINE void prefetch<std::complex<double> >(const std::complex<double> *   addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); }
-
-template<> EIGEN_STRONG_INLINE std::complex<double>  pfirst<Packet1cd>(const Packet1cd& a)
-{
-  EIGEN_ALIGN16 double res[2];
-  _mm_store_pd(res, a.v);
-  return std::complex<double>(res[0],res[1]);
-}
-
-template<> EIGEN_STRONG_INLINE Packet1cd preverse(const Packet1cd& a) { return a; }
-
-template<> EIGEN_STRONG_INLINE std::complex<double> predux<Packet1cd>(const Packet1cd& a)
-{
-  return pfirst(a);
-}
-
-template<> EIGEN_STRONG_INLINE Packet1cd preduxp<Packet1cd>(const Packet1cd* vecs)
-{
-  return vecs[0];
-}
-
-template<> EIGEN_STRONG_INLINE std::complex<double> predux_mul<Packet1cd>(const Packet1cd& a)
-{
-  return pfirst(a);
-}
-
-template<int Offset>
-struct palign_impl<Offset,Packet1cd>
-{
-  static EIGEN_STRONG_INLINE void run(Packet1cd& /*first*/, const Packet1cd& /*second*/)
-  {
-    // FIXME is it sure we never have to align a Packet1cd?
-    // Even though a std::complex<double> has 16 bytes, it is not necessarily aligned on a 16 bytes boundary...
-  }
-};
-
-template<> struct conj_helper<Packet1cd, Packet1cd, false,true>
-{
-  EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet1cd& x, const Packet1cd& y, const Packet1cd& c) const
-  { return padd(pmul(x,y),c); }
-
-  EIGEN_STRONG_INLINE Packet1cd pmul(const Packet1cd& a, const Packet1cd& b) const
-  {
-    #ifdef EIGEN_VECTORIZE_SSE3
-    return internal::pmul(a, pconj(b));
-    #else
-    const __m128d mask = _mm_castsi128_pd(_mm_set_epi32(0x80000000,0x0,0x0,0x0));
-    return Packet1cd(_mm_add_pd(_mm_xor_pd(_mm_mul_pd(vec2d_swizzle1(a.v, 0, 0), b.v), mask),
-                                _mm_mul_pd(vec2d_swizzle1(a.v, 1, 1),
-                                           vec2d_swizzle1(b.v, 1, 0))));
-    #endif
-  }
-};
-
-template<> struct conj_helper<Packet1cd, Packet1cd, true,false>
-{
-  EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet1cd& x, const Packet1cd& y, const Packet1cd& c) const
-  { return padd(pmul(x,y),c); }
-
-  EIGEN_STRONG_INLINE Packet1cd pmul(const Packet1cd& a, const Packet1cd& b) const
-  {
-    #ifdef EIGEN_VECTORIZE_SSE3
-    return internal::pmul(pconj(a), b);
-    #else
-    const __m128d mask = _mm_castsi128_pd(_mm_set_epi32(0x80000000,0x0,0x0,0x0));
-    return Packet1cd(_mm_add_pd(_mm_mul_pd(vec2d_swizzle1(a.v, 0, 0), b.v),
-                                _mm_xor_pd(_mm_mul_pd(vec2d_swizzle1(a.v, 1, 1),
-                                                      vec2d_swizzle1(b.v, 1, 0)), mask)));
-    #endif
-  }
-};
-
-template<> struct conj_helper<Packet1cd, Packet1cd, true,true>
-{
-  EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet1cd& x, const Packet1cd& y, const Packet1cd& c) const
-  { return padd(pmul(x,y),c); }
-
-  EIGEN_STRONG_INLINE Packet1cd pmul(const Packet1cd& a, const Packet1cd& b) const
-  {
-    #ifdef EIGEN_VECTORIZE_SSE3
-    return pconj(internal::pmul(a, b));
-    #else
-    const __m128d mask = _mm_castsi128_pd(_mm_set_epi32(0x80000000,0x0,0x0,0x0));
-    return Packet1cd(_mm_sub_pd(_mm_xor_pd(_mm_mul_pd(vec2d_swizzle1(a.v, 0, 0), b.v), mask),
-                                _mm_mul_pd(vec2d_swizzle1(a.v, 1, 1),
-                                           vec2d_swizzle1(b.v, 1, 0))));
-    #endif
-  }
-};
-
-EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet1cd,Packet2d)
-
-template<> EIGEN_STRONG_INLINE Packet1cd pdiv<Packet1cd>(const Packet1cd& a, const Packet1cd& b)
-{
-  // TODO optimize it for SSE3 and 4
-  Packet1cd res = conj_helper<Packet1cd,Packet1cd,false,true>().pmul(a,b);
-  __m128d s = _mm_mul_pd(b.v,b.v);
-  return Packet1cd(_mm_div_pd(res.v, _mm_add_pd(s,_mm_shuffle_pd(s, s, 0x1))));
-}
-
-EIGEN_STRONG_INLINE Packet1cd pcplxflip/* <Packet1cd> */(const Packet1cd& x)
-{
-  return Packet1cd(preverse(Packet2d(x.v)));
-}
-
-EIGEN_DEVICE_FUNC inline void
-ptranspose(PacketBlock<Packet2cf,2>& kernel) {
-  __m128d w1 = _mm_castps_pd(kernel.packet[0].v);
-  __m128d w2 = _mm_castps_pd(kernel.packet[1].v);
-
-  __m128 tmp = _mm_castpd_ps(_mm_unpackhi_pd(w1, w2));
-  kernel.packet[0].v = _mm_castpd_ps(_mm_unpacklo_pd(w1, w2));
-  kernel.packet[1].v = tmp;
-}
-
-template<>  EIGEN_STRONG_INLINE Packet2cf pblend(const Selector<2>& ifPacket, const Packet2cf& thenPacket, const Packet2cf& elsePacket) {
-  __m128d result = pblend<Packet2d>(ifPacket, _mm_castps_pd(thenPacket.v), _mm_castps_pd(elsePacket.v));
-  return Packet2cf(_mm_castpd_ps(result));
-}
-
-template<> EIGEN_STRONG_INLINE Packet2cf pinsertfirst(const Packet2cf& a, std::complex<float> b)
-{
-  return Packet2cf(_mm_loadl_pi(a.v, reinterpret_cast<const __m64*>(&b)));
-}
-
-template<> EIGEN_STRONG_INLINE Packet1cd pinsertfirst(const Packet1cd&, std::complex<double> b)
-{
-  return pset1<Packet1cd>(b);
-}
-
-template<> EIGEN_STRONG_INLINE Packet2cf pinsertlast(const Packet2cf& a, std::complex<float> b)
-{
-  return Packet2cf(_mm_loadh_pi(a.v, reinterpret_cast<const __m64*>(&b)));
-}
-
-template<> EIGEN_STRONG_INLINE Packet1cd pinsertlast(const Packet1cd&, std::complex<double> b)
-{
-  return pset1<Packet1cd>(b);
-}
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_COMPLEX_SSE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/SSE/MathFunctions.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/SSE/MathFunctions.h
deleted file mode 100644
index 7b5f948..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/SSE/MathFunctions.h
+++ /dev/null
@@ -1,562 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2007 Julien Pommier
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-/* The sin, cos, exp, and log functions of this file come from
- * Julien Pommier's sse math library: http://gruntthepeon.free.fr/ssemath/
- */
-
-#ifndef EIGEN_MATH_FUNCTIONS_SSE_H
-#define EIGEN_MATH_FUNCTIONS_SSE_H
-
-namespace Eigen {
-
-namespace internal {
-
-template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
-Packet4f plog<Packet4f>(const Packet4f& _x)
-{
-  Packet4f x = _x;
-  _EIGEN_DECLARE_CONST_Packet4f(1 , 1.0f);
-  _EIGEN_DECLARE_CONST_Packet4f(half, 0.5f);
-  _EIGEN_DECLARE_CONST_Packet4i(0x7f, 0x7f);
-
-  _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(inv_mant_mask, ~0x7f800000);
-
-  /* the smallest non denormalized float number */
-  _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(min_norm_pos,  0x00800000);
-  _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(minus_inf,     0xff800000);//-1.f/0.f);
-
-  /* natural logarithm computed for 4 simultaneous float
-    return NaN for x <= 0
-  */
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_SQRTHF, 0.707106781186547524f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p0, 7.0376836292E-2f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p1, - 1.1514610310E-1f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p2, 1.1676998740E-1f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p3, - 1.2420140846E-1f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p4, + 1.4249322787E-1f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p5, - 1.6668057665E-1f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p6, + 2.0000714765E-1f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p7, - 2.4999993993E-1f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_log_p8, + 3.3333331174E-1f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_log_q1, -2.12194440e-4f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_log_q2, 0.693359375f);
-
-
-  Packet4i emm0;
-
-  Packet4f invalid_mask = _mm_cmpnge_ps(x, _mm_setzero_ps()); // not greater equal is true if x is NaN
-  Packet4f iszero_mask = _mm_cmpeq_ps(x, _mm_setzero_ps());
-
-  x = pmax(x, p4f_min_norm_pos);  /* cut off denormalized stuff */
-  emm0 = _mm_srli_epi32(_mm_castps_si128(x), 23);
-
-  /* keep only the fractional part */
-  x = _mm_and_ps(x, p4f_inv_mant_mask);
-  x = _mm_or_ps(x, p4f_half);
-
-  emm0 = _mm_sub_epi32(emm0, p4i_0x7f);
-  Packet4f e = padd(Packet4f(_mm_cvtepi32_ps(emm0)), p4f_1);
-
-  /* part2:
-     if( x < SQRTHF ) {
-       e -= 1;
-       x = x + x - 1.0;
-     } else { x = x - 1.0; }
-  */
-  Packet4f mask = _mm_cmplt_ps(x, p4f_cephes_SQRTHF);
-  Packet4f tmp = pand(x, mask);
-  x = psub(x, p4f_1);
-  e = psub(e, pand(p4f_1, mask));
-  x = padd(x, tmp);
-
-  Packet4f x2 = pmul(x,x);
-  Packet4f x3 = pmul(x2,x);
-
-  Packet4f y, y1, y2;
-  y  = pmadd(p4f_cephes_log_p0, x, p4f_cephes_log_p1);
-  y1 = pmadd(p4f_cephes_log_p3, x, p4f_cephes_log_p4);
-  y2 = pmadd(p4f_cephes_log_p6, x, p4f_cephes_log_p7);
-  y  = pmadd(y , x, p4f_cephes_log_p2);
-  y1 = pmadd(y1, x, p4f_cephes_log_p5);
-  y2 = pmadd(y2, x, p4f_cephes_log_p8);
-  y = pmadd(y, x3, y1);
-  y = pmadd(y, x3, y2);
-  y = pmul(y, x3);
-
-  y1 = pmul(e, p4f_cephes_log_q1);
-  tmp = pmul(x2, p4f_half);
-  y = padd(y, y1);
-  x = psub(x, tmp);
-  y2 = pmul(e, p4f_cephes_log_q2);
-  x = padd(x, y);
-  x = padd(x, y2);
-  // negative arg will be NAN, 0 will be -INF
-  return _mm_or_ps(_mm_andnot_ps(iszero_mask, _mm_or_ps(x, invalid_mask)),
-                   _mm_and_ps(iszero_mask, p4f_minus_inf));
-}
-
-template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
-Packet4f pexp<Packet4f>(const Packet4f& _x)
-{
-  Packet4f x = _x;
-  _EIGEN_DECLARE_CONST_Packet4f(1 , 1.0f);
-  _EIGEN_DECLARE_CONST_Packet4f(half, 0.5f);
-  _EIGEN_DECLARE_CONST_Packet4i(0x7f, 0x7f);
-
-
-  _EIGEN_DECLARE_CONST_Packet4f(exp_hi,  88.3762626647950f);
-  _EIGEN_DECLARE_CONST_Packet4f(exp_lo, -88.3762626647949f);
-
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_LOG2EF, 1.44269504088896341f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_C1, 0.693359375f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_C2, -2.12194440e-4f);
-
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p0, 1.9875691500E-4f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p1, 1.3981999507E-3f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p2, 8.3334519073E-3f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p3, 4.1665795894E-2f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p4, 1.6666665459E-1f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_exp_p5, 5.0000001201E-1f);
-
-  Packet4f tmp, fx;
-  Packet4i emm0;
-
-  // clamp x
-  x = pmax(pmin(x, p4f_exp_hi), p4f_exp_lo);
-
-  /* express exp(x) as exp(g + n*log(2)) */
-  fx = pmadd(x, p4f_cephes_LOG2EF, p4f_half);
-
-#ifdef EIGEN_VECTORIZE_SSE4_1
-  fx = _mm_floor_ps(fx);
-#else
-  emm0 = _mm_cvttps_epi32(fx);
-  tmp  = _mm_cvtepi32_ps(emm0);
-  /* if greater, substract 1 */
-  Packet4f mask = _mm_cmpgt_ps(tmp, fx);
-  mask = _mm_and_ps(mask, p4f_1);
-  fx = psub(tmp, mask);
-#endif
-
-  tmp = pmul(fx, p4f_cephes_exp_C1);
-  Packet4f z = pmul(fx, p4f_cephes_exp_C2);
-  x = psub(x, tmp);
-  x = psub(x, z);
-
-  z = pmul(x,x);
-
-  Packet4f y = p4f_cephes_exp_p0;
-  y = pmadd(y, x, p4f_cephes_exp_p1);
-  y = pmadd(y, x, p4f_cephes_exp_p2);
-  y = pmadd(y, x, p4f_cephes_exp_p3);
-  y = pmadd(y, x, p4f_cephes_exp_p4);
-  y = pmadd(y, x, p4f_cephes_exp_p5);
-  y = pmadd(y, z, x);
-  y = padd(y, p4f_1);
-
-  // build 2^n
-  emm0 = _mm_cvttps_epi32(fx);
-  emm0 = _mm_add_epi32(emm0, p4i_0x7f);
-  emm0 = _mm_slli_epi32(emm0, 23);
-  return pmax(pmul(y, Packet4f(_mm_castsi128_ps(emm0))), _x);
-}
-template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
-Packet2d pexp<Packet2d>(const Packet2d& _x)
-{
-  Packet2d x = _x;
-
-  _EIGEN_DECLARE_CONST_Packet2d(1 , 1.0);
-  _EIGEN_DECLARE_CONST_Packet2d(2 , 2.0);
-  _EIGEN_DECLARE_CONST_Packet2d(half, 0.5);
-
-  _EIGEN_DECLARE_CONST_Packet2d(exp_hi,  709.437);
-  _EIGEN_DECLARE_CONST_Packet2d(exp_lo, -709.436139303);
-
-  _EIGEN_DECLARE_CONST_Packet2d(cephes_LOG2EF, 1.4426950408889634073599);
-
-  _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_p0, 1.26177193074810590878e-4);
-  _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_p1, 3.02994407707441961300e-2);
-  _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_p2, 9.99999999999999999910e-1);
-
-  _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_q0, 3.00198505138664455042e-6);
-  _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_q1, 2.52448340349684104192e-3);
-  _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_q2, 2.27265548208155028766e-1);
-  _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_q3, 2.00000000000000000009e0);
-
-  _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_C1, 0.693145751953125);
-  _EIGEN_DECLARE_CONST_Packet2d(cephes_exp_C2, 1.42860682030941723212e-6);
-  static const __m128i p4i_1023_0 = _mm_setr_epi32(1023, 1023, 0, 0);
-
-  Packet2d tmp, fx;
-  Packet4i emm0;
-
-  // clamp x
-  x = pmax(pmin(x, p2d_exp_hi), p2d_exp_lo);
-  /* express exp(x) as exp(g + n*log(2)) */
-  fx = pmadd(p2d_cephes_LOG2EF, x, p2d_half);
-
-#ifdef EIGEN_VECTORIZE_SSE4_1
-  fx = _mm_floor_pd(fx);
-#else
-  emm0 = _mm_cvttpd_epi32(fx);
-  tmp  = _mm_cvtepi32_pd(emm0);
-  /* if greater, substract 1 */
-  Packet2d mask = _mm_cmpgt_pd(tmp, fx);
-  mask = _mm_and_pd(mask, p2d_1);
-  fx = psub(tmp, mask);
-#endif
-
-  tmp = pmul(fx, p2d_cephes_exp_C1);
-  Packet2d z = pmul(fx, p2d_cephes_exp_C2);
-  x = psub(x, tmp);
-  x = psub(x, z);
-
-  Packet2d x2 = pmul(x,x);
-
-  Packet2d px = p2d_cephes_exp_p0;
-  px = pmadd(px, x2, p2d_cephes_exp_p1);
-  px = pmadd(px, x2, p2d_cephes_exp_p2);
-  px = pmul (px, x);
-
-  Packet2d qx = p2d_cephes_exp_q0;
-  qx = pmadd(qx, x2, p2d_cephes_exp_q1);
-  qx = pmadd(qx, x2, p2d_cephes_exp_q2);
-  qx = pmadd(qx, x2, p2d_cephes_exp_q3);
-
-  x = pdiv(px,psub(qx,px));
-  x = pmadd(p2d_2,x,p2d_1);
-
-  // build 2^n
-  emm0 = _mm_cvttpd_epi32(fx);
-  emm0 = _mm_add_epi32(emm0, p4i_1023_0);
-  emm0 = _mm_slli_epi32(emm0, 20);
-  emm0 = _mm_shuffle_epi32(emm0, _MM_SHUFFLE(1,2,0,3));
-  return pmax(pmul(x, Packet2d(_mm_castsi128_pd(emm0))), _x);
-}
-
-/* evaluation of 4 sines at onces, using SSE2 intrinsics.
-
-   The code is the exact rewriting of the cephes sinf function.
-   Precision is excellent as long as x < 8192 (I did not bother to
-   take into account the special handling they have for greater values
-   -- it does not return garbage for arguments over 8192, though, but
-   the extra precision is missing).
-
-   Note that it is such that sinf((float)M_PI) = 8.74e-8, which is the
-   surprising but correct result.
-*/
-
-template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
-Packet4f psin<Packet4f>(const Packet4f& _x)
-{
-  Packet4f x = _x;
-  _EIGEN_DECLARE_CONST_Packet4f(1 , 1.0f);
-  _EIGEN_DECLARE_CONST_Packet4f(half, 0.5f);
-
-  _EIGEN_DECLARE_CONST_Packet4i(1, 1);
-  _EIGEN_DECLARE_CONST_Packet4i(not1, ~1);
-  _EIGEN_DECLARE_CONST_Packet4i(2, 2);
-  _EIGEN_DECLARE_CONST_Packet4i(4, 4);
-
-  _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(sign_mask, 0x80000000);
-
-  _EIGEN_DECLARE_CONST_Packet4f(minus_cephes_DP1,-0.78515625f);
-  _EIGEN_DECLARE_CONST_Packet4f(minus_cephes_DP2, -2.4187564849853515625e-4f);
-  _EIGEN_DECLARE_CONST_Packet4f(minus_cephes_DP3, -3.77489497744594108e-8f);
-  _EIGEN_DECLARE_CONST_Packet4f(sincof_p0, -1.9515295891E-4f);
-  _EIGEN_DECLARE_CONST_Packet4f(sincof_p1,  8.3321608736E-3f);
-  _EIGEN_DECLARE_CONST_Packet4f(sincof_p2, -1.6666654611E-1f);
-  _EIGEN_DECLARE_CONST_Packet4f(coscof_p0,  2.443315711809948E-005f);
-  _EIGEN_DECLARE_CONST_Packet4f(coscof_p1, -1.388731625493765E-003f);
-  _EIGEN_DECLARE_CONST_Packet4f(coscof_p2,  4.166664568298827E-002f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_FOPI, 1.27323954473516f); // 4 / M_PI
-
-  Packet4f xmm1, xmm2, xmm3, sign_bit, y;
-
-  Packet4i emm0, emm2;
-  sign_bit = x;
-  /* take the absolute value */
-  x = pabs(x);
-
-  /* take the modulo */
-
-  /* extract the sign bit (upper one) */
-  sign_bit = _mm_and_ps(sign_bit, p4f_sign_mask);
-
-  /* scale by 4/Pi */
-  y = pmul(x, p4f_cephes_FOPI);
-
-  /* store the integer part of y in mm0 */
-  emm2 = _mm_cvttps_epi32(y);
-  /* j=(j+1) & (~1) (see the cephes sources) */
-  emm2 = _mm_add_epi32(emm2, p4i_1);
-  emm2 = _mm_and_si128(emm2, p4i_not1);
-  y = _mm_cvtepi32_ps(emm2);
-  /* get the swap sign flag */
-  emm0 = _mm_and_si128(emm2, p4i_4);
-  emm0 = _mm_slli_epi32(emm0, 29);
-  /* get the polynom selection mask
-     there is one polynom for 0 <= x <= Pi/4
-     and another one for Pi/4<x<=Pi/2
-
-     Both branches will be computed.
-  */
-  emm2 = _mm_and_si128(emm2, p4i_2);
-  emm2 = _mm_cmpeq_epi32(emm2, _mm_setzero_si128());
-
-  Packet4f swap_sign_bit = _mm_castsi128_ps(emm0);
-  Packet4f poly_mask = _mm_castsi128_ps(emm2);
-  sign_bit = _mm_xor_ps(sign_bit, swap_sign_bit);
-
-  /* The magic pass: "Extended precision modular arithmetic"
-     x = ((x - y * DP1) - y * DP2) - y * DP3; */
-  xmm1 = pmul(y, p4f_minus_cephes_DP1);
-  xmm2 = pmul(y, p4f_minus_cephes_DP2);
-  xmm3 = pmul(y, p4f_minus_cephes_DP3);
-  x = padd(x, xmm1);
-  x = padd(x, xmm2);
-  x = padd(x, xmm3);
-
-  /* Evaluate the first polynom  (0 <= x <= Pi/4) */
-  y = p4f_coscof_p0;
-  Packet4f z = _mm_mul_ps(x,x);
-
-  y = pmadd(y, z, p4f_coscof_p1);
-  y = pmadd(y, z, p4f_coscof_p2);
-  y = pmul(y, z);
-  y = pmul(y, z);
-  Packet4f tmp = pmul(z, p4f_half);
-  y = psub(y, tmp);
-  y = padd(y, p4f_1);
-
-  /* Evaluate the second polynom  (Pi/4 <= x <= 0) */
-
-  Packet4f y2 = p4f_sincof_p0;
-  y2 = pmadd(y2, z, p4f_sincof_p1);
-  y2 = pmadd(y2, z, p4f_sincof_p2);
-  y2 = pmul(y2, z);
-  y2 = pmul(y2, x);
-  y2 = padd(y2, x);
-
-  /* select the correct result from the two polynoms */
-  y2 = _mm_and_ps(poly_mask, y2);
-  y = _mm_andnot_ps(poly_mask, y);
-  y = _mm_or_ps(y,y2);
-  /* update the sign */
-  return _mm_xor_ps(y, sign_bit);
-}
-
-/* almost the same as psin */
-template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
-Packet4f pcos<Packet4f>(const Packet4f& _x)
-{
-  Packet4f x = _x;
-  _EIGEN_DECLARE_CONST_Packet4f(1 , 1.0f);
-  _EIGEN_DECLARE_CONST_Packet4f(half, 0.5f);
-
-  _EIGEN_DECLARE_CONST_Packet4i(1, 1);
-  _EIGEN_DECLARE_CONST_Packet4i(not1, ~1);
-  _EIGEN_DECLARE_CONST_Packet4i(2, 2);
-  _EIGEN_DECLARE_CONST_Packet4i(4, 4);
-
-  _EIGEN_DECLARE_CONST_Packet4f(minus_cephes_DP1,-0.78515625f);
-  _EIGEN_DECLARE_CONST_Packet4f(minus_cephes_DP2, -2.4187564849853515625e-4f);
-  _EIGEN_DECLARE_CONST_Packet4f(minus_cephes_DP3, -3.77489497744594108e-8f);
-  _EIGEN_DECLARE_CONST_Packet4f(sincof_p0, -1.9515295891E-4f);
-  _EIGEN_DECLARE_CONST_Packet4f(sincof_p1,  8.3321608736E-3f);
-  _EIGEN_DECLARE_CONST_Packet4f(sincof_p2, -1.6666654611E-1f);
-  _EIGEN_DECLARE_CONST_Packet4f(coscof_p0,  2.443315711809948E-005f);
-  _EIGEN_DECLARE_CONST_Packet4f(coscof_p1, -1.388731625493765E-003f);
-  _EIGEN_DECLARE_CONST_Packet4f(coscof_p2,  4.166664568298827E-002f);
-  _EIGEN_DECLARE_CONST_Packet4f(cephes_FOPI, 1.27323954473516f); // 4 / M_PI
-
-  Packet4f xmm1, xmm2, xmm3, y;
-  Packet4i emm0, emm2;
-
-  x = pabs(x);
-
-  /* scale by 4/Pi */
-  y = pmul(x, p4f_cephes_FOPI);
-
-  /* get the integer part of y */
-  emm2 = _mm_cvttps_epi32(y);
-  /* j=(j+1) & (~1) (see the cephes sources) */
-  emm2 = _mm_add_epi32(emm2, p4i_1);
-  emm2 = _mm_and_si128(emm2, p4i_not1);
-  y = _mm_cvtepi32_ps(emm2);
-
-  emm2 = _mm_sub_epi32(emm2, p4i_2);
-
-  /* get the swap sign flag */
-  emm0 = _mm_andnot_si128(emm2, p4i_4);
-  emm0 = _mm_slli_epi32(emm0, 29);
-  /* get the polynom selection mask */
-  emm2 = _mm_and_si128(emm2, p4i_2);
-  emm2 = _mm_cmpeq_epi32(emm2, _mm_setzero_si128());
-
-  Packet4f sign_bit = _mm_castsi128_ps(emm0);
-  Packet4f poly_mask = _mm_castsi128_ps(emm2);
-
-  /* The magic pass: "Extended precision modular arithmetic"
-     x = ((x - y * DP1) - y * DP2) - y * DP3; */
-  xmm1 = pmul(y, p4f_minus_cephes_DP1);
-  xmm2 = pmul(y, p4f_minus_cephes_DP2);
-  xmm3 = pmul(y, p4f_minus_cephes_DP3);
-  x = padd(x, xmm1);
-  x = padd(x, xmm2);
-  x = padd(x, xmm3);
-
-  /* Evaluate the first polynom  (0 <= x <= Pi/4) */
-  y = p4f_coscof_p0;
-  Packet4f z = pmul(x,x);
-
-  y = pmadd(y,z,p4f_coscof_p1);
-  y = pmadd(y,z,p4f_coscof_p2);
-  y = pmul(y, z);
-  y = pmul(y, z);
-  Packet4f tmp = _mm_mul_ps(z, p4f_half);
-  y = psub(y, tmp);
-  y = padd(y, p4f_1);
-
-  /* Evaluate the second polynom  (Pi/4 <= x <= 0) */
-  Packet4f y2 = p4f_sincof_p0;
-  y2 = pmadd(y2, z, p4f_sincof_p1);
-  y2 = pmadd(y2, z, p4f_sincof_p2);
-  y2 = pmul(y2, z);
-  y2 = pmadd(y2, x, x);
-
-  /* select the correct result from the two polynoms */
-  y2 = _mm_and_ps(poly_mask, y2);
-  y  = _mm_andnot_ps(poly_mask, y);
-  y  = _mm_or_ps(y,y2);
-
-  /* update the sign */
-  return _mm_xor_ps(y, sign_bit);
-}
-
-#if EIGEN_FAST_MATH
-
-// Functions for sqrt.
-// The EIGEN_FAST_MATH version uses the _mm_rsqrt_ps approximation and one step
-// of Newton's method, at a cost of 1-2 bits of precision as opposed to the
-// exact solution. It does not handle +inf, or denormalized numbers correctly.
-// The main advantage of this approach is not just speed, but also the fact that
-// it can be inlined and pipelined with other computations, further reducing its
-// effective latency. This is similar to Quake3's fast inverse square root.
-// For detail see here: http://www.beyond3d.com/content/articles/8/
-template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
-Packet4f psqrt<Packet4f>(const Packet4f& _x)
-{
-  Packet4f half = pmul(_x, pset1<Packet4f>(.5f));
-  Packet4f denormal_mask = _mm_and_ps(
-      _mm_cmpge_ps(_x, _mm_setzero_ps()),
-      _mm_cmplt_ps(_x, pset1<Packet4f>((std::numeric_limits<float>::min)())));
-
-  // Compute approximate reciprocal sqrt.
-  Packet4f x = _mm_rsqrt_ps(_x);
-  // Do a single step of Newton's iteration.
-  x = pmul(x, psub(pset1<Packet4f>(1.5f), pmul(half, pmul(x,x))));
-  // Flush results for denormals to zero.
-  return _mm_andnot_ps(denormal_mask, pmul(_x,x));
-}
-
-#else
-
-template<>EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
-Packet4f psqrt<Packet4f>(const Packet4f& x) { return _mm_sqrt_ps(x); }
-
-#endif
-
-template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
-Packet2d psqrt<Packet2d>(const Packet2d& x) { return _mm_sqrt_pd(x); }
-
-#if EIGEN_FAST_MATH
-
-template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
-Packet4f prsqrt<Packet4f>(const Packet4f& _x) {
-  _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(inf, 0x7f800000);
-  _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(nan, 0x7fc00000);
-  _EIGEN_DECLARE_CONST_Packet4f(one_point_five, 1.5f);
-  _EIGEN_DECLARE_CONST_Packet4f(minus_half, -0.5f);
-  _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(flt_min, 0x00800000);
-
-  Packet4f neg_half = pmul(_x, p4f_minus_half);
-
-  // select only the inverse sqrt of positive normal inputs (denormals are
-  // flushed to zero and cause infs as well).
-  Packet4f le_zero_mask = _mm_cmple_ps(_x, p4f_flt_min);
-  Packet4f x = _mm_andnot_ps(le_zero_mask, _mm_rsqrt_ps(_x));
-
-  // Fill in NaNs and Infs for the negative/zero entries.
-  Packet4f neg_mask = _mm_cmplt_ps(_x, _mm_setzero_ps());
-  Packet4f zero_mask = _mm_andnot_ps(neg_mask, le_zero_mask);
-  Packet4f infs_and_nans = _mm_or_ps(_mm_and_ps(neg_mask, p4f_nan),
-                                     _mm_and_ps(zero_mask, p4f_inf));
-
-  // Do a single step of Newton's iteration.
-  x = pmul(x, pmadd(neg_half, pmul(x, x), p4f_one_point_five));
-
-  // Insert NaNs and Infs in all the right places.
-  return _mm_or_ps(x, infs_and_nans);
-}
-
-#else
-
-template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
-Packet4f prsqrt<Packet4f>(const Packet4f& x) {
-  // Unfortunately we can't use the much faster mm_rqsrt_ps since it only provides an approximation.
-  return _mm_div_ps(pset1<Packet4f>(1.0f), _mm_sqrt_ps(x));
-}
-
-#endif
-
-template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
-Packet2d prsqrt<Packet2d>(const Packet2d& x) {
-  // Unfortunately we can't use the much faster mm_rqsrt_pd since it only provides an approximation.
-  return _mm_div_pd(pset1<Packet2d>(1.0), _mm_sqrt_pd(x));
-}
-
-// Hyperbolic Tangent function.
-template <>
-EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet4f
-ptanh<Packet4f>(const Packet4f& x) {
-  return internal::generic_fast_tanh_float(x);
-}
-
-} // end namespace internal
-
-namespace numext {
-
-template<>
-EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-float sqrt(const float &x)
-{
-  return internal::pfirst(internal::Packet4f(_mm_sqrt_ss(_mm_set_ss(x))));
-}
-
-template<>
-EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-double sqrt(const double &x)
-{
-#if EIGEN_COMP_GNUC_STRICT
-  // This works around a GCC bug generating poor code for _mm_sqrt_pd
-  // See https://bitbucket.org/eigen/eigen/commits/14f468dba4d350d7c19c9b93072e19f7b3df563b
-  return internal::pfirst(internal::Packet2d(__builtin_ia32_sqrtsd(_mm_set_sd(x))));
-#else
-  return internal::pfirst(internal::Packet2d(_mm_sqrt_pd(_mm_set_sd(x))));
-#endif
-}
-
-} // end namespace numex
-
-} // end namespace Eigen
-
-#endif // EIGEN_MATH_FUNCTIONS_SSE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/SSE/PacketMath.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/SSE/PacketMath.h
deleted file mode 100644
index 60e2517..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/SSE/PacketMath.h
+++ /dev/null
@@ -1,895 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_PACKET_MATH_SSE_H
-#define EIGEN_PACKET_MATH_SSE_H
-
-namespace Eigen {
-
-namespace internal {
-
-#ifndef EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD
-#define EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD 8
-#endif
-
-#ifndef EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS
-#define EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS (2*sizeof(void*))
-#endif
-
-#ifdef __FMA__
-#ifndef EIGEN_HAS_SINGLE_INSTRUCTION_MADD
-#define EIGEN_HAS_SINGLE_INSTRUCTION_MADD 1
-#endif
-#endif
-
-#if ((defined EIGEN_VECTORIZE_AVX) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_MINGW) && (__GXX_ABI_VERSION < 1004)) || EIGEN_OS_QNX
-// With GCC's default ABI version, a __m128 or __m256 are the same types and therefore we cannot
-// have overloads for both types without linking error.
-// One solution is to increase ABI version using -fabi-version=4 (or greater).
-// Otherwise, we workaround this inconvenience by wrapping 128bit types into the following helper
-// structure:
-template<typename T>
-struct eigen_packet_wrapper
-{
-  EIGEN_ALWAYS_INLINE operator T&() { return m_val; }
-  EIGEN_ALWAYS_INLINE operator const T&() const { return m_val; }
-  EIGEN_ALWAYS_INLINE eigen_packet_wrapper() {}
-  EIGEN_ALWAYS_INLINE eigen_packet_wrapper(const T &v) : m_val(v) {}
-  EIGEN_ALWAYS_INLINE eigen_packet_wrapper& operator=(const T &v) {
-    m_val = v;
-    return *this;
-  }
-  
-  T m_val;
-};
-typedef eigen_packet_wrapper<__m128>  Packet4f;
-typedef eigen_packet_wrapper<__m128i> Packet4i;
-typedef eigen_packet_wrapper<__m128d> Packet2d;
-#else
-typedef __m128  Packet4f;
-typedef __m128i Packet4i;
-typedef __m128d Packet2d;
-#endif
-
-template<> struct is_arithmetic<__m128>  { enum { value = true }; };
-template<> struct is_arithmetic<__m128i> { enum { value = true }; };
-template<> struct is_arithmetic<__m128d> { enum { value = true }; };
-
-#define vec4f_swizzle1(v,p,q,r,s) \
-  (_mm_castsi128_ps(_mm_shuffle_epi32( _mm_castps_si128(v), ((s)<<6|(r)<<4|(q)<<2|(p)))))
-
-#define vec4i_swizzle1(v,p,q,r,s) \
-  (_mm_shuffle_epi32( v, ((s)<<6|(r)<<4|(q)<<2|(p))))
-
-#define vec2d_swizzle1(v,p,q) \
-  (_mm_castsi128_pd(_mm_shuffle_epi32( _mm_castpd_si128(v), ((q*2+1)<<6|(q*2)<<4|(p*2+1)<<2|(p*2)))))
-  
-#define vec4f_swizzle2(a,b,p,q,r,s) \
-  (_mm_shuffle_ps( (a), (b), ((s)<<6|(r)<<4|(q)<<2|(p))))
-
-#define vec4i_swizzle2(a,b,p,q,r,s) \
-  (_mm_castps_si128( (_mm_shuffle_ps( _mm_castsi128_ps(a), _mm_castsi128_ps(b), ((s)<<6|(r)<<4|(q)<<2|(p))))))
-
-#define _EIGEN_DECLARE_CONST_Packet4f(NAME,X) \
-  const Packet4f p4f_##NAME = pset1<Packet4f>(X)
-
-#define _EIGEN_DECLARE_CONST_Packet2d(NAME,X) \
-  const Packet2d p2d_##NAME = pset1<Packet2d>(X)
-
-#define _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(NAME,X) \
-  const Packet4f p4f_##NAME = _mm_castsi128_ps(pset1<Packet4i>(X))
-
-#define _EIGEN_DECLARE_CONST_Packet4i(NAME,X) \
-  const Packet4i p4i_##NAME = pset1<Packet4i>(X)
-
-
-// Use the packet_traits defined in AVX/PacketMath.h instead if we're going
-// to leverage AVX instructions.
-#ifndef EIGEN_VECTORIZE_AVX
-template<> struct packet_traits<float>  : default_packet_traits
-{
-  typedef Packet4f type;
-  typedef Packet4f half;
-  enum {
-    Vectorizable = 1,
-    AlignedOnScalar = 1,
-    size=4,
-    HasHalfPacket = 0,
-
-    HasDiv  = 1,
-    HasSin  = EIGEN_FAST_MATH,
-    HasCos  = EIGEN_FAST_MATH,
-    HasLog  = 1,
-    HasExp  = 1,
-    HasSqrt = 1,
-    HasRsqrt = 1,
-    HasTanh  = EIGEN_FAST_MATH,
-    HasBlend = 1
-
-#ifdef EIGEN_VECTORIZE_SSE4_1
-    ,
-    HasRound = 1,
-    HasFloor = 1,
-    HasCeil = 1
-#endif
-  };
-};
-template<> struct packet_traits<double> : default_packet_traits
-{
-  typedef Packet2d type;
-  typedef Packet2d half;
-  enum {
-    Vectorizable = 1,
-    AlignedOnScalar = 1,
-    size=2,
-    HasHalfPacket = 0,
-
-    HasDiv  = 1,
-    HasExp  = 1,
-    HasSqrt = 1,
-    HasRsqrt = 1,
-    HasBlend = 1
-
-#ifdef EIGEN_VECTORIZE_SSE4_1
-    ,
-    HasRound = 1,
-    HasFloor = 1,
-    HasCeil = 1
-#endif
-  };
-};
-#endif
-template<> struct packet_traits<int>    : default_packet_traits
-{
-  typedef Packet4i type;
-  typedef Packet4i half;
-  enum {
-    Vectorizable = 1,
-    AlignedOnScalar = 1,
-    size=4,
-
-    HasBlend = 1
-  };
-};
-
-template<> struct unpacket_traits<Packet4f> { typedef float  type; enum {size=4, alignment=Aligned16}; typedef Packet4f half; };
-template<> struct unpacket_traits<Packet2d> { typedef double type; enum {size=2, alignment=Aligned16}; typedef Packet2d half; };
-template<> struct unpacket_traits<Packet4i> { typedef int    type; enum {size=4, alignment=Aligned16}; typedef Packet4i half; };
-
-#ifndef EIGEN_VECTORIZE_AVX
-template<> struct scalar_div_cost<float,true> { enum { value = 7 }; };
-template<> struct scalar_div_cost<double,true> { enum { value = 8 }; };
-#endif
-
-#if EIGEN_COMP_MSVC==1500
-// Workaround MSVC 9 internal compiler error.
-// TODO: It has been detected with win64 builds (amd64), so let's check whether it also happens in 32bits+SSE mode
-// TODO: let's check whether there does not exist a better fix, like adding a pset0() function. (it crashed on pset1(0)).
-template<> EIGEN_STRONG_INLINE Packet4f pset1<Packet4f>(const float&  from) { return _mm_set_ps(from,from,from,from); }
-template<> EIGEN_STRONG_INLINE Packet2d pset1<Packet2d>(const double& from) { return _mm_set_pd(from,from); }
-template<> EIGEN_STRONG_INLINE Packet4i pset1<Packet4i>(const int&    from) { return _mm_set_epi32(from,from,from,from); }
-#else
-template<> EIGEN_STRONG_INLINE Packet4f pset1<Packet4f>(const float&  from) { return _mm_set_ps1(from); }
-template<> EIGEN_STRONG_INLINE Packet2d pset1<Packet2d>(const double& from) { return _mm_set1_pd(from); }
-template<> EIGEN_STRONG_INLINE Packet4i pset1<Packet4i>(const int&    from) { return _mm_set1_epi32(from); }
-#endif
-
-// GCC generates a shufps instruction for _mm_set1_ps/_mm_load1_ps instead of the more efficient pshufd instruction.
-// However, using inrinsics for pset1 makes gcc to generate crappy code in some cases (see bug 203)
-// Using inline assembly is also not an option because then gcc fails to reorder properly the instructions.
-// Therefore, we introduced the pload1 functions to be used in product kernels for which bug 203 does not apply.
-// Also note that with AVX, we want it to generate a vbroadcastss.
-#if EIGEN_COMP_GNUC_STRICT && (!defined __AVX__)
-template<> EIGEN_STRONG_INLINE Packet4f pload1<Packet4f>(const float *from) {
-  return vec4f_swizzle1(_mm_load_ss(from),0,0,0,0);
-}
-#endif
-  
-template<> EIGEN_STRONG_INLINE Packet4f plset<Packet4f>(const float& a) { return _mm_add_ps(pset1<Packet4f>(a), _mm_set_ps(3,2,1,0)); }
-template<> EIGEN_STRONG_INLINE Packet2d plset<Packet2d>(const double& a) { return _mm_add_pd(pset1<Packet2d>(a),_mm_set_pd(1,0)); }
-template<> EIGEN_STRONG_INLINE Packet4i plset<Packet4i>(const int& a) { return _mm_add_epi32(pset1<Packet4i>(a),_mm_set_epi32(3,2,1,0)); }
-
-template<> EIGEN_STRONG_INLINE Packet4f padd<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_add_ps(a,b); }
-template<> EIGEN_STRONG_INLINE Packet2d padd<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_add_pd(a,b); }
-template<> EIGEN_STRONG_INLINE Packet4i padd<Packet4i>(const Packet4i& a, const Packet4i& b) { return _mm_add_epi32(a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet4f psub<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_sub_ps(a,b); }
-template<> EIGEN_STRONG_INLINE Packet2d psub<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_sub_pd(a,b); }
-template<> EIGEN_STRONG_INLINE Packet4i psub<Packet4i>(const Packet4i& a, const Packet4i& b) { return _mm_sub_epi32(a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet4f pnegate(const Packet4f& a)
-{
-  const Packet4f mask = _mm_castsi128_ps(_mm_setr_epi32(0x80000000,0x80000000,0x80000000,0x80000000));
-  return _mm_xor_ps(a,mask);
-}
-template<> EIGEN_STRONG_INLINE Packet2d pnegate(const Packet2d& a)
-{
-  const Packet2d mask = _mm_castsi128_pd(_mm_setr_epi32(0x0,0x80000000,0x0,0x80000000));
-  return _mm_xor_pd(a,mask);
-}
-template<> EIGEN_STRONG_INLINE Packet4i pnegate(const Packet4i& a)
-{
-  return psub(Packet4i(_mm_setr_epi32(0,0,0,0)), a);
-}
-
-template<> EIGEN_STRONG_INLINE Packet4f pconj(const Packet4f& a) { return a; }
-template<> EIGEN_STRONG_INLINE Packet2d pconj(const Packet2d& a) { return a; }
-template<> EIGEN_STRONG_INLINE Packet4i pconj(const Packet4i& a) { return a; }
-
-template<> EIGEN_STRONG_INLINE Packet4f pmul<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_mul_ps(a,b); }
-template<> EIGEN_STRONG_INLINE Packet2d pmul<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_mul_pd(a,b); }
-template<> EIGEN_STRONG_INLINE Packet4i pmul<Packet4i>(const Packet4i& a, const Packet4i& b)
-{
-#ifdef EIGEN_VECTORIZE_SSE4_1
-  return _mm_mullo_epi32(a,b);
-#else
-  // this version is slightly faster than 4 scalar products
-  return vec4i_swizzle1(
-            vec4i_swizzle2(
-              _mm_mul_epu32(a,b),
-              _mm_mul_epu32(vec4i_swizzle1(a,1,0,3,2),
-                            vec4i_swizzle1(b,1,0,3,2)),
-              0,2,0,2),
-            0,2,1,3);
-#endif
-}
-
-template<> EIGEN_STRONG_INLINE Packet4f pdiv<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_div_ps(a,b); }
-template<> EIGEN_STRONG_INLINE Packet2d pdiv<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_div_pd(a,b); }
-
-// for some weird raisons, it has to be overloaded for packet of integers
-template<> EIGEN_STRONG_INLINE Packet4i pmadd(const Packet4i& a, const Packet4i& b, const Packet4i& c) { return padd(pmul(a,b), c); }
-#ifdef __FMA__
-template<> EIGEN_STRONG_INLINE Packet4f pmadd(const Packet4f& a, const Packet4f& b, const Packet4f& c) { return _mm_fmadd_ps(a,b,c); }
-template<> EIGEN_STRONG_INLINE Packet2d pmadd(const Packet2d& a, const Packet2d& b, const Packet2d& c) { return _mm_fmadd_pd(a,b,c); }
-#endif
-
-template<> EIGEN_STRONG_INLINE Packet4f pmin<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_min_ps(a,b); }
-template<> EIGEN_STRONG_INLINE Packet2d pmin<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_min_pd(a,b); }
-template<> EIGEN_STRONG_INLINE Packet4i pmin<Packet4i>(const Packet4i& a, const Packet4i& b)
-{
-#ifdef EIGEN_VECTORIZE_SSE4_1
-  return _mm_min_epi32(a,b);
-#else
-  // after some bench, this version *is* faster than a scalar implementation
-  Packet4i mask = _mm_cmplt_epi32(a,b);
-  return _mm_or_si128(_mm_and_si128(mask,a),_mm_andnot_si128(mask,b));
-#endif
-}
-
-template<> EIGEN_STRONG_INLINE Packet4f pmax<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_max_ps(a,b); }
-template<> EIGEN_STRONG_INLINE Packet2d pmax<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_max_pd(a,b); }
-template<> EIGEN_STRONG_INLINE Packet4i pmax<Packet4i>(const Packet4i& a, const Packet4i& b)
-{
-#ifdef EIGEN_VECTORIZE_SSE4_1
-  return _mm_max_epi32(a,b);
-#else
-  // after some bench, this version *is* faster than a scalar implementation
-  Packet4i mask = _mm_cmpgt_epi32(a,b);
-  return _mm_or_si128(_mm_and_si128(mask,a),_mm_andnot_si128(mask,b));
-#endif
-}
-
-#ifdef EIGEN_VECTORIZE_SSE4_1
-template<> EIGEN_STRONG_INLINE Packet4f pround<Packet4f>(const Packet4f& a) { return _mm_round_ps(a, 0); }
-template<> EIGEN_STRONG_INLINE Packet2d pround<Packet2d>(const Packet2d& a) { return _mm_round_pd(a, 0); }
-
-template<> EIGEN_STRONG_INLINE Packet4f pceil<Packet4f>(const Packet4f& a) { return _mm_ceil_ps(a); }
-template<> EIGEN_STRONG_INLINE Packet2d pceil<Packet2d>(const Packet2d& a) { return _mm_ceil_pd(a); }
-
-template<> EIGEN_STRONG_INLINE Packet4f pfloor<Packet4f>(const Packet4f& a) { return _mm_floor_ps(a); }
-template<> EIGEN_STRONG_INLINE Packet2d pfloor<Packet2d>(const Packet2d& a) { return _mm_floor_pd(a); }
-#endif
-
-template<> EIGEN_STRONG_INLINE Packet4f pand<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_and_ps(a,b); }
-template<> EIGEN_STRONG_INLINE Packet2d pand<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_and_pd(a,b); }
-template<> EIGEN_STRONG_INLINE Packet4i pand<Packet4i>(const Packet4i& a, const Packet4i& b) { return _mm_and_si128(a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet4f por<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_or_ps(a,b); }
-template<> EIGEN_STRONG_INLINE Packet2d por<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_or_pd(a,b); }
-template<> EIGEN_STRONG_INLINE Packet4i por<Packet4i>(const Packet4i& a, const Packet4i& b) { return _mm_or_si128(a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet4f pxor<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_xor_ps(a,b); }
-template<> EIGEN_STRONG_INLINE Packet2d pxor<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_xor_pd(a,b); }
-template<> EIGEN_STRONG_INLINE Packet4i pxor<Packet4i>(const Packet4i& a, const Packet4i& b) { return _mm_xor_si128(a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet4f pandnot<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_andnot_ps(a,b); }
-template<> EIGEN_STRONG_INLINE Packet2d pandnot<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_andnot_pd(a,b); }
-template<> EIGEN_STRONG_INLINE Packet4i pandnot<Packet4i>(const Packet4i& a, const Packet4i& b) { return _mm_andnot_si128(a,b); }
-
-template<> EIGEN_STRONG_INLINE Packet4f pload<Packet4f>(const float*   from) { EIGEN_DEBUG_ALIGNED_LOAD return _mm_load_ps(from); }
-template<> EIGEN_STRONG_INLINE Packet2d pload<Packet2d>(const double*  from) { EIGEN_DEBUG_ALIGNED_LOAD return _mm_load_pd(from); }
-template<> EIGEN_STRONG_INLINE Packet4i pload<Packet4i>(const int*     from) { EIGEN_DEBUG_ALIGNED_LOAD return _mm_load_si128(reinterpret_cast<const __m128i*>(from)); }
-
-#if EIGEN_COMP_MSVC
-  template<> EIGEN_STRONG_INLINE Packet4f ploadu<Packet4f>(const float*  from) {
-    EIGEN_DEBUG_UNALIGNED_LOAD
-    #if (EIGEN_COMP_MSVC==1600)
-    // NOTE Some version of MSVC10 generates bad code when using _mm_loadu_ps
-    // (i.e., it does not generate an unaligned load!!
-    __m128 res = _mm_loadl_pi(_mm_set1_ps(0.0f), (const __m64*)(from));
-    res = _mm_loadh_pi(res, (const __m64*)(from+2));
-    return res;
-    #else
-    return _mm_loadu_ps(from);
-    #endif
-  }
-#else
-// NOTE: with the code below, MSVC's compiler crashes!
-
-template<> EIGEN_STRONG_INLINE Packet4f ploadu<Packet4f>(const float* from)
-{
-  EIGEN_DEBUG_UNALIGNED_LOAD
-  return _mm_loadu_ps(from);
-}
-#endif
-
-template<> EIGEN_STRONG_INLINE Packet2d ploadu<Packet2d>(const double* from)
-{
-  EIGEN_DEBUG_UNALIGNED_LOAD
-  return _mm_loadu_pd(from);
-}
-template<> EIGEN_STRONG_INLINE Packet4i ploadu<Packet4i>(const int* from)
-{
-  EIGEN_DEBUG_UNALIGNED_LOAD
-  return _mm_loadu_si128(reinterpret_cast<const __m128i*>(from));
-}
-
-
-template<> EIGEN_STRONG_INLINE Packet4f ploaddup<Packet4f>(const float*   from)
-{
-  return vec4f_swizzle1(_mm_castpd_ps(_mm_load_sd(reinterpret_cast<const double*>(from))), 0, 0, 1, 1);
-}
-template<> EIGEN_STRONG_INLINE Packet2d ploaddup<Packet2d>(const double*  from)
-{ return pset1<Packet2d>(from[0]); }
-template<> EIGEN_STRONG_INLINE Packet4i ploaddup<Packet4i>(const int*     from)
-{
-  Packet4i tmp;
-  tmp = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(from));
-  return vec4i_swizzle1(tmp, 0, 0, 1, 1);
-}
-
-template<> EIGEN_STRONG_INLINE void pstore<float>(float*   to, const Packet4f& from) { EIGEN_DEBUG_ALIGNED_STORE _mm_store_ps(to, from); }
-template<> EIGEN_STRONG_INLINE void pstore<double>(double* to, const Packet2d& from) { EIGEN_DEBUG_ALIGNED_STORE _mm_store_pd(to, from); }
-template<> EIGEN_STRONG_INLINE void pstore<int>(int*       to, const Packet4i& from) { EIGEN_DEBUG_ALIGNED_STORE _mm_store_si128(reinterpret_cast<__m128i*>(to), from); }
-
-template<> EIGEN_STRONG_INLINE void pstoreu<double>(double* to, const Packet2d& from) { EIGEN_DEBUG_UNALIGNED_STORE _mm_storeu_pd(to, from); }
-template<> EIGEN_STRONG_INLINE void pstoreu<float>(float*   to, const Packet4f& from) { EIGEN_DEBUG_UNALIGNED_STORE _mm_storeu_ps(to, from); }
-template<> EIGEN_STRONG_INLINE void pstoreu<int>(int*       to, const Packet4i& from) { EIGEN_DEBUG_UNALIGNED_STORE _mm_storeu_si128(reinterpret_cast<__m128i*>(to), from); }
-
-template<> EIGEN_DEVICE_FUNC inline Packet4f pgather<float, Packet4f>(const float* from, Index stride)
-{
- return _mm_set_ps(from[3*stride], from[2*stride], from[1*stride], from[0*stride]);
-}
-template<> EIGEN_DEVICE_FUNC inline Packet2d pgather<double, Packet2d>(const double* from, Index stride)
-{
- return _mm_set_pd(from[1*stride], from[0*stride]);
-}
-template<> EIGEN_DEVICE_FUNC inline Packet4i pgather<int, Packet4i>(const int* from, Index stride)
-{
- return _mm_set_epi32(from[3*stride], from[2*stride], from[1*stride], from[0*stride]);
- }
-
-template<> EIGEN_DEVICE_FUNC inline void pscatter<float, Packet4f>(float* to, const Packet4f& from, Index stride)
-{
-  to[stride*0] = _mm_cvtss_f32(from);
-  to[stride*1] = _mm_cvtss_f32(_mm_shuffle_ps(from, from, 1));
-  to[stride*2] = _mm_cvtss_f32(_mm_shuffle_ps(from, from, 2));
-  to[stride*3] = _mm_cvtss_f32(_mm_shuffle_ps(from, from, 3));
-}
-template<> EIGEN_DEVICE_FUNC inline void pscatter<double, Packet2d>(double* to, const Packet2d& from, Index stride)
-{
-  to[stride*0] = _mm_cvtsd_f64(from);
-  to[stride*1] = _mm_cvtsd_f64(_mm_shuffle_pd(from, from, 1));
-}
-template<> EIGEN_DEVICE_FUNC inline void pscatter<int, Packet4i>(int* to, const Packet4i& from, Index stride)
-{
-  to[stride*0] = _mm_cvtsi128_si32(from);
-  to[stride*1] = _mm_cvtsi128_si32(_mm_shuffle_epi32(from, 1));
-  to[stride*2] = _mm_cvtsi128_si32(_mm_shuffle_epi32(from, 2));
-  to[stride*3] = _mm_cvtsi128_si32(_mm_shuffle_epi32(from, 3));
-}
-
-// some compilers might be tempted to perform multiple moves instead of using a vector path.
-template<> EIGEN_STRONG_INLINE void pstore1<Packet4f>(float* to, const float& a)
-{
-  Packet4f pa = _mm_set_ss(a);
-  pstore(to, Packet4f(vec4f_swizzle1(pa,0,0,0,0)));
-}
-// some compilers might be tempted to perform multiple moves instead of using a vector path.
-template<> EIGEN_STRONG_INLINE void pstore1<Packet2d>(double* to, const double& a)
-{
-  Packet2d pa = _mm_set_sd(a);
-  pstore(to, Packet2d(vec2d_swizzle1(pa,0,0)));
-}
-
-#if EIGEN_COMP_PGI
-typedef const void * SsePrefetchPtrType;
-#else
-typedef const char * SsePrefetchPtrType;
-#endif
-
-#ifndef EIGEN_VECTORIZE_AVX
-template<> EIGEN_STRONG_INLINE void prefetch<float>(const float*   addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); }
-template<> EIGEN_STRONG_INLINE void prefetch<double>(const double* addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); }
-template<> EIGEN_STRONG_INLINE void prefetch<int>(const int*       addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); }
-#endif
-
-#if EIGEN_COMP_MSVC_STRICT && EIGEN_OS_WIN64
-// The temporary variable fixes an internal compilation error in vs <= 2008 and a wrong-result bug in vs 2010
-// Direct of the struct members fixed bug #62.
-template<> EIGEN_STRONG_INLINE float  pfirst<Packet4f>(const Packet4f& a) { return a.m128_f32[0]; }
-template<> EIGEN_STRONG_INLINE double pfirst<Packet2d>(const Packet2d& a) { return a.m128d_f64[0]; }
-template<> EIGEN_STRONG_INLINE int    pfirst<Packet4i>(const Packet4i& a) { int x = _mm_cvtsi128_si32(a); return x; }
-#elif EIGEN_COMP_MSVC_STRICT
-// The temporary variable fixes an internal compilation error in vs <= 2008 and a wrong-result bug in vs 2010
-template<> EIGEN_STRONG_INLINE float  pfirst<Packet4f>(const Packet4f& a) { float x = _mm_cvtss_f32(a); return x; }
-template<> EIGEN_STRONG_INLINE double pfirst<Packet2d>(const Packet2d& a) { double x = _mm_cvtsd_f64(a); return x; }
-template<> EIGEN_STRONG_INLINE int    pfirst<Packet4i>(const Packet4i& a) { int x = _mm_cvtsi128_si32(a); return x; }
-#else
-template<> EIGEN_STRONG_INLINE float  pfirst<Packet4f>(const Packet4f& a) { return _mm_cvtss_f32(a); }
-template<> EIGEN_STRONG_INLINE double pfirst<Packet2d>(const Packet2d& a) { return _mm_cvtsd_f64(a); }
-template<> EIGEN_STRONG_INLINE int    pfirst<Packet4i>(const Packet4i& a) { return _mm_cvtsi128_si32(a); }
-#endif
-
-template<> EIGEN_STRONG_INLINE Packet4f preverse(const Packet4f& a)
-{ return _mm_shuffle_ps(a,a,0x1B); }
-template<> EIGEN_STRONG_INLINE Packet2d preverse(const Packet2d& a)
-{ return _mm_shuffle_pd(a,a,0x1); }
-template<> EIGEN_STRONG_INLINE Packet4i preverse(const Packet4i& a)
-{ return _mm_shuffle_epi32(a,0x1B); }
-
-template<> EIGEN_STRONG_INLINE Packet4f pabs(const Packet4f& a)
-{
-  const Packet4f mask = _mm_castsi128_ps(_mm_setr_epi32(0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF));
-  return _mm_and_ps(a,mask);
-}
-template<> EIGEN_STRONG_INLINE Packet2d pabs(const Packet2d& a)
-{
-  const Packet2d mask = _mm_castsi128_pd(_mm_setr_epi32(0xFFFFFFFF,0x7FFFFFFF,0xFFFFFFFF,0x7FFFFFFF));
-  return _mm_and_pd(a,mask);
-}
-template<> EIGEN_STRONG_INLINE Packet4i pabs(const Packet4i& a)
-{
-  #ifdef EIGEN_VECTORIZE_SSSE3
-  return _mm_abs_epi32(a);
-  #else
-  Packet4i aux = _mm_srai_epi32(a,31);
-  return _mm_sub_epi32(_mm_xor_si128(a,aux),aux);
-  #endif
-}
-
-// with AVX, the default implementations based on pload1 are faster
-#ifndef __AVX__
-template<> EIGEN_STRONG_INLINE void
-pbroadcast4<Packet4f>(const float *a,
-                      Packet4f& a0, Packet4f& a1, Packet4f& a2, Packet4f& a3)
-{
-  a3 = pload<Packet4f>(a);
-  a0 = vec4f_swizzle1(a3, 0,0,0,0);
-  a1 = vec4f_swizzle1(a3, 1,1,1,1);
-  a2 = vec4f_swizzle1(a3, 2,2,2,2);
-  a3 = vec4f_swizzle1(a3, 3,3,3,3);
-}
-template<> EIGEN_STRONG_INLINE void
-pbroadcast4<Packet2d>(const double *a,
-                      Packet2d& a0, Packet2d& a1, Packet2d& a2, Packet2d& a3)
-{
-#ifdef EIGEN_VECTORIZE_SSE3
-  a0 = _mm_loaddup_pd(a+0);
-  a1 = _mm_loaddup_pd(a+1);
-  a2 = _mm_loaddup_pd(a+2);
-  a3 = _mm_loaddup_pd(a+3);
-#else
-  a1 = pload<Packet2d>(a);
-  a0 = vec2d_swizzle1(a1, 0,0);
-  a1 = vec2d_swizzle1(a1, 1,1);
-  a3 = pload<Packet2d>(a+2);
-  a2 = vec2d_swizzle1(a3, 0,0);
-  a3 = vec2d_swizzle1(a3, 1,1);
-#endif
-}
-#endif
-
-EIGEN_STRONG_INLINE void punpackp(Packet4f* vecs)
-{
-  vecs[1] = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(vecs[0]), 0x55));
-  vecs[2] = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(vecs[0]), 0xAA));
-  vecs[3] = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(vecs[0]), 0xFF));
-  vecs[0] = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(vecs[0]), 0x00));
-}
-
-#ifdef EIGEN_VECTORIZE_SSE3
-template<> EIGEN_STRONG_INLINE Packet4f preduxp<Packet4f>(const Packet4f* vecs)
-{
-  return _mm_hadd_ps(_mm_hadd_ps(vecs[0], vecs[1]),_mm_hadd_ps(vecs[2], vecs[3]));
-}
-
-template<> EIGEN_STRONG_INLINE Packet2d preduxp<Packet2d>(const Packet2d* vecs)
-{
-  return _mm_hadd_pd(vecs[0], vecs[1]);
-}
-
-#else
-template<> EIGEN_STRONG_INLINE Packet4f preduxp<Packet4f>(const Packet4f* vecs)
-{
-  Packet4f tmp0, tmp1, tmp2;
-  tmp0 = _mm_unpacklo_ps(vecs[0], vecs[1]);
-  tmp1 = _mm_unpackhi_ps(vecs[0], vecs[1]);
-  tmp2 = _mm_unpackhi_ps(vecs[2], vecs[3]);
-  tmp0 = _mm_add_ps(tmp0, tmp1);
-  tmp1 = _mm_unpacklo_ps(vecs[2], vecs[3]);
-  tmp1 = _mm_add_ps(tmp1, tmp2);
-  tmp2 = _mm_movehl_ps(tmp1, tmp0);
-  tmp0 = _mm_movelh_ps(tmp0, tmp1);
-  return _mm_add_ps(tmp0, tmp2);
-}
-
-template<> EIGEN_STRONG_INLINE Packet2d preduxp<Packet2d>(const Packet2d* vecs)
-{
-  return _mm_add_pd(_mm_unpacklo_pd(vecs[0], vecs[1]), _mm_unpackhi_pd(vecs[0], vecs[1]));
-}
-#endif  // SSE3
-
-template<> EIGEN_STRONG_INLINE float predux<Packet4f>(const Packet4f& a)
-{
-  // Disable SSE3 _mm_hadd_pd that is extremely slow on all existing Intel's architectures
-  // (from Nehalem to Haswell)
-// #ifdef EIGEN_VECTORIZE_SSE3
-//   Packet4f tmp = _mm_add_ps(a, vec4f_swizzle1(a,2,3,2,3));
-//   return pfirst<Packet4f>(_mm_hadd_ps(tmp, tmp));
-// #else
-  Packet4f tmp = _mm_add_ps(a, _mm_movehl_ps(a,a));
-  return pfirst<Packet4f>(_mm_add_ss(tmp, _mm_shuffle_ps(tmp,tmp, 1)));
-// #endif
-}
-
-template<> EIGEN_STRONG_INLINE double predux<Packet2d>(const Packet2d& a)
-{
-  // Disable SSE3 _mm_hadd_pd that is extremely slow on all existing Intel's architectures
-  // (from Nehalem to Haswell)
-// #ifdef EIGEN_VECTORIZE_SSE3
-//   return pfirst<Packet2d>(_mm_hadd_pd(a, a));
-// #else
-  return pfirst<Packet2d>(_mm_add_sd(a, _mm_unpackhi_pd(a,a)));
-// #endif
-}
-
-#ifdef EIGEN_VECTORIZE_SSSE3
-template<> EIGEN_STRONG_INLINE Packet4i preduxp<Packet4i>(const Packet4i* vecs)
-{
-  return _mm_hadd_epi32(_mm_hadd_epi32(vecs[0], vecs[1]),_mm_hadd_epi32(vecs[2], vecs[3]));
-}
-template<> EIGEN_STRONG_INLINE int predux<Packet4i>(const Packet4i& a)
-{
-  Packet4i tmp0 = _mm_hadd_epi32(a,a);
-  return pfirst<Packet4i>(_mm_hadd_epi32(tmp0,tmp0));
-}
-#else
-template<> EIGEN_STRONG_INLINE int predux<Packet4i>(const Packet4i& a)
-{
-  Packet4i tmp = _mm_add_epi32(a, _mm_unpackhi_epi64(a,a));
-  return pfirst(tmp) + pfirst<Packet4i>(_mm_shuffle_epi32(tmp, 1));
-}
-
-template<> EIGEN_STRONG_INLINE Packet4i preduxp<Packet4i>(const Packet4i* vecs)
-{
-  Packet4i tmp0, tmp1, tmp2;
-  tmp0 = _mm_unpacklo_epi32(vecs[0], vecs[1]);
-  tmp1 = _mm_unpackhi_epi32(vecs[0], vecs[1]);
-  tmp2 = _mm_unpackhi_epi32(vecs[2], vecs[3]);
-  tmp0 = _mm_add_epi32(tmp0, tmp1);
-  tmp1 = _mm_unpacklo_epi32(vecs[2], vecs[3]);
-  tmp1 = _mm_add_epi32(tmp1, tmp2);
-  tmp2 = _mm_unpacklo_epi64(tmp0, tmp1);
-  tmp0 = _mm_unpackhi_epi64(tmp0, tmp1);
-  return _mm_add_epi32(tmp0, tmp2);
-}
-#endif
-// Other reduction functions:
-
-// mul
-template<> EIGEN_STRONG_INLINE float predux_mul<Packet4f>(const Packet4f& a)
-{
-  Packet4f tmp = _mm_mul_ps(a, _mm_movehl_ps(a,a));
-  return pfirst<Packet4f>(_mm_mul_ss(tmp, _mm_shuffle_ps(tmp,tmp, 1)));
-}
-template<> EIGEN_STRONG_INLINE double predux_mul<Packet2d>(const Packet2d& a)
-{
-  return pfirst<Packet2d>(_mm_mul_sd(a, _mm_unpackhi_pd(a,a)));
-}
-template<> EIGEN_STRONG_INLINE int predux_mul<Packet4i>(const Packet4i& a)
-{
-  // after some experiments, it is seems this is the fastest way to implement it
-  // for GCC (eg., reusing pmul is very slow !)
-  // TODO try to call _mm_mul_epu32 directly
-  EIGEN_ALIGN16 int aux[4];
-  pstore(aux, a);
-  return  (aux[0] * aux[1]) * (aux[2] * aux[3]);;
-}
-
-// min
-template<> EIGEN_STRONG_INLINE float predux_min<Packet4f>(const Packet4f& a)
-{
-  Packet4f tmp = _mm_min_ps(a, _mm_movehl_ps(a,a));
-  return pfirst<Packet4f>(_mm_min_ss(tmp, _mm_shuffle_ps(tmp,tmp, 1)));
-}
-template<> EIGEN_STRONG_INLINE double predux_min<Packet2d>(const Packet2d& a)
-{
-  return pfirst<Packet2d>(_mm_min_sd(a, _mm_unpackhi_pd(a,a)));
-}
-template<> EIGEN_STRONG_INLINE int predux_min<Packet4i>(const Packet4i& a)
-{
-#ifdef EIGEN_VECTORIZE_SSE4_1
-  Packet4i tmp = _mm_min_epi32(a, _mm_shuffle_epi32(a, _MM_SHUFFLE(0,0,3,2)));
-  return pfirst<Packet4i>(_mm_min_epi32(tmp,_mm_shuffle_epi32(tmp, 1)));
-#else
-  // after some experiments, it is seems this is the fastest way to implement it
-  // for GCC (eg., it does not like using std::min after the pstore !!)
-  EIGEN_ALIGN16 int aux[4];
-  pstore(aux, a);
-  int aux0 = aux[0]<aux[1] ? aux[0] : aux[1];
-  int aux2 = aux[2]<aux[3] ? aux[2] : aux[3];
-  return aux0<aux2 ? aux0 : aux2;
-#endif // EIGEN_VECTORIZE_SSE4_1
-}
-
-// max
-template<> EIGEN_STRONG_INLINE float predux_max<Packet4f>(const Packet4f& a)
-{
-  Packet4f tmp = _mm_max_ps(a, _mm_movehl_ps(a,a));
-  return pfirst<Packet4f>(_mm_max_ss(tmp, _mm_shuffle_ps(tmp,tmp, 1)));
-}
-template<> EIGEN_STRONG_INLINE double predux_max<Packet2d>(const Packet2d& a)
-{
-  return pfirst<Packet2d>(_mm_max_sd(a, _mm_unpackhi_pd(a,a)));
-}
-template<> EIGEN_STRONG_INLINE int predux_max<Packet4i>(const Packet4i& a)
-{
-#ifdef EIGEN_VECTORIZE_SSE4_1
-  Packet4i tmp = _mm_max_epi32(a, _mm_shuffle_epi32(a, _MM_SHUFFLE(0,0,3,2)));
-  return pfirst<Packet4i>(_mm_max_epi32(tmp,_mm_shuffle_epi32(tmp, 1)));
-#else
-  // after some experiments, it is seems this is the fastest way to implement it
-  // for GCC (eg., it does not like using std::min after the pstore !!)
-  EIGEN_ALIGN16 int aux[4];
-  pstore(aux, a);
-  int aux0 = aux[0]>aux[1] ? aux[0] : aux[1];
-  int aux2 = aux[2]>aux[3] ? aux[2] : aux[3];
-  return aux0>aux2 ? aux0 : aux2;
-#endif // EIGEN_VECTORIZE_SSE4_1
-}
-
-#if EIGEN_COMP_GNUC
-// template <> EIGEN_STRONG_INLINE Packet4f pmadd(const Packet4f&  a, const Packet4f&  b, const Packet4f&  c)
-// {
-//   Packet4f res = b;
-//   asm("mulps %[a], %[b] \n\taddps %[c], %[b]" : [b] "+x" (res) : [a] "x" (a), [c] "x" (c));
-//   return res;
-// }
-// EIGEN_STRONG_INLINE Packet4i _mm_alignr_epi8(const Packet4i&  a, const Packet4i&  b, const int i)
-// {
-//   Packet4i res = a;
-//   asm("palignr %[i], %[a], %[b] " : [b] "+x" (res) : [a] "x" (a), [i] "i" (i));
-//   return res;
-// }
-#endif
-
-#ifdef EIGEN_VECTORIZE_SSSE3
-// SSSE3 versions
-template<int Offset>
-struct palign_impl<Offset,Packet4f>
-{
-  static EIGEN_STRONG_INLINE void run(Packet4f& first, const Packet4f& second)
-  {
-    if (Offset!=0)
-      first = _mm_castsi128_ps(_mm_alignr_epi8(_mm_castps_si128(second), _mm_castps_si128(first), Offset*4));
-  }
-};
-
-template<int Offset>
-struct palign_impl<Offset,Packet4i>
-{
-  static EIGEN_STRONG_INLINE void run(Packet4i& first, const Packet4i& second)
-  {
-    if (Offset!=0)
-      first = _mm_alignr_epi8(second,first, Offset*4);
-  }
-};
-
-template<int Offset>
-struct palign_impl<Offset,Packet2d>
-{
-  static EIGEN_STRONG_INLINE void run(Packet2d& first, const Packet2d& second)
-  {
-    if (Offset==1)
-      first = _mm_castsi128_pd(_mm_alignr_epi8(_mm_castpd_si128(second), _mm_castpd_si128(first), 8));
-  }
-};
-#else
-// SSE2 versions
-template<int Offset>
-struct palign_impl<Offset,Packet4f>
-{
-  static EIGEN_STRONG_INLINE void run(Packet4f& first, const Packet4f& second)
-  {
-    if (Offset==1)
-    {
-      first = _mm_move_ss(first,second);
-      first = _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(first),0x39));
-    }
-    else if (Offset==2)
-    {
-      first = _mm_movehl_ps(first,first);
-      first = _mm_movelh_ps(first,second);
-    }
-    else if (Offset==3)
-    {
-      first = _mm_move_ss(first,second);
-      first = _mm_shuffle_ps(first,second,0x93);
-    }
-  }
-};
-
-template<int Offset>
-struct palign_impl<Offset,Packet4i>
-{
-  static EIGEN_STRONG_INLINE void run(Packet4i& first, const Packet4i& second)
-  {
-    if (Offset==1)
-    {
-      first = _mm_castps_si128(_mm_move_ss(_mm_castsi128_ps(first),_mm_castsi128_ps(second)));
-      first = _mm_shuffle_epi32(first,0x39);
-    }
-    else if (Offset==2)
-    {
-      first = _mm_castps_si128(_mm_movehl_ps(_mm_castsi128_ps(first),_mm_castsi128_ps(first)));
-      first = _mm_castps_si128(_mm_movelh_ps(_mm_castsi128_ps(first),_mm_castsi128_ps(second)));
-    }
-    else if (Offset==3)
-    {
-      first = _mm_castps_si128(_mm_move_ss(_mm_castsi128_ps(first),_mm_castsi128_ps(second)));
-      first = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(first),_mm_castsi128_ps(second),0x93));
-    }
-  }
-};
-
-template<int Offset>
-struct palign_impl<Offset,Packet2d>
-{
-  static EIGEN_STRONG_INLINE void run(Packet2d& first, const Packet2d& second)
-  {
-    if (Offset==1)
-    {
-      first = _mm_castps_pd(_mm_movehl_ps(_mm_castpd_ps(first),_mm_castpd_ps(first)));
-      first = _mm_castps_pd(_mm_movelh_ps(_mm_castpd_ps(first),_mm_castpd_ps(second)));
-    }
-  }
-};
-#endif
-
-EIGEN_DEVICE_FUNC inline void
-ptranspose(PacketBlock<Packet4f,4>& kernel) {
-  _MM_TRANSPOSE4_PS(kernel.packet[0], kernel.packet[1], kernel.packet[2], kernel.packet[3]);
-}
-
-EIGEN_DEVICE_FUNC inline void
-ptranspose(PacketBlock<Packet2d,2>& kernel) {
-  __m128d tmp = _mm_unpackhi_pd(kernel.packet[0], kernel.packet[1]);
-  kernel.packet[0] = _mm_unpacklo_pd(kernel.packet[0], kernel.packet[1]);
-  kernel.packet[1] = tmp;
-}
-
-EIGEN_DEVICE_FUNC inline void
-ptranspose(PacketBlock<Packet4i,4>& kernel) {
-  __m128i T0 = _mm_unpacklo_epi32(kernel.packet[0], kernel.packet[1]);
-  __m128i T1 = _mm_unpacklo_epi32(kernel.packet[2], kernel.packet[3]);
-  __m128i T2 = _mm_unpackhi_epi32(kernel.packet[0], kernel.packet[1]);
-  __m128i T3 = _mm_unpackhi_epi32(kernel.packet[2], kernel.packet[3]);
-
-  kernel.packet[0] = _mm_unpacklo_epi64(T0, T1);
-  kernel.packet[1] = _mm_unpackhi_epi64(T0, T1);
-  kernel.packet[2] = _mm_unpacklo_epi64(T2, T3);
-  kernel.packet[3] = _mm_unpackhi_epi64(T2, T3);
-}
-
-template<> EIGEN_STRONG_INLINE Packet4i pblend(const Selector<4>& ifPacket, const Packet4i& thenPacket, const Packet4i& elsePacket) {
-  const __m128i zero = _mm_setzero_si128();
-  const __m128i select = _mm_set_epi32(ifPacket.select[3], ifPacket.select[2], ifPacket.select[1], ifPacket.select[0]);
-  __m128i false_mask = _mm_cmpeq_epi32(select, zero);
-#ifdef EIGEN_VECTORIZE_SSE4_1
-  return _mm_blendv_epi8(thenPacket, elsePacket, false_mask);
-#else
-  return _mm_or_si128(_mm_andnot_si128(false_mask, thenPacket), _mm_and_si128(false_mask, elsePacket));
-#endif
-}
-template<> EIGEN_STRONG_INLINE Packet4f pblend(const Selector<4>& ifPacket, const Packet4f& thenPacket, const Packet4f& elsePacket) {
-  const __m128 zero = _mm_setzero_ps();
-  const __m128 select = _mm_set_ps(ifPacket.select[3], ifPacket.select[2], ifPacket.select[1], ifPacket.select[0]);
-  __m128 false_mask = _mm_cmpeq_ps(select, zero);
-#ifdef EIGEN_VECTORIZE_SSE4_1
-  return _mm_blendv_ps(thenPacket, elsePacket, false_mask);
-#else
-  return _mm_or_ps(_mm_andnot_ps(false_mask, thenPacket), _mm_and_ps(false_mask, elsePacket));
-#endif
-}
-template<> EIGEN_STRONG_INLINE Packet2d pblend(const Selector<2>& ifPacket, const Packet2d& thenPacket, const Packet2d& elsePacket) {
-  const __m128d zero = _mm_setzero_pd();
-  const __m128d select = _mm_set_pd(ifPacket.select[1], ifPacket.select[0]);
-  __m128d false_mask = _mm_cmpeq_pd(select, zero);
-#ifdef EIGEN_VECTORIZE_SSE4_1
-  return _mm_blendv_pd(thenPacket, elsePacket, false_mask);
-#else
-  return _mm_or_pd(_mm_andnot_pd(false_mask, thenPacket), _mm_and_pd(false_mask, elsePacket));
-#endif
-}
-
-template<> EIGEN_STRONG_INLINE Packet4f pinsertfirst(const Packet4f& a, float b)
-{
-#ifdef EIGEN_VECTORIZE_SSE4_1
-  return _mm_blend_ps(a,pset1<Packet4f>(b),1);
-#else
-  return _mm_move_ss(a, _mm_load_ss(&b));
-#endif
-}
-
-template<> EIGEN_STRONG_INLINE Packet2d pinsertfirst(const Packet2d& a, double b)
-{
-#ifdef EIGEN_VECTORIZE_SSE4_1
-  return _mm_blend_pd(a,pset1<Packet2d>(b),1);
-#else
-  return _mm_move_sd(a, _mm_load_sd(&b));
-#endif
-}
-
-template<> EIGEN_STRONG_INLINE Packet4f pinsertlast(const Packet4f& a, float b)
-{
-#ifdef EIGEN_VECTORIZE_SSE4_1
-  return _mm_blend_ps(a,pset1<Packet4f>(b),(1<<3));
-#else
-  const Packet4f mask = _mm_castsi128_ps(_mm_setr_epi32(0x0,0x0,0x0,0xFFFFFFFF));
-  return _mm_or_ps(_mm_andnot_ps(mask, a), _mm_and_ps(mask, pset1<Packet4f>(b)));
-#endif
-}
-
-template<> EIGEN_STRONG_INLINE Packet2d pinsertlast(const Packet2d& a, double b)
-{
-#ifdef EIGEN_VECTORIZE_SSE4_1
-  return _mm_blend_pd(a,pset1<Packet2d>(b),(1<<1));
-#else
-  const Packet2d mask = _mm_castsi128_pd(_mm_setr_epi32(0x0,0x0,0xFFFFFFFF,0xFFFFFFFF));
-  return _mm_or_pd(_mm_andnot_pd(mask, a), _mm_and_pd(mask, pset1<Packet2d>(b)));
-#endif
-}
-
-// Scalar path for pmadd with FMA to ensure consistency with vectorized path.
-#ifdef __FMA__
-template<> EIGEN_STRONG_INLINE float pmadd(const float& a, const float& b, const float& c) {
-  return ::fmaf(a,b,c);
-}
-template<> EIGEN_STRONG_INLINE double pmadd(const double& a, const double& b, const double& c) {
-  return ::fma(a,b,c);
-}
-#endif
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#if EIGEN_COMP_PGI
-// PGI++ does not define the following intrinsics in C++ mode.
-static inline __m128  _mm_castpd_ps   (__m128d x) { return reinterpret_cast<__m128&>(x);  }
-static inline __m128i _mm_castpd_si128(__m128d x) { return reinterpret_cast<__m128i&>(x); }
-static inline __m128d _mm_castps_pd   (__m128  x) { return reinterpret_cast<__m128d&>(x); }
-static inline __m128i _mm_castps_si128(__m128  x) { return reinterpret_cast<__m128i&>(x); }
-static inline __m128  _mm_castsi128_ps(__m128i x) { return reinterpret_cast<__m128&>(x);  }
-static inline __m128d _mm_castsi128_pd(__m128i x) { return reinterpret_cast<__m128d&>(x); }
-#endif
-
-#endif // EIGEN_PACKET_MATH_SSE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/SSE/TypeCasting.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/SSE/TypeCasting.h
deleted file mode 100644
index c6ca8c7..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/arch/SSE/TypeCasting.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2015 Benoit Steiner <benoit.steiner.goog@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_TYPE_CASTING_SSE_H
-#define EIGEN_TYPE_CASTING_SSE_H
-
-namespace Eigen {
-
-namespace internal {
-
-#ifndef EIGEN_VECTORIZE_AVX
-template <>
-struct type_casting_traits<float, int> {
-  enum {
-    VectorizedCast = 1,
-    SrcCoeffRatio = 1,
-    TgtCoeffRatio = 1
-  };
-};
-
-template <>
-struct type_casting_traits<int, float> {
-  enum {
-    VectorizedCast = 1,
-    SrcCoeffRatio = 1,
-    TgtCoeffRatio = 1
-  };
-};
-
-template <>
-struct type_casting_traits<double, float> {
-  enum {
-    VectorizedCast = 1,
-    SrcCoeffRatio = 2,
-    TgtCoeffRatio = 1
-  };
-};
-
-template <>
-struct type_casting_traits<float, double> {
-  enum {
-    VectorizedCast = 1,
-    SrcCoeffRatio = 1,
-    TgtCoeffRatio = 2
-  };
-};
-#endif
-
-template<> EIGEN_STRONG_INLINE Packet4i pcast<Packet4f, Packet4i>(const Packet4f& a) {
-  return _mm_cvttps_epi32(a);
-}
-
-template<> EIGEN_STRONG_INLINE Packet4f pcast<Packet4i, Packet4f>(const Packet4i& a) {
-  return _mm_cvtepi32_ps(a);
-}
-
-template<> EIGEN_STRONG_INLINE Packet4f pcast<Packet2d, Packet4f>(const Packet2d& a, const Packet2d& b) {
-  return _mm_shuffle_ps(_mm_cvtpd_ps(a), _mm_cvtpd_ps(b), (1 << 2) | (1 << 6));
-}
-
-template<> EIGEN_STRONG_INLINE Packet2d pcast<Packet4f, Packet2d>(const Packet4f& a) {
-  // Simply discard the second half of the input
-  return _mm_cvtps_pd(a);
-}
-
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_TYPE_CASTING_SSE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/functors/AssignmentFunctors.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/functors/AssignmentFunctors.h
deleted file mode 100644
index 4153b87..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/functors/AssignmentFunctors.h
+++ /dev/null
@@ -1,168 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_ASSIGNMENT_FUNCTORS_H
-#define EIGEN_ASSIGNMENT_FUNCTORS_H
-
-namespace Eigen {
-
-namespace internal {
-  
-/** \internal
-  * \brief Template functor for scalar/packet assignment
-  *
-  */
-template<typename DstScalar,typename SrcScalar> struct assign_op {
-
-  EIGEN_EMPTY_STRUCT_CTOR(assign_op)
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a = b; }
-  
-  template<int Alignment, typename Packet>
-  EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const
-  { internal::pstoret<DstScalar,Packet,Alignment>(a,b); }
-};
-
-// Empty overload for void type (used by PermutationMatrix)
-template<typename DstScalar> struct assign_op<DstScalar,void> {};
-
-template<typename DstScalar,typename SrcScalar>
-struct functor_traits<assign_op<DstScalar,SrcScalar> > {
-  enum {
-    Cost = NumTraits<DstScalar>::ReadCost,
-    PacketAccess = is_same<DstScalar,SrcScalar>::value && packet_traits<DstScalar>::Vectorizable && packet_traits<SrcScalar>::Vectorizable
-  };
-};
-
-/** \internal
-  * \brief Template functor for scalar/packet assignment with addition
-  *
-  */
-template<typename DstScalar,typename SrcScalar> struct add_assign_op {
-
-  EIGEN_EMPTY_STRUCT_CTOR(add_assign_op)
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a += b; }
-  
-  template<int Alignment, typename Packet>
-  EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const
-  { internal::pstoret<DstScalar,Packet,Alignment>(a,internal::padd(internal::ploadt<Packet,Alignment>(a),b)); }
-};
-template<typename DstScalar,typename SrcScalar>
-struct functor_traits<add_assign_op<DstScalar,SrcScalar> > {
-  enum {
-    Cost = NumTraits<DstScalar>::ReadCost + NumTraits<DstScalar>::AddCost,
-    PacketAccess = is_same<DstScalar,SrcScalar>::value && packet_traits<DstScalar>::HasAdd
-  };
-};
-
-/** \internal
-  * \brief Template functor for scalar/packet assignment with subtraction
-  *
-  */
-template<typename DstScalar,typename SrcScalar> struct sub_assign_op {
-
-  EIGEN_EMPTY_STRUCT_CTOR(sub_assign_op)
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a -= b; }
-  
-  template<int Alignment, typename Packet>
-  EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const
-  { internal::pstoret<DstScalar,Packet,Alignment>(a,internal::psub(internal::ploadt<Packet,Alignment>(a),b)); }
-};
-template<typename DstScalar,typename SrcScalar>
-struct functor_traits<sub_assign_op<DstScalar,SrcScalar> > {
-  enum {
-    Cost = NumTraits<DstScalar>::ReadCost + NumTraits<DstScalar>::AddCost,
-    PacketAccess = is_same<DstScalar,SrcScalar>::value && packet_traits<DstScalar>::HasSub
-  };
-};
-
-/** \internal
-  * \brief Template functor for scalar/packet assignment with multiplication
-  *
-  */
-template<typename DstScalar, typename SrcScalar=DstScalar>
-struct mul_assign_op {
-
-  EIGEN_EMPTY_STRUCT_CTOR(mul_assign_op)
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a *= b; }
-  
-  template<int Alignment, typename Packet>
-  EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const
-  { internal::pstoret<DstScalar,Packet,Alignment>(a,internal::pmul(internal::ploadt<Packet,Alignment>(a),b)); }
-};
-template<typename DstScalar, typename SrcScalar>
-struct functor_traits<mul_assign_op<DstScalar,SrcScalar> > {
-  enum {
-    Cost = NumTraits<DstScalar>::ReadCost + NumTraits<DstScalar>::MulCost,
-    PacketAccess = is_same<DstScalar,SrcScalar>::value && packet_traits<DstScalar>::HasMul
-  };
-};
-
-/** \internal
-  * \brief Template functor for scalar/packet assignment with diviving
-  *
-  */
-template<typename DstScalar, typename SrcScalar=DstScalar> struct div_assign_op {
-
-  EIGEN_EMPTY_STRUCT_CTOR(div_assign_op)
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a /= b; }
-  
-  template<int Alignment, typename Packet>
-  EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const
-  { internal::pstoret<DstScalar,Packet,Alignment>(a,internal::pdiv(internal::ploadt<Packet,Alignment>(a),b)); }
-};
-template<typename DstScalar, typename SrcScalar>
-struct functor_traits<div_assign_op<DstScalar,SrcScalar> > {
-  enum {
-    Cost = NumTraits<DstScalar>::ReadCost + NumTraits<DstScalar>::MulCost,
-    PacketAccess = is_same<DstScalar,SrcScalar>::value && packet_traits<DstScalar>::HasDiv
-  };
-};
-
-/** \internal
-  * \brief Template functor for scalar/packet assignment with swapping
-  *
-  * It works as follow. For a non-vectorized evaluation loop, we have:
-  *   for(i) func(A.coeffRef(i), B.coeff(i));
-  * where B is a SwapWrapper expression. The trick is to make SwapWrapper::coeff behaves like a non-const coeffRef.
-  * Actually, SwapWrapper might not even be needed since even if B is a plain expression, since it has to be writable
-  * B.coeff already returns a const reference to the underlying scalar value.
-  * 
-  * The case of a vectorized loop is more tricky:
-  *   for(i,j) func.assignPacket<A_Align>(&A.coeffRef(i,j), B.packet<B_Align>(i,j));
-  * Here, B must be a SwapWrapper whose packet function actually returns a proxy object holding a Scalar*,
-  * the actual alignment and Packet type.
-  *
-  */
-template<typename Scalar> struct swap_assign_op {
-
-  EIGEN_EMPTY_STRUCT_CTOR(swap_assign_op)
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(Scalar& a, const Scalar& b) const
-  {
-#ifdef __CUDACC__
-    // FIXME is there some kind of cuda::swap?
-    Scalar t=b; const_cast<Scalar&>(b)=a; a=t;
-#else
-    using std::swap;
-    swap(a,const_cast<Scalar&>(b));
-#endif
-  }
-};
-template<typename Scalar>
-struct functor_traits<swap_assign_op<Scalar> > {
-  enum {
-    Cost = 3 * NumTraits<Scalar>::ReadCost,
-    PacketAccess = packet_traits<Scalar>::Vectorizable
-  };
-};
-
-} // namespace internal
-
-} // namespace Eigen
-
-#endif // EIGEN_ASSIGNMENT_FUNCTORS_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/functors/BinaryFunctors.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/functors/BinaryFunctors.h
deleted file mode 100644
index 3eae6b8..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/functors/BinaryFunctors.h
+++ /dev/null
@@ -1,475 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_BINARY_FUNCTORS_H
-#define EIGEN_BINARY_FUNCTORS_H
-
-namespace Eigen {
-
-namespace internal {
-
-//---------- associative binary functors ----------
-
-template<typename Arg1, typename Arg2>
-struct binary_op_base
-{
-  typedef Arg1 first_argument_type;
-  typedef Arg2 second_argument_type;
-};
-
-/** \internal
-  * \brief Template functor to compute the sum of two scalars
-  *
-  * \sa class CwiseBinaryOp, MatrixBase::operator+, class VectorwiseOp, DenseBase::sum()
-  */
-template<typename LhsScalar,typename RhsScalar>
-struct scalar_sum_op : binary_op_base<LhsScalar,RhsScalar>
-{
-  typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_sum_op>::ReturnType result_type;
-#ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_sum_op)
-#else
-  scalar_sum_op() {
-    EIGEN_SCALAR_BINARY_OP_PLUGIN
-  }
-#endif
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a + b; }
-  template<typename Packet>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
-  { return internal::padd(a,b); }
-  template<typename Packet>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type predux(const Packet& a) const
-  { return internal::predux(a); }
-};
-template<typename LhsScalar,typename RhsScalar>
-struct functor_traits<scalar_sum_op<LhsScalar,RhsScalar> > {
-  enum {
-    Cost = (NumTraits<LhsScalar>::AddCost+NumTraits<RhsScalar>::AddCost)/2, // rough estimate!
-    PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasAdd && packet_traits<RhsScalar>::HasAdd
-    // TODO vectorize mixed sum
-  };
-};
-
-/** \internal
-  * \brief Template specialization to deprecate the summation of boolean expressions.
-  * This is required to solve Bug 426.
-  * \sa DenseBase::count(), DenseBase::any(), ArrayBase::cast(), MatrixBase::cast()
-  */
-template<> struct scalar_sum_op<bool,bool> : scalar_sum_op<int,int> {
-  EIGEN_DEPRECATED
-  scalar_sum_op() {}
-};
-
-
-/** \internal
-  * \brief Template functor to compute the product of two scalars
-  *
-  * \sa class CwiseBinaryOp, Cwise::operator*(), class VectorwiseOp, MatrixBase::redux()
-  */
-template<typename LhsScalar,typename RhsScalar>
-struct scalar_product_op  : binary_op_base<LhsScalar,RhsScalar>
-{
-  typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_product_op>::ReturnType result_type;
-#ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_product_op)
-#else
-  scalar_product_op() {
-    EIGEN_SCALAR_BINARY_OP_PLUGIN
-  }
-#endif
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a * b; }
-  template<typename Packet>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
-  { return internal::pmul(a,b); }
-  template<typename Packet>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type predux(const Packet& a) const
-  { return internal::predux_mul(a); }
-};
-template<typename LhsScalar,typename RhsScalar>
-struct functor_traits<scalar_product_op<LhsScalar,RhsScalar> > {
-  enum {
-    Cost = (NumTraits<LhsScalar>::MulCost + NumTraits<RhsScalar>::MulCost)/2, // rough estimate!
-    PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasMul && packet_traits<RhsScalar>::HasMul
-    // TODO vectorize mixed product
-  };
-};
-
-/** \internal
-  * \brief Template functor to compute the conjugate product of two scalars
-  *
-  * This is a short cut for conj(x) * y which is needed for optimization purpose; in Eigen2 support mode, this becomes x * conj(y)
-  */
-template<typename LhsScalar,typename RhsScalar>
-struct scalar_conj_product_op  : binary_op_base<LhsScalar,RhsScalar>
-{
-
-  enum {
-    Conj = NumTraits<LhsScalar>::IsComplex
-  };
-  
-  typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_conj_product_op>::ReturnType result_type;
-  
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_conj_product_op)
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const
-  { return conj_helper<LhsScalar,RhsScalar,Conj,false>().pmul(a,b); }
-  
-  template<typename Packet>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
-  { return conj_helper<Packet,Packet,Conj,false>().pmul(a,b); }
-};
-template<typename LhsScalar,typename RhsScalar>
-struct functor_traits<scalar_conj_product_op<LhsScalar,RhsScalar> > {
-  enum {
-    Cost = NumTraits<LhsScalar>::MulCost,
-    PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMul
-  };
-};
-
-/** \internal
-  * \brief Template functor to compute the min of two scalars
-  *
-  * \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class VectorwiseOp, MatrixBase::minCoeff()
-  */
-template<typename LhsScalar,typename RhsScalar>
-struct scalar_min_op : binary_op_base<LhsScalar,RhsScalar>
-{
-  typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_min_op>::ReturnType result_type;
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_min_op)
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return numext::mini(a, b); }
-  template<typename Packet>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
-  { return internal::pmin(a,b); }
-  template<typename Packet>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type predux(const Packet& a) const
-  { return internal::predux_min(a); }
-};
-template<typename LhsScalar,typename RhsScalar>
-struct functor_traits<scalar_min_op<LhsScalar,RhsScalar> > {
-  enum {
-    Cost = (NumTraits<LhsScalar>::AddCost+NumTraits<RhsScalar>::AddCost)/2,
-    PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMin
-  };
-};
-
-/** \internal
-  * \brief Template functor to compute the max of two scalars
-  *
-  * \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class VectorwiseOp, MatrixBase::maxCoeff()
-  */
-template<typename LhsScalar,typename RhsScalar>
-struct scalar_max_op  : binary_op_base<LhsScalar,RhsScalar>
-{
-  typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_max_op>::ReturnType result_type;
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_max_op)
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return numext::maxi(a, b); }
-  template<typename Packet>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
-  { return internal::pmax(a,b); }
-  template<typename Packet>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type predux(const Packet& a) const
-  { return internal::predux_max(a); }
-};
-template<typename LhsScalar,typename RhsScalar>
-struct functor_traits<scalar_max_op<LhsScalar,RhsScalar> > {
-  enum {
-    Cost = (NumTraits<LhsScalar>::AddCost+NumTraits<RhsScalar>::AddCost)/2,
-    PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMax
-  };
-};
-
-/** \internal
-  * \brief Template functors for comparison of two scalars
-  * \todo Implement packet-comparisons
-  */
-template<typename LhsScalar, typename RhsScalar, ComparisonName cmp> struct scalar_cmp_op;
-
-template<typename LhsScalar, typename RhsScalar, ComparisonName cmp>
-struct functor_traits<scalar_cmp_op<LhsScalar,RhsScalar, cmp> > {
-  enum {
-    Cost = (NumTraits<LhsScalar>::AddCost+NumTraits<RhsScalar>::AddCost)/2,
-    PacketAccess = false
-  };
-};
-
-template<ComparisonName Cmp, typename LhsScalar, typename RhsScalar>
-struct result_of<scalar_cmp_op<LhsScalar, RhsScalar, Cmp>(LhsScalar,RhsScalar)> {
-  typedef bool type;
-};
-
-
-template<typename LhsScalar, typename RhsScalar>
-struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_EQ> : binary_op_base<LhsScalar,RhsScalar>
-{
-  typedef bool result_type;
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a==b;}
-};
-template<typename LhsScalar, typename RhsScalar>
-struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_LT> : binary_op_base<LhsScalar,RhsScalar>
-{
-  typedef bool result_type;
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a<b;}
-};
-template<typename LhsScalar, typename RhsScalar>
-struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_LE> : binary_op_base<LhsScalar,RhsScalar>
-{
-  typedef bool result_type;
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a<=b;}
-};
-template<typename LhsScalar, typename RhsScalar>
-struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_GT> : binary_op_base<LhsScalar,RhsScalar>
-{
-  typedef bool result_type;
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a>b;}
-};
-template<typename LhsScalar, typename RhsScalar>
-struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_GE> : binary_op_base<LhsScalar,RhsScalar>
-{
-  typedef bool result_type;
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a>=b;}
-};
-template<typename LhsScalar, typename RhsScalar>
-struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_UNORD> : binary_op_base<LhsScalar,RhsScalar>
-{
-  typedef bool result_type;
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return !(a<=b || b<=a);}
-};
-template<typename LhsScalar, typename RhsScalar>
-struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_NEQ> : binary_op_base<LhsScalar,RhsScalar>
-{
-  typedef bool result_type;
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a!=b;}
-};
-
-
-/** \internal
-  * \brief Template functor to compute the hypot of two \b positive \b and \b real scalars
-  *
-  * \sa MatrixBase::stableNorm(), class Redux
-  */
-template<typename Scalar>
-struct scalar_hypot_op<Scalar,Scalar> : binary_op_base<Scalar,Scalar>
-{
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_hypot_op)
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar &x, const Scalar &y) const
-  {
-    // This functor is used by hypotNorm only for which it is faster to first apply abs
-    // on all coefficients prior to reduction through hypot.
-    // This way we avoid calling abs on positive and real entries, and this also permits
-    // to seamlessly handle complexes. Otherwise we would have to handle both real and complexes
-    // through the same functor...
-    return internal::positive_real_hypot(x,y);
-  }
-};
-template<typename Scalar>
-struct functor_traits<scalar_hypot_op<Scalar,Scalar> > {
-  enum
-  {
-    Cost = 3 * NumTraits<Scalar>::AddCost +
-           2 * NumTraits<Scalar>::MulCost +
-           2 * scalar_div_cost<Scalar,false>::value,
-    PacketAccess = false
-  };
-};
-
-/** \internal
-  * \brief Template functor to compute the pow of two scalars
-  */
-template<typename Scalar, typename Exponent>
-struct scalar_pow_op  : binary_op_base<Scalar,Exponent>
-{
-  typedef typename ScalarBinaryOpTraits<Scalar,Exponent,scalar_pow_op>::ReturnType result_type;
-#ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_pow_op)
-#else
-  scalar_pow_op() {
-    typedef Scalar LhsScalar;
-    typedef Exponent RhsScalar;
-    EIGEN_SCALAR_BINARY_OP_PLUGIN
-  }
-#endif
-  EIGEN_DEVICE_FUNC
-  inline result_type operator() (const Scalar& a, const Exponent& b) const { return numext::pow(a, b); }
-};
-template<typename Scalar, typename Exponent>
-struct functor_traits<scalar_pow_op<Scalar,Exponent> > {
-  enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false };
-};
-
-
-
-//---------- non associative binary functors ----------
-
-/** \internal
-  * \brief Template functor to compute the difference of two scalars
-  *
-  * \sa class CwiseBinaryOp, MatrixBase::operator-
-  */
-template<typename LhsScalar,typename RhsScalar>
-struct scalar_difference_op : binary_op_base<LhsScalar,RhsScalar>
-{
-  typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_difference_op>::ReturnType result_type;
-#ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_difference_op)
-#else
-  scalar_difference_op() {
-    EIGEN_SCALAR_BINARY_OP_PLUGIN
-  }
-#endif
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a - b; }
-  template<typename Packet>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
-  { return internal::psub(a,b); }
-};
-template<typename LhsScalar,typename RhsScalar>
-struct functor_traits<scalar_difference_op<LhsScalar,RhsScalar> > {
-  enum {
-    Cost = (NumTraits<LhsScalar>::AddCost+NumTraits<RhsScalar>::AddCost)/2,
-    PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasSub && packet_traits<RhsScalar>::HasSub
-  };
-};
-
-/** \internal
-  * \brief Template functor to compute the quotient of two scalars
-  *
-  * \sa class CwiseBinaryOp, Cwise::operator/()
-  */
-template<typename LhsScalar,typename RhsScalar>
-struct scalar_quotient_op  : binary_op_base<LhsScalar,RhsScalar>
-{
-  typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_quotient_op>::ReturnType result_type;
-#ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_quotient_op)
-#else
-  scalar_quotient_op() {
-    EIGEN_SCALAR_BINARY_OP_PLUGIN
-  }
-#endif
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a / b; }
-  template<typename Packet>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
-  { return internal::pdiv(a,b); }
-};
-template<typename LhsScalar,typename RhsScalar>
-struct functor_traits<scalar_quotient_op<LhsScalar,RhsScalar> > {
-  typedef typename scalar_quotient_op<LhsScalar,RhsScalar>::result_type result_type;
-  enum {
-    PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasDiv && packet_traits<RhsScalar>::HasDiv,
-    Cost = scalar_div_cost<result_type,PacketAccess>::value
-  };
-};
-
-
-
-/** \internal
-  * \brief Template functor to compute the and of two booleans
-  *
-  * \sa class CwiseBinaryOp, ArrayBase::operator&&
-  */
-struct scalar_boolean_and_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_and_op)
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a && b; }
-};
-template<> struct functor_traits<scalar_boolean_and_op> {
-  enum {
-    Cost = NumTraits<bool>::AddCost,
-    PacketAccess = false
-  };
-};
-
-/** \internal
-  * \brief Template functor to compute the or of two booleans
-  *
-  * \sa class CwiseBinaryOp, ArrayBase::operator||
-  */
-struct scalar_boolean_or_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_or_op)
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a || b; }
-};
-template<> struct functor_traits<scalar_boolean_or_op> {
-  enum {
-    Cost = NumTraits<bool>::AddCost,
-    PacketAccess = false
-  };
-};
-
-/** \internal
- * \brief Template functor to compute the xor of two booleans
- *
- * \sa class CwiseBinaryOp, ArrayBase::operator^
- */
-struct scalar_boolean_xor_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_xor_op)
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a ^ b; }
-};
-template<> struct functor_traits<scalar_boolean_xor_op> {
-  enum {
-    Cost = NumTraits<bool>::AddCost,
-    PacketAccess = false
-  };
-};
-
-
-
-//---------- binary functors bound to a constant, thus appearing as a unary functor ----------
-
-// The following two classes permits to turn any binary functor into a unary one with one argument bound to a constant value.
-// They are analogues to std::binder1st/binder2nd but with the following differences:
-//  - they are compatible with packetOp
-//  - they are portable across C++ versions (the std::binder* are deprecated in C++11)
-template<typename BinaryOp> struct bind1st_op : BinaryOp {
-
-  typedef typename BinaryOp::first_argument_type  first_argument_type;
-  typedef typename BinaryOp::second_argument_type second_argument_type;
-  typedef typename BinaryOp::result_type          result_type;
-
-  bind1st_op(const first_argument_type &val) : m_value(val) {}
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const second_argument_type& b) const { return BinaryOp::operator()(m_value,b); }
-
-  template<typename Packet>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& b) const
-  { return BinaryOp::packetOp(internal::pset1<Packet>(m_value), b); }
-
-  first_argument_type m_value;
-};
-template<typename BinaryOp> struct functor_traits<bind1st_op<BinaryOp> > : functor_traits<BinaryOp> {};
-
-
-template<typename BinaryOp> struct bind2nd_op : BinaryOp {
-
-  typedef typename BinaryOp::first_argument_type  first_argument_type;
-  typedef typename BinaryOp::second_argument_type second_argument_type;
-  typedef typename BinaryOp::result_type          result_type;
-
-  bind2nd_op(const second_argument_type &val) : m_value(val) {}
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const first_argument_type& a) const { return BinaryOp::operator()(a,m_value); }
-
-  template<typename Packet>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
-  { return BinaryOp::packetOp(a,internal::pset1<Packet>(m_value)); }
-
-  second_argument_type m_value;
-};
-template<typename BinaryOp> struct functor_traits<bind2nd_op<BinaryOp> > : functor_traits<BinaryOp> {};
-
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_BINARY_FUNCTORS_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/functors/NullaryFunctors.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/functors/NullaryFunctors.h
deleted file mode 100644
index b03be02..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/functors/NullaryFunctors.h
+++ /dev/null
@@ -1,188 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2016 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_NULLARY_FUNCTORS_H
-#define EIGEN_NULLARY_FUNCTORS_H
-
-namespace Eigen {
-
-namespace internal {
-
-template<typename Scalar>
-struct scalar_constant_op {
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_constant_op(const scalar_constant_op& other) : m_other(other.m_other) { }
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_constant_op(const Scalar& other) : m_other(other) { }
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() () const { return m_other; }
-  template<typename PacketType>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const PacketType packetOp() const { return internal::pset1<PacketType>(m_other); }
-  const Scalar m_other;
-};
-template<typename Scalar>
-struct functor_traits<scalar_constant_op<Scalar> >
-{ enum { Cost = 0 /* as the constant value should be loaded in register only once for the whole expression */,
-         PacketAccess = packet_traits<Scalar>::Vectorizable, IsRepeatable = true }; };
-
-template<typename Scalar> struct scalar_identity_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_identity_op)
-  template<typename IndexType>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (IndexType row, IndexType col) const { return row==col ? Scalar(1) : Scalar(0); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_identity_op<Scalar> >
-{ enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = false, IsRepeatable = true }; };
-
-template <typename Scalar, typename Packet, bool IsInteger> struct linspaced_op_impl;
-
-template <typename Scalar, typename Packet>
-struct linspaced_op_impl<Scalar,Packet,/*IsInteger*/false>
-{
-  linspaced_op_impl(const Scalar& low, const Scalar& high, Index num_steps) :
-    m_low(low), m_high(high), m_size1(num_steps==1 ? 1 : num_steps-1), m_step(num_steps==1 ? Scalar() : (high-low)/Scalar(num_steps-1)),
-    m_flip(numext::abs(high)<numext::abs(low))
-  {}
-
-  template<typename IndexType>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (IndexType i) const {
-    typedef typename NumTraits<Scalar>::Real RealScalar;
-    if(m_flip)
-      return (i==0)? m_low : (m_high - RealScalar(m_size1-i)*m_step);
-    else
-      return (i==m_size1)? m_high : (m_low + RealScalar(i)*m_step);
-  }
-
-  template<typename IndexType>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(IndexType i) const
-  {
-    // Principle:
-    // [low, ..., low] + ( [step, ..., step] * ( [i, ..., i] + [0, ..., size] ) )
-    if(m_flip)
-    {
-      Packet pi = plset<Packet>(Scalar(i-m_size1));
-      Packet res = padd(pset1<Packet>(m_high), pmul(pset1<Packet>(m_step), pi));
-      if(i==0)
-        res = pinsertfirst(res, m_low);
-      return res;
-    }
-    else
-    {
-      Packet pi = plset<Packet>(Scalar(i));
-      Packet res = padd(pset1<Packet>(m_low), pmul(pset1<Packet>(m_step), pi));
-      if(i==m_size1-unpacket_traits<Packet>::size+1)
-        res = pinsertlast(res, m_high);
-      return res;
-    }
-  }
-
-  const Scalar m_low;
-  const Scalar m_high;
-  const Index m_size1;
-  const Scalar m_step;
-  const bool m_flip;
-};
-
-template <typename Scalar, typename Packet>
-struct linspaced_op_impl<Scalar,Packet,/*IsInteger*/true>
-{
-  linspaced_op_impl(const Scalar& low, const Scalar& high, Index num_steps) :
-    m_low(low),
-    m_multiplier((high-low)/convert_index<Scalar>(num_steps<=1 ? 1 : num_steps-1)),
-    m_divisor(convert_index<Scalar>((high>=low?num_steps:-num_steps)+(high-low))/((numext::abs(high-low)+1)==0?1:(numext::abs(high-low)+1))),
-    m_use_divisor(num_steps>1 && (numext::abs(high-low)+1)<num_steps)
-  {}
-
-  template<typename IndexType>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
-  const Scalar operator() (IndexType i) const
-  {
-    if(m_use_divisor) return m_low + convert_index<Scalar>(i)/m_divisor;
-    else              return m_low + convert_index<Scalar>(i)*m_multiplier;
-  }
-
-  const Scalar m_low;
-  const Scalar m_multiplier;
-  const Scalar m_divisor;
-  const bool m_use_divisor;
-};
-
-// ----- Linspace functor ----------------------------------------------------------------
-
-// Forward declaration (we default to random access which does not really give
-// us a speed gain when using packet access but it allows to use the functor in
-// nested expressions).
-template <typename Scalar, typename PacketType> struct linspaced_op;
-template <typename Scalar, typename PacketType> struct functor_traits< linspaced_op<Scalar,PacketType> >
-{
-  enum
-  {
-    Cost = 1,
-    PacketAccess =   (!NumTraits<Scalar>::IsInteger) && packet_traits<Scalar>::HasSetLinear && packet_traits<Scalar>::HasBlend,
-                  /*&& ((!NumTraits<Scalar>::IsInteger) || packet_traits<Scalar>::HasDiv),*/ // <- vectorization for integer is currently disabled
-    IsRepeatable = true
-  };
-};
-template <typename Scalar, typename PacketType> struct linspaced_op
-{
-  linspaced_op(const Scalar& low, const Scalar& high, Index num_steps)
-    : impl((num_steps==1 ? high : low),high,num_steps)
-  {}
-
-  template<typename IndexType>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (IndexType i) const { return impl(i); }
-
-  template<typename Packet,typename IndexType>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(IndexType i) const { return impl.packetOp(i); }
-
-  // This proxy object handles the actual required temporaries and the different
-  // implementations (integer vs. floating point).
-  const linspaced_op_impl<Scalar,PacketType,NumTraits<Scalar>::IsInteger> impl;
-};
-
-// Linear access is automatically determined from the operator() prototypes available for the given functor.
-// If it exposes an operator()(i,j), then we assume the i and j coefficients are required independently
-// and linear access is not possible. In all other cases, linear access is enabled.
-// Users should not have to deal with this structure.
-template<typename Functor> struct functor_has_linear_access { enum { ret = !has_binary_operator<Functor>::value }; };
-
-// For unreliable compilers, let's specialize the has_*ary_operator
-// helpers so that at least built-in nullary functors work fine.
-#if !( (EIGEN_COMP_MSVC>1600) || (EIGEN_GNUC_AT_LEAST(4,8)) || (EIGEN_COMP_ICC>=1600))
-template<typename Scalar,typename IndexType>
-struct has_nullary_operator<scalar_constant_op<Scalar>,IndexType> { enum { value = 1}; };
-template<typename Scalar,typename IndexType>
-struct has_unary_operator<scalar_constant_op<Scalar>,IndexType> { enum { value = 0}; };
-template<typename Scalar,typename IndexType>
-struct has_binary_operator<scalar_constant_op<Scalar>,IndexType> { enum { value = 0}; };
-
-template<typename Scalar,typename IndexType>
-struct has_nullary_operator<scalar_identity_op<Scalar>,IndexType> { enum { value = 0}; };
-template<typename Scalar,typename IndexType>
-struct has_unary_operator<scalar_identity_op<Scalar>,IndexType> { enum { value = 0}; };
-template<typename Scalar,typename IndexType>
-struct has_binary_operator<scalar_identity_op<Scalar>,IndexType> { enum { value = 1}; };
-
-template<typename Scalar, typename PacketType,typename IndexType>
-struct has_nullary_operator<linspaced_op<Scalar,PacketType>,IndexType> { enum { value = 0}; };
-template<typename Scalar, typename PacketType,typename IndexType>
-struct has_unary_operator<linspaced_op<Scalar,PacketType>,IndexType> { enum { value = 1}; };
-template<typename Scalar, typename PacketType,typename IndexType>
-struct has_binary_operator<linspaced_op<Scalar,PacketType>,IndexType> { enum { value = 0}; };
-
-template<typename Scalar,typename IndexType>
-struct has_nullary_operator<scalar_random_op<Scalar>,IndexType> { enum { value = 1}; };
-template<typename Scalar,typename IndexType>
-struct has_unary_operator<scalar_random_op<Scalar>,IndexType> { enum { value = 0}; };
-template<typename Scalar,typename IndexType>
-struct has_binary_operator<scalar_random_op<Scalar>,IndexType> { enum { value = 0}; };
-#endif
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_NULLARY_FUNCTORS_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/functors/StlFunctors.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/functors/StlFunctors.h
deleted file mode 100644
index 9c1d758..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/functors/StlFunctors.h
+++ /dev/null
@@ -1,136 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_STL_FUNCTORS_H
-#define EIGEN_STL_FUNCTORS_H
-
-namespace Eigen {
-
-namespace internal {
-
-// default functor traits for STL functors:
-
-template<typename T>
-struct functor_traits<std::multiplies<T> >
-{ enum { Cost = NumTraits<T>::MulCost, PacketAccess = false }; };
-
-template<typename T>
-struct functor_traits<std::divides<T> >
-{ enum { Cost = NumTraits<T>::MulCost, PacketAccess = false }; };
-
-template<typename T>
-struct functor_traits<std::plus<T> >
-{ enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
-
-template<typename T>
-struct functor_traits<std::minus<T> >
-{ enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
-
-template<typename T>
-struct functor_traits<std::negate<T> >
-{ enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
-
-template<typename T>
-struct functor_traits<std::logical_or<T> >
-{ enum { Cost = 1, PacketAccess = false }; };
-
-template<typename T>
-struct functor_traits<std::logical_and<T> >
-{ enum { Cost = 1, PacketAccess = false }; };
-
-template<typename T>
-struct functor_traits<std::logical_not<T> >
-{ enum { Cost = 1, PacketAccess = false }; };
-
-template<typename T>
-struct functor_traits<std::greater<T> >
-{ enum { Cost = 1, PacketAccess = false }; };
-
-template<typename T>
-struct functor_traits<std::less<T> >
-{ enum { Cost = 1, PacketAccess = false }; };
-
-template<typename T>
-struct functor_traits<std::greater_equal<T> >
-{ enum { Cost = 1, PacketAccess = false }; };
-
-template<typename T>
-struct functor_traits<std::less_equal<T> >
-{ enum { Cost = 1, PacketAccess = false }; };
-
-template<typename T>
-struct functor_traits<std::equal_to<T> >
-{ enum { Cost = 1, PacketAccess = false }; };
-
-template<typename T>
-struct functor_traits<std::not_equal_to<T> >
-{ enum { Cost = 1, PacketAccess = false }; };
-
-#if (__cplusplus < 201103L) && (EIGEN_COMP_MSVC <= 1900)
-// std::binder* are deprecated since c++11 and will be removed in c++17
-template<typename T>
-struct functor_traits<std::binder2nd<T> >
-{ enum { Cost = functor_traits<T>::Cost, PacketAccess = false }; };
-
-template<typename T>
-struct functor_traits<std::binder1st<T> >
-{ enum { Cost = functor_traits<T>::Cost, PacketAccess = false }; };
-#endif
-
-#if (__cplusplus < 201703L) && (EIGEN_COMP_MSVC < 1910)
-// std::unary_negate is deprecated since c++17 and will be removed in c++20
-template<typename T>
-struct functor_traits<std::unary_negate<T> >
-{ enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false }; };
-
-// std::binary_negate is deprecated since c++17 and will be removed in c++20
-template<typename T>
-struct functor_traits<std::binary_negate<T> >
-{ enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false }; };
-#endif
-
-#ifdef EIGEN_STDEXT_SUPPORT
-
-template<typename T0,typename T1>
-struct functor_traits<std::project1st<T0,T1> >
-{ enum { Cost = 0, PacketAccess = false }; };
-
-template<typename T0,typename T1>
-struct functor_traits<std::project2nd<T0,T1> >
-{ enum { Cost = 0, PacketAccess = false }; };
-
-template<typename T0,typename T1>
-struct functor_traits<std::select2nd<std::pair<T0,T1> > >
-{ enum { Cost = 0, PacketAccess = false }; };
-
-template<typename T0,typename T1>
-struct functor_traits<std::select1st<std::pair<T0,T1> > >
-{ enum { Cost = 0, PacketAccess = false }; };
-
-template<typename T0,typename T1>
-struct functor_traits<std::unary_compose<T0,T1> >
-{ enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost, PacketAccess = false }; };
-
-template<typename T0,typename T1,typename T2>
-struct functor_traits<std::binary_compose<T0,T1,T2> >
-{ enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost + functor_traits<T2>::Cost, PacketAccess = false }; };
-
-#endif // EIGEN_STDEXT_SUPPORT
-
-// allow to add new functors and specializations of functor_traits from outside Eigen.
-// this macro is really needed because functor_traits must be specialized after it is declared but before it is used...
-#ifdef EIGEN_FUNCTORS_PLUGIN
-#include EIGEN_FUNCTORS_PLUGIN
-#endif
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_STL_FUNCTORS_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/functors/TernaryFunctors.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/functors/TernaryFunctors.h
deleted file mode 100644
index b254e96..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/functors/TernaryFunctors.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2016 Eugene Brevdo <ebrevdo@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_TERNARY_FUNCTORS_H
-#define EIGEN_TERNARY_FUNCTORS_H
-
-namespace Eigen {
-
-namespace internal {
-
-//---------- associative ternary functors ----------
-
-
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_TERNARY_FUNCTORS_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/functors/UnaryFunctors.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/functors/UnaryFunctors.h
deleted file mode 100644
index 2e6a00f..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/functors/UnaryFunctors.h
+++ /dev/null
@@ -1,792 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2016 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_UNARY_FUNCTORS_H
-#define EIGEN_UNARY_FUNCTORS_H
-
-namespace Eigen {
-
-namespace internal {
-
-/** \internal
-  * \brief Template functor to compute the opposite of a scalar
-  *
-  * \sa class CwiseUnaryOp, MatrixBase::operator-
-  */
-template<typename Scalar> struct scalar_opposite_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_opposite_op)
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return -a; }
-  template<typename Packet>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
-  { return internal::pnegate(a); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_opposite_op<Scalar> >
-{ enum {
-    Cost = NumTraits<Scalar>::AddCost,
-    PacketAccess = packet_traits<Scalar>::HasNegate };
-};
-
-/** \internal
-  * \brief Template functor to compute the absolute value of a scalar
-  *
-  * \sa class CwiseUnaryOp, Cwise::abs
-  */
-template<typename Scalar> struct scalar_abs_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_abs_op)
-  typedef typename NumTraits<Scalar>::Real result_type;
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return numext::abs(a); }
-  template<typename Packet>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
-  { return internal::pabs(a); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_abs_op<Scalar> >
-{
-  enum {
-    Cost = NumTraits<Scalar>::AddCost,
-    PacketAccess = packet_traits<Scalar>::HasAbs
-  };
-};
-
-/** \internal
-  * \brief Template functor to compute the score of a scalar, to chose a pivot
-  *
-  * \sa class CwiseUnaryOp
-  */
-template<typename Scalar> struct scalar_score_coeff_op : scalar_abs_op<Scalar>
-{
-  typedef void Score_is_abs;
-};
-template<typename Scalar>
-struct functor_traits<scalar_score_coeff_op<Scalar> > : functor_traits<scalar_abs_op<Scalar> > {};
-
-/* Avoid recomputing abs when we know the score and they are the same. Not a true Eigen functor.  */
-template<typename Scalar, typename=void> struct abs_knowing_score
-{
-  EIGEN_EMPTY_STRUCT_CTOR(abs_knowing_score)
-  typedef typename NumTraits<Scalar>::Real result_type;
-  template<typename Score>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a, const Score&) const { return numext::abs(a); }
-};
-template<typename Scalar> struct abs_knowing_score<Scalar, typename scalar_score_coeff_op<Scalar>::Score_is_abs>
-{
-  EIGEN_EMPTY_STRUCT_CTOR(abs_knowing_score)
-  typedef typename NumTraits<Scalar>::Real result_type;
-  template<typename Scal>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const Scal&, const result_type& a) const { return a; }
-};
-
-/** \internal
-  * \brief Template functor to compute the squared absolute value of a scalar
-  *
-  * \sa class CwiseUnaryOp, Cwise::abs2
-  */
-template<typename Scalar> struct scalar_abs2_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_abs2_op)
-  typedef typename NumTraits<Scalar>::Real result_type;
-  EIGEN_DEVICE_FUNC
-  EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return numext::abs2(a); }
-  template<typename Packet>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
-  { return internal::pmul(a,a); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_abs2_op<Scalar> >
-{ enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasAbs2 }; };
-
-/** \internal
-  * \brief Template functor to compute the conjugate of a complex value
-  *
-  * \sa class CwiseUnaryOp, MatrixBase::conjugate()
-  */
-template<typename Scalar> struct scalar_conjugate_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_conjugate_op)
-  EIGEN_DEVICE_FUNC
-  EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { using numext::conj; return conj(a); }
-  template<typename Packet>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const { return internal::pconj(a); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_conjugate_op<Scalar> >
-{
-  enum {
-    Cost = NumTraits<Scalar>::IsComplex ? NumTraits<Scalar>::AddCost : 0,
-    PacketAccess = packet_traits<Scalar>::HasConj
-  };
-};
-
-/** \internal
-  * \brief Template functor to compute the phase angle of a complex
-  *
-  * \sa class CwiseUnaryOp, Cwise::arg
-  */
-template<typename Scalar> struct scalar_arg_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_arg_op)
-  typedef typename NumTraits<Scalar>::Real result_type;
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { using numext::arg; return arg(a); }
-  template<typename Packet>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
-  { return internal::parg(a); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_arg_op<Scalar> >
-{
-  enum {
-    Cost = NumTraits<Scalar>::IsComplex ? 5 * NumTraits<Scalar>::MulCost : NumTraits<Scalar>::AddCost,
-    PacketAccess = packet_traits<Scalar>::HasArg
-  };
-};
-/** \internal
-  * \brief Template functor to cast a scalar to another type
-  *
-  * \sa class CwiseUnaryOp, MatrixBase::cast()
-  */
-template<typename Scalar, typename NewType>
-struct scalar_cast_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_cast_op)
-  typedef NewType result_type;
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const NewType operator() (const Scalar& a) const { return cast<Scalar, NewType>(a); }
-};
-template<typename Scalar, typename NewType>
-struct functor_traits<scalar_cast_op<Scalar,NewType> >
-{ enum { Cost = is_same<Scalar, NewType>::value ? 0 : NumTraits<NewType>::AddCost, PacketAccess = false }; };
-
-/** \internal
-  * \brief Template functor to extract the real part of a complex
-  *
-  * \sa class CwiseUnaryOp, MatrixBase::real()
-  */
-template<typename Scalar>
-struct scalar_real_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_real_op)
-  typedef typename NumTraits<Scalar>::Real result_type;
-  EIGEN_DEVICE_FUNC
-  EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::real(a); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_real_op<Scalar> >
-{ enum { Cost = 0, PacketAccess = false }; };
-
-/** \internal
-  * \brief Template functor to extract the imaginary part of a complex
-  *
-  * \sa class CwiseUnaryOp, MatrixBase::imag()
-  */
-template<typename Scalar>
-struct scalar_imag_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_op)
-  typedef typename NumTraits<Scalar>::Real result_type;
-  EIGEN_DEVICE_FUNC
-  EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::imag(a); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_imag_op<Scalar> >
-{ enum { Cost = 0, PacketAccess = false }; };
-
-/** \internal
-  * \brief Template functor to extract the real part of a complex as a reference
-  *
-  * \sa class CwiseUnaryOp, MatrixBase::real()
-  */
-template<typename Scalar>
-struct scalar_real_ref_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_real_ref_op)
-  typedef typename NumTraits<Scalar>::Real result_type;
-  EIGEN_DEVICE_FUNC
-  EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return numext::real_ref(*const_cast<Scalar*>(&a)); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_real_ref_op<Scalar> >
-{ enum { Cost = 0, PacketAccess = false }; };
-
-/** \internal
-  * \brief Template functor to extract the imaginary part of a complex as a reference
-  *
-  * \sa class CwiseUnaryOp, MatrixBase::imag()
-  */
-template<typename Scalar>
-struct scalar_imag_ref_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_ref_op)
-  typedef typename NumTraits<Scalar>::Real result_type;
-  EIGEN_DEVICE_FUNC
-  EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return numext::imag_ref(*const_cast<Scalar*>(&a)); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_imag_ref_op<Scalar> >
-{ enum { Cost = 0, PacketAccess = false }; };
-
-/** \internal
-  *
-  * \brief Template functor to compute the exponential of a scalar
-  *
-  * \sa class CwiseUnaryOp, Cwise::exp()
-  */
-template<typename Scalar> struct scalar_exp_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_exp_op)
-  EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::exp(a); }
-  template <typename Packet>
-  EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pexp(a); }
-};
-template <typename Scalar>
-struct functor_traits<scalar_exp_op<Scalar> > {
-  enum {
-    PacketAccess = packet_traits<Scalar>::HasExp,
-    // The following numbers are based on the AVX implementation.
-#ifdef EIGEN_VECTORIZE_FMA
-    // Haswell can issue 2 add/mul/madd per cycle.
-    Cost =
-    (sizeof(Scalar) == 4
-     // float: 8 pmadd, 4 pmul, 2 padd/psub, 6 other
-     ? (8 * NumTraits<Scalar>::AddCost + 6 * NumTraits<Scalar>::MulCost)
-     // double: 7 pmadd, 5 pmul, 3 padd/psub, 1 div,  13 other
-     : (14 * NumTraits<Scalar>::AddCost +
-        6 * NumTraits<Scalar>::MulCost +
-        scalar_div_cost<Scalar,packet_traits<Scalar>::HasDiv>::value))
-#else
-    Cost =
-    (sizeof(Scalar) == 4
-     // float: 7 pmadd, 6 pmul, 4 padd/psub, 10 other
-     ? (21 * NumTraits<Scalar>::AddCost + 13 * NumTraits<Scalar>::MulCost)
-     // double: 7 pmadd, 5 pmul, 3 padd/psub, 1 div,  13 other
-     : (23 * NumTraits<Scalar>::AddCost +
-        12 * NumTraits<Scalar>::MulCost +
-        scalar_div_cost<Scalar,packet_traits<Scalar>::HasDiv>::value))
-#endif
-  };
-};
-
-/** \internal
-  *
-  * \brief Template functor to compute the logarithm of a scalar
-  *
-  * \sa class CwiseUnaryOp, ArrayBase::log()
-  */
-template<typename Scalar> struct scalar_log_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_log_op)
-  EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::log(a); }
-  template <typename Packet>
-  EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::plog(a); }
-};
-template <typename Scalar>
-struct functor_traits<scalar_log_op<Scalar> > {
-  enum {
-    PacketAccess = packet_traits<Scalar>::HasLog,
-    Cost =
-    (PacketAccess
-     // The following numbers are based on the AVX implementation.
-#ifdef EIGEN_VECTORIZE_FMA
-     // 8 pmadd, 6 pmul, 8 padd/psub, 16 other, can issue 2 add/mul/madd per cycle.
-     ? (20 * NumTraits<Scalar>::AddCost + 7 * NumTraits<Scalar>::MulCost)
-#else
-     // 8 pmadd, 6 pmul, 8 padd/psub, 20 other
-     ? (36 * NumTraits<Scalar>::AddCost + 14 * NumTraits<Scalar>::MulCost)
-#endif
-     // Measured cost of std::log.
-     : sizeof(Scalar)==4 ? 40 : 85)
-  };
-};
-
-/** \internal
-  *
-  * \brief Template functor to compute the logarithm of 1 plus a scalar value
-  *
-  * \sa class CwiseUnaryOp, ArrayBase::log1p()
-  */
-template<typename Scalar> struct scalar_log1p_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_log1p_op)
-  EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::log1p(a); }
-  template <typename Packet>
-  EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::plog1p(a); }
-};
-template <typename Scalar>
-struct functor_traits<scalar_log1p_op<Scalar> > {
-  enum {
-    PacketAccess = packet_traits<Scalar>::HasLog1p,
-    Cost = functor_traits<scalar_log_op<Scalar> >::Cost // TODO measure cost of log1p
-  };
-};
-
-/** \internal
-  *
-  * \brief Template functor to compute the base-10 logarithm of a scalar
-  *
-  * \sa class CwiseUnaryOp, Cwise::log10()
-  */
-template<typename Scalar> struct scalar_log10_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_log10_op)
-  EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { EIGEN_USING_STD_MATH(log10) return log10(a); }
-  template <typename Packet>
-  EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::plog10(a); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_log10_op<Scalar> >
-{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasLog10 }; };
-
-/** \internal
-  * \brief Template functor to compute the square root of a scalar
-  * \sa class CwiseUnaryOp, Cwise::sqrt()
-  */
-template<typename Scalar> struct scalar_sqrt_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_sqrt_op)
-  EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::sqrt(a); }
-  template <typename Packet>
-  EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::psqrt(a); }
-};
-template <typename Scalar>
-struct functor_traits<scalar_sqrt_op<Scalar> > {
-  enum {
-#if EIGEN_FAST_MATH
-    // The following numbers are based on the AVX implementation.
-    Cost = (sizeof(Scalar) == 8 ? 28
-                                // 4 pmul, 1 pmadd, 3 other
-                                : (3 * NumTraits<Scalar>::AddCost +
-                                   5 * NumTraits<Scalar>::MulCost)),
-#else
-    // The following numbers are based on min VSQRT throughput on Haswell.
-    Cost = (sizeof(Scalar) == 8 ? 28 : 14),
-#endif
-    PacketAccess = packet_traits<Scalar>::HasSqrt
-  };
-};
-
-/** \internal
-  * \brief Template functor to compute the reciprocal square root of a scalar
-  * \sa class CwiseUnaryOp, Cwise::rsqrt()
-  */
-template<typename Scalar> struct scalar_rsqrt_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_rsqrt_op)
-  EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return Scalar(1)/numext::sqrt(a); }
-  template <typename Packet>
-  EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::prsqrt(a); }
-};
-
-template<typename Scalar>
-struct functor_traits<scalar_rsqrt_op<Scalar> >
-{ enum {
-    Cost = 5 * NumTraits<Scalar>::MulCost,
-    PacketAccess = packet_traits<Scalar>::HasRsqrt
-  };
-};
-
-/** \internal
-  * \brief Template functor to compute the cosine of a scalar
-  * \sa class CwiseUnaryOp, ArrayBase::cos()
-  */
-template<typename Scalar> struct scalar_cos_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_cos_op)
-  EIGEN_DEVICE_FUNC inline Scalar operator() (const Scalar& a) const { return numext::cos(a); }
-  template <typename Packet>
-  EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pcos(a); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_cos_op<Scalar> >
-{
-  enum {
-    Cost = 5 * NumTraits<Scalar>::MulCost,
-    PacketAccess = packet_traits<Scalar>::HasCos
-  };
-};
-
-/** \internal
-  * \brief Template functor to compute the sine of a scalar
-  * \sa class CwiseUnaryOp, ArrayBase::sin()
-  */
-template<typename Scalar> struct scalar_sin_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_sin_op)
-  EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::sin(a); }
-  template <typename Packet>
-  EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::psin(a); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_sin_op<Scalar> >
-{
-  enum {
-    Cost = 5 * NumTraits<Scalar>::MulCost,
-    PacketAccess = packet_traits<Scalar>::HasSin
-  };
-};
-
-
-/** \internal
-  * \brief Template functor to compute the tan of a scalar
-  * \sa class CwiseUnaryOp, ArrayBase::tan()
-  */
-template<typename Scalar> struct scalar_tan_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_tan_op)
-  EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::tan(a); }
-  template <typename Packet>
-  EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::ptan(a); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_tan_op<Scalar> >
-{
-  enum {
-    Cost = 5 * NumTraits<Scalar>::MulCost,
-    PacketAccess = packet_traits<Scalar>::HasTan
-  };
-};
-
-/** \internal
-  * \brief Template functor to compute the arc cosine of a scalar
-  * \sa class CwiseUnaryOp, ArrayBase::acos()
-  */
-template<typename Scalar> struct scalar_acos_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_acos_op)
-  EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::acos(a); }
-  template <typename Packet>
-  EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pacos(a); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_acos_op<Scalar> >
-{
-  enum {
-    Cost = 5 * NumTraits<Scalar>::MulCost,
-    PacketAccess = packet_traits<Scalar>::HasACos
-  };
-};
-
-/** \internal
-  * \brief Template functor to compute the arc sine of a scalar
-  * \sa class CwiseUnaryOp, ArrayBase::asin()
-  */
-template<typename Scalar> struct scalar_asin_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_asin_op)
-  EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::asin(a); }
-  template <typename Packet>
-  EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pasin(a); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_asin_op<Scalar> >
-{
-  enum {
-    Cost = 5 * NumTraits<Scalar>::MulCost,
-    PacketAccess = packet_traits<Scalar>::HasASin
-  };
-};
-
-
-/** \internal
-  * \brief Template functor to compute the atan of a scalar
-  * \sa class CwiseUnaryOp, ArrayBase::atan()
-  */
-template<typename Scalar> struct scalar_atan_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_atan_op)
-  EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::atan(a); }
-  template <typename Packet>
-  EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::patan(a); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_atan_op<Scalar> >
-{
-  enum {
-    Cost = 5 * NumTraits<Scalar>::MulCost,
-    PacketAccess = packet_traits<Scalar>::HasATan
-  };
-};
-
-/** \internal
-  * \brief Template functor to compute the tanh of a scalar
-  * \sa class CwiseUnaryOp, ArrayBase::tanh()
-  */
-template <typename Scalar>
-struct scalar_tanh_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_tanh_op)
-  EIGEN_DEVICE_FUNC inline const Scalar operator()(const Scalar& a) const { return numext::tanh(a); }
-  template <typename Packet>
-  EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& x) const { return ptanh(x); }
-};
-
-template <typename Scalar>
-struct functor_traits<scalar_tanh_op<Scalar> > {
-  enum {
-    PacketAccess = packet_traits<Scalar>::HasTanh,
-    Cost = ( (EIGEN_FAST_MATH && is_same<Scalar,float>::value)
-// The following numbers are based on the AVX implementation,
-#ifdef EIGEN_VECTORIZE_FMA
-                // Haswell can issue 2 add/mul/madd per cycle.
-                // 9 pmadd, 2 pmul, 1 div, 2 other
-                ? (2 * NumTraits<Scalar>::AddCost +
-                   6 * NumTraits<Scalar>::MulCost +
-                   scalar_div_cost<Scalar,packet_traits<Scalar>::HasDiv>::value)
-#else
-                ? (11 * NumTraits<Scalar>::AddCost +
-                   11 * NumTraits<Scalar>::MulCost +
-                   scalar_div_cost<Scalar,packet_traits<Scalar>::HasDiv>::value)
-#endif
-                // This number assumes a naive implementation of tanh
-                : (6 * NumTraits<Scalar>::AddCost +
-                   3 * NumTraits<Scalar>::MulCost +
-                   2 * scalar_div_cost<Scalar,packet_traits<Scalar>::HasDiv>::value +
-                   functor_traits<scalar_exp_op<Scalar> >::Cost))
-  };
-};
-
-/** \internal
-  * \brief Template functor to compute the sinh of a scalar
-  * \sa class CwiseUnaryOp, ArrayBase::sinh()
-  */
-template<typename Scalar> struct scalar_sinh_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_sinh_op)
-  EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::sinh(a); }
-  template <typename Packet>
-  EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::psinh(a); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_sinh_op<Scalar> >
-{
-  enum {
-    Cost = 5 * NumTraits<Scalar>::MulCost,
-    PacketAccess = packet_traits<Scalar>::HasSinh
-  };
-};
-
-/** \internal
-  * \brief Template functor to compute the cosh of a scalar
-  * \sa class CwiseUnaryOp, ArrayBase::cosh()
-  */
-template<typename Scalar> struct scalar_cosh_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_cosh_op)
-  EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::cosh(a); }
-  template <typename Packet>
-  EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pcosh(a); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_cosh_op<Scalar> >
-{
-  enum {
-    Cost = 5 * NumTraits<Scalar>::MulCost,
-    PacketAccess = packet_traits<Scalar>::HasCosh
-  };
-};
-
-/** \internal
-  * \brief Template functor to compute the inverse of a scalar
-  * \sa class CwiseUnaryOp, Cwise::inverse()
-  */
-template<typename Scalar>
-struct scalar_inverse_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_inverse_op)
-  EIGEN_DEVICE_FUNC inline Scalar operator() (const Scalar& a) const { return Scalar(1)/a; }
-  template<typename Packet>
-  EIGEN_DEVICE_FUNC inline const Packet packetOp(const Packet& a) const
-  { return internal::pdiv(pset1<Packet>(Scalar(1)),a); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_inverse_op<Scalar> >
-{ enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasDiv }; };
-
-/** \internal
-  * \brief Template functor to compute the square of a scalar
-  * \sa class CwiseUnaryOp, Cwise::square()
-  */
-template<typename Scalar>
-struct scalar_square_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_square_op)
-  EIGEN_DEVICE_FUNC inline Scalar operator() (const Scalar& a) const { return a*a; }
-  template<typename Packet>
-  EIGEN_DEVICE_FUNC inline const Packet packetOp(const Packet& a) const
-  { return internal::pmul(a,a); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_square_op<Scalar> >
-{ enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; };
-
-/** \internal
-  * \brief Template functor to compute the cube of a scalar
-  * \sa class CwiseUnaryOp, Cwise::cube()
-  */
-template<typename Scalar>
-struct scalar_cube_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_cube_op)
-  EIGEN_DEVICE_FUNC inline Scalar operator() (const Scalar& a) const { return a*a*a; }
-  template<typename Packet>
-  EIGEN_DEVICE_FUNC inline const Packet packetOp(const Packet& a) const
-  { return internal::pmul(a,pmul(a,a)); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_cube_op<Scalar> >
-{ enum { Cost = 2*NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; };
-
-/** \internal
-  * \brief Template functor to compute the rounded value of a scalar
-  * \sa class CwiseUnaryOp, ArrayBase::round()
-  */
-template<typename Scalar> struct scalar_round_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_round_op)
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return numext::round(a); }
-  template <typename Packet>
-  EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pround(a); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_round_op<Scalar> >
-{
-  enum {
-    Cost = NumTraits<Scalar>::MulCost,
-    PacketAccess = packet_traits<Scalar>::HasRound
-  };
-};
-
-/** \internal
-  * \brief Template functor to compute the floor of a scalar
-  * \sa class CwiseUnaryOp, ArrayBase::floor()
-  */
-template<typename Scalar> struct scalar_floor_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_floor_op)
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return numext::floor(a); }
-  template <typename Packet>
-  EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pfloor(a); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_floor_op<Scalar> >
-{
-  enum {
-    Cost = NumTraits<Scalar>::MulCost,
-    PacketAccess = packet_traits<Scalar>::HasFloor
-  };
-};
-
-/** \internal
-  * \brief Template functor to compute the ceil of a scalar
-  * \sa class CwiseUnaryOp, ArrayBase::ceil()
-  */
-template<typename Scalar> struct scalar_ceil_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_ceil_op)
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return numext::ceil(a); }
-  template <typename Packet>
-  EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pceil(a); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_ceil_op<Scalar> >
-{
-  enum {
-    Cost = NumTraits<Scalar>::MulCost,
-    PacketAccess = packet_traits<Scalar>::HasCeil
-  };
-};
-
-/** \internal
-  * \brief Template functor to compute whether a scalar is NaN
-  * \sa class CwiseUnaryOp, ArrayBase::isnan()
-  */
-template<typename Scalar> struct scalar_isnan_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_isnan_op)
-  typedef bool result_type;
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return (numext::isnan)(a); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_isnan_op<Scalar> >
-{
-  enum {
-    Cost = NumTraits<Scalar>::MulCost,
-    PacketAccess = false
-  };
-};
-
-/** \internal
-  * \brief Template functor to check whether a scalar is +/-inf
-  * \sa class CwiseUnaryOp, ArrayBase::isinf()
-  */
-template<typename Scalar> struct scalar_isinf_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_isinf_op)
-  typedef bool result_type;
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return (numext::isinf)(a); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_isinf_op<Scalar> >
-{
-  enum {
-    Cost = NumTraits<Scalar>::MulCost,
-    PacketAccess = false
-  };
-};
-
-/** \internal
-  * \brief Template functor to check whether a scalar has a finite value
-  * \sa class CwiseUnaryOp, ArrayBase::isfinite()
-  */
-template<typename Scalar> struct scalar_isfinite_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_isfinite_op)
-  typedef bool result_type;
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return (numext::isfinite)(a); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_isfinite_op<Scalar> >
-{
-  enum {
-    Cost = NumTraits<Scalar>::MulCost,
-    PacketAccess = false
-  };
-};
-
-/** \internal
-  * \brief Template functor to compute the logical not of a boolean
-  *
-  * \sa class CwiseUnaryOp, ArrayBase::operator!
-  */
-template<typename Scalar> struct scalar_boolean_not_op {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_not_op)
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator() (const bool& a) const { return !a; }
-};
-template<typename Scalar>
-struct functor_traits<scalar_boolean_not_op<Scalar> > {
-  enum {
-    Cost = NumTraits<bool>::AddCost,
-    PacketAccess = false
-  };
-};
-
-/** \internal
-  * \brief Template functor to compute the signum of a scalar
-  * \sa class CwiseUnaryOp, Cwise::sign()
-  */
-template<typename Scalar,bool iscpx=(NumTraits<Scalar>::IsComplex!=0) > struct scalar_sign_op;
-template<typename Scalar>
-struct scalar_sign_op<Scalar,false> {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_sign_op)
-  EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const
-  {
-      return Scalar( (a>Scalar(0)) - (a<Scalar(0)) );
-  }
-  //TODO
-  //template <typename Packet>
-  //EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::psign(a); }
-};
-template<typename Scalar>
-struct scalar_sign_op<Scalar,true> {
-  EIGEN_EMPTY_STRUCT_CTOR(scalar_sign_op)
-  EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const
-  {
-    typedef typename NumTraits<Scalar>::Real real_type;
-    real_type aa = numext::abs(a);
-    if (aa==real_type(0))
-      return Scalar(0);
-    aa = real_type(1)/aa;
-    return Scalar(real(a)*aa, imag(a)*aa );
-  }
-  //TODO
-  //template <typename Packet>
-  //EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::psign(a); }
-};
-template<typename Scalar>
-struct functor_traits<scalar_sign_op<Scalar> >
-{ enum {
-    Cost = 
-        NumTraits<Scalar>::IsComplex
-        ? ( 8*NumTraits<Scalar>::MulCost  ) // roughly
-        : ( 3*NumTraits<Scalar>::AddCost),
-    PacketAccess = packet_traits<Scalar>::HasSign
-  };
-};
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_FUNCTORS_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/GeneralBlockPanelKernel.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/GeneralBlockPanelKernel.h
deleted file mode 100644
index e3980f6..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/GeneralBlockPanelKernel.h
+++ /dev/null
@@ -1,2156 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_GENERAL_BLOCK_PANEL_H
-#define EIGEN_GENERAL_BLOCK_PANEL_H
-
-
-namespace Eigen {
-
-namespace internal {
-
-template<typename _LhsScalar, typename _RhsScalar, bool _ConjLhs=false, bool _ConjRhs=false>
-class gebp_traits;
-
-
-/** \internal \returns b if a<=0, and returns a otherwise. */
-inline std::ptrdiff_t manage_caching_sizes_helper(std::ptrdiff_t a, std::ptrdiff_t b)
-{
-  return a<=0 ? b : a;
-}
-
-#if EIGEN_ARCH_i386_OR_x86_64
-const std::ptrdiff_t defaultL1CacheSize = 32*1024;
-const std::ptrdiff_t defaultL2CacheSize = 256*1024;
-const std::ptrdiff_t defaultL3CacheSize = 2*1024*1024;
-#else
-const std::ptrdiff_t defaultL1CacheSize = 16*1024;
-const std::ptrdiff_t defaultL2CacheSize = 512*1024;
-const std::ptrdiff_t defaultL3CacheSize = 512*1024;
-#endif
-
-/** \internal */
-struct CacheSizes {
-  CacheSizes(): m_l1(-1),m_l2(-1),m_l3(-1) {
-    int l1CacheSize, l2CacheSize, l3CacheSize;
-    queryCacheSizes(l1CacheSize, l2CacheSize, l3CacheSize);
-    m_l1 = manage_caching_sizes_helper(l1CacheSize, defaultL1CacheSize);
-    m_l2 = manage_caching_sizes_helper(l2CacheSize, defaultL2CacheSize);
-    m_l3 = manage_caching_sizes_helper(l3CacheSize, defaultL3CacheSize);
-  }
-
-  std::ptrdiff_t m_l1;
-  std::ptrdiff_t m_l2;
-  std::ptrdiff_t m_l3;
-};
-
-
-/** \internal */
-inline void manage_caching_sizes(Action action, std::ptrdiff_t* l1, std::ptrdiff_t* l2, std::ptrdiff_t* l3)
-{
-  static CacheSizes m_cacheSizes;
-
-  if(action==SetAction)
-  {
-    // set the cpu cache size and cache all block sizes from a global cache size in byte
-    eigen_internal_assert(l1!=0 && l2!=0);
-    m_cacheSizes.m_l1 = *l1;
-    m_cacheSizes.m_l2 = *l2;
-    m_cacheSizes.m_l3 = *l3;
-  }
-  else if(action==GetAction)
-  {
-    eigen_internal_assert(l1!=0 && l2!=0);
-    *l1 = m_cacheSizes.m_l1;
-    *l2 = m_cacheSizes.m_l2;
-    *l3 = m_cacheSizes.m_l3;
-  }
-  else
-  {
-    eigen_internal_assert(false);
-  }
-}
-
-/* Helper for computeProductBlockingSizes.
- *
- * Given a m x k times k x n matrix product of scalar types \c LhsScalar and \c RhsScalar,
- * this function computes the blocking size parameters along the respective dimensions
- * for matrix products and related algorithms. The blocking sizes depends on various
- * parameters:
- * - the L1 and L2 cache sizes,
- * - the register level blocking sizes defined by gebp_traits,
- * - the number of scalars that fit into a packet (when vectorization is enabled).
- *
- * \sa setCpuCacheSizes */
-
-template<typename LhsScalar, typename RhsScalar, int KcFactor, typename Index>
-void evaluateProductBlockingSizesHeuristic(Index& k, Index& m, Index& n, Index num_threads = 1)
-{
-  typedef gebp_traits<LhsScalar,RhsScalar> Traits;
-
-  // Explanations:
-  // Let's recall that the product algorithms form mc x kc vertical panels A' on the lhs and
-  // kc x nc blocks B' on the rhs. B' has to fit into L2/L3 cache. Moreover, A' is processed
-  // per mr x kc horizontal small panels where mr is the blocking size along the m dimension
-  // at the register level. This small horizontal panel has to stay within L1 cache.
-  std::ptrdiff_t l1, l2, l3;
-  manage_caching_sizes(GetAction, &l1, &l2, &l3);
-
-  if (num_threads > 1) {
-    typedef typename Traits::ResScalar ResScalar;
-    enum {
-      kdiv = KcFactor * (Traits::mr * sizeof(LhsScalar) + Traits::nr * sizeof(RhsScalar)),
-      ksub = Traits::mr * Traits::nr * sizeof(ResScalar),
-      kr = 8,
-      mr = Traits::mr,
-      nr = Traits::nr
-    };
-    // Increasing k gives us more time to prefetch the content of the "C"
-    // registers. However once the latency is hidden there is no point in
-    // increasing the value of k, so we'll cap it at 320 (value determined
-    // experimentally).
-    const Index k_cache = (numext::mini<Index>)((l1-ksub)/kdiv, 320);
-    if (k_cache < k) {
-      k = k_cache - (k_cache % kr);
-      eigen_internal_assert(k > 0);
-    }
-
-    const Index n_cache = (l2-l1) / (nr * sizeof(RhsScalar) * k);
-    const Index n_per_thread = numext::div_ceil(n, num_threads);
-    if (n_cache <= n_per_thread) {
-      // Don't exceed the capacity of the l2 cache.
-      eigen_internal_assert(n_cache >= static_cast<Index>(nr));
-      n = n_cache - (n_cache % nr);
-      eigen_internal_assert(n > 0);
-    } else {
-      n = (numext::mini<Index>)(n, (n_per_thread + nr - 1) - ((n_per_thread + nr - 1) % nr));
-    }
-
-    if (l3 > l2) {
-      // l3 is shared between all cores, so we'll give each thread its own chunk of l3.
-      const Index m_cache = (l3-l2) / (sizeof(LhsScalar) * k * num_threads);
-      const Index m_per_thread = numext::div_ceil(m, num_threads);
-      if(m_cache < m_per_thread && m_cache >= static_cast<Index>(mr)) {
-        m = m_cache - (m_cache % mr);
-        eigen_internal_assert(m > 0);
-      } else {
-        m = (numext::mini<Index>)(m, (m_per_thread + mr - 1) - ((m_per_thread + mr - 1) % mr));
-      }
-    }
-  }
-  else {
-    // In unit tests we do not want to use extra large matrices,
-    // so we reduce the cache size to check the blocking strategy is not flawed
-#ifdef EIGEN_DEBUG_SMALL_PRODUCT_BLOCKS
-    l1 = 9*1024;
-    l2 = 32*1024;
-    l3 = 512*1024;
-#endif
-
-    // Early return for small problems because the computation below are time consuming for small problems.
-    // Perhaps it would make more sense to consider k*n*m??
-    // Note that for very tiny problem, this function should be bypassed anyway
-    // because we use the coefficient-based implementation for them.
-    if((numext::maxi)(k,(numext::maxi)(m,n))<48)
-      return;
-
-    typedef typename Traits::ResScalar ResScalar;
-    enum {
-      k_peeling = 8,
-      k_div = KcFactor * (Traits::mr * sizeof(LhsScalar) + Traits::nr * sizeof(RhsScalar)),
-      k_sub = Traits::mr * Traits::nr * sizeof(ResScalar)
-    };
-
-    // ---- 1st level of blocking on L1, yields kc ----
-
-    // Blocking on the third dimension (i.e., k) is chosen so that an horizontal panel
-    // of size mr x kc of the lhs plus a vertical panel of kc x nr of the rhs both fits within L1 cache.
-    // We also include a register-level block of the result (mx x nr).
-    // (In an ideal world only the lhs panel would stay in L1)
-    // Moreover, kc has to be a multiple of 8 to be compatible with loop peeling, leading to a maximum blocking size of:
-    const Index max_kc = numext::maxi<Index>(((l1-k_sub)/k_div) & (~(k_peeling-1)),1);
-    const Index old_k = k;
-    if(k>max_kc)
-    {
-      // We are really blocking on the third dimension:
-      // -> reduce blocking size to make sure the last block is as large as possible
-      //    while keeping the same number of sweeps over the result.
-      k = (k%max_kc)==0 ? max_kc
-                        : max_kc - k_peeling * ((max_kc-1-(k%max_kc))/(k_peeling*(k/max_kc+1)));
-
-      eigen_internal_assert(((old_k/k) == (old_k/max_kc)) && "the number of sweeps has to remain the same");
-    }
-
-    // ---- 2nd level of blocking on max(L2,L3), yields nc ----
-
-    // TODO find a reliable way to get the actual amount of cache per core to use for 2nd level blocking, that is:
-    //      actual_l2 = max(l2, l3/nb_core_sharing_l3)
-    // The number below is quite conservative: it is better to underestimate the cache size rather than overestimating it)
-    // For instance, it corresponds to 6MB of L3 shared among 4 cores.
-    #ifdef EIGEN_DEBUG_SMALL_PRODUCT_BLOCKS
-    const Index actual_l2 = l3;
-    #else
-    const Index actual_l2 = 1572864; // == 1.5 MB
-    #endif
-
-    // Here, nc is chosen such that a block of kc x nc of the rhs fit within half of L2.
-    // The second half is implicitly reserved to access the result and lhs coefficients.
-    // When k<max_kc, then nc can arbitrarily growth. In practice, it seems to be fruitful
-    // to limit this growth: we bound nc to growth by a factor x1.5.
-    // However, if the entire lhs block fit within L1, then we are not going to block on the rows at all,
-    // and it becomes fruitful to keep the packed rhs blocks in L1 if there is enough remaining space.
-    Index max_nc;
-    const Index lhs_bytes = m * k * sizeof(LhsScalar);
-    const Index remaining_l1 = l1- k_sub - lhs_bytes;
-    if(remaining_l1 >= Index(Traits::nr*sizeof(RhsScalar))*k)
-    {
-      // L1 blocking
-      max_nc = remaining_l1 / (k*sizeof(RhsScalar));
-    }
-    else
-    {
-      // L2 blocking
-      max_nc = (3*actual_l2)/(2*2*max_kc*sizeof(RhsScalar));
-    }
-    // WARNING Below, we assume that Traits::nr is a power of two.
-    Index nc = numext::mini<Index>(actual_l2/(2*k*sizeof(RhsScalar)), max_nc) & (~(Traits::nr-1));
-    if(n>nc)
-    {
-      // We are really blocking over the columns:
-      // -> reduce blocking size to make sure the last block is as large as possible
-      //    while keeping the same number of sweeps over the packed lhs.
-      //    Here we allow one more sweep if this gives us a perfect match, thus the commented "-1"
-      n = (n%nc)==0 ? nc
-                    : (nc - Traits::nr * ((nc/*-1*/-(n%nc))/(Traits::nr*(n/nc+1))));
-    }
-    else if(old_k==k)
-    {
-      // So far, no blocking at all, i.e., kc==k, and nc==n.
-      // In this case, let's perform a blocking over the rows such that the packed lhs data is kept in cache L1/L2
-      // TODO: part of this blocking strategy is now implemented within the kernel itself, so the L1-based heuristic here should be obsolete.
-      Index problem_size = k*n*sizeof(LhsScalar);
-      Index actual_lm = actual_l2;
-      Index max_mc = m;
-      if(problem_size<=1024)
-      {
-        // problem is small enough to keep in L1
-        // Let's choose m such that lhs's block fit in 1/3 of L1
-        actual_lm = l1;
-      }
-      else if(l3!=0 && problem_size<=32768)
-      {
-        // we have both L2 and L3, and problem is small enough to be kept in L2
-        // Let's choose m such that lhs's block fit in 1/3 of L2
-        actual_lm = l2;
-        max_mc = (numext::mini<Index>)(576,max_mc);
-      }
-      Index mc = (numext::mini<Index>)(actual_lm/(3*k*sizeof(LhsScalar)), max_mc);
-      if (mc > Traits::mr) mc -= mc % Traits::mr;
-      else if (mc==0) return;
-      m = (m%mc)==0 ? mc
-                    : (mc - Traits::mr * ((mc/*-1*/-(m%mc))/(Traits::mr*(m/mc+1))));
-    }
-  }
-}
-
-template <typename Index>
-inline bool useSpecificBlockingSizes(Index& k, Index& m, Index& n)
-{
-#ifdef EIGEN_TEST_SPECIFIC_BLOCKING_SIZES
-  if (EIGEN_TEST_SPECIFIC_BLOCKING_SIZES) {
-    k = numext::mini<Index>(k, EIGEN_TEST_SPECIFIC_BLOCKING_SIZE_K);
-    m = numext::mini<Index>(m, EIGEN_TEST_SPECIFIC_BLOCKING_SIZE_M);
-    n = numext::mini<Index>(n, EIGEN_TEST_SPECIFIC_BLOCKING_SIZE_N);
-    return true;
-  }
-#else
-  EIGEN_UNUSED_VARIABLE(k)
-  EIGEN_UNUSED_VARIABLE(m)
-  EIGEN_UNUSED_VARIABLE(n)
-#endif
-  return false;
-}
-
-/** \brief Computes the blocking parameters for a m x k times k x n matrix product
-  *
-  * \param[in,out] k Input: the third dimension of the product. Output: the blocking size along the same dimension.
-  * \param[in,out] m Input: the number of rows of the left hand side. Output: the blocking size along the same dimension.
-  * \param[in,out] n Input: the number of columns of the right hand side. Output: the blocking size along the same dimension.
-  *
-  * Given a m x k times k x n matrix product of scalar types \c LhsScalar and \c RhsScalar,
-  * this function computes the blocking size parameters along the respective dimensions
-  * for matrix products and related algorithms.
-  *
-  * The blocking size parameters may be evaluated:
-  *   - either by a heuristic based on cache sizes;
-  *   - or using fixed prescribed values (for testing purposes).
-  *
-  * \sa setCpuCacheSizes */
-
-template<typename LhsScalar, typename RhsScalar, int KcFactor, typename Index>
-void computeProductBlockingSizes(Index& k, Index& m, Index& n, Index num_threads = 1)
-{
-  if (!useSpecificBlockingSizes(k, m, n)) {
-    evaluateProductBlockingSizesHeuristic<LhsScalar, RhsScalar, KcFactor, Index>(k, m, n, num_threads);
-  }
-}
-
-template<typename LhsScalar, typename RhsScalar, typename Index>
-inline void computeProductBlockingSizes(Index& k, Index& m, Index& n, Index num_threads = 1)
-{
-  computeProductBlockingSizes<LhsScalar,RhsScalar,1,Index>(k, m, n, num_threads);
-}
-
-#ifdef EIGEN_HAS_SINGLE_INSTRUCTION_CJMADD
-  #define CJMADD(CJ,A,B,C,T)  C = CJ.pmadd(A,B,C);
-#else
-
-  // FIXME (a bit overkill maybe ?)
-
-  template<typename CJ, typename A, typename B, typename C, typename T> struct gebp_madd_selector {
-    EIGEN_ALWAYS_INLINE static void run(const CJ& cj, A& a, B& b, C& c, T& /*t*/)
-    {
-      c = cj.pmadd(a,b,c);
-    }
-  };
-
-  template<typename CJ, typename T> struct gebp_madd_selector<CJ,T,T,T,T> {
-    EIGEN_ALWAYS_INLINE static void run(const CJ& cj, T& a, T& b, T& c, T& t)
-    {
-      t = b; t = cj.pmul(a,t); c = padd(c,t);
-    }
-  };
-
-  template<typename CJ, typename A, typename B, typename C, typename T>
-  EIGEN_STRONG_INLINE void gebp_madd(const CJ& cj, A& a, B& b, C& c, T& t)
-  {
-    gebp_madd_selector<CJ,A,B,C,T>::run(cj,a,b,c,t);
-  }
-
-  #define CJMADD(CJ,A,B,C,T)  gebp_madd(CJ,A,B,C,T);
-//   #define CJMADD(CJ,A,B,C,T)  T = B; T = CJ.pmul(A,T); C = padd(C,T);
-#endif
-
-/* Vectorization logic
- *  real*real: unpack rhs to constant packets, ...
- * 
- *  cd*cd : unpack rhs to (b_r,b_r), (b_i,b_i), mul to get (a_r b_r,a_i b_r) (a_r b_i,a_i b_i),
- *          storing each res packet into two packets (2x2),
- *          at the end combine them: swap the second and addsub them 
- *  cf*cf : same but with 2x4 blocks
- *  cplx*real : unpack rhs to constant packets, ...
- *  real*cplx : load lhs as (a0,a0,a1,a1), and mul as usual
- */
-template<typename _LhsScalar, typename _RhsScalar, bool _ConjLhs, bool _ConjRhs>
-class gebp_traits
-{
-public:
-  typedef _LhsScalar LhsScalar;
-  typedef _RhsScalar RhsScalar;
-  typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar>::ReturnType ResScalar;
-
-  enum {
-    ConjLhs = _ConjLhs,
-    ConjRhs = _ConjRhs,
-    Vectorizable = packet_traits<LhsScalar>::Vectorizable && packet_traits<RhsScalar>::Vectorizable,
-    LhsPacketSize = Vectorizable ? packet_traits<LhsScalar>::size : 1,
-    RhsPacketSize = Vectorizable ? packet_traits<RhsScalar>::size : 1,
-    ResPacketSize = Vectorizable ? packet_traits<ResScalar>::size : 1,
-    
-    NumberOfRegisters = EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS,
-
-    // register block size along the N direction must be 1 or 4
-    nr = 4,
-
-    // register block size along the M direction (currently, this one cannot be modified)
-    default_mr = (EIGEN_PLAIN_ENUM_MIN(16,NumberOfRegisters)/2/nr)*LhsPacketSize,
-#if defined(EIGEN_HAS_SINGLE_INSTRUCTION_MADD) && !defined(EIGEN_VECTORIZE_ALTIVEC) && !defined(EIGEN_VECTORIZE_VSX)
-    // we assume 16 registers
-    // See bug 992, if the scalar type is not vectorizable but that EIGEN_HAS_SINGLE_INSTRUCTION_MADD is defined,
-    // then using 3*LhsPacketSize triggers non-implemented paths in syrk.
-    mr = Vectorizable ? 3*LhsPacketSize : default_mr,
-#else
-    mr = default_mr,
-#endif
-    
-    LhsProgress = LhsPacketSize,
-    RhsProgress = 1
-  };
-
-  typedef typename packet_traits<LhsScalar>::type  _LhsPacket;
-  typedef typename packet_traits<RhsScalar>::type  _RhsPacket;
-  typedef typename packet_traits<ResScalar>::type  _ResPacket;
-
-  typedef typename conditional<Vectorizable,_LhsPacket,LhsScalar>::type LhsPacket;
-  typedef typename conditional<Vectorizable,_RhsPacket,RhsScalar>::type RhsPacket;
-  typedef typename conditional<Vectorizable,_ResPacket,ResScalar>::type ResPacket;
-
-  typedef ResPacket AccPacket;
-  
-  EIGEN_STRONG_INLINE void initAcc(AccPacket& p)
-  {
-    p = pset1<ResPacket>(ResScalar(0));
-  }
-  
-  EIGEN_STRONG_INLINE void broadcastRhs(const RhsScalar* b, RhsPacket& b0, RhsPacket& b1, RhsPacket& b2, RhsPacket& b3)
-  {
-    pbroadcast4(b, b0, b1, b2, b3);
-  }
-  
-//   EIGEN_STRONG_INLINE void broadcastRhs(const RhsScalar* b, RhsPacket& b0, RhsPacket& b1)
-//   {
-//     pbroadcast2(b, b0, b1);
-//   }
-  
-  template<typename RhsPacketType>
-  EIGEN_STRONG_INLINE void loadRhs(const RhsScalar* b, RhsPacketType& dest) const
-  {
-    dest = pset1<RhsPacketType>(*b);
-  }
-  
-  EIGEN_STRONG_INLINE void loadRhsQuad(const RhsScalar* b, RhsPacket& dest) const
-  {
-    dest = ploadquad<RhsPacket>(b);
-  }
-
-  template<typename LhsPacketType>
-  EIGEN_STRONG_INLINE void loadLhs(const LhsScalar* a, LhsPacketType& dest) const
-  {
-    dest = pload<LhsPacketType>(a);
-  }
-
-  template<typename LhsPacketType>
-  EIGEN_STRONG_INLINE void loadLhsUnaligned(const LhsScalar* a, LhsPacketType& dest) const
-  {
-    dest = ploadu<LhsPacketType>(a);
-  }
-
-  template<typename LhsPacketType, typename RhsPacketType, typename AccPacketType>
-  EIGEN_STRONG_INLINE void madd(const LhsPacketType& a, const RhsPacketType& b, AccPacketType& c, AccPacketType& tmp) const
-  {
-    conj_helper<LhsPacketType,RhsPacketType,ConjLhs,ConjRhs> cj;
-    // It would be a lot cleaner to call pmadd all the time. Unfortunately if we
-    // let gcc allocate the register in which to store the result of the pmul
-    // (in the case where there is no FMA) gcc fails to figure out how to avoid
-    // spilling register.
-#ifdef EIGEN_HAS_SINGLE_INSTRUCTION_MADD
-    EIGEN_UNUSED_VARIABLE(tmp);
-    c = cj.pmadd(a,b,c);
-#else
-    tmp = b; tmp = cj.pmul(a,tmp); c = padd(c,tmp);
-#endif
-  }
-
-  EIGEN_STRONG_INLINE void acc(const AccPacket& c, const ResPacket& alpha, ResPacket& r) const
-  {
-    r = pmadd(c,alpha,r);
-  }
-  
-  template<typename ResPacketHalf>
-  EIGEN_STRONG_INLINE void acc(const ResPacketHalf& c, const ResPacketHalf& alpha, ResPacketHalf& r) const
-  {
-    r = pmadd(c,alpha,r);
-  }
-
-};
-
-template<typename RealScalar, bool _ConjLhs>
-class gebp_traits<std::complex<RealScalar>, RealScalar, _ConjLhs, false>
-{
-public:
-  typedef std::complex<RealScalar> LhsScalar;
-  typedef RealScalar RhsScalar;
-  typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar>::ReturnType ResScalar;
-
-  enum {
-    ConjLhs = _ConjLhs,
-    ConjRhs = false,
-    Vectorizable = packet_traits<LhsScalar>::Vectorizable && packet_traits<RhsScalar>::Vectorizable,
-    LhsPacketSize = Vectorizable ? packet_traits<LhsScalar>::size : 1,
-    RhsPacketSize = Vectorizable ? packet_traits<RhsScalar>::size : 1,
-    ResPacketSize = Vectorizable ? packet_traits<ResScalar>::size : 1,
-    
-    NumberOfRegisters = EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS,
-    nr = 4,
-#if defined(EIGEN_HAS_SINGLE_INSTRUCTION_MADD) && !defined(EIGEN_VECTORIZE_ALTIVEC) && !defined(EIGEN_VECTORIZE_VSX)
-    // we assume 16 registers
-    mr = 3*LhsPacketSize,
-#else
-    mr = (EIGEN_PLAIN_ENUM_MIN(16,NumberOfRegisters)/2/nr)*LhsPacketSize,
-#endif
-
-    LhsProgress = LhsPacketSize,
-    RhsProgress = 1
-  };
-
-  typedef typename packet_traits<LhsScalar>::type  _LhsPacket;
-  typedef typename packet_traits<RhsScalar>::type  _RhsPacket;
-  typedef typename packet_traits<ResScalar>::type  _ResPacket;
-
-  typedef typename conditional<Vectorizable,_LhsPacket,LhsScalar>::type LhsPacket;
-  typedef typename conditional<Vectorizable,_RhsPacket,RhsScalar>::type RhsPacket;
-  typedef typename conditional<Vectorizable,_ResPacket,ResScalar>::type ResPacket;
-
-  typedef ResPacket AccPacket;
-
-  EIGEN_STRONG_INLINE void initAcc(AccPacket& p)
-  {
-    p = pset1<ResPacket>(ResScalar(0));
-  }
-
-  EIGEN_STRONG_INLINE void loadRhs(const RhsScalar* b, RhsPacket& dest) const
-  {
-    dest = pset1<RhsPacket>(*b);
-  }
-  
-  EIGEN_STRONG_INLINE void loadRhsQuad(const RhsScalar* b, RhsPacket& dest) const
-  {
-    dest = pset1<RhsPacket>(*b);
-  }
-
-  EIGEN_STRONG_INLINE void loadLhs(const LhsScalar* a, LhsPacket& dest) const
-  {
-    dest = pload<LhsPacket>(a);
-  }
-
-  EIGEN_STRONG_INLINE void loadLhsUnaligned(const LhsScalar* a, LhsPacket& dest) const
-  {
-    dest = ploadu<LhsPacket>(a);
-  }
-
-  EIGEN_STRONG_INLINE void broadcastRhs(const RhsScalar* b, RhsPacket& b0, RhsPacket& b1, RhsPacket& b2, RhsPacket& b3)
-  {
-    pbroadcast4(b, b0, b1, b2, b3);
-  }
-  
-//   EIGEN_STRONG_INLINE void broadcastRhs(const RhsScalar* b, RhsPacket& b0, RhsPacket& b1)
-//   {
-//     pbroadcast2(b, b0, b1);
-//   }
-
-  EIGEN_STRONG_INLINE void madd(const LhsPacket& a, const RhsPacket& b, AccPacket& c, RhsPacket& tmp) const
-  {
-    madd_impl(a, b, c, tmp, typename conditional<Vectorizable,true_type,false_type>::type());
-  }
-
-  EIGEN_STRONG_INLINE void madd_impl(const LhsPacket& a, const RhsPacket& b, AccPacket& c, RhsPacket& tmp, const true_type&) const
-  {
-#ifdef EIGEN_HAS_SINGLE_INSTRUCTION_MADD
-    EIGEN_UNUSED_VARIABLE(tmp);
-    c.v = pmadd(a.v,b,c.v);
-#else
-    tmp = b; tmp = pmul(a.v,tmp); c.v = padd(c.v,tmp);
-#endif
-  }
-
-  EIGEN_STRONG_INLINE void madd_impl(const LhsScalar& a, const RhsScalar& b, ResScalar& c, RhsScalar& /*tmp*/, const false_type&) const
-  {
-    c += a * b;
-  }
-
-  EIGEN_STRONG_INLINE void acc(const AccPacket& c, const ResPacket& alpha, ResPacket& r) const
-  {
-    r = cj.pmadd(c,alpha,r);
-  }
-
-protected:
-  conj_helper<ResPacket,ResPacket,ConjLhs,false> cj;
-};
-
-template<typename Packet>
-struct DoublePacket
-{
-  Packet first;
-  Packet second;
-};
-
-template<typename Packet>
-DoublePacket<Packet> padd(const DoublePacket<Packet> &a, const DoublePacket<Packet> &b)
-{
-  DoublePacket<Packet> res;
-  res.first  = padd(a.first, b.first);
-  res.second = padd(a.second,b.second);
-  return res;
-}
-
-template<typename Packet>
-const DoublePacket<Packet>& predux_downto4(const DoublePacket<Packet> &a)
-{
-  return a;
-}
-
-template<typename Packet> struct unpacket_traits<DoublePacket<Packet> > { typedef DoublePacket<Packet> half; };
-// template<typename Packet>
-// DoublePacket<Packet> pmadd(const DoublePacket<Packet> &a, const DoublePacket<Packet> &b)
-// {
-//   DoublePacket<Packet> res;
-//   res.first  = padd(a.first, b.first);
-//   res.second = padd(a.second,b.second);
-//   return res;
-// }
-
-template<typename RealScalar, bool _ConjLhs, bool _ConjRhs>
-class gebp_traits<std::complex<RealScalar>, std::complex<RealScalar>, _ConjLhs, _ConjRhs >
-{
-public:
-  typedef std::complex<RealScalar>  Scalar;
-  typedef std::complex<RealScalar>  LhsScalar;
-  typedef std::complex<RealScalar>  RhsScalar;
-  typedef std::complex<RealScalar>  ResScalar;
-  
-  enum {
-    ConjLhs = _ConjLhs,
-    ConjRhs = _ConjRhs,
-    Vectorizable = packet_traits<RealScalar>::Vectorizable
-                && packet_traits<Scalar>::Vectorizable,
-    RealPacketSize  = Vectorizable ? packet_traits<RealScalar>::size : 1,
-    ResPacketSize   = Vectorizable ? packet_traits<ResScalar>::size : 1,
-    LhsPacketSize = Vectorizable ? packet_traits<LhsScalar>::size : 1,
-    RhsPacketSize = Vectorizable ? packet_traits<RhsScalar>::size : 1,
-
-    // FIXME: should depend on NumberOfRegisters
-    nr = 4,
-    mr = ResPacketSize,
-
-    LhsProgress = ResPacketSize,
-    RhsProgress = 1
-  };
-  
-  typedef typename packet_traits<RealScalar>::type RealPacket;
-  typedef typename packet_traits<Scalar>::type     ScalarPacket;
-  typedef DoublePacket<RealPacket> DoublePacketType;
-
-  typedef typename conditional<Vectorizable,RealPacket,  Scalar>::type LhsPacket;
-  typedef typename conditional<Vectorizable,DoublePacketType,Scalar>::type RhsPacket;
-  typedef typename conditional<Vectorizable,ScalarPacket,Scalar>::type ResPacket;
-  typedef typename conditional<Vectorizable,DoublePacketType,Scalar>::type AccPacket;
-  
-  EIGEN_STRONG_INLINE void initAcc(Scalar& p) { p = Scalar(0); }
-
-  EIGEN_STRONG_INLINE void initAcc(DoublePacketType& p)
-  {
-    p.first   = pset1<RealPacket>(RealScalar(0));
-    p.second  = pset1<RealPacket>(RealScalar(0));
-  }
-
-  // Scalar path
-  EIGEN_STRONG_INLINE void loadRhs(const RhsScalar* b, ResPacket& dest) const
-  {
-    dest = pset1<ResPacket>(*b);
-  }
-
-  // Vectorized path
-  EIGEN_STRONG_INLINE void loadRhs(const RhsScalar* b, DoublePacketType& dest) const
-  {
-    dest.first  = pset1<RealPacket>(real(*b));
-    dest.second = pset1<RealPacket>(imag(*b));
-  }
-  
-  EIGEN_STRONG_INLINE void loadRhsQuad(const RhsScalar* b, ResPacket& dest) const
-  {
-    loadRhs(b,dest);
-  }
-  EIGEN_STRONG_INLINE void loadRhsQuad(const RhsScalar* b, DoublePacketType& dest) const
-  {
-    eigen_internal_assert(unpacket_traits<ScalarPacket>::size<=4);
-    loadRhs(b,dest);
-  }
-  
-  EIGEN_STRONG_INLINE void broadcastRhs(const RhsScalar* b, RhsPacket& b0, RhsPacket& b1, RhsPacket& b2, RhsPacket& b3)
-  {
-    // FIXME not sure that's the best way to implement it!
-    loadRhs(b+0, b0);
-    loadRhs(b+1, b1);
-    loadRhs(b+2, b2);
-    loadRhs(b+3, b3);
-  }
-  
-  // Vectorized path
-  EIGEN_STRONG_INLINE void broadcastRhs(const RhsScalar* b, DoublePacketType& b0, DoublePacketType& b1)
-  {
-    // FIXME not sure that's the best way to implement it!
-    loadRhs(b+0, b0);
-    loadRhs(b+1, b1);
-  }
-  
-  // Scalar path
-  EIGEN_STRONG_INLINE void broadcastRhs(const RhsScalar* b, RhsScalar& b0, RhsScalar& b1)
-  {
-    // FIXME not sure that's the best way to implement it!
-    loadRhs(b+0, b0);
-    loadRhs(b+1, b1);
-  }
-
-  // nothing special here
-  EIGEN_STRONG_INLINE void loadLhs(const LhsScalar* a, LhsPacket& dest) const
-  {
-    dest = pload<LhsPacket>((const typename unpacket_traits<LhsPacket>::type*)(a));
-  }
-
-  EIGEN_STRONG_INLINE void loadLhsUnaligned(const LhsScalar* a, LhsPacket& dest) const
-  {
-    dest = ploadu<LhsPacket>((const typename unpacket_traits<LhsPacket>::type*)(a));
-  }
-
-  EIGEN_STRONG_INLINE void madd(const LhsPacket& a, const RhsPacket& b, DoublePacketType& c, RhsPacket& /*tmp*/) const
-  {
-    c.first   = padd(pmul(a,b.first), c.first);
-    c.second  = padd(pmul(a,b.second),c.second);
-  }
-
-  EIGEN_STRONG_INLINE void madd(const LhsPacket& a, const RhsPacket& b, ResPacket& c, RhsPacket& /*tmp*/) const
-  {
-    c = cj.pmadd(a,b,c);
-  }
-  
-  EIGEN_STRONG_INLINE void acc(const Scalar& c, const Scalar& alpha, Scalar& r) const { r += alpha * c; }
-  
-  EIGEN_STRONG_INLINE void acc(const DoublePacketType& c, const ResPacket& alpha, ResPacket& r) const
-  {
-    // assemble c
-    ResPacket tmp;
-    if((!ConjLhs)&&(!ConjRhs))
-    {
-      tmp = pcplxflip(pconj(ResPacket(c.second)));
-      tmp = padd(ResPacket(c.first),tmp);
-    }
-    else if((!ConjLhs)&&(ConjRhs))
-    {
-      tmp = pconj(pcplxflip(ResPacket(c.second)));
-      tmp = padd(ResPacket(c.first),tmp);
-    }
-    else if((ConjLhs)&&(!ConjRhs))
-    {
-      tmp = pcplxflip(ResPacket(c.second));
-      tmp = padd(pconj(ResPacket(c.first)),tmp);
-    }
-    else if((ConjLhs)&&(ConjRhs))
-    {
-      tmp = pcplxflip(ResPacket(c.second));
-      tmp = psub(pconj(ResPacket(c.first)),tmp);
-    }
-    
-    r = pmadd(tmp,alpha,r);
-  }
-
-protected:
-  conj_helper<LhsScalar,RhsScalar,ConjLhs,ConjRhs> cj;
-};
-
-template<typename RealScalar, bool _ConjRhs>
-class gebp_traits<RealScalar, std::complex<RealScalar>, false, _ConjRhs >
-{
-public:
-  typedef std::complex<RealScalar>  Scalar;
-  typedef RealScalar  LhsScalar;
-  typedef Scalar      RhsScalar;
-  typedef Scalar      ResScalar;
-
-  enum {
-    ConjLhs = false,
-    ConjRhs = _ConjRhs,
-    Vectorizable = packet_traits<RealScalar>::Vectorizable
-                && packet_traits<Scalar>::Vectorizable,
-    LhsPacketSize = Vectorizable ? packet_traits<LhsScalar>::size : 1,
-    RhsPacketSize = Vectorizable ? packet_traits<RhsScalar>::size : 1,
-    ResPacketSize = Vectorizable ? packet_traits<ResScalar>::size : 1,
-    
-    NumberOfRegisters = EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS,
-    // FIXME: should depend on NumberOfRegisters
-    nr = 4,
-    mr = (EIGEN_PLAIN_ENUM_MIN(16,NumberOfRegisters)/2/nr)*ResPacketSize,
-
-    LhsProgress = ResPacketSize,
-    RhsProgress = 1
-  };
-
-  typedef typename packet_traits<LhsScalar>::type  _LhsPacket;
-  typedef typename packet_traits<RhsScalar>::type  _RhsPacket;
-  typedef typename packet_traits<ResScalar>::type  _ResPacket;
-
-  typedef typename conditional<Vectorizable,_LhsPacket,LhsScalar>::type LhsPacket;
-  typedef typename conditional<Vectorizable,_RhsPacket,RhsScalar>::type RhsPacket;
-  typedef typename conditional<Vectorizable,_ResPacket,ResScalar>::type ResPacket;
-
-  typedef ResPacket AccPacket;
-
-  EIGEN_STRONG_INLINE void initAcc(AccPacket& p)
-  {
-    p = pset1<ResPacket>(ResScalar(0));
-  }
-
-  EIGEN_STRONG_INLINE void loadRhs(const RhsScalar* b, RhsPacket& dest) const
-  {
-    dest = pset1<RhsPacket>(*b);
-  }
-  
-  void broadcastRhs(const RhsScalar* b, RhsPacket& b0, RhsPacket& b1, RhsPacket& b2, RhsPacket& b3)
-  {
-    pbroadcast4(b, b0, b1, b2, b3);
-  }
-  
-//   EIGEN_STRONG_INLINE void broadcastRhs(const RhsScalar* b, RhsPacket& b0, RhsPacket& b1)
-//   {
-//     // FIXME not sure that's the best way to implement it!
-//     b0 = pload1<RhsPacket>(b+0);
-//     b1 = pload1<RhsPacket>(b+1);
-//   }
-
-  EIGEN_STRONG_INLINE void loadLhs(const LhsScalar* a, LhsPacket& dest) const
-  {
-    dest = ploaddup<LhsPacket>(a);
-  }
-  
-  EIGEN_STRONG_INLINE void loadRhsQuad(const RhsScalar* b, RhsPacket& dest) const
-  {
-    eigen_internal_assert(unpacket_traits<RhsPacket>::size<=4);
-    loadRhs(b,dest);
-  }
-
-  EIGEN_STRONG_INLINE void loadLhsUnaligned(const LhsScalar* a, LhsPacket& dest) const
-  {
-    dest = ploaddup<LhsPacket>(a);
-  }
-
-  EIGEN_STRONG_INLINE void madd(const LhsPacket& a, const RhsPacket& b, AccPacket& c, RhsPacket& tmp) const
-  {
-    madd_impl(a, b, c, tmp, typename conditional<Vectorizable,true_type,false_type>::type());
-  }
-
-  EIGEN_STRONG_INLINE void madd_impl(const LhsPacket& a, const RhsPacket& b, AccPacket& c, RhsPacket& tmp, const true_type&) const
-  {
-#ifdef EIGEN_HAS_SINGLE_INSTRUCTION_MADD
-    EIGEN_UNUSED_VARIABLE(tmp);
-    c.v = pmadd(a,b.v,c.v);
-#else
-    tmp = b; tmp.v = pmul(a,tmp.v); c = padd(c,tmp);
-#endif
-    
-  }
-
-  EIGEN_STRONG_INLINE void madd_impl(const LhsScalar& a, const RhsScalar& b, ResScalar& c, RhsScalar& /*tmp*/, const false_type&) const
-  {
-    c += a * b;
-  }
-
-  EIGEN_STRONG_INLINE void acc(const AccPacket& c, const ResPacket& alpha, ResPacket& r) const
-  {
-    r = cj.pmadd(alpha,c,r);
-  }
-
-protected:
-  conj_helper<ResPacket,ResPacket,false,ConjRhs> cj;
-};
-
-/* optimized GEneral packed Block * packed Panel product kernel
- *
- * Mixing type logic: C += A * B
- *  |  A  |  B  | comments
- *  |real |cplx | no vectorization yet, would require to pack A with duplication
- *  |cplx |real | easy vectorization
- */
-template<typename LhsScalar, typename RhsScalar, typename Index, typename DataMapper, int mr, int nr, bool ConjugateLhs, bool ConjugateRhs>
-struct gebp_kernel
-{
-  typedef gebp_traits<LhsScalar,RhsScalar,ConjugateLhs,ConjugateRhs> Traits;
-  typedef typename Traits::ResScalar ResScalar;
-  typedef typename Traits::LhsPacket LhsPacket;
-  typedef typename Traits::RhsPacket RhsPacket;
-  typedef typename Traits::ResPacket ResPacket;
-  typedef typename Traits::AccPacket AccPacket;
-
-  typedef gebp_traits<RhsScalar,LhsScalar,ConjugateRhs,ConjugateLhs> SwappedTraits;
-  typedef typename SwappedTraits::ResScalar SResScalar;
-  typedef typename SwappedTraits::LhsPacket SLhsPacket;
-  typedef typename SwappedTraits::RhsPacket SRhsPacket;
-  typedef typename SwappedTraits::ResPacket SResPacket;
-  typedef typename SwappedTraits::AccPacket SAccPacket;
-
-  typedef typename DataMapper::LinearMapper LinearMapper;
-
-  enum {
-    Vectorizable  = Traits::Vectorizable,
-    LhsProgress   = Traits::LhsProgress,
-    RhsProgress   = Traits::RhsProgress,
-    ResPacketSize = Traits::ResPacketSize
-  };
-
-  EIGEN_DONT_INLINE
-  void operator()(const DataMapper& res, const LhsScalar* blockA, const RhsScalar* blockB,
-                  Index rows, Index depth, Index cols, ResScalar alpha,
-                  Index strideA=-1, Index strideB=-1, Index offsetA=0, Index offsetB=0);
-};
-
-template<typename LhsScalar, typename RhsScalar, typename Index, typename DataMapper, int mr, int nr, bool ConjugateLhs, bool ConjugateRhs>
-EIGEN_DONT_INLINE
-void gebp_kernel<LhsScalar,RhsScalar,Index,DataMapper,mr,nr,ConjugateLhs,ConjugateRhs>
-  ::operator()(const DataMapper& res, const LhsScalar* blockA, const RhsScalar* blockB,
-               Index rows, Index depth, Index cols, ResScalar alpha,
-               Index strideA, Index strideB, Index offsetA, Index offsetB)
-  {
-    Traits traits;
-    SwappedTraits straits;
-    
-    if(strideA==-1) strideA = depth;
-    if(strideB==-1) strideB = depth;
-    conj_helper<LhsScalar,RhsScalar,ConjugateLhs,ConjugateRhs> cj;
-    Index packet_cols4 = nr>=4 ? (cols/4) * 4 : 0;
-    const Index peeled_mc3 = mr>=3*Traits::LhsProgress ? (rows/(3*LhsProgress))*(3*LhsProgress) : 0;
-    const Index peeled_mc2 = mr>=2*Traits::LhsProgress ? peeled_mc3+((rows-peeled_mc3)/(2*LhsProgress))*(2*LhsProgress) : 0;
-    const Index peeled_mc1 = mr>=1*Traits::LhsProgress ? (rows/(1*LhsProgress))*(1*LhsProgress) : 0;
-    enum { pk = 8 }; // NOTE Such a large peeling factor is important for large matrices (~ +5% when >1000 on Haswell)
-    const Index peeled_kc  = depth & ~(pk-1);
-    const Index prefetch_res_offset = 32/sizeof(ResScalar);    
-//     const Index depth2     = depth & ~1;
-
-    //---------- Process 3 * LhsProgress rows at once ----------
-    // This corresponds to 3*LhsProgress x nr register blocks.
-    // Usually, make sense only with FMA
-    if(mr>=3*Traits::LhsProgress)
-    {
-      // Here, the general idea is to loop on each largest micro horizontal panel of the lhs (3*Traits::LhsProgress x depth)
-      // and on each largest micro vertical panel of the rhs (depth * nr).
-      // Blocking sizes, i.e., 'depth' has been computed so that the micro horizontal panel of the lhs fit in L1.
-      // However, if depth is too small, we can extend the number of rows of these horizontal panels.
-      // This actual number of rows is computed as follow:
-      const Index l1 = defaultL1CacheSize; // in Bytes, TODO, l1 should be passed to this function.
-      // The max(1, ...) here is needed because we may be using blocking params larger than what our known l1 cache size
-      // suggests we should be using: either because our known l1 cache size is inaccurate (e.g. on Android, we can only guess),
-      // or because we are testing specific blocking sizes.
-      const Index actual_panel_rows = (3*LhsProgress) * std::max<Index>(1,( (l1 - sizeof(ResScalar)*mr*nr - depth*nr*sizeof(RhsScalar)) / (depth * sizeof(LhsScalar) * 3*LhsProgress) ));
-      for(Index i1=0; i1<peeled_mc3; i1+=actual_panel_rows)
-      {
-        const Index actual_panel_end = (std::min)(i1+actual_panel_rows, peeled_mc3);
-        for(Index j2=0; j2<packet_cols4; j2+=nr)
-        {
-          for(Index i=i1; i<actual_panel_end; i+=3*LhsProgress)
-          {
-          
-          // We selected a 3*Traits::LhsProgress x nr micro block of res which is entirely
-          // stored into 3 x nr registers.
-          
-          const LhsScalar* blA = &blockA[i*strideA+offsetA*(3*LhsProgress)];
-          prefetch(&blA[0]);
-
-          // gets res block as register
-          AccPacket C0, C1, C2,  C3,
-                    C4, C5, C6,  C7,
-                    C8, C9, C10, C11;
-          traits.initAcc(C0);  traits.initAcc(C1);  traits.initAcc(C2);  traits.initAcc(C3);
-          traits.initAcc(C4);  traits.initAcc(C5);  traits.initAcc(C6);  traits.initAcc(C7);
-          traits.initAcc(C8);  traits.initAcc(C9);  traits.initAcc(C10); traits.initAcc(C11);
-
-          LinearMapper r0 = res.getLinearMapper(i, j2 + 0);
-          LinearMapper r1 = res.getLinearMapper(i, j2 + 1);
-          LinearMapper r2 = res.getLinearMapper(i, j2 + 2);
-          LinearMapper r3 = res.getLinearMapper(i, j2 + 3);
-
-          r0.prefetch(0);
-          r1.prefetch(0);
-          r2.prefetch(0);
-          r3.prefetch(0);
-
-          // performs "inner" products
-          const RhsScalar* blB = &blockB[j2*strideB+offsetB*nr];
-          prefetch(&blB[0]);
-          LhsPacket A0, A1;
-
-          for(Index k=0; k<peeled_kc; k+=pk)
-          {
-            EIGEN_ASM_COMMENT("begin gebp micro kernel 3pX4");
-            RhsPacket B_0, T0;
-            LhsPacket A2;
-
-#define EIGEN_GEBP_ONESTEP(K) \
-            do { \
-              EIGEN_ASM_COMMENT("begin step of gebp micro kernel 3pX4"); \
-              EIGEN_ASM_COMMENT("Note: these asm comments work around bug 935!"); \
-              internal::prefetch(blA+(3*K+16)*LhsProgress); \
-              if (EIGEN_ARCH_ARM) { internal::prefetch(blB+(4*K+16)*RhsProgress); } /* Bug 953 */ \
-              traits.loadLhs(&blA[(0+3*K)*LhsProgress], A0);  \
-              traits.loadLhs(&blA[(1+3*K)*LhsProgress], A1);  \
-              traits.loadLhs(&blA[(2+3*K)*LhsProgress], A2);  \
-              traits.loadRhs(blB + (0+4*K)*Traits::RhsProgress, B_0); \
-              traits.madd(A0, B_0, C0, T0); \
-              traits.madd(A1, B_0, C4, T0); \
-              traits.madd(A2, B_0, C8, B_0); \
-              traits.loadRhs(blB + (1+4*K)*Traits::RhsProgress, B_0); \
-              traits.madd(A0, B_0, C1, T0); \
-              traits.madd(A1, B_0, C5, T0); \
-              traits.madd(A2, B_0, C9, B_0); \
-              traits.loadRhs(blB + (2+4*K)*Traits::RhsProgress, B_0); \
-              traits.madd(A0, B_0, C2,  T0); \
-              traits.madd(A1, B_0, C6,  T0); \
-              traits.madd(A2, B_0, C10, B_0); \
-              traits.loadRhs(blB + (3+4*K)*Traits::RhsProgress, B_0); \
-              traits.madd(A0, B_0, C3 , T0); \
-              traits.madd(A1, B_0, C7,  T0); \
-              traits.madd(A2, B_0, C11, B_0); \
-              EIGEN_ASM_COMMENT("end step of gebp micro kernel 3pX4"); \
-            } while(false)
-
-            internal::prefetch(blB);
-            EIGEN_GEBP_ONESTEP(0);
-            EIGEN_GEBP_ONESTEP(1);
-            EIGEN_GEBP_ONESTEP(2);
-            EIGEN_GEBP_ONESTEP(3);
-            EIGEN_GEBP_ONESTEP(4);
-            EIGEN_GEBP_ONESTEP(5);
-            EIGEN_GEBP_ONESTEP(6);
-            EIGEN_GEBP_ONESTEP(7);
-
-            blB += pk*4*RhsProgress;
-            blA += pk*3*Traits::LhsProgress;
-
-            EIGEN_ASM_COMMENT("end gebp micro kernel 3pX4");
-          }
-          // process remaining peeled loop
-          for(Index k=peeled_kc; k<depth; k++)
-          {
-            RhsPacket B_0, T0;
-            LhsPacket A2;
-            EIGEN_GEBP_ONESTEP(0);
-            blB += 4*RhsProgress;
-            blA += 3*Traits::LhsProgress;
-          }
-
-#undef EIGEN_GEBP_ONESTEP
-
-          ResPacket R0, R1, R2;
-          ResPacket alphav = pset1<ResPacket>(alpha);
-
-          R0 = r0.loadPacket(0 * Traits::ResPacketSize);
-          R1 = r0.loadPacket(1 * Traits::ResPacketSize);
-          R2 = r0.loadPacket(2 * Traits::ResPacketSize);
-          traits.acc(C0, alphav, R0);
-          traits.acc(C4, alphav, R1);
-          traits.acc(C8, alphav, R2);
-          r0.storePacket(0 * Traits::ResPacketSize, R0);
-          r0.storePacket(1 * Traits::ResPacketSize, R1);
-          r0.storePacket(2 * Traits::ResPacketSize, R2);
-
-          R0 = r1.loadPacket(0 * Traits::ResPacketSize);
-          R1 = r1.loadPacket(1 * Traits::ResPacketSize);
-          R2 = r1.loadPacket(2 * Traits::ResPacketSize);
-          traits.acc(C1, alphav, R0);
-          traits.acc(C5, alphav, R1);
-          traits.acc(C9, alphav, R2);
-          r1.storePacket(0 * Traits::ResPacketSize, R0);
-          r1.storePacket(1 * Traits::ResPacketSize, R1);
-          r1.storePacket(2 * Traits::ResPacketSize, R2);
-
-          R0 = r2.loadPacket(0 * Traits::ResPacketSize);
-          R1 = r2.loadPacket(1 * Traits::ResPacketSize);
-          R2 = r2.loadPacket(2 * Traits::ResPacketSize);
-          traits.acc(C2, alphav, R0);
-          traits.acc(C6, alphav, R1);
-          traits.acc(C10, alphav, R2);
-          r2.storePacket(0 * Traits::ResPacketSize, R0);
-          r2.storePacket(1 * Traits::ResPacketSize, R1);
-          r2.storePacket(2 * Traits::ResPacketSize, R2);
-
-          R0 = r3.loadPacket(0 * Traits::ResPacketSize);
-          R1 = r3.loadPacket(1 * Traits::ResPacketSize);
-          R2 = r3.loadPacket(2 * Traits::ResPacketSize);
-          traits.acc(C3, alphav, R0);
-          traits.acc(C7, alphav, R1);
-          traits.acc(C11, alphav, R2);
-          r3.storePacket(0 * Traits::ResPacketSize, R0);
-          r3.storePacket(1 * Traits::ResPacketSize, R1);
-          r3.storePacket(2 * Traits::ResPacketSize, R2);          
-          }
-        }
-
-        // Deal with remaining columns of the rhs
-        for(Index j2=packet_cols4; j2<cols; j2++)
-        {
-          for(Index i=i1; i<actual_panel_end; i+=3*LhsProgress)
-          {
-          // One column at a time
-          const LhsScalar* blA = &blockA[i*strideA+offsetA*(3*Traits::LhsProgress)];
-          prefetch(&blA[0]);
-
-          // gets res block as register
-          AccPacket C0, C4, C8;
-          traits.initAcc(C0);
-          traits.initAcc(C4);
-          traits.initAcc(C8);
-
-          LinearMapper r0 = res.getLinearMapper(i, j2);
-          r0.prefetch(0);
-
-          // performs "inner" products
-          const RhsScalar* blB = &blockB[j2*strideB+offsetB];
-          LhsPacket A0, A1, A2;
-          
-          for(Index k=0; k<peeled_kc; k+=pk)
-          {
-            EIGEN_ASM_COMMENT("begin gebp micro kernel 3pX1");
-            RhsPacket B_0;
-#define EIGEN_GEBGP_ONESTEP(K) \
-            do { \
-              EIGEN_ASM_COMMENT("begin step of gebp micro kernel 3pX1"); \
-              EIGEN_ASM_COMMENT("Note: these asm comments work around bug 935!"); \
-              traits.loadLhs(&blA[(0+3*K)*LhsProgress], A0);  \
-              traits.loadLhs(&blA[(1+3*K)*LhsProgress], A1);  \
-              traits.loadLhs(&blA[(2+3*K)*LhsProgress], A2);  \
-              traits.loadRhs(&blB[(0+K)*RhsProgress], B_0);   \
-              traits.madd(A0, B_0, C0, B_0); \
-              traits.madd(A1, B_0, C4, B_0); \
-              traits.madd(A2, B_0, C8, B_0); \
-              EIGEN_ASM_COMMENT("end step of gebp micro kernel 3pX1"); \
-            } while(false)
-        
-            EIGEN_GEBGP_ONESTEP(0);
-            EIGEN_GEBGP_ONESTEP(1);
-            EIGEN_GEBGP_ONESTEP(2);
-            EIGEN_GEBGP_ONESTEP(3);
-            EIGEN_GEBGP_ONESTEP(4);
-            EIGEN_GEBGP_ONESTEP(5);
-            EIGEN_GEBGP_ONESTEP(6);
-            EIGEN_GEBGP_ONESTEP(7);
-
-            blB += pk*RhsProgress;
-            blA += pk*3*Traits::LhsProgress;
-
-            EIGEN_ASM_COMMENT("end gebp micro kernel 3pX1");
-          }
-
-          // process remaining peeled loop
-          for(Index k=peeled_kc; k<depth; k++)
-          {
-            RhsPacket B_0;
-            EIGEN_GEBGP_ONESTEP(0);
-            blB += RhsProgress;
-            blA += 3*Traits::LhsProgress;
-          }
-#undef EIGEN_GEBGP_ONESTEP
-          ResPacket R0, R1, R2;
-          ResPacket alphav = pset1<ResPacket>(alpha);
-
-          R0 = r0.loadPacket(0 * Traits::ResPacketSize);
-          R1 = r0.loadPacket(1 * Traits::ResPacketSize);
-          R2 = r0.loadPacket(2 * Traits::ResPacketSize);
-          traits.acc(C0, alphav, R0);
-          traits.acc(C4, alphav, R1);
-          traits.acc(C8, alphav, R2);
-          r0.storePacket(0 * Traits::ResPacketSize, R0);
-          r0.storePacket(1 * Traits::ResPacketSize, R1);
-          r0.storePacket(2 * Traits::ResPacketSize, R2);          
-          }
-        }
-      }
-    }
-
-    //---------- Process 2 * LhsProgress rows at once ----------
-    if(mr>=2*Traits::LhsProgress)
-    {
-      const Index l1 = defaultL1CacheSize; // in Bytes, TODO, l1 should be passed to this function.
-      // The max(1, ...) here is needed because we may be using blocking params larger than what our known l1 cache size
-      // suggests we should be using: either because our known l1 cache size is inaccurate (e.g. on Android, we can only guess),
-      // or because we are testing specific blocking sizes.
-      Index actual_panel_rows = (2*LhsProgress) * std::max<Index>(1,( (l1 - sizeof(ResScalar)*mr*nr - depth*nr*sizeof(RhsScalar)) / (depth * sizeof(LhsScalar) * 2*LhsProgress) ));
-
-      for(Index i1=peeled_mc3; i1<peeled_mc2; i1+=actual_panel_rows)
-      {
-        Index actual_panel_end = (std::min)(i1+actual_panel_rows, peeled_mc2);
-        for(Index j2=0; j2<packet_cols4; j2+=nr)
-        {
-          for(Index i=i1; i<actual_panel_end; i+=2*LhsProgress)
-          {
-          
-          // We selected a 2*Traits::LhsProgress x nr micro block of res which is entirely
-          // stored into 2 x nr registers.
-          
-          const LhsScalar* blA = &blockA[i*strideA+offsetA*(2*Traits::LhsProgress)];
-          prefetch(&blA[0]);
-
-          // gets res block as register
-          AccPacket C0, C1, C2, C3,
-                    C4, C5, C6, C7;
-          traits.initAcc(C0); traits.initAcc(C1); traits.initAcc(C2); traits.initAcc(C3);
-          traits.initAcc(C4); traits.initAcc(C5); traits.initAcc(C6); traits.initAcc(C7);
-
-          LinearMapper r0 = res.getLinearMapper(i, j2 + 0);
-          LinearMapper r1 = res.getLinearMapper(i, j2 + 1);
-          LinearMapper r2 = res.getLinearMapper(i, j2 + 2);
-          LinearMapper r3 = res.getLinearMapper(i, j2 + 3);
-
-          r0.prefetch(prefetch_res_offset);
-          r1.prefetch(prefetch_res_offset);
-          r2.prefetch(prefetch_res_offset);
-          r3.prefetch(prefetch_res_offset);
-
-          // performs "inner" products
-          const RhsScalar* blB = &blockB[j2*strideB+offsetB*nr];
-          prefetch(&blB[0]);
-          LhsPacket A0, A1;
-
-          for(Index k=0; k<peeled_kc; k+=pk)
-          {
-            EIGEN_ASM_COMMENT("begin gebp micro kernel 2pX4");
-            RhsPacket B_0, B1, B2, B3, T0;
-
-          // NOTE: the begin/end asm comments below work around bug 935!
-          // but they are not enough for gcc>=6 without FMA (bug 1637)
-          #if EIGEN_GNUC_AT_LEAST(6,0) && defined(EIGEN_VECTORIZE_SSE)
-            #define EIGEN_GEBP_2PX4_SPILLING_WORKAROUND __asm__  ("" : [a0] "+x,m" (A0),[a1] "+x,m" (A1));
-          #else
-            #define EIGEN_GEBP_2PX4_SPILLING_WORKAROUND
-          #endif
-          #define EIGEN_GEBGP_ONESTEP(K) \
-            do {                                                                \
-              EIGEN_ASM_COMMENT("begin step of gebp micro kernel 2pX4");        \
-              traits.loadLhs(&blA[(0+2*K)*LhsProgress], A0);                    \
-              traits.loadLhs(&blA[(1+2*K)*LhsProgress], A1);                    \
-              traits.broadcastRhs(&blB[(0+4*K)*RhsProgress], B_0, B1, B2, B3);  \
-              traits.madd(A0, B_0, C0, T0);                                     \
-              traits.madd(A1, B_0, C4, B_0);                                    \
-              traits.madd(A0, B1,  C1, T0);                                     \
-              traits.madd(A1, B1,  C5, B1);                                     \
-              traits.madd(A0, B2,  C2, T0);                                     \
-              traits.madd(A1, B2,  C6, B2);                                     \
-              traits.madd(A0, B3,  C3, T0);                                     \
-              traits.madd(A1, B3,  C7, B3);                                     \
-              EIGEN_GEBP_2PX4_SPILLING_WORKAROUND                               \
-              EIGEN_ASM_COMMENT("end step of gebp micro kernel 2pX4");          \
-            } while(false)
-            
-            internal::prefetch(blB+(48+0));
-            EIGEN_GEBGP_ONESTEP(0);
-            EIGEN_GEBGP_ONESTEP(1);
-            EIGEN_GEBGP_ONESTEP(2);
-            EIGEN_GEBGP_ONESTEP(3);
-            internal::prefetch(blB+(48+16));
-            EIGEN_GEBGP_ONESTEP(4);
-            EIGEN_GEBGP_ONESTEP(5);
-            EIGEN_GEBGP_ONESTEP(6);
-            EIGEN_GEBGP_ONESTEP(7);
-
-            blB += pk*4*RhsProgress;
-            blA += pk*(2*Traits::LhsProgress);
-
-            EIGEN_ASM_COMMENT("end gebp micro kernel 2pX4");
-          }
-          // process remaining peeled loop
-          for(Index k=peeled_kc; k<depth; k++)
-          {
-            RhsPacket B_0, B1, B2, B3, T0;
-            EIGEN_GEBGP_ONESTEP(0);
-            blB += 4*RhsProgress;
-            blA += 2*Traits::LhsProgress;
-          }
-#undef EIGEN_GEBGP_ONESTEP
-
-          ResPacket R0, R1, R2, R3;
-          ResPacket alphav = pset1<ResPacket>(alpha);
-
-          R0 = r0.loadPacket(0 * Traits::ResPacketSize);
-          R1 = r0.loadPacket(1 * Traits::ResPacketSize);
-          R2 = r1.loadPacket(0 * Traits::ResPacketSize);
-          R3 = r1.loadPacket(1 * Traits::ResPacketSize);
-          traits.acc(C0, alphav, R0);
-          traits.acc(C4, alphav, R1);
-          traits.acc(C1, alphav, R2);
-          traits.acc(C5, alphav, R3);
-          r0.storePacket(0 * Traits::ResPacketSize, R0);
-          r0.storePacket(1 * Traits::ResPacketSize, R1);
-          r1.storePacket(0 * Traits::ResPacketSize, R2);
-          r1.storePacket(1 * Traits::ResPacketSize, R3);
-
-          R0 = r2.loadPacket(0 * Traits::ResPacketSize);
-          R1 = r2.loadPacket(1 * Traits::ResPacketSize);
-          R2 = r3.loadPacket(0 * Traits::ResPacketSize);
-          R3 = r3.loadPacket(1 * Traits::ResPacketSize);
-          traits.acc(C2,  alphav, R0);
-          traits.acc(C6,  alphav, R1);
-          traits.acc(C3,  alphav, R2);
-          traits.acc(C7,  alphav, R3);
-          r2.storePacket(0 * Traits::ResPacketSize, R0);
-          r2.storePacket(1 * Traits::ResPacketSize, R1);
-          r3.storePacket(0 * Traits::ResPacketSize, R2);
-          r3.storePacket(1 * Traits::ResPacketSize, R3);
-          }
-        }
-      
-        // Deal with remaining columns of the rhs
-        for(Index j2=packet_cols4; j2<cols; j2++)
-        {
-          for(Index i=i1; i<actual_panel_end; i+=2*LhsProgress)
-          {
-          // One column at a time
-          const LhsScalar* blA = &blockA[i*strideA+offsetA*(2*Traits::LhsProgress)];
-          prefetch(&blA[0]);
-
-          // gets res block as register
-          AccPacket C0, C4;
-          traits.initAcc(C0);
-          traits.initAcc(C4);
-
-          LinearMapper r0 = res.getLinearMapper(i, j2);
-          r0.prefetch(prefetch_res_offset);
-
-          // performs "inner" products
-          const RhsScalar* blB = &blockB[j2*strideB+offsetB];
-          LhsPacket A0, A1;
-
-          for(Index k=0; k<peeled_kc; k+=pk)
-          {
-            EIGEN_ASM_COMMENT("begin gebp micro kernel 2pX1");
-            RhsPacket B_0, B1;
-        
-#define EIGEN_GEBGP_ONESTEP(K) \
-            do {                                                                  \
-              EIGEN_ASM_COMMENT("begin step of gebp micro kernel 2pX1");          \
-              EIGEN_ASM_COMMENT("Note: these asm comments work around bug 935!"); \
-              traits.loadLhs(&blA[(0+2*K)*LhsProgress], A0);                      \
-              traits.loadLhs(&blA[(1+2*K)*LhsProgress], A1);                      \
-              traits.loadRhs(&blB[(0+K)*RhsProgress], B_0);                       \
-              traits.madd(A0, B_0, C0, B1);                                       \
-              traits.madd(A1, B_0, C4, B_0);                                      \
-              EIGEN_ASM_COMMENT("end step of gebp micro kernel 2pX1");            \
-            } while(false)
-        
-            EIGEN_GEBGP_ONESTEP(0);
-            EIGEN_GEBGP_ONESTEP(1);
-            EIGEN_GEBGP_ONESTEP(2);
-            EIGEN_GEBGP_ONESTEP(3);
-            EIGEN_GEBGP_ONESTEP(4);
-            EIGEN_GEBGP_ONESTEP(5);
-            EIGEN_GEBGP_ONESTEP(6);
-            EIGEN_GEBGP_ONESTEP(7);
-
-            blB += pk*RhsProgress;
-            blA += pk*2*Traits::LhsProgress;
-
-            EIGEN_ASM_COMMENT("end gebp micro kernel 2pX1");
-          }
-
-          // process remaining peeled loop
-          for(Index k=peeled_kc; k<depth; k++)
-          {
-            RhsPacket B_0, B1;
-            EIGEN_GEBGP_ONESTEP(0);
-            blB += RhsProgress;
-            blA += 2*Traits::LhsProgress;
-          }
-#undef EIGEN_GEBGP_ONESTEP
-          ResPacket R0, R1;
-          ResPacket alphav = pset1<ResPacket>(alpha);
-
-          R0 = r0.loadPacket(0 * Traits::ResPacketSize);
-          R1 = r0.loadPacket(1 * Traits::ResPacketSize);
-          traits.acc(C0, alphav, R0);
-          traits.acc(C4, alphav, R1);
-          r0.storePacket(0 * Traits::ResPacketSize, R0);
-          r0.storePacket(1 * Traits::ResPacketSize, R1);
-          }
-        }
-      }
-    }
-    //---------- Process 1 * LhsProgress rows at once ----------
-    if(mr>=1*Traits::LhsProgress)
-    {
-      // loops on each largest micro horizontal panel of lhs (1*LhsProgress x depth)
-      for(Index i=peeled_mc2; i<peeled_mc1; i+=1*LhsProgress)
-      {
-        // loops on each largest micro vertical panel of rhs (depth * nr)
-        for(Index j2=0; j2<packet_cols4; j2+=nr)
-        {
-          // We select a 1*Traits::LhsProgress x nr micro block of res which is entirely
-          // stored into 1 x nr registers.
-          
-          const LhsScalar* blA = &blockA[i*strideA+offsetA*(1*Traits::LhsProgress)];
-          prefetch(&blA[0]);
-
-          // gets res block as register
-          AccPacket C0, C1, C2, C3;
-          traits.initAcc(C0);
-          traits.initAcc(C1);
-          traits.initAcc(C2);
-          traits.initAcc(C3);
-
-          LinearMapper r0 = res.getLinearMapper(i, j2 + 0);
-          LinearMapper r1 = res.getLinearMapper(i, j2 + 1);
-          LinearMapper r2 = res.getLinearMapper(i, j2 + 2);
-          LinearMapper r3 = res.getLinearMapper(i, j2 + 3);
-
-          r0.prefetch(prefetch_res_offset);
-          r1.prefetch(prefetch_res_offset);
-          r2.prefetch(prefetch_res_offset);
-          r3.prefetch(prefetch_res_offset);
-
-          // performs "inner" products
-          const RhsScalar* blB = &blockB[j2*strideB+offsetB*nr];
-          prefetch(&blB[0]);
-          LhsPacket A0;
-
-          for(Index k=0; k<peeled_kc; k+=pk)
-          {
-            EIGEN_ASM_COMMENT("begin gebp micro kernel 1pX4");
-            RhsPacket B_0, B1, B2, B3;
-               
-#define EIGEN_GEBGP_ONESTEP(K) \
-            do {                                                                \
-              EIGEN_ASM_COMMENT("begin step of gebp micro kernel 1pX4");        \
-              EIGEN_ASM_COMMENT("Note: these asm comments work around bug 935!"); \
-              traits.loadLhs(&blA[(0+1*K)*LhsProgress], A0);                    \
-              traits.broadcastRhs(&blB[(0+4*K)*RhsProgress], B_0, B1, B2, B3);  \
-              traits.madd(A0, B_0, C0, B_0);                                    \
-              traits.madd(A0, B1,  C1, B1);                                     \
-              traits.madd(A0, B2,  C2, B2);                                     \
-              traits.madd(A0, B3,  C3, B3);                                     \
-              EIGEN_ASM_COMMENT("end step of gebp micro kernel 1pX4");          \
-            } while(false)
-            
-            internal::prefetch(blB+(48+0));
-            EIGEN_GEBGP_ONESTEP(0);
-            EIGEN_GEBGP_ONESTEP(1);
-            EIGEN_GEBGP_ONESTEP(2);
-            EIGEN_GEBGP_ONESTEP(3);
-            internal::prefetch(blB+(48+16));
-            EIGEN_GEBGP_ONESTEP(4);
-            EIGEN_GEBGP_ONESTEP(5);
-            EIGEN_GEBGP_ONESTEP(6);
-            EIGEN_GEBGP_ONESTEP(7);
-
-            blB += pk*4*RhsProgress;
-            blA += pk*1*LhsProgress;
-
-            EIGEN_ASM_COMMENT("end gebp micro kernel 1pX4");
-          }
-          // process remaining peeled loop
-          for(Index k=peeled_kc; k<depth; k++)
-          {
-            RhsPacket B_0, B1, B2, B3;
-            EIGEN_GEBGP_ONESTEP(0);
-            blB += 4*RhsProgress;
-            blA += 1*LhsProgress;
-          }
-#undef EIGEN_GEBGP_ONESTEP
-
-          ResPacket R0, R1;
-          ResPacket alphav = pset1<ResPacket>(alpha);
-
-          R0 = r0.loadPacket(0 * Traits::ResPacketSize);
-          R1 = r1.loadPacket(0 * Traits::ResPacketSize);
-          traits.acc(C0, alphav, R0);
-          traits.acc(C1,  alphav, R1);
-          r0.storePacket(0 * Traits::ResPacketSize, R0);
-          r1.storePacket(0 * Traits::ResPacketSize, R1);
-
-          R0 = r2.loadPacket(0 * Traits::ResPacketSize);
-          R1 = r3.loadPacket(0 * Traits::ResPacketSize);
-          traits.acc(C2,  alphav, R0);
-          traits.acc(C3,  alphav, R1);
-          r2.storePacket(0 * Traits::ResPacketSize, R0);
-          r3.storePacket(0 * Traits::ResPacketSize, R1);
-        }
-
-        // Deal with remaining columns of the rhs
-        for(Index j2=packet_cols4; j2<cols; j2++)
-        {
-          // One column at a time
-          const LhsScalar* blA = &blockA[i*strideA+offsetA*(1*Traits::LhsProgress)];
-          prefetch(&blA[0]);
-
-          // gets res block as register
-          AccPacket C0;
-          traits.initAcc(C0);
-
-          LinearMapper r0 = res.getLinearMapper(i, j2);
-
-          // performs "inner" products
-          const RhsScalar* blB = &blockB[j2*strideB+offsetB];
-          LhsPacket A0;
-
-          for(Index k=0; k<peeled_kc; k+=pk)
-          {
-            EIGEN_ASM_COMMENT("begin gebp micro kernel 1pX1");
-            RhsPacket B_0;
-        
-#define EIGEN_GEBGP_ONESTEP(K) \
-            do {                                                                \
-              EIGEN_ASM_COMMENT("begin step of gebp micro kernel 1pX1");        \
-              EIGEN_ASM_COMMENT("Note: these asm comments work around bug 935!"); \
-              traits.loadLhs(&blA[(0+1*K)*LhsProgress], A0);                    \
-              traits.loadRhs(&blB[(0+K)*RhsProgress], B_0);                     \
-              traits.madd(A0, B_0, C0, B_0);                                    \
-              EIGEN_ASM_COMMENT("end step of gebp micro kernel 1pX1");          \
-            } while(false);
-
-            EIGEN_GEBGP_ONESTEP(0);
-            EIGEN_GEBGP_ONESTEP(1);
-            EIGEN_GEBGP_ONESTEP(2);
-            EIGEN_GEBGP_ONESTEP(3);
-            EIGEN_GEBGP_ONESTEP(4);
-            EIGEN_GEBGP_ONESTEP(5);
-            EIGEN_GEBGP_ONESTEP(6);
-            EIGEN_GEBGP_ONESTEP(7);
-
-            blB += pk*RhsProgress;
-            blA += pk*1*Traits::LhsProgress;
-
-            EIGEN_ASM_COMMENT("end gebp micro kernel 1pX1");
-          }
-
-          // process remaining peeled loop
-          for(Index k=peeled_kc; k<depth; k++)
-          {
-            RhsPacket B_0;
-            EIGEN_GEBGP_ONESTEP(0);
-            blB += RhsProgress;
-            blA += 1*Traits::LhsProgress;
-          }
-#undef EIGEN_GEBGP_ONESTEP
-          ResPacket R0;
-          ResPacket alphav = pset1<ResPacket>(alpha);
-          R0 = r0.loadPacket(0 * Traits::ResPacketSize);
-          traits.acc(C0, alphav, R0);
-          r0.storePacket(0 * Traits::ResPacketSize, R0);
-        }
-      }
-    }
-    //---------- Process remaining rows, 1 at once ----------
-    if(peeled_mc1<rows)
-    {
-      // loop on each panel of the rhs
-      for(Index j2=0; j2<packet_cols4; j2+=nr)
-      {
-        // loop on each row of the lhs (1*LhsProgress x depth)
-        for(Index i=peeled_mc1; i<rows; i+=1)
-        {
-          const LhsScalar* blA = &blockA[i*strideA+offsetA];
-          prefetch(&blA[0]);
-          const RhsScalar* blB = &blockB[j2*strideB+offsetB*nr];
-
-          // The following piece of code wont work for 512 bit registers
-          // Moreover, if LhsProgress==8 it assumes that there is a half packet of the same size
-          // as nr (which is currently 4) for the return type.
-          const int SResPacketHalfSize = unpacket_traits<typename unpacket_traits<SResPacket>::half>::size;
-          if ((SwappedTraits::LhsProgress % 4) == 0 &&
-              (SwappedTraits::LhsProgress <= 8) &&
-              (SwappedTraits::LhsProgress!=8 || SResPacketHalfSize==nr))
-          {
-            SAccPacket C0, C1, C2, C3;
-            straits.initAcc(C0);
-            straits.initAcc(C1);
-            straits.initAcc(C2);
-            straits.initAcc(C3);
-
-            const Index spk   = (std::max)(1,SwappedTraits::LhsProgress/4);
-            const Index endk  = (depth/spk)*spk;
-            const Index endk4 = (depth/(spk*4))*(spk*4);
-
-            Index k=0;
-            for(; k<endk4; k+=4*spk)
-            {
-              SLhsPacket A0,A1;
-              SRhsPacket B_0,B_1;
-
-              straits.loadLhsUnaligned(blB+0*SwappedTraits::LhsProgress, A0);
-              straits.loadLhsUnaligned(blB+1*SwappedTraits::LhsProgress, A1);
-
-              straits.loadRhsQuad(blA+0*spk, B_0);
-              straits.loadRhsQuad(blA+1*spk, B_1);
-              straits.madd(A0,B_0,C0,B_0);
-              straits.madd(A1,B_1,C1,B_1);
-
-              straits.loadLhsUnaligned(blB+2*SwappedTraits::LhsProgress, A0);
-              straits.loadLhsUnaligned(blB+3*SwappedTraits::LhsProgress, A1);
-              straits.loadRhsQuad(blA+2*spk, B_0);
-              straits.loadRhsQuad(blA+3*spk, B_1);
-              straits.madd(A0,B_0,C2,B_0);
-              straits.madd(A1,B_1,C3,B_1);
-
-              blB += 4*SwappedTraits::LhsProgress;
-              blA += 4*spk;
-            }
-            C0 = padd(padd(C0,C1),padd(C2,C3));
-            for(; k<endk; k+=spk)
-            {
-              SLhsPacket A0;
-              SRhsPacket B_0;
-
-              straits.loadLhsUnaligned(blB, A0);
-              straits.loadRhsQuad(blA, B_0);
-              straits.madd(A0,B_0,C0,B_0);
-
-              blB += SwappedTraits::LhsProgress;
-              blA += spk;
-            }
-            if(SwappedTraits::LhsProgress==8)
-            {
-              // Special case where we have to first reduce the accumulation register C0
-              typedef typename conditional<SwappedTraits::LhsProgress>=8,typename unpacket_traits<SResPacket>::half,SResPacket>::type SResPacketHalf;
-              typedef typename conditional<SwappedTraits::LhsProgress>=8,typename unpacket_traits<SLhsPacket>::half,SLhsPacket>::type SLhsPacketHalf;
-              typedef typename conditional<SwappedTraits::LhsProgress>=8,typename unpacket_traits<SLhsPacket>::half,SRhsPacket>::type SRhsPacketHalf;
-              typedef typename conditional<SwappedTraits::LhsProgress>=8,typename unpacket_traits<SAccPacket>::half,SAccPacket>::type SAccPacketHalf;
-
-              SResPacketHalf R = res.template gatherPacket<SResPacketHalf>(i, j2);
-              SResPacketHalf alphav = pset1<SResPacketHalf>(alpha);
-
-              if(depth-endk>0)
-              {
-                // We have to handle the last row of the rhs which corresponds to a half-packet
-                SLhsPacketHalf a0;
-                SRhsPacketHalf b0;
-                straits.loadLhsUnaligned(blB, a0);
-                straits.loadRhs(blA, b0);
-                SAccPacketHalf c0 = predux_downto4(C0);
-                straits.madd(a0,b0,c0,b0);
-                straits.acc(c0, alphav, R);
-              }
-              else
-              {
-                straits.acc(predux_downto4(C0), alphav, R);
-              }
-              res.scatterPacket(i, j2, R);
-            }
-            else
-            {
-              SResPacket R = res.template gatherPacket<SResPacket>(i, j2);
-              SResPacket alphav = pset1<SResPacket>(alpha);
-              straits.acc(C0, alphav, R);
-              res.scatterPacket(i, j2, R);
-            }
-          }
-          else // scalar path
-          {
-            // get a 1 x 4 res block as registers
-            ResScalar C0(0), C1(0), C2(0), C3(0);
-
-            for(Index k=0; k<depth; k++)
-            {
-              LhsScalar A0;
-              RhsScalar B_0, B_1;
-
-              A0 = blA[k];
-
-              B_0 = blB[0];
-              B_1 = blB[1];
-              CJMADD(cj,A0,B_0,C0,  B_0);
-              CJMADD(cj,A0,B_1,C1,  B_1);
-              
-              B_0 = blB[2];
-              B_1 = blB[3];
-              CJMADD(cj,A0,B_0,C2,  B_0);
-              CJMADD(cj,A0,B_1,C3,  B_1);
-              
-              blB += 4;
-            }
-            res(i, j2 + 0) += alpha * C0;
-            res(i, j2 + 1) += alpha * C1;
-            res(i, j2 + 2) += alpha * C2;
-            res(i, j2 + 3) += alpha * C3;
-          }
-        }
-      }
-      // remaining columns
-      for(Index j2=packet_cols4; j2<cols; j2++)
-      {
-        // loop on each row of the lhs (1*LhsProgress x depth)
-        for(Index i=peeled_mc1; i<rows; i+=1)
-        {
-          const LhsScalar* blA = &blockA[i*strideA+offsetA];
-          prefetch(&blA[0]);
-          // gets a 1 x 1 res block as registers
-          ResScalar C0(0);
-          const RhsScalar* blB = &blockB[j2*strideB+offsetB];
-          for(Index k=0; k<depth; k++)
-          {
-            LhsScalar A0 = blA[k];
-            RhsScalar B_0 = blB[k];
-            CJMADD(cj, A0, B_0, C0, B_0);
-          }
-          res(i, j2) += alpha * C0;
-        }
-      }
-    }
-  }
-
-
-#undef CJMADD
-
-// pack a block of the lhs
-// The traversal is as follow (mr==4):
-//   0  4  8 12 ...
-//   1  5  9 13 ...
-//   2  6 10 14 ...
-//   3  7 11 15 ...
-//
-//  16 20 24 28 ...
-//  17 21 25 29 ...
-//  18 22 26 30 ...
-//  19 23 27 31 ...
-//
-//  32 33 34 35 ...
-//  36 36 38 39 ...
-template<typename Scalar, typename Index, typename DataMapper, int Pack1, int Pack2, bool Conjugate, bool PanelMode>
-struct gemm_pack_lhs<Scalar, Index, DataMapper, Pack1, Pack2, ColMajor, Conjugate, PanelMode>
-{
-  typedef typename DataMapper::LinearMapper LinearMapper;
-  EIGEN_DONT_INLINE void operator()(Scalar* blockA, const DataMapper& lhs, Index depth, Index rows, Index stride=0, Index offset=0);
-};
-
-template<typename Scalar, typename Index, typename DataMapper, int Pack1, int Pack2, bool Conjugate, bool PanelMode>
-EIGEN_DONT_INLINE void gemm_pack_lhs<Scalar, Index, DataMapper, Pack1, Pack2, ColMajor, Conjugate, PanelMode>
-  ::operator()(Scalar* blockA, const DataMapper& lhs, Index depth, Index rows, Index stride, Index offset)
-{
-  typedef typename packet_traits<Scalar>::type Packet;
-  enum { PacketSize = packet_traits<Scalar>::size };
-
-  EIGEN_ASM_COMMENT("EIGEN PRODUCT PACK LHS");
-  EIGEN_UNUSED_VARIABLE(stride);
-  EIGEN_UNUSED_VARIABLE(offset);
-  eigen_assert(((!PanelMode) && stride==0 && offset==0) || (PanelMode && stride>=depth && offset<=stride));
-  eigen_assert( ((Pack1%PacketSize)==0 && Pack1<=4*PacketSize) || (Pack1<=4) );
-  conj_if<NumTraits<Scalar>::IsComplex && Conjugate> cj;
-  Index count = 0;
-
-  const Index peeled_mc3 = Pack1>=3*PacketSize ? (rows/(3*PacketSize))*(3*PacketSize) : 0;
-  const Index peeled_mc2 = Pack1>=2*PacketSize ? peeled_mc3+((rows-peeled_mc3)/(2*PacketSize))*(2*PacketSize) : 0;
-  const Index peeled_mc1 = Pack1>=1*PacketSize ? (rows/(1*PacketSize))*(1*PacketSize) : 0;
-  const Index peeled_mc0 = Pack2>=1*PacketSize ? peeled_mc1
-                         : Pack2>1             ? (rows/Pack2)*Pack2 : 0;
-
-  Index i=0;
-
-  // Pack 3 packets
-  if(Pack1>=3*PacketSize)
-  {
-    for(; i<peeled_mc3; i+=3*PacketSize)
-    {
-      if(PanelMode) count += (3*PacketSize) * offset;
-
-      for(Index k=0; k<depth; k++)
-      {
-        Packet A, B, C;
-        A = lhs.loadPacket(i+0*PacketSize, k);
-        B = lhs.loadPacket(i+1*PacketSize, k);
-        C = lhs.loadPacket(i+2*PacketSize, k);
-        pstore(blockA+count, cj.pconj(A)); count+=PacketSize;
-        pstore(blockA+count, cj.pconj(B)); count+=PacketSize;
-        pstore(blockA+count, cj.pconj(C)); count+=PacketSize;
-      }
-      if(PanelMode) count += (3*PacketSize) * (stride-offset-depth);
-    }
-  }
-  // Pack 2 packets
-  if(Pack1>=2*PacketSize)
-  {
-    for(; i<peeled_mc2; i+=2*PacketSize)
-    {
-      if(PanelMode) count += (2*PacketSize) * offset;
-
-      for(Index k=0; k<depth; k++)
-      {
-        Packet A, B;
-        A = lhs.loadPacket(i+0*PacketSize, k);
-        B = lhs.loadPacket(i+1*PacketSize, k);
-        pstore(blockA+count, cj.pconj(A)); count+=PacketSize;
-        pstore(blockA+count, cj.pconj(B)); count+=PacketSize;
-      }
-      if(PanelMode) count += (2*PacketSize) * (stride-offset-depth);
-    }
-  }
-  // Pack 1 packets
-  if(Pack1>=1*PacketSize)
-  {
-    for(; i<peeled_mc1; i+=1*PacketSize)
-    {
-      if(PanelMode) count += (1*PacketSize) * offset;
-
-      for(Index k=0; k<depth; k++)
-      {
-        Packet A;
-        A = lhs.loadPacket(i+0*PacketSize, k);
-        pstore(blockA+count, cj.pconj(A));
-        count+=PacketSize;
-      }
-      if(PanelMode) count += (1*PacketSize) * (stride-offset-depth);
-    }
-  }
-  // Pack scalars
-  if(Pack2<PacketSize && Pack2>1)
-  {
-    for(; i<peeled_mc0; i+=Pack2)
-    {
-      if(PanelMode) count += Pack2 * offset;
-
-      for(Index k=0; k<depth; k++)
-        for(Index w=0; w<Pack2; w++)
-          blockA[count++] = cj(lhs(i+w, k));
-
-      if(PanelMode) count += Pack2 * (stride-offset-depth);
-    }
-  }
-  for(; i<rows; i++)
-  {
-    if(PanelMode) count += offset;
-    for(Index k=0; k<depth; k++)
-      blockA[count++] = cj(lhs(i, k));
-    if(PanelMode) count += (stride-offset-depth);
-  }
-}
-
-template<typename Scalar, typename Index, typename DataMapper, int Pack1, int Pack2, bool Conjugate, bool PanelMode>
-struct gemm_pack_lhs<Scalar, Index, DataMapper, Pack1, Pack2, RowMajor, Conjugate, PanelMode>
-{
-  typedef typename DataMapper::LinearMapper LinearMapper;
-  EIGEN_DONT_INLINE void operator()(Scalar* blockA, const DataMapper& lhs, Index depth, Index rows, Index stride=0, Index offset=0);
-};
-
-template<typename Scalar, typename Index, typename DataMapper, int Pack1, int Pack2, bool Conjugate, bool PanelMode>
-EIGEN_DONT_INLINE void gemm_pack_lhs<Scalar, Index, DataMapper, Pack1, Pack2, RowMajor, Conjugate, PanelMode>
-  ::operator()(Scalar* blockA, const DataMapper& lhs, Index depth, Index rows, Index stride, Index offset)
-{
-  typedef typename packet_traits<Scalar>::type Packet;
-  enum { PacketSize = packet_traits<Scalar>::size };
-
-  EIGEN_ASM_COMMENT("EIGEN PRODUCT PACK LHS");
-  EIGEN_UNUSED_VARIABLE(stride);
-  EIGEN_UNUSED_VARIABLE(offset);
-  eigen_assert(((!PanelMode) && stride==0 && offset==0) || (PanelMode && stride>=depth && offset<=stride));
-  conj_if<NumTraits<Scalar>::IsComplex && Conjugate> cj;
-  Index count = 0;
-
-//   const Index peeled_mc3 = Pack1>=3*PacketSize ? (rows/(3*PacketSize))*(3*PacketSize) : 0;
-//   const Index peeled_mc2 = Pack1>=2*PacketSize ? peeled_mc3+((rows-peeled_mc3)/(2*PacketSize))*(2*PacketSize) : 0;
-//   const Index peeled_mc1 = Pack1>=1*PacketSize ? (rows/(1*PacketSize))*(1*PacketSize) : 0;
-
-  int pack = Pack1;
-  Index i = 0;
-  while(pack>0)
-  {
-    Index remaining_rows = rows-i;
-    Index peeled_mc = i+(remaining_rows/pack)*pack;
-    for(; i<peeled_mc; i+=pack)
-    {
-      if(PanelMode) count += pack * offset;
-
-      const Index peeled_k = (depth/PacketSize)*PacketSize;
-      Index k=0;
-      if(pack>=PacketSize)
-      {
-        for(; k<peeled_k; k+=PacketSize)
-        {
-          for (Index m = 0; m < pack; m += PacketSize)
-          {
-            PacketBlock<Packet> kernel;
-            for (int p = 0; p < PacketSize; ++p) kernel.packet[p] = lhs.loadPacket(i+p+m, k);
-            ptranspose(kernel);
-            for (int p = 0; p < PacketSize; ++p) pstore(blockA+count+m+(pack)*p, cj.pconj(kernel.packet[p]));
-          }
-          count += PacketSize*pack;
-        }
-      }
-      for(; k<depth; k++)
-      {
-        Index w=0;
-        for(; w<pack-3; w+=4)
-        {
-          Scalar a(cj(lhs(i+w+0, k))),
-                 b(cj(lhs(i+w+1, k))),
-                 c(cj(lhs(i+w+2, k))),
-                 d(cj(lhs(i+w+3, k)));
-          blockA[count++] = a;
-          blockA[count++] = b;
-          blockA[count++] = c;
-          blockA[count++] = d;
-        }
-        if(pack%4)
-          for(;w<pack;++w)
-            blockA[count++] = cj(lhs(i+w, k));
-      }
-
-      if(PanelMode) count += pack * (stride-offset-depth);
-    }
-
-    pack -= PacketSize;
-    if(pack<Pack2 && (pack+PacketSize)!=Pack2)
-      pack = Pack2;
-  }
-
-  for(; i<rows; i++)
-  {
-    if(PanelMode) count += offset;
-    for(Index k=0; k<depth; k++)
-      blockA[count++] = cj(lhs(i, k));
-    if(PanelMode) count += (stride-offset-depth);
-  }
-}
-
-// copy a complete panel of the rhs
-// this version is optimized for column major matrices
-// The traversal order is as follow: (nr==4):
-//  0  1  2  3   12 13 14 15   24 27
-//  4  5  6  7   16 17 18 19   25 28
-//  8  9 10 11   20 21 22 23   26 29
-//  .  .  .  .    .  .  .  .    .  .
-template<typename Scalar, typename Index, typename DataMapper, int nr, bool Conjugate, bool PanelMode>
-struct gemm_pack_rhs<Scalar, Index, DataMapper, nr, ColMajor, Conjugate, PanelMode>
-{
-  typedef typename packet_traits<Scalar>::type Packet;
-  typedef typename DataMapper::LinearMapper LinearMapper;
-  enum { PacketSize = packet_traits<Scalar>::size };
-  EIGEN_DONT_INLINE void operator()(Scalar* blockB, const DataMapper& rhs, Index depth, Index cols, Index stride=0, Index offset=0);
-};
-
-template<typename Scalar, typename Index, typename DataMapper, int nr, bool Conjugate, bool PanelMode>
-EIGEN_DONT_INLINE void gemm_pack_rhs<Scalar, Index, DataMapper, nr, ColMajor, Conjugate, PanelMode>
-  ::operator()(Scalar* blockB, const DataMapper& rhs, Index depth, Index cols, Index stride, Index offset)
-{
-  EIGEN_ASM_COMMENT("EIGEN PRODUCT PACK RHS COLMAJOR");
-  EIGEN_UNUSED_VARIABLE(stride);
-  EIGEN_UNUSED_VARIABLE(offset);
-  eigen_assert(((!PanelMode) && stride==0 && offset==0) || (PanelMode && stride>=depth && offset<=stride));
-  conj_if<NumTraits<Scalar>::IsComplex && Conjugate> cj;
-  Index packet_cols8 = nr>=8 ? (cols/8) * 8 : 0;
-  Index packet_cols4 = nr>=4 ? (cols/4) * 4 : 0;
-  Index count = 0;
-  const Index peeled_k = (depth/PacketSize)*PacketSize;
-//   if(nr>=8)
-//   {
-//     for(Index j2=0; j2<packet_cols8; j2+=8)
-//     {
-//       // skip what we have before
-//       if(PanelMode) count += 8 * offset;
-//       const Scalar* b0 = &rhs[(j2+0)*rhsStride];
-//       const Scalar* b1 = &rhs[(j2+1)*rhsStride];
-//       const Scalar* b2 = &rhs[(j2+2)*rhsStride];
-//       const Scalar* b3 = &rhs[(j2+3)*rhsStride];
-//       const Scalar* b4 = &rhs[(j2+4)*rhsStride];
-//       const Scalar* b5 = &rhs[(j2+5)*rhsStride];
-//       const Scalar* b6 = &rhs[(j2+6)*rhsStride];
-//       const Scalar* b7 = &rhs[(j2+7)*rhsStride];
-//       Index k=0;
-//       if(PacketSize==8) // TODO enbale vectorized transposition for PacketSize==4
-//       {
-//         for(; k<peeled_k; k+=PacketSize) {
-//           PacketBlock<Packet> kernel;
-//           for (int p = 0; p < PacketSize; ++p) {
-//             kernel.packet[p] = ploadu<Packet>(&rhs[(j2+p)*rhsStride+k]);
-//           }
-//           ptranspose(kernel);
-//           for (int p = 0; p < PacketSize; ++p) {
-//             pstoreu(blockB+count, cj.pconj(kernel.packet[p]));
-//             count+=PacketSize;
-//           }
-//         }
-//       }
-//       for(; k<depth; k++)
-//       {
-//         blockB[count+0] = cj(b0[k]);
-//         blockB[count+1] = cj(b1[k]);
-//         blockB[count+2] = cj(b2[k]);
-//         blockB[count+3] = cj(b3[k]);
-//         blockB[count+4] = cj(b4[k]);
-//         blockB[count+5] = cj(b5[k]);
-//         blockB[count+6] = cj(b6[k]);
-//         blockB[count+7] = cj(b7[k]);
-//         count += 8;
-//       }
-//       // skip what we have after
-//       if(PanelMode) count += 8 * (stride-offset-depth);
-//     }
-//   }
-
-  if(nr>=4)
-  {
-    for(Index j2=packet_cols8; j2<packet_cols4; j2+=4)
-    {
-      // skip what we have before
-      if(PanelMode) count += 4 * offset;
-      const LinearMapper dm0 = rhs.getLinearMapper(0, j2 + 0);
-      const LinearMapper dm1 = rhs.getLinearMapper(0, j2 + 1);
-      const LinearMapper dm2 = rhs.getLinearMapper(0, j2 + 2);
-      const LinearMapper dm3 = rhs.getLinearMapper(0, j2 + 3);
-
-      Index k=0;
-      if((PacketSize%4)==0) // TODO enable vectorized transposition for PacketSize==2 ??
-      {
-        for(; k<peeled_k; k+=PacketSize) {
-          PacketBlock<Packet,(PacketSize%4)==0?4:PacketSize> kernel;
-          kernel.packet[0] = dm0.loadPacket(k);
-          kernel.packet[1%PacketSize] = dm1.loadPacket(k);
-          kernel.packet[2%PacketSize] = dm2.loadPacket(k);
-          kernel.packet[3%PacketSize] = dm3.loadPacket(k);
-          ptranspose(kernel);
-          pstoreu(blockB+count+0*PacketSize, cj.pconj(kernel.packet[0]));
-          pstoreu(blockB+count+1*PacketSize, cj.pconj(kernel.packet[1%PacketSize]));
-          pstoreu(blockB+count+2*PacketSize, cj.pconj(kernel.packet[2%PacketSize]));
-          pstoreu(blockB+count+3*PacketSize, cj.pconj(kernel.packet[3%PacketSize]));
-          count+=4*PacketSize;
-        }
-      }
-      for(; k<depth; k++)
-      {
-        blockB[count+0] = cj(dm0(k));
-        blockB[count+1] = cj(dm1(k));
-        blockB[count+2] = cj(dm2(k));
-        blockB[count+3] = cj(dm3(k));
-        count += 4;
-      }
-      // skip what we have after
-      if(PanelMode) count += 4 * (stride-offset-depth);
-    }
-  }
-
-  // copy the remaining columns one at a time (nr==1)
-  for(Index j2=packet_cols4; j2<cols; ++j2)
-  {
-    if(PanelMode) count += offset;
-    const LinearMapper dm0 = rhs.getLinearMapper(0, j2);
-    for(Index k=0; k<depth; k++)
-    {
-      blockB[count] = cj(dm0(k));
-      count += 1;
-    }
-    if(PanelMode) count += (stride-offset-depth);
-  }
-}
-
-// this version is optimized for row major matrices
-template<typename Scalar, typename Index, typename DataMapper, int nr, bool Conjugate, bool PanelMode>
-struct gemm_pack_rhs<Scalar, Index, DataMapper, nr, RowMajor, Conjugate, PanelMode>
-{
-  typedef typename packet_traits<Scalar>::type Packet;
-  typedef typename DataMapper::LinearMapper LinearMapper;
-  enum { PacketSize = packet_traits<Scalar>::size };
-  EIGEN_DONT_INLINE void operator()(Scalar* blockB, const DataMapper& rhs, Index depth, Index cols, Index stride=0, Index offset=0);
-};
-
-template<typename Scalar, typename Index, typename DataMapper, int nr, bool Conjugate, bool PanelMode>
-EIGEN_DONT_INLINE void gemm_pack_rhs<Scalar, Index, DataMapper, nr, RowMajor, Conjugate, PanelMode>
-  ::operator()(Scalar* blockB, const DataMapper& rhs, Index depth, Index cols, Index stride, Index offset)
-{
-  EIGEN_ASM_COMMENT("EIGEN PRODUCT PACK RHS ROWMAJOR");
-  EIGEN_UNUSED_VARIABLE(stride);
-  EIGEN_UNUSED_VARIABLE(offset);
-  eigen_assert(((!PanelMode) && stride==0 && offset==0) || (PanelMode && stride>=depth && offset<=stride));
-  conj_if<NumTraits<Scalar>::IsComplex && Conjugate> cj;
-  Index packet_cols8 = nr>=8 ? (cols/8) * 8 : 0;
-  Index packet_cols4 = nr>=4 ? (cols/4) * 4 : 0;
-  Index count = 0;
-
-//   if(nr>=8)
-//   {
-//     for(Index j2=0; j2<packet_cols8; j2+=8)
-//     {
-//       // skip what we have before
-//       if(PanelMode) count += 8 * offset;
-//       for(Index k=0; k<depth; k++)
-//       {
-//         if (PacketSize==8) {
-//           Packet A = ploadu<Packet>(&rhs[k*rhsStride + j2]);
-//           pstoreu(blockB+count, cj.pconj(A));
-//         } else if (PacketSize==4) {
-//           Packet A = ploadu<Packet>(&rhs[k*rhsStride + j2]);
-//           Packet B = ploadu<Packet>(&rhs[k*rhsStride + j2 + PacketSize]);
-//           pstoreu(blockB+count, cj.pconj(A));
-//           pstoreu(blockB+count+PacketSize, cj.pconj(B));
-//         } else {
-//           const Scalar* b0 = &rhs[k*rhsStride + j2];
-//           blockB[count+0] = cj(b0[0]);
-//           blockB[count+1] = cj(b0[1]);
-//           blockB[count+2] = cj(b0[2]);
-//           blockB[count+3] = cj(b0[3]);
-//           blockB[count+4] = cj(b0[4]);
-//           blockB[count+5] = cj(b0[5]);
-//           blockB[count+6] = cj(b0[6]);
-//           blockB[count+7] = cj(b0[7]);
-//         }
-//         count += 8;
-//       }
-//       // skip what we have after
-//       if(PanelMode) count += 8 * (stride-offset-depth);
-//     }
-//   }
-  if(nr>=4)
-  {
-    for(Index j2=packet_cols8; j2<packet_cols4; j2+=4)
-    {
-      // skip what we have before
-      if(PanelMode) count += 4 * offset;
-      for(Index k=0; k<depth; k++)
-      {
-        if (PacketSize==4) {
-          Packet A = rhs.loadPacket(k, j2);
-          pstoreu(blockB+count, cj.pconj(A));
-          count += PacketSize;
-        } else {
-          const LinearMapper dm0 = rhs.getLinearMapper(k, j2);
-          blockB[count+0] = cj(dm0(0));
-          blockB[count+1] = cj(dm0(1));
-          blockB[count+2] = cj(dm0(2));
-          blockB[count+3] = cj(dm0(3));
-          count += 4;
-        }
-      }
-      // skip what we have after
-      if(PanelMode) count += 4 * (stride-offset-depth);
-    }
-  }
-  // copy the remaining columns one at a time (nr==1)
-  for(Index j2=packet_cols4; j2<cols; ++j2)
-  {
-    if(PanelMode) count += offset;
-    for(Index k=0; k<depth; k++)
-    {
-      blockB[count] = cj(rhs(k, j2));
-      count += 1;
-    }
-    if(PanelMode) count += stride-offset-depth;
-  }
-}
-
-} // end namespace internal
-
-/** \returns the currently set level 1 cpu cache size (in bytes) used to estimate the ideal blocking size parameters.
-  * \sa setCpuCacheSize */
-inline std::ptrdiff_t l1CacheSize()
-{
-  std::ptrdiff_t l1, l2, l3;
-  internal::manage_caching_sizes(GetAction, &l1, &l2, &l3);
-  return l1;
-}
-
-/** \returns the currently set level 2 cpu cache size (in bytes) used to estimate the ideal blocking size parameters.
-  * \sa setCpuCacheSize */
-inline std::ptrdiff_t l2CacheSize()
-{
-  std::ptrdiff_t l1, l2, l3;
-  internal::manage_caching_sizes(GetAction, &l1, &l2, &l3);
-  return l2;
-}
-
-/** \returns the currently set level 3 cpu cache size (in bytes) used to estimate the ideal blocking size paramete\
-rs.                                                                                                                
-* \sa setCpuCacheSize */
-inline std::ptrdiff_t l3CacheSize()
-{
-  std::ptrdiff_t l1, l2, l3;
-  internal::manage_caching_sizes(GetAction, &l1, &l2, &l3);
-  return l3;
-}
-
-/** Set the cpu L1 and L2 cache sizes (in bytes).
-  * These values are use to adjust the size of the blocks
-  * for the algorithms working per blocks.
-  *
-  * \sa computeProductBlockingSizes */
-inline void setCpuCacheSizes(std::ptrdiff_t l1, std::ptrdiff_t l2, std::ptrdiff_t l3)
-{
-  internal::manage_caching_sizes(SetAction, &l1, &l2, &l3);
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_GENERAL_BLOCK_PANEL_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/GeneralMatrixMatrix.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/GeneralMatrixMatrix.h
deleted file mode 100644
index 6440e1d..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/GeneralMatrixMatrix.h
+++ /dev/null
@@ -1,492 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_GENERAL_MATRIX_MATRIX_H
-#define EIGEN_GENERAL_MATRIX_MATRIX_H
-
-namespace Eigen {
-
-namespace internal {
-
-template<typename _LhsScalar, typename _RhsScalar> class level3_blocking;
-
-/* Specialization for a row-major destination matrix => simple transposition of the product */
-template<
-  typename Index,
-  typename LhsScalar, int LhsStorageOrder, bool ConjugateLhs,
-  typename RhsScalar, int RhsStorageOrder, bool ConjugateRhs>
-struct general_matrix_matrix_product<Index,LhsScalar,LhsStorageOrder,ConjugateLhs,RhsScalar,RhsStorageOrder,ConjugateRhs,RowMajor>
-{
-  typedef gebp_traits<RhsScalar,LhsScalar> Traits;
-
-  typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar>::ReturnType ResScalar;
-  static EIGEN_STRONG_INLINE void run(
-    Index rows, Index cols, Index depth,
-    const LhsScalar* lhs, Index lhsStride,
-    const RhsScalar* rhs, Index rhsStride,
-    ResScalar* res, Index resStride,
-    ResScalar alpha,
-    level3_blocking<RhsScalar,LhsScalar>& blocking,
-    GemmParallelInfo<Index>* info = 0)
-  {
-    // transpose the product such that the result is column major
-    general_matrix_matrix_product<Index,
-      RhsScalar, RhsStorageOrder==RowMajor ? ColMajor : RowMajor, ConjugateRhs,
-      LhsScalar, LhsStorageOrder==RowMajor ? ColMajor : RowMajor, ConjugateLhs,
-      ColMajor>
-    ::run(cols,rows,depth,rhs,rhsStride,lhs,lhsStride,res,resStride,alpha,blocking,info);
-  }
-};
-
-/*  Specialization for a col-major destination matrix
- *    => Blocking algorithm following Goto's paper */
-template<
-  typename Index,
-  typename LhsScalar, int LhsStorageOrder, bool ConjugateLhs,
-  typename RhsScalar, int RhsStorageOrder, bool ConjugateRhs>
-struct general_matrix_matrix_product<Index,LhsScalar,LhsStorageOrder,ConjugateLhs,RhsScalar,RhsStorageOrder,ConjugateRhs,ColMajor>
-{
-
-typedef gebp_traits<LhsScalar,RhsScalar> Traits;
-
-typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar>::ReturnType ResScalar;
-static void run(Index rows, Index cols, Index depth,
-  const LhsScalar* _lhs, Index lhsStride,
-  const RhsScalar* _rhs, Index rhsStride,
-  ResScalar* _res, Index resStride,
-  ResScalar alpha,
-  level3_blocking<LhsScalar,RhsScalar>& blocking,
-  GemmParallelInfo<Index>* info = 0)
-{
-  typedef const_blas_data_mapper<LhsScalar, Index, LhsStorageOrder> LhsMapper;
-  typedef const_blas_data_mapper<RhsScalar, Index, RhsStorageOrder> RhsMapper;
-  typedef blas_data_mapper<typename Traits::ResScalar, Index, ColMajor> ResMapper;
-  LhsMapper lhs(_lhs,lhsStride);
-  RhsMapper rhs(_rhs,rhsStride);
-  ResMapper res(_res, resStride);
-
-  Index kc = blocking.kc();                   // cache block size along the K direction
-  Index mc = (std::min)(rows,blocking.mc());  // cache block size along the M direction
-  Index nc = (std::min)(cols,blocking.nc());  // cache block size along the N direction
-
-  gemm_pack_lhs<LhsScalar, Index, LhsMapper, Traits::mr, Traits::LhsProgress, LhsStorageOrder> pack_lhs;
-  gemm_pack_rhs<RhsScalar, Index, RhsMapper, Traits::nr, RhsStorageOrder> pack_rhs;
-  gebp_kernel<LhsScalar, RhsScalar, Index, ResMapper, Traits::mr, Traits::nr, ConjugateLhs, ConjugateRhs> gebp;
-
-#ifdef EIGEN_HAS_OPENMP
-  if(info)
-  {
-    // this is the parallel version!
-    int tid = omp_get_thread_num();
-    int threads = omp_get_num_threads();
-
-    LhsScalar* blockA = blocking.blockA();
-    eigen_internal_assert(blockA!=0);
-
-    std::size_t sizeB = kc*nc;
-    ei_declare_aligned_stack_constructed_variable(RhsScalar, blockB, sizeB, 0);
-
-    // For each horizontal panel of the rhs, and corresponding vertical panel of the lhs...
-    for(Index k=0; k<depth; k+=kc)
-    {
-      const Index actual_kc = (std::min)(k+kc,depth)-k; // => rows of B', and cols of the A'
-
-      // In order to reduce the chance that a thread has to wait for the other,
-      // let's start by packing B'.
-      pack_rhs(blockB, rhs.getSubMapper(k,0), actual_kc, nc);
-
-      // Pack A_k to A' in a parallel fashion:
-      // each thread packs the sub block A_k,i to A'_i where i is the thread id.
-
-      // However, before copying to A'_i, we have to make sure that no other thread is still using it,
-      // i.e., we test that info[tid].users equals 0.
-      // Then, we set info[tid].users to the number of threads to mark that all other threads are going to use it.
-      while(info[tid].users!=0) {}
-      info[tid].users += threads;
-
-      pack_lhs(blockA+info[tid].lhs_start*actual_kc, lhs.getSubMapper(info[tid].lhs_start,k), actual_kc, info[tid].lhs_length);
-
-      // Notify the other threads that the part A'_i is ready to go.
-      info[tid].sync = k;
-
-      // Computes C_i += A' * B' per A'_i
-      for(int shift=0; shift<threads; ++shift)
-      {
-        int i = (tid+shift)%threads;
-
-        // At this point we have to make sure that A'_i has been updated by the thread i,
-        // we use testAndSetOrdered to mimic a volatile access.
-        // However, no need to wait for the B' part which has been updated by the current thread!
-        if (shift>0) {
-          while(info[i].sync!=k) {
-          }
-        }
-
-        gebp(res.getSubMapper(info[i].lhs_start, 0), blockA+info[i].lhs_start*actual_kc, blockB, info[i].lhs_length, actual_kc, nc, alpha);
-      }
-
-      // Then keep going as usual with the remaining B'
-      for(Index j=nc; j<cols; j+=nc)
-      {
-        const Index actual_nc = (std::min)(j+nc,cols)-j;
-
-        // pack B_k,j to B'
-        pack_rhs(blockB, rhs.getSubMapper(k,j), actual_kc, actual_nc);
-
-        // C_j += A' * B'
-        gebp(res.getSubMapper(0, j), blockA, blockB, rows, actual_kc, actual_nc, alpha);
-      }
-
-      // Release all the sub blocks A'_i of A' for the current thread,
-      // i.e., we simply decrement the number of users by 1
-      for(Index i=0; i<threads; ++i)
-        #pragma omp atomic
-        info[i].users -= 1;
-    }
-  }
-  else
-#endif // EIGEN_HAS_OPENMP
-  {
-    EIGEN_UNUSED_VARIABLE(info);
-
-    // this is the sequential version!
-    std::size_t sizeA = kc*mc;
-    std::size_t sizeB = kc*nc;
-
-    ei_declare_aligned_stack_constructed_variable(LhsScalar, blockA, sizeA, blocking.blockA());
-    ei_declare_aligned_stack_constructed_variable(RhsScalar, blockB, sizeB, blocking.blockB());
-
-    const bool pack_rhs_once = mc!=rows && kc==depth && nc==cols;
-
-    // For each horizontal panel of the rhs, and corresponding panel of the lhs...
-    for(Index i2=0; i2<rows; i2+=mc)
-    {
-      const Index actual_mc = (std::min)(i2+mc,rows)-i2;
-
-      for(Index k2=0; k2<depth; k2+=kc)
-      {
-        const Index actual_kc = (std::min)(k2+kc,depth)-k2;
-
-        // OK, here we have selected one horizontal panel of rhs and one vertical panel of lhs.
-        // => Pack lhs's panel into a sequential chunk of memory (L2/L3 caching)
-        // Note that this panel will be read as many times as the number of blocks in the rhs's
-        // horizontal panel which is, in practice, a very low number.
-        pack_lhs(blockA, lhs.getSubMapper(i2,k2), actual_kc, actual_mc);
-
-        // For each kc x nc block of the rhs's horizontal panel...
-        for(Index j2=0; j2<cols; j2+=nc)
-        {
-          const Index actual_nc = (std::min)(j2+nc,cols)-j2;
-
-          // We pack the rhs's block into a sequential chunk of memory (L2 caching)
-          // Note that this block will be read a very high number of times, which is equal to the number of
-          // micro horizontal panel of the large rhs's panel (e.g., rows/12 times).
-          if((!pack_rhs_once) || i2==0)
-            pack_rhs(blockB, rhs.getSubMapper(k2,j2), actual_kc, actual_nc);
-
-          // Everything is packed, we can now call the panel * block kernel:
-          gebp(res.getSubMapper(i2, j2), blockA, blockB, actual_mc, actual_kc, actual_nc, alpha);
-        }
-      }
-    }
-  }
-}
-
-};
-
-/*********************************************************************************
-*  Specialization of generic_product_impl for "large" GEMM, i.e.,
-*  implementation of the high level wrapper to general_matrix_matrix_product
-**********************************************************************************/
-
-template<typename Scalar, typename Index, typename Gemm, typename Lhs, typename Rhs, typename Dest, typename BlockingType>
-struct gemm_functor
-{
-  gemm_functor(const Lhs& lhs, const Rhs& rhs, Dest& dest, const Scalar& actualAlpha, BlockingType& blocking)
-    : m_lhs(lhs), m_rhs(rhs), m_dest(dest), m_actualAlpha(actualAlpha), m_blocking(blocking)
-  {}
-
-  void initParallelSession(Index num_threads) const
-  {
-    m_blocking.initParallel(m_lhs.rows(), m_rhs.cols(), m_lhs.cols(), num_threads);
-    m_blocking.allocateA();
-  }
-
-  void operator() (Index row, Index rows, Index col=0, Index cols=-1, GemmParallelInfo<Index>* info=0) const
-  {
-    if(cols==-1)
-      cols = m_rhs.cols();
-
-    Gemm::run(rows, cols, m_lhs.cols(),
-              &m_lhs.coeffRef(row,0), m_lhs.outerStride(),
-              &m_rhs.coeffRef(0,col), m_rhs.outerStride(),
-              (Scalar*)&(m_dest.coeffRef(row,col)), m_dest.outerStride(),
-              m_actualAlpha, m_blocking, info);
-  }
-
-  typedef typename Gemm::Traits Traits;
-
-  protected:
-    const Lhs& m_lhs;
-    const Rhs& m_rhs;
-    Dest& m_dest;
-    Scalar m_actualAlpha;
-    BlockingType& m_blocking;
-};
-
-template<int StorageOrder, typename LhsScalar, typename RhsScalar, int MaxRows, int MaxCols, int MaxDepth, int KcFactor=1,
-bool FiniteAtCompileTime = MaxRows!=Dynamic && MaxCols!=Dynamic && MaxDepth != Dynamic> class gemm_blocking_space;
-
-template<typename _LhsScalar, typename _RhsScalar>
-class level3_blocking
-{
-    typedef _LhsScalar LhsScalar;
-    typedef _RhsScalar RhsScalar;
-
-  protected:
-    LhsScalar* m_blockA;
-    RhsScalar* m_blockB;
-
-    Index m_mc;
-    Index m_nc;
-    Index m_kc;
-
-  public:
-
-    level3_blocking()
-      : m_blockA(0), m_blockB(0), m_mc(0), m_nc(0), m_kc(0)
-    {}
-
-    inline Index mc() const { return m_mc; }
-    inline Index nc() const { return m_nc; }
-    inline Index kc() const { return m_kc; }
-
-    inline LhsScalar* blockA() { return m_blockA; }
-    inline RhsScalar* blockB() { return m_blockB; }
-};
-
-template<int StorageOrder, typename _LhsScalar, typename _RhsScalar, int MaxRows, int MaxCols, int MaxDepth, int KcFactor>
-class gemm_blocking_space<StorageOrder,_LhsScalar,_RhsScalar,MaxRows, MaxCols, MaxDepth, KcFactor, true /* == FiniteAtCompileTime */>
-  : public level3_blocking<
-      typename conditional<StorageOrder==RowMajor,_RhsScalar,_LhsScalar>::type,
-      typename conditional<StorageOrder==RowMajor,_LhsScalar,_RhsScalar>::type>
-{
-    enum {
-      Transpose = StorageOrder==RowMajor,
-      ActualRows = Transpose ? MaxCols : MaxRows,
-      ActualCols = Transpose ? MaxRows : MaxCols
-    };
-    typedef typename conditional<Transpose,_RhsScalar,_LhsScalar>::type LhsScalar;
-    typedef typename conditional<Transpose,_LhsScalar,_RhsScalar>::type RhsScalar;
-    typedef gebp_traits<LhsScalar,RhsScalar> Traits;
-    enum {
-      SizeA = ActualRows * MaxDepth,
-      SizeB = ActualCols * MaxDepth
-    };
-
-#if EIGEN_MAX_STATIC_ALIGN_BYTES >= EIGEN_DEFAULT_ALIGN_BYTES
-    EIGEN_ALIGN_MAX LhsScalar m_staticA[SizeA];
-    EIGEN_ALIGN_MAX RhsScalar m_staticB[SizeB];
-#else
-    EIGEN_ALIGN_MAX char m_staticA[SizeA * sizeof(LhsScalar) + EIGEN_DEFAULT_ALIGN_BYTES-1];
-    EIGEN_ALIGN_MAX char m_staticB[SizeB * sizeof(RhsScalar) + EIGEN_DEFAULT_ALIGN_BYTES-1];
-#endif
-
-  public:
-
-    gemm_blocking_space(Index /*rows*/, Index /*cols*/, Index /*depth*/, Index /*num_threads*/, bool /*full_rows = false*/)
-    {
-      this->m_mc = ActualRows;
-      this->m_nc = ActualCols;
-      this->m_kc = MaxDepth;
-#if EIGEN_MAX_STATIC_ALIGN_BYTES >= EIGEN_DEFAULT_ALIGN_BYTES
-      this->m_blockA = m_staticA;
-      this->m_blockB = m_staticB;
-#else
-      this->m_blockA = reinterpret_cast<LhsScalar*>((internal::UIntPtr(m_staticA) + (EIGEN_DEFAULT_ALIGN_BYTES-1)) & ~std::size_t(EIGEN_DEFAULT_ALIGN_BYTES-1));
-      this->m_blockB = reinterpret_cast<RhsScalar*>((internal::UIntPtr(m_staticB) + (EIGEN_DEFAULT_ALIGN_BYTES-1)) & ~std::size_t(EIGEN_DEFAULT_ALIGN_BYTES-1));
-#endif
-    }
-
-    void initParallel(Index, Index, Index, Index)
-    {}
-
-    inline void allocateA() {}
-    inline void allocateB() {}
-    inline void allocateAll() {}
-};
-
-template<int StorageOrder, typename _LhsScalar, typename _RhsScalar, int MaxRows, int MaxCols, int MaxDepth, int KcFactor>
-class gemm_blocking_space<StorageOrder,_LhsScalar,_RhsScalar,MaxRows, MaxCols, MaxDepth, KcFactor, false>
-  : public level3_blocking<
-      typename conditional<StorageOrder==RowMajor,_RhsScalar,_LhsScalar>::type,
-      typename conditional<StorageOrder==RowMajor,_LhsScalar,_RhsScalar>::type>
-{
-    enum {
-      Transpose = StorageOrder==RowMajor
-    };
-    typedef typename conditional<Transpose,_RhsScalar,_LhsScalar>::type LhsScalar;
-    typedef typename conditional<Transpose,_LhsScalar,_RhsScalar>::type RhsScalar;
-    typedef gebp_traits<LhsScalar,RhsScalar> Traits;
-
-    Index m_sizeA;
-    Index m_sizeB;
-
-  public:
-
-    gemm_blocking_space(Index rows, Index cols, Index depth, Index num_threads, bool l3_blocking)
-    {
-      this->m_mc = Transpose ? cols : rows;
-      this->m_nc = Transpose ? rows : cols;
-      this->m_kc = depth;
-
-      if(l3_blocking)
-      {
-        computeProductBlockingSizes<LhsScalar,RhsScalar,KcFactor>(this->m_kc, this->m_mc, this->m_nc, num_threads);
-      }
-      else  // no l3 blocking
-      {
-        Index n = this->m_nc;
-        computeProductBlockingSizes<LhsScalar,RhsScalar,KcFactor>(this->m_kc, this->m_mc, n, num_threads);
-      }
-
-      m_sizeA = this->m_mc * this->m_kc;
-      m_sizeB = this->m_kc * this->m_nc;
-    }
-
-    void initParallel(Index rows, Index cols, Index depth, Index num_threads)
-    {
-      this->m_mc = Transpose ? cols : rows;
-      this->m_nc = Transpose ? rows : cols;
-      this->m_kc = depth;
-
-      eigen_internal_assert(this->m_blockA==0 && this->m_blockB==0);
-      Index m = this->m_mc;
-      computeProductBlockingSizes<LhsScalar,RhsScalar,KcFactor>(this->m_kc, m, this->m_nc, num_threads);
-      m_sizeA = this->m_mc * this->m_kc;
-      m_sizeB = this->m_kc * this->m_nc;
-    }
-
-    void allocateA()
-    {
-      if(this->m_blockA==0)
-        this->m_blockA = aligned_new<LhsScalar>(m_sizeA);
-    }
-
-    void allocateB()
-    {
-      if(this->m_blockB==0)
-        this->m_blockB = aligned_new<RhsScalar>(m_sizeB);
-    }
-
-    void allocateAll()
-    {
-      allocateA();
-      allocateB();
-    }
-
-    ~gemm_blocking_space()
-    {
-      aligned_delete(this->m_blockA, m_sizeA);
-      aligned_delete(this->m_blockB, m_sizeB);
-    }
-};
-
-} // end namespace internal
-
-namespace internal {
-
-template<typename Lhs, typename Rhs>
-struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,GemmProduct>
-  : generic_product_impl_base<Lhs,Rhs,generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,GemmProduct> >
-{
-  typedef typename Product<Lhs,Rhs>::Scalar Scalar;
-  typedef typename Lhs::Scalar LhsScalar;
-  typedef typename Rhs::Scalar RhsScalar;
-
-  typedef internal::blas_traits<Lhs> LhsBlasTraits;
-  typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType;
-  typedef typename internal::remove_all<ActualLhsType>::type ActualLhsTypeCleaned;
-
-  typedef internal::blas_traits<Rhs> RhsBlasTraits;
-  typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType;
-  typedef typename internal::remove_all<ActualRhsType>::type ActualRhsTypeCleaned;
-
-  enum {
-    MaxDepthAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(Lhs::MaxColsAtCompileTime,Rhs::MaxRowsAtCompileTime)
-  };
-
-  typedef generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,CoeffBasedProductMode> lazyproduct;
-
-  template<typename Dst>
-  static void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
-  {
-    if((rhs.rows()+dst.rows()+dst.cols())<20 && rhs.rows()>0)
-      lazyproduct::evalTo(dst, lhs, rhs);
-    else
-    {
-      dst.setZero();
-      scaleAndAddTo(dst, lhs, rhs, Scalar(1));
-    }
-  }
-
-  template<typename Dst>
-  static void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
-  {
-    if((rhs.rows()+dst.rows()+dst.cols())<20 && rhs.rows()>0)
-      lazyproduct::addTo(dst, lhs, rhs);
-    else
-      scaleAndAddTo(dst,lhs, rhs, Scalar(1));
-  }
-
-  template<typename Dst>
-  static void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
-  {
-    if((rhs.rows()+dst.rows()+dst.cols())<20 && rhs.rows()>0)
-      lazyproduct::subTo(dst, lhs, rhs);
-    else
-      scaleAndAddTo(dst, lhs, rhs, Scalar(-1));
-  }
-
-  template<typename Dest>
-  static void scaleAndAddTo(Dest& dst, const Lhs& a_lhs, const Rhs& a_rhs, const Scalar& alpha)
-  {
-    eigen_assert(dst.rows()==a_lhs.rows() && dst.cols()==a_rhs.cols());
-    if(a_lhs.cols()==0 || a_lhs.rows()==0 || a_rhs.cols()==0)
-      return;
-
-    typename internal::add_const_on_value_type<ActualLhsType>::type lhs = LhsBlasTraits::extract(a_lhs);
-    typename internal::add_const_on_value_type<ActualRhsType>::type rhs = RhsBlasTraits::extract(a_rhs);
-
-    Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(a_lhs)
-                               * RhsBlasTraits::extractScalarFactor(a_rhs);
-
-    typedef internal::gemm_blocking_space<(Dest::Flags&RowMajorBit) ? RowMajor : ColMajor,LhsScalar,RhsScalar,
-            Dest::MaxRowsAtCompileTime,Dest::MaxColsAtCompileTime,MaxDepthAtCompileTime> BlockingType;
-
-    typedef internal::gemm_functor<
-      Scalar, Index,
-      internal::general_matrix_matrix_product<
-        Index,
-        LhsScalar, (ActualLhsTypeCleaned::Flags&RowMajorBit) ? RowMajor : ColMajor, bool(LhsBlasTraits::NeedToConjugate),
-        RhsScalar, (ActualRhsTypeCleaned::Flags&RowMajorBit) ? RowMajor : ColMajor, bool(RhsBlasTraits::NeedToConjugate),
-        (Dest::Flags&RowMajorBit) ? RowMajor : ColMajor>,
-      ActualLhsTypeCleaned, ActualRhsTypeCleaned, Dest, BlockingType> GemmFunctor;
-
-    BlockingType blocking(dst.rows(), dst.cols(), lhs.cols(), 1, true);
-    internal::parallelize_gemm<(Dest::MaxRowsAtCompileTime>32 || Dest::MaxRowsAtCompileTime==Dynamic)>
-        (GemmFunctor(lhs, rhs, dst, actualAlpha, blocking), a_lhs.rows(), a_rhs.cols(), a_lhs.cols(), Dest::Flags&RowMajorBit);
-  }
-};
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_GENERAL_MATRIX_MATRIX_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h
deleted file mode 100644
index e844e37..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h
+++ /dev/null
@@ -1,311 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_H
-#define EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_H
-
-namespace Eigen { 
-
-template<typename Scalar, typename Index, int StorageOrder, int UpLo, bool ConjLhs, bool ConjRhs>
-struct selfadjoint_rank1_update;
-
-namespace internal {
-
-/**********************************************************************
-* This file implements a general A * B product while
-* evaluating only one triangular part of the product.
-* This is a more general version of self adjoint product (C += A A^T)
-* as the level 3 SYRK Blas routine.
-**********************************************************************/
-
-// forward declarations (defined at the end of this file)
-template<typename LhsScalar, typename RhsScalar, typename Index, int mr, int nr, bool ConjLhs, bool ConjRhs, int UpLo>
-struct tribb_kernel;
-  
-/* Optimized matrix-matrix product evaluating only one triangular half */
-template <typename Index,
-          typename LhsScalar, int LhsStorageOrder, bool ConjugateLhs,
-          typename RhsScalar, int RhsStorageOrder, bool ConjugateRhs,
-                              int ResStorageOrder, int  UpLo, int Version = Specialized>
-struct general_matrix_matrix_triangular_product;
-
-// as usual if the result is row major => we transpose the product
-template <typename Index, typename LhsScalar, int LhsStorageOrder, bool ConjugateLhs,
-                          typename RhsScalar, int RhsStorageOrder, bool ConjugateRhs, int  UpLo, int Version>
-struct general_matrix_matrix_triangular_product<Index,LhsScalar,LhsStorageOrder,ConjugateLhs,RhsScalar,RhsStorageOrder,ConjugateRhs,RowMajor,UpLo,Version>
-{
-  typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar>::ReturnType ResScalar;
-  static EIGEN_STRONG_INLINE void run(Index size, Index depth,const LhsScalar* lhs, Index lhsStride,
-                                      const RhsScalar* rhs, Index rhsStride, ResScalar* res, Index resStride,
-                                      const ResScalar& alpha, level3_blocking<RhsScalar,LhsScalar>& blocking)
-  {
-    general_matrix_matrix_triangular_product<Index,
-        RhsScalar, RhsStorageOrder==RowMajor ? ColMajor : RowMajor, ConjugateRhs,
-        LhsScalar, LhsStorageOrder==RowMajor ? ColMajor : RowMajor, ConjugateLhs,
-        ColMajor, UpLo==Lower?Upper:Lower>
-      ::run(size,depth,rhs,rhsStride,lhs,lhsStride,res,resStride,alpha,blocking);
-  }
-};
-
-template <typename Index, typename LhsScalar, int LhsStorageOrder, bool ConjugateLhs,
-                          typename RhsScalar, int RhsStorageOrder, bool ConjugateRhs, int  UpLo, int Version>
-struct general_matrix_matrix_triangular_product<Index,LhsScalar,LhsStorageOrder,ConjugateLhs,RhsScalar,RhsStorageOrder,ConjugateRhs,ColMajor,UpLo,Version>
-{
-  typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar>::ReturnType ResScalar;
-  static EIGEN_STRONG_INLINE void run(Index size, Index depth,const LhsScalar* _lhs, Index lhsStride,
-                                      const RhsScalar* _rhs, Index rhsStride, ResScalar* _res, Index resStride,
-                                      const ResScalar& alpha, level3_blocking<LhsScalar,RhsScalar>& blocking)
-  {
-    typedef gebp_traits<LhsScalar,RhsScalar> Traits;
-
-    typedef const_blas_data_mapper<LhsScalar, Index, LhsStorageOrder> LhsMapper;
-    typedef const_blas_data_mapper<RhsScalar, Index, RhsStorageOrder> RhsMapper;
-    typedef blas_data_mapper<typename Traits::ResScalar, Index, ColMajor> ResMapper;
-    LhsMapper lhs(_lhs,lhsStride);
-    RhsMapper rhs(_rhs,rhsStride);
-    ResMapper res(_res, resStride);
-
-    Index kc = blocking.kc();
-    Index mc = (std::min)(size,blocking.mc());
-
-    // !!! mc must be a multiple of nr:
-    if(mc > Traits::nr)
-      mc = (mc/Traits::nr)*Traits::nr;
-
-    std::size_t sizeA = kc*mc;
-    std::size_t sizeB = kc*size;
-
-    ei_declare_aligned_stack_constructed_variable(LhsScalar, blockA, sizeA, blocking.blockA());
-    ei_declare_aligned_stack_constructed_variable(RhsScalar, blockB, sizeB, blocking.blockB());
-
-    gemm_pack_lhs<LhsScalar, Index, LhsMapper, Traits::mr, Traits::LhsProgress, LhsStorageOrder> pack_lhs;
-    gemm_pack_rhs<RhsScalar, Index, RhsMapper, Traits::nr, RhsStorageOrder> pack_rhs;
-    gebp_kernel<LhsScalar, RhsScalar, Index, ResMapper, Traits::mr, Traits::nr, ConjugateLhs, ConjugateRhs> gebp;
-    tribb_kernel<LhsScalar, RhsScalar, Index, Traits::mr, Traits::nr, ConjugateLhs, ConjugateRhs, UpLo> sybb;
-
-    for(Index k2=0; k2<depth; k2+=kc)
-    {
-      const Index actual_kc = (std::min)(k2+kc,depth)-k2;
-
-      // note that the actual rhs is the transpose/adjoint of mat
-      pack_rhs(blockB, rhs.getSubMapper(k2,0), actual_kc, size);
-
-      for(Index i2=0; i2<size; i2+=mc)
-      {
-        const Index actual_mc = (std::min)(i2+mc,size)-i2;
-
-        pack_lhs(blockA, lhs.getSubMapper(i2, k2), actual_kc, actual_mc);
-
-        // the selected actual_mc * size panel of res is split into three different part:
-        //  1 - before the diagonal => processed with gebp or skipped
-        //  2 - the actual_mc x actual_mc symmetric block => processed with a special kernel
-        //  3 - after the diagonal => processed with gebp or skipped
-        if (UpLo==Lower)
-          gebp(res.getSubMapper(i2, 0), blockA, blockB, actual_mc, actual_kc,
-               (std::min)(size,i2), alpha, -1, -1, 0, 0);
-
-
-        sybb(_res+resStride*i2 + i2, resStride, blockA, blockB + actual_kc*i2, actual_mc, actual_kc, alpha);
-
-        if (UpLo==Upper)
-        {
-          Index j2 = i2+actual_mc;
-          gebp(res.getSubMapper(i2, j2), blockA, blockB+actual_kc*j2, actual_mc,
-               actual_kc, (std::max)(Index(0), size-j2), alpha, -1, -1, 0, 0);
-        }
-      }
-    }
-  }
-};
-
-// Optimized packed Block * packed Block product kernel evaluating only one given triangular part
-// This kernel is built on top of the gebp kernel:
-// - the current destination block is processed per panel of actual_mc x BlockSize
-//   where BlockSize is set to the minimal value allowing gebp to be as fast as possible
-// - then, as usual, each panel is split into three parts along the diagonal,
-//   the sub blocks above and below the diagonal are processed as usual,
-//   while the triangular block overlapping the diagonal is evaluated into a
-//   small temporary buffer which is then accumulated into the result using a
-//   triangular traversal.
-template<typename LhsScalar, typename RhsScalar, typename Index, int mr, int nr, bool ConjLhs, bool ConjRhs, int UpLo>
-struct tribb_kernel
-{
-  typedef gebp_traits<LhsScalar,RhsScalar,ConjLhs,ConjRhs> Traits;
-  typedef typename Traits::ResScalar ResScalar;
-
-  enum {
-    BlockSize  = meta_least_common_multiple<EIGEN_PLAIN_ENUM_MAX(mr,nr),EIGEN_PLAIN_ENUM_MIN(mr,nr)>::ret
-  };
-  void operator()(ResScalar* _res, Index resStride, const LhsScalar* blockA, const RhsScalar* blockB, Index size, Index depth, const ResScalar& alpha)
-  {
-    typedef blas_data_mapper<ResScalar, Index, ColMajor> ResMapper;
-    ResMapper res(_res, resStride);
-    gebp_kernel<LhsScalar, RhsScalar, Index, ResMapper, mr, nr, ConjLhs, ConjRhs> gebp_kernel;
-
-    Matrix<ResScalar,BlockSize,BlockSize,ColMajor> buffer((internal::constructor_without_unaligned_array_assert()));
-
-    // let's process the block per panel of actual_mc x BlockSize,
-    // again, each is split into three parts, etc.
-    for (Index j=0; j<size; j+=BlockSize)
-    {
-      Index actualBlockSize = std::min<Index>(BlockSize,size - j);
-      const RhsScalar* actual_b = blockB+j*depth;
-
-      if(UpLo==Upper)
-        gebp_kernel(res.getSubMapper(0, j), blockA, actual_b, j, depth, actualBlockSize, alpha,
-                    -1, -1, 0, 0);
-
-      // selfadjoint micro block
-      {
-        Index i = j;
-        buffer.setZero();
-        // 1 - apply the kernel on the temporary buffer
-        gebp_kernel(ResMapper(buffer.data(), BlockSize), blockA+depth*i, actual_b, actualBlockSize, depth, actualBlockSize, alpha,
-                    -1, -1, 0, 0);
-        // 2 - triangular accumulation
-        for(Index j1=0; j1<actualBlockSize; ++j1)
-        {
-          ResScalar* r = &res(i, j + j1);
-          for(Index i1=UpLo==Lower ? j1 : 0;
-              UpLo==Lower ? i1<actualBlockSize : i1<=j1; ++i1)
-            r[i1] += buffer(i1,j1);
-        }
-      }
-
-      if(UpLo==Lower)
-      {
-        Index i = j+actualBlockSize;
-        gebp_kernel(res.getSubMapper(i, j), blockA+depth*i, actual_b, size-i, 
-                    depth, actualBlockSize, alpha, -1, -1, 0, 0);
-      }
-    }
-  }
-};
-
-} // end namespace internal
-
-// high level API
-
-template<typename MatrixType, typename ProductType, int UpLo, bool IsOuterProduct>
-struct general_product_to_triangular_selector;
-
-
-template<typename MatrixType, typename ProductType, int UpLo>
-struct general_product_to_triangular_selector<MatrixType,ProductType,UpLo,true>
-{
-  static void run(MatrixType& mat, const ProductType& prod, const typename MatrixType::Scalar& alpha, bool beta)
-  {
-    typedef typename MatrixType::Scalar Scalar;
-    
-    typedef typename internal::remove_all<typename ProductType::LhsNested>::type Lhs;
-    typedef internal::blas_traits<Lhs> LhsBlasTraits;
-    typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhs;
-    typedef typename internal::remove_all<ActualLhs>::type _ActualLhs;
-    typename internal::add_const_on_value_type<ActualLhs>::type actualLhs = LhsBlasTraits::extract(prod.lhs());
-    
-    typedef typename internal::remove_all<typename ProductType::RhsNested>::type Rhs;
-    typedef internal::blas_traits<Rhs> RhsBlasTraits;
-    typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhs;
-    typedef typename internal::remove_all<ActualRhs>::type _ActualRhs;
-    typename internal::add_const_on_value_type<ActualRhs>::type actualRhs = RhsBlasTraits::extract(prod.rhs());
-
-    Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs().derived()) * RhsBlasTraits::extractScalarFactor(prod.rhs().derived());
-
-    if(!beta)
-      mat.template triangularView<UpLo>().setZero();
-
-    enum {
-      StorageOrder = (internal::traits<MatrixType>::Flags&RowMajorBit) ? RowMajor : ColMajor,
-      UseLhsDirectly = _ActualLhs::InnerStrideAtCompileTime==1,
-      UseRhsDirectly = _ActualRhs::InnerStrideAtCompileTime==1
-    };
-    
-    internal::gemv_static_vector_if<Scalar,Lhs::SizeAtCompileTime,Lhs::MaxSizeAtCompileTime,!UseLhsDirectly> static_lhs;
-    ei_declare_aligned_stack_constructed_variable(Scalar, actualLhsPtr, actualLhs.size(),
-      (UseLhsDirectly ? const_cast<Scalar*>(actualLhs.data()) : static_lhs.data()));
-    if(!UseLhsDirectly) Map<typename _ActualLhs::PlainObject>(actualLhsPtr, actualLhs.size()) = actualLhs;
-    
-    internal::gemv_static_vector_if<Scalar,Rhs::SizeAtCompileTime,Rhs::MaxSizeAtCompileTime,!UseRhsDirectly> static_rhs;
-    ei_declare_aligned_stack_constructed_variable(Scalar, actualRhsPtr, actualRhs.size(),
-      (UseRhsDirectly ? const_cast<Scalar*>(actualRhs.data()) : static_rhs.data()));
-    if(!UseRhsDirectly) Map<typename _ActualRhs::PlainObject>(actualRhsPtr, actualRhs.size()) = actualRhs;
-    
-    
-    selfadjoint_rank1_update<Scalar,Index,StorageOrder,UpLo,
-                              LhsBlasTraits::NeedToConjugate && NumTraits<Scalar>::IsComplex,
-                              RhsBlasTraits::NeedToConjugate && NumTraits<Scalar>::IsComplex>
-          ::run(actualLhs.size(), mat.data(), mat.outerStride(), actualLhsPtr, actualRhsPtr, actualAlpha);
-  }
-};
-
-template<typename MatrixType, typename ProductType, int UpLo>
-struct general_product_to_triangular_selector<MatrixType,ProductType,UpLo,false>
-{
-  static void run(MatrixType& mat, const ProductType& prod, const typename MatrixType::Scalar& alpha, bool beta)
-  {
-    typedef typename internal::remove_all<typename ProductType::LhsNested>::type Lhs;
-    typedef internal::blas_traits<Lhs> LhsBlasTraits;
-    typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhs;
-    typedef typename internal::remove_all<ActualLhs>::type _ActualLhs;
-    typename internal::add_const_on_value_type<ActualLhs>::type actualLhs = LhsBlasTraits::extract(prod.lhs());
-    
-    typedef typename internal::remove_all<typename ProductType::RhsNested>::type Rhs;
-    typedef internal::blas_traits<Rhs> RhsBlasTraits;
-    typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhs;
-    typedef typename internal::remove_all<ActualRhs>::type _ActualRhs;
-    typename internal::add_const_on_value_type<ActualRhs>::type actualRhs = RhsBlasTraits::extract(prod.rhs());
-
-    typename ProductType::Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs().derived()) * RhsBlasTraits::extractScalarFactor(prod.rhs().derived());
-
-    if(!beta)
-      mat.template triangularView<UpLo>().setZero();
-
-    enum {
-      IsRowMajor = (internal::traits<MatrixType>::Flags&RowMajorBit) ? 1 : 0,
-      LhsIsRowMajor = _ActualLhs::Flags&RowMajorBit ? 1 : 0,
-      RhsIsRowMajor = _ActualRhs::Flags&RowMajorBit ? 1 : 0,
-      SkipDiag = (UpLo&(UnitDiag|ZeroDiag))!=0
-    };
-
-    Index size = mat.cols();
-    if(SkipDiag)
-      size--;
-    Index depth = actualLhs.cols();
-
-    typedef internal::gemm_blocking_space<IsRowMajor ? RowMajor : ColMajor,typename Lhs::Scalar,typename Rhs::Scalar,
-          MatrixType::MaxColsAtCompileTime, MatrixType::MaxColsAtCompileTime, _ActualRhs::MaxColsAtCompileTime> BlockingType;
-
-    BlockingType blocking(size, size, depth, 1, false);
-
-    internal::general_matrix_matrix_triangular_product<Index,
-      typename Lhs::Scalar, LhsIsRowMajor ? RowMajor : ColMajor, LhsBlasTraits::NeedToConjugate,
-      typename Rhs::Scalar, RhsIsRowMajor ? RowMajor : ColMajor, RhsBlasTraits::NeedToConjugate,
-      IsRowMajor ? RowMajor : ColMajor, UpLo&(Lower|Upper)>
-      ::run(size, depth,
-            &actualLhs.coeffRef(SkipDiag&&(UpLo&Lower)==Lower ? 1 : 0,0), actualLhs.outerStride(),
-            &actualRhs.coeffRef(0,SkipDiag&&(UpLo&Upper)==Upper ? 1 : 0), actualRhs.outerStride(),
-            mat.data() + (SkipDiag ? (bool(IsRowMajor) != ((UpLo&Lower)==Lower) ? 1 : mat.outerStride() ) : 0), mat.outerStride(), actualAlpha, blocking);
-  }
-};
-
-template<typename MatrixType, unsigned int UpLo>
-template<typename ProductType>
-TriangularView<MatrixType,UpLo>& TriangularViewImpl<MatrixType,UpLo,Dense>::_assignProduct(const ProductType& prod, const Scalar& alpha, bool beta)
-{
-  EIGEN_STATIC_ASSERT((UpLo&UnitDiag)==0, WRITING_TO_TRIANGULAR_PART_WITH_UNIT_DIAGONAL_IS_NOT_SUPPORTED);
-  eigen_assert(derived().nestedExpression().rows() == prod.rows() && derived().cols() == prod.cols());
-  
-  general_product_to_triangular_selector<MatrixType, ProductType, UpLo, internal::traits<ProductType>::InnerSize==1>::run(derived().nestedExpression().const_cast_derived(), prod, alpha, beta);
-  
-  return derived();
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/GeneralMatrixVector.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/GeneralMatrixVector.h
deleted file mode 100644
index a597c1f..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/GeneralMatrixVector.h
+++ /dev/null
@@ -1,619 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_GENERAL_MATRIX_VECTOR_H
-#define EIGEN_GENERAL_MATRIX_VECTOR_H
-
-namespace Eigen {
-
-namespace internal {
-
-/* Optimized col-major matrix * vector product:
- * This algorithm processes 4 columns at onces that allows to both reduce
- * the number of load/stores of the result by a factor 4 and to reduce
- * the instruction dependency. Moreover, we know that all bands have the
- * same alignment pattern.
- *
- * Mixing type logic: C += alpha * A * B
- *  |  A  |  B  |alpha| comments
- *  |real |cplx |cplx | no vectorization
- *  |real |cplx |real | alpha is converted to a cplx when calling the run function, no vectorization
- *  |cplx |real |cplx | invalid, the caller has to do tmp: = A * B; C += alpha*tmp
- *  |cplx |real |real | optimal case, vectorization possible via real-cplx mul
- *
- * Accesses to the matrix coefficients follow the following logic:
- *
- * - if all columns have the same alignment then
- *   - if the columns have the same alignment as the result vector, then easy! (-> AllAligned case)
- *   - otherwise perform unaligned loads only (-> NoneAligned case)
- * - otherwise
- *   - if even columns have the same alignment then
- *     // odd columns are guaranteed to have the same alignment too
- *     - if even or odd columns have the same alignment as the result, then
- *       // for a register size of 2 scalars, this is guarantee to be the case (e.g., SSE with double)
- *       - perform half aligned and half unaligned loads (-> EvenAligned case)
- *     - otherwise perform unaligned loads only (-> NoneAligned case)
- *   - otherwise, if the register size is 4 scalars (e.g., SSE with float) then
- *     - one over 4 consecutive columns is guaranteed to be aligned with the result vector,
- *       perform simple aligned loads for this column and aligned loads plus re-alignment for the other. (-> FirstAligned case)
- *       // this re-alignment is done by the palign function implemented for SSE in Eigen/src/Core/arch/SSE/PacketMath.h
- *   - otherwise,
- *     // if we get here, this means the register size is greater than 4 (e.g., AVX with floats),
- *     // we currently fall back to the NoneAligned case
- *
- * The same reasoning apply for the transposed case.
- *
- * The last case (PacketSize>4) could probably be improved by generalizing the FirstAligned case, but since we do not support AVX yet...
- * One might also wonder why in the EvenAligned case we perform unaligned loads instead of using the aligned-loads plus re-alignment
- * strategy as in the FirstAligned case. The reason is that we observed that unaligned loads on a 8 byte boundary are not too slow
- * compared to unaligned loads on a 4 byte boundary.
- *
- */
-template<typename Index, typename LhsScalar, typename LhsMapper, bool ConjugateLhs, typename RhsScalar, typename RhsMapper, bool ConjugateRhs, int Version>
-struct general_matrix_vector_product<Index,LhsScalar,LhsMapper,ColMajor,ConjugateLhs,RhsScalar,RhsMapper,ConjugateRhs,Version>
-{
-  typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar>::ReturnType ResScalar;
-
-enum {
-  Vectorizable = packet_traits<LhsScalar>::Vectorizable && packet_traits<RhsScalar>::Vectorizable
-              && int(packet_traits<LhsScalar>::size)==int(packet_traits<RhsScalar>::size),
-  LhsPacketSize = Vectorizable ? packet_traits<LhsScalar>::size : 1,
-  RhsPacketSize = Vectorizable ? packet_traits<RhsScalar>::size : 1,
-  ResPacketSize = Vectorizable ? packet_traits<ResScalar>::size : 1
-};
-
-typedef typename packet_traits<LhsScalar>::type  _LhsPacket;
-typedef typename packet_traits<RhsScalar>::type  _RhsPacket;
-typedef typename packet_traits<ResScalar>::type  _ResPacket;
-
-typedef typename conditional<Vectorizable,_LhsPacket,LhsScalar>::type LhsPacket;
-typedef typename conditional<Vectorizable,_RhsPacket,RhsScalar>::type RhsPacket;
-typedef typename conditional<Vectorizable,_ResPacket,ResScalar>::type ResPacket;
-
-EIGEN_DONT_INLINE static void run(
-  Index rows, Index cols,
-  const LhsMapper& lhs,
-  const RhsMapper& rhs,
-        ResScalar* res, Index resIncr,
-  RhsScalar alpha);
-};
-
-template<typename Index, typename LhsScalar, typename LhsMapper, bool ConjugateLhs, typename RhsScalar, typename RhsMapper, bool ConjugateRhs, int Version>
-EIGEN_DONT_INLINE void general_matrix_vector_product<Index,LhsScalar,LhsMapper,ColMajor,ConjugateLhs,RhsScalar,RhsMapper,ConjugateRhs,Version>::run(
-  Index rows, Index cols,
-  const LhsMapper& lhs,
-  const RhsMapper& rhs,
-        ResScalar* res, Index resIncr,
-  RhsScalar alpha)
-{
-  EIGEN_UNUSED_VARIABLE(resIncr);
-  eigen_internal_assert(resIncr==1);
-  #ifdef _EIGEN_ACCUMULATE_PACKETS
-  #error _EIGEN_ACCUMULATE_PACKETS has already been defined
-  #endif
-  #define _EIGEN_ACCUMULATE_PACKETS(Alignment0,Alignment13,Alignment2) \
-    pstore(&res[j], \
-      padd(pload<ResPacket>(&res[j]), \
-        padd( \
-      padd(pcj.pmul(lhs0.template load<LhsPacket, Alignment0>(j),    ptmp0), \
-      pcj.pmul(lhs1.template load<LhsPacket, Alignment13>(j),   ptmp1)),   \
-      padd(pcj.pmul(lhs2.template load<LhsPacket, Alignment2>(j),    ptmp2), \
-      pcj.pmul(lhs3.template load<LhsPacket, Alignment13>(j),   ptmp3)) )))
-
-  typedef typename LhsMapper::VectorMapper LhsScalars;
-
-  conj_helper<LhsScalar,RhsScalar,ConjugateLhs,ConjugateRhs> cj;
-  conj_helper<LhsPacket,RhsPacket,ConjugateLhs,ConjugateRhs> pcj;
-  if(ConjugateRhs)
-    alpha = numext::conj(alpha);
-
-  enum { AllAligned = 0, EvenAligned, FirstAligned, NoneAligned };
-  const Index columnsAtOnce = 4;
-  const Index peels = 2;
-  const Index LhsPacketAlignedMask = LhsPacketSize-1;
-  const Index ResPacketAlignedMask = ResPacketSize-1;
-//  const Index PeelAlignedMask = ResPacketSize*peels-1;
-  const Index size = rows;
-
-  const Index lhsStride = lhs.stride();
-
-  // How many coeffs of the result do we have to skip to be aligned.
-  // Here we assume data are at least aligned on the base scalar type.
-  Index alignedStart = internal::first_default_aligned(res,size);
-  Index alignedSize = ResPacketSize>1 ? alignedStart + ((size-alignedStart) & ~ResPacketAlignedMask) : 0;
-  const Index peeledSize = alignedSize - RhsPacketSize*peels - RhsPacketSize + 1;
-
-  const Index alignmentStep = LhsPacketSize>1 ? (LhsPacketSize - lhsStride % LhsPacketSize) & LhsPacketAlignedMask : 0;
-  Index alignmentPattern = alignmentStep==0 ? AllAligned
-                       : alignmentStep==(LhsPacketSize/2) ? EvenAligned
-                       : FirstAligned;
-
-  // we cannot assume the first element is aligned because of sub-matrices
-  const Index lhsAlignmentOffset = lhs.firstAligned(size);
-
-  // find how many columns do we have to skip to be aligned with the result (if possible)
-  Index skipColumns = 0;
-  // if the data cannot be aligned (TODO add some compile time tests when possible, e.g. for floats)
-  if( (lhsAlignmentOffset < 0) || (lhsAlignmentOffset == size) || (UIntPtr(res)%sizeof(ResScalar)) )
-  {
-    alignedSize = 0;
-    alignedStart = 0;
-    alignmentPattern = NoneAligned;
-  }
-  else if(LhsPacketSize > 4)
-  {
-    // TODO: extend the code to support aligned loads whenever possible when LhsPacketSize > 4.
-    // Currently, it seems to be better to perform unaligned loads anyway
-    alignmentPattern = NoneAligned;
-  }
-  else if (LhsPacketSize>1)
-  {
-  //    eigen_internal_assert(size_t(firstLhs+lhsAlignmentOffset)%sizeof(LhsPacket)==0 || size<LhsPacketSize);
-
-    while (skipColumns<LhsPacketSize &&
-          alignedStart != ((lhsAlignmentOffset + alignmentStep*skipColumns)%LhsPacketSize))
-      ++skipColumns;
-    if (skipColumns==LhsPacketSize)
-    {
-      // nothing can be aligned, no need to skip any column
-      alignmentPattern = NoneAligned;
-      skipColumns = 0;
-    }
-    else
-    {
-      skipColumns = (std::min)(skipColumns,cols);
-      // note that the skiped columns are processed later.
-    }
-
-    /*    eigen_internal_assert(  (alignmentPattern==NoneAligned)
-                      || (skipColumns + columnsAtOnce >= cols)
-                      || LhsPacketSize > size
-                      || (size_t(firstLhs+alignedStart+lhsStride*skipColumns)%sizeof(LhsPacket))==0);*/
-  }
-  else if(Vectorizable)
-  {
-    alignedStart = 0;
-    alignedSize = size;
-    alignmentPattern = AllAligned;
-  }
-
-  const Index offset1 = (alignmentPattern==FirstAligned && alignmentStep==1)?3:1;
-  const Index offset3 = (alignmentPattern==FirstAligned && alignmentStep==1)?1:3;
-
-  Index columnBound = ((cols-skipColumns)/columnsAtOnce)*columnsAtOnce + skipColumns;
-  for (Index i=skipColumns; i<columnBound; i+=columnsAtOnce)
-  {
-    RhsPacket ptmp0 = pset1<RhsPacket>(alpha*rhs(i, 0)),
-              ptmp1 = pset1<RhsPacket>(alpha*rhs(i+offset1, 0)),
-              ptmp2 = pset1<RhsPacket>(alpha*rhs(i+2, 0)),
-              ptmp3 = pset1<RhsPacket>(alpha*rhs(i+offset3, 0));
-
-    // this helps a lot generating better binary code
-    const LhsScalars lhs0 = lhs.getVectorMapper(0, i+0),   lhs1 = lhs.getVectorMapper(0, i+offset1),
-                     lhs2 = lhs.getVectorMapper(0, i+2),   lhs3 = lhs.getVectorMapper(0, i+offset3);
-
-    if (Vectorizable)
-    {
-      /* explicit vectorization */
-      // process initial unaligned coeffs
-      for (Index j=0; j<alignedStart; ++j)
-      {
-        res[j] = cj.pmadd(lhs0(j), pfirst(ptmp0), res[j]);
-        res[j] = cj.pmadd(lhs1(j), pfirst(ptmp1), res[j]);
-        res[j] = cj.pmadd(lhs2(j), pfirst(ptmp2), res[j]);
-        res[j] = cj.pmadd(lhs3(j), pfirst(ptmp3), res[j]);
-      }
-
-      if (alignedSize>alignedStart)
-      {
-        switch(alignmentPattern)
-        {
-          case AllAligned:
-            for (Index j = alignedStart; j<alignedSize; j+=ResPacketSize)
-              _EIGEN_ACCUMULATE_PACKETS(Aligned,Aligned,Aligned);
-            break;
-          case EvenAligned:
-            for (Index j = alignedStart; j<alignedSize; j+=ResPacketSize)
-              _EIGEN_ACCUMULATE_PACKETS(Aligned,Unaligned,Aligned);
-            break;
-          case FirstAligned:
-          {
-            Index j = alignedStart;
-            if(peels>1)
-            {
-              LhsPacket A00, A01, A02, A03, A10, A11, A12, A13;
-              ResPacket T0, T1;
-
-              A01 = lhs1.template load<LhsPacket, Aligned>(alignedStart-1);
-              A02 = lhs2.template load<LhsPacket, Aligned>(alignedStart-2);
-              A03 = lhs3.template load<LhsPacket, Aligned>(alignedStart-3);
-
-              for (; j<peeledSize; j+=peels*ResPacketSize)
-              {
-                A11 = lhs1.template load<LhsPacket, Aligned>(j-1+LhsPacketSize);  palign<1>(A01,A11);
-                A12 = lhs2.template load<LhsPacket, Aligned>(j-2+LhsPacketSize);  palign<2>(A02,A12);
-                A13 = lhs3.template load<LhsPacket, Aligned>(j-3+LhsPacketSize);  palign<3>(A03,A13);
-
-                A00 = lhs0.template load<LhsPacket, Aligned>(j);
-                A10 = lhs0.template load<LhsPacket, Aligned>(j+LhsPacketSize);
-                T0  = pcj.pmadd(A00, ptmp0, pload<ResPacket>(&res[j]));
-                T1  = pcj.pmadd(A10, ptmp0, pload<ResPacket>(&res[j+ResPacketSize]));
-
-                T0  = pcj.pmadd(A01, ptmp1, T0);
-                A01 = lhs1.template load<LhsPacket, Aligned>(j-1+2*LhsPacketSize);  palign<1>(A11,A01);
-                T0  = pcj.pmadd(A02, ptmp2, T0);
-                A02 = lhs2.template load<LhsPacket, Aligned>(j-2+2*LhsPacketSize);  palign<2>(A12,A02);
-                T0  = pcj.pmadd(A03, ptmp3, T0);
-                pstore(&res[j],T0);
-                A03 = lhs3.template load<LhsPacket, Aligned>(j-3+2*LhsPacketSize);  palign<3>(A13,A03);
-                T1  = pcj.pmadd(A11, ptmp1, T1);
-                T1  = pcj.pmadd(A12, ptmp2, T1);
-                T1  = pcj.pmadd(A13, ptmp3, T1);
-                pstore(&res[j+ResPacketSize],T1);
-              }
-            }
-            for (; j<alignedSize; j+=ResPacketSize)
-              _EIGEN_ACCUMULATE_PACKETS(Aligned,Unaligned,Unaligned);
-            break;
-          }
-          default:
-            for (Index j = alignedStart; j<alignedSize; j+=ResPacketSize)
-              _EIGEN_ACCUMULATE_PACKETS(Unaligned,Unaligned,Unaligned);
-            break;
-        }
-      }
-    } // end explicit vectorization
-
-    /* process remaining coeffs (or all if there is no explicit vectorization) */
-    for (Index j=alignedSize; j<size; ++j)
-    {
-      res[j] = cj.pmadd(lhs0(j), pfirst(ptmp0), res[j]);
-      res[j] = cj.pmadd(lhs1(j), pfirst(ptmp1), res[j]);
-      res[j] = cj.pmadd(lhs2(j), pfirst(ptmp2), res[j]);
-      res[j] = cj.pmadd(lhs3(j), pfirst(ptmp3), res[j]);
-    }
-  }
-
-  // process remaining first and last columns (at most columnsAtOnce-1)
-  Index end = cols;
-  Index start = columnBound;
-  do
-  {
-    for (Index k=start; k<end; ++k)
-    {
-      RhsPacket ptmp0 = pset1<RhsPacket>(alpha*rhs(k, 0));
-      const LhsScalars lhs0 = lhs.getVectorMapper(0, k);
-
-      if (Vectorizable)
-      {
-        /* explicit vectorization */
-        // process first unaligned result's coeffs
-        for (Index j=0; j<alignedStart; ++j)
-          res[j] += cj.pmul(lhs0(j), pfirst(ptmp0));
-        // process aligned result's coeffs
-        if (lhs0.template aligned<LhsPacket>(alignedStart))
-          for (Index i = alignedStart;i<alignedSize;i+=ResPacketSize)
-            pstore(&res[i], pcj.pmadd(lhs0.template load<LhsPacket, Aligned>(i), ptmp0, pload<ResPacket>(&res[i])));
-        else
-          for (Index i = alignedStart;i<alignedSize;i+=ResPacketSize)
-            pstore(&res[i], pcj.pmadd(lhs0.template load<LhsPacket, Unaligned>(i), ptmp0, pload<ResPacket>(&res[i])));
-      }
-
-      // process remaining scalars (or all if no explicit vectorization)
-      for (Index i=alignedSize; i<size; ++i)
-        res[i] += cj.pmul(lhs0(i), pfirst(ptmp0));
-    }
-    if (skipColumns)
-    {
-      start = 0;
-      end = skipColumns;
-      skipColumns = 0;
-    }
-    else
-      break;
-  } while(Vectorizable);
-  #undef _EIGEN_ACCUMULATE_PACKETS
-}
-
-/* Optimized row-major matrix * vector product:
- * This algorithm processes 4 rows at onces that allows to both reduce
- * the number of load/stores of the result by a factor 4 and to reduce
- * the instruction dependency. Moreover, we know that all bands have the
- * same alignment pattern.
- *
- * Mixing type logic:
- *  - alpha is always a complex (or converted to a complex)
- *  - no vectorization
- */
-template<typename Index, typename LhsScalar, typename LhsMapper, bool ConjugateLhs, typename RhsScalar, typename RhsMapper, bool ConjugateRhs, int Version>
-struct general_matrix_vector_product<Index,LhsScalar,LhsMapper,RowMajor,ConjugateLhs,RhsScalar,RhsMapper,ConjugateRhs,Version>
-{
-typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar>::ReturnType ResScalar;
-
-enum {
-  Vectorizable = packet_traits<LhsScalar>::Vectorizable && packet_traits<RhsScalar>::Vectorizable
-              && int(packet_traits<LhsScalar>::size)==int(packet_traits<RhsScalar>::size),
-  LhsPacketSize = Vectorizable ? packet_traits<LhsScalar>::size : 1,
-  RhsPacketSize = Vectorizable ? packet_traits<RhsScalar>::size : 1,
-  ResPacketSize = Vectorizable ? packet_traits<ResScalar>::size : 1
-};
-
-typedef typename packet_traits<LhsScalar>::type  _LhsPacket;
-typedef typename packet_traits<RhsScalar>::type  _RhsPacket;
-typedef typename packet_traits<ResScalar>::type  _ResPacket;
-
-typedef typename conditional<Vectorizable,_LhsPacket,LhsScalar>::type LhsPacket;
-typedef typename conditional<Vectorizable,_RhsPacket,RhsScalar>::type RhsPacket;
-typedef typename conditional<Vectorizable,_ResPacket,ResScalar>::type ResPacket;
-
-EIGEN_DONT_INLINE static void run(
-  Index rows, Index cols,
-  const LhsMapper& lhs,
-  const RhsMapper& rhs,
-        ResScalar* res, Index resIncr,
-  ResScalar alpha);
-};
-
-template<typename Index, typename LhsScalar, typename LhsMapper, bool ConjugateLhs, typename RhsScalar, typename RhsMapper, bool ConjugateRhs, int Version>
-EIGEN_DONT_INLINE void general_matrix_vector_product<Index,LhsScalar,LhsMapper,RowMajor,ConjugateLhs,RhsScalar,RhsMapper,ConjugateRhs,Version>::run(
-  Index rows, Index cols,
-  const LhsMapper& lhs,
-  const RhsMapper& rhs,
-  ResScalar* res, Index resIncr,
-  ResScalar alpha)
-{
-  eigen_internal_assert(rhs.stride()==1);
-
-  #ifdef _EIGEN_ACCUMULATE_PACKETS
-  #error _EIGEN_ACCUMULATE_PACKETS has already been defined
-  #endif
-
-  #define _EIGEN_ACCUMULATE_PACKETS(Alignment0,Alignment13,Alignment2) {\
-    RhsPacket b = rhs.getVectorMapper(j, 0).template load<RhsPacket, Aligned>(0);  \
-    ptmp0 = pcj.pmadd(lhs0.template load<LhsPacket, Alignment0>(j), b, ptmp0); \
-    ptmp1 = pcj.pmadd(lhs1.template load<LhsPacket, Alignment13>(j), b, ptmp1); \
-    ptmp2 = pcj.pmadd(lhs2.template load<LhsPacket, Alignment2>(j), b, ptmp2); \
-    ptmp3 = pcj.pmadd(lhs3.template load<LhsPacket, Alignment13>(j), b, ptmp3); }
-
-  conj_helper<LhsScalar,RhsScalar,ConjugateLhs,ConjugateRhs> cj;
-  conj_helper<LhsPacket,RhsPacket,ConjugateLhs,ConjugateRhs> pcj;
-
-  typedef typename LhsMapper::VectorMapper LhsScalars;
-
-  enum { AllAligned=0, EvenAligned=1, FirstAligned=2, NoneAligned=3 };
-  const Index rowsAtOnce = 4;
-  const Index peels = 2;
-  const Index RhsPacketAlignedMask = RhsPacketSize-1;
-  const Index LhsPacketAlignedMask = LhsPacketSize-1;
-  const Index depth = cols;
-  const Index lhsStride = lhs.stride();
-
-  // How many coeffs of the result do we have to skip to be aligned.
-  // Here we assume data are at least aligned on the base scalar type
-  // if that's not the case then vectorization is discarded, see below.
-  Index alignedStart = rhs.firstAligned(depth);
-  Index alignedSize = RhsPacketSize>1 ? alignedStart + ((depth-alignedStart) & ~RhsPacketAlignedMask) : 0;
-  const Index peeledSize = alignedSize - RhsPacketSize*peels - RhsPacketSize + 1;
-
-  const Index alignmentStep = LhsPacketSize>1 ? (LhsPacketSize - lhsStride % LhsPacketSize) & LhsPacketAlignedMask : 0;
-  Index alignmentPattern = alignmentStep==0 ? AllAligned
-                           : alignmentStep==(LhsPacketSize/2) ? EvenAligned
-                           : FirstAligned;
-
-  // we cannot assume the first element is aligned because of sub-matrices
-  const Index lhsAlignmentOffset = lhs.firstAligned(depth);
-  const Index rhsAlignmentOffset = rhs.firstAligned(rows);
-
-  // find how many rows do we have to skip to be aligned with rhs (if possible)
-  Index skipRows = 0;
-  // if the data cannot be aligned (TODO add some compile time tests when possible, e.g. for floats)
-  if( (sizeof(LhsScalar)!=sizeof(RhsScalar)) ||
-      (lhsAlignmentOffset < 0) || (lhsAlignmentOffset == depth) ||
-      (rhsAlignmentOffset < 0) || (rhsAlignmentOffset == rows) )
-  {
-    alignedSize = 0;
-    alignedStart = 0;
-    alignmentPattern = NoneAligned;
-  }
-  else if(LhsPacketSize > 4)
-  {
-    // TODO: extend the code to support aligned loads whenever possible when LhsPacketSize > 4.
-    alignmentPattern = NoneAligned;
-  }
-  else if (LhsPacketSize>1)
-  {
-  //    eigen_internal_assert(size_t(firstLhs+lhsAlignmentOffset)%sizeof(LhsPacket)==0  || depth<LhsPacketSize);
-
-    while (skipRows<LhsPacketSize &&
-           alignedStart != ((lhsAlignmentOffset + alignmentStep*skipRows)%LhsPacketSize))
-      ++skipRows;
-    if (skipRows==LhsPacketSize)
-    {
-      // nothing can be aligned, no need to skip any column
-      alignmentPattern = NoneAligned;
-      skipRows = 0;
-    }
-    else
-    {
-      skipRows = (std::min)(skipRows,Index(rows));
-      // note that the skiped columns are processed later.
-    }
-    /*    eigen_internal_assert(  alignmentPattern==NoneAligned
-                      || LhsPacketSize==1
-                      || (skipRows + rowsAtOnce >= rows)
-                      || LhsPacketSize > depth
-                      || (size_t(firstLhs+alignedStart+lhsStride*skipRows)%sizeof(LhsPacket))==0);*/
-  }
-  else if(Vectorizable)
-  {
-    alignedStart = 0;
-    alignedSize = depth;
-    alignmentPattern = AllAligned;
-  }
-
-  const Index offset1 = (alignmentPattern==FirstAligned && alignmentStep==1)?3:1;
-  const Index offset3 = (alignmentPattern==FirstAligned && alignmentStep==1)?1:3;
-
-  Index rowBound = ((rows-skipRows)/rowsAtOnce)*rowsAtOnce + skipRows;
-  for (Index i=skipRows; i<rowBound; i+=rowsAtOnce)
-  {
-    // FIXME: what is the purpose of this EIGEN_ALIGN_DEFAULT ??
-    EIGEN_ALIGN_MAX ResScalar tmp0 = ResScalar(0);
-    ResScalar tmp1 = ResScalar(0), tmp2 = ResScalar(0), tmp3 = ResScalar(0);
-
-    // this helps the compiler generating good binary code
-    const LhsScalars lhs0 = lhs.getVectorMapper(i+0, 0),    lhs1 = lhs.getVectorMapper(i+offset1, 0),
-                     lhs2 = lhs.getVectorMapper(i+2, 0),    lhs3 = lhs.getVectorMapper(i+offset3, 0);
-
-    if (Vectorizable)
-    {
-      /* explicit vectorization */
-      ResPacket ptmp0 = pset1<ResPacket>(ResScalar(0)), ptmp1 = pset1<ResPacket>(ResScalar(0)),
-                ptmp2 = pset1<ResPacket>(ResScalar(0)), ptmp3 = pset1<ResPacket>(ResScalar(0));
-
-      // process initial unaligned coeffs
-      // FIXME this loop get vectorized by the compiler !
-      for (Index j=0; j<alignedStart; ++j)
-      {
-        RhsScalar b = rhs(j, 0);
-        tmp0 += cj.pmul(lhs0(j),b); tmp1 += cj.pmul(lhs1(j),b);
-        tmp2 += cj.pmul(lhs2(j),b); tmp3 += cj.pmul(lhs3(j),b);
-      }
-
-      if (alignedSize>alignedStart)
-      {
-        switch(alignmentPattern)
-        {
-          case AllAligned:
-            for (Index j = alignedStart; j<alignedSize; j+=RhsPacketSize)
-              _EIGEN_ACCUMULATE_PACKETS(Aligned,Aligned,Aligned);
-            break;
-          case EvenAligned:
-            for (Index j = alignedStart; j<alignedSize; j+=RhsPacketSize)
-              _EIGEN_ACCUMULATE_PACKETS(Aligned,Unaligned,Aligned);
-            break;
-          case FirstAligned:
-          {
-            Index j = alignedStart;
-            if (peels>1)
-            {
-              /* Here we proccess 4 rows with with two peeled iterations to hide
-               * the overhead of unaligned loads. Moreover unaligned loads are handled
-               * using special shift/move operations between the two aligned packets
-               * overlaping the desired unaligned packet. This is *much* more efficient
-               * than basic unaligned loads.
-               */
-              LhsPacket A01, A02, A03, A11, A12, A13;
-              A01 = lhs1.template load<LhsPacket, Aligned>(alignedStart-1);
-              A02 = lhs2.template load<LhsPacket, Aligned>(alignedStart-2);
-              A03 = lhs3.template load<LhsPacket, Aligned>(alignedStart-3);
-
-              for (; j<peeledSize; j+=peels*RhsPacketSize)
-              {
-                RhsPacket b = rhs.getVectorMapper(j, 0).template load<RhsPacket, Aligned>(0);
-                A11 = lhs1.template load<LhsPacket, Aligned>(j-1+LhsPacketSize);  palign<1>(A01,A11);
-                A12 = lhs2.template load<LhsPacket, Aligned>(j-2+LhsPacketSize);  palign<2>(A02,A12);
-                A13 = lhs3.template load<LhsPacket, Aligned>(j-3+LhsPacketSize);  palign<3>(A03,A13);
-
-                ptmp0 = pcj.pmadd(lhs0.template load<LhsPacket, Aligned>(j), b, ptmp0);
-                ptmp1 = pcj.pmadd(A01, b, ptmp1);
-                A01 = lhs1.template load<LhsPacket, Aligned>(j-1+2*LhsPacketSize);  palign<1>(A11,A01);
-                ptmp2 = pcj.pmadd(A02, b, ptmp2);
-                A02 = lhs2.template load<LhsPacket, Aligned>(j-2+2*LhsPacketSize);  palign<2>(A12,A02);
-                ptmp3 = pcj.pmadd(A03, b, ptmp3);
-                A03 = lhs3.template load<LhsPacket, Aligned>(j-3+2*LhsPacketSize);  palign<3>(A13,A03);
-
-                b = rhs.getVectorMapper(j+RhsPacketSize, 0).template load<RhsPacket, Aligned>(0);
-                ptmp0 = pcj.pmadd(lhs0.template load<LhsPacket, Aligned>(j+LhsPacketSize), b, ptmp0);
-                ptmp1 = pcj.pmadd(A11, b, ptmp1);
-                ptmp2 = pcj.pmadd(A12, b, ptmp2);
-                ptmp3 = pcj.pmadd(A13, b, ptmp3);
-              }
-            }
-            for (; j<alignedSize; j+=RhsPacketSize)
-              _EIGEN_ACCUMULATE_PACKETS(Aligned,Unaligned,Unaligned);
-            break;
-          }
-          default:
-            for (Index j = alignedStart; j<alignedSize; j+=RhsPacketSize)
-              _EIGEN_ACCUMULATE_PACKETS(Unaligned,Unaligned,Unaligned);
-            break;
-        }
-        tmp0 += predux(ptmp0);
-        tmp1 += predux(ptmp1);
-        tmp2 += predux(ptmp2);
-        tmp3 += predux(ptmp3);
-      }
-    } // end explicit vectorization
-
-    // process remaining coeffs (or all if no explicit vectorization)
-    // FIXME this loop get vectorized by the compiler !
-    for (Index j=alignedSize; j<depth; ++j)
-    {
-      RhsScalar b = rhs(j, 0);
-      tmp0 += cj.pmul(lhs0(j),b); tmp1 += cj.pmul(lhs1(j),b);
-      tmp2 += cj.pmul(lhs2(j),b); tmp3 += cj.pmul(lhs3(j),b);
-    }
-    res[i*resIncr]            += alpha*tmp0;
-    res[(i+offset1)*resIncr]  += alpha*tmp1;
-    res[(i+2)*resIncr]        += alpha*tmp2;
-    res[(i+offset3)*resIncr]  += alpha*tmp3;
-  }
-
-  // process remaining first and last rows (at most columnsAtOnce-1)
-  Index end = rows;
-  Index start = rowBound;
-  do
-  {
-    for (Index i=start; i<end; ++i)
-    {
-      EIGEN_ALIGN_MAX ResScalar tmp0 = ResScalar(0);
-      ResPacket ptmp0 = pset1<ResPacket>(tmp0);
-      const LhsScalars lhs0 = lhs.getVectorMapper(i, 0);
-      // process first unaligned result's coeffs
-      // FIXME this loop get vectorized by the compiler !
-      for (Index j=0; j<alignedStart; ++j)
-        tmp0 += cj.pmul(lhs0(j), rhs(j, 0));
-
-      if (alignedSize>alignedStart)
-      {
-        // process aligned rhs coeffs
-        if (lhs0.template aligned<LhsPacket>(alignedStart))
-          for (Index j = alignedStart;j<alignedSize;j+=RhsPacketSize)
-            ptmp0 = pcj.pmadd(lhs0.template load<LhsPacket, Aligned>(j), rhs.getVectorMapper(j, 0).template load<RhsPacket, Aligned>(0), ptmp0);
-        else
-          for (Index j = alignedStart;j<alignedSize;j+=RhsPacketSize)
-            ptmp0 = pcj.pmadd(lhs0.template load<LhsPacket, Unaligned>(j), rhs.getVectorMapper(j, 0).template load<RhsPacket, Aligned>(0), ptmp0);
-        tmp0 += predux(ptmp0);
-      }
-
-      // process remaining scalars
-      // FIXME this loop get vectorized by the compiler !
-      for (Index j=alignedSize; j<depth; ++j)
-        tmp0 += cj.pmul(lhs0(j), rhs(j, 0));
-      res[i*resIncr] += alpha*tmp0;
-    }
-    if (skipRows)
-    {
-      start = 0;
-      end = skipRows;
-      skipRows = 0;
-    }
-    else
-      break;
-  } while(Vectorizable);
-
-  #undef _EIGEN_ACCUMULATE_PACKETS
-}
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_GENERAL_MATRIX_VECTOR_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/Parallelizer.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/Parallelizer.h
deleted file mode 100644
index c2f084c..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/Parallelizer.h
+++ /dev/null
@@ -1,163 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_PARALLELIZER_H
-#define EIGEN_PARALLELIZER_H
-
-namespace Eigen {
-
-namespace internal {
-
-/** \internal */
-inline void manage_multi_threading(Action action, int* v)
-{
-  static EIGEN_UNUSED int m_maxThreads = -1;
-
-  if(action==SetAction)
-  {
-    eigen_internal_assert(v!=0);
-    m_maxThreads = *v;
-  }
-  else if(action==GetAction)
-  {
-    eigen_internal_assert(v!=0);
-    #ifdef EIGEN_HAS_OPENMP
-    if(m_maxThreads>0)
-      *v = m_maxThreads;
-    else
-      *v = omp_get_max_threads();
-    #else
-    *v = 1;
-    #endif
-  }
-  else
-  {
-    eigen_internal_assert(false);
-  }
-}
-
-}
-
-/** Must be call first when calling Eigen from multiple threads */
-inline void initParallel()
-{
-  int nbt;
-  internal::manage_multi_threading(GetAction, &nbt);
-  std::ptrdiff_t l1, l2, l3;
-  internal::manage_caching_sizes(GetAction, &l1, &l2, &l3);
-}
-
-/** \returns the max number of threads reserved for Eigen
-  * \sa setNbThreads */
-inline int nbThreads()
-{
-  int ret;
-  internal::manage_multi_threading(GetAction, &ret);
-  return ret;
-}
-
-/** Sets the max number of threads reserved for Eigen
-  * \sa nbThreads */
-inline void setNbThreads(int v)
-{
-  internal::manage_multi_threading(SetAction, &v);
-}
-
-namespace internal {
-
-template<typename Index> struct GemmParallelInfo
-{
-  GemmParallelInfo() : sync(-1), users(0), lhs_start(0), lhs_length(0) {}
-
-  Index volatile sync;
-  int volatile users;
-
-  Index lhs_start;
-  Index lhs_length;
-};
-
-template<bool Condition, typename Functor, typename Index>
-void parallelize_gemm(const Functor& func, Index rows, Index cols, Index depth, bool transpose)
-{
-  // TODO when EIGEN_USE_BLAS is defined,
-  // we should still enable OMP for other scalar types
-#if !(defined (EIGEN_HAS_OPENMP)) || defined (EIGEN_USE_BLAS)
-  // FIXME the transpose variable is only needed to properly split
-  // the matrix product when multithreading is enabled. This is a temporary
-  // fix to support row-major destination matrices. This whole
-  // parallelizer mechanism has to be redisigned anyway.
-  EIGEN_UNUSED_VARIABLE(depth);
-  EIGEN_UNUSED_VARIABLE(transpose);
-  func(0,rows, 0,cols);
-#else
-
-  // Dynamically check whether we should enable or disable OpenMP.
-  // The conditions are:
-  // - the max number of threads we can create is greater than 1
-  // - we are not already in a parallel code
-  // - the sizes are large enough
-
-  // compute the maximal number of threads from the size of the product:
-  // This first heuristic takes into account that the product kernel is fully optimized when working with nr columns at once.
-  Index size = transpose ? rows : cols;
-  Index pb_max_threads = std::max<Index>(1,size / Functor::Traits::nr);
-
-  // compute the maximal number of threads from the total amount of work:
-  double work = static_cast<double>(rows) * static_cast<double>(cols) *
-      static_cast<double>(depth);
-  double kMinTaskSize = 50000;  // FIXME improve this heuristic.
-  pb_max_threads = std::max<Index>(1, std::min<Index>(pb_max_threads, work / kMinTaskSize));
-
-  // compute the number of threads we are going to use
-  Index threads = std::min<Index>(nbThreads(), pb_max_threads);
-
-  // if multi-threading is explicitely disabled, not useful, or if we already are in a parallel session,
-  // then abort multi-threading
-  // FIXME omp_get_num_threads()>1 only works for openmp, what if the user does not use openmp?
-  if((!Condition) || (threads==1) || (omp_get_num_threads()>1))
-    return func(0,rows, 0,cols);
-
-  Eigen::initParallel();
-  func.initParallelSession(threads);
-
-  if(transpose)
-    std::swap(rows,cols);
-
-  ei_declare_aligned_stack_constructed_variable(GemmParallelInfo<Index>,info,threads,0);
-
-  #pragma omp parallel num_threads(threads)
-  {
-    Index i = omp_get_thread_num();
-    // Note that the actual number of threads might be lower than the number of request ones.
-    Index actual_threads = omp_get_num_threads();
-
-    Index blockCols = (cols / actual_threads) & ~Index(0x3);
-    Index blockRows = (rows / actual_threads);
-    blockRows = (blockRows/Functor::Traits::mr)*Functor::Traits::mr;
-
-    Index r0 = i*blockRows;
-    Index actualBlockRows = (i+1==actual_threads) ? rows-r0 : blockRows;
-
-    Index c0 = i*blockCols;
-    Index actualBlockCols = (i+1==actual_threads) ? cols-c0 : blockCols;
-
-    info[i].lhs_start = r0;
-    info[i].lhs_length = actualBlockRows;
-
-    if(transpose) func(c0, actualBlockCols, 0, rows, info);
-    else          func(0, rows, c0, actualBlockCols, info);
-  }
-#endif
-}
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_PARALLELIZER_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/SelfadjointMatrixMatrix.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/SelfadjointMatrixMatrix.h
deleted file mode 100644
index da6f82a..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/SelfadjointMatrixMatrix.h
+++ /dev/null
@@ -1,521 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_SELFADJOINT_MATRIX_MATRIX_H
-#define EIGEN_SELFADJOINT_MATRIX_MATRIX_H
-
-namespace Eigen { 
-
-namespace internal {
-
-// pack a selfadjoint block diagonal for use with the gebp_kernel
-template<typename Scalar, typename Index, int Pack1, int Pack2_dummy, int StorageOrder>
-struct symm_pack_lhs
-{
-  template<int BlockRows> inline
-  void pack(Scalar* blockA, const const_blas_data_mapper<Scalar,Index,StorageOrder>& lhs, Index cols, Index i, Index& count)
-  {
-    // normal copy
-    for(Index k=0; k<i; k++)
-      for(Index w=0; w<BlockRows; w++)
-        blockA[count++] = lhs(i+w,k);           // normal
-    // symmetric copy
-    Index h = 0;
-    for(Index k=i; k<i+BlockRows; k++)
-    {
-      for(Index w=0; w<h; w++)
-        blockA[count++] = numext::conj(lhs(k, i+w)); // transposed
-
-      blockA[count++] = numext::real(lhs(k,k));   // real (diagonal)
-
-      for(Index w=h+1; w<BlockRows; w++)
-        blockA[count++] = lhs(i+w, k);          // normal
-      ++h;
-    }
-    // transposed copy
-    for(Index k=i+BlockRows; k<cols; k++)
-      for(Index w=0; w<BlockRows; w++)
-        blockA[count++] = numext::conj(lhs(k, i+w)); // transposed
-  }
-  void operator()(Scalar* blockA, const Scalar* _lhs, Index lhsStride, Index cols, Index rows)
-  {
-    enum { PacketSize = packet_traits<Scalar>::size };
-    const_blas_data_mapper<Scalar,Index,StorageOrder> lhs(_lhs,lhsStride);
-    Index count = 0;
-    //Index peeled_mc3 = (rows/Pack1)*Pack1;
-    
-    const Index peeled_mc3 = Pack1>=3*PacketSize ? (rows/(3*PacketSize))*(3*PacketSize) : 0;
-    const Index peeled_mc2 = Pack1>=2*PacketSize ? peeled_mc3+((rows-peeled_mc3)/(2*PacketSize))*(2*PacketSize) : 0;
-    const Index peeled_mc1 = Pack1>=1*PacketSize ? (rows/(1*PacketSize))*(1*PacketSize) : 0;
-    
-    if(Pack1>=3*PacketSize)
-      for(Index i=0; i<peeled_mc3; i+=3*PacketSize)
-        pack<3*PacketSize>(blockA, lhs, cols, i, count);
-    
-    if(Pack1>=2*PacketSize)
-      for(Index i=peeled_mc3; i<peeled_mc2; i+=2*PacketSize)
-        pack<2*PacketSize>(blockA, lhs, cols, i, count);
-    
-    if(Pack1>=1*PacketSize)
-      for(Index i=peeled_mc2; i<peeled_mc1; i+=1*PacketSize)
-        pack<1*PacketSize>(blockA, lhs, cols, i, count);
-
-    // do the same with mr==1
-    for(Index i=peeled_mc1; i<rows; i++)
-    {
-      for(Index k=0; k<i; k++)
-        blockA[count++] = lhs(i, k);                   // normal
-
-      blockA[count++] = numext::real(lhs(i, i));       // real (diagonal)
-
-      for(Index k=i+1; k<cols; k++)
-        blockA[count++] = numext::conj(lhs(k, i));     // transposed
-    }
-  }
-};
-
-template<typename Scalar, typename Index, int nr, int StorageOrder>
-struct symm_pack_rhs
-{
-  enum { PacketSize = packet_traits<Scalar>::size };
-  void operator()(Scalar* blockB, const Scalar* _rhs, Index rhsStride, Index rows, Index cols, Index k2)
-  {
-    Index end_k = k2 + rows;
-    Index count = 0;
-    const_blas_data_mapper<Scalar,Index,StorageOrder> rhs(_rhs,rhsStride);
-    Index packet_cols8 = nr>=8 ? (cols/8) * 8 : 0;
-    Index packet_cols4 = nr>=4 ? (cols/4) * 4 : 0;
-
-    // first part: normal case
-    for(Index j2=0; j2<k2; j2+=nr)
-    {
-      for(Index k=k2; k<end_k; k++)
-      {
-        blockB[count+0] = rhs(k,j2+0);
-        blockB[count+1] = rhs(k,j2+1);
-        if (nr>=4)
-        {
-          blockB[count+2] = rhs(k,j2+2);
-          blockB[count+3] = rhs(k,j2+3);
-        }
-        if (nr>=8)
-        {
-          blockB[count+4] = rhs(k,j2+4);
-          blockB[count+5] = rhs(k,j2+5);
-          blockB[count+6] = rhs(k,j2+6);
-          blockB[count+7] = rhs(k,j2+7);
-        }
-        count += nr;
-      }
-    }
-
-    // second part: diagonal block
-    Index end8 = nr>=8 ? (std::min)(k2+rows,packet_cols8) : k2;
-    if(nr>=8)
-    {
-      for(Index j2=k2; j2<end8; j2+=8)
-      {
-        // again we can split vertically in three different parts (transpose, symmetric, normal)
-        // transpose
-        for(Index k=k2; k<j2; k++)
-        {
-          blockB[count+0] = numext::conj(rhs(j2+0,k));
-          blockB[count+1] = numext::conj(rhs(j2+1,k));
-          blockB[count+2] = numext::conj(rhs(j2+2,k));
-          blockB[count+3] = numext::conj(rhs(j2+3,k));
-          blockB[count+4] = numext::conj(rhs(j2+4,k));
-          blockB[count+5] = numext::conj(rhs(j2+5,k));
-          blockB[count+6] = numext::conj(rhs(j2+6,k));
-          blockB[count+7] = numext::conj(rhs(j2+7,k));
-          count += 8;
-        }
-        // symmetric
-        Index h = 0;
-        for(Index k=j2; k<j2+8; k++)
-        {
-          // normal
-          for (Index w=0 ; w<h; ++w)
-            blockB[count+w] = rhs(k,j2+w);
-
-          blockB[count+h] = numext::real(rhs(k,k));
-
-          // transpose
-          for (Index w=h+1 ; w<8; ++w)
-            blockB[count+w] = numext::conj(rhs(j2+w,k));
-          count += 8;
-          ++h;
-        }
-        // normal
-        for(Index k=j2+8; k<end_k; k++)
-        {
-          blockB[count+0] = rhs(k,j2+0);
-          blockB[count+1] = rhs(k,j2+1);
-          blockB[count+2] = rhs(k,j2+2);
-          blockB[count+3] = rhs(k,j2+3);
-          blockB[count+4] = rhs(k,j2+4);
-          blockB[count+5] = rhs(k,j2+5);
-          blockB[count+6] = rhs(k,j2+6);
-          blockB[count+7] = rhs(k,j2+7);
-          count += 8;
-        }
-      }
-    }
-    if(nr>=4)
-    {
-      for(Index j2=end8; j2<(std::min)(k2+rows,packet_cols4); j2+=4)
-      {
-        // again we can split vertically in three different parts (transpose, symmetric, normal)
-        // transpose
-        for(Index k=k2; k<j2; k++)
-        {
-          blockB[count+0] = numext::conj(rhs(j2+0,k));
-          blockB[count+1] = numext::conj(rhs(j2+1,k));
-          blockB[count+2] = numext::conj(rhs(j2+2,k));
-          blockB[count+3] = numext::conj(rhs(j2+3,k));
-          count += 4;
-        }
-        // symmetric
-        Index h = 0;
-        for(Index k=j2; k<j2+4; k++)
-        {
-          // normal
-          for (Index w=0 ; w<h; ++w)
-            blockB[count+w] = rhs(k,j2+w);
-
-          blockB[count+h] = numext::real(rhs(k,k));
-
-          // transpose
-          for (Index w=h+1 ; w<4; ++w)
-            blockB[count+w] = numext::conj(rhs(j2+w,k));
-          count += 4;
-          ++h;
-        }
-        // normal
-        for(Index k=j2+4; k<end_k; k++)
-        {
-          blockB[count+0] = rhs(k,j2+0);
-          blockB[count+1] = rhs(k,j2+1);
-          blockB[count+2] = rhs(k,j2+2);
-          blockB[count+3] = rhs(k,j2+3);
-          count += 4;
-        }
-      }
-    }
-
-    // third part: transposed
-    if(nr>=8)
-    {
-      for(Index j2=k2+rows; j2<packet_cols8; j2+=8)
-      {
-        for(Index k=k2; k<end_k; k++)
-        {
-          blockB[count+0] = numext::conj(rhs(j2+0,k));
-          blockB[count+1] = numext::conj(rhs(j2+1,k));
-          blockB[count+2] = numext::conj(rhs(j2+2,k));
-          blockB[count+3] = numext::conj(rhs(j2+3,k));
-          blockB[count+4] = numext::conj(rhs(j2+4,k));
-          blockB[count+5] = numext::conj(rhs(j2+5,k));
-          blockB[count+6] = numext::conj(rhs(j2+6,k));
-          blockB[count+7] = numext::conj(rhs(j2+7,k));
-          count += 8;
-        }
-      }
-    }
-    if(nr>=4)
-    {
-      for(Index j2=(std::max)(packet_cols8,k2+rows); j2<packet_cols4; j2+=4)
-      {
-        for(Index k=k2; k<end_k; k++)
-        {
-          blockB[count+0] = numext::conj(rhs(j2+0,k));
-          blockB[count+1] = numext::conj(rhs(j2+1,k));
-          blockB[count+2] = numext::conj(rhs(j2+2,k));
-          blockB[count+3] = numext::conj(rhs(j2+3,k));
-          count += 4;
-        }
-      }
-    }
-
-    // copy the remaining columns one at a time (=> the same with nr==1)
-    for(Index j2=packet_cols4; j2<cols; ++j2)
-    {
-      // transpose
-      Index half = (std::min)(end_k,j2);
-      for(Index k=k2; k<half; k++)
-      {
-        blockB[count] = numext::conj(rhs(j2,k));
-        count += 1;
-      }
-
-      if(half==j2 && half<k2+rows)
-      {
-        blockB[count] = numext::real(rhs(j2,j2));
-        count += 1;
-      }
-      else
-        half--;
-
-      // normal
-      for(Index k=half+1; k<k2+rows; k++)
-      {
-        blockB[count] = rhs(k,j2);
-        count += 1;
-      }
-    }
-  }
-};
-
-/* Optimized selfadjoint matrix * matrix (_SYMM) product built on top of
- * the general matrix matrix product.
- */
-template <typename Scalar, typename Index,
-          int LhsStorageOrder, bool LhsSelfAdjoint, bool ConjugateLhs,
-          int RhsStorageOrder, bool RhsSelfAdjoint, bool ConjugateRhs,
-          int ResStorageOrder>
-struct product_selfadjoint_matrix;
-
-template <typename Scalar, typename Index,
-          int LhsStorageOrder, bool LhsSelfAdjoint, bool ConjugateLhs,
-          int RhsStorageOrder, bool RhsSelfAdjoint, bool ConjugateRhs>
-struct product_selfadjoint_matrix<Scalar,Index,LhsStorageOrder,LhsSelfAdjoint,ConjugateLhs, RhsStorageOrder,RhsSelfAdjoint,ConjugateRhs,RowMajor>
-{
-
-  static EIGEN_STRONG_INLINE void run(
-    Index rows, Index cols,
-    const Scalar* lhs, Index lhsStride,
-    const Scalar* rhs, Index rhsStride,
-    Scalar* res,       Index resStride,
-    const Scalar& alpha, level3_blocking<Scalar,Scalar>& blocking)
-  {
-    product_selfadjoint_matrix<Scalar, Index,
-      EIGEN_LOGICAL_XOR(RhsSelfAdjoint,RhsStorageOrder==RowMajor) ? ColMajor : RowMajor,
-      RhsSelfAdjoint, NumTraits<Scalar>::IsComplex && EIGEN_LOGICAL_XOR(RhsSelfAdjoint,ConjugateRhs),
-      EIGEN_LOGICAL_XOR(LhsSelfAdjoint,LhsStorageOrder==RowMajor) ? ColMajor : RowMajor,
-      LhsSelfAdjoint, NumTraits<Scalar>::IsComplex && EIGEN_LOGICAL_XOR(LhsSelfAdjoint,ConjugateLhs),
-      ColMajor>
-      ::run(cols, rows,  rhs, rhsStride,  lhs, lhsStride,  res, resStride,  alpha, blocking);
-  }
-};
-
-template <typename Scalar, typename Index,
-          int LhsStorageOrder, bool ConjugateLhs,
-          int RhsStorageOrder, bool ConjugateRhs>
-struct product_selfadjoint_matrix<Scalar,Index,LhsStorageOrder,true,ConjugateLhs, RhsStorageOrder,false,ConjugateRhs,ColMajor>
-{
-
-  static EIGEN_DONT_INLINE void run(
-    Index rows, Index cols,
-    const Scalar* _lhs, Index lhsStride,
-    const Scalar* _rhs, Index rhsStride,
-    Scalar* res,        Index resStride,
-    const Scalar& alpha, level3_blocking<Scalar,Scalar>& blocking);
-};
-
-template <typename Scalar, typename Index,
-          int LhsStorageOrder, bool ConjugateLhs,
-          int RhsStorageOrder, bool ConjugateRhs>
-EIGEN_DONT_INLINE void product_selfadjoint_matrix<Scalar,Index,LhsStorageOrder,true,ConjugateLhs, RhsStorageOrder,false,ConjugateRhs,ColMajor>::run(
-    Index rows, Index cols,
-    const Scalar* _lhs, Index lhsStride,
-    const Scalar* _rhs, Index rhsStride,
-    Scalar* _res,        Index resStride,
-    const Scalar& alpha, level3_blocking<Scalar,Scalar>& blocking)
-  {
-    Index size = rows;
-
-    typedef gebp_traits<Scalar,Scalar> Traits;
-
-    typedef const_blas_data_mapper<Scalar, Index, LhsStorageOrder> LhsMapper;
-    typedef const_blas_data_mapper<Scalar, Index, (LhsStorageOrder == RowMajor) ? ColMajor : RowMajor> LhsTransposeMapper;
-    typedef const_blas_data_mapper<Scalar, Index, RhsStorageOrder> RhsMapper;
-    typedef blas_data_mapper<typename Traits::ResScalar, Index, ColMajor> ResMapper;
-    LhsMapper lhs(_lhs,lhsStride);
-    LhsTransposeMapper lhs_transpose(_lhs,lhsStride);
-    RhsMapper rhs(_rhs,rhsStride);
-    ResMapper res(_res, resStride);
-
-    Index kc = blocking.kc();                   // cache block size along the K direction
-    Index mc = (std::min)(rows,blocking.mc());  // cache block size along the M direction
-    // kc must be smaller than mc
-    kc = (std::min)(kc,mc);
-    std::size_t sizeA = kc*mc;
-    std::size_t sizeB = kc*cols;
-    ei_declare_aligned_stack_constructed_variable(Scalar, blockA, sizeA, blocking.blockA());
-    ei_declare_aligned_stack_constructed_variable(Scalar, blockB, sizeB, blocking.blockB());
-
-    gebp_kernel<Scalar, Scalar, Index, ResMapper, Traits::mr, Traits::nr, ConjugateLhs, ConjugateRhs> gebp_kernel;
-    symm_pack_lhs<Scalar, Index, Traits::mr, Traits::LhsProgress, LhsStorageOrder> pack_lhs;
-    gemm_pack_rhs<Scalar, Index, RhsMapper, Traits::nr,RhsStorageOrder> pack_rhs;
-    gemm_pack_lhs<Scalar, Index, LhsTransposeMapper, Traits::mr, Traits::LhsProgress, LhsStorageOrder==RowMajor?ColMajor:RowMajor, true> pack_lhs_transposed;
-
-    for(Index k2=0; k2<size; k2+=kc)
-    {
-      const Index actual_kc = (std::min)(k2+kc,size)-k2;
-
-      // we have selected one row panel of rhs and one column panel of lhs
-      // pack rhs's panel into a sequential chunk of memory
-      // and expand each coeff to a constant packet for further reuse
-      pack_rhs(blockB, rhs.getSubMapper(k2,0), actual_kc, cols);
-
-      // the select lhs's panel has to be split in three different parts:
-      //  1 - the transposed panel above the diagonal block => transposed packed copy
-      //  2 - the diagonal block => special packed copy
-      //  3 - the panel below the diagonal block => generic packed copy
-      for(Index i2=0; i2<k2; i2+=mc)
-      {
-        const Index actual_mc = (std::min)(i2+mc,k2)-i2;
-        // transposed packed copy
-        pack_lhs_transposed(blockA, lhs_transpose.getSubMapper(i2, k2), actual_kc, actual_mc);
-
-        gebp_kernel(res.getSubMapper(i2, 0), blockA, blockB, actual_mc, actual_kc, cols, alpha);
-      }
-      // the block diagonal
-      {
-        const Index actual_mc = (std::min)(k2+kc,size)-k2;
-        // symmetric packed copy
-        pack_lhs(blockA, &lhs(k2,k2), lhsStride, actual_kc, actual_mc);
-
-        gebp_kernel(res.getSubMapper(k2, 0), blockA, blockB, actual_mc, actual_kc, cols, alpha);
-      }
-
-      for(Index i2=k2+kc; i2<size; i2+=mc)
-      {
-        const Index actual_mc = (std::min)(i2+mc,size)-i2;
-        gemm_pack_lhs<Scalar, Index, LhsMapper, Traits::mr, Traits::LhsProgress, LhsStorageOrder,false>()
-          (blockA, lhs.getSubMapper(i2, k2), actual_kc, actual_mc);
-
-        gebp_kernel(res.getSubMapper(i2, 0), blockA, blockB, actual_mc, actual_kc, cols, alpha);
-      }
-    }
-  }
-
-// matrix * selfadjoint product
-template <typename Scalar, typename Index,
-          int LhsStorageOrder, bool ConjugateLhs,
-          int RhsStorageOrder, bool ConjugateRhs>
-struct product_selfadjoint_matrix<Scalar,Index,LhsStorageOrder,false,ConjugateLhs, RhsStorageOrder,true,ConjugateRhs,ColMajor>
-{
-
-  static EIGEN_DONT_INLINE void run(
-    Index rows, Index cols,
-    const Scalar* _lhs, Index lhsStride,
-    const Scalar* _rhs, Index rhsStride,
-    Scalar* res,        Index resStride,
-    const Scalar& alpha, level3_blocking<Scalar,Scalar>& blocking);
-};
-
-template <typename Scalar, typename Index,
-          int LhsStorageOrder, bool ConjugateLhs,
-          int RhsStorageOrder, bool ConjugateRhs>
-EIGEN_DONT_INLINE void product_selfadjoint_matrix<Scalar,Index,LhsStorageOrder,false,ConjugateLhs, RhsStorageOrder,true,ConjugateRhs,ColMajor>::run(
-    Index rows, Index cols,
-    const Scalar* _lhs, Index lhsStride,
-    const Scalar* _rhs, Index rhsStride,
-    Scalar* _res,        Index resStride,
-    const Scalar& alpha, level3_blocking<Scalar,Scalar>& blocking)
-  {
-    Index size = cols;
-
-    typedef gebp_traits<Scalar,Scalar> Traits;
-
-    typedef const_blas_data_mapper<Scalar, Index, LhsStorageOrder> LhsMapper;
-    typedef blas_data_mapper<typename Traits::ResScalar, Index, ColMajor> ResMapper;
-    LhsMapper lhs(_lhs,lhsStride);
-    ResMapper res(_res,resStride);
-
-    Index kc = blocking.kc();                   // cache block size along the K direction
-    Index mc = (std::min)(rows,blocking.mc());  // cache block size along the M direction
-    std::size_t sizeA = kc*mc;
-    std::size_t sizeB = kc*cols;
-    ei_declare_aligned_stack_constructed_variable(Scalar, blockA, sizeA, blocking.blockA());
-    ei_declare_aligned_stack_constructed_variable(Scalar, blockB, sizeB, blocking.blockB());
-
-    gebp_kernel<Scalar, Scalar, Index, ResMapper, Traits::mr, Traits::nr, ConjugateLhs, ConjugateRhs> gebp_kernel;
-    gemm_pack_lhs<Scalar, Index, LhsMapper, Traits::mr, Traits::LhsProgress, LhsStorageOrder> pack_lhs;
-    symm_pack_rhs<Scalar, Index, Traits::nr,RhsStorageOrder> pack_rhs;
-
-    for(Index k2=0; k2<size; k2+=kc)
-    {
-      const Index actual_kc = (std::min)(k2+kc,size)-k2;
-
-      pack_rhs(blockB, _rhs, rhsStride, actual_kc, cols, k2);
-
-      // => GEPP
-      for(Index i2=0; i2<rows; i2+=mc)
-      {
-        const Index actual_mc = (std::min)(i2+mc,rows)-i2;
-        pack_lhs(blockA, lhs.getSubMapper(i2, k2), actual_kc, actual_mc);
-
-        gebp_kernel(res.getSubMapper(i2, 0), blockA, blockB, actual_mc, actual_kc, cols, alpha);
-      }
-    }
-  }
-
-} // end namespace internal
-
-/***************************************************************************
-* Wrapper to product_selfadjoint_matrix
-***************************************************************************/
-
-namespace internal {
-  
-template<typename Lhs, int LhsMode, typename Rhs, int RhsMode>
-struct selfadjoint_product_impl<Lhs,LhsMode,false,Rhs,RhsMode,false>
-{
-  typedef typename Product<Lhs,Rhs>::Scalar Scalar;
-  
-  typedef internal::blas_traits<Lhs> LhsBlasTraits;
-  typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType;
-  typedef internal::blas_traits<Rhs> RhsBlasTraits;
-  typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType;
-  
-  enum {
-    LhsIsUpper = (LhsMode&(Upper|Lower))==Upper,
-    LhsIsSelfAdjoint = (LhsMode&SelfAdjoint)==SelfAdjoint,
-    RhsIsUpper = (RhsMode&(Upper|Lower))==Upper,
-    RhsIsSelfAdjoint = (RhsMode&SelfAdjoint)==SelfAdjoint
-  };
-  
-  template<typename Dest>
-  static void run(Dest &dst, const Lhs &a_lhs, const Rhs &a_rhs, const Scalar& alpha)
-  {
-    eigen_assert(dst.rows()==a_lhs.rows() && dst.cols()==a_rhs.cols());
-
-    typename internal::add_const_on_value_type<ActualLhsType>::type lhs = LhsBlasTraits::extract(a_lhs);
-    typename internal::add_const_on_value_type<ActualRhsType>::type rhs = RhsBlasTraits::extract(a_rhs);
-
-    Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(a_lhs)
-                               * RhsBlasTraits::extractScalarFactor(a_rhs);
-
-    typedef internal::gemm_blocking_space<(Dest::Flags&RowMajorBit) ? RowMajor : ColMajor,Scalar,Scalar,
-              Lhs::MaxRowsAtCompileTime, Rhs::MaxColsAtCompileTime, Lhs::MaxColsAtCompileTime,1> BlockingType;
-
-    BlockingType blocking(lhs.rows(), rhs.cols(), lhs.cols(), 1, false);
-
-    internal::product_selfadjoint_matrix<Scalar, Index,
-      EIGEN_LOGICAL_XOR(LhsIsUpper,internal::traits<Lhs>::Flags &RowMajorBit) ? RowMajor : ColMajor, LhsIsSelfAdjoint,
-      NumTraits<Scalar>::IsComplex && EIGEN_LOGICAL_XOR(LhsIsUpper,bool(LhsBlasTraits::NeedToConjugate)),
-      EIGEN_LOGICAL_XOR(RhsIsUpper,internal::traits<Rhs>::Flags &RowMajorBit) ? RowMajor : ColMajor, RhsIsSelfAdjoint,
-      NumTraits<Scalar>::IsComplex && EIGEN_LOGICAL_XOR(RhsIsUpper,bool(RhsBlasTraits::NeedToConjugate)),
-      internal::traits<Dest>::Flags&RowMajorBit  ? RowMajor : ColMajor>
-      ::run(
-        lhs.rows(), rhs.cols(),                 // sizes
-        &lhs.coeffRef(0,0), lhs.outerStride(),  // lhs info
-        &rhs.coeffRef(0,0), rhs.outerStride(),  // rhs info
-        &dst.coeffRef(0,0), dst.outerStride(),  // result info
-        actualAlpha, blocking                   // alpha
-      );
-  }
-};
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_SELFADJOINT_MATRIX_MATRIX_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/SelfadjointMatrixVector.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/SelfadjointMatrixVector.h
deleted file mode 100644
index 3fd180e..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/SelfadjointMatrixVector.h
+++ /dev/null
@@ -1,260 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_SELFADJOINT_MATRIX_VECTOR_H
-#define EIGEN_SELFADJOINT_MATRIX_VECTOR_H
-
-namespace Eigen { 
-
-namespace internal {
-
-/* Optimized selfadjoint matrix * vector product:
- * This algorithm processes 2 columns at onces that allows to both reduce
- * the number of load/stores of the result by a factor 2 and to reduce
- * the instruction dependency.
- */
-
-template<typename Scalar, typename Index, int StorageOrder, int UpLo, bool ConjugateLhs, bool ConjugateRhs, int Version=Specialized>
-struct selfadjoint_matrix_vector_product;
-
-template<typename Scalar, typename Index, int StorageOrder, int UpLo, bool ConjugateLhs, bool ConjugateRhs, int Version>
-struct selfadjoint_matrix_vector_product
-
-{
-static EIGEN_DONT_INLINE void run(
-  Index size,
-  const Scalar*  lhs, Index lhsStride,
-  const Scalar*  rhs,
-  Scalar* res,
-  Scalar alpha);
-};
-
-template<typename Scalar, typename Index, int StorageOrder, int UpLo, bool ConjugateLhs, bool ConjugateRhs, int Version>
-EIGEN_DONT_INLINE void selfadjoint_matrix_vector_product<Scalar,Index,StorageOrder,UpLo,ConjugateLhs,ConjugateRhs,Version>::run(
-  Index size,
-  const Scalar*  lhs, Index lhsStride,
-  const Scalar*  rhs,
-  Scalar* res,
-  Scalar alpha)
-{
-  typedef typename packet_traits<Scalar>::type Packet;
-  typedef typename NumTraits<Scalar>::Real RealScalar;
-  const Index PacketSize = sizeof(Packet)/sizeof(Scalar);
-
-  enum {
-    IsRowMajor = StorageOrder==RowMajor ? 1 : 0,
-    IsLower = UpLo == Lower ? 1 : 0,
-    FirstTriangular = IsRowMajor == IsLower
-  };
-
-  conj_helper<Scalar,Scalar,NumTraits<Scalar>::IsComplex && EIGEN_LOGICAL_XOR(ConjugateLhs,  IsRowMajor), ConjugateRhs> cj0;
-  conj_helper<Scalar,Scalar,NumTraits<Scalar>::IsComplex && EIGEN_LOGICAL_XOR(ConjugateLhs, !IsRowMajor), ConjugateRhs> cj1;
-  conj_helper<RealScalar,Scalar,false, ConjugateRhs> cjd;
-
-  conj_helper<Packet,Packet,NumTraits<Scalar>::IsComplex && EIGEN_LOGICAL_XOR(ConjugateLhs,  IsRowMajor), ConjugateRhs> pcj0;
-  conj_helper<Packet,Packet,NumTraits<Scalar>::IsComplex && EIGEN_LOGICAL_XOR(ConjugateLhs, !IsRowMajor), ConjugateRhs> pcj1;
-
-  Scalar cjAlpha = ConjugateRhs ? numext::conj(alpha) : alpha;
-
-
-  Index bound = (std::max)(Index(0),size-8) & 0xfffffffe;
-  if (FirstTriangular)
-    bound = size - bound;
-
-  for (Index j=FirstTriangular ? bound : 0;
-       j<(FirstTriangular ? size : bound);j+=2)
-  {
-    const Scalar* EIGEN_RESTRICT A0 = lhs + j*lhsStride;
-    const Scalar* EIGEN_RESTRICT A1 = lhs + (j+1)*lhsStride;
-
-    Scalar t0 = cjAlpha * rhs[j];
-    Packet ptmp0 = pset1<Packet>(t0);
-    Scalar t1 = cjAlpha * rhs[j+1];
-    Packet ptmp1 = pset1<Packet>(t1);
-
-    Scalar t2(0);
-    Packet ptmp2 = pset1<Packet>(t2);
-    Scalar t3(0);
-    Packet ptmp3 = pset1<Packet>(t3);
-
-    Index starti = FirstTriangular ? 0 : j+2;
-    Index endi   = FirstTriangular ? j : size;
-    Index alignedStart = (starti) + internal::first_default_aligned(&res[starti], endi-starti);
-    Index alignedEnd = alignedStart + ((endi-alignedStart)/(PacketSize))*(PacketSize);
-
-    res[j]   += cjd.pmul(numext::real(A0[j]), t0);
-    res[j+1] += cjd.pmul(numext::real(A1[j+1]), t1);
-    if(FirstTriangular)
-    {
-      res[j]   += cj0.pmul(A1[j],   t1);
-      t3       += cj1.pmul(A1[j],   rhs[j]);
-    }
-    else
-    {
-      res[j+1] += cj0.pmul(A0[j+1],t0);
-      t2 += cj1.pmul(A0[j+1], rhs[j+1]);
-    }
-
-    for (Index i=starti; i<alignedStart; ++i)
-    {
-      res[i] += cj0.pmul(A0[i], t0) + cj0.pmul(A1[i],t1);
-      t2 += cj1.pmul(A0[i], rhs[i]);
-      t3 += cj1.pmul(A1[i], rhs[i]);
-    }
-    // Yes this an optimization for gcc 4.3 and 4.4 (=> huge speed up)
-    // gcc 4.2 does this optimization automatically.
-    const Scalar* EIGEN_RESTRICT a0It  = A0  + alignedStart;
-    const Scalar* EIGEN_RESTRICT a1It  = A1  + alignedStart;
-    const Scalar* EIGEN_RESTRICT rhsIt = rhs + alignedStart;
-          Scalar* EIGEN_RESTRICT resIt = res + alignedStart;
-    for (Index i=alignedStart; i<alignedEnd; i+=PacketSize)
-    {
-      Packet A0i = ploadu<Packet>(a0It);  a0It  += PacketSize;
-      Packet A1i = ploadu<Packet>(a1It);  a1It  += PacketSize;
-      Packet Bi  = ploadu<Packet>(rhsIt); rhsIt += PacketSize; // FIXME should be aligned in most cases
-      Packet Xi  = pload <Packet>(resIt);
-
-      Xi    = pcj0.pmadd(A0i,ptmp0, pcj0.pmadd(A1i,ptmp1,Xi));
-      ptmp2 = pcj1.pmadd(A0i,  Bi, ptmp2);
-      ptmp3 = pcj1.pmadd(A1i,  Bi, ptmp3);
-      pstore(resIt,Xi); resIt += PacketSize;
-    }
-    for (Index i=alignedEnd; i<endi; i++)
-    {
-      res[i] += cj0.pmul(A0[i], t0) + cj0.pmul(A1[i],t1);
-      t2 += cj1.pmul(A0[i], rhs[i]);
-      t3 += cj1.pmul(A1[i], rhs[i]);
-    }
-
-    res[j]   += alpha * (t2 + predux(ptmp2));
-    res[j+1] += alpha * (t3 + predux(ptmp3));
-  }
-  for (Index j=FirstTriangular ? 0 : bound;j<(FirstTriangular ? bound : size);j++)
-  {
-    const Scalar* EIGEN_RESTRICT A0 = lhs + j*lhsStride;
-
-    Scalar t1 = cjAlpha * rhs[j];
-    Scalar t2(0);
-    res[j] += cjd.pmul(numext::real(A0[j]), t1);
-    for (Index i=FirstTriangular ? 0 : j+1; i<(FirstTriangular ? j : size); i++)
-    {
-      res[i] += cj0.pmul(A0[i], t1);
-      t2 += cj1.pmul(A0[i], rhs[i]);
-    }
-    res[j] += alpha * t2;
-  }
-}
-
-} // end namespace internal 
-
-/***************************************************************************
-* Wrapper to product_selfadjoint_vector
-***************************************************************************/
-
-namespace internal {
-
-template<typename Lhs, int LhsMode, typename Rhs>
-struct selfadjoint_product_impl<Lhs,LhsMode,false,Rhs,0,true>
-{
-  typedef typename Product<Lhs,Rhs>::Scalar Scalar;
-  
-  typedef internal::blas_traits<Lhs> LhsBlasTraits;
-  typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType;
-  typedef typename internal::remove_all<ActualLhsType>::type ActualLhsTypeCleaned;
-  
-  typedef internal::blas_traits<Rhs> RhsBlasTraits;
-  typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType;
-  typedef typename internal::remove_all<ActualRhsType>::type ActualRhsTypeCleaned;
-
-  enum { LhsUpLo = LhsMode&(Upper|Lower) };
-
-  template<typename Dest>
-  static void run(Dest& dest, const Lhs &a_lhs, const Rhs &a_rhs, const Scalar& alpha)
-  {
-    typedef typename Dest::Scalar ResScalar;
-    typedef typename Rhs::Scalar RhsScalar;
-    typedef Map<Matrix<ResScalar,Dynamic,1>, EIGEN_PLAIN_ENUM_MIN(AlignedMax,internal::packet_traits<ResScalar>::size)> MappedDest;
-    
-    eigen_assert(dest.rows()==a_lhs.rows() && dest.cols()==a_rhs.cols());
-
-    typename internal::add_const_on_value_type<ActualLhsType>::type lhs = LhsBlasTraits::extract(a_lhs);
-    typename internal::add_const_on_value_type<ActualRhsType>::type rhs = RhsBlasTraits::extract(a_rhs);
-
-    Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(a_lhs)
-                               * RhsBlasTraits::extractScalarFactor(a_rhs);
-
-    enum {
-      EvalToDest = (Dest::InnerStrideAtCompileTime==1),
-      UseRhs = (ActualRhsTypeCleaned::InnerStrideAtCompileTime==1)
-    };
-    
-    internal::gemv_static_vector_if<ResScalar,Dest::SizeAtCompileTime,Dest::MaxSizeAtCompileTime,!EvalToDest> static_dest;
-    internal::gemv_static_vector_if<RhsScalar,ActualRhsTypeCleaned::SizeAtCompileTime,ActualRhsTypeCleaned::MaxSizeAtCompileTime,!UseRhs> static_rhs;
-
-    ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(),
-                                                  EvalToDest ? dest.data() : static_dest.data());
-                                                  
-    ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhsPtr,rhs.size(),
-        UseRhs ? const_cast<RhsScalar*>(rhs.data()) : static_rhs.data());
-    
-    if(!EvalToDest)
-    {
-      #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
-      Index size = dest.size();
-      EIGEN_DENSE_STORAGE_CTOR_PLUGIN
-      #endif
-      MappedDest(actualDestPtr, dest.size()) = dest;
-    }
-      
-    if(!UseRhs)
-    {
-      #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
-      Index size = rhs.size();
-      EIGEN_DENSE_STORAGE_CTOR_PLUGIN
-      #endif
-      Map<typename ActualRhsTypeCleaned::PlainObject>(actualRhsPtr, rhs.size()) = rhs;
-    }
-      
-      
-    internal::selfadjoint_matrix_vector_product<Scalar, Index, (internal::traits<ActualLhsTypeCleaned>::Flags&RowMajorBit) ? RowMajor : ColMajor,
-                                                int(LhsUpLo), bool(LhsBlasTraits::NeedToConjugate), bool(RhsBlasTraits::NeedToConjugate)>::run
-      (
-        lhs.rows(),                             // size
-        &lhs.coeffRef(0,0),  lhs.outerStride(), // lhs info
-        actualRhsPtr,                           // rhs info
-        actualDestPtr,                          // result info
-        actualAlpha                             // scale factor
-      );
-    
-    if(!EvalToDest)
-      dest = MappedDest(actualDestPtr, dest.size());
-  }
-};
-
-template<typename Lhs, typename Rhs, int RhsMode>
-struct selfadjoint_product_impl<Lhs,0,true,Rhs,RhsMode,false>
-{
-  typedef typename Product<Lhs,Rhs>::Scalar Scalar;
-  enum { RhsUpLo = RhsMode&(Upper|Lower)  };
-
-  template<typename Dest>
-  static void run(Dest& dest, const Lhs &a_lhs, const Rhs &a_rhs, const Scalar& alpha)
-  {
-    // let's simply transpose the product
-    Transpose<Dest> destT(dest);
-    selfadjoint_product_impl<Transpose<const Rhs>, int(RhsUpLo)==Upper ? Lower : Upper, false,
-                             Transpose<const Lhs>, 0, true>::run(destT, a_rhs.transpose(), a_lhs.transpose(), alpha);
-  }
-};
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_SELFADJOINT_MATRIX_VECTOR_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/SelfadjointProduct.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/SelfadjointProduct.h
deleted file mode 100644
index f038d68..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/SelfadjointProduct.h
+++ /dev/null
@@ -1,133 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_SELFADJOINT_PRODUCT_H
-#define EIGEN_SELFADJOINT_PRODUCT_H
-
-/**********************************************************************
-* This file implements a self adjoint product: C += A A^T updating only
-* half of the selfadjoint matrix C.
-* It corresponds to the level 3 SYRK and level 2 SYR Blas routines.
-**********************************************************************/
-
-namespace Eigen { 
-
-
-template<typename Scalar, typename Index, int UpLo, bool ConjLhs, bool ConjRhs>
-struct selfadjoint_rank1_update<Scalar,Index,ColMajor,UpLo,ConjLhs,ConjRhs>
-{
-  static void run(Index size, Scalar* mat, Index stride, const Scalar* vecX, const Scalar* vecY, const Scalar& alpha)
-  {
-    internal::conj_if<ConjRhs> cj;
-    typedef Map<const Matrix<Scalar,Dynamic,1> > OtherMap;
-    typedef typename internal::conditional<ConjLhs,typename OtherMap::ConjugateReturnType,const OtherMap&>::type ConjLhsType;
-    for (Index i=0; i<size; ++i)
-    {
-      Map<Matrix<Scalar,Dynamic,1> >(mat+stride*i+(UpLo==Lower ? i : 0), (UpLo==Lower ? size-i : (i+1)))
-          += (alpha * cj(vecY[i])) * ConjLhsType(OtherMap(vecX+(UpLo==Lower ? i : 0),UpLo==Lower ? size-i : (i+1)));
-    }
-  }
-};
-
-template<typename Scalar, typename Index, int UpLo, bool ConjLhs, bool ConjRhs>
-struct selfadjoint_rank1_update<Scalar,Index,RowMajor,UpLo,ConjLhs,ConjRhs>
-{
-  static void run(Index size, Scalar* mat, Index stride, const Scalar* vecX, const Scalar* vecY, const Scalar& alpha)
-  {
-    selfadjoint_rank1_update<Scalar,Index,ColMajor,UpLo==Lower?Upper:Lower,ConjRhs,ConjLhs>::run(size,mat,stride,vecY,vecX,alpha);
-  }
-};
-
-template<typename MatrixType, typename OtherType, int UpLo, bool OtherIsVector = OtherType::IsVectorAtCompileTime>
-struct selfadjoint_product_selector;
-
-template<typename MatrixType, typename OtherType, int UpLo>
-struct selfadjoint_product_selector<MatrixType,OtherType,UpLo,true>
-{
-  static void run(MatrixType& mat, const OtherType& other, const typename MatrixType::Scalar& alpha)
-  {
-    typedef typename MatrixType::Scalar Scalar;
-    typedef internal::blas_traits<OtherType> OtherBlasTraits;
-    typedef typename OtherBlasTraits::DirectLinearAccessType ActualOtherType;
-    typedef typename internal::remove_all<ActualOtherType>::type _ActualOtherType;
-    typename internal::add_const_on_value_type<ActualOtherType>::type actualOther = OtherBlasTraits::extract(other.derived());
-
-    Scalar actualAlpha = alpha * OtherBlasTraits::extractScalarFactor(other.derived());
-
-    enum {
-      StorageOrder = (internal::traits<MatrixType>::Flags&RowMajorBit) ? RowMajor : ColMajor,
-      UseOtherDirectly = _ActualOtherType::InnerStrideAtCompileTime==1
-    };
-    internal::gemv_static_vector_if<Scalar,OtherType::SizeAtCompileTime,OtherType::MaxSizeAtCompileTime,!UseOtherDirectly> static_other;
-
-    ei_declare_aligned_stack_constructed_variable(Scalar, actualOtherPtr, other.size(),
-      (UseOtherDirectly ? const_cast<Scalar*>(actualOther.data()) : static_other.data()));
-      
-    if(!UseOtherDirectly)
-      Map<typename _ActualOtherType::PlainObject>(actualOtherPtr, actualOther.size()) = actualOther;
-    
-    selfadjoint_rank1_update<Scalar,Index,StorageOrder,UpLo,
-                              OtherBlasTraits::NeedToConjugate  && NumTraits<Scalar>::IsComplex,
-                            (!OtherBlasTraits::NeedToConjugate) && NumTraits<Scalar>::IsComplex>
-          ::run(other.size(), mat.data(), mat.outerStride(), actualOtherPtr, actualOtherPtr, actualAlpha);
-  }
-};
-
-template<typename MatrixType, typename OtherType, int UpLo>
-struct selfadjoint_product_selector<MatrixType,OtherType,UpLo,false>
-{
-  static void run(MatrixType& mat, const OtherType& other, const typename MatrixType::Scalar& alpha)
-  {
-    typedef typename MatrixType::Scalar Scalar;
-    typedef internal::blas_traits<OtherType> OtherBlasTraits;
-    typedef typename OtherBlasTraits::DirectLinearAccessType ActualOtherType;
-    typedef typename internal::remove_all<ActualOtherType>::type _ActualOtherType;
-    typename internal::add_const_on_value_type<ActualOtherType>::type actualOther = OtherBlasTraits::extract(other.derived());
-
-    Scalar actualAlpha = alpha * OtherBlasTraits::extractScalarFactor(other.derived());
-
-    enum {
-      IsRowMajor = (internal::traits<MatrixType>::Flags&RowMajorBit) ? 1 : 0,
-      OtherIsRowMajor = _ActualOtherType::Flags&RowMajorBit ? 1 : 0
-    };
-
-    Index size = mat.cols();
-    Index depth = actualOther.cols();
-
-    typedef internal::gemm_blocking_space<IsRowMajor ? RowMajor : ColMajor,Scalar,Scalar,
-              MatrixType::MaxColsAtCompileTime, MatrixType::MaxColsAtCompileTime, _ActualOtherType::MaxColsAtCompileTime> BlockingType;
-
-    BlockingType blocking(size, size, depth, 1, false);
-
-
-    internal::general_matrix_matrix_triangular_product<Index,
-      Scalar, OtherIsRowMajor ? RowMajor : ColMajor,   OtherBlasTraits::NeedToConjugate  && NumTraits<Scalar>::IsComplex,
-      Scalar, OtherIsRowMajor ? ColMajor : RowMajor, (!OtherBlasTraits::NeedToConjugate) && NumTraits<Scalar>::IsComplex,
-      IsRowMajor ? RowMajor : ColMajor, UpLo>
-      ::run(size, depth,
-            &actualOther.coeffRef(0,0), actualOther.outerStride(), &actualOther.coeffRef(0,0), actualOther.outerStride(),
-            mat.data(), mat.outerStride(), actualAlpha, blocking);
-  }
-};
-
-// high level API
-
-template<typename MatrixType, unsigned int UpLo>
-template<typename DerivedU>
-SelfAdjointView<MatrixType,UpLo>& SelfAdjointView<MatrixType,UpLo>
-::rankUpdate(const MatrixBase<DerivedU>& u, const Scalar& alpha)
-{
-  selfadjoint_product_selector<MatrixType,DerivedU,UpLo>::run(_expression().const_cast_derived(), u.derived(), alpha);
-
-  return *this;
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_SELFADJOINT_PRODUCT_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/SelfadjointRank2Update.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/SelfadjointRank2Update.h
deleted file mode 100644
index 2ae3641..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/SelfadjointRank2Update.h
+++ /dev/null
@@ -1,93 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_SELFADJOINTRANK2UPTADE_H
-#define EIGEN_SELFADJOINTRANK2UPTADE_H
-
-namespace Eigen { 
-
-namespace internal {
-
-/* Optimized selfadjoint matrix += alpha * uv' + conj(alpha)*vu'
- * It corresponds to the Level2 syr2 BLAS routine
- */
-
-template<typename Scalar, typename Index, typename UType, typename VType, int UpLo>
-struct selfadjoint_rank2_update_selector;
-
-template<typename Scalar, typename Index, typename UType, typename VType>
-struct selfadjoint_rank2_update_selector<Scalar,Index,UType,VType,Lower>
-{
-  static void run(Scalar* mat, Index stride, const UType& u, const VType& v, const Scalar& alpha)
-  {
-    const Index size = u.size();
-    for (Index i=0; i<size; ++i)
-    {
-      Map<Matrix<Scalar,Dynamic,1> >(mat+stride*i+i, size-i) +=
-                        (numext::conj(alpha) * numext::conj(u.coeff(i))) * v.tail(size-i)
-                      + (alpha * numext::conj(v.coeff(i))) * u.tail(size-i);
-    }
-  }
-};
-
-template<typename Scalar, typename Index, typename UType, typename VType>
-struct selfadjoint_rank2_update_selector<Scalar,Index,UType,VType,Upper>
-{
-  static void run(Scalar* mat, Index stride, const UType& u, const VType& v, const Scalar& alpha)
-  {
-    const Index size = u.size();
-    for (Index i=0; i<size; ++i)
-      Map<Matrix<Scalar,Dynamic,1> >(mat+stride*i, i+1) +=
-                        (numext::conj(alpha)  * numext::conj(u.coeff(i))) * v.head(i+1)
-                      + (alpha * numext::conj(v.coeff(i))) * u.head(i+1);
-  }
-};
-
-template<bool Cond, typename T> struct conj_expr_if
-  : conditional<!Cond, const T&,
-      CwiseUnaryOp<scalar_conjugate_op<typename traits<T>::Scalar>,T> > {};
-
-} // end namespace internal
-
-template<typename MatrixType, unsigned int UpLo>
-template<typename DerivedU, typename DerivedV>
-SelfAdjointView<MatrixType,UpLo>& SelfAdjointView<MatrixType,UpLo>
-::rankUpdate(const MatrixBase<DerivedU>& u, const MatrixBase<DerivedV>& v, const Scalar& alpha)
-{
-  typedef internal::blas_traits<DerivedU> UBlasTraits;
-  typedef typename UBlasTraits::DirectLinearAccessType ActualUType;
-  typedef typename internal::remove_all<ActualUType>::type _ActualUType;
-  typename internal::add_const_on_value_type<ActualUType>::type actualU = UBlasTraits::extract(u.derived());
-
-  typedef internal::blas_traits<DerivedV> VBlasTraits;
-  typedef typename VBlasTraits::DirectLinearAccessType ActualVType;
-  typedef typename internal::remove_all<ActualVType>::type _ActualVType;
-  typename internal::add_const_on_value_type<ActualVType>::type actualV = VBlasTraits::extract(v.derived());
-
-  // If MatrixType is row major, then we use the routine for lower triangular in the upper triangular case and
-  // vice versa, and take the complex conjugate of all coefficients and vector entries.
-
-  enum { IsRowMajor = (internal::traits<MatrixType>::Flags&RowMajorBit) ? 1 : 0 };
-  Scalar actualAlpha = alpha * UBlasTraits::extractScalarFactor(u.derived())
-                             * numext::conj(VBlasTraits::extractScalarFactor(v.derived()));
-  if (IsRowMajor)
-    actualAlpha = numext::conj(actualAlpha);
-
-  typedef typename internal::remove_all<typename internal::conj_expr_if<IsRowMajor ^ UBlasTraits::NeedToConjugate,_ActualUType>::type>::type UType;
-  typedef typename internal::remove_all<typename internal::conj_expr_if<IsRowMajor ^ VBlasTraits::NeedToConjugate,_ActualVType>::type>::type VType;
-  internal::selfadjoint_rank2_update_selector<Scalar, Index, UType, VType,
-    (IsRowMajor ? int(UpLo==Upper ? Lower : Upper) : UpLo)>
-    ::run(_expression().const_cast_derived().data(),_expression().outerStride(),UType(actualU),VType(actualV),actualAlpha);
-
-  return *this;
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_SELFADJOINTRANK2UPTADE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/TriangularMatrixMatrix.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/TriangularMatrixMatrix.h
deleted file mode 100644
index f784507..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/TriangularMatrixMatrix.h
+++ /dev/null
@@ -1,466 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_TRIANGULAR_MATRIX_MATRIX_H
-#define EIGEN_TRIANGULAR_MATRIX_MATRIX_H
-
-namespace Eigen { 
-
-namespace internal {
-
-// template<typename Scalar, int mr, int StorageOrder, bool Conjugate, int Mode>
-// struct gemm_pack_lhs_triangular
-// {
-//   Matrix<Scalar,mr,mr,
-//   void operator()(Scalar* blockA, const EIGEN_RESTRICT Scalar* _lhs, int lhsStride, int depth, int rows)
-//   {
-//     conj_if<NumTraits<Scalar>::IsComplex && Conjugate> cj;
-//     const_blas_data_mapper<Scalar, StorageOrder> lhs(_lhs,lhsStride);
-//     int count = 0;
-//     const int peeled_mc = (rows/mr)*mr;
-//     for(int i=0; i<peeled_mc; i+=mr)
-//     {
-//       for(int k=0; k<depth; k++)
-//         for(int w=0; w<mr; w++)
-//           blockA[count++] = cj(lhs(i+w, k));
-//     }
-//     for(int i=peeled_mc; i<rows; i++)
-//     {
-//       for(int k=0; k<depth; k++)
-//         blockA[count++] = cj(lhs(i, k));
-//     }
-//   }
-// };
-
-/* Optimized triangular matrix * matrix (_TRMM++) product built on top of
- * the general matrix matrix product.
- */
-template <typename Scalar, typename Index,
-          int Mode, bool LhsIsTriangular,
-          int LhsStorageOrder, bool ConjugateLhs,
-          int RhsStorageOrder, bool ConjugateRhs,
-          int ResStorageOrder, int Version = Specialized>
-struct product_triangular_matrix_matrix;
-
-template <typename Scalar, typename Index,
-          int Mode, bool LhsIsTriangular,
-          int LhsStorageOrder, bool ConjugateLhs,
-          int RhsStorageOrder, bool ConjugateRhs, int Version>
-struct product_triangular_matrix_matrix<Scalar,Index,Mode,LhsIsTriangular,
-                                           LhsStorageOrder,ConjugateLhs,
-                                           RhsStorageOrder,ConjugateRhs,RowMajor,Version>
-{
-  static EIGEN_STRONG_INLINE void run(
-    Index rows, Index cols, Index depth,
-    const Scalar* lhs, Index lhsStride,
-    const Scalar* rhs, Index rhsStride,
-    Scalar* res,       Index resStride,
-    const Scalar& alpha, level3_blocking<Scalar,Scalar>& blocking)
-  {
-    product_triangular_matrix_matrix<Scalar, Index,
-      (Mode&(UnitDiag|ZeroDiag)) | ((Mode&Upper) ? Lower : Upper),
-      (!LhsIsTriangular),
-      RhsStorageOrder==RowMajor ? ColMajor : RowMajor,
-      ConjugateRhs,
-      LhsStorageOrder==RowMajor ? ColMajor : RowMajor,
-      ConjugateLhs,
-      ColMajor>
-      ::run(cols, rows, depth, rhs, rhsStride, lhs, lhsStride, res, resStride, alpha, blocking);
-  }
-};
-
-// implements col-major += alpha * op(triangular) * op(general)
-template <typename Scalar, typename Index, int Mode,
-          int LhsStorageOrder, bool ConjugateLhs,
-          int RhsStorageOrder, bool ConjugateRhs, int Version>
-struct product_triangular_matrix_matrix<Scalar,Index,Mode,true,
-                                           LhsStorageOrder,ConjugateLhs,
-                                           RhsStorageOrder,ConjugateRhs,ColMajor,Version>
-{
-  
-  typedef gebp_traits<Scalar,Scalar> Traits;
-  enum {
-    SmallPanelWidth   = 2 * EIGEN_PLAIN_ENUM_MAX(Traits::mr,Traits::nr),
-    IsLower = (Mode&Lower) == Lower,
-    SetDiag = (Mode&(ZeroDiag|UnitDiag)) ? 0 : 1
-  };
-
-  static EIGEN_DONT_INLINE void run(
-    Index _rows, Index _cols, Index _depth,
-    const Scalar* _lhs, Index lhsStride,
-    const Scalar* _rhs, Index rhsStride,
-    Scalar* res,        Index resStride,
-    const Scalar& alpha, level3_blocking<Scalar,Scalar>& blocking);
-};
-
-template <typename Scalar, typename Index, int Mode,
-          int LhsStorageOrder, bool ConjugateLhs,
-          int RhsStorageOrder, bool ConjugateRhs, int Version>
-EIGEN_DONT_INLINE void product_triangular_matrix_matrix<Scalar,Index,Mode,true,
-                                                        LhsStorageOrder,ConjugateLhs,
-                                                        RhsStorageOrder,ConjugateRhs,ColMajor,Version>::run(
-    Index _rows, Index _cols, Index _depth,
-    const Scalar* _lhs, Index lhsStride,
-    const Scalar* _rhs, Index rhsStride,
-    Scalar* _res,        Index resStride,
-    const Scalar& alpha, level3_blocking<Scalar,Scalar>& blocking)
-  {
-    // strip zeros
-    Index diagSize  = (std::min)(_rows,_depth);
-    Index rows      = IsLower ? _rows : diagSize;
-    Index depth     = IsLower ? diagSize : _depth;
-    Index cols      = _cols;
-    
-    typedef const_blas_data_mapper<Scalar, Index, LhsStorageOrder> LhsMapper;
-    typedef const_blas_data_mapper<Scalar, Index, RhsStorageOrder> RhsMapper;
-    typedef blas_data_mapper<typename Traits::ResScalar, Index, ColMajor> ResMapper;
-    LhsMapper lhs(_lhs,lhsStride);
-    RhsMapper rhs(_rhs,rhsStride);
-    ResMapper res(_res, resStride);
-
-    Index kc = blocking.kc();                   // cache block size along the K direction
-    Index mc = (std::min)(rows,blocking.mc());  // cache block size along the M direction
-    // The small panel size must not be larger than blocking size.
-    // Usually this should never be the case because SmallPanelWidth^2 is very small
-    // compared to L2 cache size, but let's be safe:
-    Index panelWidth = (std::min)(Index(SmallPanelWidth),(std::min)(kc,mc));
-
-    std::size_t sizeA = kc*mc;
-    std::size_t sizeB = kc*cols;
-
-    ei_declare_aligned_stack_constructed_variable(Scalar, blockA, sizeA, blocking.blockA());
-    ei_declare_aligned_stack_constructed_variable(Scalar, blockB, sizeB, blocking.blockB());
-
-    // To work around an "error: member reference base type 'Matrix<...>
-    // (Eigen::internal::constructor_without_unaligned_array_assert (*)())' is
-    // not a structure or union" compilation error in nvcc (tested V8.0.61),
-    // create a dummy internal::constructor_without_unaligned_array_assert
-    // object to pass to the Matrix constructor.
-    internal::constructor_without_unaligned_array_assert a;
-    Matrix<Scalar,SmallPanelWidth,SmallPanelWidth,LhsStorageOrder> triangularBuffer(a);
-    triangularBuffer.setZero();
-    if((Mode&ZeroDiag)==ZeroDiag)
-      triangularBuffer.diagonal().setZero();
-    else
-      triangularBuffer.diagonal().setOnes();
-
-    gebp_kernel<Scalar, Scalar, Index, ResMapper, Traits::mr, Traits::nr, ConjugateLhs, ConjugateRhs> gebp_kernel;
-    gemm_pack_lhs<Scalar, Index, LhsMapper, Traits::mr, Traits::LhsProgress, LhsStorageOrder> pack_lhs;
-    gemm_pack_rhs<Scalar, Index, RhsMapper, Traits::nr,RhsStorageOrder> pack_rhs;
-
-    for(Index k2=IsLower ? depth : 0;
-        IsLower ? k2>0 : k2<depth;
-        IsLower ? k2-=kc : k2+=kc)
-    {
-      Index actual_kc = (std::min)(IsLower ? k2 : depth-k2, kc);
-      Index actual_k2 = IsLower ? k2-actual_kc : k2;
-
-      // align blocks with the end of the triangular part for trapezoidal lhs
-      if((!IsLower)&&(k2<rows)&&(k2+actual_kc>rows))
-      {
-        actual_kc = rows-k2;
-        k2 = k2+actual_kc-kc;
-      }
-
-      pack_rhs(blockB, rhs.getSubMapper(actual_k2,0), actual_kc, cols);
-
-      // the selected lhs's panel has to be split in three different parts:
-      //  1 - the part which is zero => skip it
-      //  2 - the diagonal block => special kernel
-      //  3 - the dense panel below (lower case) or above (upper case) the diagonal block => GEPP
-
-      // the block diagonal, if any:
-      if(IsLower || actual_k2<rows)
-      {
-        // for each small vertical panels of lhs
-        for (Index k1=0; k1<actual_kc; k1+=panelWidth)
-        {
-          Index actualPanelWidth = std::min<Index>(actual_kc-k1, panelWidth);
-          Index lengthTarget = IsLower ? actual_kc-k1-actualPanelWidth : k1;
-          Index startBlock   = actual_k2+k1;
-          Index blockBOffset = k1;
-
-          // => GEBP with the micro triangular block
-          // The trick is to pack this micro block while filling the opposite triangular part with zeros.
-          // To this end we do an extra triangular copy to a small temporary buffer
-          for (Index k=0;k<actualPanelWidth;++k)
-          {
-            if (SetDiag)
-              triangularBuffer.coeffRef(k,k) = lhs(startBlock+k,startBlock+k);
-            for (Index i=IsLower ? k+1 : 0; IsLower ? i<actualPanelWidth : i<k; ++i)
-              triangularBuffer.coeffRef(i,k) = lhs(startBlock+i,startBlock+k);
-          }
-          pack_lhs(blockA, LhsMapper(triangularBuffer.data(), triangularBuffer.outerStride()), actualPanelWidth, actualPanelWidth);
-
-          gebp_kernel(res.getSubMapper(startBlock, 0), blockA, blockB,
-                      actualPanelWidth, actualPanelWidth, cols, alpha,
-                      actualPanelWidth, actual_kc, 0, blockBOffset);
-
-          // GEBP with remaining micro panel
-          if (lengthTarget>0)
-          {
-            Index startTarget  = IsLower ? actual_k2+k1+actualPanelWidth : actual_k2;
-
-            pack_lhs(blockA, lhs.getSubMapper(startTarget,startBlock), actualPanelWidth, lengthTarget);
-
-            gebp_kernel(res.getSubMapper(startTarget, 0), blockA, blockB,
-                        lengthTarget, actualPanelWidth, cols, alpha,
-                        actualPanelWidth, actual_kc, 0, blockBOffset);
-          }
-        }
-      }
-      // the part below (lower case) or above (upper case) the diagonal => GEPP
-      {
-        Index start = IsLower ? k2 : 0;
-        Index end   = IsLower ? rows : (std::min)(actual_k2,rows);
-        for(Index i2=start; i2<end; i2+=mc)
-        {
-          const Index actual_mc = (std::min)(i2+mc,end)-i2;
-          gemm_pack_lhs<Scalar, Index, LhsMapper, Traits::mr,Traits::LhsProgress, LhsStorageOrder,false>()
-            (blockA, lhs.getSubMapper(i2, actual_k2), actual_kc, actual_mc);
-
-          gebp_kernel(res.getSubMapper(i2, 0), blockA, blockB, actual_mc,
-                      actual_kc, cols, alpha, -1, -1, 0, 0);
-        }
-      }
-    }
-  }
-
-// implements col-major += alpha * op(general) * op(triangular)
-template <typename Scalar, typename Index, int Mode,
-          int LhsStorageOrder, bool ConjugateLhs,
-          int RhsStorageOrder, bool ConjugateRhs, int Version>
-struct product_triangular_matrix_matrix<Scalar,Index,Mode,false,
-                                        LhsStorageOrder,ConjugateLhs,
-                                        RhsStorageOrder,ConjugateRhs,ColMajor,Version>
-{
-  typedef gebp_traits<Scalar,Scalar> Traits;
-  enum {
-    SmallPanelWidth   = EIGEN_PLAIN_ENUM_MAX(Traits::mr,Traits::nr),
-    IsLower = (Mode&Lower) == Lower,
-    SetDiag = (Mode&(ZeroDiag|UnitDiag)) ? 0 : 1
-  };
-
-  static EIGEN_DONT_INLINE void run(
-    Index _rows, Index _cols, Index _depth,
-    const Scalar* _lhs, Index lhsStride,
-    const Scalar* _rhs, Index rhsStride,
-    Scalar* res,        Index resStride,
-    const Scalar& alpha, level3_blocking<Scalar,Scalar>& blocking);
-};
-
-template <typename Scalar, typename Index, int Mode,
-          int LhsStorageOrder, bool ConjugateLhs,
-          int RhsStorageOrder, bool ConjugateRhs, int Version>
-EIGEN_DONT_INLINE void product_triangular_matrix_matrix<Scalar,Index,Mode,false,
-                                                        LhsStorageOrder,ConjugateLhs,
-                                                        RhsStorageOrder,ConjugateRhs,ColMajor,Version>::run(
-    Index _rows, Index _cols, Index _depth,
-    const Scalar* _lhs, Index lhsStride,
-    const Scalar* _rhs, Index rhsStride,
-    Scalar* _res,        Index resStride,
-    const Scalar& alpha, level3_blocking<Scalar,Scalar>& blocking)
-  {
-    const Index PacketBytes = packet_traits<Scalar>::size*sizeof(Scalar);
-    // strip zeros
-    Index diagSize  = (std::min)(_cols,_depth);
-    Index rows      = _rows;
-    Index depth     = IsLower ? _depth : diagSize;
-    Index cols      = IsLower ? diagSize : _cols;
-    
-    typedef const_blas_data_mapper<Scalar, Index, LhsStorageOrder> LhsMapper;
-    typedef const_blas_data_mapper<Scalar, Index, RhsStorageOrder> RhsMapper;
-    typedef blas_data_mapper<typename Traits::ResScalar, Index, ColMajor> ResMapper;
-    LhsMapper lhs(_lhs,lhsStride);
-    RhsMapper rhs(_rhs,rhsStride);
-    ResMapper res(_res, resStride);
-
-    Index kc = blocking.kc();                   // cache block size along the K direction
-    Index mc = (std::min)(rows,blocking.mc());  // cache block size along the M direction
-
-    std::size_t sizeA = kc*mc;
-    std::size_t sizeB = kc*cols+EIGEN_MAX_ALIGN_BYTES/sizeof(Scalar);
-
-    ei_declare_aligned_stack_constructed_variable(Scalar, blockA, sizeA, blocking.blockA());
-    ei_declare_aligned_stack_constructed_variable(Scalar, blockB, sizeB, blocking.blockB());
-
-    internal::constructor_without_unaligned_array_assert a;
-    Matrix<Scalar,SmallPanelWidth,SmallPanelWidth,RhsStorageOrder> triangularBuffer(a);
-    triangularBuffer.setZero();
-    if((Mode&ZeroDiag)==ZeroDiag)
-      triangularBuffer.diagonal().setZero();
-    else
-      triangularBuffer.diagonal().setOnes();
-
-    gebp_kernel<Scalar, Scalar, Index, ResMapper, Traits::mr, Traits::nr, ConjugateLhs, ConjugateRhs> gebp_kernel;
-    gemm_pack_lhs<Scalar, Index, LhsMapper, Traits::mr, Traits::LhsProgress, LhsStorageOrder> pack_lhs;
-    gemm_pack_rhs<Scalar, Index, RhsMapper, Traits::nr,RhsStorageOrder> pack_rhs;
-    gemm_pack_rhs<Scalar, Index, RhsMapper, Traits::nr,RhsStorageOrder,false,true> pack_rhs_panel;
-
-    for(Index k2=IsLower ? 0 : depth;
-        IsLower ? k2<depth  : k2>0;
-        IsLower ? k2+=kc   : k2-=kc)
-    {
-      Index actual_kc = (std::min)(IsLower ? depth-k2 : k2, kc);
-      Index actual_k2 = IsLower ? k2 : k2-actual_kc;
-
-      // align blocks with the end of the triangular part for trapezoidal rhs
-      if(IsLower && (k2<cols) && (actual_k2+actual_kc>cols))
-      {
-        actual_kc = cols-k2;
-        k2 = actual_k2 + actual_kc - kc;
-      }
-
-      // remaining size
-      Index rs = IsLower ? (std::min)(cols,actual_k2) : cols - k2;
-      // size of the triangular part
-      Index ts = (IsLower && actual_k2>=cols) ? 0 : actual_kc;
-
-      Scalar* geb = blockB+ts*ts;
-      geb = geb + internal::first_aligned<PacketBytes>(geb,PacketBytes/sizeof(Scalar));
-
-      pack_rhs(geb, rhs.getSubMapper(actual_k2,IsLower ? 0 : k2), actual_kc, rs);
-
-      // pack the triangular part of the rhs padding the unrolled blocks with zeros
-      if(ts>0)
-      {
-        for (Index j2=0; j2<actual_kc; j2+=SmallPanelWidth)
-        {
-          Index actualPanelWidth = std::min<Index>(actual_kc-j2, SmallPanelWidth);
-          Index actual_j2 = actual_k2 + j2;
-          Index panelOffset = IsLower ? j2+actualPanelWidth : 0;
-          Index panelLength = IsLower ? actual_kc-j2-actualPanelWidth : j2;
-          // general part
-          pack_rhs_panel(blockB+j2*actual_kc,
-                         rhs.getSubMapper(actual_k2+panelOffset, actual_j2),
-                         panelLength, actualPanelWidth,
-                         actual_kc, panelOffset);
-
-          // append the triangular part via a temporary buffer
-          for (Index j=0;j<actualPanelWidth;++j)
-          {
-            if (SetDiag)
-              triangularBuffer.coeffRef(j,j) = rhs(actual_j2+j,actual_j2+j);
-            for (Index k=IsLower ? j+1 : 0; IsLower ? k<actualPanelWidth : k<j; ++k)
-              triangularBuffer.coeffRef(k,j) = rhs(actual_j2+k,actual_j2+j);
-          }
-
-          pack_rhs_panel(blockB+j2*actual_kc,
-                         RhsMapper(triangularBuffer.data(), triangularBuffer.outerStride()),
-                         actualPanelWidth, actualPanelWidth,
-                         actual_kc, j2);
-        }
-      }
-
-      for (Index i2=0; i2<rows; i2+=mc)
-      {
-        const Index actual_mc = (std::min)(mc,rows-i2);
-        pack_lhs(blockA, lhs.getSubMapper(i2, actual_k2), actual_kc, actual_mc);
-
-        // triangular kernel
-        if(ts>0)
-        {
-          for (Index j2=0; j2<actual_kc; j2+=SmallPanelWidth)
-          {
-            Index actualPanelWidth = std::min<Index>(actual_kc-j2, SmallPanelWidth);
-            Index panelLength = IsLower ? actual_kc-j2 : j2+actualPanelWidth;
-            Index blockOffset = IsLower ? j2 : 0;
-
-            gebp_kernel(res.getSubMapper(i2, actual_k2 + j2),
-                        blockA, blockB+j2*actual_kc,
-                        actual_mc, panelLength, actualPanelWidth,
-                        alpha,
-                        actual_kc, actual_kc,  // strides
-                        blockOffset, blockOffset);// offsets
-          }
-        }
-        gebp_kernel(res.getSubMapper(i2, IsLower ? 0 : k2),
-                    blockA, geb, actual_mc, actual_kc, rs,
-                    alpha,
-                    -1, -1, 0, 0);
-      }
-    }
-  }
-
-/***************************************************************************
-* Wrapper to product_triangular_matrix_matrix
-***************************************************************************/
-
-} // end namespace internal
-
-namespace internal {
-template<int Mode, bool LhsIsTriangular, typename Lhs, typename Rhs>
-struct triangular_product_impl<Mode,LhsIsTriangular,Lhs,false,Rhs,false>
-{
-  template<typename Dest> static void run(Dest& dst, const Lhs &a_lhs, const Rhs &a_rhs, const typename Dest::Scalar& alpha)
-  {
-    typedef typename Lhs::Scalar  LhsScalar;
-    typedef typename Rhs::Scalar  RhsScalar;
-    typedef typename Dest::Scalar Scalar;
-    
-    typedef internal::blas_traits<Lhs> LhsBlasTraits;
-    typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType;
-    typedef typename internal::remove_all<ActualLhsType>::type ActualLhsTypeCleaned;
-    typedef internal::blas_traits<Rhs> RhsBlasTraits;
-    typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType;
-    typedef typename internal::remove_all<ActualRhsType>::type ActualRhsTypeCleaned;
-    
-    typename internal::add_const_on_value_type<ActualLhsType>::type lhs = LhsBlasTraits::extract(a_lhs);
-    typename internal::add_const_on_value_type<ActualRhsType>::type rhs = RhsBlasTraits::extract(a_rhs);
-
-    LhsScalar lhs_alpha = LhsBlasTraits::extractScalarFactor(a_lhs);
-    RhsScalar rhs_alpha = RhsBlasTraits::extractScalarFactor(a_rhs);
-    Scalar actualAlpha = alpha * lhs_alpha * rhs_alpha;
-
-    typedef internal::gemm_blocking_space<(Dest::Flags&RowMajorBit) ? RowMajor : ColMajor,Scalar,Scalar,
-              Lhs::MaxRowsAtCompileTime, Rhs::MaxColsAtCompileTime, Lhs::MaxColsAtCompileTime,4> BlockingType;
-
-    enum { IsLower = (Mode&Lower) == Lower };
-    Index stripedRows  = ((!LhsIsTriangular) || (IsLower))  ? lhs.rows() : (std::min)(lhs.rows(),lhs.cols());
-    Index stripedCols  = ((LhsIsTriangular)  || (!IsLower)) ? rhs.cols() : (std::min)(rhs.cols(),rhs.rows());
-    Index stripedDepth = LhsIsTriangular ? ((!IsLower) ? lhs.cols() : (std::min)(lhs.cols(),lhs.rows()))
-                                         : ((IsLower)  ? rhs.rows() : (std::min)(rhs.rows(),rhs.cols()));
-
-    BlockingType blocking(stripedRows, stripedCols, stripedDepth, 1, false);
-
-    internal::product_triangular_matrix_matrix<Scalar, Index,
-      Mode, LhsIsTriangular,
-      (internal::traits<ActualLhsTypeCleaned>::Flags&RowMajorBit) ? RowMajor : ColMajor, LhsBlasTraits::NeedToConjugate,
-      (internal::traits<ActualRhsTypeCleaned>::Flags&RowMajorBit) ? RowMajor : ColMajor, RhsBlasTraits::NeedToConjugate,
-      (internal::traits<Dest          >::Flags&RowMajorBit) ? RowMajor : ColMajor>
-      ::run(
-        stripedRows, stripedCols, stripedDepth,   // sizes
-        &lhs.coeffRef(0,0), lhs.outerStride(),    // lhs info
-        &rhs.coeffRef(0,0), rhs.outerStride(),    // rhs info
-        &dst.coeffRef(0,0), dst.outerStride(),    // result info
-        actualAlpha, blocking
-      );
-
-    // Apply correction if the diagonal is unit and a scalar factor was nested:
-    if ((Mode&UnitDiag)==UnitDiag)
-    {
-      if (LhsIsTriangular && lhs_alpha!=LhsScalar(1))
-      {
-        Index diagSize = (std::min)(lhs.rows(),lhs.cols());
-        dst.topRows(diagSize) -= ((lhs_alpha-LhsScalar(1))*a_rhs).topRows(diagSize);
-      }
-      else if ((!LhsIsTriangular) && rhs_alpha!=RhsScalar(1))
-      {
-        Index diagSize = (std::min)(rhs.rows(),rhs.cols());
-        dst.leftCols(diagSize) -= (rhs_alpha-RhsScalar(1))*a_lhs.leftCols(diagSize);
-      }
-    }
-  }
-};
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_TRIANGULAR_MATRIX_MATRIX_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/TriangularMatrixVector.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/TriangularMatrixVector.h
deleted file mode 100644
index 76bfa15..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/TriangularMatrixVector.h
+++ /dev/null
@@ -1,350 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_TRIANGULARMATRIXVECTOR_H
-#define EIGEN_TRIANGULARMATRIXVECTOR_H
-
-namespace Eigen {
-
-namespace internal {
-
-template<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs, int StorageOrder, int Version=Specialized>
-struct triangular_matrix_vector_product;
-
-template<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs, int Version>
-struct triangular_matrix_vector_product<Index,Mode,LhsScalar,ConjLhs,RhsScalar,ConjRhs,ColMajor,Version>
-{
-  typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar>::ReturnType ResScalar;
-  enum {
-    IsLower = ((Mode&Lower)==Lower),
-    HasUnitDiag = (Mode & UnitDiag)==UnitDiag,
-    HasZeroDiag = (Mode & ZeroDiag)==ZeroDiag
-  };
-  static EIGEN_DONT_INLINE  void run(Index _rows, Index _cols, const LhsScalar* _lhs, Index lhsStride,
-                                     const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, const RhsScalar& alpha);
-};
-
-template<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs, int Version>
-EIGEN_DONT_INLINE void triangular_matrix_vector_product<Index,Mode,LhsScalar,ConjLhs,RhsScalar,ConjRhs,ColMajor,Version>
-  ::run(Index _rows, Index _cols, const LhsScalar* _lhs, Index lhsStride,
-        const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, const RhsScalar& alpha)
-  {
-    static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH;
-    Index size = (std::min)(_rows,_cols);
-    Index rows = IsLower ? _rows : (std::min)(_rows,_cols);
-    Index cols = IsLower ? (std::min)(_rows,_cols) : _cols;
-
-    typedef Map<const Matrix<LhsScalar,Dynamic,Dynamic,ColMajor>, 0, OuterStride<> > LhsMap;
-    const LhsMap lhs(_lhs,rows,cols,OuterStride<>(lhsStride));
-    typename conj_expr_if<ConjLhs,LhsMap>::type cjLhs(lhs);
-
-    typedef Map<const Matrix<RhsScalar,Dynamic,1>, 0, InnerStride<> > RhsMap;
-    const RhsMap rhs(_rhs,cols,InnerStride<>(rhsIncr));
-    typename conj_expr_if<ConjRhs,RhsMap>::type cjRhs(rhs);
-
-    typedef Map<Matrix<ResScalar,Dynamic,1> > ResMap;
-    ResMap res(_res,rows);
-
-    typedef const_blas_data_mapper<LhsScalar,Index,ColMajor> LhsMapper;
-    typedef const_blas_data_mapper<RhsScalar,Index,RowMajor> RhsMapper;
-
-    for (Index pi=0; pi<size; pi+=PanelWidth)
-    {
-      Index actualPanelWidth = (std::min)(PanelWidth, size-pi);
-      for (Index k=0; k<actualPanelWidth; ++k)
-      {
-        Index i = pi + k;
-        Index s = IsLower ? ((HasUnitDiag||HasZeroDiag) ? i+1 : i ) : pi;
-        Index r = IsLower ? actualPanelWidth-k : k+1;
-        if ((!(HasUnitDiag||HasZeroDiag)) || (--r)>0)
-          res.segment(s,r) += (alpha * cjRhs.coeff(i)) * cjLhs.col(i).segment(s,r);
-        if (HasUnitDiag)
-          res.coeffRef(i) += alpha * cjRhs.coeff(i);
-      }
-      Index r = IsLower ? rows - pi - actualPanelWidth : pi;
-      if (r>0)
-      {
-        Index s = IsLower ? pi+actualPanelWidth : 0;
-        general_matrix_vector_product<Index,LhsScalar,LhsMapper,ColMajor,ConjLhs,RhsScalar,RhsMapper,ConjRhs,BuiltIn>::run(
-            r, actualPanelWidth,
-            LhsMapper(&lhs.coeffRef(s,pi), lhsStride),
-            RhsMapper(&rhs.coeffRef(pi), rhsIncr),
-            &res.coeffRef(s), resIncr, alpha);
-      }
-    }
-    if((!IsLower) && cols>size)
-    {
-      general_matrix_vector_product<Index,LhsScalar,LhsMapper,ColMajor,ConjLhs,RhsScalar,RhsMapper,ConjRhs>::run(
-          rows, cols-size,
-          LhsMapper(&lhs.coeffRef(0,size), lhsStride),
-          RhsMapper(&rhs.coeffRef(size), rhsIncr),
-          _res, resIncr, alpha);
-    }
-  }
-
-template<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs,int Version>
-struct triangular_matrix_vector_product<Index,Mode,LhsScalar,ConjLhs,RhsScalar,ConjRhs,RowMajor,Version>
-{
-  typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar>::ReturnType ResScalar;
-  enum {
-    IsLower = ((Mode&Lower)==Lower),
-    HasUnitDiag = (Mode & UnitDiag)==UnitDiag,
-    HasZeroDiag = (Mode & ZeroDiag)==ZeroDiag
-  };
-  static EIGEN_DONT_INLINE void run(Index _rows, Index _cols, const LhsScalar* _lhs, Index lhsStride,
-                                    const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, const ResScalar& alpha);
-};
-
-template<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs,int Version>
-EIGEN_DONT_INLINE void triangular_matrix_vector_product<Index,Mode,LhsScalar,ConjLhs,RhsScalar,ConjRhs,RowMajor,Version>
-  ::run(Index _rows, Index _cols, const LhsScalar* _lhs, Index lhsStride,
-        const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, const ResScalar& alpha)
-  {
-    static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH;
-    Index diagSize = (std::min)(_rows,_cols);
-    Index rows = IsLower ? _rows : diagSize;
-    Index cols = IsLower ? diagSize : _cols;
-
-    typedef Map<const Matrix<LhsScalar,Dynamic,Dynamic,RowMajor>, 0, OuterStride<> > LhsMap;
-    const LhsMap lhs(_lhs,rows,cols,OuterStride<>(lhsStride));
-    typename conj_expr_if<ConjLhs,LhsMap>::type cjLhs(lhs);
-
-    typedef Map<const Matrix<RhsScalar,Dynamic,1> > RhsMap;
-    const RhsMap rhs(_rhs,cols);
-    typename conj_expr_if<ConjRhs,RhsMap>::type cjRhs(rhs);
-
-    typedef Map<Matrix<ResScalar,Dynamic,1>, 0, InnerStride<> > ResMap;
-    ResMap res(_res,rows,InnerStride<>(resIncr));
-
-    typedef const_blas_data_mapper<LhsScalar,Index,RowMajor> LhsMapper;
-    typedef const_blas_data_mapper<RhsScalar,Index,RowMajor> RhsMapper;
-
-    for (Index pi=0; pi<diagSize; pi+=PanelWidth)
-    {
-      Index actualPanelWidth = (std::min)(PanelWidth, diagSize-pi);
-      for (Index k=0; k<actualPanelWidth; ++k)
-      {
-        Index i = pi + k;
-        Index s = IsLower ? pi  : ((HasUnitDiag||HasZeroDiag) ? i+1 : i);
-        Index r = IsLower ? k+1 : actualPanelWidth-k;
-        if ((!(HasUnitDiag||HasZeroDiag)) || (--r)>0)
-          res.coeffRef(i) += alpha * (cjLhs.row(i).segment(s,r).cwiseProduct(cjRhs.segment(s,r).transpose())).sum();
-        if (HasUnitDiag)
-          res.coeffRef(i) += alpha * cjRhs.coeff(i);
-      }
-      Index r = IsLower ? pi : cols - pi - actualPanelWidth;
-      if (r>0)
-      {
-        Index s = IsLower ? 0 : pi + actualPanelWidth;
-        general_matrix_vector_product<Index,LhsScalar,LhsMapper,RowMajor,ConjLhs,RhsScalar,RhsMapper,ConjRhs,BuiltIn>::run(
-            actualPanelWidth, r,
-            LhsMapper(&lhs.coeffRef(pi,s), lhsStride),
-            RhsMapper(&rhs.coeffRef(s), rhsIncr),
-            &res.coeffRef(pi), resIncr, alpha);
-      }
-    }
-    if(IsLower && rows>diagSize)
-    {
-      general_matrix_vector_product<Index,LhsScalar,LhsMapper,RowMajor,ConjLhs,RhsScalar,RhsMapper,ConjRhs>::run(
-            rows-diagSize, cols,
-            LhsMapper(&lhs.coeffRef(diagSize,0), lhsStride),
-            RhsMapper(&rhs.coeffRef(0), rhsIncr),
-            &res.coeffRef(diagSize), resIncr, alpha);
-    }
-  }
-
-/***************************************************************************
-* Wrapper to product_triangular_vector
-***************************************************************************/
-
-template<int Mode,int StorageOrder>
-struct trmv_selector;
-
-} // end namespace internal
-
-namespace internal {
-
-template<int Mode, typename Lhs, typename Rhs>
-struct triangular_product_impl<Mode,true,Lhs,false,Rhs,true>
-{
-  template<typename Dest> static void run(Dest& dst, const Lhs &lhs, const Rhs &rhs, const typename Dest::Scalar& alpha)
-  {
-    eigen_assert(dst.rows()==lhs.rows() && dst.cols()==rhs.cols());
-  
-    internal::trmv_selector<Mode,(int(internal::traits<Lhs>::Flags)&RowMajorBit) ? RowMajor : ColMajor>::run(lhs, rhs, dst, alpha);
-  }
-};
-
-template<int Mode, typename Lhs, typename Rhs>
-struct triangular_product_impl<Mode,false,Lhs,true,Rhs,false>
-{
-  template<typename Dest> static void run(Dest& dst, const Lhs &lhs, const Rhs &rhs, const typename Dest::Scalar& alpha)
-  {
-    eigen_assert(dst.rows()==lhs.rows() && dst.cols()==rhs.cols());
-
-    Transpose<Dest> dstT(dst);
-    internal::trmv_selector<(Mode & (UnitDiag|ZeroDiag)) | ((Mode & Lower) ? Upper : Lower),
-                            (int(internal::traits<Rhs>::Flags)&RowMajorBit) ? ColMajor : RowMajor>
-            ::run(rhs.transpose(),lhs.transpose(), dstT, alpha);
-  }
-};
-
-} // end namespace internal
-
-namespace internal {
-
-// TODO: find a way to factorize this piece of code with gemv_selector since the logic is exactly the same.
-  
-template<int Mode> struct trmv_selector<Mode,ColMajor>
-{
-  template<typename Lhs, typename Rhs, typename Dest>
-  static void run(const Lhs &lhs, const Rhs &rhs, Dest& dest, const typename Dest::Scalar& alpha)
-  {
-    typedef typename Lhs::Scalar      LhsScalar;
-    typedef typename Rhs::Scalar      RhsScalar;
-    typedef typename Dest::Scalar     ResScalar;
-    typedef typename Dest::RealScalar RealScalar;
-    
-    typedef internal::blas_traits<Lhs> LhsBlasTraits;
-    typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType;
-    typedef internal::blas_traits<Rhs> RhsBlasTraits;
-    typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType;
-    
-    typedef Map<Matrix<ResScalar,Dynamic,1>, EIGEN_PLAIN_ENUM_MIN(AlignedMax,internal::packet_traits<ResScalar>::size)> MappedDest;
-
-    typename internal::add_const_on_value_type<ActualLhsType>::type actualLhs = LhsBlasTraits::extract(lhs);
-    typename internal::add_const_on_value_type<ActualRhsType>::type actualRhs = RhsBlasTraits::extract(rhs);
-
-    LhsScalar lhs_alpha = LhsBlasTraits::extractScalarFactor(lhs);
-    RhsScalar rhs_alpha = RhsBlasTraits::extractScalarFactor(rhs);
-    ResScalar actualAlpha = alpha * lhs_alpha * rhs_alpha;
-
-    enum {
-      // FIXME find a way to allow an inner stride on the result if packet_traits<Scalar>::size==1
-      // on, the other hand it is good for the cache to pack the vector anyways...
-      EvalToDestAtCompileTime = Dest::InnerStrideAtCompileTime==1,
-      ComplexByReal = (NumTraits<LhsScalar>::IsComplex) && (!NumTraits<RhsScalar>::IsComplex),
-      MightCannotUseDest = (Dest::InnerStrideAtCompileTime!=1) || ComplexByReal
-    };
-
-    gemv_static_vector_if<ResScalar,Dest::SizeAtCompileTime,Dest::MaxSizeAtCompileTime,MightCannotUseDest> static_dest;
-
-    bool alphaIsCompatible = (!ComplexByReal) || (numext::imag(actualAlpha)==RealScalar(0));
-    bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible;
-
-    RhsScalar compatibleAlpha = get_factor<ResScalar,RhsScalar>::run(actualAlpha);
-
-    ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(),
-                                                  evalToDest ? dest.data() : static_dest.data());
-
-    if(!evalToDest)
-    {
-      #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
-      Index size = dest.size();
-      EIGEN_DENSE_STORAGE_CTOR_PLUGIN
-      #endif
-      if(!alphaIsCompatible)
-      {
-        MappedDest(actualDestPtr, dest.size()).setZero();
-        compatibleAlpha = RhsScalar(1);
-      }
-      else
-        MappedDest(actualDestPtr, dest.size()) = dest;
-    }
-
-    internal::triangular_matrix_vector_product
-      <Index,Mode,
-       LhsScalar, LhsBlasTraits::NeedToConjugate,
-       RhsScalar, RhsBlasTraits::NeedToConjugate,
-       ColMajor>
-      ::run(actualLhs.rows(),actualLhs.cols(),
-            actualLhs.data(),actualLhs.outerStride(),
-            actualRhs.data(),actualRhs.innerStride(),
-            actualDestPtr,1,compatibleAlpha);
-
-    if (!evalToDest)
-    {
-      if(!alphaIsCompatible)
-        dest += actualAlpha * MappedDest(actualDestPtr, dest.size());
-      else
-        dest = MappedDest(actualDestPtr, dest.size());
-    }
-
-    if ( ((Mode&UnitDiag)==UnitDiag) && (lhs_alpha!=LhsScalar(1)) )
-    {
-      Index diagSize = (std::min)(lhs.rows(),lhs.cols());
-      dest.head(diagSize) -= (lhs_alpha-LhsScalar(1))*rhs.head(diagSize);
-    }
-  }
-};
-
-template<int Mode> struct trmv_selector<Mode,RowMajor>
-{
-  template<typename Lhs, typename Rhs, typename Dest>
-  static void run(const Lhs &lhs, const Rhs &rhs, Dest& dest, const typename Dest::Scalar& alpha)
-  {
-    typedef typename Lhs::Scalar      LhsScalar;
-    typedef typename Rhs::Scalar      RhsScalar;
-    typedef typename Dest::Scalar     ResScalar;
-    
-    typedef internal::blas_traits<Lhs> LhsBlasTraits;
-    typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType;
-    typedef internal::blas_traits<Rhs> RhsBlasTraits;
-    typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType;
-    typedef typename internal::remove_all<ActualRhsType>::type ActualRhsTypeCleaned;
-
-    typename add_const<ActualLhsType>::type actualLhs = LhsBlasTraits::extract(lhs);
-    typename add_const<ActualRhsType>::type actualRhs = RhsBlasTraits::extract(rhs);
-
-    LhsScalar lhs_alpha = LhsBlasTraits::extractScalarFactor(lhs);
-    RhsScalar rhs_alpha = RhsBlasTraits::extractScalarFactor(rhs);
-    ResScalar actualAlpha = alpha * lhs_alpha * rhs_alpha;
-
-    enum {
-      DirectlyUseRhs = ActualRhsTypeCleaned::InnerStrideAtCompileTime==1
-    };
-
-    gemv_static_vector_if<RhsScalar,ActualRhsTypeCleaned::SizeAtCompileTime,ActualRhsTypeCleaned::MaxSizeAtCompileTime,!DirectlyUseRhs> static_rhs;
-
-    ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhsPtr,actualRhs.size(),
-        DirectlyUseRhs ? const_cast<RhsScalar*>(actualRhs.data()) : static_rhs.data());
-
-    if(!DirectlyUseRhs)
-    {
-      #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
-      Index size = actualRhs.size();
-      EIGEN_DENSE_STORAGE_CTOR_PLUGIN
-      #endif
-      Map<typename ActualRhsTypeCleaned::PlainObject>(actualRhsPtr, actualRhs.size()) = actualRhs;
-    }
-
-    internal::triangular_matrix_vector_product
-      <Index,Mode,
-       LhsScalar, LhsBlasTraits::NeedToConjugate,
-       RhsScalar, RhsBlasTraits::NeedToConjugate,
-       RowMajor>
-      ::run(actualLhs.rows(),actualLhs.cols(),
-            actualLhs.data(),actualLhs.outerStride(),
-            actualRhsPtr,1,
-            dest.data(),dest.innerStride(),
-            actualAlpha);
-
-    if ( ((Mode&UnitDiag)==UnitDiag) && (lhs_alpha!=LhsScalar(1)) )
-    {
-      Index diagSize = (std::min)(lhs.rows(),lhs.cols());
-      dest.head(diagSize) -= (lhs_alpha-LhsScalar(1))*rhs.head(diagSize);
-    }
-  }
-};
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_TRIANGULARMATRIXVECTOR_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/TriangularSolverMatrix.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/TriangularSolverMatrix.h
deleted file mode 100644
index 223c38b..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/TriangularSolverMatrix.h
+++ /dev/null
@@ -1,335 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_TRIANGULAR_SOLVER_MATRIX_H
-#define EIGEN_TRIANGULAR_SOLVER_MATRIX_H
-
-namespace Eigen { 
-
-namespace internal {
-
-// if the rhs is row major, let's transpose the product
-template <typename Scalar, typename Index, int Side, int Mode, bool Conjugate, int TriStorageOrder>
-struct triangular_solve_matrix<Scalar,Index,Side,Mode,Conjugate,TriStorageOrder,RowMajor>
-{
-  static void run(
-    Index size, Index cols,
-    const Scalar*  tri, Index triStride,
-    Scalar* _other, Index otherStride,
-    level3_blocking<Scalar,Scalar>& blocking)
-  {
-    triangular_solve_matrix<
-      Scalar, Index, Side==OnTheLeft?OnTheRight:OnTheLeft,
-      (Mode&UnitDiag) | ((Mode&Upper) ? Lower : Upper),
-      NumTraits<Scalar>::IsComplex && Conjugate,
-      TriStorageOrder==RowMajor ? ColMajor : RowMajor, ColMajor>
-      ::run(size, cols, tri, triStride, _other, otherStride, blocking);
-  }
-};
-
-/* Optimized triangular solver with multiple right hand side and the triangular matrix on the left
- */
-template <typename Scalar, typename Index, int Mode, bool Conjugate, int TriStorageOrder>
-struct triangular_solve_matrix<Scalar,Index,OnTheLeft,Mode,Conjugate,TriStorageOrder,ColMajor>
-{
-  static EIGEN_DONT_INLINE void run(
-    Index size, Index otherSize,
-    const Scalar* _tri, Index triStride,
-    Scalar* _other, Index otherStride,
-    level3_blocking<Scalar,Scalar>& blocking);
-};
-template <typename Scalar, typename Index, int Mode, bool Conjugate, int TriStorageOrder>
-EIGEN_DONT_INLINE void triangular_solve_matrix<Scalar,Index,OnTheLeft,Mode,Conjugate,TriStorageOrder,ColMajor>::run(
-    Index size, Index otherSize,
-    const Scalar* _tri, Index triStride,
-    Scalar* _other, Index otherStride,
-    level3_blocking<Scalar,Scalar>& blocking)
-  {
-    Index cols = otherSize;
-
-    typedef const_blas_data_mapper<Scalar, Index, TriStorageOrder> TriMapper;
-    typedef blas_data_mapper<Scalar, Index, ColMajor> OtherMapper;
-    TriMapper tri(_tri, triStride);
-    OtherMapper other(_other, otherStride);
-
-    typedef gebp_traits<Scalar,Scalar> Traits;
-
-    enum {
-      SmallPanelWidth   = EIGEN_PLAIN_ENUM_MAX(Traits::mr,Traits::nr),
-      IsLower = (Mode&Lower) == Lower
-    };
-
-    Index kc = blocking.kc();                   // cache block size along the K direction
-    Index mc = (std::min)(size,blocking.mc());  // cache block size along the M direction
-
-    std::size_t sizeA = kc*mc;
-    std::size_t sizeB = kc*cols;
-
-    ei_declare_aligned_stack_constructed_variable(Scalar, blockA, sizeA, blocking.blockA());
-    ei_declare_aligned_stack_constructed_variable(Scalar, blockB, sizeB, blocking.blockB());
-
-    conj_if<Conjugate> conj;
-    gebp_kernel<Scalar, Scalar, Index, OtherMapper, Traits::mr, Traits::nr, Conjugate, false> gebp_kernel;
-    gemm_pack_lhs<Scalar, Index, TriMapper, Traits::mr, Traits::LhsProgress, TriStorageOrder> pack_lhs;
-    gemm_pack_rhs<Scalar, Index, OtherMapper, Traits::nr, ColMajor, false, true> pack_rhs;
-
-    // the goal here is to subdivise the Rhs panels such that we keep some cache
-    // coherence when accessing the rhs elements
-    std::ptrdiff_t l1, l2, l3;
-    manage_caching_sizes(GetAction, &l1, &l2, &l3);
-    Index subcols = cols>0 ? l2/(4 * sizeof(Scalar) * std::max<Index>(otherStride,size)) : 0;
-    subcols = std::max<Index>((subcols/Traits::nr)*Traits::nr, Traits::nr);
-
-    for(Index k2=IsLower ? 0 : size;
-        IsLower ? k2<size : k2>0;
-        IsLower ? k2+=kc : k2-=kc)
-    {
-      const Index actual_kc = (std::min)(IsLower ? size-k2 : k2, kc);
-
-      // We have selected and packed a big horizontal panel R1 of rhs. Let B be the packed copy of this panel,
-      // and R2 the remaining part of rhs. The corresponding vertical panel of lhs is split into
-      // A11 (the triangular part) and A21 the remaining rectangular part.
-      // Then the high level algorithm is:
-      //  - B = R1                    => general block copy (done during the next step)
-      //  - R1 = A11^-1 B             => tricky part
-      //  - update B from the new R1  => actually this has to be performed continuously during the above step
-      //  - R2 -= A21 * B             => GEPP
-
-      // The tricky part: compute R1 = A11^-1 B while updating B from R1
-      // The idea is to split A11 into multiple small vertical panels.
-      // Each panel can be split into a small triangular part T1k which is processed without optimization,
-      // and the remaining small part T2k which is processed using gebp with appropriate block strides
-      for(Index j2=0; j2<cols; j2+=subcols)
-      {
-        Index actual_cols = (std::min)(cols-j2,subcols);
-        // for each small vertical panels [T1k^T, T2k^T]^T of lhs
-        for (Index k1=0; k1<actual_kc; k1+=SmallPanelWidth)
-        {
-          Index actualPanelWidth = std::min<Index>(actual_kc-k1, SmallPanelWidth);
-          // tr solve
-          for (Index k=0; k<actualPanelWidth; ++k)
-          {
-            // TODO write a small kernel handling this (can be shared with trsv)
-            Index i  = IsLower ? k2+k1+k : k2-k1-k-1;
-            Index rs = actualPanelWidth - k - 1; // remaining size
-            Index s  = TriStorageOrder==RowMajor ? (IsLower ? k2+k1 : i+1)
-                                                 :  IsLower ? i+1 : i-rs;
-
-            Scalar a = (Mode & UnitDiag) ? Scalar(1) : Scalar(1)/conj(tri(i,i));
-            for (Index j=j2; j<j2+actual_cols; ++j)
-            {
-              if (TriStorageOrder==RowMajor)
-              {
-                Scalar b(0);
-                const Scalar* l = &tri(i,s);
-                Scalar* r = &other(s,j);
-                for (Index i3=0; i3<k; ++i3)
-                  b += conj(l[i3]) * r[i3];
-
-                other(i,j) = (other(i,j) - b)*a;
-              }
-              else
-              {
-                Scalar b = (other(i,j) *= a);
-                Scalar* r = &other(s,j);
-                const Scalar* l = &tri(s,i);
-                for (Index i3=0;i3<rs;++i3)
-                  r[i3] -= b * conj(l[i3]);
-              }
-            }
-          }
-
-          Index lengthTarget = actual_kc-k1-actualPanelWidth;
-          Index startBlock   = IsLower ? k2+k1 : k2-k1-actualPanelWidth;
-          Index blockBOffset = IsLower ? k1 : lengthTarget;
-
-          // update the respective rows of B from other
-          pack_rhs(blockB+actual_kc*j2, other.getSubMapper(startBlock,j2), actualPanelWidth, actual_cols, actual_kc, blockBOffset);
-
-          // GEBP
-          if (lengthTarget>0)
-          {
-            Index startTarget  = IsLower ? k2+k1+actualPanelWidth : k2-actual_kc;
-
-            pack_lhs(blockA, tri.getSubMapper(startTarget,startBlock), actualPanelWidth, lengthTarget);
-
-            gebp_kernel(other.getSubMapper(startTarget,j2), blockA, blockB+actual_kc*j2, lengthTarget, actualPanelWidth, actual_cols, Scalar(-1),
-                        actualPanelWidth, actual_kc, 0, blockBOffset);
-          }
-        }
-      }
-      
-      // R2 -= A21 * B => GEPP
-      {
-        Index start = IsLower ? k2+kc : 0;
-        Index end   = IsLower ? size : k2-kc;
-        for(Index i2=start; i2<end; i2+=mc)
-        {
-          const Index actual_mc = (std::min)(mc,end-i2);
-          if (actual_mc>0)
-          {
-            pack_lhs(blockA, tri.getSubMapper(i2, IsLower ? k2 : k2-kc), actual_kc, actual_mc);
-
-            gebp_kernel(other.getSubMapper(i2, 0), blockA, blockB, actual_mc, actual_kc, cols, Scalar(-1), -1, -1, 0, 0);
-          }
-        }
-      }
-    }
-  }
-
-/* Optimized triangular solver with multiple left hand sides and the triangular matrix on the right
- */
-template <typename Scalar, typename Index, int Mode, bool Conjugate, int TriStorageOrder>
-struct triangular_solve_matrix<Scalar,Index,OnTheRight,Mode,Conjugate,TriStorageOrder,ColMajor>
-{
-  static EIGEN_DONT_INLINE void run(
-    Index size, Index otherSize,
-    const Scalar* _tri, Index triStride,
-    Scalar* _other, Index otherStride,
-    level3_blocking<Scalar,Scalar>& blocking);
-};
-template <typename Scalar, typename Index, int Mode, bool Conjugate, int TriStorageOrder>
-EIGEN_DONT_INLINE void triangular_solve_matrix<Scalar,Index,OnTheRight,Mode,Conjugate,TriStorageOrder,ColMajor>::run(
-    Index size, Index otherSize,
-    const Scalar* _tri, Index triStride,
-    Scalar* _other, Index otherStride,
-    level3_blocking<Scalar,Scalar>& blocking)
-  {
-    Index rows = otherSize;
-    typedef typename NumTraits<Scalar>::Real RealScalar;
-
-    typedef blas_data_mapper<Scalar, Index, ColMajor> LhsMapper;
-    typedef const_blas_data_mapper<Scalar, Index, TriStorageOrder> RhsMapper;
-    LhsMapper lhs(_other, otherStride);
-    RhsMapper rhs(_tri, triStride);
-
-    typedef gebp_traits<Scalar,Scalar> Traits;
-    enum {
-      RhsStorageOrder   = TriStorageOrder,
-      SmallPanelWidth   = EIGEN_PLAIN_ENUM_MAX(Traits::mr,Traits::nr),
-      IsLower = (Mode&Lower) == Lower
-    };
-
-    Index kc = blocking.kc();                   // cache block size along the K direction
-    Index mc = (std::min)(rows,blocking.mc());  // cache block size along the M direction
-
-    std::size_t sizeA = kc*mc;
-    std::size_t sizeB = kc*size;
-
-    ei_declare_aligned_stack_constructed_variable(Scalar, blockA, sizeA, blocking.blockA());
-    ei_declare_aligned_stack_constructed_variable(Scalar, blockB, sizeB, blocking.blockB());
-
-    conj_if<Conjugate> conj;
-    gebp_kernel<Scalar, Scalar, Index, LhsMapper, Traits::mr, Traits::nr, false, Conjugate> gebp_kernel;
-    gemm_pack_rhs<Scalar, Index, RhsMapper, Traits::nr, RhsStorageOrder> pack_rhs;
-    gemm_pack_rhs<Scalar, Index, RhsMapper, Traits::nr, RhsStorageOrder,false,true> pack_rhs_panel;
-    gemm_pack_lhs<Scalar, Index, LhsMapper, Traits::mr, Traits::LhsProgress, ColMajor, false, true> pack_lhs_panel;
-
-    for(Index k2=IsLower ? size : 0;
-        IsLower ? k2>0 : k2<size;
-        IsLower ? k2-=kc : k2+=kc)
-    {
-      const Index actual_kc = (std::min)(IsLower ? k2 : size-k2, kc);
-      Index actual_k2 = IsLower ? k2-actual_kc : k2 ;
-
-      Index startPanel = IsLower ? 0 : k2+actual_kc;
-      Index rs = IsLower ? actual_k2 : size - actual_k2 - actual_kc;
-      Scalar* geb = blockB+actual_kc*actual_kc;
-
-      if (rs>0) pack_rhs(geb, rhs.getSubMapper(actual_k2,startPanel), actual_kc, rs);
-
-      // triangular packing (we only pack the panels off the diagonal,
-      // neglecting the blocks overlapping the diagonal
-      {
-        for (Index j2=0; j2<actual_kc; j2+=SmallPanelWidth)
-        {
-          Index actualPanelWidth = std::min<Index>(actual_kc-j2, SmallPanelWidth);
-          Index actual_j2 = actual_k2 + j2;
-          Index panelOffset = IsLower ? j2+actualPanelWidth : 0;
-          Index panelLength = IsLower ? actual_kc-j2-actualPanelWidth : j2;
-
-          if (panelLength>0)
-          pack_rhs_panel(blockB+j2*actual_kc,
-                         rhs.getSubMapper(actual_k2+panelOffset, actual_j2),
-                         panelLength, actualPanelWidth,
-                         actual_kc, panelOffset);
-        }
-      }
-
-      for(Index i2=0; i2<rows; i2+=mc)
-      {
-        const Index actual_mc = (std::min)(mc,rows-i2);
-
-        // triangular solver kernel
-        {
-          // for each small block of the diagonal (=> vertical panels of rhs)
-          for (Index j2 = IsLower
-                      ? (actual_kc - ((actual_kc%SmallPanelWidth) ? Index(actual_kc%SmallPanelWidth)
-                                                                  : Index(SmallPanelWidth)))
-                      : 0;
-               IsLower ? j2>=0 : j2<actual_kc;
-               IsLower ? j2-=SmallPanelWidth : j2+=SmallPanelWidth)
-          {
-            Index actualPanelWidth = std::min<Index>(actual_kc-j2, SmallPanelWidth);
-            Index absolute_j2 = actual_k2 + j2;
-            Index panelOffset = IsLower ? j2+actualPanelWidth : 0;
-            Index panelLength = IsLower ? actual_kc - j2 - actualPanelWidth : j2;
-
-            // GEBP
-            if(panelLength>0)
-            {
-              gebp_kernel(lhs.getSubMapper(i2,absolute_j2),
-                          blockA, blockB+j2*actual_kc,
-                          actual_mc, panelLength, actualPanelWidth,
-                          Scalar(-1),
-                          actual_kc, actual_kc, // strides
-                          panelOffset, panelOffset); // offsets
-            }
-
-            // unblocked triangular solve
-            for (Index k=0; k<actualPanelWidth; ++k)
-            {
-              Index j = IsLower ? absolute_j2+actualPanelWidth-k-1 : absolute_j2+k;
-
-              Scalar* r = &lhs(i2,j);
-              for (Index k3=0; k3<k; ++k3)
-              {
-                Scalar b = conj(rhs(IsLower ? j+1+k3 : absolute_j2+k3,j));
-                Scalar* a = &lhs(i2,IsLower ? j+1+k3 : absolute_j2+k3);
-                for (Index i=0; i<actual_mc; ++i)
-                  r[i] -= a[i] * b;
-              }
-              if((Mode & UnitDiag)==0)
-              {
-                Scalar inv_rjj = RealScalar(1)/conj(rhs(j,j));
-                for (Index i=0; i<actual_mc; ++i)
-                  r[i] *= inv_rjj;
-              }
-            }
-
-            // pack the just computed part of lhs to A
-            pack_lhs_panel(blockA, LhsMapper(_other+absolute_j2*otherStride+i2, otherStride),
-                           actualPanelWidth, actual_mc,
-                           actual_kc, j2);
-          }
-        }
-
-        if (rs>0)
-          gebp_kernel(lhs.getSubMapper(i2, startPanel), blockA, geb,
-                      actual_mc, actual_kc, rs, Scalar(-1),
-                      -1, -1, 0, 0);
-      }
-    }
-  }
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_TRIANGULAR_SOLVER_MATRIX_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/TriangularSolverVector.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/TriangularSolverVector.h
deleted file mode 100644
index b994759..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/products/TriangularSolverVector.h
+++ /dev/null
@@ -1,145 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_TRIANGULAR_SOLVER_VECTOR_H
-#define EIGEN_TRIANGULAR_SOLVER_VECTOR_H
-
-namespace Eigen {
-
-namespace internal {
-
-template<typename LhsScalar, typename RhsScalar, typename Index, int Mode, bool Conjugate, int StorageOrder>
-struct triangular_solve_vector<LhsScalar, RhsScalar, Index, OnTheRight, Mode, Conjugate, StorageOrder>
-{
-  static void run(Index size, const LhsScalar* _lhs, Index lhsStride, RhsScalar* rhs)
-  {
-    triangular_solve_vector<LhsScalar,RhsScalar,Index,OnTheLeft,
-        ((Mode&Upper)==Upper ? Lower : Upper) | (Mode&UnitDiag),
-        Conjugate,StorageOrder==RowMajor?ColMajor:RowMajor
-      >::run(size, _lhs, lhsStride, rhs);
-  }
-};
-
-// forward and backward substitution, row-major, rhs is a vector
-template<typename LhsScalar, typename RhsScalar, typename Index, int Mode, bool Conjugate>
-struct triangular_solve_vector<LhsScalar, RhsScalar, Index, OnTheLeft, Mode, Conjugate, RowMajor>
-{
-  enum {
-    IsLower = ((Mode&Lower)==Lower)
-  };
-  static void run(Index size, const LhsScalar* _lhs, Index lhsStride, RhsScalar* rhs)
-  {
-    typedef Map<const Matrix<LhsScalar,Dynamic,Dynamic,RowMajor>, 0, OuterStride<> > LhsMap;
-    const LhsMap lhs(_lhs,size,size,OuterStride<>(lhsStride));
-
-    typedef const_blas_data_mapper<LhsScalar,Index,RowMajor> LhsMapper;
-    typedef const_blas_data_mapper<RhsScalar,Index,ColMajor> RhsMapper;
-
-    typename internal::conditional<
-                          Conjugate,
-                          const CwiseUnaryOp<typename internal::scalar_conjugate_op<LhsScalar>,LhsMap>,
-                          const LhsMap&>
-                        ::type cjLhs(lhs);
-    static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH;
-    for(Index pi=IsLower ? 0 : size;
-        IsLower ? pi<size : pi>0;
-        IsLower ? pi+=PanelWidth : pi-=PanelWidth)
-    {
-      Index actualPanelWidth = (std::min)(IsLower ? size - pi : pi, PanelWidth);
-
-      Index r = IsLower ? pi : size - pi; // remaining size
-      if (r > 0)
-      {
-        // let's directly call the low level product function because:
-        // 1 - it is faster to compile
-        // 2 - it is slighlty faster at runtime
-        Index startRow = IsLower ? pi : pi-actualPanelWidth;
-        Index startCol = IsLower ? 0 : pi;
-
-        general_matrix_vector_product<Index,LhsScalar,LhsMapper,RowMajor,Conjugate,RhsScalar,RhsMapper,false>::run(
-          actualPanelWidth, r,
-          LhsMapper(&lhs.coeffRef(startRow,startCol), lhsStride),
-          RhsMapper(rhs + startCol, 1),
-          rhs + startRow, 1,
-          RhsScalar(-1));
-      }
-
-      for(Index k=0; k<actualPanelWidth; ++k)
-      {
-        Index i = IsLower ? pi+k : pi-k-1;
-        Index s = IsLower ? pi   : i+1;
-        if (k>0)
-          rhs[i] -= (cjLhs.row(i).segment(s,k).transpose().cwiseProduct(Map<const Matrix<RhsScalar,Dynamic,1> >(rhs+s,k))).sum();
-
-        if(!(Mode & UnitDiag))
-          rhs[i] /= cjLhs(i,i);
-      }
-    }
-  }
-};
-
-// forward and backward substitution, column-major, rhs is a vector
-template<typename LhsScalar, typename RhsScalar, typename Index, int Mode, bool Conjugate>
-struct triangular_solve_vector<LhsScalar, RhsScalar, Index, OnTheLeft, Mode, Conjugate, ColMajor>
-{
-  enum {
-    IsLower = ((Mode&Lower)==Lower)
-  };
-  static void run(Index size, const LhsScalar* _lhs, Index lhsStride, RhsScalar* rhs)
-  {
-    typedef Map<const Matrix<LhsScalar,Dynamic,Dynamic,ColMajor>, 0, OuterStride<> > LhsMap;
-    const LhsMap lhs(_lhs,size,size,OuterStride<>(lhsStride));
-    typedef const_blas_data_mapper<LhsScalar,Index,ColMajor> LhsMapper;
-    typedef const_blas_data_mapper<RhsScalar,Index,ColMajor> RhsMapper;
-    typename internal::conditional<Conjugate,
-                                   const CwiseUnaryOp<typename internal::scalar_conjugate_op<LhsScalar>,LhsMap>,
-                                   const LhsMap&
-                                  >::type cjLhs(lhs);
-    static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH;
-
-    for(Index pi=IsLower ? 0 : size;
-        IsLower ? pi<size : pi>0;
-        IsLower ? pi+=PanelWidth : pi-=PanelWidth)
-    {
-      Index actualPanelWidth = (std::min)(IsLower ? size - pi : pi, PanelWidth);
-      Index startBlock = IsLower ? pi : pi-actualPanelWidth;
-      Index endBlock = IsLower ? pi + actualPanelWidth : 0;
-
-      for(Index k=0; k<actualPanelWidth; ++k)
-      {
-        Index i = IsLower ? pi+k : pi-k-1;
-        if(!(Mode & UnitDiag))
-          rhs[i] /= cjLhs.coeff(i,i);
-
-        Index r = actualPanelWidth - k - 1; // remaining size
-        Index s = IsLower ? i+1 : i-r;
-        if (r>0)
-          Map<Matrix<RhsScalar,Dynamic,1> >(rhs+s,r) -= rhs[i] * cjLhs.col(i).segment(s,r);
-      }
-      Index r = IsLower ? size - endBlock : startBlock; // remaining size
-      if (r > 0)
-      {
-        // let's directly call the low level product function because:
-        // 1 - it is faster to compile
-        // 2 - it is slighlty faster at runtime
-        general_matrix_vector_product<Index,LhsScalar,LhsMapper,ColMajor,Conjugate,RhsScalar,RhsMapper,false>::run(
-            r, actualPanelWidth,
-            LhsMapper(&lhs.coeffRef(endBlock,startBlock), lhsStride),
-            RhsMapper(rhs+startBlock, 1),
-            rhs+endBlock, 1, RhsScalar(-1));
-      }
-    }
-  }
-};
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_TRIANGULAR_SOLVER_VECTOR_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/BlasUtil.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/BlasUtil.h
deleted file mode 100644
index 6e6ee11..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/BlasUtil.h
+++ /dev/null
@@ -1,398 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_BLASUTIL_H
-#define EIGEN_BLASUTIL_H
-
-// This file contains many lightweight helper classes used to
-// implement and control fast level 2 and level 3 BLAS-like routines.
-
-namespace Eigen {
-
-namespace internal {
-
-// forward declarations
-template<typename LhsScalar, typename RhsScalar, typename Index, typename DataMapper, int mr, int nr, bool ConjugateLhs=false, bool ConjugateRhs=false>
-struct gebp_kernel;
-
-template<typename Scalar, typename Index, typename DataMapper, int nr, int StorageOrder, bool Conjugate = false, bool PanelMode=false>
-struct gemm_pack_rhs;
-
-template<typename Scalar, typename Index, typename DataMapper, int Pack1, int Pack2, int StorageOrder, bool Conjugate = false, bool PanelMode = false>
-struct gemm_pack_lhs;
-
-template<
-  typename Index,
-  typename LhsScalar, int LhsStorageOrder, bool ConjugateLhs,
-  typename RhsScalar, int RhsStorageOrder, bool ConjugateRhs,
-  int ResStorageOrder>
-struct general_matrix_matrix_product;
-
-template<typename Index,
-         typename LhsScalar, typename LhsMapper, int LhsStorageOrder, bool ConjugateLhs,
-         typename RhsScalar, typename RhsMapper, bool ConjugateRhs, int Version=Specialized>
-struct general_matrix_vector_product;
-
-
-template<bool Conjugate> struct conj_if;
-
-template<> struct conj_if<true> {
-  template<typename T>
-  inline T operator()(const T& x) const { return numext::conj(x); }
-  template<typename T>
-  inline T pconj(const T& x) const { return internal::pconj(x); }
-};
-
-template<> struct conj_if<false> {
-  template<typename T>
-  inline const T& operator()(const T& x) const { return x; }
-  template<typename T>
-  inline const T& pconj(const T& x) const { return x; }
-};
-
-// Generic implementation for custom complex types.
-template<typename LhsScalar, typename RhsScalar, bool ConjLhs, bool ConjRhs>
-struct conj_helper
-{
-  typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar>::ReturnType Scalar;
-
-  EIGEN_STRONG_INLINE Scalar pmadd(const LhsScalar& x, const RhsScalar& y, const Scalar& c) const
-  { return padd(c, pmul(x,y)); }
-
-  EIGEN_STRONG_INLINE Scalar pmul(const LhsScalar& x, const RhsScalar& y) const
-  { return conj_if<ConjLhs>()(x) *  conj_if<ConjRhs>()(y); }
-};
-
-template<typename Scalar> struct conj_helper<Scalar,Scalar,false,false>
-{
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar pmadd(const Scalar& x, const Scalar& y, const Scalar& c) const { return internal::pmadd(x,y,c); }
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const Scalar& y) const { return internal::pmul(x,y); }
-};
-
-template<typename RealScalar> struct conj_helper<std::complex<RealScalar>, std::complex<RealScalar>, false,true>
-{
-  typedef std::complex<RealScalar> Scalar;
-  EIGEN_STRONG_INLINE Scalar pmadd(const Scalar& x, const Scalar& y, const Scalar& c) const
-  { return c + pmul(x,y); }
-
-  EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const Scalar& y) const
-  { return Scalar(numext::real(x)*numext::real(y) + numext::imag(x)*numext::imag(y), numext::imag(x)*numext::real(y) - numext::real(x)*numext::imag(y)); }
-};
-
-template<typename RealScalar> struct conj_helper<std::complex<RealScalar>, std::complex<RealScalar>, true,false>
-{
-  typedef std::complex<RealScalar> Scalar;
-  EIGEN_STRONG_INLINE Scalar pmadd(const Scalar& x, const Scalar& y, const Scalar& c) const
-  { return c + pmul(x,y); }
-
-  EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const Scalar& y) const
-  { return Scalar(numext::real(x)*numext::real(y) + numext::imag(x)*numext::imag(y), numext::real(x)*numext::imag(y) - numext::imag(x)*numext::real(y)); }
-};
-
-template<typename RealScalar> struct conj_helper<std::complex<RealScalar>, std::complex<RealScalar>, true,true>
-{
-  typedef std::complex<RealScalar> Scalar;
-  EIGEN_STRONG_INLINE Scalar pmadd(const Scalar& x, const Scalar& y, const Scalar& c) const
-  { return c + pmul(x,y); }
-
-  EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const Scalar& y) const
-  { return Scalar(numext::real(x)*numext::real(y) - numext::imag(x)*numext::imag(y), - numext::real(x)*numext::imag(y) - numext::imag(x)*numext::real(y)); }
-};
-
-template<typename RealScalar,bool Conj> struct conj_helper<std::complex<RealScalar>, RealScalar, Conj,false>
-{
-  typedef std::complex<RealScalar> Scalar;
-  EIGEN_STRONG_INLINE Scalar pmadd(const Scalar& x, const RealScalar& y, const Scalar& c) const
-  { return padd(c, pmul(x,y)); }
-  EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const RealScalar& y) const
-  { return conj_if<Conj>()(x)*y; }
-};
-
-template<typename RealScalar,bool Conj> struct conj_helper<RealScalar, std::complex<RealScalar>, false,Conj>
-{
-  typedef std::complex<RealScalar> Scalar;
-  EIGEN_STRONG_INLINE Scalar pmadd(const RealScalar& x, const Scalar& y, const Scalar& c) const
-  { return padd(c, pmul(x,y)); }
-  EIGEN_STRONG_INLINE Scalar pmul(const RealScalar& x, const Scalar& y) const
-  { return x*conj_if<Conj>()(y); }
-};
-
-template<typename From,typename To> struct get_factor {
-  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE To run(const From& x) { return To(x); }
-};
-
-template<typename Scalar> struct get_factor<Scalar,typename NumTraits<Scalar>::Real> {
-  EIGEN_DEVICE_FUNC
-  static EIGEN_STRONG_INLINE typename NumTraits<Scalar>::Real run(const Scalar& x) { return numext::real(x); }
-};
-
-
-template<typename Scalar, typename Index>
-class BlasVectorMapper {
-  public:
-  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE BlasVectorMapper(Scalar *data) : m_data(data) {}
-
-  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar operator()(Index i) const {
-    return m_data[i];
-  }
-  template <typename Packet, int AlignmentType>
-  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet load(Index i) const {
-    return ploadt<Packet, AlignmentType>(m_data + i);
-  }
-
-  template <typename Packet>
-  EIGEN_DEVICE_FUNC bool aligned(Index i) const {
-    return (UIntPtr(m_data+i)%sizeof(Packet))==0;
-  }
-
-  protected:
-  Scalar* m_data;
-};
-
-template<typename Scalar, typename Index, int AlignmentType>
-class BlasLinearMapper {
-  public:
-  typedef typename packet_traits<Scalar>::type Packet;
-  typedef typename packet_traits<Scalar>::half HalfPacket;
-
-  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE BlasLinearMapper(Scalar *data) : m_data(data) {}
-
-  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void prefetch(int i) const {
-    internal::prefetch(&operator()(i));
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar& operator()(Index i) const {
-    return m_data[i];
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet loadPacket(Index i) const {
-    return ploadt<Packet, AlignmentType>(m_data + i);
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE HalfPacket loadHalfPacket(Index i) const {
-    return ploadt<HalfPacket, AlignmentType>(m_data + i);
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacket(Index i, const Packet &p) const {
-    pstoret<Scalar, Packet, AlignmentType>(m_data + i, p);
-  }
-
-  protected:
-  Scalar *m_data;
-};
-
-// Lightweight helper class to access matrix coefficients.
-template<typename Scalar, typename Index, int StorageOrder, int AlignmentType = Unaligned>
-class blas_data_mapper {
-  public:
-  typedef typename packet_traits<Scalar>::type Packet;
-  typedef typename packet_traits<Scalar>::half HalfPacket;
-
-  typedef BlasLinearMapper<Scalar, Index, AlignmentType> LinearMapper;
-  typedef BlasVectorMapper<Scalar, Index> VectorMapper;
-
-  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE blas_data_mapper(Scalar* data, Index stride) : m_data(data), m_stride(stride) {}
-
-  EIGEN_DEVICE_FUNC  EIGEN_ALWAYS_INLINE blas_data_mapper<Scalar, Index, StorageOrder, AlignmentType>
-  getSubMapper(Index i, Index j) const {
-    return blas_data_mapper<Scalar, Index, StorageOrder, AlignmentType>(&operator()(i, j), m_stride);
-  }
-
-  EIGEN_DEVICE_FUNC  EIGEN_ALWAYS_INLINE LinearMapper getLinearMapper(Index i, Index j) const {
-    return LinearMapper(&operator()(i, j));
-  }
-
-  EIGEN_DEVICE_FUNC  EIGEN_ALWAYS_INLINE VectorMapper getVectorMapper(Index i, Index j) const {
-    return VectorMapper(&operator()(i, j));
-  }
-
-
-  EIGEN_DEVICE_FUNC
-  EIGEN_ALWAYS_INLINE Scalar& operator()(Index i, Index j) const {
-    return m_data[StorageOrder==RowMajor ? j + i*m_stride : i + j*m_stride];
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet loadPacket(Index i, Index j) const {
-    return ploadt<Packet, AlignmentType>(&operator()(i, j));
-  }
-
-  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE HalfPacket loadHalfPacket(Index i, Index j) const {
-    return ploadt<HalfPacket, AlignmentType>(&operator()(i, j));
-  }
-
-  template<typename SubPacket>
-  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void scatterPacket(Index i, Index j, const SubPacket &p) const {
-    pscatter<Scalar, SubPacket>(&operator()(i, j), p, m_stride);
-  }
-
-  template<typename SubPacket>
-  EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE SubPacket gatherPacket(Index i, Index j) const {
-    return pgather<Scalar, SubPacket>(&operator()(i, j), m_stride);
-  }
-
-  EIGEN_DEVICE_FUNC const Index stride() const { return m_stride; }
-  EIGEN_DEVICE_FUNC const Scalar* data() const { return m_data; }
-
-  EIGEN_DEVICE_FUNC Index firstAligned(Index size) const {
-    if (UIntPtr(m_data)%sizeof(Scalar)) {
-      return -1;
-    }
-    return internal::first_default_aligned(m_data, size);
-  }
-
-  protected:
-  Scalar* EIGEN_RESTRICT m_data;
-  const Index m_stride;
-};
-
-// lightweight helper class to access matrix coefficients (const version)
-template<typename Scalar, typename Index, int StorageOrder>
-class const_blas_data_mapper : public blas_data_mapper<const Scalar, Index, StorageOrder> {
-  public:
-  EIGEN_ALWAYS_INLINE const_blas_data_mapper(const Scalar *data, Index stride) : blas_data_mapper<const Scalar, Index, StorageOrder>(data, stride) {}
-
-  EIGEN_ALWAYS_INLINE const_blas_data_mapper<Scalar, Index, StorageOrder> getSubMapper(Index i, Index j) const {
-    return const_blas_data_mapper<Scalar, Index, StorageOrder>(&(this->operator()(i, j)), this->m_stride);
-  }
-};
-
-
-/* Helper class to analyze the factors of a Product expression.
- * In particular it allows to pop out operator-, scalar multiples,
- * and conjugate */
-template<typename XprType> struct blas_traits
-{
-  typedef typename traits<XprType>::Scalar Scalar;
-  typedef const XprType& ExtractType;
-  typedef XprType _ExtractType;
-  enum {
-    IsComplex = NumTraits<Scalar>::IsComplex,
-    IsTransposed = false,
-    NeedToConjugate = false,
-    HasUsableDirectAccess = (    (int(XprType::Flags)&DirectAccessBit)
-                              && (   bool(XprType::IsVectorAtCompileTime)
-                                  || int(inner_stride_at_compile_time<XprType>::ret) == 1)
-                             ) ?  1 : 0
-  };
-  typedef typename conditional<bool(HasUsableDirectAccess),
-    ExtractType,
-    typename _ExtractType::PlainObject
-    >::type DirectLinearAccessType;
-  static inline ExtractType extract(const XprType& x) { return x; }
-  static inline const Scalar extractScalarFactor(const XprType&) { return Scalar(1); }
-};
-
-// pop conjugate
-template<typename Scalar, typename NestedXpr>
-struct blas_traits<CwiseUnaryOp<scalar_conjugate_op<Scalar>, NestedXpr> >
- : blas_traits<NestedXpr>
-{
-  typedef blas_traits<NestedXpr> Base;
-  typedef CwiseUnaryOp<scalar_conjugate_op<Scalar>, NestedXpr> XprType;
-  typedef typename Base::ExtractType ExtractType;
-
-  enum {
-    IsComplex = NumTraits<Scalar>::IsComplex,
-    NeedToConjugate = Base::NeedToConjugate ? 0 : IsComplex
-  };
-  static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); }
-  static inline Scalar extractScalarFactor(const XprType& x) { return conj(Base::extractScalarFactor(x.nestedExpression())); }
-};
-
-// pop scalar multiple
-template<typename Scalar, typename NestedXpr, typename Plain>
-struct blas_traits<CwiseBinaryOp<scalar_product_op<Scalar>, const CwiseNullaryOp<scalar_constant_op<Scalar>,Plain>, NestedXpr> >
- : blas_traits<NestedXpr>
-{
-  typedef blas_traits<NestedXpr> Base;
-  typedef CwiseBinaryOp<scalar_product_op<Scalar>, const CwiseNullaryOp<scalar_constant_op<Scalar>,Plain>, NestedXpr> XprType;
-  typedef typename Base::ExtractType ExtractType;
-  static inline ExtractType extract(const XprType& x) { return Base::extract(x.rhs()); }
-  static inline Scalar extractScalarFactor(const XprType& x)
-  { return x.lhs().functor().m_other * Base::extractScalarFactor(x.rhs()); }
-};
-template<typename Scalar, typename NestedXpr, typename Plain>
-struct blas_traits<CwiseBinaryOp<scalar_product_op<Scalar>, NestedXpr, const CwiseNullaryOp<scalar_constant_op<Scalar>,Plain> > >
- : blas_traits<NestedXpr>
-{
-  typedef blas_traits<NestedXpr> Base;
-  typedef CwiseBinaryOp<scalar_product_op<Scalar>, NestedXpr, const CwiseNullaryOp<scalar_constant_op<Scalar>,Plain> > XprType;
-  typedef typename Base::ExtractType ExtractType;
-  static inline ExtractType extract(const XprType& x) { return Base::extract(x.lhs()); }
-  static inline Scalar extractScalarFactor(const XprType& x)
-  { return Base::extractScalarFactor(x.lhs()) * x.rhs().functor().m_other; }
-};
-template<typename Scalar, typename Plain1, typename Plain2>
-struct blas_traits<CwiseBinaryOp<scalar_product_op<Scalar>, const CwiseNullaryOp<scalar_constant_op<Scalar>,Plain1>,
-                                                            const CwiseNullaryOp<scalar_constant_op<Scalar>,Plain2> > >
- : blas_traits<CwiseNullaryOp<scalar_constant_op<Scalar>,Plain1> >
-{};
-
-// pop opposite
-template<typename Scalar, typename NestedXpr>
-struct blas_traits<CwiseUnaryOp<scalar_opposite_op<Scalar>, NestedXpr> >
- : blas_traits<NestedXpr>
-{
-  typedef blas_traits<NestedXpr> Base;
-  typedef CwiseUnaryOp<scalar_opposite_op<Scalar>, NestedXpr> XprType;
-  typedef typename Base::ExtractType ExtractType;
-  static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); }
-  static inline Scalar extractScalarFactor(const XprType& x)
-  { return - Base::extractScalarFactor(x.nestedExpression()); }
-};
-
-// pop/push transpose
-template<typename NestedXpr>
-struct blas_traits<Transpose<NestedXpr> >
- : blas_traits<NestedXpr>
-{
-  typedef typename NestedXpr::Scalar Scalar;
-  typedef blas_traits<NestedXpr> Base;
-  typedef Transpose<NestedXpr> XprType;
-  typedef Transpose<const typename Base::_ExtractType>  ExtractType; // const to get rid of a compile error; anyway blas traits are only used on the RHS
-  typedef Transpose<const typename Base::_ExtractType> _ExtractType;
-  typedef typename conditional<bool(Base::HasUsableDirectAccess),
-    ExtractType,
-    typename ExtractType::PlainObject
-    >::type DirectLinearAccessType;
-  enum {
-    IsTransposed = Base::IsTransposed ? 0 : 1
-  };
-  static inline ExtractType extract(const XprType& x) { return ExtractType(Base::extract(x.nestedExpression())); }
-  static inline Scalar extractScalarFactor(const XprType& x) { return Base::extractScalarFactor(x.nestedExpression()); }
-};
-
-template<typename T>
-struct blas_traits<const T>
-     : blas_traits<T>
-{};
-
-template<typename T, bool HasUsableDirectAccess=blas_traits<T>::HasUsableDirectAccess>
-struct extract_data_selector {
-  static const typename T::Scalar* run(const T& m)
-  {
-    return blas_traits<T>::extract(m).data();
-  }
-};
-
-template<typename T>
-struct extract_data_selector<T,false> {
-  static typename T::Scalar* run(const T&) { return 0; }
-};
-
-template<typename T> const typename T::Scalar* extract_data(const T& m)
-{
-  return extract_data_selector<T>::run(m);
-}
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_BLASUTIL_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/Constants.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/Constants.h
deleted file mode 100644
index 7587d68..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/Constants.h
+++ /dev/null
@@ -1,547 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2015 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_CONSTANTS_H
-#define EIGEN_CONSTANTS_H
-
-namespace Eigen {
-
-/** This value means that a positive quantity (e.g., a size) is not known at compile-time, and that instead the value is
-  * stored in some runtime variable.
-  *
-  * Changing the value of Dynamic breaks the ABI, as Dynamic is often used as a template parameter for Matrix.
-  */
-const int Dynamic = -1;
-
-/** This value means that a signed quantity (e.g., a signed index) is not known at compile-time, and that instead its value
-  * has to be specified at runtime.
-  */
-const int DynamicIndex = 0xffffff;
-
-/** This value means +Infinity; it is currently used only as the p parameter to MatrixBase::lpNorm<int>().
-  * The value Infinity there means the L-infinity norm.
-  */
-const int Infinity = -1;
-
-/** This value means that the cost to evaluate an expression coefficient is either very expensive or
-  * cannot be known at compile time.
-  *
-  * This value has to be positive to (1) simplify cost computation, and (2) allow to distinguish between a very expensive and very very expensive expressions.
-  * It thus must also be large enough to make sure unrolling won't happen and that sub expressions will be evaluated, but not too large to avoid overflow.
-  */
-const int HugeCost = 10000;
-
-/** \defgroup flags Flags
-  * \ingroup Core_Module
-  *
-  * These are the possible bits which can be OR'ed to constitute the flags of a matrix or
-  * expression.
-  *
-  * It is important to note that these flags are a purely compile-time notion. They are a compile-time property of
-  * an expression type, implemented as enum's. They are not stored in memory at runtime, and they do not incur any
-  * runtime overhead.
-  *
-  * \sa MatrixBase::Flags
-  */
-
-/** \ingroup flags
-  *
-  * for a matrix, this means that the storage order is row-major.
-  * If this bit is not set, the storage order is column-major.
-  * For an expression, this determines the storage order of
-  * the matrix created by evaluation of that expression.
-  * \sa \blank  \ref TopicStorageOrders */
-const unsigned int RowMajorBit = 0x1;
-
-/** \ingroup flags
-  * means the expression should be evaluated by the calling expression */
-const unsigned int EvalBeforeNestingBit = 0x2;
-
-/** \ingroup flags
-  * \deprecated
-  * means the expression should be evaluated before any assignment */
-EIGEN_DEPRECATED
-const unsigned int EvalBeforeAssigningBit = 0x4; // FIXME deprecated
-
-/** \ingroup flags
-  *
-  * Short version: means the expression might be vectorized
-  *
-  * Long version: means that the coefficients can be handled by packets
-  * and start at a memory location whose alignment meets the requirements
-  * of the present CPU architecture for optimized packet access. In the fixed-size
-  * case, there is the additional condition that it be possible to access all the
-  * coefficients by packets (this implies the requirement that the size be a multiple of 16 bytes,
-  * and that any nontrivial strides don't break the alignment). In the dynamic-size case,
-  * there is no such condition on the total size and strides, so it might not be possible to access
-  * all coeffs by packets.
-  *
-  * \note This bit can be set regardless of whether vectorization is actually enabled.
-  *       To check for actual vectorizability, see \a ActualPacketAccessBit.
-  */
-const unsigned int PacketAccessBit = 0x8;
-
-#ifdef EIGEN_VECTORIZE
-/** \ingroup flags
-  *
-  * If vectorization is enabled (EIGEN_VECTORIZE is defined) this constant
-  * is set to the value \a PacketAccessBit.
-  *
-  * If vectorization is not enabled (EIGEN_VECTORIZE is not defined) this constant
-  * is set to the value 0.
-  */
-const unsigned int ActualPacketAccessBit = PacketAccessBit;
-#else
-const unsigned int ActualPacketAccessBit = 0x0;
-#endif
-
-/** \ingroup flags
-  *
-  * Short version: means the expression can be seen as 1D vector.
-  *
-  * Long version: means that one can access the coefficients
-  * of this expression by coeff(int), and coeffRef(int) in the case of a lvalue expression. These
-  * index-based access methods are guaranteed
-  * to not have to do any runtime computation of a (row, col)-pair from the index, so that it
-  * is guaranteed that whenever it is available, index-based access is at least as fast as
-  * (row,col)-based access. Expressions for which that isn't possible don't have the LinearAccessBit.
-  *
-  * If both PacketAccessBit and LinearAccessBit are set, then the
-  * packets of this expression can be accessed by packet(int), and writePacket(int) in the case of a
-  * lvalue expression.
-  *
-  * Typically, all vector expressions have the LinearAccessBit, but there is one exception:
-  * Product expressions don't have it, because it would be troublesome for vectorization, even when the
-  * Product is a vector expression. Thus, vector Product expressions allow index-based coefficient access but
-  * not index-based packet access, so they don't have the LinearAccessBit.
-  */
-const unsigned int LinearAccessBit = 0x10;
-
-/** \ingroup flags
-  *
-  * Means the expression has a coeffRef() method, i.e. is writable as its individual coefficients are directly addressable.
-  * This rules out read-only expressions.
-  *
-  * Note that DirectAccessBit and LvalueBit are mutually orthogonal, as there are examples of expression having one but note
-  * the other:
-  *   \li writable expressions that don't have a very simple memory layout as a strided array, have LvalueBit but not DirectAccessBit
-  *   \li Map-to-const expressions, for example Map<const Matrix>, have DirectAccessBit but not LvalueBit
-  *
-  * Expressions having LvalueBit also have their coeff() method returning a const reference instead of returning a new value.
-  */
-const unsigned int LvalueBit = 0x20;
-
-/** \ingroup flags
-  *
-  * Means that the underlying array of coefficients can be directly accessed as a plain strided array. The memory layout
-  * of the array of coefficients must be exactly the natural one suggested by rows(), cols(),
-  * outerStride(), innerStride(), and the RowMajorBit. This rules out expressions such as Diagonal, whose coefficients,
-  * though referencable, do not have such a regular memory layout.
-  *
-  * See the comment on LvalueBit for an explanation of how LvalueBit and DirectAccessBit are mutually orthogonal.
-  */
-const unsigned int DirectAccessBit = 0x40;
-
-/** \deprecated \ingroup flags
-  *
-  * means the first coefficient packet is guaranteed to be aligned.
-  * An expression cannot has the AlignedBit without the PacketAccessBit flag.
-  * In other words, this means we are allow to perform an aligned packet access to the first element regardless
-  * of the expression kind:
-  * \code
-  * expression.packet<Aligned>(0);
-  * \endcode
-  */
-EIGEN_DEPRECATED const unsigned int AlignedBit = 0x80;
-
-const unsigned int NestByRefBit = 0x100;
-
-/** \ingroup flags
-  *
-  * for an expression, this means that the storage order
-  * can be either row-major or column-major.
-  * The precise choice will be decided at evaluation time or when
-  * combined with other expressions.
-  * \sa \blank  \ref RowMajorBit, \ref TopicStorageOrders */
-const unsigned int NoPreferredStorageOrderBit = 0x200;
-
-/** \ingroup flags
-  *
-  * Means that the underlying coefficients can be accessed through pointers to the sparse (un)compressed storage format,
-  * that is, the expression provides:
-  * \code
-    inline const Scalar* valuePtr() const;
-    inline const Index* innerIndexPtr() const;
-    inline const Index* outerIndexPtr() const;
-    inline const Index* innerNonZeroPtr() const;
-    \endcode
-  */
-const unsigned int CompressedAccessBit = 0x400;
-
-
-// list of flags that are inherited by default
-const unsigned int HereditaryBits = RowMajorBit
-                                  | EvalBeforeNestingBit;
-
-/** \defgroup enums Enumerations
-  * \ingroup Core_Module
-  *
-  * Various enumerations used in %Eigen. Many of these are used as template parameters.
-  */
-
-/** \ingroup enums
-  * Enum containing possible values for the \c Mode or \c UpLo parameter of
-  * MatrixBase::selfadjointView() and MatrixBase::triangularView(), and selfadjoint solvers. */
-enum UpLoType {
-  /** View matrix as a lower triangular matrix. */
-  Lower=0x1,                      
-  /** View matrix as an upper triangular matrix. */
-  Upper=0x2,                      
-  /** %Matrix has ones on the diagonal; to be used in combination with #Lower or #Upper. */
-  UnitDiag=0x4, 
-  /** %Matrix has zeros on the diagonal; to be used in combination with #Lower or #Upper. */
-  ZeroDiag=0x8,
-  /** View matrix as a lower triangular matrix with ones on the diagonal. */
-  UnitLower=UnitDiag|Lower, 
-  /** View matrix as an upper triangular matrix with ones on the diagonal. */
-  UnitUpper=UnitDiag|Upper,
-  /** View matrix as a lower triangular matrix with zeros on the diagonal. */
-  StrictlyLower=ZeroDiag|Lower, 
-  /** View matrix as an upper triangular matrix with zeros on the diagonal. */
-  StrictlyUpper=ZeroDiag|Upper,
-  /** Used in BandMatrix and SelfAdjointView to indicate that the matrix is self-adjoint. */
-  SelfAdjoint=0x10,
-  /** Used to support symmetric, non-selfadjoint, complex matrices. */
-  Symmetric=0x20
-};
-
-/** \ingroup enums
-  * Enum for indicating whether a buffer is aligned or not. */
-enum AlignmentType {
-  Unaligned=0,        /**< Data pointer has no specific alignment. */
-  Aligned8=8,         /**< Data pointer is aligned on a 8 bytes boundary. */
-  Aligned16=16,       /**< Data pointer is aligned on a 16 bytes boundary. */
-  Aligned32=32,       /**< Data pointer is aligned on a 32 bytes boundary. */
-  Aligned64=64,       /**< Data pointer is aligned on a 64 bytes boundary. */
-  Aligned128=128,     /**< Data pointer is aligned on a 128 bytes boundary. */
-  AlignedMask=255,
-  Aligned=16,         /**< \deprecated Synonym for Aligned16. */
-#if EIGEN_MAX_ALIGN_BYTES==128
-  AlignedMax = Aligned128
-#elif EIGEN_MAX_ALIGN_BYTES==64
-  AlignedMax = Aligned64
-#elif EIGEN_MAX_ALIGN_BYTES==32
-  AlignedMax = Aligned32
-#elif EIGEN_MAX_ALIGN_BYTES==16
-  AlignedMax = Aligned16
-#elif EIGEN_MAX_ALIGN_BYTES==8
-  AlignedMax = Aligned8
-#elif EIGEN_MAX_ALIGN_BYTES==0
-  AlignedMax = Unaligned
-#else
-#error Invalid value for EIGEN_MAX_ALIGN_BYTES
-#endif
-};
-
-/** \ingroup enums
- * Enum used by DenseBase::corner() in Eigen2 compatibility mode. */
-// FIXME after the corner() API change, this was not needed anymore, except by AlignedBox
-// TODO: find out what to do with that. Adapt the AlignedBox API ?
-enum CornerType { TopLeft, TopRight, BottomLeft, BottomRight };
-
-/** \ingroup enums
-  * Enum containing possible values for the \p Direction parameter of
-  * Reverse, PartialReduxExpr and VectorwiseOp. */
-enum DirectionType { 
-  /** For Reverse, all columns are reversed; 
-    * for PartialReduxExpr and VectorwiseOp, act on columns. */
-  Vertical, 
-  /** For Reverse, all rows are reversed; 
-    * for PartialReduxExpr and VectorwiseOp, act on rows. */
-  Horizontal, 
-  /** For Reverse, both rows and columns are reversed; 
-    * not used for PartialReduxExpr and VectorwiseOp. */
-  BothDirections 
-};
-
-/** \internal \ingroup enums
-  * Enum to specify how to traverse the entries of a matrix. */
-enum TraversalType {
-  /** \internal Default traversal, no vectorization, no index-based access */
-  DefaultTraversal,
-  /** \internal No vectorization, use index-based access to have only one for loop instead of 2 nested loops */
-  LinearTraversal,
-  /** \internal Equivalent to a slice vectorization for fixed-size matrices having good alignment
-    * and good size */
-  InnerVectorizedTraversal,
-  /** \internal Vectorization path using a single loop plus scalar loops for the
-    * unaligned boundaries */
-  LinearVectorizedTraversal,
-  /** \internal Generic vectorization path using one vectorized loop per row/column with some
-    * scalar loops to handle the unaligned boundaries */
-  SliceVectorizedTraversal,
-  /** \internal Special case to properly handle incompatible scalar types or other defecting cases*/
-  InvalidTraversal,
-  /** \internal Evaluate all entries at once */
-  AllAtOnceTraversal
-};
-
-/** \internal \ingroup enums
-  * Enum to specify whether to unroll loops when traversing over the entries of a matrix. */
-enum UnrollingType {
-  /** \internal Do not unroll loops. */
-  NoUnrolling,
-  /** \internal Unroll only the inner loop, but not the outer loop. */
-  InnerUnrolling,
-  /** \internal Unroll both the inner and the outer loop. If there is only one loop, 
-    * because linear traversal is used, then unroll that loop. */
-  CompleteUnrolling
-};
-
-/** \internal \ingroup enums
-  * Enum to specify whether to use the default (built-in) implementation or the specialization. */
-enum SpecializedType {
-  Specialized,
-  BuiltIn
-};
-
-/** \ingroup enums
-  * Enum containing possible values for the \p _Options template parameter of
-  * Matrix, Array and BandMatrix. */
-enum StorageOptions {
-  /** Storage order is column major (see \ref TopicStorageOrders). */
-  ColMajor = 0,
-  /** Storage order is row major (see \ref TopicStorageOrders). */
-  RowMajor = 0x1,  // it is only a coincidence that this is equal to RowMajorBit -- don't rely on that
-  /** Align the matrix itself if it is vectorizable fixed-size */
-  AutoAlign = 0,
-  /** Don't require alignment for the matrix itself (the array of coefficients, if dynamically allocated, may still be requested to be aligned) */ // FIXME --- clarify the situation
-  DontAlign = 0x2
-};
-
-/** \ingroup enums
-  * Enum for specifying whether to apply or solve on the left or right. */
-enum SideType {
-  /** Apply transformation on the left. */
-  OnTheLeft = 1,  
-  /** Apply transformation on the right. */
-  OnTheRight = 2  
-};
-
-/* the following used to be written as:
- *
- *   struct NoChange_t {};
- *   namespace {
- *     EIGEN_UNUSED NoChange_t NoChange;
- *   }
- *
- * on the ground that it feels dangerous to disambiguate overloaded functions on enum/integer types.  
- * However, this leads to "variable declared but never referenced" warnings on Intel Composer XE,
- * and we do not know how to get rid of them (bug 450).
- */
-
-enum NoChange_t   { NoChange };
-enum Sequential_t { Sequential };
-enum Default_t    { Default };
-
-/** \internal \ingroup enums
-  * Used in AmbiVector. */
-enum AmbiVectorMode {
-  IsDense         = 0,
-  IsSparse
-};
-
-/** \ingroup enums
-  * Used as template parameter in DenseCoeffBase and MapBase to indicate 
-  * which accessors should be provided. */
-enum AccessorLevels {
-  /** Read-only access via a member function. */
-  ReadOnlyAccessors, 
-  /** Read/write access via member functions. */
-  WriteAccessors, 
-  /** Direct read-only access to the coefficients. */
-  DirectAccessors, 
-  /** Direct read/write access to the coefficients. */
-  DirectWriteAccessors
-};
-
-/** \ingroup enums
-  * Enum with options to give to various decompositions. */
-enum DecompositionOptions {
-  /** \internal Not used (meant for LDLT?). */
-  Pivoting            = 0x01, 
-  /** \internal Not used (meant for LDLT?). */
-  NoPivoting          = 0x02, 
-  /** Used in JacobiSVD to indicate that the square matrix U is to be computed. */
-  ComputeFullU        = 0x04,
-  /** Used in JacobiSVD to indicate that the thin matrix U is to be computed. */
-  ComputeThinU        = 0x08,
-  /** Used in JacobiSVD to indicate that the square matrix V is to be computed. */
-  ComputeFullV        = 0x10,
-  /** Used in JacobiSVD to indicate that the thin matrix V is to be computed. */
-  ComputeThinV        = 0x20,
-  /** Used in SelfAdjointEigenSolver and GeneralizedSelfAdjointEigenSolver to specify
-    * that only the eigenvalues are to be computed and not the eigenvectors. */
-  EigenvaluesOnly     = 0x40,
-  /** Used in SelfAdjointEigenSolver and GeneralizedSelfAdjointEigenSolver to specify
-    * that both the eigenvalues and the eigenvectors are to be computed. */
-  ComputeEigenvectors = 0x80,
-  /** \internal */
-  EigVecMask = EigenvaluesOnly | ComputeEigenvectors,
-  /** Used in GeneralizedSelfAdjointEigenSolver to indicate that it should
-    * solve the generalized eigenproblem \f$ Ax = \lambda B x \f$. */
-  Ax_lBx              = 0x100,
-  /** Used in GeneralizedSelfAdjointEigenSolver to indicate that it should
-    * solve the generalized eigenproblem \f$ ABx = \lambda x \f$. */
-  ABx_lx              = 0x200,
-  /** Used in GeneralizedSelfAdjointEigenSolver to indicate that it should
-    * solve the generalized eigenproblem \f$ BAx = \lambda x \f$. */
-  BAx_lx              = 0x400,
-  /** \internal */
-  GenEigMask = Ax_lBx | ABx_lx | BAx_lx
-};
-
-/** \ingroup enums
-  * Possible values for the \p QRPreconditioner template parameter of JacobiSVD. */
-enum QRPreconditioners {
-  /** Do not specify what is to be done if the SVD of a non-square matrix is asked for. */
-  NoQRPreconditioner,
-  /** Use a QR decomposition without pivoting as the first step. */
-  HouseholderQRPreconditioner,
-  /** Use a QR decomposition with column pivoting as the first step. */
-  ColPivHouseholderQRPreconditioner,
-  /** Use a QR decomposition with full pivoting as the first step. */
-  FullPivHouseholderQRPreconditioner
-};
-
-#ifdef Success
-#error The preprocessor symbol 'Success' is defined, possibly by the X11 header file X.h
-#endif
-
-/** \ingroup enums
-  * Enum for reporting the status of a computation. */
-enum ComputationInfo {
-  /** Computation was successful. */
-  Success = 0,        
-  /** The provided data did not satisfy the prerequisites. */
-  NumericalIssue = 1, 
-  /** Iterative procedure did not converge. */
-  NoConvergence = 2,
-  /** The inputs are invalid, or the algorithm has been improperly called.
-    * When assertions are enabled, such errors trigger an assert. */
-  InvalidInput = 3
-};
-
-/** \ingroup enums
-  * Enum used to specify how a particular transformation is stored in a matrix.
-  * \sa Transform, Hyperplane::transform(). */
-enum TransformTraits {
-  /** Transformation is an isometry. */
-  Isometry      = 0x1,
-  /** Transformation is an affine transformation stored as a (Dim+1)^2 matrix whose last row is 
-    * assumed to be [0 ... 0 1]. */
-  Affine        = 0x2,
-  /** Transformation is an affine transformation stored as a (Dim) x (Dim+1) matrix. */
-  AffineCompact = 0x10 | Affine,
-  /** Transformation is a general projective transformation stored as a (Dim+1)^2 matrix. */
-  Projective    = 0x20
-};
-
-/** \internal \ingroup enums
-  * Enum used to choose between implementation depending on the computer architecture. */
-namespace Architecture
-{
-  enum Type {
-    Generic = 0x0,
-    SSE = 0x1,
-    AltiVec = 0x2,
-    VSX = 0x3,
-    NEON = 0x4,
-#if defined EIGEN_VECTORIZE_SSE
-    Target = SSE
-#elif defined EIGEN_VECTORIZE_ALTIVEC
-    Target = AltiVec
-#elif defined EIGEN_VECTORIZE_VSX
-    Target = VSX
-#elif defined EIGEN_VECTORIZE_NEON
-    Target = NEON
-#else
-    Target = Generic
-#endif
-  };
-}
-
-/** \internal \ingroup enums
-  * Enum used as template parameter in Product and product evaluators. */
-enum ProductImplType
-{ DefaultProduct=0, LazyProduct, AliasFreeProduct, CoeffBasedProductMode, LazyCoeffBasedProductMode, OuterProduct, InnerProduct, GemvProduct, GemmProduct };
-
-/** \internal \ingroup enums
-  * Enum used in experimental parallel implementation. */
-enum Action {GetAction, SetAction};
-
-/** The type used to identify a dense storage. */
-struct Dense {};
-
-/** The type used to identify a general sparse storage. */
-struct Sparse {};
-
-/** The type used to identify a general solver (factored) storage. */
-struct SolverStorage {};
-
-/** The type used to identify a permutation storage. */
-struct PermutationStorage {};
-
-/** The type used to identify a permutation storage. */
-struct TranspositionsStorage {};
-
-/** The type used to identify a matrix expression */
-struct MatrixXpr {};
-
-/** The type used to identify an array expression */
-struct ArrayXpr {};
-
-// An evaluator must define its shape. By default, it can be one of the following:
-struct DenseShape             { static std::string debugName() { return "DenseShape"; } };
-struct SolverShape            { static std::string debugName() { return "SolverShape"; } };
-struct HomogeneousShape       { static std::string debugName() { return "HomogeneousShape"; } };
-struct DiagonalShape          { static std::string debugName() { return "DiagonalShape"; } };
-struct BandShape              { static std::string debugName() { return "BandShape"; } };
-struct TriangularShape        { static std::string debugName() { return "TriangularShape"; } };
-struct SelfAdjointShape       { static std::string debugName() { return "SelfAdjointShape"; } };
-struct PermutationShape       { static std::string debugName() { return "PermutationShape"; } };
-struct TranspositionsShape    { static std::string debugName() { return "TranspositionsShape"; } };
-struct SparseShape            { static std::string debugName() { return "SparseShape"; } };
-
-namespace internal {
-
-  // random access iterators based on coeff*() accessors.
-struct IndexBased {};
-
-// evaluator based on iterators to access coefficients. 
-struct IteratorBased {};
-
-/** \internal
- * Constants for comparison functors
- */
-enum ComparisonName {
-  cmp_EQ = 0,
-  cmp_LT = 1,
-  cmp_LE = 2,
-  cmp_UNORD = 3,
-  cmp_NEQ = 4,
-  cmp_GT = 5,
-  cmp_GE = 6
-};
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_CONSTANTS_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/DisableStupidWarnings.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/DisableStupidWarnings.h
deleted file mode 100644
index ce573a8..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/DisableStupidWarnings.h
+++ /dev/null
@@ -1,86 +0,0 @@
-#ifndef EIGEN_WARNINGS_DISABLED
-#define EIGEN_WARNINGS_DISABLED
-
-#ifdef _MSC_VER
-  // 4100 - unreferenced formal parameter (occurred e.g. in aligned_allocator::destroy(pointer p))
-  // 4101 - unreferenced local variable
-  // 4127 - conditional expression is constant
-  // 4181 - qualifier applied to reference type ignored
-  // 4211 - nonstandard extension used : redefined extern to static
-  // 4244 - 'argument' : conversion from 'type1' to 'type2', possible loss of data
-  // 4273 - QtAlignedMalloc, inconsistent DLL linkage
-  // 4324 - structure was padded due to declspec(align())
-  // 4503 - decorated name length exceeded, name was truncated
-  // 4512 - assignment operator could not be generated
-  // 4522 - 'class' : multiple assignment operators specified
-  // 4700 - uninitialized local variable 'xyz' used
-  // 4714 - function marked as __forceinline not inlined
-  // 4717 - 'function' : recursive on all control paths, function will cause runtime stack overflow
-  // 4800 - 'type' : forcing value to bool 'true' or 'false' (performance warning)
-  #ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS
-    #pragma warning( push )
-  #endif
-  #pragma warning( disable : 4100 4101 4127 4181 4211 4244 4273 4324 4503 4512 4522 4700 4714 4717 4800)
-
-#elif defined __INTEL_COMPILER
-  // 2196 - routine is both "inline" and "noinline" ("noinline" assumed)
-  //        ICC 12 generates this warning even without any inline keyword, when defining class methods 'inline' i.e. inside of class body
-  //        typedef that may be a reference type.
-  // 279  - controlling expression is constant
-  //        ICC 12 generates this warning on assert(constant_expression_depending_on_template_params) and frankly this is a legitimate use case.
-  // 1684 - conversion from pointer to same-sized integral type (potential portability problem)
-  // 2259 - non-pointer conversion from "Eigen::Index={ptrdiff_t={long}}" to "int" may lose significant bits
-  #ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS
-    #pragma warning push
-  #endif
-  #pragma warning disable 2196 279 1684 2259
-
-#elif defined __clang__
-  // -Wconstant-logical-operand - warning: use of logical && with constant operand; switch to bitwise & or remove constant
-  //     this is really a stupid warning as it warns on compile-time expressions involving enums
-  #ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS
-    #pragma clang diagnostic push
-  #endif
-  #pragma clang diagnostic ignored "-Wconstant-logical-operand"
-
-#elif defined __GNUC__
-
-  #if (!defined(EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS)) &&  (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
-    #pragma GCC diagnostic push
-  #endif
-  // g++ warns about local variables shadowing member functions, which is too strict
-  #pragma GCC diagnostic ignored "-Wshadow"
-  #if __GNUC__ == 4 && __GNUC_MINOR__ < 8
-    // Until g++-4.7 there are warnings when comparing unsigned int vs 0, even in templated functions:
-    #pragma GCC diagnostic ignored "-Wtype-limits"
-  #endif
-  #if __GNUC__>=6
-    #pragma GCC diagnostic ignored "-Wignored-attributes"
-  #endif
-  #if __GNUC__>=9
-    #pragma GCC diagnostic ignored "-Wdeprecated-copy"
-  #endif
-
-#endif
-
-#if defined __NVCC__
-  // Disable the "statement is unreachable" message
-  #pragma diag_suppress code_is_unreachable
-  // Disable the "dynamic initialization in unreachable code" message
-  #pragma diag_suppress initialization_not_reachable
-  // Disable the "invalid error number" message that we get with older versions of nvcc
-  #pragma diag_suppress 1222
-  // Disable the "calling a __host__ function from a __host__ __device__ function is not allowed" messages (yes, there are many of them and they seem to change with every version of the compiler)
-  #pragma diag_suppress 2527
-  #pragma diag_suppress 2529
-  #pragma diag_suppress 2651
-  #pragma diag_suppress 2653
-  #pragma diag_suppress 2668
-  #pragma diag_suppress 2669
-  #pragma diag_suppress 2670
-  #pragma diag_suppress 2671
-  #pragma diag_suppress 2735
-  #pragma diag_suppress 2737
-#endif
-
-#endif // not EIGEN_WARNINGS_DISABLED
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/ForwardDeclarations.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/ForwardDeclarations.h
deleted file mode 100644
index ea10739..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/ForwardDeclarations.h
+++ /dev/null
@@ -1,302 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_FORWARDDECLARATIONS_H
-#define EIGEN_FORWARDDECLARATIONS_H
-
-namespace Eigen {
-namespace internal {
-
-template<typename T> struct traits;
-
-// here we say once and for all that traits<const T> == traits<T>
-// When constness must affect traits, it has to be constness on template parameters on which T itself depends.
-// For example, traits<Map<const T> > != traits<Map<T> >, but
-//              traits<const Map<T> > == traits<Map<T> >
-template<typename T> struct traits<const T> : traits<T> {};
-
-template<typename Derived> struct has_direct_access
-{
-  enum { ret = (traits<Derived>::Flags & DirectAccessBit) ? 1 : 0 };
-};
-
-template<typename Derived> struct accessors_level
-{
-  enum { has_direct_access = (traits<Derived>::Flags & DirectAccessBit) ? 1 : 0,
-         has_write_access = (traits<Derived>::Flags & LvalueBit) ? 1 : 0,
-         value = has_direct_access ? (has_write_access ? DirectWriteAccessors : DirectAccessors)
-                                   : (has_write_access ? WriteAccessors       : ReadOnlyAccessors)
-  };
-};
-
-template<typename T> struct evaluator_traits;
-
-template< typename T> struct evaluator;
-
-} // end namespace internal
-
-template<typename T> struct NumTraits;
-
-template<typename Derived> struct EigenBase;
-template<typename Derived> class DenseBase;
-template<typename Derived> class PlainObjectBase;
-
-
-template<typename Derived,
-         int Level = internal::accessors_level<Derived>::value >
-class DenseCoeffsBase;
-
-template<typename _Scalar, int _Rows, int _Cols,
-         int _Options = AutoAlign |
-#if EIGEN_GNUC_AT(3,4)
-    // workaround a bug in at least gcc 3.4.6
-    // the innermost ?: ternary operator is misparsed. We write it slightly
-    // differently and this makes gcc 3.4.6 happy, but it's ugly.
-    // The error would only show up with EIGEN_DEFAULT_TO_ROW_MAJOR is defined
-    // (when EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION is RowMajor)
-                          ( (_Rows==1 && _Cols!=1) ? Eigen::RowMajor
-                          : !(_Cols==1 && _Rows!=1) ?  EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION
-                          : Eigen::ColMajor ),
-#else
-                          ( (_Rows==1 && _Cols!=1) ? Eigen::RowMajor
-                          : (_Cols==1 && _Rows!=1) ? Eigen::ColMajor
-                          : EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION ),
-#endif
-         int _MaxRows = _Rows,
-         int _MaxCols = _Cols
-> class Matrix;
-
-template<typename Derived> class MatrixBase;
-template<typename Derived> class ArrayBase;
-
-template<typename ExpressionType, unsigned int Added, unsigned int Removed> class Flagged;
-template<typename ExpressionType, template <typename> class StorageBase > class NoAlias;
-template<typename ExpressionType> class NestByValue;
-template<typename ExpressionType> class ForceAlignedAccess;
-template<typename ExpressionType> class SwapWrapper;
-
-template<typename XprType, int BlockRows=Dynamic, int BlockCols=Dynamic, bool InnerPanel = false> class Block;
-
-template<typename MatrixType, int Size=Dynamic> class VectorBlock;
-template<typename MatrixType> class Transpose;
-template<typename MatrixType> class Conjugate;
-template<typename NullaryOp, typename MatrixType>         class CwiseNullaryOp;
-template<typename UnaryOp,   typename MatrixType>         class CwiseUnaryOp;
-template<typename ViewOp,    typename MatrixType>         class CwiseUnaryView;
-template<typename BinaryOp,  typename Lhs, typename Rhs>  class CwiseBinaryOp;
-template<typename TernaryOp, typename Arg1, typename Arg2, typename Arg3>  class CwiseTernaryOp;
-template<typename Decomposition, typename Rhstype>        class Solve;
-template<typename XprType>                                class Inverse;
-
-template<typename Lhs, typename Rhs, int Option = DefaultProduct> class Product;
-
-template<typename Derived> class DiagonalBase;
-template<typename _DiagonalVectorType> class DiagonalWrapper;
-template<typename _Scalar, int SizeAtCompileTime, int MaxSizeAtCompileTime=SizeAtCompileTime> class DiagonalMatrix;
-template<typename MatrixType, typename DiagonalType, int ProductOrder> class DiagonalProduct;
-template<typename MatrixType, int Index = 0> class Diagonal;
-template<int SizeAtCompileTime, int MaxSizeAtCompileTime = SizeAtCompileTime, typename IndexType=int> class PermutationMatrix;
-template<int SizeAtCompileTime, int MaxSizeAtCompileTime = SizeAtCompileTime, typename IndexType=int> class Transpositions;
-template<typename Derived> class PermutationBase;
-template<typename Derived> class TranspositionsBase;
-template<typename _IndicesType> class PermutationWrapper;
-template<typename _IndicesType> class TranspositionsWrapper;
-
-template<typename Derived,
-         int Level = internal::accessors_level<Derived>::has_write_access ? WriteAccessors : ReadOnlyAccessors
-> class MapBase;
-template<int InnerStrideAtCompileTime, int OuterStrideAtCompileTime> class Stride;
-template<int Value = Dynamic> class InnerStride;
-template<int Value = Dynamic> class OuterStride;
-template<typename MatrixType, int MapOptions=Unaligned, typename StrideType = Stride<0,0> > class Map;
-template<typename Derived> class RefBase;
-template<typename PlainObjectType, int Options = 0,
-         typename StrideType = typename internal::conditional<PlainObjectType::IsVectorAtCompileTime,InnerStride<1>,OuterStride<> >::type > class Ref;
-
-template<typename Derived> class TriangularBase;
-template<typename MatrixType, unsigned int Mode> class TriangularView;
-template<typename MatrixType, unsigned int Mode> class SelfAdjointView;
-template<typename MatrixType> class SparseView;
-template<typename ExpressionType> class WithFormat;
-template<typename MatrixType> struct CommaInitializer;
-template<typename Derived> class ReturnByValue;
-template<typename ExpressionType> class ArrayWrapper;
-template<typename ExpressionType> class MatrixWrapper;
-template<typename Derived> class SolverBase;
-template<typename XprType> class InnerIterator;
-
-namespace internal {
-template<typename DecompositionType> struct kernel_retval_base;
-template<typename DecompositionType> struct kernel_retval;
-template<typename DecompositionType> struct image_retval_base;
-template<typename DecompositionType> struct image_retval;
-} // end namespace internal
-
-namespace internal {
-template<typename _Scalar, int Rows=Dynamic, int Cols=Dynamic, int Supers=Dynamic, int Subs=Dynamic, int Options=0> class BandMatrix;
-}
-
-namespace internal {
-template<typename Lhs, typename Rhs> struct product_type;
-
-template<bool> struct EnableIf;
-
-/** \internal
-  * \class product_evaluator
-  * Products need their own evaluator with more template arguments allowing for
-  * easier partial template specializations.
-  */
-template< typename T,
-          int ProductTag = internal::product_type<typename T::Lhs,typename T::Rhs>::ret,
-          typename LhsShape = typename evaluator_traits<typename T::Lhs>::Shape,
-          typename RhsShape = typename evaluator_traits<typename T::Rhs>::Shape,
-          typename LhsScalar = typename traits<typename T::Lhs>::Scalar,
-          typename RhsScalar = typename traits<typename T::Rhs>::Scalar
-        > struct product_evaluator;
-}
-
-template<typename Lhs, typename Rhs,
-         int ProductType = internal::product_type<Lhs,Rhs>::value>
-struct ProductReturnType;
-
-// this is a workaround for sun CC
-template<typename Lhs, typename Rhs> struct LazyProductReturnType;
-
-namespace internal {
-
-// Provides scalar/packet-wise product and product with accumulation
-// with optional conjugation of the arguments.
-template<typename LhsScalar, typename RhsScalar, bool ConjLhs=false, bool ConjRhs=false> struct conj_helper;
-
-template<typename LhsScalar,typename RhsScalar=LhsScalar> struct scalar_sum_op;
-template<typename LhsScalar,typename RhsScalar=LhsScalar> struct scalar_difference_op;
-template<typename LhsScalar,typename RhsScalar=LhsScalar> struct scalar_conj_product_op;
-template<typename LhsScalar,typename RhsScalar=LhsScalar> struct scalar_min_op;
-template<typename LhsScalar,typename RhsScalar=LhsScalar> struct scalar_max_op;
-template<typename Scalar> struct scalar_opposite_op;
-template<typename Scalar> struct scalar_conjugate_op;
-template<typename Scalar> struct scalar_real_op;
-template<typename Scalar> struct scalar_imag_op;
-template<typename Scalar> struct scalar_abs_op;
-template<typename Scalar> struct scalar_abs2_op;
-template<typename Scalar> struct scalar_sqrt_op;
-template<typename Scalar> struct scalar_rsqrt_op;
-template<typename Scalar> struct scalar_exp_op;
-template<typename Scalar> struct scalar_log_op;
-template<typename Scalar> struct scalar_cos_op;
-template<typename Scalar> struct scalar_sin_op;
-template<typename Scalar> struct scalar_acos_op;
-template<typename Scalar> struct scalar_asin_op;
-template<typename Scalar> struct scalar_tan_op;
-template<typename Scalar> struct scalar_inverse_op;
-template<typename Scalar> struct scalar_square_op;
-template<typename Scalar> struct scalar_cube_op;
-template<typename Scalar, typename NewType> struct scalar_cast_op;
-template<typename Scalar> struct scalar_random_op;
-template<typename Scalar> struct scalar_constant_op;
-template<typename Scalar> struct scalar_identity_op;
-template<typename Scalar,bool iscpx> struct scalar_sign_op;
-template<typename Scalar,typename ScalarExponent> struct scalar_pow_op;
-template<typename LhsScalar,typename RhsScalar=LhsScalar> struct scalar_hypot_op;
-template<typename LhsScalar,typename RhsScalar=LhsScalar> struct scalar_product_op;
-template<typename LhsScalar,typename RhsScalar=LhsScalar> struct scalar_quotient_op;
-
-// SpecialFunctions module
-template<typename Scalar> struct scalar_lgamma_op;
-template<typename Scalar> struct scalar_digamma_op;
-template<typename Scalar> struct scalar_erf_op;
-template<typename Scalar> struct scalar_erfc_op;
-template<typename Scalar> struct scalar_igamma_op;
-template<typename Scalar> struct scalar_igammac_op;
-template<typename Scalar> struct scalar_zeta_op;
-template<typename Scalar> struct scalar_betainc_op;
-
-} // end namespace internal
-
-struct IOFormat;
-
-// Array module
-template<typename _Scalar, int _Rows, int _Cols,
-         int _Options = AutoAlign |
-#if EIGEN_GNUC_AT(3,4)
-    // workaround a bug in at least gcc 3.4.6
-    // the innermost ?: ternary operator is misparsed. We write it slightly
-    // differently and this makes gcc 3.4.6 happy, but it's ugly.
-    // The error would only show up with EIGEN_DEFAULT_TO_ROW_MAJOR is defined
-    // (when EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION is RowMajor)
-                          ( (_Rows==1 && _Cols!=1) ? Eigen::RowMajor
-                          : !(_Cols==1 && _Rows!=1) ?  EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION
-                          : Eigen::ColMajor ),
-#else
-                          ( (_Rows==1 && _Cols!=1) ? Eigen::RowMajor
-                          : (_Cols==1 && _Rows!=1) ? Eigen::ColMajor
-                          : EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION ),
-#endif
-         int _MaxRows = _Rows, int _MaxCols = _Cols> class Array;
-template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType> class Select;
-template<typename MatrixType, typename BinaryOp, int Direction> class PartialReduxExpr;
-template<typename ExpressionType, int Direction> class VectorwiseOp;
-template<typename MatrixType,int RowFactor,int ColFactor> class Replicate;
-template<typename MatrixType, int Direction = BothDirections> class Reverse;
-
-template<typename MatrixType> class FullPivLU;
-template<typename MatrixType> class PartialPivLU;
-namespace internal {
-template<typename MatrixType> struct inverse_impl;
-}
-template<typename MatrixType> class HouseholderQR;
-template<typename MatrixType> class ColPivHouseholderQR;
-template<typename MatrixType> class FullPivHouseholderQR;
-template<typename MatrixType> class CompleteOrthogonalDecomposition;
-template<typename MatrixType, int QRPreconditioner = ColPivHouseholderQRPreconditioner> class JacobiSVD;
-template<typename MatrixType> class BDCSVD;
-template<typename MatrixType, int UpLo = Lower> class LLT;
-template<typename MatrixType, int UpLo = Lower> class LDLT;
-template<typename VectorsType, typename CoeffsType, int Side=OnTheLeft> class HouseholderSequence;
-template<typename Scalar>     class JacobiRotation;
-
-// Geometry module:
-template<typename Derived, int _Dim> class RotationBase;
-template<typename Lhs, typename Rhs> class Cross;
-template<typename Derived> class QuaternionBase;
-template<typename Scalar> class Rotation2D;
-template<typename Scalar> class AngleAxis;
-template<typename Scalar,int Dim> class Translation;
-template<typename Scalar,int Dim> class AlignedBox;
-template<typename Scalar, int Options = AutoAlign> class Quaternion;
-template<typename Scalar,int Dim,int Mode,int _Options=AutoAlign> class Transform;
-template <typename _Scalar, int _AmbientDim, int Options=AutoAlign> class ParametrizedLine;
-template <typename _Scalar, int _AmbientDim, int Options=AutoAlign> class Hyperplane;
-template<typename Scalar> class UniformScaling;
-template<typename MatrixType,int Direction> class Homogeneous;
-
-// Sparse module:
-template<typename Derived> class SparseMatrixBase;
-
-// MatrixFunctions module
-template<typename Derived> struct MatrixExponentialReturnValue;
-template<typename Derived> class MatrixFunctionReturnValue;
-template<typename Derived> class MatrixSquareRootReturnValue;
-template<typename Derived> class MatrixLogarithmReturnValue;
-template<typename Derived> class MatrixPowerReturnValue;
-template<typename Derived> class MatrixComplexPowerReturnValue;
-
-namespace internal {
-template <typename Scalar>
-struct stem_function
-{
-  typedef std::complex<typename NumTraits<Scalar>::Real> ComplexScalar;
-  typedef ComplexScalar type(ComplexScalar, int);
-};
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_FORWARDDECLARATIONS_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/Macros.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/Macros.h
deleted file mode 100644
index aa054a0..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/Macros.h
+++ /dev/null
@@ -1,1001 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2015 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_MACROS_H
-#define EIGEN_MACROS_H
-
-#define EIGEN_WORLD_VERSION 3
-#define EIGEN_MAJOR_VERSION 3
-#define EIGEN_MINOR_VERSION 7
-
-#define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \
-                                      (EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \
-                                                                 EIGEN_MINOR_VERSION>=z))))
-
-// Compiler identification, EIGEN_COMP_*
-
-/// \internal EIGEN_COMP_GNUC set to 1 for all compilers compatible with GCC
-#ifdef __GNUC__
-  #define EIGEN_COMP_GNUC 1
-#else
-  #define EIGEN_COMP_GNUC 0
-#endif
-
-/// \internal EIGEN_COMP_CLANG set to major+minor version (e.g., 307 for clang 3.7) if the compiler is clang
-#if defined(__clang__)
-  #define EIGEN_COMP_CLANG (__clang_major__*100+__clang_minor__)
-#else
-  #define EIGEN_COMP_CLANG 0
-#endif
-
-
-/// \internal EIGEN_COMP_LLVM set to 1 if the compiler backend is llvm
-#if defined(__llvm__)
-  #define EIGEN_COMP_LLVM 1
-#else
-  #define EIGEN_COMP_LLVM 0
-#endif
-
-/// \internal EIGEN_COMP_ICC set to __INTEL_COMPILER if the compiler is Intel compiler, 0 otherwise
-#if defined(__INTEL_COMPILER)
-  #define EIGEN_COMP_ICC __INTEL_COMPILER
-#else
-  #define EIGEN_COMP_ICC 0
-#endif
-
-/// \internal EIGEN_COMP_MINGW set to 1 if the compiler is mingw
-#if defined(__MINGW32__)
-  #define EIGEN_COMP_MINGW 1
-#else
-  #define EIGEN_COMP_MINGW 0
-#endif
-
-/// \internal EIGEN_COMP_SUNCC set to 1 if the compiler is Solaris Studio
-#if defined(__SUNPRO_CC)
-  #define EIGEN_COMP_SUNCC 1
-#else
-  #define EIGEN_COMP_SUNCC 0
-#endif
-
-/// \internal EIGEN_COMP_MSVC set to _MSC_VER if the compiler is Microsoft Visual C++, 0 otherwise.
-#if defined(_MSC_VER)
-  #define EIGEN_COMP_MSVC _MSC_VER
-#else
-  #define EIGEN_COMP_MSVC 0
-#endif
-
-// For the record, here is a table summarizing the possible values for EIGEN_COMP_MSVC:
-//  name  ver   MSC_VER
-//  2008    9      1500
-//  2010   10      1600
-//  2012   11      1700
-//  2013   12      1800
-//  2015   14      1900
-//  "15"   15      1900
-
-/// \internal EIGEN_COMP_MSVC_STRICT set to 1 if the compiler is really Microsoft Visual C++ and not ,e.g., ICC or clang-cl
-#if EIGEN_COMP_MSVC && !(EIGEN_COMP_ICC || EIGEN_COMP_LLVM || EIGEN_COMP_CLANG)
-  #define EIGEN_COMP_MSVC_STRICT _MSC_VER
-#else
-  #define EIGEN_COMP_MSVC_STRICT 0
-#endif
-
-/// \internal EIGEN_COMP_IBM set to 1 if the compiler is IBM XL C++
-#if defined(__IBMCPP__) || defined(__xlc__)
-  #define EIGEN_COMP_IBM 1
-#else
-  #define EIGEN_COMP_IBM 0
-#endif
-
-/// \internal EIGEN_COMP_PGI set to 1 if the compiler is Portland Group Compiler
-#if defined(__PGI)
-  #define EIGEN_COMP_PGI 1
-#else
-  #define EIGEN_COMP_PGI 0
-#endif
-
-/// \internal EIGEN_COMP_ARM set to 1 if the compiler is ARM Compiler
-#if defined(__CC_ARM) || defined(__ARMCC_VERSION)
-  #define EIGEN_COMP_ARM 1
-#else
-  #define EIGEN_COMP_ARM 0
-#endif
-
-/// \internal EIGEN_COMP_ARM set to 1 if the compiler is ARM Compiler
-#if defined(__EMSCRIPTEN__)
-  #define EIGEN_COMP_EMSCRIPTEN 1
-#else
-  #define EIGEN_COMP_EMSCRIPTEN 0
-#endif
-
-
-/// \internal EIGEN_GNUC_STRICT set to 1 if the compiler is really GCC and not a compatible compiler (e.g., ICC, clang, mingw, etc.)
-#if EIGEN_COMP_GNUC && !(EIGEN_COMP_CLANG || EIGEN_COMP_ICC || EIGEN_COMP_MINGW || EIGEN_COMP_PGI || EIGEN_COMP_IBM || EIGEN_COMP_ARM || EIGEN_COMP_EMSCRIPTEN)
-  #define EIGEN_COMP_GNUC_STRICT 1
-#else
-  #define EIGEN_COMP_GNUC_STRICT 0
-#endif
-
-
-#if EIGEN_COMP_GNUC
-  #define EIGEN_GNUC_AT_LEAST(x,y) ((__GNUC__==x && __GNUC_MINOR__>=y) || __GNUC__>x)
-  #define EIGEN_GNUC_AT_MOST(x,y)  ((__GNUC__==x && __GNUC_MINOR__<=y) || __GNUC__<x)
-  #define EIGEN_GNUC_AT(x,y)       ( __GNUC__==x && __GNUC_MINOR__==y )
-#else
-  #define EIGEN_GNUC_AT_LEAST(x,y) 0
-  #define EIGEN_GNUC_AT_MOST(x,y)  0
-  #define EIGEN_GNUC_AT(x,y)       0
-#endif
-
-// FIXME: could probably be removed as we do not support gcc 3.x anymore
-#if EIGEN_COMP_GNUC && (__GNUC__ <= 3)
-#define EIGEN_GCC3_OR_OLDER 1
-#else
-#define EIGEN_GCC3_OR_OLDER 0
-#endif
-
-
-// Architecture identification, EIGEN_ARCH_*
-
-#if defined(__x86_64__) || defined(_M_X64) || defined(__amd64)
-  #define EIGEN_ARCH_x86_64 1
-#else
-  #define EIGEN_ARCH_x86_64 0
-#endif
-
-#if defined(__i386__) || defined(_M_IX86) || defined(_X86_) || defined(__i386)
-  #define EIGEN_ARCH_i386 1
-#else
-  #define EIGEN_ARCH_i386 0
-#endif
-
-#if EIGEN_ARCH_x86_64 || EIGEN_ARCH_i386
-  #define EIGEN_ARCH_i386_OR_x86_64 1
-#else
-  #define EIGEN_ARCH_i386_OR_x86_64 0
-#endif
-
-/// \internal EIGEN_ARCH_ARM set to 1 if the architecture is ARM
-#if defined(__arm__)
-  #define EIGEN_ARCH_ARM 1
-#else
-  #define EIGEN_ARCH_ARM 0
-#endif
-
-/// \internal EIGEN_ARCH_ARM64 set to 1 if the architecture is ARM64
-#if defined(__aarch64__)
-  #define EIGEN_ARCH_ARM64 1
-#else
-  #define EIGEN_ARCH_ARM64 0
-#endif
-
-#if EIGEN_ARCH_ARM || EIGEN_ARCH_ARM64
-  #define EIGEN_ARCH_ARM_OR_ARM64 1
-#else
-  #define EIGEN_ARCH_ARM_OR_ARM64 0
-#endif
-
-/// \internal EIGEN_ARCH_MIPS set to 1 if the architecture is MIPS
-#if defined(__mips__) || defined(__mips)
-  #define EIGEN_ARCH_MIPS 1
-#else
-  #define EIGEN_ARCH_MIPS 0
-#endif
-
-/// \internal EIGEN_ARCH_SPARC set to 1 if the architecture is SPARC
-#if defined(__sparc__) || defined(__sparc)
-  #define EIGEN_ARCH_SPARC 1
-#else
-  #define EIGEN_ARCH_SPARC 0
-#endif
-
-/// \internal EIGEN_ARCH_IA64 set to 1 if the architecture is Intel Itanium
-#if defined(__ia64__)
-  #define EIGEN_ARCH_IA64 1
-#else
-  #define EIGEN_ARCH_IA64 0
-#endif
-
-/// \internal EIGEN_ARCH_PPC set to 1 if the architecture is PowerPC
-#if defined(__powerpc__) || defined(__ppc__) || defined(_M_PPC)
-  #define EIGEN_ARCH_PPC 1
-#else
-  #define EIGEN_ARCH_PPC 0
-#endif
-
-
-
-// Operating system identification, EIGEN_OS_*
-
-/// \internal EIGEN_OS_UNIX set to 1 if the OS is a unix variant
-#if defined(__unix__) || defined(__unix)
-  #define EIGEN_OS_UNIX 1
-#else
-  #define EIGEN_OS_UNIX 0
-#endif
-
-/// \internal EIGEN_OS_LINUX set to 1 if the OS is based on Linux kernel
-#if defined(__linux__)
-  #define EIGEN_OS_LINUX 1
-#else
-  #define EIGEN_OS_LINUX 0
-#endif
-
-/// \internal EIGEN_OS_ANDROID set to 1 if the OS is Android
-// note: ANDROID is defined when using ndk_build, __ANDROID__ is defined when using a standalone toolchain.
-#if defined(__ANDROID__) || defined(ANDROID)
-  #define EIGEN_OS_ANDROID 1
-#else
-  #define EIGEN_OS_ANDROID 0
-#endif
-
-/// \internal EIGEN_OS_GNULINUX set to 1 if the OS is GNU Linux and not Linux-based OS (e.g., not android)
-#if defined(__gnu_linux__) && !(EIGEN_OS_ANDROID)
-  #define EIGEN_OS_GNULINUX 1
-#else
-  #define EIGEN_OS_GNULINUX 0
-#endif
-
-/// \internal EIGEN_OS_BSD set to 1 if the OS is a BSD variant
-#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__)
-  #define EIGEN_OS_BSD 1
-#else
-  #define EIGEN_OS_BSD 0
-#endif
-
-/// \internal EIGEN_OS_MAC set to 1 if the OS is MacOS
-#if defined(__APPLE__)
-  #define EIGEN_OS_MAC 1
-#else
-  #define EIGEN_OS_MAC 0
-#endif
-
-/// \internal EIGEN_OS_QNX set to 1 if the OS is QNX
-#if defined(__QNX__)
-  #define EIGEN_OS_QNX 1
-#else
-  #define EIGEN_OS_QNX 0
-#endif
-
-/// \internal EIGEN_OS_WIN set to 1 if the OS is Windows based
-#if defined(_WIN32)
-  #define EIGEN_OS_WIN 1
-#else
-  #define EIGEN_OS_WIN 0
-#endif
-
-/// \internal EIGEN_OS_WIN64 set to 1 if the OS is Windows 64bits
-#if defined(_WIN64)
-  #define EIGEN_OS_WIN64 1
-#else
-  #define EIGEN_OS_WIN64 0
-#endif
-
-/// \internal EIGEN_OS_WINCE set to 1 if the OS is Windows CE
-#if defined(_WIN32_WCE)
-  #define EIGEN_OS_WINCE 1
-#else
-  #define EIGEN_OS_WINCE 0
-#endif
-
-/// \internal EIGEN_OS_CYGWIN set to 1 if the OS is Windows/Cygwin
-#if defined(__CYGWIN__)
-  #define EIGEN_OS_CYGWIN 1
-#else
-  #define EIGEN_OS_CYGWIN 0
-#endif
-
-/// \internal EIGEN_OS_WIN_STRICT set to 1 if the OS is really Windows and not some variants
-#if EIGEN_OS_WIN && !( EIGEN_OS_WINCE || EIGEN_OS_CYGWIN )
-  #define EIGEN_OS_WIN_STRICT 1
-#else
-  #define EIGEN_OS_WIN_STRICT 0
-#endif
-
-/// \internal EIGEN_OS_SUN set to 1 if the OS is SUN
-#if (defined(sun) || defined(__sun)) && !(defined(__SVR4) || defined(__svr4__))
-  #define EIGEN_OS_SUN 1
-#else
-  #define EIGEN_OS_SUN 0
-#endif
-
-/// \internal EIGEN_OS_SOLARIS set to 1 if the OS is Solaris
-#if (defined(sun) || defined(__sun)) && (defined(__SVR4) || defined(__svr4__))
-  #define EIGEN_OS_SOLARIS 1
-#else
-  #define EIGEN_OS_SOLARIS 0
-#endif
-
-
-
-#if EIGEN_GNUC_AT_MOST(4,3) && !EIGEN_COMP_CLANG
-  // see bug 89
-  #define EIGEN_SAFE_TO_USE_STANDARD_ASSERT_MACRO 0
-#else
-  #define EIGEN_SAFE_TO_USE_STANDARD_ASSERT_MACRO 1
-#endif
-
-// This macro can be used to prevent from macro expansion, e.g.:
-//   std::max EIGEN_NOT_A_MACRO(a,b)
-#define EIGEN_NOT_A_MACRO
-
-#ifdef EIGEN_DEFAULT_TO_ROW_MAJOR
-#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION Eigen::RowMajor
-#else
-#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION Eigen::ColMajor
-#endif
-
-#ifndef EIGEN_DEFAULT_DENSE_INDEX_TYPE
-#define EIGEN_DEFAULT_DENSE_INDEX_TYPE std::ptrdiff_t
-#endif
-
-// Cross compiler wrapper around LLVM's __has_builtin
-#ifdef __has_builtin
-#  define EIGEN_HAS_BUILTIN(x) __has_builtin(x)
-#else
-#  define EIGEN_HAS_BUILTIN(x) 0
-#endif
-
-// A Clang feature extension to determine compiler features.
-// We use it to determine 'cxx_rvalue_references'
-#ifndef __has_feature
-# define __has_feature(x) 0
-#endif
-
-// Upperbound on the C++ version to use.
-// Expected values are 03, 11, 14, 17, etc.
-// By default, let's use an arbitrarily large C++ version.
-#ifndef EIGEN_MAX_CPP_VER
-#define EIGEN_MAX_CPP_VER 99
-#endif
-
-#if EIGEN_MAX_CPP_VER>=11 && (defined(__cplusplus) && (__cplusplus >= 201103L) || EIGEN_COMP_MSVC >= 1900)
-#define EIGEN_HAS_CXX11 1
-#else
-#define EIGEN_HAS_CXX11 0
-#endif
-
-
-// Do we support r-value references?
-#ifndef EIGEN_HAS_RVALUE_REFERENCES
-#if EIGEN_MAX_CPP_VER>=11 && \
-    (__has_feature(cxx_rvalue_references) || \
-    (defined(__cplusplus) && __cplusplus >= 201103L) || \
-    (EIGEN_COMP_MSVC >= 1600))
-  #define EIGEN_HAS_RVALUE_REFERENCES 1
-#else
-  #define EIGEN_HAS_RVALUE_REFERENCES 0
-#endif
-#endif
-
-// Does the compiler support C99?
-#ifndef EIGEN_HAS_C99_MATH
-#if EIGEN_MAX_CPP_VER>=11 && \
-    ((defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901))       \
-  || (defined(__GNUC__) && defined(_GLIBCXX_USE_C99)) \
-  || (defined(_LIBCPP_VERSION) && !defined(_MSC_VER)))
-  #define EIGEN_HAS_C99_MATH 1
-#else
-  #define EIGEN_HAS_C99_MATH 0
-#endif
-#endif
-
-// Does the compiler support result_of?
-#ifndef EIGEN_HAS_STD_RESULT_OF
-#if EIGEN_MAX_CPP_VER>=11 && ((__has_feature(cxx_lambdas) || (defined(__cplusplus) && __cplusplus >= 201103L)))
-#define EIGEN_HAS_STD_RESULT_OF 1
-#else
-#define EIGEN_HAS_STD_RESULT_OF 0
-#endif
-#endif
-
-// Does the compiler support variadic templates?
-#ifndef EIGEN_HAS_VARIADIC_TEMPLATES
-#if EIGEN_MAX_CPP_VER>=11 && (__cplusplus > 199711L || EIGEN_COMP_MSVC >= 1900) \
-  && (!defined(__NVCC__) || !EIGEN_ARCH_ARM_OR_ARM64 || (EIGEN_CUDACC_VER >= 80000) )
-    // ^^ Disable the use of variadic templates when compiling with versions of nvcc older than 8.0 on ARM devices:
-    //    this prevents nvcc from crashing when compiling Eigen on Tegra X1
-#define EIGEN_HAS_VARIADIC_TEMPLATES 1
-#else
-#define EIGEN_HAS_VARIADIC_TEMPLATES 0
-#endif
-#endif
-
-// Does the compiler fully support const expressions? (as in c++14)
-#ifndef EIGEN_HAS_CONSTEXPR
-
-#ifdef __CUDACC__
-// Const expressions are supported provided that c++11 is enabled and we're using either clang or nvcc 7.5 or above
-#if EIGEN_MAX_CPP_VER>=14 && (__cplusplus > 199711L && (EIGEN_COMP_CLANG || EIGEN_CUDACC_VER >= 70500))
-  #define EIGEN_HAS_CONSTEXPR 1
-#endif
-#elif EIGEN_MAX_CPP_VER>=14 && (__has_feature(cxx_relaxed_constexpr) || (defined(__cplusplus) && __cplusplus >= 201402L) || \
-  (EIGEN_GNUC_AT_LEAST(4,8) && (__cplusplus > 199711L)))
-#define EIGEN_HAS_CONSTEXPR 1
-#endif
-
-#ifndef EIGEN_HAS_CONSTEXPR
-#define EIGEN_HAS_CONSTEXPR 0
-#endif
-
-#endif
-
-// Does the compiler support C++11 math?
-// Let's be conservative and enable the default C++11 implementation only if we are sure it exists
-#ifndef EIGEN_HAS_CXX11_MATH
-  #if EIGEN_MAX_CPP_VER>=11 && ((__cplusplus > 201103L) || (__cplusplus >= 201103L) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_CLANG || EIGEN_COMP_MSVC || EIGEN_COMP_ICC)  \
-      && (EIGEN_ARCH_i386_OR_x86_64) && (EIGEN_OS_GNULINUX || EIGEN_OS_WIN_STRICT || EIGEN_OS_MAC))
-    #define EIGEN_HAS_CXX11_MATH 1
-  #else
-    #define EIGEN_HAS_CXX11_MATH 0
-  #endif
-#endif
-
-// Does the compiler support proper C++11 containers?
-#ifndef EIGEN_HAS_CXX11_CONTAINERS
-  #if    EIGEN_MAX_CPP_VER>=11 && \
-         ((__cplusplus > 201103L) \
-      || ((__cplusplus >= 201103L) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_CLANG || EIGEN_COMP_ICC>=1400)) \
-      || EIGEN_COMP_MSVC >= 1900)
-    #define EIGEN_HAS_CXX11_CONTAINERS 1
-  #else
-    #define EIGEN_HAS_CXX11_CONTAINERS 0
-  #endif
-#endif
-
-// Does the compiler support C++11 noexcept?
-#ifndef EIGEN_HAS_CXX11_NOEXCEPT
-  #if    EIGEN_MAX_CPP_VER>=11 && \
-         (__has_feature(cxx_noexcept) \
-      || (__cplusplus > 201103L) \
-      || ((__cplusplus >= 201103L) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_CLANG || EIGEN_COMP_ICC>=1400)) \
-      || EIGEN_COMP_MSVC >= 1900)
-    #define EIGEN_HAS_CXX11_NOEXCEPT 1
-  #else
-    #define EIGEN_HAS_CXX11_NOEXCEPT 0
-  #endif
-#endif
-
-/** Allows to disable some optimizations which might affect the accuracy of the result.
-  * Such optimization are enabled by default, and set EIGEN_FAST_MATH to 0 to disable them.
-  * They currently include:
-  *   - single precision ArrayBase::sin() and ArrayBase::cos() for SSE and AVX vectorization.
-  */
-#ifndef EIGEN_FAST_MATH
-#define EIGEN_FAST_MATH 1
-#endif
-
-#define EIGEN_DEBUG_VAR(x) std::cerr << #x << " = " << x << std::endl;
-
-// concatenate two tokens
-#define EIGEN_CAT2(a,b) a ## b
-#define EIGEN_CAT(a,b) EIGEN_CAT2(a,b)
-
-#define EIGEN_COMMA ,
-
-// convert a token to a string
-#define EIGEN_MAKESTRING2(a) #a
-#define EIGEN_MAKESTRING(a) EIGEN_MAKESTRING2(a)
-
-// EIGEN_STRONG_INLINE is a stronger version of the inline, using __forceinline on MSVC,
-// but it still doesn't use GCC's always_inline. This is useful in (common) situations where MSVC needs forceinline
-// but GCC is still doing fine with just inline.
-#ifndef EIGEN_STRONG_INLINE
-#if EIGEN_COMP_MSVC || EIGEN_COMP_ICC
-#define EIGEN_STRONG_INLINE __forceinline
-#else
-#define EIGEN_STRONG_INLINE inline
-#endif
-#endif
-
-// EIGEN_ALWAYS_INLINE is the stronget, it has the effect of making the function inline and adding every possible
-// attribute to maximize inlining. This should only be used when really necessary: in particular,
-// it uses __attribute__((always_inline)) on GCC, which most of the time is useless and can severely harm compile times.
-// FIXME with the always_inline attribute,
-// gcc 3.4.x and 4.1 reports the following compilation error:
-//   Eval.h:91: sorry, unimplemented: inlining failed in call to 'const Eigen::Eval<Derived> Eigen::MatrixBase<Scalar, Derived>::eval() const'
-//    : function body not available
-//   See also bug 1367
-#if EIGEN_GNUC_AT_LEAST(4,2)
-#define EIGEN_ALWAYS_INLINE __attribute__((always_inline)) inline
-#else
-#define EIGEN_ALWAYS_INLINE EIGEN_STRONG_INLINE
-#endif
-
-#if EIGEN_COMP_GNUC
-#define EIGEN_DONT_INLINE __attribute__((noinline))
-#elif EIGEN_COMP_MSVC
-#define EIGEN_DONT_INLINE __declspec(noinline)
-#else
-#define EIGEN_DONT_INLINE
-#endif
-
-#if EIGEN_COMP_GNUC
-#define EIGEN_PERMISSIVE_EXPR __extension__
-#else
-#define EIGEN_PERMISSIVE_EXPR
-#endif
-
-// this macro allows to get rid of linking errors about multiply defined functions.
-//  - static is not very good because it prevents definitions from different object files to be merged.
-//           So static causes the resulting linked executable to be bloated with multiple copies of the same function.
-//  - inline is not perfect either as it unwantedly hints the compiler toward inlining the function.
-#define EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
-#define EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS inline
-
-#ifdef NDEBUG
-# ifndef EIGEN_NO_DEBUG
-#  define EIGEN_NO_DEBUG
-# endif
-#endif
-
-// eigen_plain_assert is where we implement the workaround for the assert() bug in GCC <= 4.3, see bug 89
-#ifdef EIGEN_NO_DEBUG
-  #define eigen_plain_assert(x)
-#else
-  #if EIGEN_SAFE_TO_USE_STANDARD_ASSERT_MACRO
-    namespace Eigen {
-    namespace internal {
-    inline bool copy_bool(bool b) { return b; }
-    }
-    }
-    #define eigen_plain_assert(x) assert(x)
-  #else
-    // work around bug 89
-    #include <cstdlib>   // for abort
-    #include <iostream>  // for std::cerr
-
-    namespace Eigen {
-    namespace internal {
-    // trivial function copying a bool. Must be EIGEN_DONT_INLINE, so we implement it after including Eigen headers.
-    // see bug 89.
-    namespace {
-    EIGEN_DONT_INLINE bool copy_bool(bool b) { return b; }
-    }
-    inline void assert_fail(const char *condition, const char *function, const char *file, int line)
-    {
-      std::cerr << "assertion failed: " << condition << " in function " << function << " at " << file << ":" << line << std::endl;
-      abort();
-    }
-    }
-    }
-    #define eigen_plain_assert(x) \
-      do { \
-        if(!Eigen::internal::copy_bool(x)) \
-          Eigen::internal::assert_fail(EIGEN_MAKESTRING(x), __PRETTY_FUNCTION__, __FILE__, __LINE__); \
-      } while(false)
-  #endif
-#endif
-
-// eigen_assert can be overridden
-#ifndef eigen_assert
-#define eigen_assert(x) eigen_plain_assert(x)
-#endif
-
-#ifdef EIGEN_INTERNAL_DEBUGGING
-#define eigen_internal_assert(x) eigen_assert(x)
-#else
-#define eigen_internal_assert(x)
-#endif
-
-#ifdef EIGEN_NO_DEBUG
-#define EIGEN_ONLY_USED_FOR_DEBUG(x) EIGEN_UNUSED_VARIABLE(x)
-#else
-#define EIGEN_ONLY_USED_FOR_DEBUG(x)
-#endif
-
-#ifndef EIGEN_NO_DEPRECATED_WARNING
-  #if EIGEN_COMP_GNUC
-    #define EIGEN_DEPRECATED __attribute__((deprecated))
-  #elif EIGEN_COMP_MSVC
-    #define EIGEN_DEPRECATED __declspec(deprecated)
-  #else
-    #define EIGEN_DEPRECATED
-  #endif
-#else
-  #define EIGEN_DEPRECATED
-#endif
-
-#if EIGEN_COMP_GNUC
-#define EIGEN_UNUSED __attribute__((unused))
-#else
-#define EIGEN_UNUSED
-#endif
-
-// Suppresses 'unused variable' warnings.
-namespace Eigen {
-  namespace internal {
-    template<typename T> EIGEN_DEVICE_FUNC void ignore_unused_variable(const T&) {}
-  }
-}
-#define EIGEN_UNUSED_VARIABLE(var) Eigen::internal::ignore_unused_variable(var);
-
-#if !defined(EIGEN_ASM_COMMENT)
-  #if EIGEN_COMP_GNUC && (EIGEN_ARCH_i386_OR_x86_64 || EIGEN_ARCH_ARM_OR_ARM64)
-    #define EIGEN_ASM_COMMENT(X)  __asm__("#" X)
-  #else
-    #define EIGEN_ASM_COMMENT(X)
-  #endif
-#endif
-
-
-//------------------------------------------------------------------------------------------
-// Static and dynamic alignment control
-//
-// The main purpose of this section is to define EIGEN_MAX_ALIGN_BYTES and EIGEN_MAX_STATIC_ALIGN_BYTES
-// as the maximal boundary in bytes on which dynamically and statically allocated data may be alignment respectively.
-// The values of EIGEN_MAX_ALIGN_BYTES and EIGEN_MAX_STATIC_ALIGN_BYTES can be specified by the user. If not,
-// a default value is automatically computed based on architecture, compiler, and OS.
-//
-// This section also defines macros EIGEN_ALIGN_TO_BOUNDARY(N) and the shortcuts EIGEN_ALIGN{8,16,32,_MAX}
-// to be used to declare statically aligned buffers.
-//------------------------------------------------------------------------------------------
-
-
-/* EIGEN_ALIGN_TO_BOUNDARY(n) forces data to be n-byte aligned. This is used to satisfy SIMD requirements.
- * However, we do that EVEN if vectorization (EIGEN_VECTORIZE) is disabled,
- * so that vectorization doesn't affect binary compatibility.
- *
- * If we made alignment depend on whether or not EIGEN_VECTORIZE is defined, it would be impossible to link
- * vectorized and non-vectorized code.
- */
-#if (defined __CUDACC__)
-  #define EIGEN_ALIGN_TO_BOUNDARY(n) __align__(n)
-#elif EIGEN_COMP_GNUC || EIGEN_COMP_PGI || EIGEN_COMP_IBM || EIGEN_COMP_ARM
-  #define EIGEN_ALIGN_TO_BOUNDARY(n) __attribute__((aligned(n)))
-#elif EIGEN_COMP_MSVC
-  #define EIGEN_ALIGN_TO_BOUNDARY(n) __declspec(align(n))
-#elif EIGEN_COMP_SUNCC
-  // FIXME not sure about this one:
-  #define EIGEN_ALIGN_TO_BOUNDARY(n) __attribute__((aligned(n)))
-#else
-  #error Please tell me what is the equivalent of __attribute__((aligned(n))) for your compiler
-#endif
-
-// If the user explicitly disable vectorization, then we also disable alignment
-#if defined(EIGEN_DONT_VECTORIZE)
-  #define EIGEN_IDEAL_MAX_ALIGN_BYTES 0
-#elif defined(EIGEN_VECTORIZE_AVX512)
-  // 64 bytes static alignmeent is preferred only if really required
-  #define EIGEN_IDEAL_MAX_ALIGN_BYTES 64
-#elif defined(__AVX__)
-  // 32 bytes static alignmeent is preferred only if really required
-  #define EIGEN_IDEAL_MAX_ALIGN_BYTES 32
-#else
-  #define EIGEN_IDEAL_MAX_ALIGN_BYTES 16
-#endif
-
-
-// EIGEN_MIN_ALIGN_BYTES defines the minimal value for which the notion of explicit alignment makes sense
-#define EIGEN_MIN_ALIGN_BYTES 16
-
-// Defined the boundary (in bytes) on which the data needs to be aligned. Note
-// that unless EIGEN_ALIGN is defined and not equal to 0, the data may not be
-// aligned at all regardless of the value of this #define.
-
-#if (defined(EIGEN_DONT_ALIGN_STATICALLY) || defined(EIGEN_DONT_ALIGN))  && defined(EIGEN_MAX_STATIC_ALIGN_BYTES) && EIGEN_MAX_STATIC_ALIGN_BYTES>0
-#error EIGEN_MAX_STATIC_ALIGN_BYTES and EIGEN_DONT_ALIGN[_STATICALLY] are both defined with EIGEN_MAX_STATIC_ALIGN_BYTES!=0. Use EIGEN_MAX_STATIC_ALIGN_BYTES=0 as a synonym of EIGEN_DONT_ALIGN_STATICALLY.
-#endif
-
-// EIGEN_DONT_ALIGN_STATICALLY and EIGEN_DONT_ALIGN are deprectated
-// They imply EIGEN_MAX_STATIC_ALIGN_BYTES=0
-#if defined(EIGEN_DONT_ALIGN_STATICALLY) || defined(EIGEN_DONT_ALIGN)
-  #ifdef EIGEN_MAX_STATIC_ALIGN_BYTES
-    #undef EIGEN_MAX_STATIC_ALIGN_BYTES
-  #endif
-  #define EIGEN_MAX_STATIC_ALIGN_BYTES 0
-#endif
-
-#ifndef EIGEN_MAX_STATIC_ALIGN_BYTES
-
-  // Try to automatically guess what is the best default value for EIGEN_MAX_STATIC_ALIGN_BYTES
-
-  // 16 byte alignment is only useful for vectorization. Since it affects the ABI, we need to enable
-  // 16 byte alignment on all platforms where vectorization might be enabled. In theory we could always
-  // enable alignment, but it can be a cause of problems on some platforms, so we just disable it in
-  // certain common platform (compiler+architecture combinations) to avoid these problems.
-  // Only static alignment is really problematic (relies on nonstandard compiler extensions),
-  // try to keep heap alignment even when we have to disable static alignment.
-  #if EIGEN_COMP_GNUC && !(EIGEN_ARCH_i386_OR_x86_64 || EIGEN_ARCH_ARM_OR_ARM64 || EIGEN_ARCH_PPC || EIGEN_ARCH_IA64)
-  #define EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT 1
-  #elif EIGEN_ARCH_ARM_OR_ARM64 && EIGEN_COMP_GNUC_STRICT && EIGEN_GNUC_AT_MOST(4, 6)
-  // Old versions of GCC on ARM, at least 4.4, were once seen to have buggy static alignment support.
-  // Not sure which version fixed it, hopefully it doesn't affect 4.7, which is still somewhat in use.
-  // 4.8 and newer seem definitely unaffected.
-  #define EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT 1
-  #else
-  #define EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT 0
-  #endif
-
-  // static alignment is completely disabled with GCC 3, Sun Studio, and QCC/QNX
-  #if !EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT \
-  && !EIGEN_GCC3_OR_OLDER \
-  && !EIGEN_COMP_SUNCC \
-  && !EIGEN_OS_QNX
-    #define EIGEN_ARCH_WANTS_STACK_ALIGNMENT 1
-  #else
-    #define EIGEN_ARCH_WANTS_STACK_ALIGNMENT 0
-  #endif
-
-  #if EIGEN_ARCH_WANTS_STACK_ALIGNMENT
-    #define EIGEN_MAX_STATIC_ALIGN_BYTES EIGEN_IDEAL_MAX_ALIGN_BYTES
-  #else
-    #define EIGEN_MAX_STATIC_ALIGN_BYTES 0
-  #endif
-
-#endif
-
-// If EIGEN_MAX_ALIGN_BYTES is defined, then it is considered as an upper bound for EIGEN_MAX_ALIGN_BYTES
-#if defined(EIGEN_MAX_ALIGN_BYTES) && EIGEN_MAX_ALIGN_BYTES<EIGEN_MAX_STATIC_ALIGN_BYTES
-#undef EIGEN_MAX_STATIC_ALIGN_BYTES
-#define EIGEN_MAX_STATIC_ALIGN_BYTES EIGEN_MAX_ALIGN_BYTES
-#endif
-
-#if EIGEN_MAX_STATIC_ALIGN_BYTES==0 && !defined(EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT)
-  #define EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT
-#endif
-
-// At this stage, EIGEN_MAX_STATIC_ALIGN_BYTES>0 is the true test whether we want to align arrays on the stack or not.
-// It takes into account both the user choice to explicitly enable/disable alignment (by settting EIGEN_MAX_STATIC_ALIGN_BYTES)
-// and the architecture config (EIGEN_ARCH_WANTS_STACK_ALIGNMENT).
-// Henceforth, only EIGEN_MAX_STATIC_ALIGN_BYTES should be used.
-
-
-// Shortcuts to EIGEN_ALIGN_TO_BOUNDARY
-#define EIGEN_ALIGN8  EIGEN_ALIGN_TO_BOUNDARY(8)
-#define EIGEN_ALIGN16 EIGEN_ALIGN_TO_BOUNDARY(16)
-#define EIGEN_ALIGN32 EIGEN_ALIGN_TO_BOUNDARY(32)
-#define EIGEN_ALIGN64 EIGEN_ALIGN_TO_BOUNDARY(64)
-#if EIGEN_MAX_STATIC_ALIGN_BYTES>0
-#define EIGEN_ALIGN_MAX EIGEN_ALIGN_TO_BOUNDARY(EIGEN_MAX_STATIC_ALIGN_BYTES)
-#else
-#define EIGEN_ALIGN_MAX
-#endif
-
-
-// Dynamic alignment control
-
-#if defined(EIGEN_DONT_ALIGN) && defined(EIGEN_MAX_ALIGN_BYTES) && EIGEN_MAX_ALIGN_BYTES>0
-#error EIGEN_MAX_ALIGN_BYTES and EIGEN_DONT_ALIGN are both defined with EIGEN_MAX_ALIGN_BYTES!=0. Use EIGEN_MAX_ALIGN_BYTES=0 as a synonym of EIGEN_DONT_ALIGN.
-#endif
-
-#ifdef EIGEN_DONT_ALIGN
-  #ifdef EIGEN_MAX_ALIGN_BYTES
-    #undef EIGEN_MAX_ALIGN_BYTES
-  #endif
-  #define EIGEN_MAX_ALIGN_BYTES 0
-#elif !defined(EIGEN_MAX_ALIGN_BYTES)
-  #define EIGEN_MAX_ALIGN_BYTES EIGEN_IDEAL_MAX_ALIGN_BYTES
-#endif
-
-#if EIGEN_IDEAL_MAX_ALIGN_BYTES > EIGEN_MAX_ALIGN_BYTES
-#define EIGEN_DEFAULT_ALIGN_BYTES EIGEN_IDEAL_MAX_ALIGN_BYTES
-#else
-#define EIGEN_DEFAULT_ALIGN_BYTES EIGEN_MAX_ALIGN_BYTES
-#endif
-
-
-#ifndef EIGEN_UNALIGNED_VECTORIZE
-#define EIGEN_UNALIGNED_VECTORIZE 1
-#endif
-
-//----------------------------------------------------------------------
-
-
-#ifdef EIGEN_DONT_USE_RESTRICT_KEYWORD
-  #define EIGEN_RESTRICT
-#endif
-#ifndef EIGEN_RESTRICT
-  #define EIGEN_RESTRICT __restrict
-#endif
-
-#ifndef EIGEN_STACK_ALLOCATION_LIMIT
-// 131072 == 128 KB
-#define EIGEN_STACK_ALLOCATION_LIMIT 131072
-#endif
-
-#ifndef EIGEN_DEFAULT_IO_FORMAT
-#ifdef EIGEN_MAKING_DOCS
-// format used in Eigen's documentation
-// needed to define it here as escaping characters in CMake add_definition's argument seems very problematic.
-#define EIGEN_DEFAULT_IO_FORMAT Eigen::IOFormat(3, 0, " ", "\n", "", "")
-#else
-#define EIGEN_DEFAULT_IO_FORMAT Eigen::IOFormat()
-#endif
-#endif
-
-// just an empty macro !
-#define EIGEN_EMPTY
-
-#if EIGEN_COMP_MSVC_STRICT && (EIGEN_COMP_MSVC < 1900 || EIGEN_CUDACC_VER>0)
-  // for older MSVC versions, as well as 1900 && CUDA 8, using the base operator is sufficient (cf Bugs 1000, 1324)
-  #define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
-    using Base::operator =;
-#elif EIGEN_COMP_CLANG // workaround clang bug (see http://forum.kde.org/viewtopic.php?f=74&t=102653)
-  #define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
-    using Base::operator =; \
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator=(const Derived& other) { Base::operator=(other); return *this; } \
-    template <typename OtherDerived> \
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator=(const DenseBase<OtherDerived>& other) { Base::operator=(other.derived()); return *this; }
-#else
-  #define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
-    using Base::operator =; \
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator=(const Derived& other) \
-    { \
-      Base::operator=(other); \
-      return *this; \
-    }
-#endif
-
-
-/** \internal
- * \brief Macro to manually inherit assignment operators.
- * This is necessary, because the implicitly defined assignment operator gets deleted when a custom operator= is defined.
- */
-#define EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Derived) EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived)
-
-/**
-* Just a side note. Commenting within defines works only by documenting
-* behind the object (via '!<'). Comments cannot be multi-line and thus
-* we have these extra long lines. What is confusing doxygen over here is
-* that we use '\' and basically have a bunch of typedefs with their
-* documentation in a single line.
-**/
-
-#define EIGEN_GENERIC_PUBLIC_INTERFACE(Derived) \
-  typedef typename Eigen::internal::traits<Derived>::Scalar Scalar; /*!< \brief Numeric type, e.g. float, double, int or std::complex<float>. */ \
-  typedef typename Eigen::NumTraits<Scalar>::Real RealScalar; /*!< \brief The underlying numeric type for composed scalar types. \details In cases where Scalar is e.g. std::complex<T>, T were corresponding to RealScalar. */ \
-  typedef typename Base::CoeffReturnType CoeffReturnType; /*!< \brief The return type for coefficient access. \details Depending on whether the object allows direct coefficient access (e.g. for a MatrixXd), this type is either 'const Scalar&' or simply 'Scalar' for objects that do not allow direct coefficient access. */ \
-  typedef typename Eigen::internal::ref_selector<Derived>::type Nested; \
-  typedef typename Eigen::internal::traits<Derived>::StorageKind StorageKind; \
-  typedef typename Eigen::internal::traits<Derived>::StorageIndex StorageIndex; \
-  enum { RowsAtCompileTime = Eigen::internal::traits<Derived>::RowsAtCompileTime, \
-        ColsAtCompileTime = Eigen::internal::traits<Derived>::ColsAtCompileTime, \
-        Flags = Eigen::internal::traits<Derived>::Flags, \
-        SizeAtCompileTime = Base::SizeAtCompileTime, \
-        MaxSizeAtCompileTime = Base::MaxSizeAtCompileTime, \
-        IsVectorAtCompileTime = Base::IsVectorAtCompileTime }; \
-  using Base::derived; \
-  using Base::const_cast_derived;
-
-
-// FIXME Maybe the EIGEN_DENSE_PUBLIC_INTERFACE could be removed as importing PacketScalar is rarely needed
-#define EIGEN_DENSE_PUBLIC_INTERFACE(Derived) \
-  EIGEN_GENERIC_PUBLIC_INTERFACE(Derived) \
-  typedef typename Base::PacketScalar PacketScalar;
-
-
-#define EIGEN_PLAIN_ENUM_MIN(a,b) (((int)a <= (int)b) ? (int)a : (int)b)
-#define EIGEN_PLAIN_ENUM_MAX(a,b) (((int)a >= (int)b) ? (int)a : (int)b)
-
-// EIGEN_SIZE_MIN_PREFER_DYNAMIC gives the min between compile-time sizes. 0 has absolute priority, followed by 1,
-// followed by Dynamic, followed by other finite values. The reason for giving Dynamic the priority over
-// finite values is that min(3, Dynamic) should be Dynamic, since that could be anything between 0 and 3.
-#define EIGEN_SIZE_MIN_PREFER_DYNAMIC(a,b) (((int)a == 0 || (int)b == 0) ? 0 \
-                           : ((int)a == 1 || (int)b == 1) ? 1 \
-                           : ((int)a == Dynamic || (int)b == Dynamic) ? Dynamic \
-                           : ((int)a <= (int)b) ? (int)a : (int)b)
-
-// EIGEN_SIZE_MIN_PREFER_FIXED is a variant of EIGEN_SIZE_MIN_PREFER_DYNAMIC comparing MaxSizes. The difference is that finite values
-// now have priority over Dynamic, so that min(3, Dynamic) gives 3. Indeed, whatever the actual value is
-// (between 0 and 3), it is not more than 3.
-#define EIGEN_SIZE_MIN_PREFER_FIXED(a,b)  (((int)a == 0 || (int)b == 0) ? 0 \
-                           : ((int)a == 1 || (int)b == 1) ? 1 \
-                           : ((int)a == Dynamic && (int)b == Dynamic) ? Dynamic \
-                           : ((int)a == Dynamic) ? (int)b \
-                           : ((int)b == Dynamic) ? (int)a \
-                           : ((int)a <= (int)b) ? (int)a : (int)b)
-
-// see EIGEN_SIZE_MIN_PREFER_DYNAMIC. No need for a separate variant for MaxSizes here.
-#define EIGEN_SIZE_MAX(a,b) (((int)a == Dynamic || (int)b == Dynamic) ? Dynamic \
-                           : ((int)a >= (int)b) ? (int)a : (int)b)
-
-#define EIGEN_LOGICAL_XOR(a,b) (((a) || (b)) && !((a) && (b)))
-
-#define EIGEN_IMPLIES(a,b) (!(a) || (b))
-
-// the expression type of a standard coefficient wise binary operation
-#define EIGEN_CWISE_BINARY_RETURN_TYPE(LHS,RHS,OPNAME) \
-    CwiseBinaryOp< \
-      EIGEN_CAT(EIGEN_CAT(internal::scalar_,OPNAME),_op)< \
-          typename internal::traits<LHS>::Scalar, \
-          typename internal::traits<RHS>::Scalar \
-      >, \
-      const LHS, \
-      const RHS \
-    >
-
-#define EIGEN_MAKE_CWISE_BINARY_OP(METHOD,OPNAME) \
-  template<typename OtherDerived> \
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const EIGEN_CWISE_BINARY_RETURN_TYPE(Derived,OtherDerived,OPNAME) \
-  (METHOD)(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const \
-  { \
-    return EIGEN_CWISE_BINARY_RETURN_TYPE(Derived,OtherDerived,OPNAME)(derived(), other.derived()); \
-  }
-
-#define EIGEN_SCALAR_BINARY_SUPPORTED(OPNAME,TYPEA,TYPEB) \
-  (Eigen::internal::has_ReturnType<Eigen::ScalarBinaryOpTraits<TYPEA,TYPEB,EIGEN_CAT(EIGEN_CAT(Eigen::internal::scalar_,OPNAME),_op)<TYPEA,TYPEB>  > >::value)
-
-#define EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(EXPR,SCALAR,OPNAME) \
-  CwiseBinaryOp<EIGEN_CAT(EIGEN_CAT(internal::scalar_,OPNAME),_op)<typename internal::traits<EXPR>::Scalar,SCALAR>, const EXPR, \
-                const typename internal::plain_constant_type<EXPR,SCALAR>::type>
-
-#define EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(SCALAR,EXPR,OPNAME) \
-  CwiseBinaryOp<EIGEN_CAT(EIGEN_CAT(internal::scalar_,OPNAME),_op)<SCALAR,typename internal::traits<EXPR>::Scalar>, \
-                const typename internal::plain_constant_type<EXPR,SCALAR>::type, const EXPR>
-
-// Workaround for MSVC 2010 (see ML thread "patch with compile for for MSVC 2010")
-#if EIGEN_COMP_MSVC_STRICT<=1600
-#define EIGEN_MSVC10_WORKAROUND_BINARYOP_RETURN_TYPE(X) typename internal::enable_if<true,X>::type
-#else
-#define EIGEN_MSVC10_WORKAROUND_BINARYOP_RETURN_TYPE(X) X
-#endif
-
-#define EIGEN_MAKE_SCALAR_BINARY_OP_ONTHERIGHT(METHOD,OPNAME) \
-  template <typename T> EIGEN_DEVICE_FUNC inline \
-  EIGEN_MSVC10_WORKAROUND_BINARYOP_RETURN_TYPE(const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(Derived,typename internal::promote_scalar_arg<Scalar EIGEN_COMMA T EIGEN_COMMA EIGEN_SCALAR_BINARY_SUPPORTED(OPNAME,Scalar,T)>::type,OPNAME))\
-  (METHOD)(const T& scalar) const { \
-    typedef typename internal::promote_scalar_arg<Scalar,T,EIGEN_SCALAR_BINARY_SUPPORTED(OPNAME,Scalar,T)>::type PromotedT; \
-    return EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(Derived,PromotedT,OPNAME)(derived(), \
-           typename internal::plain_constant_type<Derived,PromotedT>::type(derived().rows(), derived().cols(), internal::scalar_constant_op<PromotedT>(scalar))); \
-  }
-
-#define EIGEN_MAKE_SCALAR_BINARY_OP_ONTHELEFT(METHOD,OPNAME) \
-  template <typename T> EIGEN_DEVICE_FUNC inline friend \
-  EIGEN_MSVC10_WORKAROUND_BINARYOP_RETURN_TYPE(const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(typename internal::promote_scalar_arg<Scalar EIGEN_COMMA T EIGEN_COMMA EIGEN_SCALAR_BINARY_SUPPORTED(OPNAME,T,Scalar)>::type,Derived,OPNAME)) \
-  (METHOD)(const T& scalar, const StorageBaseType& matrix) { \
-    typedef typename internal::promote_scalar_arg<Scalar,T,EIGEN_SCALAR_BINARY_SUPPORTED(OPNAME,T,Scalar)>::type PromotedT; \
-    return EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(PromotedT,Derived,OPNAME)( \
-           typename internal::plain_constant_type<Derived,PromotedT>::type(matrix.derived().rows(), matrix.derived().cols(), internal::scalar_constant_op<PromotedT>(scalar)), matrix.derived()); \
-  }
-
-#define EIGEN_MAKE_SCALAR_BINARY_OP(METHOD,OPNAME) \
-  EIGEN_MAKE_SCALAR_BINARY_OP_ONTHELEFT(METHOD,OPNAME) \
-  EIGEN_MAKE_SCALAR_BINARY_OP_ONTHERIGHT(METHOD,OPNAME)
-
-
-#ifdef EIGEN_EXCEPTIONS
-#  define EIGEN_THROW_X(X) throw X
-#  define EIGEN_THROW throw
-#  define EIGEN_TRY try
-#  define EIGEN_CATCH(X) catch (X)
-#else
-#  ifdef __CUDA_ARCH__
-#    define EIGEN_THROW_X(X) asm("trap;")
-#    define EIGEN_THROW asm("trap;")
-#  else
-#    define EIGEN_THROW_X(X) std::abort()
-#    define EIGEN_THROW std::abort()
-#  endif
-#  define EIGEN_TRY if (true)
-#  define EIGEN_CATCH(X) else
-#endif
-
-
-#if EIGEN_HAS_CXX11_NOEXCEPT
-#   define EIGEN_INCLUDE_TYPE_TRAITS
-#   define EIGEN_NOEXCEPT noexcept
-#   define EIGEN_NOEXCEPT_IF(x) noexcept(x)
-#   define EIGEN_NO_THROW noexcept(true)
-#   define EIGEN_EXCEPTION_SPEC(X) noexcept(false)
-#else
-#   define EIGEN_NOEXCEPT
-#   define EIGEN_NOEXCEPT_IF(x)
-#   define EIGEN_NO_THROW throw()
-#   if EIGEN_COMP_MSVC
-      // MSVC does not support exception specifications (warning C4290),
-      // and they are deprecated in c++11 anyway.
-#     define EIGEN_EXCEPTION_SPEC(X) throw()
-#   else
-#     define EIGEN_EXCEPTION_SPEC(X) throw(X)
-#   endif
-#endif
-
-#endif // EIGEN_MACROS_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/Memory.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/Memory.h
deleted file mode 100644
index 291383c..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/Memory.h
+++ /dev/null
@@ -1,993 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2015 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2008-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2009 Kenneth Riddile <kfriddile@yahoo.com>
-// Copyright (C) 2010 Hauke Heibel <hauke.heibel@gmail.com>
-// Copyright (C) 2010 Thomas Capricelli <orzel@freehackers.org>
-// Copyright (C) 2013 Pavel Holoborodko <pavel@holoborodko.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-
-/*****************************************************************************
-*** Platform checks for aligned malloc functions                           ***
-*****************************************************************************/
-
-#ifndef EIGEN_MEMORY_H
-#define EIGEN_MEMORY_H
-
-#ifndef EIGEN_MALLOC_ALREADY_ALIGNED
-
-// Try to determine automatically if malloc is already aligned.
-
-// On 64-bit systems, glibc's malloc returns 16-byte-aligned pointers, see:
-//   http://www.gnu.org/s/libc/manual/html_node/Aligned-Memory-Blocks.html
-// This is true at least since glibc 2.8.
-// This leaves the question how to detect 64-bit. According to this document,
-//   http://gcc.fyxm.net/summit/2003/Porting%20to%2064%20bit.pdf
-// page 114, "[The] LP64 model [...] is used by all 64-bit UNIX ports" so it's indeed
-// quite safe, at least within the context of glibc, to equate 64-bit with LP64.
-#if defined(__GLIBC__) && ((__GLIBC__>=2 && __GLIBC_MINOR__ >= 8) || __GLIBC__>2) \
- && defined(__LP64__) && ! defined( __SANITIZE_ADDRESS__ ) && (EIGEN_DEFAULT_ALIGN_BYTES == 16)
-  #define EIGEN_GLIBC_MALLOC_ALREADY_ALIGNED 1
-#else
-  #define EIGEN_GLIBC_MALLOC_ALREADY_ALIGNED 0
-#endif
-
-// FreeBSD 6 seems to have 16-byte aligned malloc
-//   See http://svn.freebsd.org/viewvc/base/stable/6/lib/libc/stdlib/malloc.c?view=markup
-// FreeBSD 7 seems to have 16-byte aligned malloc except on ARM and MIPS architectures
-//   See http://svn.freebsd.org/viewvc/base/stable/7/lib/libc/stdlib/malloc.c?view=markup
-#if defined(__FreeBSD__) && !(EIGEN_ARCH_ARM || EIGEN_ARCH_MIPS) && (EIGEN_DEFAULT_ALIGN_BYTES == 16)
-  #define EIGEN_FREEBSD_MALLOC_ALREADY_ALIGNED 1
-#else
-  #define EIGEN_FREEBSD_MALLOC_ALREADY_ALIGNED 0
-#endif
-
-#if (EIGEN_OS_MAC && (EIGEN_DEFAULT_ALIGN_BYTES == 16))     \
- || (EIGEN_OS_WIN64 && (EIGEN_DEFAULT_ALIGN_BYTES == 16))   \
- || EIGEN_GLIBC_MALLOC_ALREADY_ALIGNED              \
- || EIGEN_FREEBSD_MALLOC_ALREADY_ALIGNED
-  #define EIGEN_MALLOC_ALREADY_ALIGNED 1
-#else
-  #define EIGEN_MALLOC_ALREADY_ALIGNED 0
-#endif
-
-#endif
-
-namespace Eigen {
-
-namespace internal {
-
-EIGEN_DEVICE_FUNC 
-inline void throw_std_bad_alloc()
-{
-  #ifdef EIGEN_EXCEPTIONS
-    throw std::bad_alloc();
-  #else
-    std::size_t huge = static_cast<std::size_t>(-1);
-    ::operator new(huge);
-  #endif
-}
-
-/*****************************************************************************
-*** Implementation of handmade aligned functions                           ***
-*****************************************************************************/
-
-/* ----- Hand made implementations of aligned malloc/free and realloc ----- */
-
-/** \internal Like malloc, but the returned pointer is guaranteed to be 16-byte aligned.
-  * Fast, but wastes 16 additional bytes of memory. Does not throw any exception.
-  */
-inline void* handmade_aligned_malloc(std::size_t size)
-{
-  void *original = std::malloc(size+EIGEN_DEFAULT_ALIGN_BYTES);
-  if (original == 0) return 0;
-  void *aligned = reinterpret_cast<void*>((reinterpret_cast<std::size_t>(original) & ~(std::size_t(EIGEN_DEFAULT_ALIGN_BYTES-1))) + EIGEN_DEFAULT_ALIGN_BYTES);
-  *(reinterpret_cast<void**>(aligned) - 1) = original;
-  return aligned;
-}
-
-/** \internal Frees memory allocated with handmade_aligned_malloc */
-inline void handmade_aligned_free(void *ptr)
-{
-  if (ptr) std::free(*(reinterpret_cast<void**>(ptr) - 1));
-}
-
-/** \internal
-  * \brief Reallocates aligned memory.
-  * Since we know that our handmade version is based on std::malloc
-  * we can use std::realloc to implement efficient reallocation.
-  */
-inline void* handmade_aligned_realloc(void* ptr, std::size_t size, std::size_t = 0)
-{
-  if (ptr == 0) return handmade_aligned_malloc(size);
-  void *original = *(reinterpret_cast<void**>(ptr) - 1);
-  std::ptrdiff_t previous_offset = static_cast<char *>(ptr)-static_cast<char *>(original);
-  original = std::realloc(original,size+EIGEN_DEFAULT_ALIGN_BYTES);
-  if (original == 0) return 0;
-  void *aligned = reinterpret_cast<void*>((reinterpret_cast<std::size_t>(original) & ~(std::size_t(EIGEN_DEFAULT_ALIGN_BYTES-1))) + EIGEN_DEFAULT_ALIGN_BYTES);
-  void *previous_aligned = static_cast<char *>(original)+previous_offset;
-  if(aligned!=previous_aligned)
-    std::memmove(aligned, previous_aligned, size);
-  
-  *(reinterpret_cast<void**>(aligned) - 1) = original;
-  return aligned;
-}
-
-/*****************************************************************************
-*** Implementation of portable aligned versions of malloc/free/realloc     ***
-*****************************************************************************/
-
-#ifdef EIGEN_NO_MALLOC
-EIGEN_DEVICE_FUNC inline void check_that_malloc_is_allowed()
-{
-  eigen_assert(false && "heap allocation is forbidden (EIGEN_NO_MALLOC is defined)");
-}
-#elif defined EIGEN_RUNTIME_NO_MALLOC
-EIGEN_DEVICE_FUNC inline bool is_malloc_allowed_impl(bool update, bool new_value = false)
-{
-  static bool value = true;
-  if (update == 1)
-    value = new_value;
-  return value;
-}
-EIGEN_DEVICE_FUNC inline bool is_malloc_allowed() { return is_malloc_allowed_impl(false); }
-EIGEN_DEVICE_FUNC inline bool set_is_malloc_allowed(bool new_value) { return is_malloc_allowed_impl(true, new_value); }
-EIGEN_DEVICE_FUNC inline void check_that_malloc_is_allowed()
-{
-  eigen_assert(is_malloc_allowed() && "heap allocation is forbidden (EIGEN_RUNTIME_NO_MALLOC is defined and g_is_malloc_allowed is false)");
-}
-#else 
-EIGEN_DEVICE_FUNC inline void check_that_malloc_is_allowed()
-{}
-#endif
-
-/** \internal Allocates \a size bytes. The returned pointer is guaranteed to have 16 or 32 bytes alignment depending on the requirements.
-  * On allocation error, the returned pointer is null, and std::bad_alloc is thrown.
-  */
-EIGEN_DEVICE_FUNC inline void* aligned_malloc(std::size_t size)
-{
-  check_that_malloc_is_allowed();
-
-  void *result;
-  #if (EIGEN_DEFAULT_ALIGN_BYTES==0) || EIGEN_MALLOC_ALREADY_ALIGNED
-    result = std::malloc(size);
-    #if EIGEN_DEFAULT_ALIGN_BYTES==16
-    eigen_assert((size<16 || (std::size_t(result)%16)==0) && "System's malloc returned an unaligned pointer. Compile with EIGEN_MALLOC_ALREADY_ALIGNED=0 to fallback to handmade alignd memory allocator.");
-    #endif
-  #else
-    result = handmade_aligned_malloc(size);
-  #endif
-
-  if(!result && size)
-    throw_std_bad_alloc();
-
-  return result;
-}
-
-/** \internal Frees memory allocated with aligned_malloc. */
-EIGEN_DEVICE_FUNC inline void aligned_free(void *ptr)
-{
-  #if (EIGEN_DEFAULT_ALIGN_BYTES==0) || EIGEN_MALLOC_ALREADY_ALIGNED
-    std::free(ptr);
-  #else
-    handmade_aligned_free(ptr);
-  #endif
-}
-
-/**
-  * \internal
-  * \brief Reallocates an aligned block of memory.
-  * \throws std::bad_alloc on allocation failure
-  */
-inline void* aligned_realloc(void *ptr, std::size_t new_size, std::size_t old_size)
-{
-  EIGEN_UNUSED_VARIABLE(old_size);
-
-  void *result;
-#if (EIGEN_DEFAULT_ALIGN_BYTES==0) || EIGEN_MALLOC_ALREADY_ALIGNED
-  result = std::realloc(ptr,new_size);
-#else
-  result = handmade_aligned_realloc(ptr,new_size,old_size);
-#endif
-
-  if (!result && new_size)
-    throw_std_bad_alloc();
-
-  return result;
-}
-
-/*****************************************************************************
-*** Implementation of conditionally aligned functions                      ***
-*****************************************************************************/
-
-/** \internal Allocates \a size bytes. If Align is true, then the returned ptr is 16-byte-aligned.
-  * On allocation error, the returned pointer is null, and a std::bad_alloc is thrown.
-  */
-template<bool Align> EIGEN_DEVICE_FUNC inline void* conditional_aligned_malloc(std::size_t size)
-{
-  return aligned_malloc(size);
-}
-
-template<> EIGEN_DEVICE_FUNC inline void* conditional_aligned_malloc<false>(std::size_t size)
-{
-  check_that_malloc_is_allowed();
-
-  void *result = std::malloc(size);
-  if(!result && size)
-    throw_std_bad_alloc();
-  return result;
-}
-
-/** \internal Frees memory allocated with conditional_aligned_malloc */
-template<bool Align> EIGEN_DEVICE_FUNC inline void conditional_aligned_free(void *ptr)
-{
-  aligned_free(ptr);
-}
-
-template<> EIGEN_DEVICE_FUNC inline void conditional_aligned_free<false>(void *ptr)
-{
-  std::free(ptr);
-}
-
-template<bool Align> inline void* conditional_aligned_realloc(void* ptr, std::size_t new_size, std::size_t old_size)
-{
-  return aligned_realloc(ptr, new_size, old_size);
-}
-
-template<> inline void* conditional_aligned_realloc<false>(void* ptr, std::size_t new_size, std::size_t)
-{
-  return std::realloc(ptr, new_size);
-}
-
-/*****************************************************************************
-*** Construction/destruction of array elements                             ***
-*****************************************************************************/
-
-/** \internal Destructs the elements of an array.
-  * The \a size parameters tells on how many objects to call the destructor of T.
-  */
-template<typename T> EIGEN_DEVICE_FUNC inline void destruct_elements_of_array(T *ptr, std::size_t size)
-{
-  // always destruct an array starting from the end.
-  if(ptr)
-    while(size) ptr[--size].~T();
-}
-
-/** \internal Constructs the elements of an array.
-  * The \a size parameter tells on how many objects to call the constructor of T.
-  */
-template<typename T> EIGEN_DEVICE_FUNC inline T* construct_elements_of_array(T *ptr, std::size_t size)
-{
-  std::size_t i;
-  EIGEN_TRY
-  {
-      for (i = 0; i < size; ++i) ::new (ptr + i) T;
-      return ptr;
-  }
-  EIGEN_CATCH(...)
-  {
-    destruct_elements_of_array(ptr, i);
-    EIGEN_THROW;
-  }
-  return NULL;
-}
-
-/*****************************************************************************
-*** Implementation of aligned new/delete-like functions                    ***
-*****************************************************************************/
-
-template<typename T>
-EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void check_size_for_overflow(std::size_t size)
-{
-  if(size > std::size_t(-1) / sizeof(T))
-    throw_std_bad_alloc();
-}
-
-/** \internal Allocates \a size objects of type T. The returned pointer is guaranteed to have 16 bytes alignment.
-  * On allocation error, the returned pointer is undefined, but a std::bad_alloc is thrown.
-  * The default constructor of T is called.
-  */
-template<typename T> EIGEN_DEVICE_FUNC inline T* aligned_new(std::size_t size)
-{
-  check_size_for_overflow<T>(size);
-  T *result = reinterpret_cast<T*>(aligned_malloc(sizeof(T)*size));
-  EIGEN_TRY
-  {
-    return construct_elements_of_array(result, size);
-  }
-  EIGEN_CATCH(...)
-  {
-    aligned_free(result);
-    EIGEN_THROW;
-  }
-  return result;
-}
-
-template<typename T, bool Align> EIGEN_DEVICE_FUNC inline T* conditional_aligned_new(std::size_t size)
-{
-  check_size_for_overflow<T>(size);
-  T *result = reinterpret_cast<T*>(conditional_aligned_malloc<Align>(sizeof(T)*size));
-  EIGEN_TRY
-  {
-    return construct_elements_of_array(result, size);
-  }
-  EIGEN_CATCH(...)
-  {
-    conditional_aligned_free<Align>(result);
-    EIGEN_THROW;
-  }
-  return result;
-}
-
-/** \internal Deletes objects constructed with aligned_new
-  * The \a size parameters tells on how many objects to call the destructor of T.
-  */
-template<typename T> EIGEN_DEVICE_FUNC inline void aligned_delete(T *ptr, std::size_t size)
-{
-  destruct_elements_of_array<T>(ptr, size);
-  aligned_free(ptr);
-}
-
-/** \internal Deletes objects constructed with conditional_aligned_new
-  * The \a size parameters tells on how many objects to call the destructor of T.
-  */
-template<typename T, bool Align> EIGEN_DEVICE_FUNC inline void conditional_aligned_delete(T *ptr, std::size_t size)
-{
-  destruct_elements_of_array<T>(ptr, size);
-  conditional_aligned_free<Align>(ptr);
-}
-
-template<typename T, bool Align> EIGEN_DEVICE_FUNC inline T* conditional_aligned_realloc_new(T* pts, std::size_t new_size, std::size_t old_size)
-{
-  check_size_for_overflow<T>(new_size);
-  check_size_for_overflow<T>(old_size);
-  if(new_size < old_size)
-    destruct_elements_of_array(pts+new_size, old_size-new_size);
-  T *result = reinterpret_cast<T*>(conditional_aligned_realloc<Align>(reinterpret_cast<void*>(pts), sizeof(T)*new_size, sizeof(T)*old_size));
-  if(new_size > old_size)
-  {
-    EIGEN_TRY
-    {
-      construct_elements_of_array(result+old_size, new_size-old_size);
-    }
-    EIGEN_CATCH(...)
-    {
-      conditional_aligned_free<Align>(result);
-      EIGEN_THROW;
-    }
-  }
-  return result;
-}
-
-
-template<typename T, bool Align> EIGEN_DEVICE_FUNC inline T* conditional_aligned_new_auto(std::size_t size)
-{
-  if(size==0)
-    return 0; // short-cut. Also fixes Bug 884
-  check_size_for_overflow<T>(size);
-  T *result = reinterpret_cast<T*>(conditional_aligned_malloc<Align>(sizeof(T)*size));
-  if(NumTraits<T>::RequireInitialization)
-  {
-    EIGEN_TRY
-    {
-      construct_elements_of_array(result, size);
-    }
-    EIGEN_CATCH(...)
-    {
-      conditional_aligned_free<Align>(result);
-      EIGEN_THROW;
-    }
-  }
-  return result;
-}
-
-template<typename T, bool Align> inline T* conditional_aligned_realloc_new_auto(T* pts, std::size_t new_size, std::size_t old_size)
-{
-  check_size_for_overflow<T>(new_size);
-  check_size_for_overflow<T>(old_size);
-  if(NumTraits<T>::RequireInitialization && (new_size < old_size))
-    destruct_elements_of_array(pts+new_size, old_size-new_size);
-  T *result = reinterpret_cast<T*>(conditional_aligned_realloc<Align>(reinterpret_cast<void*>(pts), sizeof(T)*new_size, sizeof(T)*old_size));
-  if(NumTraits<T>::RequireInitialization && (new_size > old_size))
-  {
-    EIGEN_TRY
-    {
-      construct_elements_of_array(result+old_size, new_size-old_size);
-    }
-    EIGEN_CATCH(...)
-    {
-      conditional_aligned_free<Align>(result);
-      EIGEN_THROW;
-    }
-  }
-  return result;
-}
-
-template<typename T, bool Align> EIGEN_DEVICE_FUNC inline void conditional_aligned_delete_auto(T *ptr, std::size_t size)
-{
-  if(NumTraits<T>::RequireInitialization)
-    destruct_elements_of_array<T>(ptr, size);
-  conditional_aligned_free<Align>(ptr);
-}
-
-/****************************************************************************/
-
-/** \internal Returns the index of the first element of the array that is well aligned with respect to the requested \a Alignment.
-  *
-  * \tparam Alignment requested alignment in Bytes.
-  * \param array the address of the start of the array
-  * \param size the size of the array
-  *
-  * \note If no element of the array is well aligned or the requested alignment is not a multiple of a scalar,
-  * the size of the array is returned. For example with SSE, the requested alignment is typically 16-bytes. If
-  * packet size for the given scalar type is 1, then everything is considered well-aligned.
-  *
-  * \note Otherwise, if the Alignment is larger that the scalar size, we rely on the assumptions that sizeof(Scalar) is a
-  * power of 2. On the other hand, we do not assume that the array address is a multiple of sizeof(Scalar), as that fails for
-  * example with Scalar=double on certain 32-bit platforms, see bug #79.
-  *
-  * There is also the variant first_aligned(const MatrixBase&) defined in DenseCoeffsBase.h.
-  * \sa first_default_aligned()
-  */
-template<int Alignment, typename Scalar, typename Index>
-EIGEN_DEVICE_FUNC inline Index first_aligned(const Scalar* array, Index size)
-{
-  const Index ScalarSize = sizeof(Scalar);
-  const Index AlignmentSize = Alignment / ScalarSize;
-  const Index AlignmentMask = AlignmentSize-1;
-
-  if(AlignmentSize<=1)
-  {
-    // Either the requested alignment if smaller than a scalar, or it exactly match a 1 scalar
-    // so that all elements of the array have the same alignment.
-    return 0;
-  }
-  else if( (UIntPtr(array) & (sizeof(Scalar)-1)) || (Alignment%ScalarSize)!=0)
-  {
-    // The array is not aligned to the size of a single scalar, or the requested alignment is not a multiple of the scalar size.
-    // Consequently, no element of the array is well aligned.
-    return size;
-  }
-  else
-  {
-    Index first = (AlignmentSize - (Index((UIntPtr(array)/sizeof(Scalar))) & AlignmentMask)) & AlignmentMask;
-    return (first < size) ? first : size;
-  }
-}
-
-/** \internal Returns the index of the first element of the array that is well aligned with respect the largest packet requirement.
-   * \sa first_aligned(Scalar*,Index) and first_default_aligned(DenseBase<Derived>) */
-template<typename Scalar, typename Index>
-EIGEN_DEVICE_FUNC inline Index first_default_aligned(const Scalar* array, Index size)
-{
-  typedef typename packet_traits<Scalar>::type DefaultPacketType;
-  return first_aligned<unpacket_traits<DefaultPacketType>::alignment>(array, size);
-}
-
-/** \internal Returns the smallest integer multiple of \a base and greater or equal to \a size
-  */ 
-template<typename Index> 
-inline Index first_multiple(Index size, Index base)
-{
-  return ((size+base-1)/base)*base;
-}
-
-// std::copy is much slower than memcpy, so let's introduce a smart_copy which
-// use memcpy on trivial types, i.e., on types that does not require an initialization ctor.
-template<typename T, bool UseMemcpy> struct smart_copy_helper;
-
-template<typename T> EIGEN_DEVICE_FUNC void smart_copy(const T* start, const T* end, T* target)
-{
-  smart_copy_helper<T,!NumTraits<T>::RequireInitialization>::run(start, end, target);
-}
-
-template<typename T> struct smart_copy_helper<T,true> {
-  EIGEN_DEVICE_FUNC static inline void run(const T* start, const T* end, T* target)
-  {
-    IntPtr size = IntPtr(end)-IntPtr(start);
-    if(size==0) return;
-    eigen_internal_assert(start!=0 && end!=0 && target!=0);
-    std::memcpy(target, start, size);
-  }
-};
-
-template<typename T> struct smart_copy_helper<T,false> {
-  EIGEN_DEVICE_FUNC static inline void run(const T* start, const T* end, T* target)
-  { std::copy(start, end, target); }
-};
-
-// intelligent memmove. falls back to std::memmove for POD types, uses std::copy otherwise. 
-template<typename T, bool UseMemmove> struct smart_memmove_helper;
-
-template<typename T> void smart_memmove(const T* start, const T* end, T* target)
-{
-  smart_memmove_helper<T,!NumTraits<T>::RequireInitialization>::run(start, end, target);
-}
-
-template<typename T> struct smart_memmove_helper<T,true> {
-  static inline void run(const T* start, const T* end, T* target)
-  {
-    IntPtr size = IntPtr(end)-IntPtr(start);
-    if(size==0) return;
-    eigen_internal_assert(start!=0 && end!=0 && target!=0);
-    std::memmove(target, start, size);
-  }
-};
-
-template<typename T> struct smart_memmove_helper<T,false> {
-  static inline void run(const T* start, const T* end, T* target)
-  { 
-    if (UIntPtr(target) < UIntPtr(start))
-    {
-      std::copy(start, end, target);
-    }
-    else                                 
-    {
-      std::ptrdiff_t count = (std::ptrdiff_t(end)-std::ptrdiff_t(start)) / sizeof(T);
-      std::copy_backward(start, end, target + count); 
-    }
-  }
-};
-
-
-/*****************************************************************************
-*** Implementation of runtime stack allocation (falling back to malloc)    ***
-*****************************************************************************/
-
-// you can overwrite Eigen's default behavior regarding alloca by defining EIGEN_ALLOCA
-// to the appropriate stack allocation function
-#ifndef EIGEN_ALLOCA
-  #if EIGEN_OS_LINUX || EIGEN_OS_MAC || (defined alloca)
-    #define EIGEN_ALLOCA alloca
-  #elif EIGEN_COMP_MSVC
-    #define EIGEN_ALLOCA _alloca
-  #endif
-#endif
-
-// This helper class construct the allocated memory, and takes care of destructing and freeing the handled data
-// at destruction time. In practice this helper class is mainly useful to avoid memory leak in case of exceptions.
-template<typename T> class aligned_stack_memory_handler : noncopyable
-{
-  public:
-    /* Creates a stack_memory_handler responsible for the buffer \a ptr of size \a size.
-     * Note that \a ptr can be 0 regardless of the other parameters.
-     * This constructor takes care of constructing/initializing the elements of the buffer if required by the scalar type T (see NumTraits<T>::RequireInitialization).
-     * In this case, the buffer elements will also be destructed when this handler will be destructed.
-     * Finally, if \a dealloc is true, then the pointer \a ptr is freed.
-     **/
-    aligned_stack_memory_handler(T* ptr, std::size_t size, bool dealloc)
-      : m_ptr(ptr), m_size(size), m_deallocate(dealloc)
-    {
-      if(NumTraits<T>::RequireInitialization && m_ptr)
-        Eigen::internal::construct_elements_of_array(m_ptr, size);
-    }
-    ~aligned_stack_memory_handler()
-    {
-      if(NumTraits<T>::RequireInitialization && m_ptr)
-        Eigen::internal::destruct_elements_of_array<T>(m_ptr, m_size);
-      if(m_deallocate)
-        Eigen::internal::aligned_free(m_ptr);
-    }
-  protected:
-    T* m_ptr;
-    std::size_t m_size;
-    bool m_deallocate;
-};
-
-template<typename T> class scoped_array : noncopyable
-{
-  T* m_ptr;
-public:
-  explicit scoped_array(std::ptrdiff_t size)
-  {
-    m_ptr = new T[size];
-  }
-  ~scoped_array()
-  {
-    delete[] m_ptr;
-  }
-  T& operator[](std::ptrdiff_t i) { return m_ptr[i]; }
-  const T& operator[](std::ptrdiff_t i) const { return m_ptr[i]; }
-  T* &ptr() { return m_ptr; }
-  const T* ptr() const { return m_ptr; }
-  operator const T*() const { return m_ptr; }
-};
-
-template<typename T> void swap(scoped_array<T> &a,scoped_array<T> &b)
-{
-  std::swap(a.ptr(),b.ptr());
-}
-    
-} // end namespace internal
-
-/** \internal
-  * Declares, allocates and construct an aligned buffer named NAME of SIZE elements of type TYPE on the stack
-  * if SIZE is smaller than EIGEN_STACK_ALLOCATION_LIMIT, and if stack allocation is supported by the platform
-  * (currently, this is Linux and Visual Studio only). Otherwise the memory is allocated on the heap.
-  * The allocated buffer is automatically deleted when exiting the scope of this declaration.
-  * If BUFFER is non null, then the declared variable is simply an alias for BUFFER, and no allocation/deletion occurs.
-  * Here is an example:
-  * \code
-  * {
-  *   ei_declare_aligned_stack_constructed_variable(float,data,size,0);
-  *   // use data[0] to data[size-1]
-  * }
-  * \endcode
-  * The underlying stack allocation function can controlled with the EIGEN_ALLOCA preprocessor token.
-  */
-#ifdef EIGEN_ALLOCA
-  
-  #if EIGEN_DEFAULT_ALIGN_BYTES>0
-    // We always manually re-align the result of EIGEN_ALLOCA.
-    // If alloca is already aligned, the compiler should be smart enough to optimize away the re-alignment.
-    #define EIGEN_ALIGNED_ALLOCA(SIZE) reinterpret_cast<void*>((internal::UIntPtr(EIGEN_ALLOCA(SIZE+EIGEN_DEFAULT_ALIGN_BYTES-1)) + EIGEN_DEFAULT_ALIGN_BYTES-1) & ~(std::size_t(EIGEN_DEFAULT_ALIGN_BYTES-1)))
-  #else
-    #define EIGEN_ALIGNED_ALLOCA(SIZE) EIGEN_ALLOCA(SIZE)
-  #endif
-
-  #define ei_declare_aligned_stack_constructed_variable(TYPE,NAME,SIZE,BUFFER) \
-    Eigen::internal::check_size_for_overflow<TYPE>(SIZE); \
-    TYPE* NAME = (BUFFER)!=0 ? (BUFFER) \
-               : reinterpret_cast<TYPE*>( \
-                      (sizeof(TYPE)*SIZE<=EIGEN_STACK_ALLOCATION_LIMIT) ? EIGEN_ALIGNED_ALLOCA(sizeof(TYPE)*SIZE) \
-                    : Eigen::internal::aligned_malloc(sizeof(TYPE)*SIZE) );  \
-    Eigen::internal::aligned_stack_memory_handler<TYPE> EIGEN_CAT(NAME,_stack_memory_destructor)((BUFFER)==0 ? NAME : 0,SIZE,sizeof(TYPE)*SIZE>EIGEN_STACK_ALLOCATION_LIMIT)
-
-#else
-
-  #define ei_declare_aligned_stack_constructed_variable(TYPE,NAME,SIZE,BUFFER) \
-    Eigen::internal::check_size_for_overflow<TYPE>(SIZE); \
-    TYPE* NAME = (BUFFER)!=0 ? BUFFER : reinterpret_cast<TYPE*>(Eigen::internal::aligned_malloc(sizeof(TYPE)*SIZE));    \
-    Eigen::internal::aligned_stack_memory_handler<TYPE> EIGEN_CAT(NAME,_stack_memory_destructor)((BUFFER)==0 ? NAME : 0,SIZE,true)
-    
-#endif
-
-
-/*****************************************************************************
-*** Implementation of EIGEN_MAKE_ALIGNED_OPERATOR_NEW [_IF]                ***
-*****************************************************************************/
-
-#if EIGEN_MAX_ALIGN_BYTES!=0
-  #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \
-      void* operator new(std::size_t size, const std::nothrow_t&) EIGEN_NO_THROW { \
-        EIGEN_TRY { return Eigen::internal::conditional_aligned_malloc<NeedsToAlign>(size); } \
-        EIGEN_CATCH (...) { return 0; } \
-      }
-  #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign) \
-      void *operator new(std::size_t size) { \
-        return Eigen::internal::conditional_aligned_malloc<NeedsToAlign>(size); \
-      } \
-      void *operator new[](std::size_t size) { \
-        return Eigen::internal::conditional_aligned_malloc<NeedsToAlign>(size); \
-      } \
-      void operator delete(void * ptr) EIGEN_NO_THROW { Eigen::internal::conditional_aligned_free<NeedsToAlign>(ptr); } \
-      void operator delete[](void * ptr) EIGEN_NO_THROW { Eigen::internal::conditional_aligned_free<NeedsToAlign>(ptr); } \
-      void operator delete(void * ptr, std::size_t /* sz */) EIGEN_NO_THROW { Eigen::internal::conditional_aligned_free<NeedsToAlign>(ptr); } \
-      void operator delete[](void * ptr, std::size_t /* sz */) EIGEN_NO_THROW { Eigen::internal::conditional_aligned_free<NeedsToAlign>(ptr); } \
-      /* in-place new and delete. since (at least afaik) there is no actual   */ \
-      /* memory allocated we can safely let the default implementation handle */ \
-      /* this particular case. */ \
-      static void *operator new(std::size_t size, void *ptr) { return ::operator new(size,ptr); } \
-      static void *operator new[](std::size_t size, void* ptr) { return ::operator new[](size,ptr); } \
-      void operator delete(void * memory, void *ptr) EIGEN_NO_THROW { return ::operator delete(memory,ptr); } \
-      void operator delete[](void * memory, void *ptr) EIGEN_NO_THROW { return ::operator delete[](memory,ptr); } \
-      /* nothrow-new (returns zero instead of std::bad_alloc) */ \
-      EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \
-      void operator delete(void *ptr, const std::nothrow_t&) EIGEN_NO_THROW { \
-        Eigen::internal::conditional_aligned_free<NeedsToAlign>(ptr); \
-      } \
-      typedef void eigen_aligned_operator_new_marker_type;
-#else
-  #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
-#endif
-
-#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(true)
-#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(Scalar,Size) \
-  EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(bool(((Size)!=Eigen::Dynamic) && ((sizeof(Scalar)*(Size))%EIGEN_MAX_ALIGN_BYTES==0)))
-
-/****************************************************************************/
-
-/** \class aligned_allocator
-* \ingroup Core_Module
-*
-* \brief STL compatible allocator to use with types requiring a non standrad alignment.
-*
-* The memory is aligned as for dynamically aligned matrix/array types such as MatrixXd.
-* By default, it will thus provide at least 16 bytes alignment and more in following cases:
-*  - 32 bytes alignment if AVX is enabled.
-*  - 64 bytes alignment if AVX512 is enabled.
-*
-* This can be controled using the \c EIGEN_MAX_ALIGN_BYTES macro as documented
-* \link TopicPreprocessorDirectivesPerformance there \endlink.
-*
-* Example:
-* \code
-* // Matrix4f requires 16 bytes alignment:
-* std::map< int, Matrix4f, std::less<int>, 
-*           aligned_allocator<std::pair<const int, Matrix4f> > > my_map_mat4;
-* // Vector3f does not require 16 bytes alignment, no need to use Eigen's allocator:
-* std::map< int, Vector3f > my_map_vec3;
-* \endcode
-*
-* \sa \blank \ref TopicStlContainers.
-*/
-template<class T>
-class aligned_allocator : public std::allocator<T>
-{
-public:
-  typedef std::size_t     size_type;
-  typedef std::ptrdiff_t  difference_type;
-  typedef T*              pointer;
-  typedef const T*        const_pointer;
-  typedef T&              reference;
-  typedef const T&        const_reference;
-  typedef T               value_type;
-
-  template<class U>
-  struct rebind
-  {
-    typedef aligned_allocator<U> other;
-  };
-
-  aligned_allocator() : std::allocator<T>() {}
-
-  aligned_allocator(const aligned_allocator& other) : std::allocator<T>(other) {}
-
-  template<class U>
-  aligned_allocator(const aligned_allocator<U>& other) : std::allocator<T>(other) {}
-
-  ~aligned_allocator() {}
-
-  pointer allocate(size_type num, const void* /*hint*/ = 0)
-  {
-    internal::check_size_for_overflow<T>(num);
-    size_type size = num * sizeof(T);
-#if EIGEN_COMP_GNUC_STRICT && EIGEN_GNUC_AT_LEAST(7,0)
-    // workaround gcc bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87544
-    // It triggered eigen/Eigen/src/Core/util/Memory.h:189:12: warning: argument 1 value '18446744073709551612' exceeds maximum object size 9223372036854775807
-    if(size>=std::size_t((std::numeric_limits<std::ptrdiff_t>::max)()))
-      return 0;
-    else
-#endif
-      return static_cast<pointer>( internal::aligned_malloc(size) );
-  }
-
-  void deallocate(pointer p, size_type /*num*/)
-  {
-    internal::aligned_free(p);
-  }
-};
-
-//---------- Cache sizes ----------
-
-#if !defined(EIGEN_NO_CPUID)
-#  if EIGEN_COMP_GNUC && EIGEN_ARCH_i386_OR_x86_64
-#    if defined(__PIC__) && EIGEN_ARCH_i386
-       // Case for x86 with PIC
-#      define EIGEN_CPUID(abcd,func,id) \
-         __asm__ __volatile__ ("xchgl %%ebx, %k1;cpuid; xchgl %%ebx,%k1": "=a" (abcd[0]), "=&r" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "a" (func), "c" (id));
-#    elif defined(__PIC__) && EIGEN_ARCH_x86_64
-       // Case for x64 with PIC. In theory this is only a problem with recent gcc and with medium or large code model, not with the default small code model.
-       // However, we cannot detect which code model is used, and the xchg overhead is negligible anyway.
-#      define EIGEN_CPUID(abcd,func,id) \
-        __asm__ __volatile__ ("xchg{q}\t{%%}rbx, %q1; cpuid; xchg{q}\t{%%}rbx, %q1": "=a" (abcd[0]), "=&r" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "0" (func), "2" (id));
-#    else
-       // Case for x86_64 or x86 w/o PIC
-#      define EIGEN_CPUID(abcd,func,id) \
-         __asm__ __volatile__ ("cpuid": "=a" (abcd[0]), "=b" (abcd[1]), "=c" (abcd[2]), "=d" (abcd[3]) : "0" (func), "2" (id) );
-#    endif
-#  elif EIGEN_COMP_MSVC
-#    if (EIGEN_COMP_MSVC > 1500) && EIGEN_ARCH_i386_OR_x86_64
-#      define EIGEN_CPUID(abcd,func,id) __cpuidex((int*)abcd,func,id)
-#    endif
-#  endif
-#endif
-
-namespace internal {
-
-#ifdef EIGEN_CPUID
-
-inline bool cpuid_is_vendor(int abcd[4], const int vendor[3])
-{
-  return abcd[1]==vendor[0] && abcd[3]==vendor[1] && abcd[2]==vendor[2];
-}
-
-inline void queryCacheSizes_intel_direct(int& l1, int& l2, int& l3)
-{
-  int abcd[4];
-  l1 = l2 = l3 = 0;
-  int cache_id = 0;
-  int cache_type = 0;
-  do {
-    abcd[0] = abcd[1] = abcd[2] = abcd[3] = 0;
-    EIGEN_CPUID(abcd,0x4,cache_id);
-    cache_type  = (abcd[0] & 0x0F) >> 0;
-    if(cache_type==1||cache_type==3) // data or unified cache
-    {
-      int cache_level = (abcd[0] & 0xE0) >> 5;  // A[7:5]
-      int ways        = (abcd[1] & 0xFFC00000) >> 22; // B[31:22]
-      int partitions  = (abcd[1] & 0x003FF000) >> 12; // B[21:12]
-      int line_size   = (abcd[1] & 0x00000FFF) >>  0; // B[11:0]
-      int sets        = (abcd[2]);                    // C[31:0]
-
-      int cache_size = (ways+1) * (partitions+1) * (line_size+1) * (sets+1);
-
-      switch(cache_level)
-      {
-        case 1: l1 = cache_size; break;
-        case 2: l2 = cache_size; break;
-        case 3: l3 = cache_size; break;
-        default: break;
-      }
-    }
-    cache_id++;
-  } while(cache_type>0 && cache_id<16);
-}
-
-inline void queryCacheSizes_intel_codes(int& l1, int& l2, int& l3)
-{
-  int abcd[4];
-  abcd[0] = abcd[1] = abcd[2] = abcd[3] = 0;
-  l1 = l2 = l3 = 0;
-  EIGEN_CPUID(abcd,0x00000002,0);
-  unsigned char * bytes = reinterpret_cast<unsigned char *>(abcd)+2;
-  bool check_for_p2_core2 = false;
-  for(int i=0; i<14; ++i)
-  {
-    switch(bytes[i])
-    {
-      case 0x0A: l1 = 8; break;   // 0Ah   data L1 cache, 8 KB, 2 ways, 32 byte lines
-      case 0x0C: l1 = 16; break;  // 0Ch   data L1 cache, 16 KB, 4 ways, 32 byte lines
-      case 0x0E: l1 = 24; break;  // 0Eh   data L1 cache, 24 KB, 6 ways, 64 byte lines
-      case 0x10: l1 = 16; break;  // 10h   data L1 cache, 16 KB, 4 ways, 32 byte lines (IA-64)
-      case 0x15: l1 = 16; break;  // 15h   code L1 cache, 16 KB, 4 ways, 32 byte lines (IA-64)
-      case 0x2C: l1 = 32; break;  // 2Ch   data L1 cache, 32 KB, 8 ways, 64 byte lines
-      case 0x30: l1 = 32; break;  // 30h   code L1 cache, 32 KB, 8 ways, 64 byte lines
-      case 0x60: l1 = 16; break;  // 60h   data L1 cache, 16 KB, 8 ways, 64 byte lines, sectored
-      case 0x66: l1 = 8; break;   // 66h   data L1 cache, 8 KB, 4 ways, 64 byte lines, sectored
-      case 0x67: l1 = 16; break;  // 67h   data L1 cache, 16 KB, 4 ways, 64 byte lines, sectored
-      case 0x68: l1 = 32; break;  // 68h   data L1 cache, 32 KB, 4 ways, 64 byte lines, sectored
-      case 0x1A: l2 = 96; break;   // code and data L2 cache, 96 KB, 6 ways, 64 byte lines (IA-64)
-      case 0x22: l3 = 512; break;   // code and data L3 cache, 512 KB, 4 ways (!), 64 byte lines, dual-sectored
-      case 0x23: l3 = 1024; break;   // code and data L3 cache, 1024 KB, 8 ways, 64 byte lines, dual-sectored
-      case 0x25: l3 = 2048; break;   // code and data L3 cache, 2048 KB, 8 ways, 64 byte lines, dual-sectored
-      case 0x29: l3 = 4096; break;   // code and data L3 cache, 4096 KB, 8 ways, 64 byte lines, dual-sectored
-      case 0x39: l2 = 128; break;   // code and data L2 cache, 128 KB, 4 ways, 64 byte lines, sectored
-      case 0x3A: l2 = 192; break;   // code and data L2 cache, 192 KB, 6 ways, 64 byte lines, sectored
-      case 0x3B: l2 = 128; break;   // code and data L2 cache, 128 KB, 2 ways, 64 byte lines, sectored
-      case 0x3C: l2 = 256; break;   // code and data L2 cache, 256 KB, 4 ways, 64 byte lines, sectored
-      case 0x3D: l2 = 384; break;   // code and data L2 cache, 384 KB, 6 ways, 64 byte lines, sectored
-      case 0x3E: l2 = 512; break;   // code and data L2 cache, 512 KB, 4 ways, 64 byte lines, sectored
-      case 0x40: l2 = 0; break;   // no integrated L2 cache (P6 core) or L3 cache (P4 core)
-      case 0x41: l2 = 128; break;   // code and data L2 cache, 128 KB, 4 ways, 32 byte lines
-      case 0x42: l2 = 256; break;   // code and data L2 cache, 256 KB, 4 ways, 32 byte lines
-      case 0x43: l2 = 512; break;   // code and data L2 cache, 512 KB, 4 ways, 32 byte lines
-      case 0x44: l2 = 1024; break;   // code and data L2 cache, 1024 KB, 4 ways, 32 byte lines
-      case 0x45: l2 = 2048; break;   // code and data L2 cache, 2048 KB, 4 ways, 32 byte lines
-      case 0x46: l3 = 4096; break;   // code and data L3 cache, 4096 KB, 4 ways, 64 byte lines
-      case 0x47: l3 = 8192; break;   // code and data L3 cache, 8192 KB, 8 ways, 64 byte lines
-      case 0x48: l2 = 3072; break;   // code and data L2 cache, 3072 KB, 12 ways, 64 byte lines
-      case 0x49: if(l2!=0) l3 = 4096; else {check_for_p2_core2=true; l3 = l2 = 4096;} break;// code and data L3 cache, 4096 KB, 16 ways, 64 byte lines (P4) or L2 for core2
-      case 0x4A: l3 = 6144; break;   // code and data L3 cache, 6144 KB, 12 ways, 64 byte lines
-      case 0x4B: l3 = 8192; break;   // code and data L3 cache, 8192 KB, 16 ways, 64 byte lines
-      case 0x4C: l3 = 12288; break;   // code and data L3 cache, 12288 KB, 12 ways, 64 byte lines
-      case 0x4D: l3 = 16384; break;   // code and data L3 cache, 16384 KB, 16 ways, 64 byte lines
-      case 0x4E: l2 = 6144; break;   // code and data L2 cache, 6144 KB, 24 ways, 64 byte lines
-      case 0x78: l2 = 1024; break;   // code and data L2 cache, 1024 KB, 4 ways, 64 byte lines
-      case 0x79: l2 = 128; break;   // code and data L2 cache, 128 KB, 8 ways, 64 byte lines, dual-sectored
-      case 0x7A: l2 = 256; break;   // code and data L2 cache, 256 KB, 8 ways, 64 byte lines, dual-sectored
-      case 0x7B: l2 = 512; break;   // code and data L2 cache, 512 KB, 8 ways, 64 byte lines, dual-sectored
-      case 0x7C: l2 = 1024; break;   // code and data L2 cache, 1024 KB, 8 ways, 64 byte lines, dual-sectored
-      case 0x7D: l2 = 2048; break;   // code and data L2 cache, 2048 KB, 8 ways, 64 byte lines
-      case 0x7E: l2 = 256; break;   // code and data L2 cache, 256 KB, 8 ways, 128 byte lines, sect. (IA-64)
-      case 0x7F: l2 = 512; break;   // code and data L2 cache, 512 KB, 2 ways, 64 byte lines
-      case 0x80: l2 = 512; break;   // code and data L2 cache, 512 KB, 8 ways, 64 byte lines
-      case 0x81: l2 = 128; break;   // code and data L2 cache, 128 KB, 8 ways, 32 byte lines
-      case 0x82: l2 = 256; break;   // code and data L2 cache, 256 KB, 8 ways, 32 byte lines
-      case 0x83: l2 = 512; break;   // code and data L2 cache, 512 KB, 8 ways, 32 byte lines
-      case 0x84: l2 = 1024; break;   // code and data L2 cache, 1024 KB, 8 ways, 32 byte lines
-      case 0x85: l2 = 2048; break;   // code and data L2 cache, 2048 KB, 8 ways, 32 byte lines
-      case 0x86: l2 = 512; break;   // code and data L2 cache, 512 KB, 4 ways, 64 byte lines
-      case 0x87: l2 = 1024; break;   // code and data L2 cache, 1024 KB, 8 ways, 64 byte lines
-      case 0x88: l3 = 2048; break;   // code and data L3 cache, 2048 KB, 4 ways, 64 byte lines (IA-64)
-      case 0x89: l3 = 4096; break;   // code and data L3 cache, 4096 KB, 4 ways, 64 byte lines (IA-64)
-      case 0x8A: l3 = 8192; break;   // code and data L3 cache, 8192 KB, 4 ways, 64 byte lines (IA-64)
-      case 0x8D: l3 = 3072; break;   // code and data L3 cache, 3072 KB, 12 ways, 128 byte lines (IA-64)
-
-      default: break;
-    }
-  }
-  if(check_for_p2_core2 && l2 == l3)
-    l3 = 0;
-  l1 *= 1024;
-  l2 *= 1024;
-  l3 *= 1024;
-}
-
-inline void queryCacheSizes_intel(int& l1, int& l2, int& l3, int max_std_funcs)
-{
-  if(max_std_funcs>=4)
-    queryCacheSizes_intel_direct(l1,l2,l3);
-  else
-    queryCacheSizes_intel_codes(l1,l2,l3);
-}
-
-inline void queryCacheSizes_amd(int& l1, int& l2, int& l3)
-{
-  int abcd[4];
-  abcd[0] = abcd[1] = abcd[2] = abcd[3] = 0;
-  EIGEN_CPUID(abcd,0x80000005,0);
-  l1 = (abcd[2] >> 24) * 1024; // C[31:24] = L1 size in KB
-  abcd[0] = abcd[1] = abcd[2] = abcd[3] = 0;
-  EIGEN_CPUID(abcd,0x80000006,0);
-  l2 = (abcd[2] >> 16) * 1024; // C[31;16] = l2 cache size in KB
-  l3 = ((abcd[3] & 0xFFFC000) >> 18) * 512 * 1024; // D[31;18] = l3 cache size in 512KB
-}
-#endif
-
-/** \internal
- * Queries and returns the cache sizes in Bytes of the L1, L2, and L3 data caches respectively */
-inline void queryCacheSizes(int& l1, int& l2, int& l3)
-{
-  #ifdef EIGEN_CPUID
-  int abcd[4];
-  const int GenuineIntel[] = {0x756e6547, 0x49656e69, 0x6c65746e};
-  const int AuthenticAMD[] = {0x68747541, 0x69746e65, 0x444d4163};
-  const int AMDisbetter_[] = {0x69444d41, 0x74656273, 0x21726574}; // "AMDisbetter!"
-
-  // identify the CPU vendor
-  EIGEN_CPUID(abcd,0x0,0);
-  int max_std_funcs = abcd[1];
-  if(cpuid_is_vendor(abcd,GenuineIntel))
-    queryCacheSizes_intel(l1,l2,l3,max_std_funcs);
-  else if(cpuid_is_vendor(abcd,AuthenticAMD) || cpuid_is_vendor(abcd,AMDisbetter_))
-    queryCacheSizes_amd(l1,l2,l3);
-  else
-    // by default let's use Intel's API
-    queryCacheSizes_intel(l1,l2,l3,max_std_funcs);
-
-  // here is the list of other vendors:
-//   ||cpuid_is_vendor(abcd,"VIA VIA VIA ")
-//   ||cpuid_is_vendor(abcd,"CyrixInstead")
-//   ||cpuid_is_vendor(abcd,"CentaurHauls")
-//   ||cpuid_is_vendor(abcd,"GenuineTMx86")
-//   ||cpuid_is_vendor(abcd,"TransmetaCPU")
-//   ||cpuid_is_vendor(abcd,"RiseRiseRise")
-//   ||cpuid_is_vendor(abcd,"Geode by NSC")
-//   ||cpuid_is_vendor(abcd,"SiS SiS SiS ")
-//   ||cpuid_is_vendor(abcd,"UMC UMC UMC ")
-//   ||cpuid_is_vendor(abcd,"NexGenDriven")
-  #else
-  l1 = l2 = l3 = -1;
-  #endif
-}
-
-/** \internal
- * \returns the size in Bytes of the L1 data cache */
-inline int queryL1CacheSize()
-{
-  int l1(-1), l2, l3;
-  queryCacheSizes(l1,l2,l3);
-  return l1;
-}
-
-/** \internal
- * \returns the size in Bytes of the L2 or L3 cache if this later is present */
-inline int queryTopLevelCacheSize()
-{
-  int l1, l2(-1), l3(-1);
-  queryCacheSizes(l1,l2,l3);
-  return (std::max)(l2,l3);
-}
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_MEMORY_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/Meta.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/Meta.h
deleted file mode 100644
index d31e954..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/Meta.h
+++ /dev/null
@@ -1,534 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2015 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_META_H
-#define EIGEN_META_H
-
-#if defined(__CUDA_ARCH__)
-#include <cfloat>
-#include <math_constants.h>
-#endif
-
-#if EIGEN_COMP_ICC>=1600 &&  __cplusplus >= 201103L
-#include <cstdint>
-#endif
-
-namespace Eigen {
-
-typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE DenseIndex;
-
-/**
- * \brief The Index type as used for the API.
- * \details To change this, \c \#define the preprocessor symbol \c EIGEN_DEFAULT_DENSE_INDEX_TYPE.
- * \sa \blank \ref TopicPreprocessorDirectives, StorageIndex.
- */
-
-typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE Index;
-
-namespace internal {
-
-/** \internal
-  * \file Meta.h
-  * This file contains generic metaprogramming classes which are not specifically related to Eigen.
-  * \note In case you wonder, yes we're aware that Boost already provides all these features,
-  * we however don't want to add a dependency to Boost.
-  */
-
-// Only recent versions of ICC complain about using ptrdiff_t to hold pointers,
-// and older versions do not provide *intptr_t types.
-#if EIGEN_COMP_ICC>=1600 &&  __cplusplus >= 201103L
-typedef std::intptr_t  IntPtr;
-typedef std::uintptr_t UIntPtr;
-#else
-typedef std::ptrdiff_t IntPtr;
-typedef std::size_t UIntPtr;
-#endif
-
-struct true_type {  enum { value = 1 }; };
-struct false_type { enum { value = 0 }; };
-
-template<bool Condition, typename Then, typename Else>
-struct conditional { typedef Then type; };
-
-template<typename Then, typename Else>
-struct conditional <false, Then, Else> { typedef Else type; };
-
-template<typename T, typename U> struct is_same { enum { value = 0 }; };
-template<typename T> struct is_same<T,T> { enum { value = 1 }; };
-
-template<typename T> struct remove_reference { typedef T type; };
-template<typename T> struct remove_reference<T&> { typedef T type; };
-
-template<typename T> struct remove_pointer { typedef T type; };
-template<typename T> struct remove_pointer<T*> { typedef T type; };
-template<typename T> struct remove_pointer<T*const> { typedef T type; };
-
-template <class T> struct remove_const { typedef T type; };
-template <class T> struct remove_const<const T> { typedef T type; };
-template <class T> struct remove_const<const T[]> { typedef T type[]; };
-template <class T, unsigned int Size> struct remove_const<const T[Size]> { typedef T type[Size]; };
-
-template<typename T> struct remove_all { typedef T type; };
-template<typename T> struct remove_all<const T>   { typedef typename remove_all<T>::type type; };
-template<typename T> struct remove_all<T const&>  { typedef typename remove_all<T>::type type; };
-template<typename T> struct remove_all<T&>        { typedef typename remove_all<T>::type type; };
-template<typename T> struct remove_all<T const*>  { typedef typename remove_all<T>::type type; };
-template<typename T> struct remove_all<T*>        { typedef typename remove_all<T>::type type; };
-
-template<typename T> struct is_arithmetic      { enum { value = false }; };
-template<> struct is_arithmetic<float>         { enum { value = true }; };
-template<> struct is_arithmetic<double>        { enum { value = true }; };
-template<> struct is_arithmetic<long double>   { enum { value = true }; };
-template<> struct is_arithmetic<bool>          { enum { value = true }; };
-template<> struct is_arithmetic<char>          { enum { value = true }; };
-template<> struct is_arithmetic<signed char>   { enum { value = true }; };
-template<> struct is_arithmetic<unsigned char> { enum { value = true }; };
-template<> struct is_arithmetic<signed short>  { enum { value = true }; };
-template<> struct is_arithmetic<unsigned short>{ enum { value = true }; };
-template<> struct is_arithmetic<signed int>    { enum { value = true }; };
-template<> struct is_arithmetic<unsigned int>  { enum { value = true }; };
-template<> struct is_arithmetic<signed long>   { enum { value = true }; };
-template<> struct is_arithmetic<unsigned long> { enum { value = true }; };
-
-template<typename T> struct is_integral        { enum { value = false }; };
-template<> struct is_integral<bool>            { enum { value = true }; };
-template<> struct is_integral<char>            { enum { value = true }; };
-template<> struct is_integral<signed char>     { enum { value = true }; };
-template<> struct is_integral<unsigned char>   { enum { value = true }; };
-template<> struct is_integral<signed short>    { enum { value = true }; };
-template<> struct is_integral<unsigned short>  { enum { value = true }; };
-template<> struct is_integral<signed int>      { enum { value = true }; };
-template<> struct is_integral<unsigned int>    { enum { value = true }; };
-template<> struct is_integral<signed long>     { enum { value = true }; };
-template<> struct is_integral<unsigned long>   { enum { value = true }; };
-
-#if EIGEN_HAS_CXX11
-using std::make_unsigned;
-#else
-// TODO: Possibly improve this implementation of make_unsigned.
-// It is currently used only by
-// template<typename Scalar> struct random_default_impl<Scalar, false, true>.
-template<typename> struct make_unsigned;
-template<> struct make_unsigned<char>             { typedef unsigned char type; };
-template<> struct make_unsigned<signed char>      { typedef unsigned char type; };
-template<> struct make_unsigned<unsigned char>    { typedef unsigned char type; };
-template<> struct make_unsigned<signed short>     { typedef unsigned short type; };
-template<> struct make_unsigned<unsigned short>   { typedef unsigned short type; };
-template<> struct make_unsigned<signed int>       { typedef unsigned int type; };
-template<> struct make_unsigned<unsigned int>     { typedef unsigned int type; };
-template<> struct make_unsigned<signed long>      { typedef unsigned long type; };
-template<> struct make_unsigned<unsigned long>    { typedef unsigned long type; };
-#if EIGEN_COMP_MSVC
-template<> struct make_unsigned<signed __int64>   { typedef unsigned __int64 type; };
-template<> struct make_unsigned<unsigned __int64> { typedef unsigned __int64 type; };
-#endif
-#endif
-
-template <typename T> struct add_const { typedef const T type; };
-template <typename T> struct add_const<T&> { typedef T& type; };
-
-template <typename T> struct is_const { enum { value = 0 }; };
-template <typename T> struct is_const<T const> { enum { value = 1 }; };
-
-template<typename T> struct add_const_on_value_type            { typedef const T type;  };
-template<typename T> struct add_const_on_value_type<T&>        { typedef T const& type; };
-template<typename T> struct add_const_on_value_type<T*>        { typedef T const* type; };
-template<typename T> struct add_const_on_value_type<T* const>  { typedef T const* const type; };
-template<typename T> struct add_const_on_value_type<T const* const>  { typedef T const* const type; };
-
-
-template<typename From, typename To>
-struct is_convertible_impl
-{
-private:
-  struct any_conversion
-  {
-    template <typename T> any_conversion(const volatile T&);
-    template <typename T> any_conversion(T&);
-  };
-  struct yes {int a[1];};
-  struct no  {int a[2];};
-
-  static yes test(const To&, int);
-  static no  test(any_conversion, ...);
-
-public:
-  static From ms_from;
-#ifdef __INTEL_COMPILER
-  #pragma warning push
-  #pragma warning ( disable : 2259 )
-#endif
-  enum { value = sizeof(test(ms_from, 0))==sizeof(yes) };
-#ifdef __INTEL_COMPILER
-  #pragma warning pop
-#endif
-};
-
-template<typename From, typename To>
-struct is_convertible
-{
-  enum { value = is_convertible_impl<typename remove_all<From>::type,
-                                     typename remove_all<To  >::type>::value };
-};
-
-/** \internal Allows to enable/disable an overload
-  * according to a compile time condition.
-  */
-template<bool Condition, typename T=void> struct enable_if;
-
-template<typename T> struct enable_if<true,T>
-{ typedef T type; };
-
-#if defined(__CUDA_ARCH__)
-#if !defined(__FLT_EPSILON__)
-#define __FLT_EPSILON__ FLT_EPSILON
-#define __DBL_EPSILON__ DBL_EPSILON
-#endif
-
-namespace device {
-
-template<typename T> struct numeric_limits
-{
-  EIGEN_DEVICE_FUNC
-  static T epsilon() { return 0; }
-  static T (max)() { assert(false && "Highest not supported for this type"); }
-  static T (min)() { assert(false && "Lowest not supported for this type"); }
-  static T infinity() { assert(false && "Infinity not supported for this type"); }
-  static T quiet_NaN() { assert(false && "quiet_NaN not supported for this type"); }
-};
-template<> struct numeric_limits<float>
-{
-  EIGEN_DEVICE_FUNC
-  static float epsilon() { return __FLT_EPSILON__; }
-  EIGEN_DEVICE_FUNC
-  static float (max)() { return CUDART_MAX_NORMAL_F; }
-  EIGEN_DEVICE_FUNC
-  static float (min)() { return FLT_MIN; }
-  EIGEN_DEVICE_FUNC
-  static float infinity() { return CUDART_INF_F; }
-  EIGEN_DEVICE_FUNC
-  static float quiet_NaN() { return CUDART_NAN_F; }
-};
-template<> struct numeric_limits<double>
-{
-  EIGEN_DEVICE_FUNC
-  static double epsilon() { return __DBL_EPSILON__; }
-  EIGEN_DEVICE_FUNC
-  static double (max)() { return DBL_MAX; }
-  EIGEN_DEVICE_FUNC
-  static double (min)() { return DBL_MIN; }
-  EIGEN_DEVICE_FUNC
-  static double infinity() { return CUDART_INF; }
-  EIGEN_DEVICE_FUNC
-  static double quiet_NaN() { return CUDART_NAN; }
-};
-template<> struct numeric_limits<int>
-{
-  EIGEN_DEVICE_FUNC
-  static int epsilon() { return 0; }
-  EIGEN_DEVICE_FUNC
-  static int (max)() { return INT_MAX; }
-  EIGEN_DEVICE_FUNC
-  static int (min)() { return INT_MIN; }
-};
-template<> struct numeric_limits<unsigned int>
-{
-  EIGEN_DEVICE_FUNC
-  static unsigned int epsilon() { return 0; }
-  EIGEN_DEVICE_FUNC
-  static unsigned int (max)() { return UINT_MAX; }
-  EIGEN_DEVICE_FUNC
-  static unsigned int (min)() { return 0; }
-};
-template<> struct numeric_limits<long>
-{
-  EIGEN_DEVICE_FUNC
-  static long epsilon() { return 0; }
-  EIGEN_DEVICE_FUNC
-  static long (max)() { return LONG_MAX; }
-  EIGEN_DEVICE_FUNC
-  static long (min)() { return LONG_MIN; }
-};
-template<> struct numeric_limits<unsigned long>
-{
-  EIGEN_DEVICE_FUNC
-  static unsigned long epsilon() { return 0; }
-  EIGEN_DEVICE_FUNC
-  static unsigned long (max)() { return ULONG_MAX; }
-  EIGEN_DEVICE_FUNC
-  static unsigned long (min)() { return 0; }
-};
-template<> struct numeric_limits<long long>
-{
-  EIGEN_DEVICE_FUNC
-  static long long epsilon() { return 0; }
-  EIGEN_DEVICE_FUNC
-  static long long (max)() { return LLONG_MAX; }
-  EIGEN_DEVICE_FUNC
-  static long long (min)() { return LLONG_MIN; }
-};
-template<> struct numeric_limits<unsigned long long>
-{
-  EIGEN_DEVICE_FUNC
-  static unsigned long long epsilon() { return 0; }
-  EIGEN_DEVICE_FUNC
-  static unsigned long long (max)() { return ULLONG_MAX; }
-  EIGEN_DEVICE_FUNC
-  static unsigned long long (min)() { return 0; }
-};
-
-}
-
-#endif
-
-/** \internal
-  * A base class do disable default copy ctor and copy assignement operator.
-  */
-class noncopyable
-{
-  EIGEN_DEVICE_FUNC noncopyable(const noncopyable&);
-  EIGEN_DEVICE_FUNC const noncopyable& operator=(const noncopyable&);
-protected:
-  EIGEN_DEVICE_FUNC noncopyable() {}
-  EIGEN_DEVICE_FUNC ~noncopyable() {}
-};
-
-/** \internal
-  * Convenient struct to get the result type of a unary or binary functor.
-  *
-  * It supports both the current STL mechanism (using the result_type member) as well as
-  * upcoming next STL generation (using a templated result member).
-  * If none of these members is provided, then the type of the first argument is returned. FIXME, that behavior is a pretty bad hack.
-  */
-#if EIGEN_HAS_STD_RESULT_OF
-template<typename T> struct result_of {
-  typedef typename std::result_of<T>::type type1;
-  typedef typename remove_all<type1>::type type;
-};
-#else
-template<typename T> struct result_of { };
-
-struct has_none {int a[1];};
-struct has_std_result_type {int a[2];};
-struct has_tr1_result {int a[3];};
-
-template<typename Func, typename ArgType, int SizeOf=sizeof(has_none)>
-struct unary_result_of_select {typedef typename internal::remove_all<ArgType>::type type;};
-
-template<typename Func, typename ArgType>
-struct unary_result_of_select<Func, ArgType, sizeof(has_std_result_type)> {typedef typename Func::result_type type;};
-
-template<typename Func, typename ArgType>
-struct unary_result_of_select<Func, ArgType, sizeof(has_tr1_result)> {typedef typename Func::template result<Func(ArgType)>::type type;};
-
-template<typename Func, typename ArgType>
-struct result_of<Func(ArgType)> {
-    template<typename T>
-    static has_std_result_type    testFunctor(T const *, typename T::result_type const * = 0);
-    template<typename T>
-    static has_tr1_result         testFunctor(T const *, typename T::template result<T(ArgType)>::type const * = 0);
-    static has_none               testFunctor(...);
-
-    // note that the following indirection is needed for gcc-3.3
-    enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))};
-    typedef typename unary_result_of_select<Func, ArgType, FunctorType>::type type;
-};
-
-template<typename Func, typename ArgType0, typename ArgType1, int SizeOf=sizeof(has_none)>
-struct binary_result_of_select {typedef typename internal::remove_all<ArgType0>::type type;};
-
-template<typename Func, typename ArgType0, typename ArgType1>
-struct binary_result_of_select<Func, ArgType0, ArgType1, sizeof(has_std_result_type)>
-{typedef typename Func::result_type type;};
-
-template<typename Func, typename ArgType0, typename ArgType1>
-struct binary_result_of_select<Func, ArgType0, ArgType1, sizeof(has_tr1_result)>
-{typedef typename Func::template result<Func(ArgType0,ArgType1)>::type type;};
-
-template<typename Func, typename ArgType0, typename ArgType1>
-struct result_of<Func(ArgType0,ArgType1)> {
-    template<typename T>
-    static has_std_result_type    testFunctor(T const *, typename T::result_type const * = 0);
-    template<typename T>
-    static has_tr1_result         testFunctor(T const *, typename T::template result<T(ArgType0,ArgType1)>::type const * = 0);
-    static has_none               testFunctor(...);
-
-    // note that the following indirection is needed for gcc-3.3
-    enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))};
-    typedef typename binary_result_of_select<Func, ArgType0, ArgType1, FunctorType>::type type;
-};
-
-template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2, int SizeOf=sizeof(has_none)>
-struct ternary_result_of_select {typedef typename internal::remove_all<ArgType0>::type type;};
-
-template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2>
-struct ternary_result_of_select<Func, ArgType0, ArgType1, ArgType2, sizeof(has_std_result_type)>
-{typedef typename Func::result_type type;};
-
-template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2>
-struct ternary_result_of_select<Func, ArgType0, ArgType1, ArgType2, sizeof(has_tr1_result)>
-{typedef typename Func::template result<Func(ArgType0,ArgType1,ArgType2)>::type type;};
-
-template<typename Func, typename ArgType0, typename ArgType1, typename ArgType2>
-struct result_of<Func(ArgType0,ArgType1,ArgType2)> {
-    template<typename T>
-    static has_std_result_type    testFunctor(T const *, typename T::result_type const * = 0);
-    template<typename T>
-    static has_tr1_result         testFunctor(T const *, typename T::template result<T(ArgType0,ArgType1,ArgType2)>::type const * = 0);
-    static has_none               testFunctor(...);
-
-    // note that the following indirection is needed for gcc-3.3
-    enum {FunctorType = sizeof(testFunctor(static_cast<Func*>(0)))};
-    typedef typename ternary_result_of_select<Func, ArgType0, ArgType1, ArgType2, FunctorType>::type type;
-};
-#endif
-
-struct meta_yes { char a[1]; };
-struct meta_no  { char a[2]; };
-
-// Check whether T::ReturnType does exist
-template <typename T>
-struct has_ReturnType
-{
-  template <typename C> static meta_yes testFunctor(typename C::ReturnType const *);
-  template <typename C> static meta_no testFunctor(...);
-
-  enum { value = sizeof(testFunctor<T>(0)) == sizeof(meta_yes) };
-};
-
-template<typename T> const T* return_ptr();
-
-template <typename T, typename IndexType=Index>
-struct has_nullary_operator
-{
-  template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()())>0)>::type * = 0);
-  static meta_no testFunctor(...);
-
-  enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
-};
-
-template <typename T, typename IndexType=Index>
-struct has_unary_operator
-{
-  template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()(IndexType(0)))>0)>::type * = 0);
-  static meta_no testFunctor(...);
-
-  enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
-};
-
-template <typename T, typename IndexType=Index>
-struct has_binary_operator
-{
-  template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()(IndexType(0),IndexType(0)))>0)>::type * = 0);
-  static meta_no testFunctor(...);
-
-  enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
-};
-
-/** \internal In short, it computes int(sqrt(\a Y)) with \a Y an integer.
-  * Usage example: \code meta_sqrt<1023>::ret \endcode
-  */
-template<int Y,
-         int InfX = 0,
-         int SupX = ((Y==1) ? 1 : Y/2),
-         bool Done = ((SupX-InfX)<=1 ? true : ((SupX*SupX <= Y) && ((SupX+1)*(SupX+1) > Y))) >
-                                // use ?: instead of || just to shut up a stupid gcc 4.3 warning
-class meta_sqrt
-{
-    enum {
-      MidX = (InfX+SupX)/2,
-      TakeInf = MidX*MidX > Y ? 1 : 0,
-      NewInf = int(TakeInf) ? InfX : int(MidX),
-      NewSup = int(TakeInf) ? int(MidX) : SupX
-    };
-  public:
-    enum { ret = meta_sqrt<Y,NewInf,NewSup>::ret };
-};
-
-template<int Y, int InfX, int SupX>
-class meta_sqrt<Y, InfX, SupX, true> { public:  enum { ret = (SupX*SupX <= Y) ? SupX : InfX }; };
-
-
-/** \internal Computes the least common multiple of two positive integer A and B
-  * at compile-time. It implements a naive algorithm testing all multiples of A.
-  * It thus works better if A>=B.
-  */
-template<int A, int B, int K=1, bool Done = ((A*K)%B)==0>
-struct meta_least_common_multiple
-{
-  enum { ret = meta_least_common_multiple<A,B,K+1>::ret };
-};
-template<int A, int B, int K>
-struct meta_least_common_multiple<A,B,K,true>
-{
-  enum { ret = A*K };
-};
-
-/** \internal determines whether the product of two numeric types is allowed and what the return type is */
-template<typename T, typename U> struct scalar_product_traits
-{
-  enum { Defined = 0 };
-};
-
-// FIXME quick workaround around current limitation of result_of
-// template<typename Scalar, typename ArgType0, typename ArgType1>
-// struct result_of<scalar_product_op<Scalar>(ArgType0,ArgType1)> {
-// typedef typename scalar_product_traits<typename remove_all<ArgType0>::type, typename remove_all<ArgType1>::type>::ReturnType type;
-// };
-
-} // end namespace internal
-
-namespace numext {
-  
-#if defined(__CUDA_ARCH__)
-template<typename T> EIGEN_DEVICE_FUNC   void swap(T &a, T &b) { T tmp = b; b = a; a = tmp; }
-#else
-template<typename T> EIGEN_STRONG_INLINE void swap(T &a, T &b) { std::swap(a,b); }
-#endif
-
-#if defined(__CUDA_ARCH__)
-using internal::device::numeric_limits;
-#else
-using std::numeric_limits;
-#endif
-
-// Integer division with rounding up.
-// T is assumed to be an integer type with a>=0, and b>0
-template<typename T>
-T div_ceil(const T &a, const T &b)
-{
-  return (a+b-1) / b;
-}
-
-// The aim of the following functions is to bypass -Wfloat-equal warnings
-// when we really want a strict equality comparison on floating points.
-template<typename X, typename Y> EIGEN_STRONG_INLINE
-bool equal_strict(const X& x,const Y& y) { return x == y; }
-
-template<> EIGEN_STRONG_INLINE
-bool equal_strict(const float& x,const float& y) { return std::equal_to<float>()(x,y); }
-
-template<> EIGEN_STRONG_INLINE
-bool equal_strict(const double& x,const double& y) { return std::equal_to<double>()(x,y); }
-
-template<typename X, typename Y> EIGEN_STRONG_INLINE
-bool not_equal_strict(const X& x,const Y& y) { return x != y; }
-
-template<> EIGEN_STRONG_INLINE
-bool not_equal_strict(const float& x,const float& y) { return std::not_equal_to<float>()(x,y); }
-
-template<> EIGEN_STRONG_INLINE
-bool not_equal_strict(const double& x,const double& y) { return std::not_equal_to<double>()(x,y); }
-
-} // end namespace numext
-
-} // end namespace Eigen
-
-#endif // EIGEN_META_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/ReenableStupidWarnings.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/ReenableStupidWarnings.h
deleted file mode 100644
index ecc82b7..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/ReenableStupidWarnings.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifdef EIGEN_WARNINGS_DISABLED
-#undef EIGEN_WARNINGS_DISABLED
-
-#ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS
-  #ifdef _MSC_VER
-    #pragma warning( pop )
-  #elif defined __INTEL_COMPILER
-    #pragma warning pop
-  #elif defined __clang__
-    #pragma clang diagnostic pop
-  #elif defined __GNUC__  &&  (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
-    #pragma GCC diagnostic pop
-  #endif
-
-  #if defined __NVCC__
-//    Don't reenable the diagnostic messages, as it turns out these messages need
-//    to be disabled at the point of the template instantiation (i.e the user code)
-//    otherwise they'll be triggered by nvcc.
-//    #pragma diag_default code_is_unreachable
-//    #pragma diag_default initialization_not_reachable
-//    #pragma diag_default 2651
-//    #pragma diag_default 2653
-  #endif
-
-#endif
-
-#endif // EIGEN_WARNINGS_DISABLED
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/StaticAssert.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/StaticAssert.h
deleted file mode 100644
index 500e477..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/StaticAssert.h
+++ /dev/null
@@ -1,218 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_STATIC_ASSERT_H
-#define EIGEN_STATIC_ASSERT_H
-
-/* Some notes on Eigen's static assertion mechanism:
- *
- *  - in EIGEN_STATIC_ASSERT(CONDITION,MSG) the parameter CONDITION must be a compile time boolean
- *    expression, and MSG an enum listed in struct internal::static_assertion<true>
- *
- *  - define EIGEN_NO_STATIC_ASSERT to disable them (and save compilation time)
- *    in that case, the static assertion is converted to the following runtime assert:
- *      eigen_assert(CONDITION && "MSG")
- *
- *  - currently EIGEN_STATIC_ASSERT can only be used in function scope
- *
- */
-
-#ifndef EIGEN_STATIC_ASSERT
-#ifndef EIGEN_NO_STATIC_ASSERT
-
-  #if EIGEN_MAX_CPP_VER>=11 && (__has_feature(cxx_static_assert) || (defined(__cplusplus) && __cplusplus >= 201103L) || (EIGEN_COMP_MSVC >= 1600))
-
-    // if native static_assert is enabled, let's use it
-    #define EIGEN_STATIC_ASSERT(X,MSG) static_assert(X,#MSG);
-
-  #else // not CXX0X
-
-    namespace Eigen {
-
-    namespace internal {
-
-    template<bool condition>
-    struct static_assertion {};
-
-    template<>
-    struct static_assertion<true>
-    {
-      enum {
-        YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX=1,
-        YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES=1,
-        YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES=1,
-        THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE=1,
-        THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE=1,
-        THIS_METHOD_IS_ONLY_FOR_OBJECTS_OF_A_SPECIFIC_SIZE=1,
-        OUT_OF_RANGE_ACCESS=1,
-        YOU_MADE_A_PROGRAMMING_MISTAKE=1,
-        EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT=1,
-        EIGEN_INTERNAL_COMPILATION_ERROR_OR_YOU_MADE_A_PROGRAMMING_MISTAKE=1,
-        YOU_CALLED_A_FIXED_SIZE_METHOD_ON_A_DYNAMIC_SIZE_MATRIX_OR_VECTOR=1,
-        YOU_CALLED_A_DYNAMIC_SIZE_METHOD_ON_A_FIXED_SIZE_MATRIX_OR_VECTOR=1,
-        UNALIGNED_LOAD_AND_STORE_OPERATIONS_UNIMPLEMENTED_ON_ALTIVEC=1,
-        THIS_FUNCTION_IS_NOT_FOR_INTEGER_NUMERIC_TYPES=1,
-        FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED=1,
-        NUMERIC_TYPE_MUST_BE_REAL=1,
-        COEFFICIENT_WRITE_ACCESS_TO_SELFADJOINT_NOT_SUPPORTED=1,
-        WRITING_TO_TRIANGULAR_PART_WITH_UNIT_DIAGONAL_IS_NOT_SUPPORTED=1,
-        THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE=1,
-        INVALID_MATRIX_PRODUCT=1,
-        INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS=1,
-        INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION=1,
-        YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY=1,
-        THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES=1,
-        THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES=1,
-        INVALID_MATRIX_TEMPLATE_PARAMETERS=1,
-        INVALID_MATRIXBASE_TEMPLATE_PARAMETERS=1,
-        BOTH_MATRICES_MUST_HAVE_THE_SAME_STORAGE_ORDER=1,
-        THIS_METHOD_IS_ONLY_FOR_DIAGONAL_MATRIX=1,
-        THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE=1,
-        THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_WITH_DIRECT_MEMORY_ACCESS_SUCH_AS_MAP_OR_PLAIN_MATRICES=1,
-        YOU_ALREADY_SPECIFIED_THIS_STRIDE=1,
-        INVALID_STORAGE_ORDER_FOR_THIS_VECTOR_EXPRESSION=1,
-        THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD=1,
-        PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1=1,
-        THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS=1,
-        YOU_CANNOT_MIX_ARRAYS_AND_MATRICES=1,
-        YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION=1,
-        THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY=1,
-        YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT=1,
-        THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS=1,
-        THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS=1,
-        THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL=1,
-        THIS_METHOD_IS_ONLY_FOR_ARRAYS_NOT_MATRICES=1,
-        YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED=1,
-        YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED=1,
-        THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE=1,
-        THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH=1,
-        OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG=1,
-        IMPLICIT_CONVERSION_TO_SCALAR_IS_FOR_INNER_PRODUCT_ONLY=1,
-        STORAGE_LAYOUT_DOES_NOT_MATCH=1,
-        EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT__INVALID_COST_VALUE=1,
-        THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS=1,
-        MATRIX_FREE_CONJUGATE_GRADIENT_IS_COMPATIBLE_WITH_UPPER_UNION_LOWER_MODE_ONLY=1,
-        THIS_TYPE_IS_NOT_SUPPORTED=1,
-        STORAGE_KIND_MUST_MATCH=1,
-        STORAGE_INDEX_MUST_MATCH=1,
-        CHOLMOD_SUPPORTS_DOUBLE_PRECISION_ONLY=1,
-        SELFADJOINTVIEW_ACCEPTS_UPPER_AND_LOWER_MODE_ONLY=1
-      };
-    };
-
-    } // end namespace internal
-
-    } // end namespace Eigen
-
-    // Specialized implementation for MSVC to avoid "conditional
-    // expression is constant" warnings.  This implementation doesn't
-    // appear to work under GCC, hence the multiple implementations.
-    #if EIGEN_COMP_MSVC
-
-      #define EIGEN_STATIC_ASSERT(CONDITION,MSG) \
-        {Eigen::internal::static_assertion<bool(CONDITION)>::MSG;}
-
-    #else
-      // In some cases clang interprets bool(CONDITION) as function declaration
-      #define EIGEN_STATIC_ASSERT(CONDITION,MSG) \
-        if (Eigen::internal::static_assertion<static_cast<bool>(CONDITION)>::MSG) {}
-
-    #endif
-
-  #endif // not CXX0X
-
-#else // EIGEN_NO_STATIC_ASSERT
-
-  #define EIGEN_STATIC_ASSERT(CONDITION,MSG) eigen_assert((CONDITION) && #MSG);
-
-#endif // EIGEN_NO_STATIC_ASSERT
-#endif // EIGEN_STATIC_ASSERT
-
-// static assertion failing if the type \a TYPE is not a vector type
-#define EIGEN_STATIC_ASSERT_VECTOR_ONLY(TYPE) \
-  EIGEN_STATIC_ASSERT(TYPE::IsVectorAtCompileTime, \
-                      YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX)
-
-// static assertion failing if the type \a TYPE is not fixed-size
-#define EIGEN_STATIC_ASSERT_FIXED_SIZE(TYPE) \
-  EIGEN_STATIC_ASSERT(TYPE::SizeAtCompileTime!=Eigen::Dynamic, \
-                      YOU_CALLED_A_FIXED_SIZE_METHOD_ON_A_DYNAMIC_SIZE_MATRIX_OR_VECTOR)
-
-// static assertion failing if the type \a TYPE is not dynamic-size
-#define EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(TYPE) \
-  EIGEN_STATIC_ASSERT(TYPE::SizeAtCompileTime==Eigen::Dynamic, \
-                      YOU_CALLED_A_DYNAMIC_SIZE_METHOD_ON_A_FIXED_SIZE_MATRIX_OR_VECTOR)
-
-// static assertion failing if the type \a TYPE is not a vector type of the given size
-#define EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(TYPE, SIZE) \
-  EIGEN_STATIC_ASSERT(TYPE::IsVectorAtCompileTime && TYPE::SizeAtCompileTime==SIZE, \
-                      THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE)
-
-// static assertion failing if the type \a TYPE is not a vector type of the given size
-#define EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(TYPE, ROWS, COLS) \
-  EIGEN_STATIC_ASSERT(TYPE::RowsAtCompileTime==ROWS && TYPE::ColsAtCompileTime==COLS, \
-                      THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE)
-
-// static assertion failing if the two vector expression types are not compatible (same fixed-size or dynamic size)
-#define EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(TYPE0,TYPE1) \
-  EIGEN_STATIC_ASSERT( \
-      (int(TYPE0::SizeAtCompileTime)==Eigen::Dynamic \
-    || int(TYPE1::SizeAtCompileTime)==Eigen::Dynamic \
-    || int(TYPE0::SizeAtCompileTime)==int(TYPE1::SizeAtCompileTime)),\
-    YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES)
-
-#define EIGEN_PREDICATE_SAME_MATRIX_SIZE(TYPE0,TYPE1) \
-     ( \
-        (int(Eigen::internal::size_of_xpr_at_compile_time<TYPE0>::ret)==0 && int(Eigen::internal::size_of_xpr_at_compile_time<TYPE1>::ret)==0) \
-    || (\
-          (int(TYPE0::RowsAtCompileTime)==Eigen::Dynamic \
-        || int(TYPE1::RowsAtCompileTime)==Eigen::Dynamic \
-        || int(TYPE0::RowsAtCompileTime)==int(TYPE1::RowsAtCompileTime)) \
-      &&  (int(TYPE0::ColsAtCompileTime)==Eigen::Dynamic \
-        || int(TYPE1::ColsAtCompileTime)==Eigen::Dynamic \
-        || int(TYPE0::ColsAtCompileTime)==int(TYPE1::ColsAtCompileTime))\
-       ) \
-     )
-
-#define EIGEN_STATIC_ASSERT_NON_INTEGER(TYPE) \
-    EIGEN_STATIC_ASSERT(!NumTraits<TYPE>::IsInteger, THIS_FUNCTION_IS_NOT_FOR_INTEGER_NUMERIC_TYPES)
-
-
-// static assertion failing if it is guaranteed at compile-time that the two matrix expression types have different sizes
-#define EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(TYPE0,TYPE1) \
-  EIGEN_STATIC_ASSERT( \
-     EIGEN_PREDICATE_SAME_MATRIX_SIZE(TYPE0,TYPE1),\
-    YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES)
-
-#define EIGEN_STATIC_ASSERT_SIZE_1x1(TYPE) \
-      EIGEN_STATIC_ASSERT((TYPE::RowsAtCompileTime == 1 || TYPE::RowsAtCompileTime == Dynamic) && \
-                          (TYPE::ColsAtCompileTime == 1 || TYPE::ColsAtCompileTime == Dynamic), \
-                          THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS)
-
-#define EIGEN_STATIC_ASSERT_LVALUE(Derived) \
-      EIGEN_STATIC_ASSERT(Eigen::internal::is_lvalue<Derived>::value, \
-                          THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY)
-
-#define EIGEN_STATIC_ASSERT_ARRAYXPR(Derived) \
-      EIGEN_STATIC_ASSERT((Eigen::internal::is_same<typename Eigen::internal::traits<Derived>::XprKind, ArrayXpr>::value), \
-                          THIS_METHOD_IS_ONLY_FOR_ARRAYS_NOT_MATRICES)
-
-#define EIGEN_STATIC_ASSERT_SAME_XPR_KIND(Derived1, Derived2) \
-      EIGEN_STATIC_ASSERT((Eigen::internal::is_same<typename Eigen::internal::traits<Derived1>::XprKind, \
-                                             typename Eigen::internal::traits<Derived2>::XprKind \
-                                            >::value), \
-                          YOU_CANNOT_MIX_ARRAYS_AND_MATRICES)
-
-// Check that a cost value is positive, and that is stay within a reasonable range
-// TODO this check could be enabled for internal debugging only
-#define EIGEN_INTERNAL_CHECK_COST_VALUE(C) \
-      EIGEN_STATIC_ASSERT((C)>=0 && (C)<=HugeCost*HugeCost, EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT__INVALID_COST_VALUE);
-
-#endif // EIGEN_STATIC_ASSERT_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/XprHelper.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/XprHelper.h
deleted file mode 100644
index ba5bd18..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Core/util/XprHelper.h
+++ /dev/null
@@ -1,821 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_XPRHELPER_H
-#define EIGEN_XPRHELPER_H
-
-// just a workaround because GCC seems to not really like empty structs
-// FIXME: gcc 4.3 generates bad code when strict-aliasing is enabled
-// so currently we simply disable this optimization for gcc 4.3
-#if EIGEN_COMP_GNUC && !EIGEN_GNUC_AT(4,3)
-  #define EIGEN_EMPTY_STRUCT_CTOR(X) \
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE X() {} \
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE X(const X& ) {}
-#else
-  #define EIGEN_EMPTY_STRUCT_CTOR(X)
-#endif
-
-namespace Eigen {
-
-namespace internal {
-
-template<typename IndexDest, typename IndexSrc>
-EIGEN_DEVICE_FUNC
-inline IndexDest convert_index(const IndexSrc& idx) {
-  // for sizeof(IndexDest)>=sizeof(IndexSrc) compilers should be able to optimize this away:
-  eigen_internal_assert(idx <= NumTraits<IndexDest>::highest() && "Index value to big for target type");
-  return IndexDest(idx);
-}
-
-
-// promote_scalar_arg is an helper used in operation between an expression and a scalar, like:
-//    expression * scalar
-// Its role is to determine how the type T of the scalar operand should be promoted given the scalar type ExprScalar of the given expression.
-// The IsSupported template parameter must be provided by the caller as: internal::has_ReturnType<ScalarBinaryOpTraits<ExprScalar,T,op> >::value using the proper order for ExprScalar and T.
-// Then the logic is as follows:
-//  - if the operation is natively supported as defined by IsSupported, then the scalar type is not promoted, and T is returned.
-//  - otherwise, NumTraits<ExprScalar>::Literal is returned if T is implicitly convertible to NumTraits<ExprScalar>::Literal AND that this does not imply a float to integer conversion.
-//  - otherwise, ExprScalar is returned if T is implicitly convertible to ExprScalar AND that this does not imply a float to integer conversion.
-//  - In all other cases, the promoted type is not defined, and the respective operation is thus invalid and not available (SFINAE).
-template<typename ExprScalar,typename T, bool IsSupported>
-struct promote_scalar_arg;
-
-template<typename S,typename T>
-struct promote_scalar_arg<S,T,true>
-{
-  typedef T type;
-};
-
-// Recursively check safe conversion to PromotedType, and then ExprScalar if they are different.
-template<typename ExprScalar,typename T,typename PromotedType,
-  bool ConvertibleToLiteral = internal::is_convertible<T,PromotedType>::value,
-  bool IsSafe = NumTraits<T>::IsInteger || !NumTraits<PromotedType>::IsInteger>
-struct promote_scalar_arg_unsupported;
-
-// Start recursion with NumTraits<ExprScalar>::Literal
-template<typename S,typename T>
-struct promote_scalar_arg<S,T,false> : promote_scalar_arg_unsupported<S,T,typename NumTraits<S>::Literal> {};
-
-// We found a match!
-template<typename S,typename T, typename PromotedType>
-struct promote_scalar_arg_unsupported<S,T,PromotedType,true,true>
-{
-  typedef PromotedType type;
-};
-
-// No match, but no real-to-integer issues, and ExprScalar and current PromotedType are different,
-// so let's try to promote to ExprScalar
-template<typename ExprScalar,typename T, typename PromotedType>
-struct promote_scalar_arg_unsupported<ExprScalar,T,PromotedType,false,true>
-   : promote_scalar_arg_unsupported<ExprScalar,T,ExprScalar>
-{};
-
-// Unsafe real-to-integer, let's stop.
-template<typename S,typename T, typename PromotedType, bool ConvertibleToLiteral>
-struct promote_scalar_arg_unsupported<S,T,PromotedType,ConvertibleToLiteral,false> {};
-
-// T is not even convertible to ExprScalar, let's stop.
-template<typename S,typename T>
-struct promote_scalar_arg_unsupported<S,T,S,false,true> {};
-
-//classes inheriting no_assignment_operator don't generate a default operator=.
-class no_assignment_operator
-{
-  private:
-    no_assignment_operator& operator=(const no_assignment_operator&);
-};
-
-/** \internal return the index type with the largest number of bits */
-template<typename I1, typename I2>
-struct promote_index_type
-{
-  typedef typename conditional<(sizeof(I1)<sizeof(I2)), I2, I1>::type type;
-};
-
-/** \internal If the template parameter Value is Dynamic, this class is just a wrapper around a T variable that
-  * can be accessed using value() and setValue().
-  * Otherwise, this class is an empty structure and value() just returns the template parameter Value.
-  */
-template<typename T, int Value> class variable_if_dynamic
-{
-  public:
-    EIGEN_EMPTY_STRUCT_CTOR(variable_if_dynamic)
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamic(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); eigen_assert(v == T(Value)); }
-    EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T value() { return T(Value); }
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T) {}
-};
-
-template<typename T> class variable_if_dynamic<T, Dynamic>
-{
-    T m_value;
-    EIGEN_DEVICE_FUNC variable_if_dynamic() { eigen_assert(false); }
-  public:
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamic(T value) : m_value(value) {}
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T value() const { return m_value; }
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T value) { m_value = value; }
-};
-
-/** \internal like variable_if_dynamic but for DynamicIndex
-  */
-template<typename T, int Value> class variable_if_dynamicindex
-{
-  public:
-    EIGEN_EMPTY_STRUCT_CTOR(variable_if_dynamicindex)
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamicindex(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); eigen_assert(v == T(Value)); }
-    EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T value() { return T(Value); }
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T) {}
-};
-
-template<typename T> class variable_if_dynamicindex<T, DynamicIndex>
-{
-    T m_value;
-    EIGEN_DEVICE_FUNC variable_if_dynamicindex() { eigen_assert(false); }
-  public:
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamicindex(T value) : m_value(value) {}
-    EIGEN_DEVICE_FUNC T EIGEN_STRONG_INLINE value() const { return m_value; }
-    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T value) { m_value = value; }
-};
-
-template<typename T> struct functor_traits
-{
-  enum
-  {
-    Cost = 10,
-    PacketAccess = false,
-    IsRepeatable = false
-  };
-};
-
-template<typename T> struct packet_traits;
-
-template<typename T> struct unpacket_traits
-{
-  typedef T type;
-  typedef T half;
-  enum
-  {
-    size = 1,
-    alignment = 1
-  };
-};
-
-template<int Size, typename PacketType,
-         bool Stop = Size==Dynamic || (Size%unpacket_traits<PacketType>::size)==0 || is_same<PacketType,typename unpacket_traits<PacketType>::half>::value>
-struct find_best_packet_helper;
-
-template< int Size, typename PacketType>
-struct find_best_packet_helper<Size,PacketType,true>
-{
-  typedef PacketType type;
-};
-
-template<int Size, typename PacketType>
-struct find_best_packet_helper<Size,PacketType,false>
-{
-  typedef typename find_best_packet_helper<Size,typename unpacket_traits<PacketType>::half>::type type;
-};
-
-template<typename T, int Size>
-struct find_best_packet
-{
-  typedef typename find_best_packet_helper<Size,typename packet_traits<T>::type>::type type;
-};
-
-#if EIGEN_MAX_STATIC_ALIGN_BYTES>0
-template<int ArrayBytes, int AlignmentBytes,
-         bool Match     =  bool((ArrayBytes%AlignmentBytes)==0),
-         bool TryHalf   =  bool(EIGEN_MIN_ALIGN_BYTES<AlignmentBytes) >
-struct compute_default_alignment_helper
-{
-  enum { value = 0 };
-};
-
-template<int ArrayBytes, int AlignmentBytes, bool TryHalf>
-struct compute_default_alignment_helper<ArrayBytes, AlignmentBytes, true, TryHalf> // Match
-{
-  enum { value = AlignmentBytes };
-};
-
-template<int ArrayBytes, int AlignmentBytes>
-struct compute_default_alignment_helper<ArrayBytes, AlignmentBytes, false, true> // Try-half
-{
-  // current packet too large, try with an half-packet
-  enum { value = compute_default_alignment_helper<ArrayBytes, AlignmentBytes/2>::value };
-};
-#else
-// If static alignment is disabled, no need to bother.
-// This also avoids a division by zero in "bool Match =  bool((ArrayBytes%AlignmentBytes)==0)"
-template<int ArrayBytes, int AlignmentBytes>
-struct compute_default_alignment_helper
-{
-  enum { value = 0 };
-};
-#endif
-
-template<typename T, int Size> struct compute_default_alignment {
-  enum { value = compute_default_alignment_helper<Size*sizeof(T),EIGEN_MAX_STATIC_ALIGN_BYTES>::value };
-};
-
-template<typename T> struct compute_default_alignment<T,Dynamic> {
-  enum { value = EIGEN_MAX_ALIGN_BYTES };
-};
-
-template<typename _Scalar, int _Rows, int _Cols,
-         int _Options = AutoAlign |
-                          ( (_Rows==1 && _Cols!=1) ? RowMajor
-                          : (_Cols==1 && _Rows!=1) ? ColMajor
-                          : EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION ),
-         int _MaxRows = _Rows,
-         int _MaxCols = _Cols
-> class make_proper_matrix_type
-{
-    enum {
-      IsColVector = _Cols==1 && _Rows!=1,
-      IsRowVector = _Rows==1 && _Cols!=1,
-      Options = IsColVector ? (_Options | ColMajor) & ~RowMajor
-              : IsRowVector ? (_Options | RowMajor) & ~ColMajor
-              : _Options
-    };
-  public:
-    typedef Matrix<_Scalar, _Rows, _Cols, Options, _MaxRows, _MaxCols> type;
-};
-
-template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
-class compute_matrix_flags
-{
-    enum { row_major_bit = Options&RowMajor ? RowMajorBit : 0 };
-  public:
-    // FIXME currently we still have to handle DirectAccessBit at the expression level to handle DenseCoeffsBase<>
-    // and then propagate this information to the evaluator's flags.
-    // However, I (Gael) think that DirectAccessBit should only matter at the evaluation stage.
-    enum { ret = DirectAccessBit | LvalueBit | NestByRefBit | row_major_bit };
-};
-
-template<int _Rows, int _Cols> struct size_at_compile_time
-{
-  enum { ret = (_Rows==Dynamic || _Cols==Dynamic) ? Dynamic : _Rows * _Cols };
-};
-
-template<typename XprType> struct size_of_xpr_at_compile_time
-{
-  enum { ret = size_at_compile_time<traits<XprType>::RowsAtCompileTime,traits<XprType>::ColsAtCompileTime>::ret };
-};
-
-/* plain_matrix_type : the difference from eval is that plain_matrix_type is always a plain matrix type,
- * whereas eval is a const reference in the case of a matrix
- */
-
-template<typename T, typename StorageKind = typename traits<T>::StorageKind> struct plain_matrix_type;
-template<typename T, typename BaseClassType, int Flags> struct plain_matrix_type_dense;
-template<typename T> struct plain_matrix_type<T,Dense>
-{
-  typedef typename plain_matrix_type_dense<T,typename traits<T>::XprKind, traits<T>::Flags>::type type;
-};
-template<typename T> struct plain_matrix_type<T,DiagonalShape>
-{
-  typedef typename T::PlainObject type;
-};
-
-template<typename T, int Flags> struct plain_matrix_type_dense<T,MatrixXpr,Flags>
-{
-  typedef Matrix<typename traits<T>::Scalar,
-                traits<T>::RowsAtCompileTime,
-                traits<T>::ColsAtCompileTime,
-                AutoAlign | (Flags&RowMajorBit ? RowMajor : ColMajor),
-                traits<T>::MaxRowsAtCompileTime,
-                traits<T>::MaxColsAtCompileTime
-          > type;
-};
-
-template<typename T, int Flags> struct plain_matrix_type_dense<T,ArrayXpr,Flags>
-{
-  typedef Array<typename traits<T>::Scalar,
-                traits<T>::RowsAtCompileTime,
-                traits<T>::ColsAtCompileTime,
-                AutoAlign | (Flags&RowMajorBit ? RowMajor : ColMajor),
-                traits<T>::MaxRowsAtCompileTime,
-                traits<T>::MaxColsAtCompileTime
-          > type;
-};
-
-/* eval : the return type of eval(). For matrices, this is just a const reference
- * in order to avoid a useless copy
- */
-
-template<typename T, typename StorageKind = typename traits<T>::StorageKind> struct eval;
-
-template<typename T> struct eval<T,Dense>
-{
-  typedef typename plain_matrix_type<T>::type type;
-//   typedef typename T::PlainObject type;
-//   typedef T::Matrix<typename traits<T>::Scalar,
-//                 traits<T>::RowsAtCompileTime,
-//                 traits<T>::ColsAtCompileTime,
-//                 AutoAlign | (traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor),
-//                 traits<T>::MaxRowsAtCompileTime,
-//                 traits<T>::MaxColsAtCompileTime
-//           > type;
-};
-
-template<typename T> struct eval<T,DiagonalShape>
-{
-  typedef typename plain_matrix_type<T>::type type;
-};
-
-// for matrices, no need to evaluate, just use a const reference to avoid a useless copy
-template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
-struct eval<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Dense>
-{
-  typedef const Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& type;
-};
-
-template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
-struct eval<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Dense>
-{
-  typedef const Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& type;
-};
-
-
-/* similar to plain_matrix_type, but using the evaluator's Flags */
-template<typename T, typename StorageKind = typename traits<T>::StorageKind> struct plain_object_eval;
-
-template<typename T>
-struct plain_object_eval<T,Dense>
-{
-  typedef typename plain_matrix_type_dense<T,typename traits<T>::XprKind, evaluator<T>::Flags>::type type;
-};
-
-
-/* plain_matrix_type_column_major : same as plain_matrix_type but guaranteed to be column-major
- */
-template<typename T> struct plain_matrix_type_column_major
-{
-  enum { Rows = traits<T>::RowsAtCompileTime,
-         Cols = traits<T>::ColsAtCompileTime,
-         MaxRows = traits<T>::MaxRowsAtCompileTime,
-         MaxCols = traits<T>::MaxColsAtCompileTime
-  };
-  typedef Matrix<typename traits<T>::Scalar,
-                Rows,
-                Cols,
-                (MaxRows==1&&MaxCols!=1) ? RowMajor : ColMajor,
-                MaxRows,
-                MaxCols
-          > type;
-};
-
-/* plain_matrix_type_row_major : same as plain_matrix_type but guaranteed to be row-major
- */
-template<typename T> struct plain_matrix_type_row_major
-{
-  enum { Rows = traits<T>::RowsAtCompileTime,
-         Cols = traits<T>::ColsAtCompileTime,
-         MaxRows = traits<T>::MaxRowsAtCompileTime,
-         MaxCols = traits<T>::MaxColsAtCompileTime
-  };
-  typedef Matrix<typename traits<T>::Scalar,
-                Rows,
-                Cols,
-                (MaxCols==1&&MaxRows!=1) ? RowMajor : ColMajor,
-                MaxRows,
-                MaxCols
-          > type;
-};
-
-/** \internal The reference selector for template expressions. The idea is that we don't
-  * need to use references for expressions since they are light weight proxy
-  * objects which should generate no copying overhead. */
-template <typename T>
-struct ref_selector
-{
-  typedef typename conditional<
-    bool(traits<T>::Flags & NestByRefBit),
-    T const&,
-    const T
-  >::type type;
-  
-  typedef typename conditional<
-    bool(traits<T>::Flags & NestByRefBit),
-    T &,
-    T
-  >::type non_const_type;
-};
-
-/** \internal Adds the const qualifier on the value-type of T2 if and only if T1 is a const type */
-template<typename T1, typename T2>
-struct transfer_constness
-{
-  typedef typename conditional<
-    bool(internal::is_const<T1>::value),
-    typename internal::add_const_on_value_type<T2>::type,
-    T2
-  >::type type;
-};
-
-
-// However, we still need a mechanism to detect whether an expression which is evaluated multiple time
-// has to be evaluated into a temporary.
-// That's the purpose of this new nested_eval helper:
-/** \internal Determines how a given expression should be nested when evaluated multiple times.
-  * For example, when you do a * (b+c), Eigen will determine how the expression b+c should be
-  * evaluated into the bigger product expression. The choice is between nesting the expression b+c as-is, or
-  * evaluating that expression b+c into a temporary variable d, and nest d so that the resulting expression is
-  * a*d. Evaluating can be beneficial for example if every coefficient access in the resulting expression causes
-  * many coefficient accesses in the nested expressions -- as is the case with matrix product for example.
-  *
-  * \tparam T the type of the expression being nested.
-  * \tparam n the number of coefficient accesses in the nested expression for each coefficient access in the bigger expression.
-  * \tparam PlainObject the type of the temporary if needed.
-  */
-template<typename T, int n, typename PlainObject = typename plain_object_eval<T>::type> struct nested_eval
-{
-  enum {
-    ScalarReadCost = NumTraits<typename traits<T>::Scalar>::ReadCost,
-    CoeffReadCost = evaluator<T>::CoeffReadCost,  // NOTE What if an evaluator evaluate itself into a tempory?
-                                                  //      Then CoeffReadCost will be small (e.g., 1) but we still have to evaluate, especially if n>1.
-                                                  //      This situation is already taken care by the EvalBeforeNestingBit flag, which is turned ON
-                                                  //      for all evaluator creating a temporary. This flag is then propagated by the parent evaluators.
-                                                  //      Another solution could be to count the number of temps?
-    NAsInteger = n == Dynamic ? HugeCost : n,
-    CostEval   = (NAsInteger+1) * ScalarReadCost + CoeffReadCost,
-    CostNoEval = NAsInteger * CoeffReadCost,
-    Evaluate = (int(evaluator<T>::Flags) & EvalBeforeNestingBit) || (int(CostEval) < int(CostNoEval))
-  };
-
-  typedef typename conditional<Evaluate, PlainObject, typename ref_selector<T>::type>::type type;
-};
-
-template<typename T>
-EIGEN_DEVICE_FUNC
-inline T* const_cast_ptr(const T* ptr)
-{
-  return const_cast<T*>(ptr);
-}
-
-template<typename Derived, typename XprKind = typename traits<Derived>::XprKind>
-struct dense_xpr_base
-{
-  /* dense_xpr_base should only ever be used on dense expressions, thus falling either into the MatrixXpr or into the ArrayXpr cases */
-};
-
-template<typename Derived>
-struct dense_xpr_base<Derived, MatrixXpr>
-{
-  typedef MatrixBase<Derived> type;
-};
-
-template<typename Derived>
-struct dense_xpr_base<Derived, ArrayXpr>
-{
-  typedef ArrayBase<Derived> type;
-};
-
-template<typename Derived, typename XprKind = typename traits<Derived>::XprKind, typename StorageKind = typename traits<Derived>::StorageKind>
-struct generic_xpr_base;
-
-template<typename Derived, typename XprKind>
-struct generic_xpr_base<Derived, XprKind, Dense>
-{
-  typedef typename dense_xpr_base<Derived,XprKind>::type type;
-};
-
-template<typename XprType, typename CastType> struct cast_return_type
-{
-  typedef typename XprType::Scalar CurrentScalarType;
-  typedef typename remove_all<CastType>::type _CastType;
-  typedef typename _CastType::Scalar NewScalarType;
-  typedef typename conditional<is_same<CurrentScalarType,NewScalarType>::value,
-                              const XprType&,CastType>::type type;
-};
-
-template <typename A, typename B> struct promote_storage_type;
-
-template <typename A> struct promote_storage_type<A,A>
-{
-  typedef A ret;
-};
-template <typename A> struct promote_storage_type<A, const A>
-{
-  typedef A ret;
-};
-template <typename A> struct promote_storage_type<const A, A>
-{
-  typedef A ret;
-};
-
-/** \internal Specify the "storage kind" of applying a coefficient-wise
-  * binary operations between two expressions of kinds A and B respectively.
-  * The template parameter Functor permits to specialize the resulting storage kind wrt to
-  * the functor.
-  * The default rules are as follows:
-  * \code
-  * A      op A      -> A
-  * A      op dense  -> dense
-  * dense  op B      -> dense
-  * sparse op dense  -> sparse
-  * dense  op sparse -> sparse
-  * \endcode
-  */
-template <typename A, typename B, typename Functor> struct cwise_promote_storage_type;
-
-template <typename A, typename Functor>                   struct cwise_promote_storage_type<A,A,Functor>                                      { typedef A      ret; };
-template <typename Functor>                               struct cwise_promote_storage_type<Dense,Dense,Functor>                              { typedef Dense  ret; };
-template <typename A, typename Functor>                   struct cwise_promote_storage_type<A,Dense,Functor>                                  { typedef Dense  ret; };
-template <typename B, typename Functor>                   struct cwise_promote_storage_type<Dense,B,Functor>                                  { typedef Dense  ret; };
-template <typename Functor>                               struct cwise_promote_storage_type<Sparse,Dense,Functor>                             { typedef Sparse ret; };
-template <typename Functor>                               struct cwise_promote_storage_type<Dense,Sparse,Functor>                             { typedef Sparse ret; };
-
-template <typename LhsKind, typename RhsKind, int LhsOrder, int RhsOrder> struct cwise_promote_storage_order {
-  enum { value = LhsOrder };
-};
-
-template <typename LhsKind, int LhsOrder, int RhsOrder>   struct cwise_promote_storage_order<LhsKind,Sparse,LhsOrder,RhsOrder>                { enum { value = RhsOrder }; };
-template <typename RhsKind, int LhsOrder, int RhsOrder>   struct cwise_promote_storage_order<Sparse,RhsKind,LhsOrder,RhsOrder>                { enum { value = LhsOrder }; };
-template <int Order>                                      struct cwise_promote_storage_order<Sparse,Sparse,Order,Order>                       { enum { value = Order }; };
-
-
-/** \internal Specify the "storage kind" of multiplying an expression of kind A with kind B.
-  * The template parameter ProductTag permits to specialize the resulting storage kind wrt to
-  * some compile-time properties of the product: GemmProduct, GemvProduct, OuterProduct, InnerProduct.
-  * The default rules are as follows:
-  * \code
-  *  K * K            -> K
-  *  dense * K        -> dense
-  *  K * dense        -> dense
-  *  diag * K         -> K
-  *  K * diag         -> K
-  *  Perm * K         -> K
-  * K * Perm          -> K
-  * \endcode
-  */
-template <typename A, typename B, int ProductTag> struct product_promote_storage_type;
-
-template <typename A, int ProductTag> struct product_promote_storage_type<A,                  A,                  ProductTag> { typedef A     ret;};
-template <int ProductTag>             struct product_promote_storage_type<Dense,              Dense,              ProductTag> { typedef Dense ret;};
-template <typename A, int ProductTag> struct product_promote_storage_type<A,                  Dense,              ProductTag> { typedef Dense ret; };
-template <typename B, int ProductTag> struct product_promote_storage_type<Dense,              B,                  ProductTag> { typedef Dense ret; };
-
-template <typename A, int ProductTag> struct product_promote_storage_type<A,                  DiagonalShape,      ProductTag> { typedef A ret; };
-template <typename B, int ProductTag> struct product_promote_storage_type<DiagonalShape,      B,                  ProductTag> { typedef B ret; };
-template <int ProductTag>             struct product_promote_storage_type<Dense,              DiagonalShape,      ProductTag> { typedef Dense ret; };
-template <int ProductTag>             struct product_promote_storage_type<DiagonalShape,      Dense,              ProductTag> { typedef Dense ret; };
-
-template <typename A, int ProductTag> struct product_promote_storage_type<A,                  PermutationStorage, ProductTag> { typedef A ret; };
-template <typename B, int ProductTag> struct product_promote_storage_type<PermutationStorage, B,                  ProductTag> { typedef B ret; };
-template <int ProductTag>             struct product_promote_storage_type<Dense,              PermutationStorage, ProductTag> { typedef Dense ret; };
-template <int ProductTag>             struct product_promote_storage_type<PermutationStorage, Dense,              ProductTag> { typedef Dense ret; };
-
-/** \internal gives the plain matrix or array type to store a row/column/diagonal of a matrix type.
-  * \tparam Scalar optional parameter allowing to pass a different scalar type than the one of the MatrixType.
-  */
-template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
-struct plain_row_type
-{
-  typedef Matrix<Scalar, 1, ExpressionType::ColsAtCompileTime,
-                 ExpressionType::PlainObject::Options | RowMajor, 1, ExpressionType::MaxColsAtCompileTime> MatrixRowType;
-  typedef Array<Scalar, 1, ExpressionType::ColsAtCompileTime,
-                 ExpressionType::PlainObject::Options | RowMajor, 1, ExpressionType::MaxColsAtCompileTime> ArrayRowType;
-
-  typedef typename conditional<
-    is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value,
-    MatrixRowType,
-    ArrayRowType 
-  >::type type;
-};
-
-template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
-struct plain_col_type
-{
-  typedef Matrix<Scalar, ExpressionType::RowsAtCompileTime, 1,
-                 ExpressionType::PlainObject::Options & ~RowMajor, ExpressionType::MaxRowsAtCompileTime, 1> MatrixColType;
-  typedef Array<Scalar, ExpressionType::RowsAtCompileTime, 1,
-                 ExpressionType::PlainObject::Options & ~RowMajor, ExpressionType::MaxRowsAtCompileTime, 1> ArrayColType;
-
-  typedef typename conditional<
-    is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value,
-    MatrixColType,
-    ArrayColType 
-  >::type type;
-};
-
-template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
-struct plain_diag_type
-{
-  enum { diag_size = EIGEN_SIZE_MIN_PREFER_DYNAMIC(ExpressionType::RowsAtCompileTime, ExpressionType::ColsAtCompileTime),
-         max_diag_size = EIGEN_SIZE_MIN_PREFER_FIXED(ExpressionType::MaxRowsAtCompileTime, ExpressionType::MaxColsAtCompileTime)
-  };
-  typedef Matrix<Scalar, diag_size, 1, ExpressionType::PlainObject::Options & ~RowMajor, max_diag_size, 1> MatrixDiagType;
-  typedef Array<Scalar, diag_size, 1, ExpressionType::PlainObject::Options & ~RowMajor, max_diag_size, 1> ArrayDiagType;
-
-  typedef typename conditional<
-    is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value,
-    MatrixDiagType,
-    ArrayDiagType 
-  >::type type;
-};
-
-template<typename Expr,typename Scalar = typename Expr::Scalar>
-struct plain_constant_type
-{
-  enum { Options = (traits<Expr>::Flags&RowMajorBit)?RowMajor:0 };
-
-  typedef Array<Scalar,  traits<Expr>::RowsAtCompileTime,   traits<Expr>::ColsAtCompileTime,
-                Options, traits<Expr>::MaxRowsAtCompileTime,traits<Expr>::MaxColsAtCompileTime> array_type;
-
-  typedef Matrix<Scalar,  traits<Expr>::RowsAtCompileTime,   traits<Expr>::ColsAtCompileTime,
-                 Options, traits<Expr>::MaxRowsAtCompileTime,traits<Expr>::MaxColsAtCompileTime> matrix_type;
-
-  typedef CwiseNullaryOp<scalar_constant_op<Scalar>, const typename conditional<is_same< typename traits<Expr>::XprKind, MatrixXpr >::value, matrix_type, array_type>::type > type;
-};
-
-template<typename ExpressionType>
-struct is_lvalue
-{
-  enum { value = (!bool(is_const<ExpressionType>::value)) &&
-                 bool(traits<ExpressionType>::Flags & LvalueBit) };
-};
-
-template<typename T> struct is_diagonal
-{ enum { ret = false }; };
-
-template<typename T> struct is_diagonal<DiagonalBase<T> >
-{ enum { ret = true }; };
-
-template<typename T> struct is_diagonal<DiagonalWrapper<T> >
-{ enum { ret = true }; };
-
-template<typename T, int S> struct is_diagonal<DiagonalMatrix<T,S> >
-{ enum { ret = true }; };
-
-template<typename S1, typename S2> struct glue_shapes;
-template<> struct glue_shapes<DenseShape,TriangularShape> { typedef TriangularShape type;  };
-
-template<typename T1, typename T2>
-bool is_same_dense(const T1 &mat1, const T2 &mat2, typename enable_if<has_direct_access<T1>::ret&&has_direct_access<T2>::ret, T1>::type * = 0)
-{
-  return (mat1.data()==mat2.data()) && (mat1.innerStride()==mat2.innerStride()) && (mat1.outerStride()==mat2.outerStride());
-}
-
-template<typename T1, typename T2>
-bool is_same_dense(const T1 &, const T2 &, typename enable_if<!(has_direct_access<T1>::ret&&has_direct_access<T2>::ret), T1>::type * = 0)
-{
-  return false;
-}
-
-// Internal helper defining the cost of a scalar division for the type T.
-// The default heuristic can be specialized for each scalar type and architecture.
-template<typename T,bool Vectorized=false,typename EnaleIf = void>
-struct scalar_div_cost {
-  enum { value = 8*NumTraits<T>::MulCost };
-};
-
-template<typename T,bool Vectorized>
-struct scalar_div_cost<std::complex<T>, Vectorized> {
-  enum { value = 2*scalar_div_cost<T>::value
-               + 6*NumTraits<T>::MulCost
-               + 3*NumTraits<T>::AddCost
-  };
-};
-
-
-template<bool Vectorized>
-struct scalar_div_cost<signed long,Vectorized,typename conditional<sizeof(long)==8,void,false_type>::type> { enum { value = 24 }; };
-template<bool Vectorized>
-struct scalar_div_cost<unsigned long,Vectorized,typename conditional<sizeof(long)==8,void,false_type>::type> { enum { value = 21 }; };
-
-
-#ifdef EIGEN_DEBUG_ASSIGN
-std::string demangle_traversal(int t)
-{
-  if(t==DefaultTraversal) return "DefaultTraversal";
-  if(t==LinearTraversal) return "LinearTraversal";
-  if(t==InnerVectorizedTraversal) return "InnerVectorizedTraversal";
-  if(t==LinearVectorizedTraversal) return "LinearVectorizedTraversal";
-  if(t==SliceVectorizedTraversal) return "SliceVectorizedTraversal";
-  return "?";
-}
-std::string demangle_unrolling(int t)
-{
-  if(t==NoUnrolling) return "NoUnrolling";
-  if(t==InnerUnrolling) return "InnerUnrolling";
-  if(t==CompleteUnrolling) return "CompleteUnrolling";
-  return "?";
-}
-std::string demangle_flags(int f)
-{
-  std::string res;
-  if(f&RowMajorBit)                 res += " | RowMajor";
-  if(f&PacketAccessBit)             res += " | Packet";
-  if(f&LinearAccessBit)             res += " | Linear";
-  if(f&LvalueBit)                   res += " | Lvalue";
-  if(f&DirectAccessBit)             res += " | Direct";
-  if(f&NestByRefBit)                res += " | NestByRef";
-  if(f&NoPreferredStorageOrderBit)  res += " | NoPreferredStorageOrderBit";
-  
-  return res;
-}
-#endif
-
-} // end namespace internal
-
-
-/** \class ScalarBinaryOpTraits
-  * \ingroup Core_Module
-  *
-  * \brief Determines whether the given binary operation of two numeric types is allowed and what the scalar return type is.
-  *
-  * This class permits to control the scalar return type of any binary operation performed on two different scalar types through (partial) template specializations.
-  *
-  * For instance, let \c U1, \c U2 and \c U3 be three user defined scalar types for which most operations between instances of \c U1 and \c U2 returns an \c U3.
-  * You can let %Eigen knows that by defining:
-    \code
-    template<typename BinaryOp>
-    struct ScalarBinaryOpTraits<U1,U2,BinaryOp> { typedef U3 ReturnType;  };
-    template<typename BinaryOp>
-    struct ScalarBinaryOpTraits<U2,U1,BinaryOp> { typedef U3 ReturnType;  };
-    \endcode
-  * You can then explicitly disable some particular operations to get more explicit error messages:
-    \code
-    template<>
-    struct ScalarBinaryOpTraits<U1,U2,internal::scalar_max_op<U1,U2> > {};
-    \endcode
-  * Or customize the return type for individual operation:
-    \code
-    template<>
-    struct ScalarBinaryOpTraits<U1,U2,internal::scalar_sum_op<U1,U2> > { typedef U1 ReturnType; };
-    \endcode
-  *
-  * By default, the following generic combinations are supported:
-  <table class="manual">
-  <tr><th>ScalarA</th><th>ScalarB</th><th>BinaryOp</th><th>ReturnType</th><th>Note</th></tr>
-  <tr            ><td>\c T </td><td>\c T </td><td>\c * </td><td>\c T </td><td></td></tr>
-  <tr class="alt"><td>\c NumTraits<T>::Real </td><td>\c T </td><td>\c * </td><td>\c T </td><td>Only if \c NumTraits<T>::IsComplex </td></tr>
-  <tr            ><td>\c T </td><td>\c NumTraits<T>::Real </td><td>\c * </td><td>\c T </td><td>Only if \c NumTraits<T>::IsComplex </td></tr>
-  </table>
-  *
-  * \sa CwiseBinaryOp
-  */
-template<typename ScalarA, typename ScalarB, typename BinaryOp=internal::scalar_product_op<ScalarA,ScalarB> >
-struct ScalarBinaryOpTraits
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-  // for backward compatibility, use the hints given by the (deprecated) internal::scalar_product_traits class.
-  : internal::scalar_product_traits<ScalarA,ScalarB>
-#endif // EIGEN_PARSED_BY_DOXYGEN
-{};
-
-template<typename T, typename BinaryOp>
-struct ScalarBinaryOpTraits<T,T,BinaryOp>
-{
-  typedef T ReturnType;
-};
-
-template <typename T, typename BinaryOp>
-struct ScalarBinaryOpTraits<T, typename NumTraits<typename internal::enable_if<NumTraits<T>::IsComplex,T>::type>::Real, BinaryOp>
-{
-  typedef T ReturnType;
-};
-template <typename T, typename BinaryOp>
-struct ScalarBinaryOpTraits<typename NumTraits<typename internal::enable_if<NumTraits<T>::IsComplex,T>::type>::Real, T, BinaryOp>
-{
-  typedef T ReturnType;
-};
-
-// For Matrix * Permutation
-template<typename T, typename BinaryOp>
-struct ScalarBinaryOpTraits<T,void,BinaryOp>
-{
-  typedef T ReturnType;
-};
-
-// For Permutation * Matrix
-template<typename T, typename BinaryOp>
-struct ScalarBinaryOpTraits<void,T,BinaryOp>
-{
-  typedef T ReturnType;
-};
-
-// for Permutation*Permutation
-template<typename BinaryOp>
-struct ScalarBinaryOpTraits<void,void,BinaryOp>
-{
-  typedef void ReturnType;
-};
-
-// We require Lhs and Rhs to have "compatible" scalar types.
-// It is tempting to always allow mixing different types but remember that this is often impossible in the vectorized paths.
-// So allowing mixing different types gives very unexpected errors when enabling vectorization, when the user tries to
-// add together a float matrix and a double matrix.
-#define EIGEN_CHECK_BINARY_COMPATIBILIY(BINOP,LHS,RHS) \
-  EIGEN_STATIC_ASSERT((Eigen::internal::has_ReturnType<ScalarBinaryOpTraits<LHS, RHS,BINOP> >::value), \
-    YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
-    
-} // end namespace Eigen
-
-#endif // EIGEN_XPRHELPER_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/ComplexEigenSolver.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/ComplexEigenSolver.h
deleted file mode 100644
index dc5fae0..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/ComplexEigenSolver.h
+++ /dev/null
@@ -1,346 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Claire Maurice
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2010,2012 Jitse Niesen <jitse@maths.leeds.ac.uk>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_COMPLEX_EIGEN_SOLVER_H
-#define EIGEN_COMPLEX_EIGEN_SOLVER_H
-
-#include "./ComplexSchur.h"
-
-namespace Eigen { 
-
-/** \eigenvalues_module \ingroup Eigenvalues_Module
-  *
-  *
-  * \class ComplexEigenSolver
-  *
-  * \brief Computes eigenvalues and eigenvectors of general complex matrices
-  *
-  * \tparam _MatrixType the type of the matrix of which we are
-  * computing the eigendecomposition; this is expected to be an
-  * instantiation of the Matrix class template.
-  *
-  * The eigenvalues and eigenvectors of a matrix \f$ A \f$ are scalars
-  * \f$ \lambda \f$ and vectors \f$ v \f$ such that \f$ Av = \lambda v
-  * \f$.  If \f$ D \f$ is a diagonal matrix with the eigenvalues on
-  * the diagonal, and \f$ V \f$ is a matrix with the eigenvectors as
-  * its columns, then \f$ A V = V D \f$. The matrix \f$ V \f$ is
-  * almost always invertible, in which case we have \f$ A = V D V^{-1}
-  * \f$. This is called the eigendecomposition.
-  *
-  * The main function in this class is compute(), which computes the
-  * eigenvalues and eigenvectors of a given function. The
-  * documentation for that function contains an example showing the
-  * main features of the class.
-  *
-  * \sa class EigenSolver, class SelfAdjointEigenSolver
-  */
-template<typename _MatrixType> class ComplexEigenSolver
-{
-  public:
-
-    /** \brief Synonym for the template parameter \p _MatrixType. */
-    typedef _MatrixType MatrixType;
-
-    enum {
-      RowsAtCompileTime = MatrixType::RowsAtCompileTime,
-      ColsAtCompileTime = MatrixType::ColsAtCompileTime,
-      Options = MatrixType::Options,
-      MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
-      MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
-    };
-
-    /** \brief Scalar type for matrices of type #MatrixType. */
-    typedef typename MatrixType::Scalar Scalar;
-    typedef typename NumTraits<Scalar>::Real RealScalar;
-    typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
-
-    /** \brief Complex scalar type for #MatrixType.
-      *
-      * This is \c std::complex<Scalar> if #Scalar is real (e.g.,
-      * \c float or \c double) and just \c Scalar if #Scalar is
-      * complex.
-      */
-    typedef std::complex<RealScalar> ComplexScalar;
-
-    /** \brief Type for vector of eigenvalues as returned by eigenvalues().
-      *
-      * This is a column vector with entries of type #ComplexScalar.
-      * The length of the vector is the size of #MatrixType.
-      */
-    typedef Matrix<ComplexScalar, ColsAtCompileTime, 1, Options&(~RowMajor), MaxColsAtCompileTime, 1> EigenvalueType;
-
-    /** \brief Type for matrix of eigenvectors as returned by eigenvectors().
-      *
-      * This is a square matrix with entries of type #ComplexScalar.
-      * The size is the same as the size of #MatrixType.
-      */
-    typedef Matrix<ComplexScalar, RowsAtCompileTime, ColsAtCompileTime, Options, MaxRowsAtCompileTime, MaxColsAtCompileTime> EigenvectorType;
-
-    /** \brief Default constructor.
-      *
-      * The default constructor is useful in cases in which the user intends to
-      * perform decompositions via compute().
-      */
-    ComplexEigenSolver()
-            : m_eivec(),
-              m_eivalues(),
-              m_schur(),
-              m_isInitialized(false),
-              m_eigenvectorsOk(false),
-              m_matX()
-    {}
-
-    /** \brief Default Constructor with memory preallocation
-      *
-      * Like the default constructor but with preallocation of the internal data
-      * according to the specified problem \a size.
-      * \sa ComplexEigenSolver()
-      */
-    explicit ComplexEigenSolver(Index size)
-            : m_eivec(size, size),
-              m_eivalues(size),
-              m_schur(size),
-              m_isInitialized(false),
-              m_eigenvectorsOk(false),
-              m_matX(size, size)
-    {}
-
-    /** \brief Constructor; computes eigendecomposition of given matrix.
-      *
-      * \param[in]  matrix  Square matrix whose eigendecomposition is to be computed.
-      * \param[in]  computeEigenvectors  If true, both the eigenvectors and the
-      *    eigenvalues are computed; if false, only the eigenvalues are
-      *    computed.
-      *
-      * This constructor calls compute() to compute the eigendecomposition.
-      */
-    template<typename InputType>
-    explicit ComplexEigenSolver(const EigenBase<InputType>& matrix, bool computeEigenvectors = true)
-            : m_eivec(matrix.rows(),matrix.cols()),
-              m_eivalues(matrix.cols()),
-              m_schur(matrix.rows()),
-              m_isInitialized(false),
-              m_eigenvectorsOk(false),
-              m_matX(matrix.rows(),matrix.cols())
-    {
-      compute(matrix.derived(), computeEigenvectors);
-    }
-
-    /** \brief Returns the eigenvectors of given matrix.
-      *
-      * \returns  A const reference to the matrix whose columns are the eigenvectors.
-      *
-      * \pre Either the constructor
-      * ComplexEigenSolver(const MatrixType& matrix, bool) or the member
-      * function compute(const MatrixType& matrix, bool) has been called before
-      * to compute the eigendecomposition of a matrix, and
-      * \p computeEigenvectors was set to true (the default).
-      *
-      * This function returns a matrix whose columns are the eigenvectors. Column
-      * \f$ k \f$ is an eigenvector corresponding to eigenvalue number \f$ k
-      * \f$ as returned by eigenvalues().  The eigenvectors are normalized to
-      * have (Euclidean) norm equal to one. The matrix returned by this
-      * function is the matrix \f$ V \f$ in the eigendecomposition \f$ A = V D
-      * V^{-1} \f$, if it exists.
-      *
-      * Example: \include ComplexEigenSolver_eigenvectors.cpp
-      * Output: \verbinclude ComplexEigenSolver_eigenvectors.out
-      */
-    const EigenvectorType& eigenvectors() const
-    {
-      eigen_assert(m_isInitialized && "ComplexEigenSolver is not initialized.");
-      eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues.");
-      return m_eivec;
-    }
-
-    /** \brief Returns the eigenvalues of given matrix.
-      *
-      * \returns A const reference to the column vector containing the eigenvalues.
-      *
-      * \pre Either the constructor
-      * ComplexEigenSolver(const MatrixType& matrix, bool) or the member
-      * function compute(const MatrixType& matrix, bool) has been called before
-      * to compute the eigendecomposition of a matrix.
-      *
-      * This function returns a column vector containing the
-      * eigenvalues. Eigenvalues are repeated according to their
-      * algebraic multiplicity, so there are as many eigenvalues as
-      * rows in the matrix. The eigenvalues are not sorted in any particular
-      * order.
-      *
-      * Example: \include ComplexEigenSolver_eigenvalues.cpp
-      * Output: \verbinclude ComplexEigenSolver_eigenvalues.out
-      */
-    const EigenvalueType& eigenvalues() const
-    {
-      eigen_assert(m_isInitialized && "ComplexEigenSolver is not initialized.");
-      return m_eivalues;
-    }
-
-    /** \brief Computes eigendecomposition of given matrix.
-      *
-      * \param[in]  matrix  Square matrix whose eigendecomposition is to be computed.
-      * \param[in]  computeEigenvectors  If true, both the eigenvectors and the
-      *    eigenvalues are computed; if false, only the eigenvalues are
-      *    computed.
-      * \returns    Reference to \c *this
-      *
-      * This function computes the eigenvalues of the complex matrix \p matrix.
-      * The eigenvalues() function can be used to retrieve them.  If
-      * \p computeEigenvectors is true, then the eigenvectors are also computed
-      * and can be retrieved by calling eigenvectors().
-      *
-      * The matrix is first reduced to Schur form using the
-      * ComplexSchur class. The Schur decomposition is then used to
-      * compute the eigenvalues and eigenvectors.
-      *
-      * The cost of the computation is dominated by the cost of the
-      * Schur decomposition, which is \f$ O(n^3) \f$ where \f$ n \f$
-      * is the size of the matrix.
-      *
-      * Example: \include ComplexEigenSolver_compute.cpp
-      * Output: \verbinclude ComplexEigenSolver_compute.out
-      */
-    template<typename InputType>
-    ComplexEigenSolver& compute(const EigenBase<InputType>& matrix, bool computeEigenvectors = true);
-
-    /** \brief Reports whether previous computation was successful.
-      *
-      * \returns \c Success if computation was succesful, \c NoConvergence otherwise.
-      */
-    ComputationInfo info() const
-    {
-      eigen_assert(m_isInitialized && "ComplexEigenSolver is not initialized.");
-      return m_schur.info();
-    }
-
-    /** \brief Sets the maximum number of iterations allowed. */
-    ComplexEigenSolver& setMaxIterations(Index maxIters)
-    {
-      m_schur.setMaxIterations(maxIters);
-      return *this;
-    }
-
-    /** \brief Returns the maximum number of iterations. */
-    Index getMaxIterations()
-    {
-      return m_schur.getMaxIterations();
-    }
-
-  protected:
-    
-    static void check_template_parameters()
-    {
-      EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
-    }
-    
-    EigenvectorType m_eivec;
-    EigenvalueType m_eivalues;
-    ComplexSchur<MatrixType> m_schur;
-    bool m_isInitialized;
-    bool m_eigenvectorsOk;
-    EigenvectorType m_matX;
-
-  private:
-    void doComputeEigenvectors(RealScalar matrixnorm);
-    void sortEigenvalues(bool computeEigenvectors);
-};
-
-
-template<typename MatrixType>
-template<typename InputType>
-ComplexEigenSolver<MatrixType>& 
-ComplexEigenSolver<MatrixType>::compute(const EigenBase<InputType>& matrix, bool computeEigenvectors)
-{
-  check_template_parameters();
-  
-  // this code is inspired from Jampack
-  eigen_assert(matrix.cols() == matrix.rows());
-
-  // Do a complex Schur decomposition, A = U T U^*
-  // The eigenvalues are on the diagonal of T.
-  m_schur.compute(matrix.derived(), computeEigenvectors);
-
-  if(m_schur.info() == Success)
-  {
-    m_eivalues = m_schur.matrixT().diagonal();
-    if(computeEigenvectors)
-      doComputeEigenvectors(m_schur.matrixT().norm());
-    sortEigenvalues(computeEigenvectors);
-  }
-
-  m_isInitialized = true;
-  m_eigenvectorsOk = computeEigenvectors;
-  return *this;
-}
-
-
-template<typename MatrixType>
-void ComplexEigenSolver<MatrixType>::doComputeEigenvectors(RealScalar matrixnorm)
-{
-  const Index n = m_eivalues.size();
-
-  matrixnorm = numext::maxi(matrixnorm,(std::numeric_limits<RealScalar>::min)());
-
-  // Compute X such that T = X D X^(-1), where D is the diagonal of T.
-  // The matrix X is unit triangular.
-  m_matX = EigenvectorType::Zero(n, n);
-  for(Index k=n-1 ; k>=0 ; k--)
-  {
-    m_matX.coeffRef(k,k) = ComplexScalar(1.0,0.0);
-    // Compute X(i,k) using the (i,k) entry of the equation X T = D X
-    for(Index i=k-1 ; i>=0 ; i--)
-    {
-      m_matX.coeffRef(i,k) = -m_schur.matrixT().coeff(i,k);
-      if(k-i-1>0)
-        m_matX.coeffRef(i,k) -= (m_schur.matrixT().row(i).segment(i+1,k-i-1) * m_matX.col(k).segment(i+1,k-i-1)).value();
-      ComplexScalar z = m_schur.matrixT().coeff(i,i) - m_schur.matrixT().coeff(k,k);
-      if(z==ComplexScalar(0))
-      {
-        // If the i-th and k-th eigenvalue are equal, then z equals 0.
-        // Use a small value instead, to prevent division by zero.
-        numext::real_ref(z) = NumTraits<RealScalar>::epsilon() * matrixnorm;
-      }
-      m_matX.coeffRef(i,k) = m_matX.coeff(i,k) / z;
-    }
-  }
-
-  // Compute V as V = U X; now A = U T U^* = U X D X^(-1) U^* = V D V^(-1)
-  m_eivec.noalias() = m_schur.matrixU() * m_matX;
-  // .. and normalize the eigenvectors
-  for(Index k=0 ; k<n ; k++)
-  {
-    m_eivec.col(k).normalize();
-  }
-}
-
-
-template<typename MatrixType>
-void ComplexEigenSolver<MatrixType>::sortEigenvalues(bool computeEigenvectors)
-{
-  const Index n =  m_eivalues.size();
-  for (Index i=0; i<n; i++)
-  {
-    Index k;
-    m_eivalues.cwiseAbs().tail(n-i).minCoeff(&k);
-    if (k != 0)
-    {
-      k += i;
-      std::swap(m_eivalues[k],m_eivalues[i]);
-      if(computeEigenvectors)
-	m_eivec.col(i).swap(m_eivec.col(k));
-    }
-  }
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_COMPLEX_EIGEN_SOLVER_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/ComplexSchur.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/ComplexSchur.h
deleted file mode 100644
index 7f38919..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/ComplexSchur.h
+++ /dev/null
@@ -1,459 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Claire Maurice
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2010,2012 Jitse Niesen <jitse@maths.leeds.ac.uk>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_COMPLEX_SCHUR_H
-#define EIGEN_COMPLEX_SCHUR_H
-
-#include "./HessenbergDecomposition.h"
-
-namespace Eigen { 
-
-namespace internal {
-template<typename MatrixType, bool IsComplex> struct complex_schur_reduce_to_hessenberg;
-}
-
-/** \eigenvalues_module \ingroup Eigenvalues_Module
-  *
-  *
-  * \class ComplexSchur
-  *
-  * \brief Performs a complex Schur decomposition of a real or complex square matrix
-  *
-  * \tparam _MatrixType the type of the matrix of which we are
-  * computing the Schur decomposition; this is expected to be an
-  * instantiation of the Matrix class template.
-  *
-  * Given a real or complex square matrix A, this class computes the
-  * Schur decomposition: \f$ A = U T U^*\f$ where U is a unitary
-  * complex matrix, and T is a complex upper triangular matrix.  The
-  * diagonal of the matrix T corresponds to the eigenvalues of the
-  * matrix A.
-  *
-  * Call the function compute() to compute the Schur decomposition of
-  * a given matrix. Alternatively, you can use the 
-  * ComplexSchur(const MatrixType&, bool) constructor which computes
-  * the Schur decomposition at construction time. Once the
-  * decomposition is computed, you can use the matrixU() and matrixT()
-  * functions to retrieve the matrices U and V in the decomposition.
-  *
-  * \note This code is inspired from Jampack
-  *
-  * \sa class RealSchur, class EigenSolver, class ComplexEigenSolver
-  */
-template<typename _MatrixType> class ComplexSchur
-{
-  public:
-    typedef _MatrixType MatrixType;
-    enum {
-      RowsAtCompileTime = MatrixType::RowsAtCompileTime,
-      ColsAtCompileTime = MatrixType::ColsAtCompileTime,
-      Options = MatrixType::Options,
-      MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
-      MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
-    };
-
-    /** \brief Scalar type for matrices of type \p _MatrixType. */
-    typedef typename MatrixType::Scalar Scalar;
-    typedef typename NumTraits<Scalar>::Real RealScalar;
-    typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
-
-    /** \brief Complex scalar type for \p _MatrixType. 
-      *
-      * This is \c std::complex<Scalar> if #Scalar is real (e.g.,
-      * \c float or \c double) and just \c Scalar if #Scalar is
-      * complex.
-      */
-    typedef std::complex<RealScalar> ComplexScalar;
-
-    /** \brief Type for the matrices in the Schur decomposition.
-      *
-      * This is a square matrix with entries of type #ComplexScalar. 
-      * The size is the same as the size of \p _MatrixType.
-      */
-    typedef Matrix<ComplexScalar, RowsAtCompileTime, ColsAtCompileTime, Options, MaxRowsAtCompileTime, MaxColsAtCompileTime> ComplexMatrixType;
-
-    /** \brief Default constructor.
-      *
-      * \param [in] size  Positive integer, size of the matrix whose Schur decomposition will be computed.
-      *
-      * The default constructor is useful in cases in which the user
-      * intends to perform decompositions via compute().  The \p size
-      * parameter is only used as a hint. It is not an error to give a
-      * wrong \p size, but it may impair performance.
-      *
-      * \sa compute() for an example.
-      */
-    explicit ComplexSchur(Index size = RowsAtCompileTime==Dynamic ? 1 : RowsAtCompileTime)
-      : m_matT(size,size),
-        m_matU(size,size),
-        m_hess(size),
-        m_isInitialized(false),
-        m_matUisUptodate(false),
-        m_maxIters(-1)
-    {}
-
-    /** \brief Constructor; computes Schur decomposition of given matrix. 
-      * 
-      * \param[in]  matrix    Square matrix whose Schur decomposition is to be computed.
-      * \param[in]  computeU  If true, both T and U are computed; if false, only T is computed.
-      *
-      * This constructor calls compute() to compute the Schur decomposition.
-      *
-      * \sa matrixT() and matrixU() for examples.
-      */
-    template<typename InputType>
-    explicit ComplexSchur(const EigenBase<InputType>& matrix, bool computeU = true)
-      : m_matT(matrix.rows(),matrix.cols()),
-        m_matU(matrix.rows(),matrix.cols()),
-        m_hess(matrix.rows()),
-        m_isInitialized(false),
-        m_matUisUptodate(false),
-        m_maxIters(-1)
-    {
-      compute(matrix.derived(), computeU);
-    }
-
-    /** \brief Returns the unitary matrix in the Schur decomposition. 
-      *
-      * \returns A const reference to the matrix U.
-      *
-      * It is assumed that either the constructor
-      * ComplexSchur(const MatrixType& matrix, bool computeU) or the
-      * member function compute(const MatrixType& matrix, bool computeU)
-      * has been called before to compute the Schur decomposition of a
-      * matrix, and that \p computeU was set to true (the default
-      * value).
-      *
-      * Example: \include ComplexSchur_matrixU.cpp
-      * Output: \verbinclude ComplexSchur_matrixU.out
-      */
-    const ComplexMatrixType& matrixU() const
-    {
-      eigen_assert(m_isInitialized && "ComplexSchur is not initialized.");
-      eigen_assert(m_matUisUptodate && "The matrix U has not been computed during the ComplexSchur decomposition.");
-      return m_matU;
-    }
-
-    /** \brief Returns the triangular matrix in the Schur decomposition. 
-      *
-      * \returns A const reference to the matrix T.
-      *
-      * It is assumed that either the constructor
-      * ComplexSchur(const MatrixType& matrix, bool computeU) or the
-      * member function compute(const MatrixType& matrix, bool computeU)
-      * has been called before to compute the Schur decomposition of a
-      * matrix.
-      *
-      * Note that this function returns a plain square matrix. If you want to reference
-      * only the upper triangular part, use:
-      * \code schur.matrixT().triangularView<Upper>() \endcode 
-      *
-      * Example: \include ComplexSchur_matrixT.cpp
-      * Output: \verbinclude ComplexSchur_matrixT.out
-      */
-    const ComplexMatrixType& matrixT() const
-    {
-      eigen_assert(m_isInitialized && "ComplexSchur is not initialized.");
-      return m_matT;
-    }
-
-    /** \brief Computes Schur decomposition of given matrix. 
-      * 
-      * \param[in]  matrix  Square matrix whose Schur decomposition is to be computed.
-      * \param[in]  computeU  If true, both T and U are computed; if false, only T is computed.
-
-      * \returns    Reference to \c *this
-      *
-      * The Schur decomposition is computed by first reducing the
-      * matrix to Hessenberg form using the class
-      * HessenbergDecomposition. The Hessenberg matrix is then reduced
-      * to triangular form by performing QR iterations with a single
-      * shift. The cost of computing the Schur decomposition depends
-      * on the number of iterations; as a rough guide, it may be taken
-      * on the number of iterations; as a rough guide, it may be taken
-      * to be \f$25n^3\f$ complex flops, or \f$10n^3\f$ complex flops
-      * if \a computeU is false.
-      *
-      * Example: \include ComplexSchur_compute.cpp
-      * Output: \verbinclude ComplexSchur_compute.out
-      *
-      * \sa compute(const MatrixType&, bool, Index)
-      */
-    template<typename InputType>
-    ComplexSchur& compute(const EigenBase<InputType>& matrix, bool computeU = true);
-    
-    /** \brief Compute Schur decomposition from a given Hessenberg matrix
-     *  \param[in] matrixH Matrix in Hessenberg form H
-     *  \param[in] matrixQ orthogonal matrix Q that transform a matrix A to H : A = Q H Q^T
-     *  \param computeU Computes the matriX U of the Schur vectors
-     * \return Reference to \c *this
-     * 
-     *  This routine assumes that the matrix is already reduced in Hessenberg form matrixH
-     *  using either the class HessenbergDecomposition or another mean. 
-     *  It computes the upper quasi-triangular matrix T of the Schur decomposition of H
-     *  When computeU is true, this routine computes the matrix U such that 
-     *  A = U T U^T =  (QZ) T (QZ)^T = Q H Q^T where A is the initial matrix
-     * 
-     * NOTE Q is referenced if computeU is true; so, if the initial orthogonal matrix
-     * is not available, the user should give an identity matrix (Q.setIdentity())
-     * 
-     * \sa compute(const MatrixType&, bool)
-     */
-    template<typename HessMatrixType, typename OrthMatrixType>
-    ComplexSchur& computeFromHessenberg(const HessMatrixType& matrixH, const OrthMatrixType& matrixQ,  bool computeU=true);
-
-    /** \brief Reports whether previous computation was successful.
-      *
-      * \returns \c Success if computation was succesful, \c NoConvergence otherwise.
-      */
-    ComputationInfo info() const
-    {
-      eigen_assert(m_isInitialized && "ComplexSchur is not initialized.");
-      return m_info;
-    }
-
-    /** \brief Sets the maximum number of iterations allowed. 
-      *
-      * If not specified by the user, the maximum number of iterations is m_maxIterationsPerRow times the size
-      * of the matrix.
-      */
-    ComplexSchur& setMaxIterations(Index maxIters)
-    {
-      m_maxIters = maxIters;
-      return *this;
-    }
-
-    /** \brief Returns the maximum number of iterations. */
-    Index getMaxIterations()
-    {
-      return m_maxIters;
-    }
-
-    /** \brief Maximum number of iterations per row.
-      *
-      * If not otherwise specified, the maximum number of iterations is this number times the size of the
-      * matrix. It is currently set to 30.
-      */
-    static const int m_maxIterationsPerRow = 30;
-
-  protected:
-    ComplexMatrixType m_matT, m_matU;
-    HessenbergDecomposition<MatrixType> m_hess;
-    ComputationInfo m_info;
-    bool m_isInitialized;
-    bool m_matUisUptodate;
-    Index m_maxIters;
-
-  private:  
-    bool subdiagonalEntryIsNeglegible(Index i);
-    ComplexScalar computeShift(Index iu, Index iter);
-    void reduceToTriangularForm(bool computeU);
-    friend struct internal::complex_schur_reduce_to_hessenberg<MatrixType, NumTraits<Scalar>::IsComplex>;
-};
-
-/** If m_matT(i+1,i) is neglegible in floating point arithmetic
-  * compared to m_matT(i,i) and m_matT(j,j), then set it to zero and
-  * return true, else return false. */
-template<typename MatrixType>
-inline bool ComplexSchur<MatrixType>::subdiagonalEntryIsNeglegible(Index i)
-{
-  RealScalar d = numext::norm1(m_matT.coeff(i,i)) + numext::norm1(m_matT.coeff(i+1,i+1));
-  RealScalar sd = numext::norm1(m_matT.coeff(i+1,i));
-  if (internal::isMuchSmallerThan(sd, d, NumTraits<RealScalar>::epsilon()))
-  {
-    m_matT.coeffRef(i+1,i) = ComplexScalar(0);
-    return true;
-  }
-  return false;
-}
-
-
-/** Compute the shift in the current QR iteration. */
-template<typename MatrixType>
-typename ComplexSchur<MatrixType>::ComplexScalar ComplexSchur<MatrixType>::computeShift(Index iu, Index iter)
-{
-  using std::abs;
-  if (iter == 10 || iter == 20) 
-  {
-    // exceptional shift, taken from http://www.netlib.org/eispack/comqr.f
-    return abs(numext::real(m_matT.coeff(iu,iu-1))) + abs(numext::real(m_matT.coeff(iu-1,iu-2)));
-  }
-
-  // compute the shift as one of the eigenvalues of t, the 2x2
-  // diagonal block on the bottom of the active submatrix
-  Matrix<ComplexScalar,2,2> t = m_matT.template block<2,2>(iu-1,iu-1);
-  RealScalar normt = t.cwiseAbs().sum();
-  t /= normt;     // the normalization by sf is to avoid under/overflow
-
-  ComplexScalar b = t.coeff(0,1) * t.coeff(1,0);
-  ComplexScalar c = t.coeff(0,0) - t.coeff(1,1);
-  ComplexScalar disc = sqrt(c*c + RealScalar(4)*b);
-  ComplexScalar det = t.coeff(0,0) * t.coeff(1,1) - b;
-  ComplexScalar trace = t.coeff(0,0) + t.coeff(1,1);
-  ComplexScalar eival1 = (trace + disc) / RealScalar(2);
-  ComplexScalar eival2 = (trace - disc) / RealScalar(2);
-
-  if(numext::norm1(eival1) > numext::norm1(eival2))
-    eival2 = det / eival1;
-  else
-    eival1 = det / eival2;
-
-  // choose the eigenvalue closest to the bottom entry of the diagonal
-  if(numext::norm1(eival1-t.coeff(1,1)) < numext::norm1(eival2-t.coeff(1,1)))
-    return normt * eival1;
-  else
-    return normt * eival2;
-}
-
-
-template<typename MatrixType>
-template<typename InputType>
-ComplexSchur<MatrixType>& ComplexSchur<MatrixType>::compute(const EigenBase<InputType>& matrix, bool computeU)
-{
-  m_matUisUptodate = false;
-  eigen_assert(matrix.cols() == matrix.rows());
-
-  if(matrix.cols() == 1)
-  {
-    m_matT = matrix.derived().template cast<ComplexScalar>();
-    if(computeU)  m_matU = ComplexMatrixType::Identity(1,1);
-    m_info = Success;
-    m_isInitialized = true;
-    m_matUisUptodate = computeU;
-    return *this;
-  }
-
-  internal::complex_schur_reduce_to_hessenberg<MatrixType, NumTraits<Scalar>::IsComplex>::run(*this, matrix.derived(), computeU);
-  computeFromHessenberg(m_matT, m_matU, computeU);
-  return *this;
-}
-
-template<typename MatrixType>
-template<typename HessMatrixType, typename OrthMatrixType>
-ComplexSchur<MatrixType>& ComplexSchur<MatrixType>::computeFromHessenberg(const HessMatrixType& matrixH, const OrthMatrixType& matrixQ, bool computeU)
-{
-  m_matT = matrixH;
-  if(computeU)
-    m_matU = matrixQ;
-  reduceToTriangularForm(computeU);
-  return *this;
-}
-namespace internal {
-
-/* Reduce given matrix to Hessenberg form */
-template<typename MatrixType, bool IsComplex>
-struct complex_schur_reduce_to_hessenberg
-{
-  // this is the implementation for the case IsComplex = true
-  static void run(ComplexSchur<MatrixType>& _this, const MatrixType& matrix, bool computeU)
-  {
-    _this.m_hess.compute(matrix);
-    _this.m_matT = _this.m_hess.matrixH();
-    if(computeU)  _this.m_matU = _this.m_hess.matrixQ();
-  }
-};
-
-template<typename MatrixType>
-struct complex_schur_reduce_to_hessenberg<MatrixType, false>
-{
-  static void run(ComplexSchur<MatrixType>& _this, const MatrixType& matrix, bool computeU)
-  {
-    typedef typename ComplexSchur<MatrixType>::ComplexScalar ComplexScalar;
-
-    // Note: m_hess is over RealScalar; m_matT and m_matU is over ComplexScalar
-    _this.m_hess.compute(matrix);
-    _this.m_matT = _this.m_hess.matrixH().template cast<ComplexScalar>();
-    if(computeU)  
-    {
-      // This may cause an allocation which seems to be avoidable
-      MatrixType Q = _this.m_hess.matrixQ(); 
-      _this.m_matU = Q.template cast<ComplexScalar>();
-    }
-  }
-};
-
-} // end namespace internal
-
-// Reduce the Hessenberg matrix m_matT to triangular form by QR iteration.
-template<typename MatrixType>
-void ComplexSchur<MatrixType>::reduceToTriangularForm(bool computeU)
-{  
-  Index maxIters = m_maxIters;
-  if (maxIters == -1)
-    maxIters = m_maxIterationsPerRow * m_matT.rows();
-
-  // The matrix m_matT is divided in three parts. 
-  // Rows 0,...,il-1 are decoupled from the rest because m_matT(il,il-1) is zero. 
-  // Rows il,...,iu is the part we are working on (the active submatrix).
-  // Rows iu+1,...,end are already brought in triangular form.
-  Index iu = m_matT.cols() - 1;
-  Index il;
-  Index iter = 0; // number of iterations we are working on the (iu,iu) element
-  Index totalIter = 0; // number of iterations for whole matrix
-
-  while(true)
-  {
-    // find iu, the bottom row of the active submatrix
-    while(iu > 0)
-    {
-      if(!subdiagonalEntryIsNeglegible(iu-1)) break;
-      iter = 0;
-      --iu;
-    }
-
-    // if iu is zero then we are done; the whole matrix is triangularized
-    if(iu==0) break;
-
-    // if we spent too many iterations, we give up
-    iter++;
-    totalIter++;
-    if(totalIter > maxIters) break;
-
-    // find il, the top row of the active submatrix
-    il = iu-1;
-    while(il > 0 && !subdiagonalEntryIsNeglegible(il-1))
-    {
-      --il;
-    }
-
-    /* perform the QR step using Givens rotations. The first rotation
-       creates a bulge; the (il+2,il) element becomes nonzero. This
-       bulge is chased down to the bottom of the active submatrix. */
-
-    ComplexScalar shift = computeShift(iu, iter);
-    JacobiRotation<ComplexScalar> rot;
-    rot.makeGivens(m_matT.coeff(il,il) - shift, m_matT.coeff(il+1,il));
-    m_matT.rightCols(m_matT.cols()-il).applyOnTheLeft(il, il+1, rot.adjoint());
-    m_matT.topRows((std::min)(il+2,iu)+1).applyOnTheRight(il, il+1, rot);
-    if(computeU) m_matU.applyOnTheRight(il, il+1, rot);
-
-    for(Index i=il+1 ; i<iu ; i++)
-    {
-      rot.makeGivens(m_matT.coeffRef(i,i-1), m_matT.coeffRef(i+1,i-1), &m_matT.coeffRef(i,i-1));
-      m_matT.coeffRef(i+1,i-1) = ComplexScalar(0);
-      m_matT.rightCols(m_matT.cols()-i).applyOnTheLeft(i, i+1, rot.adjoint());
-      m_matT.topRows((std::min)(i+2,iu)+1).applyOnTheRight(i, i+1, rot);
-      if(computeU) m_matU.applyOnTheRight(i, i+1, rot);
-    }
-  }
-
-  if(totalIter <= maxIters)
-    m_info = Success;
-  else
-    m_info = NoConvergence;
-
-  m_isInitialized = true;
-  m_matUisUptodate = computeU;
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_COMPLEX_SCHUR_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/EigenSolver.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/EigenSolver.h
deleted file mode 100644
index f205b18..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/EigenSolver.h
+++ /dev/null
@@ -1,622 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2010,2012 Jitse Niesen <jitse@maths.leeds.ac.uk>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_EIGENSOLVER_H
-#define EIGEN_EIGENSOLVER_H
-
-#include "./RealSchur.h"
-
-namespace Eigen { 
-
-/** \eigenvalues_module \ingroup Eigenvalues_Module
-  *
-  *
-  * \class EigenSolver
-  *
-  * \brief Computes eigenvalues and eigenvectors of general matrices
-  *
-  * \tparam _MatrixType the type of the matrix of which we are computing the
-  * eigendecomposition; this is expected to be an instantiation of the Matrix
-  * class template. Currently, only real matrices are supported.
-  *
-  * The eigenvalues and eigenvectors of a matrix \f$ A \f$ are scalars
-  * \f$ \lambda \f$ and vectors \f$ v \f$ such that \f$ Av = \lambda v \f$.  If
-  * \f$ D \f$ is a diagonal matrix with the eigenvalues on the diagonal, and
-  * \f$ V \f$ is a matrix with the eigenvectors as its columns, then \f$ A V =
-  * V D \f$. The matrix \f$ V \f$ is almost always invertible, in which case we
-  * have \f$ A = V D V^{-1} \f$. This is called the eigendecomposition.
-  *
-  * The eigenvalues and eigenvectors of a matrix may be complex, even when the
-  * matrix is real. However, we can choose real matrices \f$ V \f$ and \f$ D
-  * \f$ satisfying \f$ A V = V D \f$, just like the eigendecomposition, if the
-  * matrix \f$ D \f$ is not required to be diagonal, but if it is allowed to
-  * have blocks of the form
-  * \f[ \begin{bmatrix} u & v \\ -v & u \end{bmatrix} \f]
-  * (where \f$ u \f$ and \f$ v \f$ are real numbers) on the diagonal.  These
-  * blocks correspond to complex eigenvalue pairs \f$ u \pm iv \f$. We call
-  * this variant of the eigendecomposition the pseudo-eigendecomposition.
-  *
-  * Call the function compute() to compute the eigenvalues and eigenvectors of
-  * a given matrix. Alternatively, you can use the 
-  * EigenSolver(const MatrixType&, bool) constructor which computes the
-  * eigenvalues and eigenvectors at construction time. Once the eigenvalue and
-  * eigenvectors are computed, they can be retrieved with the eigenvalues() and
-  * eigenvectors() functions. The pseudoEigenvalueMatrix() and
-  * pseudoEigenvectors() methods allow the construction of the
-  * pseudo-eigendecomposition.
-  *
-  * The documentation for EigenSolver(const MatrixType&, bool) contains an
-  * example of the typical use of this class.
-  *
-  * \note The implementation is adapted from
-  * <a href="http://math.nist.gov/javanumerics/jama/">JAMA</a> (public domain).
-  * Their code is based on EISPACK.
-  *
-  * \sa MatrixBase::eigenvalues(), class ComplexEigenSolver, class SelfAdjointEigenSolver
-  */
-template<typename _MatrixType> class EigenSolver
-{
-  public:
-
-    /** \brief Synonym for the template parameter \p _MatrixType. */
-    typedef _MatrixType MatrixType;
-
-    enum {
-      RowsAtCompileTime = MatrixType::RowsAtCompileTime,
-      ColsAtCompileTime = MatrixType::ColsAtCompileTime,
-      Options = MatrixType::Options,
-      MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
-      MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
-    };
-
-    /** \brief Scalar type for matrices of type #MatrixType. */
-    typedef typename MatrixType::Scalar Scalar;
-    typedef typename NumTraits<Scalar>::Real RealScalar;
-    typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
-
-    /** \brief Complex scalar type for #MatrixType. 
-      *
-      * This is \c std::complex<Scalar> if #Scalar is real (e.g.,
-      * \c float or \c double) and just \c Scalar if #Scalar is
-      * complex.
-      */
-    typedef std::complex<RealScalar> ComplexScalar;
-
-    /** \brief Type for vector of eigenvalues as returned by eigenvalues(). 
-      *
-      * This is a column vector with entries of type #ComplexScalar.
-      * The length of the vector is the size of #MatrixType.
-      */
-    typedef Matrix<ComplexScalar, ColsAtCompileTime, 1, Options & ~RowMajor, MaxColsAtCompileTime, 1> EigenvalueType;
-
-    /** \brief Type for matrix of eigenvectors as returned by eigenvectors(). 
-      *
-      * This is a square matrix with entries of type #ComplexScalar. 
-      * The size is the same as the size of #MatrixType.
-      */
-    typedef Matrix<ComplexScalar, RowsAtCompileTime, ColsAtCompileTime, Options, MaxRowsAtCompileTime, MaxColsAtCompileTime> EigenvectorsType;
-
-    /** \brief Default constructor.
-      *
-      * The default constructor is useful in cases in which the user intends to
-      * perform decompositions via EigenSolver::compute(const MatrixType&, bool).
-      *
-      * \sa compute() for an example.
-      */
-    EigenSolver() : m_eivec(), m_eivalues(), m_isInitialized(false), m_realSchur(), m_matT(), m_tmp() {}
-
-    /** \brief Default constructor with memory preallocation
-      *
-      * Like the default constructor but with preallocation of the internal data
-      * according to the specified problem \a size.
-      * \sa EigenSolver()
-      */
-    explicit EigenSolver(Index size)
-      : m_eivec(size, size),
-        m_eivalues(size),
-        m_isInitialized(false),
-        m_eigenvectorsOk(false),
-        m_realSchur(size),
-        m_matT(size, size), 
-        m_tmp(size)
-    {}
-
-    /** \brief Constructor; computes eigendecomposition of given matrix. 
-      * 
-      * \param[in]  matrix  Square matrix whose eigendecomposition is to be computed.
-      * \param[in]  computeEigenvectors  If true, both the eigenvectors and the
-      *    eigenvalues are computed; if false, only the eigenvalues are
-      *    computed. 
-      *
-      * This constructor calls compute() to compute the eigenvalues
-      * and eigenvectors.
-      *
-      * Example: \include EigenSolver_EigenSolver_MatrixType.cpp
-      * Output: \verbinclude EigenSolver_EigenSolver_MatrixType.out
-      *
-      * \sa compute()
-      */
-    template<typename InputType>
-    explicit EigenSolver(const EigenBase<InputType>& matrix, bool computeEigenvectors = true)
-      : m_eivec(matrix.rows(), matrix.cols()),
-        m_eivalues(matrix.cols()),
-        m_isInitialized(false),
-        m_eigenvectorsOk(false),
-        m_realSchur(matrix.cols()),
-        m_matT(matrix.rows(), matrix.cols()), 
-        m_tmp(matrix.cols())
-    {
-      compute(matrix.derived(), computeEigenvectors);
-    }
-
-    /** \brief Returns the eigenvectors of given matrix. 
-      *
-      * \returns  %Matrix whose columns are the (possibly complex) eigenvectors.
-      *
-      * \pre Either the constructor 
-      * EigenSolver(const MatrixType&,bool) or the member function
-      * compute(const MatrixType&, bool) has been called before, and
-      * \p computeEigenvectors was set to true (the default).
-      *
-      * Column \f$ k \f$ of the returned matrix is an eigenvector corresponding
-      * to eigenvalue number \f$ k \f$ as returned by eigenvalues().  The
-      * eigenvectors are normalized to have (Euclidean) norm equal to one. The
-      * matrix returned by this function is the matrix \f$ V \f$ in the
-      * eigendecomposition \f$ A = V D V^{-1} \f$, if it exists.
-      *
-      * Example: \include EigenSolver_eigenvectors.cpp
-      * Output: \verbinclude EigenSolver_eigenvectors.out
-      *
-      * \sa eigenvalues(), pseudoEigenvectors()
-      */
-    EigenvectorsType eigenvectors() const;
-
-    /** \brief Returns the pseudo-eigenvectors of given matrix. 
-      *
-      * \returns  Const reference to matrix whose columns are the pseudo-eigenvectors.
-      *
-      * \pre Either the constructor 
-      * EigenSolver(const MatrixType&,bool) or the member function
-      * compute(const MatrixType&, bool) has been called before, and
-      * \p computeEigenvectors was set to true (the default).
-      *
-      * The real matrix \f$ V \f$ returned by this function and the
-      * block-diagonal matrix \f$ D \f$ returned by pseudoEigenvalueMatrix()
-      * satisfy \f$ AV = VD \f$.
-      *
-      * Example: \include EigenSolver_pseudoEigenvectors.cpp
-      * Output: \verbinclude EigenSolver_pseudoEigenvectors.out
-      *
-      * \sa pseudoEigenvalueMatrix(), eigenvectors()
-      */
-    const MatrixType& pseudoEigenvectors() const
-    {
-      eigen_assert(m_isInitialized && "EigenSolver is not initialized.");
-      eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues.");
-      return m_eivec;
-    }
-
-    /** \brief Returns the block-diagonal matrix in the pseudo-eigendecomposition.
-      *
-      * \returns  A block-diagonal matrix.
-      *
-      * \pre Either the constructor 
-      * EigenSolver(const MatrixType&,bool) or the member function
-      * compute(const MatrixType&, bool) has been called before.
-      *
-      * The matrix \f$ D \f$ returned by this function is real and
-      * block-diagonal. The blocks on the diagonal are either 1-by-1 or 2-by-2
-      * blocks of the form
-      * \f$ \begin{bmatrix} u & v \\ -v & u \end{bmatrix} \f$.
-      * These blocks are not sorted in any particular order.
-      * The matrix \f$ D \f$ and the matrix \f$ V \f$ returned by
-      * pseudoEigenvectors() satisfy \f$ AV = VD \f$.
-      *
-      * \sa pseudoEigenvectors() for an example, eigenvalues()
-      */
-    MatrixType pseudoEigenvalueMatrix() const;
-
-    /** \brief Returns the eigenvalues of given matrix. 
-      *
-      * \returns A const reference to the column vector containing the eigenvalues.
-      *
-      * \pre Either the constructor 
-      * EigenSolver(const MatrixType&,bool) or the member function
-      * compute(const MatrixType&, bool) has been called before.
-      *
-      * The eigenvalues are repeated according to their algebraic multiplicity,
-      * so there are as many eigenvalues as rows in the matrix. The eigenvalues 
-      * are not sorted in any particular order.
-      *
-      * Example: \include EigenSolver_eigenvalues.cpp
-      * Output: \verbinclude EigenSolver_eigenvalues.out
-      *
-      * \sa eigenvectors(), pseudoEigenvalueMatrix(),
-      *     MatrixBase::eigenvalues()
-      */
-    const EigenvalueType& eigenvalues() const
-    {
-      eigen_assert(m_isInitialized && "EigenSolver is not initialized.");
-      return m_eivalues;
-    }
-
-    /** \brief Computes eigendecomposition of given matrix. 
-      * 
-      * \param[in]  matrix  Square matrix whose eigendecomposition is to be computed.
-      * \param[in]  computeEigenvectors  If true, both the eigenvectors and the
-      *    eigenvalues are computed; if false, only the eigenvalues are
-      *    computed. 
-      * \returns    Reference to \c *this
-      *
-      * This function computes the eigenvalues of the real matrix \p matrix.
-      * The eigenvalues() function can be used to retrieve them.  If 
-      * \p computeEigenvectors is true, then the eigenvectors are also computed
-      * and can be retrieved by calling eigenvectors().
-      *
-      * The matrix is first reduced to real Schur form using the RealSchur
-      * class. The Schur decomposition is then used to compute the eigenvalues
-      * and eigenvectors.
-      *
-      * The cost of the computation is dominated by the cost of the
-      * Schur decomposition, which is very approximately \f$ 25n^3 \f$
-      * (where \f$ n \f$ is the size of the matrix) if \p computeEigenvectors 
-      * is true, and \f$ 10n^3 \f$ if \p computeEigenvectors is false.
-      *
-      * This method reuses of the allocated data in the EigenSolver object.
-      *
-      * Example: \include EigenSolver_compute.cpp
-      * Output: \verbinclude EigenSolver_compute.out
-      */
-    template<typename InputType>
-    EigenSolver& compute(const EigenBase<InputType>& matrix, bool computeEigenvectors = true);
-
-    /** \returns NumericalIssue if the input contains INF or NaN values or overflow occured. Returns Success otherwise. */
-    ComputationInfo info() const
-    {
-      eigen_assert(m_isInitialized && "EigenSolver is not initialized.");
-      return m_info;
-    }
-
-    /** \brief Sets the maximum number of iterations allowed. */
-    EigenSolver& setMaxIterations(Index maxIters)
-    {
-      m_realSchur.setMaxIterations(maxIters);
-      return *this;
-    }
-
-    /** \brief Returns the maximum number of iterations. */
-    Index getMaxIterations()
-    {
-      return m_realSchur.getMaxIterations();
-    }
-
-  private:
-    void doComputeEigenvectors();
-
-  protected:
-    
-    static void check_template_parameters()
-    {
-      EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
-      EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::IsComplex, NUMERIC_TYPE_MUST_BE_REAL);
-    }
-    
-    MatrixType m_eivec;
-    EigenvalueType m_eivalues;
-    bool m_isInitialized;
-    bool m_eigenvectorsOk;
-    ComputationInfo m_info;
-    RealSchur<MatrixType> m_realSchur;
-    MatrixType m_matT;
-
-    typedef Matrix<Scalar, ColsAtCompileTime, 1, Options & ~RowMajor, MaxColsAtCompileTime, 1> ColumnVectorType;
-    ColumnVectorType m_tmp;
-};
-
-template<typename MatrixType>
-MatrixType EigenSolver<MatrixType>::pseudoEigenvalueMatrix() const
-{
-  eigen_assert(m_isInitialized && "EigenSolver is not initialized.");
-  const RealScalar precision = RealScalar(2)*NumTraits<RealScalar>::epsilon();
-  Index n = m_eivalues.rows();
-  MatrixType matD = MatrixType::Zero(n,n);
-  for (Index i=0; i<n; ++i)
-  {
-    if (internal::isMuchSmallerThan(numext::imag(m_eivalues.coeff(i)), numext::real(m_eivalues.coeff(i)), precision))
-      matD.coeffRef(i,i) = numext::real(m_eivalues.coeff(i));
-    else
-    {
-      matD.template block<2,2>(i,i) <<  numext::real(m_eivalues.coeff(i)), numext::imag(m_eivalues.coeff(i)),
-                                       -numext::imag(m_eivalues.coeff(i)), numext::real(m_eivalues.coeff(i));
-      ++i;
-    }
-  }
-  return matD;
-}
-
-template<typename MatrixType>
-typename EigenSolver<MatrixType>::EigenvectorsType EigenSolver<MatrixType>::eigenvectors() const
-{
-  eigen_assert(m_isInitialized && "EigenSolver is not initialized.");
-  eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues.");
-  const RealScalar precision = RealScalar(2)*NumTraits<RealScalar>::epsilon();
-  Index n = m_eivec.cols();
-  EigenvectorsType matV(n,n);
-  for (Index j=0; j<n; ++j)
-  {
-    if (internal::isMuchSmallerThan(numext::imag(m_eivalues.coeff(j)), numext::real(m_eivalues.coeff(j)), precision) || j+1==n)
-    {
-      // we have a real eigen value
-      matV.col(j) = m_eivec.col(j).template cast<ComplexScalar>();
-      matV.col(j).normalize();
-    }
-    else
-    {
-      // we have a pair of complex eigen values
-      for (Index i=0; i<n; ++i)
-      {
-        matV.coeffRef(i,j)   = ComplexScalar(m_eivec.coeff(i,j),  m_eivec.coeff(i,j+1));
-        matV.coeffRef(i,j+1) = ComplexScalar(m_eivec.coeff(i,j), -m_eivec.coeff(i,j+1));
-      }
-      matV.col(j).normalize();
-      matV.col(j+1).normalize();
-      ++j;
-    }
-  }
-  return matV;
-}
-
-template<typename MatrixType>
-template<typename InputType>
-EigenSolver<MatrixType>& 
-EigenSolver<MatrixType>::compute(const EigenBase<InputType>& matrix, bool computeEigenvectors)
-{
-  check_template_parameters();
-  
-  using std::sqrt;
-  using std::abs;
-  using numext::isfinite;
-  eigen_assert(matrix.cols() == matrix.rows());
-
-  // Reduce to real Schur form.
-  m_realSchur.compute(matrix.derived(), computeEigenvectors);
-  
-  m_info = m_realSchur.info();
-
-  if (m_info == Success)
-  {
-    m_matT = m_realSchur.matrixT();
-    if (computeEigenvectors)
-      m_eivec = m_realSchur.matrixU();
-  
-    // Compute eigenvalues from matT
-    m_eivalues.resize(matrix.cols());
-    Index i = 0;
-    while (i < matrix.cols()) 
-    {
-      if (i == matrix.cols() - 1 || m_matT.coeff(i+1, i) == Scalar(0)) 
-      {
-        m_eivalues.coeffRef(i) = m_matT.coeff(i, i);
-        if(!(isfinite)(m_eivalues.coeffRef(i)))
-        {
-          m_isInitialized = true;
-          m_eigenvectorsOk = false;
-          m_info = NumericalIssue;
-          return *this;
-        }
-        ++i;
-      }
-      else
-      {
-        Scalar p = Scalar(0.5) * (m_matT.coeff(i, i) - m_matT.coeff(i+1, i+1));
-        Scalar z;
-        // Compute z = sqrt(abs(p * p + m_matT.coeff(i+1, i) * m_matT.coeff(i, i+1)));
-        // without overflow
-        {
-          Scalar t0 = m_matT.coeff(i+1, i);
-          Scalar t1 = m_matT.coeff(i, i+1);
-          Scalar maxval = numext::maxi<Scalar>(abs(p),numext::maxi<Scalar>(abs(t0),abs(t1)));
-          t0 /= maxval;
-          t1 /= maxval;
-          Scalar p0 = p/maxval;
-          z = maxval * sqrt(abs(p0 * p0 + t0 * t1));
-        }
-        
-        m_eivalues.coeffRef(i)   = ComplexScalar(m_matT.coeff(i+1, i+1) + p, z);
-        m_eivalues.coeffRef(i+1) = ComplexScalar(m_matT.coeff(i+1, i+1) + p, -z);
-        if(!((isfinite)(m_eivalues.coeffRef(i)) && (isfinite)(m_eivalues.coeffRef(i+1))))
-        {
-          m_isInitialized = true;
-          m_eigenvectorsOk = false;
-          m_info = NumericalIssue;
-          return *this;
-        }
-        i += 2;
-      }
-    }
-    
-    // Compute eigenvectors.
-    if (computeEigenvectors)
-      doComputeEigenvectors();
-  }
-
-  m_isInitialized = true;
-  m_eigenvectorsOk = computeEigenvectors;
-
-  return *this;
-}
-
-
-template<typename MatrixType>
-void EigenSolver<MatrixType>::doComputeEigenvectors()
-{
-  using std::abs;
-  const Index size = m_eivec.cols();
-  const Scalar eps = NumTraits<Scalar>::epsilon();
-
-  // inefficient! this is already computed in RealSchur
-  Scalar norm(0);
-  for (Index j = 0; j < size; ++j)
-  {
-    norm += m_matT.row(j).segment((std::max)(j-1,Index(0)), size-(std::max)(j-1,Index(0))).cwiseAbs().sum();
-  }
-  
-  // Backsubstitute to find vectors of upper triangular form
-  if (norm == Scalar(0))
-  {
-    return;
-  }
-
-  for (Index n = size-1; n >= 0; n--)
-  {
-    Scalar p = m_eivalues.coeff(n).real();
-    Scalar q = m_eivalues.coeff(n).imag();
-
-    // Scalar vector
-    if (q == Scalar(0))
-    {
-      Scalar lastr(0), lastw(0);
-      Index l = n;
-
-      m_matT.coeffRef(n,n) = Scalar(1);
-      for (Index i = n-1; i >= 0; i--)
-      {
-        Scalar w = m_matT.coeff(i,i) - p;
-        Scalar r = m_matT.row(i).segment(l,n-l+1).dot(m_matT.col(n).segment(l, n-l+1));
-
-        if (m_eivalues.coeff(i).imag() < Scalar(0))
-        {
-          lastw = w;
-          lastr = r;
-        }
-        else
-        {
-          l = i;
-          if (m_eivalues.coeff(i).imag() == Scalar(0))
-          {
-            if (w != Scalar(0))
-              m_matT.coeffRef(i,n) = -r / w;
-            else
-              m_matT.coeffRef(i,n) = -r / (eps * norm);
-          }
-          else // Solve real equations
-          {
-            Scalar x = m_matT.coeff(i,i+1);
-            Scalar y = m_matT.coeff(i+1,i);
-            Scalar denom = (m_eivalues.coeff(i).real() - p) * (m_eivalues.coeff(i).real() - p) + m_eivalues.coeff(i).imag() * m_eivalues.coeff(i).imag();
-            Scalar t = (x * lastr - lastw * r) / denom;
-            m_matT.coeffRef(i,n) = t;
-            if (abs(x) > abs(lastw))
-              m_matT.coeffRef(i+1,n) = (-r - w * t) / x;
-            else
-              m_matT.coeffRef(i+1,n) = (-lastr - y * t) / lastw;
-          }
-
-          // Overflow control
-          Scalar t = abs(m_matT.coeff(i,n));
-          if ((eps * t) * t > Scalar(1))
-            m_matT.col(n).tail(size-i) /= t;
-        }
-      }
-    }
-    else if (q < Scalar(0) && n > 0) // Complex vector
-    {
-      Scalar lastra(0), lastsa(0), lastw(0);
-      Index l = n-1;
-
-      // Last vector component imaginary so matrix is triangular
-      if (abs(m_matT.coeff(n,n-1)) > abs(m_matT.coeff(n-1,n)))
-      {
-        m_matT.coeffRef(n-1,n-1) = q / m_matT.coeff(n,n-1);
-        m_matT.coeffRef(n-1,n) = -(m_matT.coeff(n,n) - p) / m_matT.coeff(n,n-1);
-      }
-      else
-      {
-        ComplexScalar cc = ComplexScalar(Scalar(0),-m_matT.coeff(n-1,n)) / ComplexScalar(m_matT.coeff(n-1,n-1)-p,q);
-        m_matT.coeffRef(n-1,n-1) = numext::real(cc);
-        m_matT.coeffRef(n-1,n) = numext::imag(cc);
-      }
-      m_matT.coeffRef(n,n-1) = Scalar(0);
-      m_matT.coeffRef(n,n) = Scalar(1);
-      for (Index i = n-2; i >= 0; i--)
-      {
-        Scalar ra = m_matT.row(i).segment(l, n-l+1).dot(m_matT.col(n-1).segment(l, n-l+1));
-        Scalar sa = m_matT.row(i).segment(l, n-l+1).dot(m_matT.col(n).segment(l, n-l+1));
-        Scalar w = m_matT.coeff(i,i) - p;
-
-        if (m_eivalues.coeff(i).imag() < Scalar(0))
-        {
-          lastw = w;
-          lastra = ra;
-          lastsa = sa;
-        }
-        else
-        {
-          l = i;
-          if (m_eivalues.coeff(i).imag() == RealScalar(0))
-          {
-            ComplexScalar cc = ComplexScalar(-ra,-sa) / ComplexScalar(w,q);
-            m_matT.coeffRef(i,n-1) = numext::real(cc);
-            m_matT.coeffRef(i,n) = numext::imag(cc);
-          }
-          else
-          {
-            // Solve complex equations
-            Scalar x = m_matT.coeff(i,i+1);
-            Scalar y = m_matT.coeff(i+1,i);
-            Scalar vr = (m_eivalues.coeff(i).real() - p) * (m_eivalues.coeff(i).real() - p) + m_eivalues.coeff(i).imag() * m_eivalues.coeff(i).imag() - q * q;
-            Scalar vi = (m_eivalues.coeff(i).real() - p) * Scalar(2) * q;
-            if ((vr == Scalar(0)) && (vi == Scalar(0)))
-              vr = eps * norm * (abs(w) + abs(q) + abs(x) + abs(y) + abs(lastw));
-
-            ComplexScalar cc = ComplexScalar(x*lastra-lastw*ra+q*sa,x*lastsa-lastw*sa-q*ra) / ComplexScalar(vr,vi);
-            m_matT.coeffRef(i,n-1) = numext::real(cc);
-            m_matT.coeffRef(i,n) = numext::imag(cc);
-            if (abs(x) > (abs(lastw) + abs(q)))
-            {
-              m_matT.coeffRef(i+1,n-1) = (-ra - w * m_matT.coeff(i,n-1) + q * m_matT.coeff(i,n)) / x;
-              m_matT.coeffRef(i+1,n) = (-sa - w * m_matT.coeff(i,n) - q * m_matT.coeff(i,n-1)) / x;
-            }
-            else
-            {
-              cc = ComplexScalar(-lastra-y*m_matT.coeff(i,n-1),-lastsa-y*m_matT.coeff(i,n)) / ComplexScalar(lastw,q);
-              m_matT.coeffRef(i+1,n-1) = numext::real(cc);
-              m_matT.coeffRef(i+1,n) = numext::imag(cc);
-            }
-          }
-
-          // Overflow control
-          Scalar t = numext::maxi<Scalar>(abs(m_matT.coeff(i,n-1)),abs(m_matT.coeff(i,n)));
-          if ((eps * t) * t > Scalar(1))
-            m_matT.block(i, n-1, size-i, 2) /= t;
-
-        }
-      }
-      
-      // We handled a pair of complex conjugate eigenvalues, so need to skip them both
-      n--;
-    }
-    else
-    {
-      eigen_assert(0 && "Internal bug in EigenSolver (INF or NaN has not been detected)"); // this should not happen
-    }
-  }
-
-  // Back transformation to get eigenvectors of original matrix
-  for (Index j = size-1; j >= 0; j--)
-  {
-    m_tmp.noalias() = m_eivec.leftCols(j+1) * m_matT.col(j).segment(0, j+1);
-    m_eivec.col(j) = m_tmp;
-  }
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_EIGENSOLVER_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h
deleted file mode 100644
index 87d789b..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h
+++ /dev/null
@@ -1,418 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2012-2016 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2010,2012 Jitse Niesen <jitse@maths.leeds.ac.uk>
-// Copyright (C) 2016 Tobias Wood <tobias@spinicist.org.uk>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_GENERALIZEDEIGENSOLVER_H
-#define EIGEN_GENERALIZEDEIGENSOLVER_H
-
-#include "./RealQZ.h"
-
-namespace Eigen { 
-
-/** \eigenvalues_module \ingroup Eigenvalues_Module
-  *
-  *
-  * \class GeneralizedEigenSolver
-  *
-  * \brief Computes the generalized eigenvalues and eigenvectors of a pair of general matrices
-  *
-  * \tparam _MatrixType the type of the matrices of which we are computing the
-  * eigen-decomposition; this is expected to be an instantiation of the Matrix
-  * class template. Currently, only real matrices are supported.
-  *
-  * The generalized eigenvalues and eigenvectors of a matrix pair \f$ A \f$ and \f$ B \f$ are scalars
-  * \f$ \lambda \f$ and vectors \f$ v \f$ such that \f$ Av = \lambda Bv \f$.  If
-  * \f$ D \f$ is a diagonal matrix with the eigenvalues on the diagonal, and
-  * \f$ V \f$ is a matrix with the eigenvectors as its columns, then \f$ A V =
-  * B V D \f$. The matrix \f$ V \f$ is almost always invertible, in which case we
-  * have \f$ A = B V D V^{-1} \f$. This is called the generalized eigen-decomposition.
-  *
-  * The generalized eigenvalues and eigenvectors of a matrix pair may be complex, even when the
-  * matrices are real. Moreover, the generalized eigenvalue might be infinite if the matrix B is
-  * singular. To workaround this difficulty, the eigenvalues are provided as a pair of complex \f$ \alpha \f$
-  * and real \f$ \beta \f$ such that: \f$ \lambda_i = \alpha_i / \beta_i \f$. If \f$ \beta_i \f$ is (nearly) zero,
-  * then one can consider the well defined left eigenvalue \f$ \mu = \beta_i / \alpha_i\f$ such that:
-  * \f$ \mu_i A v_i = B v_i \f$, or even \f$ \mu_i u_i^T A  = u_i^T B \f$ where \f$ u_i \f$ is
-  * called the left eigenvector.
-  *
-  * Call the function compute() to compute the generalized eigenvalues and eigenvectors of
-  * a given matrix pair. Alternatively, you can use the
-  * GeneralizedEigenSolver(const MatrixType&, const MatrixType&, bool) constructor which computes the
-  * eigenvalues and eigenvectors at construction time. Once the eigenvalue and
-  * eigenvectors are computed, they can be retrieved with the eigenvalues() and
-  * eigenvectors() functions.
-  *
-  * Here is an usage example of this class:
-  * Example: \include GeneralizedEigenSolver.cpp
-  * Output: \verbinclude GeneralizedEigenSolver.out
-  *
-  * \sa MatrixBase::eigenvalues(), class ComplexEigenSolver, class SelfAdjointEigenSolver
-  */
-template<typename _MatrixType> class GeneralizedEigenSolver
-{
-  public:
-
-    /** \brief Synonym for the template parameter \p _MatrixType. */
-    typedef _MatrixType MatrixType;
-
-    enum {
-      RowsAtCompileTime = MatrixType::RowsAtCompileTime,
-      ColsAtCompileTime = MatrixType::ColsAtCompileTime,
-      Options = MatrixType::Options,
-      MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
-      MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
-    };
-
-    /** \brief Scalar type for matrices of type #MatrixType. */
-    typedef typename MatrixType::Scalar Scalar;
-    typedef typename NumTraits<Scalar>::Real RealScalar;
-    typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
-
-    /** \brief Complex scalar type for #MatrixType. 
-      *
-      * This is \c std::complex<Scalar> if #Scalar is real (e.g.,
-      * \c float or \c double) and just \c Scalar if #Scalar is
-      * complex.
-      */
-    typedef std::complex<RealScalar> ComplexScalar;
-
-    /** \brief Type for vector of real scalar values eigenvalues as returned by betas().
-      *
-      * This is a column vector with entries of type #Scalar.
-      * The length of the vector is the size of #MatrixType.
-      */
-    typedef Matrix<Scalar, ColsAtCompileTime, 1, Options & ~RowMajor, MaxColsAtCompileTime, 1> VectorType;
-
-    /** \brief Type for vector of complex scalar values eigenvalues as returned by alphas().
-      *
-      * This is a column vector with entries of type #ComplexScalar.
-      * The length of the vector is the size of #MatrixType.
-      */
-    typedef Matrix<ComplexScalar, ColsAtCompileTime, 1, Options & ~RowMajor, MaxColsAtCompileTime, 1> ComplexVectorType;
-
-    /** \brief Expression type for the eigenvalues as returned by eigenvalues().
-      */
-    typedef CwiseBinaryOp<internal::scalar_quotient_op<ComplexScalar,Scalar>,ComplexVectorType,VectorType> EigenvalueType;
-
-    /** \brief Type for matrix of eigenvectors as returned by eigenvectors(). 
-      *
-      * This is a square matrix with entries of type #ComplexScalar. 
-      * The size is the same as the size of #MatrixType.
-      */
-    typedef Matrix<ComplexScalar, RowsAtCompileTime, ColsAtCompileTime, Options, MaxRowsAtCompileTime, MaxColsAtCompileTime> EigenvectorsType;
-
-    /** \brief Default constructor.
-      *
-      * The default constructor is useful in cases in which the user intends to
-      * perform decompositions via EigenSolver::compute(const MatrixType&, bool).
-      *
-      * \sa compute() for an example.
-      */
-    GeneralizedEigenSolver()
-      : m_eivec(),
-        m_alphas(),
-        m_betas(),
-        m_valuesOkay(false),
-        m_vectorsOkay(false),
-        m_realQZ()
-    {}
-
-    /** \brief Default constructor with memory preallocation
-      *
-      * Like the default constructor but with preallocation of the internal data
-      * according to the specified problem \a size.
-      * \sa GeneralizedEigenSolver()
-      */
-    explicit GeneralizedEigenSolver(Index size)
-      : m_eivec(size, size),
-        m_alphas(size),
-        m_betas(size),
-        m_valuesOkay(false),
-        m_vectorsOkay(false),
-        m_realQZ(size),
-        m_tmp(size)
-    {}
-
-    /** \brief Constructor; computes the generalized eigendecomposition of given matrix pair.
-      * 
-      * \param[in]  A  Square matrix whose eigendecomposition is to be computed.
-      * \param[in]  B  Square matrix whose eigendecomposition is to be computed.
-      * \param[in]  computeEigenvectors  If true, both the eigenvectors and the
-      *    eigenvalues are computed; if false, only the eigenvalues are computed.
-      *
-      * This constructor calls compute() to compute the generalized eigenvalues
-      * and eigenvectors.
-      *
-      * \sa compute()
-      */
-    GeneralizedEigenSolver(const MatrixType& A, const MatrixType& B, bool computeEigenvectors = true)
-      : m_eivec(A.rows(), A.cols()),
-        m_alphas(A.cols()),
-        m_betas(A.cols()),
-        m_valuesOkay(false),
-        m_vectorsOkay(false),
-        m_realQZ(A.cols()),
-        m_tmp(A.cols())
-    {
-      compute(A, B, computeEigenvectors);
-    }
-
-    /* \brief Returns the computed generalized eigenvectors.
-      *
-      * \returns  %Matrix whose columns are the (possibly complex) right eigenvectors.
-      * i.e. the eigenvectors that solve (A - l*B)x = 0. The ordering matches the eigenvalues.
-      *
-      * \pre Either the constructor 
-      * GeneralizedEigenSolver(const MatrixType&,const MatrixType&, bool) or the member function
-      * compute(const MatrixType&, const MatrixType& bool) has been called before, and
-      * \p computeEigenvectors was set to true (the default).
-      *
-      * \sa eigenvalues()
-      */
-    EigenvectorsType eigenvectors() const {
-      eigen_assert(m_vectorsOkay && "Eigenvectors for GeneralizedEigenSolver were not calculated.");
-      return m_eivec;
-    }
-
-    /** \brief Returns an expression of the computed generalized eigenvalues.
-      *
-      * \returns An expression of the column vector containing the eigenvalues.
-      *
-      * It is a shortcut for \code this->alphas().cwiseQuotient(this->betas()); \endcode
-      * Not that betas might contain zeros. It is therefore not recommended to use this function,
-      * but rather directly deal with the alphas and betas vectors.
-      *
-      * \pre Either the constructor 
-      * GeneralizedEigenSolver(const MatrixType&,const MatrixType&,bool) or the member function
-      * compute(const MatrixType&,const MatrixType&,bool) has been called before.
-      *
-      * The eigenvalues are repeated according to their algebraic multiplicity,
-      * so there are as many eigenvalues as rows in the matrix. The eigenvalues 
-      * are not sorted in any particular order.
-      *
-      * \sa alphas(), betas(), eigenvectors()
-      */
-    EigenvalueType eigenvalues() const
-    {
-      eigen_assert(m_valuesOkay && "GeneralizedEigenSolver is not initialized.");
-      return EigenvalueType(m_alphas,m_betas);
-    }
-
-    /** \returns A const reference to the vectors containing the alpha values
-      *
-      * This vector permits to reconstruct the j-th eigenvalues as alphas(i)/betas(j).
-      *
-      * \sa betas(), eigenvalues() */
-    ComplexVectorType alphas() const
-    {
-      eigen_assert(m_valuesOkay && "GeneralizedEigenSolver is not initialized.");
-      return m_alphas;
-    }
-
-    /** \returns A const reference to the vectors containing the beta values
-      *
-      * This vector permits to reconstruct the j-th eigenvalues as alphas(i)/betas(j).
-      *
-      * \sa alphas(), eigenvalues() */
-    VectorType betas() const
-    {
-      eigen_assert(m_valuesOkay && "GeneralizedEigenSolver is not initialized.");
-      return m_betas;
-    }
-
-    /** \brief Computes generalized eigendecomposition of given matrix.
-      * 
-      * \param[in]  A  Square matrix whose eigendecomposition is to be computed.
-      * \param[in]  B  Square matrix whose eigendecomposition is to be computed.
-      * \param[in]  computeEigenvectors  If true, both the eigenvectors and the
-      *    eigenvalues are computed; if false, only the eigenvalues are
-      *    computed. 
-      * \returns    Reference to \c *this
-      *
-      * This function computes the eigenvalues of the real matrix \p matrix.
-      * The eigenvalues() function can be used to retrieve them.  If 
-      * \p computeEigenvectors is true, then the eigenvectors are also computed
-      * and can be retrieved by calling eigenvectors().
-      *
-      * The matrix is first reduced to real generalized Schur form using the RealQZ
-      * class. The generalized Schur decomposition is then used to compute the eigenvalues
-      * and eigenvectors.
-      *
-      * The cost of the computation is dominated by the cost of the
-      * generalized Schur decomposition.
-      *
-      * This method reuses of the allocated data in the GeneralizedEigenSolver object.
-      */
-    GeneralizedEigenSolver& compute(const MatrixType& A, const MatrixType& B, bool computeEigenvectors = true);
-
-    ComputationInfo info() const
-    {
-      eigen_assert(m_valuesOkay && "EigenSolver is not initialized.");
-      return m_realQZ.info();
-    }
-
-    /** Sets the maximal number of iterations allowed.
-    */
-    GeneralizedEigenSolver& setMaxIterations(Index maxIters)
-    {
-      m_realQZ.setMaxIterations(maxIters);
-      return *this;
-    }
-
-  protected:
-    
-    static void check_template_parameters()
-    {
-      EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
-      EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::IsComplex, NUMERIC_TYPE_MUST_BE_REAL);
-    }
-    
-    EigenvectorsType m_eivec;
-    ComplexVectorType m_alphas;
-    VectorType m_betas;
-    bool m_valuesOkay, m_vectorsOkay;
-    RealQZ<MatrixType> m_realQZ;
-    ComplexVectorType m_tmp;
-};
-
-template<typename MatrixType>
-GeneralizedEigenSolver<MatrixType>&
-GeneralizedEigenSolver<MatrixType>::compute(const MatrixType& A, const MatrixType& B, bool computeEigenvectors)
-{
-  check_template_parameters();
-  
-  using std::sqrt;
-  using std::abs;
-  eigen_assert(A.cols() == A.rows() && B.cols() == A.rows() && B.cols() == B.rows());
-  Index size = A.cols();
-  m_valuesOkay = false;
-  m_vectorsOkay = false;
-  // Reduce to generalized real Schur form:
-  // A = Q S Z and B = Q T Z
-  m_realQZ.compute(A, B, computeEigenvectors);
-  if (m_realQZ.info() == Success)
-  {
-    // Resize storage
-    m_alphas.resize(size);
-    m_betas.resize(size);
-    if (computeEigenvectors)
-    {
-      m_eivec.resize(size,size);
-      m_tmp.resize(size);
-    }
-
-    // Aliases:
-    Map<VectorType> v(reinterpret_cast<Scalar*>(m_tmp.data()), size);
-    ComplexVectorType &cv = m_tmp;
-    const MatrixType &mS = m_realQZ.matrixS();
-    const MatrixType &mT = m_realQZ.matrixT();
-
-    Index i = 0;
-    while (i < size)
-    {
-      if (i == size - 1 || mS.coeff(i+1, i) == Scalar(0))
-      {
-        // Real eigenvalue
-        m_alphas.coeffRef(i) = mS.diagonal().coeff(i);
-        m_betas.coeffRef(i)  = mT.diagonal().coeff(i);
-        if (computeEigenvectors)
-        {
-          v.setConstant(Scalar(0.0));
-          v.coeffRef(i) = Scalar(1.0);
-          // For singular eigenvalues do nothing more
-          if(abs(m_betas.coeffRef(i)) >= (std::numeric_limits<RealScalar>::min)())
-          {
-            // Non-singular eigenvalue
-            const Scalar alpha = real(m_alphas.coeffRef(i));
-            const Scalar beta = m_betas.coeffRef(i);
-            for (Index j = i-1; j >= 0; j--)
-            {
-              const Index st = j+1;
-              const Index sz = i-j;
-              if (j > 0 && mS.coeff(j, j-1) != Scalar(0))
-              {
-                // 2x2 block
-                Matrix<Scalar, 2, 1> rhs = (alpha*mT.template block<2,Dynamic>(j-1,st,2,sz) - beta*mS.template block<2,Dynamic>(j-1,st,2,sz)) .lazyProduct( v.segment(st,sz) );
-                Matrix<Scalar, 2, 2> lhs = beta * mS.template block<2,2>(j-1,j-1) - alpha * mT.template block<2,2>(j-1,j-1);
-                v.template segment<2>(j-1) = lhs.partialPivLu().solve(rhs);
-                j--;
-              }
-              else
-              {
-                v.coeffRef(j) = -v.segment(st,sz).transpose().cwiseProduct(beta*mS.block(j,st,1,sz) - alpha*mT.block(j,st,1,sz)).sum() / (beta*mS.coeffRef(j,j) - alpha*mT.coeffRef(j,j));
-              }
-            }
-          }
-          m_eivec.col(i).real().noalias() = m_realQZ.matrixZ().transpose() * v;
-          m_eivec.col(i).real().normalize();
-          m_eivec.col(i).imag().setConstant(0);
-        }
-        ++i;
-      }
-      else
-      {
-        // We need to extract the generalized eigenvalues of the pair of a general 2x2 block S and a positive diagonal 2x2 block T
-        // Then taking beta=T_00*T_11, we can avoid any division, and alpha is the eigenvalues of A = (U^-1 * S * U) * diag(T_11,T_00):
-
-        // T =  [a 0]
-        //      [0 b]
-        RealScalar a = mT.diagonal().coeff(i),
-                   b = mT.diagonal().coeff(i+1);
-        const RealScalar beta = m_betas.coeffRef(i) = m_betas.coeffRef(i+1) = a*b;
-
-        // ^^ NOTE: using diagonal()(i) instead of coeff(i,i) workarounds a MSVC bug.
-        Matrix<RealScalar,2,2> S2 = mS.template block<2,2>(i,i) * Matrix<Scalar,2,1>(b,a).asDiagonal();
-
-        Scalar p = Scalar(0.5) * (S2.coeff(0,0) - S2.coeff(1,1));
-        Scalar z = sqrt(abs(p * p + S2.coeff(1,0) * S2.coeff(0,1)));
-        const ComplexScalar alpha = ComplexScalar(S2.coeff(1,1) + p, (beta > 0) ? z : -z);
-        m_alphas.coeffRef(i)   = conj(alpha);
-        m_alphas.coeffRef(i+1) = alpha;
-
-        if (computeEigenvectors) {
-          // Compute eigenvector in position (i+1) and then position (i) is just the conjugate
-          cv.setZero();
-          cv.coeffRef(i+1) = Scalar(1.0);
-          // here, the "static_cast" workaound expression template issues.
-          cv.coeffRef(i) = -(static_cast<Scalar>(beta*mS.coeffRef(i,i+1)) - alpha*mT.coeffRef(i,i+1))
-                          / (static_cast<Scalar>(beta*mS.coeffRef(i,i))   - alpha*mT.coeffRef(i,i));
-          for (Index j = i-1; j >= 0; j--)
-          {
-            const Index st = j+1;
-            const Index sz = i+1-j;
-            if (j > 0 && mS.coeff(j, j-1) != Scalar(0))
-            {
-              // 2x2 block
-              Matrix<ComplexScalar, 2, 1> rhs = (alpha*mT.template block<2,Dynamic>(j-1,st,2,sz) - beta*mS.template block<2,Dynamic>(j-1,st,2,sz)) .lazyProduct( cv.segment(st,sz) );
-              Matrix<ComplexScalar, 2, 2> lhs = beta * mS.template block<2,2>(j-1,j-1) - alpha * mT.template block<2,2>(j-1,j-1);
-              cv.template segment<2>(j-1) = lhs.partialPivLu().solve(rhs);
-              j--;
-            } else {
-              cv.coeffRef(j) =  cv.segment(st,sz).transpose().cwiseProduct(beta*mS.block(j,st,1,sz) - alpha*mT.block(j,st,1,sz)).sum()
-                              / (alpha*mT.coeffRef(j,j) - static_cast<Scalar>(beta*mS.coeffRef(j,j)));
-            }
-          }
-          m_eivec.col(i+1).noalias() = (m_realQZ.matrixZ().transpose() * cv);
-          m_eivec.col(i+1).normalize();
-          m_eivec.col(i) = m_eivec.col(i+1).conjugate();
-        }
-        i += 2;
-      }
-    }
-
-    m_valuesOkay = true;
-    m_vectorsOkay = computeEigenvectors;
-  }
-  return *this;
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_GENERALIZEDEIGENSOLVER_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h
deleted file mode 100644
index 5f6bb82..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h
+++ /dev/null
@@ -1,226 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_GENERALIZEDSELFADJOINTEIGENSOLVER_H
-#define EIGEN_GENERALIZEDSELFADJOINTEIGENSOLVER_H
-
-#include "./Tridiagonalization.h"
-
-namespace Eigen { 
-
-/** \eigenvalues_module \ingroup Eigenvalues_Module
-  *
-  *
-  * \class GeneralizedSelfAdjointEigenSolver
-  *
-  * \brief Computes eigenvalues and eigenvectors of the generalized selfadjoint eigen problem
-  *
-  * \tparam _MatrixType the type of the matrix of which we are computing the
-  * eigendecomposition; this is expected to be an instantiation of the Matrix
-  * class template.
-  *
-  * This class solves the generalized eigenvalue problem
-  * \f$ Av = \lambda Bv \f$. In this case, the matrix \f$ A \f$ should be
-  * selfadjoint and the matrix \f$ B \f$ should be positive definite.
-  *
-  * Only the \b lower \b triangular \b part of the input matrix is referenced.
-  *
-  * Call the function compute() to compute the eigenvalues and eigenvectors of
-  * a given matrix. Alternatively, you can use the
-  * GeneralizedSelfAdjointEigenSolver(const MatrixType&, const MatrixType&, int)
-  * constructor which computes the eigenvalues and eigenvectors at construction time.
-  * Once the eigenvalue and eigenvectors are computed, they can be retrieved with the eigenvalues()
-  * and eigenvectors() functions.
-  *
-  * The documentation for GeneralizedSelfAdjointEigenSolver(const MatrixType&, const MatrixType&, int)
-  * contains an example of the typical use of this class.
-  *
-  * \sa class SelfAdjointEigenSolver, class EigenSolver, class ComplexEigenSolver
-  */
-template<typename _MatrixType>
-class GeneralizedSelfAdjointEigenSolver : public SelfAdjointEigenSolver<_MatrixType>
-{
-    typedef SelfAdjointEigenSolver<_MatrixType> Base;
-  public:
-
-    typedef _MatrixType MatrixType;
-
-    /** \brief Default constructor for fixed-size matrices.
-      *
-      * The default constructor is useful in cases in which the user intends to
-      * perform decompositions via compute(). This constructor
-      * can only be used if \p _MatrixType is a fixed-size matrix; use
-      * GeneralizedSelfAdjointEigenSolver(Index) for dynamic-size matrices.
-      */
-    GeneralizedSelfAdjointEigenSolver() : Base() {}
-
-    /** \brief Constructor, pre-allocates memory for dynamic-size matrices.
-      *
-      * \param [in]  size  Positive integer, size of the matrix whose
-      * eigenvalues and eigenvectors will be computed.
-      *
-      * This constructor is useful for dynamic-size matrices, when the user
-      * intends to perform decompositions via compute(). The \p size
-      * parameter is only used as a hint. It is not an error to give a wrong
-      * \p size, but it may impair performance.
-      *
-      * \sa compute() for an example
-      */
-    explicit GeneralizedSelfAdjointEigenSolver(Index size)
-        : Base(size)
-    {}
-
-    /** \brief Constructor; computes generalized eigendecomposition of given matrix pencil.
-      *
-      * \param[in]  matA  Selfadjoint matrix in matrix pencil.
-      *                   Only the lower triangular part of the matrix is referenced.
-      * \param[in]  matB  Positive-definite matrix in matrix pencil.
-      *                   Only the lower triangular part of the matrix is referenced.
-      * \param[in]  options A or-ed set of flags {#ComputeEigenvectors,#EigenvaluesOnly} | {#Ax_lBx,#ABx_lx,#BAx_lx}.
-      *                     Default is #ComputeEigenvectors|#Ax_lBx.
-      *
-      * This constructor calls compute(const MatrixType&, const MatrixType&, int)
-      * to compute the eigenvalues and (if requested) the eigenvectors of the
-      * generalized eigenproblem \f$ Ax = \lambda B x \f$ with \a matA the
-      * selfadjoint matrix \f$ A \f$ and \a matB the positive definite matrix
-      * \f$ B \f$. Each eigenvector \f$ x \f$ satisfies the property
-      * \f$ x^* B x = 1 \f$. The eigenvectors are computed if
-      * \a options contains ComputeEigenvectors.
-      *
-      * In addition, the two following variants can be solved via \p options:
-      * - \c ABx_lx: \f$ ABx = \lambda x \f$
-      * - \c BAx_lx: \f$ BAx = \lambda x \f$
-      *
-      * Example: \include SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType2.cpp
-      * Output: \verbinclude SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType2.out
-      *
-      * \sa compute(const MatrixType&, const MatrixType&, int)
-      */
-    GeneralizedSelfAdjointEigenSolver(const MatrixType& matA, const MatrixType& matB,
-                                      int options = ComputeEigenvectors|Ax_lBx)
-      : Base(matA.cols())
-    {
-      compute(matA, matB, options);
-    }
-
-    /** \brief Computes generalized eigendecomposition of given matrix pencil.
-      *
-      * \param[in]  matA  Selfadjoint matrix in matrix pencil.
-      *                   Only the lower triangular part of the matrix is referenced.
-      * \param[in]  matB  Positive-definite matrix in matrix pencil.
-      *                   Only the lower triangular part of the matrix is referenced.
-      * \param[in]  options A or-ed set of flags {#ComputeEigenvectors,#EigenvaluesOnly} | {#Ax_lBx,#ABx_lx,#BAx_lx}.
-      *                     Default is #ComputeEigenvectors|#Ax_lBx.
-      *
-      * \returns    Reference to \c *this
-      *
-      * Accoring to \p options, this function computes eigenvalues and (if requested)
-      * the eigenvectors of one of the following three generalized eigenproblems:
-      * - \c Ax_lBx: \f$ Ax = \lambda B x \f$
-      * - \c ABx_lx: \f$ ABx = \lambda x \f$
-      * - \c BAx_lx: \f$ BAx = \lambda x \f$
-      * with \a matA the selfadjoint matrix \f$ A \f$ and \a matB the positive definite
-      * matrix \f$ B \f$.
-      * In addition, each eigenvector \f$ x \f$ satisfies the property \f$ x^* B x = 1 \f$.
-      *
-      * The eigenvalues() function can be used to retrieve
-      * the eigenvalues. If \p options contains ComputeEigenvectors, then the
-      * eigenvectors are also computed and can be retrieved by calling
-      * eigenvectors().
-      *
-      * The implementation uses LLT to compute the Cholesky decomposition
-      * \f$ B = LL^* \f$ and computes the classical eigendecomposition
-      * of the selfadjoint matrix \f$ L^{-1} A (L^*)^{-1} \f$ if \p options contains Ax_lBx
-      * and of \f$ L^{*} A L \f$ otherwise. This solves the
-      * generalized eigenproblem, because any solution of the generalized
-      * eigenproblem \f$ Ax = \lambda B x \f$ corresponds to a solution
-      * \f$ L^{-1} A (L^*)^{-1} (L^* x) = \lambda (L^* x) \f$ of the
-      * eigenproblem for \f$ L^{-1} A (L^*)^{-1} \f$. Similar statements
-      * can be made for the two other variants.
-      *
-      * Example: \include SelfAdjointEigenSolver_compute_MatrixType2.cpp
-      * Output: \verbinclude SelfAdjointEigenSolver_compute_MatrixType2.out
-      *
-      * \sa GeneralizedSelfAdjointEigenSolver(const MatrixType&, const MatrixType&, int)
-      */
-    GeneralizedSelfAdjointEigenSolver& compute(const MatrixType& matA, const MatrixType& matB,
-                                               int options = ComputeEigenvectors|Ax_lBx);
-
-  protected:
-
-};
-
-
-template<typename MatrixType>
-GeneralizedSelfAdjointEigenSolver<MatrixType>& GeneralizedSelfAdjointEigenSolver<MatrixType>::
-compute(const MatrixType& matA, const MatrixType& matB, int options)
-{
-  eigen_assert(matA.cols()==matA.rows() && matB.rows()==matA.rows() && matB.cols()==matB.rows());
-  eigen_assert((options&~(EigVecMask|GenEigMask))==0
-          && (options&EigVecMask)!=EigVecMask
-          && ((options&GenEigMask)==0 || (options&GenEigMask)==Ax_lBx
-           || (options&GenEigMask)==ABx_lx || (options&GenEigMask)==BAx_lx)
-          && "invalid option parameter");
-
-  bool computeEigVecs = ((options&EigVecMask)==0) || ((options&EigVecMask)==ComputeEigenvectors);
-
-  // Compute the cholesky decomposition of matB = L L' = U'U
-  LLT<MatrixType> cholB(matB);
-
-  int type = (options&GenEigMask);
-  if(type==0)
-    type = Ax_lBx;
-
-  if(type==Ax_lBx)
-  {
-    // compute C = inv(L) A inv(L')
-    MatrixType matC = matA.template selfadjointView<Lower>();
-    cholB.matrixL().template solveInPlace<OnTheLeft>(matC);
-    cholB.matrixU().template solveInPlace<OnTheRight>(matC);
-
-    Base::compute(matC, computeEigVecs ? ComputeEigenvectors : EigenvaluesOnly );
-
-    // transform back the eigen vectors: evecs = inv(U) * evecs
-    if(computeEigVecs)
-      cholB.matrixU().solveInPlace(Base::m_eivec);
-  }
-  else if(type==ABx_lx)
-  {
-    // compute C = L' A L
-    MatrixType matC = matA.template selfadjointView<Lower>();
-    matC = matC * cholB.matrixL();
-    matC = cholB.matrixU() * matC;
-
-    Base::compute(matC, computeEigVecs ? ComputeEigenvectors : EigenvaluesOnly);
-
-    // transform back the eigen vectors: evecs = inv(U) * evecs
-    if(computeEigVecs)
-      cholB.matrixU().solveInPlace(Base::m_eivec);
-  }
-  else if(type==BAx_lx)
-  {
-    // compute C = L' A L
-    MatrixType matC = matA.template selfadjointView<Lower>();
-    matC = matC * cholB.matrixL();
-    matC = cholB.matrixU() * matC;
-
-    Base::compute(matC, computeEigVecs ? ComputeEigenvectors : EigenvaluesOnly);
-
-    // transform back the eigen vectors: evecs = L * evecs
-    if(computeEigVecs)
-      Base::m_eivec = cholB.matrixL() * Base::m_eivec;
-  }
-
-  return *this;
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_GENERALIZEDSELFADJOINTEIGENSOLVER_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/HessenbergDecomposition.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/HessenbergDecomposition.h
deleted file mode 100644
index f647f69..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/HessenbergDecomposition.h
+++ /dev/null
@@ -1,374 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_HESSENBERGDECOMPOSITION_H
-#define EIGEN_HESSENBERGDECOMPOSITION_H
-
-namespace Eigen { 
-
-namespace internal {
-  
-template<typename MatrixType> struct HessenbergDecompositionMatrixHReturnType;
-template<typename MatrixType>
-struct traits<HessenbergDecompositionMatrixHReturnType<MatrixType> >
-{
-  typedef MatrixType ReturnType;
-};
-
-}
-
-/** \eigenvalues_module \ingroup Eigenvalues_Module
-  *
-  *
-  * \class HessenbergDecomposition
-  *
-  * \brief Reduces a square matrix to Hessenberg form by an orthogonal similarity transformation
-  *
-  * \tparam _MatrixType the type of the matrix of which we are computing the Hessenberg decomposition
-  *
-  * This class performs an Hessenberg decomposition of a matrix \f$ A \f$. In
-  * the real case, the Hessenberg decomposition consists of an orthogonal
-  * matrix \f$ Q \f$ and a Hessenberg matrix \f$ H \f$ such that \f$ A = Q H
-  * Q^T \f$. An orthogonal matrix is a matrix whose inverse equals its
-  * transpose (\f$ Q^{-1} = Q^T \f$). A Hessenberg matrix has zeros below the
-  * subdiagonal, so it is almost upper triangular. The Hessenberg decomposition
-  * of a complex matrix is \f$ A = Q H Q^* \f$ with \f$ Q \f$ unitary (that is,
-  * \f$ Q^{-1} = Q^* \f$).
-  *
-  * Call the function compute() to compute the Hessenberg decomposition of a
-  * given matrix. Alternatively, you can use the
-  * HessenbergDecomposition(const MatrixType&) constructor which computes the
-  * Hessenberg decomposition at construction time. Once the decomposition is
-  * computed, you can use the matrixH() and matrixQ() functions to construct
-  * the matrices H and Q in the decomposition.
-  *
-  * The documentation for matrixH() contains an example of the typical use of
-  * this class.
-  *
-  * \sa class ComplexSchur, class Tridiagonalization, \ref QR_Module "QR Module"
-  */
-template<typename _MatrixType> class HessenbergDecomposition
-{
-  public:
-
-    /** \brief Synonym for the template parameter \p _MatrixType. */
-    typedef _MatrixType MatrixType;
-
-    enum {
-      Size = MatrixType::RowsAtCompileTime,
-      SizeMinusOne = Size == Dynamic ? Dynamic : Size - 1,
-      Options = MatrixType::Options,
-      MaxSize = MatrixType::MaxRowsAtCompileTime,
-      MaxSizeMinusOne = MaxSize == Dynamic ? Dynamic : MaxSize - 1
-    };
-
-    /** \brief Scalar type for matrices of type #MatrixType. */
-    typedef typename MatrixType::Scalar Scalar;
-    typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
-
-    /** \brief Type for vector of Householder coefficients.
-      *
-      * This is column vector with entries of type #Scalar. The length of the
-      * vector is one less than the size of #MatrixType, if it is a fixed-side
-      * type.
-      */
-    typedef Matrix<Scalar, SizeMinusOne, 1, Options & ~RowMajor, MaxSizeMinusOne, 1> CoeffVectorType;
-
-    /** \brief Return type of matrixQ() */
-    typedef HouseholderSequence<MatrixType,typename internal::remove_all<typename CoeffVectorType::ConjugateReturnType>::type> HouseholderSequenceType;
-    
-    typedef internal::HessenbergDecompositionMatrixHReturnType<MatrixType> MatrixHReturnType;
-
-    /** \brief Default constructor; the decomposition will be computed later.
-      *
-      * \param [in] size  The size of the matrix whose Hessenberg decomposition will be computed.
-      *
-      * The default constructor is useful in cases in which the user intends to
-      * perform decompositions via compute().  The \p size parameter is only
-      * used as a hint. It is not an error to give a wrong \p size, but it may
-      * impair performance.
-      *
-      * \sa compute() for an example.
-      */
-    explicit HessenbergDecomposition(Index size = Size==Dynamic ? 2 : Size)
-      : m_matrix(size,size),
-        m_temp(size),
-        m_isInitialized(false)
-    {
-      if(size>1)
-        m_hCoeffs.resize(size-1);
-    }
-
-    /** \brief Constructor; computes Hessenberg decomposition of given matrix.
-      *
-      * \param[in]  matrix  Square matrix whose Hessenberg decomposition is to be computed.
-      *
-      * This constructor calls compute() to compute the Hessenberg
-      * decomposition.
-      *
-      * \sa matrixH() for an example.
-      */
-    template<typename InputType>
-    explicit HessenbergDecomposition(const EigenBase<InputType>& matrix)
-      : m_matrix(matrix.derived()),
-        m_temp(matrix.rows()),
-        m_isInitialized(false)
-    {
-      if(matrix.rows()<2)
-      {
-        m_isInitialized = true;
-        return;
-      }
-      m_hCoeffs.resize(matrix.rows()-1,1);
-      _compute(m_matrix, m_hCoeffs, m_temp);
-      m_isInitialized = true;
-    }
-
-    /** \brief Computes Hessenberg decomposition of given matrix.
-      *
-      * \param[in]  matrix  Square matrix whose Hessenberg decomposition is to be computed.
-      * \returns    Reference to \c *this
-      *
-      * The Hessenberg decomposition is computed by bringing the columns of the
-      * matrix successively in the required form using Householder reflections
-      * (see, e.g., Algorithm 7.4.2 in Golub \& Van Loan, <i>%Matrix
-      * Computations</i>). The cost is \f$ 10n^3/3 \f$ flops, where \f$ n \f$
-      * denotes the size of the given matrix.
-      *
-      * This method reuses of the allocated data in the HessenbergDecomposition
-      * object.
-      *
-      * Example: \include HessenbergDecomposition_compute.cpp
-      * Output: \verbinclude HessenbergDecomposition_compute.out
-      */
-    template<typename InputType>
-    HessenbergDecomposition& compute(const EigenBase<InputType>& matrix)
-    {
-      m_matrix = matrix.derived();
-      if(matrix.rows()<2)
-      {
-        m_isInitialized = true;
-        return *this;
-      }
-      m_hCoeffs.resize(matrix.rows()-1,1);
-      _compute(m_matrix, m_hCoeffs, m_temp);
-      m_isInitialized = true;
-      return *this;
-    }
-
-    /** \brief Returns the Householder coefficients.
-      *
-      * \returns a const reference to the vector of Householder coefficients
-      *
-      * \pre Either the constructor HessenbergDecomposition(const MatrixType&)
-      * or the member function compute(const MatrixType&) has been called
-      * before to compute the Hessenberg decomposition of a matrix.
-      *
-      * The Householder coefficients allow the reconstruction of the matrix
-      * \f$ Q \f$ in the Hessenberg decomposition from the packed data.
-      *
-      * \sa packedMatrix(), \ref Householder_Module "Householder module"
-      */
-    const CoeffVectorType& householderCoefficients() const
-    {
-      eigen_assert(m_isInitialized && "HessenbergDecomposition is not initialized.");
-      return m_hCoeffs;
-    }
-
-    /** \brief Returns the internal representation of the decomposition
-      *
-      *	\returns a const reference to a matrix with the internal representation
-      *	         of the decomposition.
-      *
-      * \pre Either the constructor HessenbergDecomposition(const MatrixType&)
-      * or the member function compute(const MatrixType&) has been called
-      * before to compute the Hessenberg decomposition of a matrix.
-      *
-      * The returned matrix contains the following information:
-      *  - the upper part and lower sub-diagonal represent the Hessenberg matrix H
-      *  - the rest of the lower part contains the Householder vectors that, combined with
-      *    Householder coefficients returned by householderCoefficients(),
-      *    allows to reconstruct the matrix Q as
-      *       \f$ Q = H_{N-1} \ldots H_1 H_0 \f$.
-      *    Here, the matrices \f$ H_i \f$ are the Householder transformations
-      *       \f$ H_i = (I - h_i v_i v_i^T) \f$
-      *    where \f$ h_i \f$ is the \f$ i \f$th Householder coefficient and
-      *    \f$ v_i \f$ is the Householder vector defined by
-      *       \f$ v_i = [ 0, \ldots, 0, 1, M(i+2,i), \ldots, M(N-1,i) ]^T \f$
-      *    with M the matrix returned by this function.
-      *
-      * See LAPACK for further details on this packed storage.
-      *
-      * Example: \include HessenbergDecomposition_packedMatrix.cpp
-      * Output: \verbinclude HessenbergDecomposition_packedMatrix.out
-      *
-      * \sa householderCoefficients()
-      */
-    const MatrixType& packedMatrix() const
-    {
-      eigen_assert(m_isInitialized && "HessenbergDecomposition is not initialized.");
-      return m_matrix;
-    }
-
-    /** \brief Reconstructs the orthogonal matrix Q in the decomposition
-      *
-      * \returns object representing the matrix Q
-      *
-      * \pre Either the constructor HessenbergDecomposition(const MatrixType&)
-      * or the member function compute(const MatrixType&) has been called
-      * before to compute the Hessenberg decomposition of a matrix.
-      *
-      * This function returns a light-weight object of template class
-      * HouseholderSequence. You can either apply it directly to a matrix or
-      * you can convert it to a matrix of type #MatrixType.
-      *
-      * \sa matrixH() for an example, class HouseholderSequence
-      */
-    HouseholderSequenceType matrixQ() const
-    {
-      eigen_assert(m_isInitialized && "HessenbergDecomposition is not initialized.");
-      return HouseholderSequenceType(m_matrix, m_hCoeffs.conjugate())
-             .setLength(m_matrix.rows() - 1)
-             .setShift(1);
-    }
-
-    /** \brief Constructs the Hessenberg matrix H in the decomposition
-      *
-      * \returns expression object representing the matrix H
-      *
-      * \pre Either the constructor HessenbergDecomposition(const MatrixType&)
-      * or the member function compute(const MatrixType&) has been called
-      * before to compute the Hessenberg decomposition of a matrix.
-      *
-      * The object returned by this function constructs the Hessenberg matrix H
-      * when it is assigned to a matrix or otherwise evaluated. The matrix H is
-      * constructed from the packed matrix as returned by packedMatrix(): The
-      * upper part (including the subdiagonal) of the packed matrix contains
-      * the matrix H. It may sometimes be better to directly use the packed
-      * matrix instead of constructing the matrix H.
-      *
-      * Example: \include HessenbergDecomposition_matrixH.cpp
-      * Output: \verbinclude HessenbergDecomposition_matrixH.out
-      *
-      * \sa matrixQ(), packedMatrix()
-      */
-    MatrixHReturnType matrixH() const
-    {
-      eigen_assert(m_isInitialized && "HessenbergDecomposition is not initialized.");
-      return MatrixHReturnType(*this);
-    }
-
-  private:
-
-    typedef Matrix<Scalar, 1, Size, Options | RowMajor, 1, MaxSize> VectorType;
-    typedef typename NumTraits<Scalar>::Real RealScalar;
-    static void _compute(MatrixType& matA, CoeffVectorType& hCoeffs, VectorType& temp);
-
-  protected:
-    MatrixType m_matrix;
-    CoeffVectorType m_hCoeffs;
-    VectorType m_temp;
-    bool m_isInitialized;
-};
-
-/** \internal
-  * Performs a tridiagonal decomposition of \a matA in place.
-  *
-  * \param matA the input selfadjoint matrix
-  * \param hCoeffs returned Householder coefficients
-  *
-  * The result is written in the lower triangular part of \a matA.
-  *
-  * Implemented from Golub's "%Matrix Computations", algorithm 8.3.1.
-  *
-  * \sa packedMatrix()
-  */
-template<typename MatrixType>
-void HessenbergDecomposition<MatrixType>::_compute(MatrixType& matA, CoeffVectorType& hCoeffs, VectorType& temp)
-{
-  eigen_assert(matA.rows()==matA.cols());
-  Index n = matA.rows();
-  temp.resize(n);
-  for (Index i = 0; i<n-1; ++i)
-  {
-    // let's consider the vector v = i-th column starting at position i+1
-    Index remainingSize = n-i-1;
-    RealScalar beta;
-    Scalar h;
-    matA.col(i).tail(remainingSize).makeHouseholderInPlace(h, beta);
-    matA.col(i).coeffRef(i+1) = beta;
-    hCoeffs.coeffRef(i) = h;
-
-    // Apply similarity transformation to remaining columns,
-    // i.e., compute A = H A H'
-
-    // A = H A
-    matA.bottomRightCorner(remainingSize, remainingSize)
-        .applyHouseholderOnTheLeft(matA.col(i).tail(remainingSize-1), h, &temp.coeffRef(0));
-
-    // A = A H'
-    matA.rightCols(remainingSize)
-        .applyHouseholderOnTheRight(matA.col(i).tail(remainingSize-1).conjugate(), numext::conj(h), &temp.coeffRef(0));
-  }
-}
-
-namespace internal {
-
-/** \eigenvalues_module \ingroup Eigenvalues_Module
-  *
-  *
-  * \brief Expression type for return value of HessenbergDecomposition::matrixH()
-  *
-  * \tparam MatrixType type of matrix in the Hessenberg decomposition
-  *
-  * Objects of this type represent the Hessenberg matrix in the Hessenberg
-  * decomposition of some matrix. The object holds a reference to the
-  * HessenbergDecomposition class until the it is assigned or evaluated for
-  * some other reason (the reference should remain valid during the life time
-  * of this object). This class is the return type of
-  * HessenbergDecomposition::matrixH(); there is probably no other use for this
-  * class.
-  */
-template<typename MatrixType> struct HessenbergDecompositionMatrixHReturnType
-: public ReturnByValue<HessenbergDecompositionMatrixHReturnType<MatrixType> >
-{
-  public:
-    /** \brief Constructor.
-      *
-      * \param[in] hess  Hessenberg decomposition
-      */
-    HessenbergDecompositionMatrixHReturnType(const HessenbergDecomposition<MatrixType>& hess) : m_hess(hess) { }
-
-    /** \brief Hessenberg matrix in decomposition.
-      *
-      * \param[out] result  Hessenberg matrix in decomposition \p hess which
-      *                     was passed to the constructor
-      */
-    template <typename ResultType>
-    inline void evalTo(ResultType& result) const
-    {
-      result = m_hess.packedMatrix();
-      Index n = result.rows();
-      if (n>2)
-        result.bottomLeftCorner(n-2, n-2).template triangularView<Lower>().setZero();
-    }
-
-    Index rows() const { return m_hess.packedMatrix().rows(); }
-    Index cols() const { return m_hess.packedMatrix().cols(); }
-
-  protected:
-    const HessenbergDecomposition<MatrixType>& m_hess;
-};
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_HESSENBERGDECOMPOSITION_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h
deleted file mode 100644
index e4e4260..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h
+++ /dev/null
@@ -1,158 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_MATRIXBASEEIGENVALUES_H
-#define EIGEN_MATRIXBASEEIGENVALUES_H
-
-namespace Eigen { 
-
-namespace internal {
-
-template<typename Derived, bool IsComplex>
-struct eigenvalues_selector
-{
-  // this is the implementation for the case IsComplex = true
-  static inline typename MatrixBase<Derived>::EigenvaluesReturnType const
-  run(const MatrixBase<Derived>& m)
-  {
-    typedef typename Derived::PlainObject PlainObject;
-    PlainObject m_eval(m);
-    return ComplexEigenSolver<PlainObject>(m_eval, false).eigenvalues();
-  }
-};
-
-template<typename Derived>
-struct eigenvalues_selector<Derived, false>
-{
-  static inline typename MatrixBase<Derived>::EigenvaluesReturnType const
-  run(const MatrixBase<Derived>& m)
-  {
-    typedef typename Derived::PlainObject PlainObject;
-    PlainObject m_eval(m);
-    return EigenSolver<PlainObject>(m_eval, false).eigenvalues();
-  }
-};
-
-} // end namespace internal
-
-/** \brief Computes the eigenvalues of a matrix 
-  * \returns Column vector containing the eigenvalues.
-  *
-  * \eigenvalues_module
-  * This function computes the eigenvalues with the help of the EigenSolver
-  * class (for real matrices) or the ComplexEigenSolver class (for complex
-  * matrices). 
-  *
-  * The eigenvalues are repeated according to their algebraic multiplicity,
-  * so there are as many eigenvalues as rows in the matrix.
-  *
-  * The SelfAdjointView class provides a better algorithm for selfadjoint
-  * matrices.
-  *
-  * Example: \include MatrixBase_eigenvalues.cpp
-  * Output: \verbinclude MatrixBase_eigenvalues.out
-  *
-  * \sa EigenSolver::eigenvalues(), ComplexEigenSolver::eigenvalues(),
-  *     SelfAdjointView::eigenvalues()
-  */
-template<typename Derived>
-inline typename MatrixBase<Derived>::EigenvaluesReturnType
-MatrixBase<Derived>::eigenvalues() const
-{
-  return internal::eigenvalues_selector<Derived, NumTraits<Scalar>::IsComplex>::run(derived());
-}
-
-/** \brief Computes the eigenvalues of a matrix
-  * \returns Column vector containing the eigenvalues.
-  *
-  * \eigenvalues_module
-  * This function computes the eigenvalues with the help of the
-  * SelfAdjointEigenSolver class.  The eigenvalues are repeated according to
-  * their algebraic multiplicity, so there are as many eigenvalues as rows in
-  * the matrix.
-  *
-  * Example: \include SelfAdjointView_eigenvalues.cpp
-  * Output: \verbinclude SelfAdjointView_eigenvalues.out
-  *
-  * \sa SelfAdjointEigenSolver::eigenvalues(), MatrixBase::eigenvalues()
-  */
-template<typename MatrixType, unsigned int UpLo> 
-inline typename SelfAdjointView<MatrixType, UpLo>::EigenvaluesReturnType
-SelfAdjointView<MatrixType, UpLo>::eigenvalues() const
-{
-  PlainObject thisAsMatrix(*this);
-  return SelfAdjointEigenSolver<PlainObject>(thisAsMatrix, false).eigenvalues();
-}
-
-
-
-/** \brief Computes the L2 operator norm
-  * \returns Operator norm of the matrix.
-  *
-  * \eigenvalues_module
-  * This function computes the L2 operator norm of a matrix, which is also
-  * known as the spectral norm. The norm of a matrix \f$ A \f$ is defined to be
-  * \f[ \|A\|_2 = \max_x \frac{\|Ax\|_2}{\|x\|_2} \f]
-  * where the maximum is over all vectors and the norm on the right is the
-  * Euclidean vector norm. The norm equals the largest singular value, which is
-  * the square root of the largest eigenvalue of the positive semi-definite
-  * matrix \f$ A^*A \f$.
-  *
-  * The current implementation uses the eigenvalues of \f$ A^*A \f$, as computed
-  * by SelfAdjointView::eigenvalues(), to compute the operator norm of a
-  * matrix.  The SelfAdjointView class provides a better algorithm for
-  * selfadjoint matrices.
-  *
-  * Example: \include MatrixBase_operatorNorm.cpp
-  * Output: \verbinclude MatrixBase_operatorNorm.out
-  *
-  * \sa SelfAdjointView::eigenvalues(), SelfAdjointView::operatorNorm()
-  */
-template<typename Derived>
-inline typename MatrixBase<Derived>::RealScalar
-MatrixBase<Derived>::operatorNorm() const
-{
-  using std::sqrt;
-  typename Derived::PlainObject m_eval(derived());
-  // FIXME if it is really guaranteed that the eigenvalues are already sorted,
-  // then we don't need to compute a maxCoeff() here, comparing the 1st and last ones is enough.
-  return sqrt((m_eval*m_eval.adjoint())
-                 .eval()
-		 .template selfadjointView<Lower>()
-		 .eigenvalues()
-		 .maxCoeff()
-		 );
-}
-
-/** \brief Computes the L2 operator norm
-  * \returns Operator norm of the matrix.
-  *
-  * \eigenvalues_module
-  * This function computes the L2 operator norm of a self-adjoint matrix. For a
-  * self-adjoint matrix, the operator norm is the largest eigenvalue.
-  *
-  * The current implementation uses the eigenvalues of the matrix, as computed
-  * by eigenvalues(), to compute the operator norm of the matrix.
-  *
-  * Example: \include SelfAdjointView_operatorNorm.cpp
-  * Output: \verbinclude SelfAdjointView_operatorNorm.out
-  *
-  * \sa eigenvalues(), MatrixBase::operatorNorm()
-  */
-template<typename MatrixType, unsigned int UpLo>
-inline typename SelfAdjointView<MatrixType, UpLo>::RealScalar
-SelfAdjointView<MatrixType, UpLo>::operatorNorm() const
-{
-  return eigenvalues().cwiseAbs().maxCoeff();
-}
-
-} // end namespace Eigen
-
-#endif
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/RealQZ.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/RealQZ.h
deleted file mode 100644
index b3a910d..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/RealQZ.h
+++ /dev/null
@@ -1,654 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2012 Alexey Korepanov <kaikaikai@yandex.ru>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_REAL_QZ_H
-#define EIGEN_REAL_QZ_H
-
-namespace Eigen {
-
-  /** \eigenvalues_module \ingroup Eigenvalues_Module
-   *
-   *
-   * \class RealQZ
-   *
-   * \brief Performs a real QZ decomposition of a pair of square matrices
-   *
-   * \tparam _MatrixType the type of the matrix of which we are computing the
-   * real QZ decomposition; this is expected to be an instantiation of the
-   * Matrix class template.
-   *
-   * Given a real square matrices A and B, this class computes the real QZ
-   * decomposition: \f$ A = Q S Z \f$, \f$ B = Q T Z \f$ where Q and Z are
-   * real orthogonal matrixes, T is upper-triangular matrix, and S is upper
-   * quasi-triangular matrix. An orthogonal matrix is a matrix whose
-   * inverse is equal to its transpose, \f$ U^{-1} = U^T \f$. A quasi-triangular
-   * matrix is a block-triangular matrix whose diagonal consists of 1-by-1
-   * blocks and 2-by-2 blocks where further reduction is impossible due to
-   * complex eigenvalues. 
-   *
-   * The eigenvalues of the pencil \f$ A - z B \f$ can be obtained from
-   * 1x1 and 2x2 blocks on the diagonals of S and T.
-   *
-   * Call the function compute() to compute the real QZ decomposition of a
-   * given pair of matrices. Alternatively, you can use the 
-   * RealQZ(const MatrixType& B, const MatrixType& B, bool computeQZ)
-   * constructor which computes the real QZ decomposition at construction
-   * time. Once the decomposition is computed, you can use the matrixS(),
-   * matrixT(), matrixQ() and matrixZ() functions to retrieve the matrices
-   * S, T, Q and Z in the decomposition. If computeQZ==false, some time
-   * is saved by not computing matrices Q and Z.
-   *
-   * Example: \include RealQZ_compute.cpp
-   * Output: \include RealQZ_compute.out
-   *
-   * \note The implementation is based on the algorithm in "Matrix Computations"
-   * by Gene H. Golub and Charles F. Van Loan, and a paper "An algorithm for
-   * generalized eigenvalue problems" by C.B.Moler and G.W.Stewart.
-   *
-   * \sa class RealSchur, class ComplexSchur, class EigenSolver, class ComplexEigenSolver
-   */
-
-  template<typename _MatrixType> class RealQZ
-  {
-    public:
-      typedef _MatrixType MatrixType;
-      enum {
-        RowsAtCompileTime = MatrixType::RowsAtCompileTime,
-        ColsAtCompileTime = MatrixType::ColsAtCompileTime,
-        Options = MatrixType::Options,
-        MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
-        MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
-      };
-      typedef typename MatrixType::Scalar Scalar;
-      typedef std::complex<typename NumTraits<Scalar>::Real> ComplexScalar;
-      typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
-
-      typedef Matrix<ComplexScalar, ColsAtCompileTime, 1, Options & ~RowMajor, MaxColsAtCompileTime, 1> EigenvalueType;
-      typedef Matrix<Scalar, ColsAtCompileTime, 1, Options & ~RowMajor, MaxColsAtCompileTime, 1> ColumnVectorType;
-
-      /** \brief Default constructor.
-       *
-       * \param [in] size  Positive integer, size of the matrix whose QZ decomposition will be computed.
-       *
-       * The default constructor is useful in cases in which the user intends to
-       * perform decompositions via compute().  The \p size parameter is only
-       * used as a hint. It is not an error to give a wrong \p size, but it may
-       * impair performance.
-       *
-       * \sa compute() for an example.
-       */
-      explicit RealQZ(Index size = RowsAtCompileTime==Dynamic ? 1 : RowsAtCompileTime) :
-        m_S(size, size),
-        m_T(size, size),
-        m_Q(size, size),
-        m_Z(size, size),
-        m_workspace(size*2),
-        m_maxIters(400),
-        m_isInitialized(false)
-        { }
-
-      /** \brief Constructor; computes real QZ decomposition of given matrices
-       * 
-       * \param[in]  A          Matrix A.
-       * \param[in]  B          Matrix B.
-       * \param[in]  computeQZ  If false, A and Z are not computed.
-       *
-       * This constructor calls compute() to compute the QZ decomposition.
-       */
-      RealQZ(const MatrixType& A, const MatrixType& B, bool computeQZ = true) :
-        m_S(A.rows(),A.cols()),
-        m_T(A.rows(),A.cols()),
-        m_Q(A.rows(),A.cols()),
-        m_Z(A.rows(),A.cols()),
-        m_workspace(A.rows()*2),
-        m_maxIters(400),
-        m_isInitialized(false) {
-          compute(A, B, computeQZ);
-        }
-
-      /** \brief Returns matrix Q in the QZ decomposition. 
-       *
-       * \returns A const reference to the matrix Q.
-       */
-      const MatrixType& matrixQ() const {
-        eigen_assert(m_isInitialized && "RealQZ is not initialized.");
-        eigen_assert(m_computeQZ && "The matrices Q and Z have not been computed during the QZ decomposition.");
-        return m_Q;
-      }
-
-      /** \brief Returns matrix Z in the QZ decomposition. 
-       *
-       * \returns A const reference to the matrix Z.
-       */
-      const MatrixType& matrixZ() const {
-        eigen_assert(m_isInitialized && "RealQZ is not initialized.");
-        eigen_assert(m_computeQZ && "The matrices Q and Z have not been computed during the QZ decomposition.");
-        return m_Z;
-      }
-
-      /** \brief Returns matrix S in the QZ decomposition. 
-       *
-       * \returns A const reference to the matrix S.
-       */
-      const MatrixType& matrixS() const {
-        eigen_assert(m_isInitialized && "RealQZ is not initialized.");
-        return m_S;
-      }
-
-      /** \brief Returns matrix S in the QZ decomposition. 
-       *
-       * \returns A const reference to the matrix S.
-       */
-      const MatrixType& matrixT() const {
-        eigen_assert(m_isInitialized && "RealQZ is not initialized.");
-        return m_T;
-      }
-
-      /** \brief Computes QZ decomposition of given matrix. 
-       * 
-       * \param[in]  A          Matrix A.
-       * \param[in]  B          Matrix B.
-       * \param[in]  computeQZ  If false, A and Z are not computed.
-       * \returns    Reference to \c *this
-       */
-      RealQZ& compute(const MatrixType& A, const MatrixType& B, bool computeQZ = true);
-
-      /** \brief Reports whether previous computation was successful.
-       *
-       * \returns \c Success if computation was succesful, \c NoConvergence otherwise.
-       */
-      ComputationInfo info() const
-      {
-        eigen_assert(m_isInitialized && "RealQZ is not initialized.");
-        return m_info;
-      }
-
-      /** \brief Returns number of performed QR-like iterations.
-      */
-      Index iterations() const
-      {
-        eigen_assert(m_isInitialized && "RealQZ is not initialized.");
-        return m_global_iter;
-      }
-
-      /** Sets the maximal number of iterations allowed to converge to one eigenvalue
-       * or decouple the problem.
-      */
-      RealQZ& setMaxIterations(Index maxIters)
-      {
-        m_maxIters = maxIters;
-        return *this;
-      }
-
-    private:
-
-      MatrixType m_S, m_T, m_Q, m_Z;
-      Matrix<Scalar,Dynamic,1> m_workspace;
-      ComputationInfo m_info;
-      Index m_maxIters;
-      bool m_isInitialized;
-      bool m_computeQZ;
-      Scalar m_normOfT, m_normOfS;
-      Index m_global_iter;
-
-      typedef Matrix<Scalar,3,1> Vector3s;
-      typedef Matrix<Scalar,2,1> Vector2s;
-      typedef Matrix<Scalar,2,2> Matrix2s;
-      typedef JacobiRotation<Scalar> JRs;
-
-      void hessenbergTriangular();
-      void computeNorms();
-      Index findSmallSubdiagEntry(Index iu);
-      Index findSmallDiagEntry(Index f, Index l);
-      void splitOffTwoRows(Index i);
-      void pushDownZero(Index z, Index f, Index l);
-      void step(Index f, Index l, Index iter);
-
-  }; // RealQZ
-
-  /** \internal Reduces S and T to upper Hessenberg - triangular form */
-  template<typename MatrixType>
-    void RealQZ<MatrixType>::hessenbergTriangular()
-    {
-
-      const Index dim = m_S.cols();
-
-      // perform QR decomposition of T, overwrite T with R, save Q
-      HouseholderQR<MatrixType> qrT(m_T);
-      m_T = qrT.matrixQR();
-      m_T.template triangularView<StrictlyLower>().setZero();
-      m_Q = qrT.householderQ();
-      // overwrite S with Q* S
-      m_S.applyOnTheLeft(m_Q.adjoint());
-      // init Z as Identity
-      if (m_computeQZ)
-        m_Z = MatrixType::Identity(dim,dim);
-      // reduce S to upper Hessenberg with Givens rotations
-      for (Index j=0; j<=dim-3; j++) {
-        for (Index i=dim-1; i>=j+2; i--) {
-          JRs G;
-          // kill S(i,j)
-          if(m_S.coeff(i,j) != 0)
-          {
-            G.makeGivens(m_S.coeff(i-1,j), m_S.coeff(i,j), &m_S.coeffRef(i-1, j));
-            m_S.coeffRef(i,j) = Scalar(0.0);
-            m_S.rightCols(dim-j-1).applyOnTheLeft(i-1,i,G.adjoint());
-            m_T.rightCols(dim-i+1).applyOnTheLeft(i-1,i,G.adjoint());
-            // update Q
-            if (m_computeQZ)
-              m_Q.applyOnTheRight(i-1,i,G);
-          }
-          // kill T(i,i-1)
-          if(m_T.coeff(i,i-1)!=Scalar(0))
-          {
-            G.makeGivens(m_T.coeff(i,i), m_T.coeff(i,i-1), &m_T.coeffRef(i,i));
-            m_T.coeffRef(i,i-1) = Scalar(0.0);
-            m_S.applyOnTheRight(i,i-1,G);
-            m_T.topRows(i).applyOnTheRight(i,i-1,G);
-            // update Z
-            if (m_computeQZ)
-              m_Z.applyOnTheLeft(i,i-1,G.adjoint());
-          }
-        }
-      }
-    }
-
-  /** \internal Computes vector L1 norms of S and T when in Hessenberg-Triangular form already */
-  template<typename MatrixType>
-    inline void RealQZ<MatrixType>::computeNorms()
-    {
-      const Index size = m_S.cols();
-      m_normOfS = Scalar(0.0);
-      m_normOfT = Scalar(0.0);
-      for (Index j = 0; j < size; ++j)
-      {
-        m_normOfS += m_S.col(j).segment(0, (std::min)(size,j+2)).cwiseAbs().sum();
-        m_normOfT += m_T.row(j).segment(j, size - j).cwiseAbs().sum();
-      }
-    }
-
-
-  /** \internal Look for single small sub-diagonal element S(res, res-1) and return res (or 0) */
-  template<typename MatrixType>
-    inline Index RealQZ<MatrixType>::findSmallSubdiagEntry(Index iu)
-    {
-      using std::abs;
-      Index res = iu;
-      while (res > 0)
-      {
-        Scalar s = abs(m_S.coeff(res-1,res-1)) + abs(m_S.coeff(res,res));
-        if (s == Scalar(0.0))
-          s = m_normOfS;
-        if (abs(m_S.coeff(res,res-1)) < NumTraits<Scalar>::epsilon() * s)
-          break;
-        res--;
-      }
-      return res;
-    }
-
-  /** \internal Look for single small diagonal element T(res, res) for res between f and l, and return res (or f-1)  */
-  template<typename MatrixType>
-    inline Index RealQZ<MatrixType>::findSmallDiagEntry(Index f, Index l)
-    {
-      using std::abs;
-      Index res = l;
-      while (res >= f) {
-        if (abs(m_T.coeff(res,res)) <= NumTraits<Scalar>::epsilon() * m_normOfT)
-          break;
-        res--;
-      }
-      return res;
-    }
-
-  /** \internal decouple 2x2 diagonal block in rows i, i+1 if eigenvalues are real */
-  template<typename MatrixType>
-    inline void RealQZ<MatrixType>::splitOffTwoRows(Index i)
-    {
-      using std::abs;
-      using std::sqrt;
-      const Index dim=m_S.cols();
-      if (abs(m_S.coeff(i+1,i))==Scalar(0))
-        return;
-      Index j = findSmallDiagEntry(i,i+1);
-      if (j==i-1)
-      {
-        // block of (S T^{-1})
-        Matrix2s STi = m_T.template block<2,2>(i,i).template triangularView<Upper>().
-          template solve<OnTheRight>(m_S.template block<2,2>(i,i));
-        Scalar p = Scalar(0.5)*(STi(0,0)-STi(1,1));
-        Scalar q = p*p + STi(1,0)*STi(0,1);
-        if (q>=0) {
-          Scalar z = sqrt(q);
-          // one QR-like iteration for ABi - lambda I
-          // is enough - when we know exact eigenvalue in advance,
-          // convergence is immediate
-          JRs G;
-          if (p>=0)
-            G.makeGivens(p + z, STi(1,0));
-          else
-            G.makeGivens(p - z, STi(1,0));
-          m_S.rightCols(dim-i).applyOnTheLeft(i,i+1,G.adjoint());
-          m_T.rightCols(dim-i).applyOnTheLeft(i,i+1,G.adjoint());
-          // update Q
-          if (m_computeQZ)
-            m_Q.applyOnTheRight(i,i+1,G);
-
-          G.makeGivens(m_T.coeff(i+1,i+1), m_T.coeff(i+1,i));
-          m_S.topRows(i+2).applyOnTheRight(i+1,i,G);
-          m_T.topRows(i+2).applyOnTheRight(i+1,i,G);
-          // update Z
-          if (m_computeQZ)
-            m_Z.applyOnTheLeft(i+1,i,G.adjoint());
-
-          m_S.coeffRef(i+1,i) = Scalar(0.0);
-          m_T.coeffRef(i+1,i) = Scalar(0.0);
-        }
-      }
-      else
-      {
-        pushDownZero(j,i,i+1);
-      }
-    }
-
-  /** \internal use zero in T(z,z) to zero S(l,l-1), working in block f..l */
-  template<typename MatrixType>
-    inline void RealQZ<MatrixType>::pushDownZero(Index z, Index f, Index l)
-    {
-      JRs G;
-      const Index dim = m_S.cols();
-      for (Index zz=z; zz<l; zz++)
-      {
-        // push 0 down
-        Index firstColS = zz>f ? (zz-1) : zz;
-        G.makeGivens(m_T.coeff(zz, zz+1), m_T.coeff(zz+1, zz+1));
-        m_S.rightCols(dim-firstColS).applyOnTheLeft(zz,zz+1,G.adjoint());
-        m_T.rightCols(dim-zz).applyOnTheLeft(zz,zz+1,G.adjoint());
-        m_T.coeffRef(zz+1,zz+1) = Scalar(0.0);
-        // update Q
-        if (m_computeQZ)
-          m_Q.applyOnTheRight(zz,zz+1,G);
-        // kill S(zz+1, zz-1)
-        if (zz>f)
-        {
-          G.makeGivens(m_S.coeff(zz+1, zz), m_S.coeff(zz+1,zz-1));
-          m_S.topRows(zz+2).applyOnTheRight(zz, zz-1,G);
-          m_T.topRows(zz+1).applyOnTheRight(zz, zz-1,G);
-          m_S.coeffRef(zz+1,zz-1) = Scalar(0.0);
-          // update Z
-          if (m_computeQZ)
-            m_Z.applyOnTheLeft(zz,zz-1,G.adjoint());
-        }
-      }
-      // finally kill S(l,l-1)
-      G.makeGivens(m_S.coeff(l,l), m_S.coeff(l,l-1));
-      m_S.applyOnTheRight(l,l-1,G);
-      m_T.applyOnTheRight(l,l-1,G);
-      m_S.coeffRef(l,l-1)=Scalar(0.0);
-      // update Z
-      if (m_computeQZ)
-        m_Z.applyOnTheLeft(l,l-1,G.adjoint());
-    }
-
-  /** \internal QR-like iterative step for block f..l */
-  template<typename MatrixType>
-    inline void RealQZ<MatrixType>::step(Index f, Index l, Index iter)
-    {
-      using std::abs;
-      const Index dim = m_S.cols();
-
-      // x, y, z
-      Scalar x, y, z;
-      if (iter==10)
-      {
-        // Wilkinson ad hoc shift
-        const Scalar
-          a11=m_S.coeff(f+0,f+0), a12=m_S.coeff(f+0,f+1),
-          a21=m_S.coeff(f+1,f+0), a22=m_S.coeff(f+1,f+1), a32=m_S.coeff(f+2,f+1),
-          b12=m_T.coeff(f+0,f+1),
-          b11i=Scalar(1.0)/m_T.coeff(f+0,f+0),
-          b22i=Scalar(1.0)/m_T.coeff(f+1,f+1),
-          a87=m_S.coeff(l-1,l-2),
-          a98=m_S.coeff(l-0,l-1),
-          b77i=Scalar(1.0)/m_T.coeff(l-2,l-2),
-          b88i=Scalar(1.0)/m_T.coeff(l-1,l-1);
-        Scalar ss = abs(a87*b77i) + abs(a98*b88i),
-               lpl = Scalar(1.5)*ss,
-               ll = ss*ss;
-        x = ll + a11*a11*b11i*b11i - lpl*a11*b11i + a12*a21*b11i*b22i
-          - a11*a21*b12*b11i*b11i*b22i;
-        y = a11*a21*b11i*b11i - lpl*a21*b11i + a21*a22*b11i*b22i 
-          - a21*a21*b12*b11i*b11i*b22i;
-        z = a21*a32*b11i*b22i;
-      }
-      else if (iter==16)
-      {
-        // another exceptional shift
-        x = m_S.coeff(f,f)/m_T.coeff(f,f)-m_S.coeff(l,l)/m_T.coeff(l,l) + m_S.coeff(l,l-1)*m_T.coeff(l-1,l) /
-          (m_T.coeff(l-1,l-1)*m_T.coeff(l,l));
-        y = m_S.coeff(f+1,f)/m_T.coeff(f,f);
-        z = 0;
-      }
-      else if (iter>23 && !(iter%8))
-      {
-        // extremely exceptional shift
-        x = internal::random<Scalar>(-1.0,1.0);
-        y = internal::random<Scalar>(-1.0,1.0);
-        z = internal::random<Scalar>(-1.0,1.0);
-      }
-      else
-      {
-        // Compute the shifts: (x,y,z,0...) = (AB^-1 - l1 I) (AB^-1 - l2 I) e1
-        // where l1 and l2 are the eigenvalues of the 2x2 matrix C = U V^-1 where
-        // U and V are 2x2 bottom right sub matrices of A and B. Thus:
-        //  = AB^-1AB^-1 + l1 l2 I - (l1+l2)(AB^-1)
-        //  = AB^-1AB^-1 + det(M) - tr(M)(AB^-1)
-        // Since we are only interested in having x, y, z with a correct ratio, we have:
-        const Scalar
-          a11 = m_S.coeff(f,f),     a12 = m_S.coeff(f,f+1),
-          a21 = m_S.coeff(f+1,f),   a22 = m_S.coeff(f+1,f+1),
-                                    a32 = m_S.coeff(f+2,f+1),
-
-          a88 = m_S.coeff(l-1,l-1), a89 = m_S.coeff(l-1,l),
-          a98 = m_S.coeff(l,l-1),   a99 = m_S.coeff(l,l),
-
-          b11 = m_T.coeff(f,f),     b12 = m_T.coeff(f,f+1),
-                                    b22 = m_T.coeff(f+1,f+1),
-
-          b88 = m_T.coeff(l-1,l-1), b89 = m_T.coeff(l-1,l),
-                                    b99 = m_T.coeff(l,l);
-
-        x = ( (a88/b88 - a11/b11)*(a99/b99 - a11/b11) - (a89/b99)*(a98/b88) + (a98/b88)*(b89/b99)*(a11/b11) ) * (b11/a21)
-          + a12/b22 - (a11/b11)*(b12/b22);
-        y = (a22/b22-a11/b11) - (a21/b11)*(b12/b22) - (a88/b88-a11/b11) - (a99/b99-a11/b11) + (a98/b88)*(b89/b99);
-        z = a32/b22;
-      }
-
-      JRs G;
-
-      for (Index k=f; k<=l-2; k++)
-      {
-        // variables for Householder reflections
-        Vector2s essential2;
-        Scalar tau, beta;
-
-        Vector3s hr(x,y,z);
-
-        // Q_k to annihilate S(k+1,k-1) and S(k+2,k-1)
-        hr.makeHouseholderInPlace(tau, beta);
-        essential2 = hr.template bottomRows<2>();
-        Index fc=(std::max)(k-1,Index(0));  // first col to update
-        m_S.template middleRows<3>(k).rightCols(dim-fc).applyHouseholderOnTheLeft(essential2, tau, m_workspace.data());
-        m_T.template middleRows<3>(k).rightCols(dim-fc).applyHouseholderOnTheLeft(essential2, tau, m_workspace.data());
-        if (m_computeQZ)
-          m_Q.template middleCols<3>(k).applyHouseholderOnTheRight(essential2, tau, m_workspace.data());
-        if (k>f)
-          m_S.coeffRef(k+2,k-1) = m_S.coeffRef(k+1,k-1) = Scalar(0.0);
-
-        // Z_{k1} to annihilate T(k+2,k+1) and T(k+2,k)
-        hr << m_T.coeff(k+2,k+2),m_T.coeff(k+2,k),m_T.coeff(k+2,k+1);
-        hr.makeHouseholderInPlace(tau, beta);
-        essential2 = hr.template bottomRows<2>();
-        {
-          Index lr = (std::min)(k+4,dim); // last row to update
-          Map<Matrix<Scalar,Dynamic,1> > tmp(m_workspace.data(),lr);
-          // S
-          tmp = m_S.template middleCols<2>(k).topRows(lr) * essential2;
-          tmp += m_S.col(k+2).head(lr);
-          m_S.col(k+2).head(lr) -= tau*tmp;
-          m_S.template middleCols<2>(k).topRows(lr) -= (tau*tmp) * essential2.adjoint();
-          // T
-          tmp = m_T.template middleCols<2>(k).topRows(lr) * essential2;
-          tmp += m_T.col(k+2).head(lr);
-          m_T.col(k+2).head(lr) -= tau*tmp;
-          m_T.template middleCols<2>(k).topRows(lr) -= (tau*tmp) * essential2.adjoint();
-        }
-        if (m_computeQZ)
-        {
-          // Z
-          Map<Matrix<Scalar,1,Dynamic> > tmp(m_workspace.data(),dim);
-          tmp = essential2.adjoint()*(m_Z.template middleRows<2>(k));
-          tmp += m_Z.row(k+2);
-          m_Z.row(k+2) -= tau*tmp;
-          m_Z.template middleRows<2>(k) -= essential2 * (tau*tmp);
-        }
-        m_T.coeffRef(k+2,k) = m_T.coeffRef(k+2,k+1) = Scalar(0.0);
-
-        // Z_{k2} to annihilate T(k+1,k)
-        G.makeGivens(m_T.coeff(k+1,k+1), m_T.coeff(k+1,k));
-        m_S.applyOnTheRight(k+1,k,G);
-        m_T.applyOnTheRight(k+1,k,G);
-        // update Z
-        if (m_computeQZ)
-          m_Z.applyOnTheLeft(k+1,k,G.adjoint());
-        m_T.coeffRef(k+1,k) = Scalar(0.0);
-
-        // update x,y,z
-        x = m_S.coeff(k+1,k);
-        y = m_S.coeff(k+2,k);
-        if (k < l-2)
-          z = m_S.coeff(k+3,k);
-      } // loop over k
-
-      // Q_{n-1} to annihilate y = S(l,l-2)
-      G.makeGivens(x,y);
-      m_S.applyOnTheLeft(l-1,l,G.adjoint());
-      m_T.applyOnTheLeft(l-1,l,G.adjoint());
-      if (m_computeQZ)
-        m_Q.applyOnTheRight(l-1,l,G);
-      m_S.coeffRef(l,l-2) = Scalar(0.0);
-
-      // Z_{n-1} to annihilate T(l,l-1)
-      G.makeGivens(m_T.coeff(l,l),m_T.coeff(l,l-1));
-      m_S.applyOnTheRight(l,l-1,G);
-      m_T.applyOnTheRight(l,l-1,G);
-      if (m_computeQZ)
-        m_Z.applyOnTheLeft(l,l-1,G.adjoint());
-      m_T.coeffRef(l,l-1) = Scalar(0.0);
-    }
-
-  template<typename MatrixType>
-    RealQZ<MatrixType>& RealQZ<MatrixType>::compute(const MatrixType& A_in, const MatrixType& B_in, bool computeQZ)
-    {
-
-      const Index dim = A_in.cols();
-
-      eigen_assert (A_in.rows()==dim && A_in.cols()==dim 
-          && B_in.rows()==dim && B_in.cols()==dim 
-          && "Need square matrices of the same dimension");
-
-      m_isInitialized = true;
-      m_computeQZ = computeQZ;
-      m_S = A_in; m_T = B_in;
-      m_workspace.resize(dim*2);
-      m_global_iter = 0;
-
-      // entrance point: hessenberg triangular decomposition
-      hessenbergTriangular();
-      // compute L1 vector norms of T, S into m_normOfS, m_normOfT
-      computeNorms();
-
-      Index l = dim-1, 
-            f, 
-            local_iter = 0;
-
-      while (l>0 && local_iter<m_maxIters)
-      {
-        f = findSmallSubdiagEntry(l);
-        // now rows and columns f..l (including) decouple from the rest of the problem
-        if (f>0) m_S.coeffRef(f,f-1) = Scalar(0.0);
-        if (f == l) // One root found
-        {
-          l--;
-          local_iter = 0;
-        }
-        else if (f == l-1) // Two roots found
-        {
-          splitOffTwoRows(f);
-          l -= 2;
-          local_iter = 0;
-        }
-        else // No convergence yet
-        {
-          // if there's zero on diagonal of T, we can isolate an eigenvalue with Givens rotations
-          Index z = findSmallDiagEntry(f,l);
-          if (z>=f)
-          {
-            // zero found
-            pushDownZero(z,f,l);
-          }
-          else
-          {
-            // We are sure now that S.block(f,f, l-f+1,l-f+1) is underuced upper-Hessenberg 
-            // and T.block(f,f, l-f+1,l-f+1) is invertible uper-triangular, which allows to
-            // apply a QR-like iteration to rows and columns f..l.
-            step(f,l, local_iter);
-            local_iter++;
-            m_global_iter++;
-          }
-        }
-      }
-      // check if we converged before reaching iterations limit
-      m_info = (local_iter<m_maxIters) ? Success : NoConvergence;
-
-      // For each non triangular 2x2 diagonal block of S,
-      //    reduce the respective 2x2 diagonal block of T to positive diagonal form using 2x2 SVD.
-      // This step is not mandatory for QZ, but it does help further extraction of eigenvalues/eigenvectors,
-      // and is in par with Lapack/Matlab QZ.
-      if(m_info==Success)
-      {
-        for(Index i=0; i<dim-1; ++i)
-        {
-          if(m_S.coeff(i+1, i) != Scalar(0))
-          {
-            JacobiRotation<Scalar> j_left, j_right;
-            internal::real_2x2_jacobi_svd(m_T, i, i+1, &j_left, &j_right);
-
-            // Apply resulting Jacobi rotations
-            m_S.applyOnTheLeft(i,i+1,j_left);
-            m_S.applyOnTheRight(i,i+1,j_right);
-            m_T.applyOnTheLeft(i,i+1,j_left);
-            m_T.applyOnTheRight(i,i+1,j_right);
-            m_T(i+1,i) = m_T(i,i+1) = Scalar(0);
-
-            if(m_computeQZ) {
-              m_Q.applyOnTheRight(i,i+1,j_left.transpose());
-              m_Z.applyOnTheLeft(i,i+1,j_right.transpose());
-            }
-
-            i++;
-          }
-        }
-      }
-
-      return *this;
-    } // end compute
-
-} // end namespace Eigen
-
-#endif //EIGEN_REAL_QZ
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/RealSchur.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/RealSchur.h
deleted file mode 100644
index 17ea903..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/RealSchur.h
+++ /dev/null
@@ -1,546 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2010,2012 Jitse Niesen <jitse@maths.leeds.ac.uk>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_REAL_SCHUR_H
-#define EIGEN_REAL_SCHUR_H
-
-#include "./HessenbergDecomposition.h"
-
-namespace Eigen { 
-
-/** \eigenvalues_module \ingroup Eigenvalues_Module
-  *
-  *
-  * \class RealSchur
-  *
-  * \brief Performs a real Schur decomposition of a square matrix
-  *
-  * \tparam _MatrixType the type of the matrix of which we are computing the
-  * real Schur decomposition; this is expected to be an instantiation of the
-  * Matrix class template.
-  *
-  * Given a real square matrix A, this class computes the real Schur
-  * decomposition: \f$ A = U T U^T \f$ where U is a real orthogonal matrix and
-  * T is a real quasi-triangular matrix. An orthogonal matrix is a matrix whose
-  * inverse is equal to its transpose, \f$ U^{-1} = U^T \f$. A quasi-triangular
-  * matrix is a block-triangular matrix whose diagonal consists of 1-by-1
-  * blocks and 2-by-2 blocks with complex eigenvalues. The eigenvalues of the
-  * blocks on the diagonal of T are the same as the eigenvalues of the matrix
-  * A, and thus the real Schur decomposition is used in EigenSolver to compute
-  * the eigendecomposition of a matrix.
-  *
-  * Call the function compute() to compute the real Schur decomposition of a
-  * given matrix. Alternatively, you can use the RealSchur(const MatrixType&, bool)
-  * constructor which computes the real Schur decomposition at construction
-  * time. Once the decomposition is computed, you can use the matrixU() and
-  * matrixT() functions to retrieve the matrices U and T in the decomposition.
-  *
-  * The documentation of RealSchur(const MatrixType&, bool) contains an example
-  * of the typical use of this class.
-  *
-  * \note The implementation is adapted from
-  * <a href="http://math.nist.gov/javanumerics/jama/">JAMA</a> (public domain).
-  * Their code is based on EISPACK.
-  *
-  * \sa class ComplexSchur, class EigenSolver, class ComplexEigenSolver
-  */
-template<typename _MatrixType> class RealSchur
-{
-  public:
-    typedef _MatrixType MatrixType;
-    enum {
-      RowsAtCompileTime = MatrixType::RowsAtCompileTime,
-      ColsAtCompileTime = MatrixType::ColsAtCompileTime,
-      Options = MatrixType::Options,
-      MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
-      MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
-    };
-    typedef typename MatrixType::Scalar Scalar;
-    typedef std::complex<typename NumTraits<Scalar>::Real> ComplexScalar;
-    typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
-
-    typedef Matrix<ComplexScalar, ColsAtCompileTime, 1, Options & ~RowMajor, MaxColsAtCompileTime, 1> EigenvalueType;
-    typedef Matrix<Scalar, ColsAtCompileTime, 1, Options & ~RowMajor, MaxColsAtCompileTime, 1> ColumnVectorType;
-
-    /** \brief Default constructor.
-      *
-      * \param [in] size  Positive integer, size of the matrix whose Schur decomposition will be computed.
-      *
-      * The default constructor is useful in cases in which the user intends to
-      * perform decompositions via compute().  The \p size parameter is only
-      * used as a hint. It is not an error to give a wrong \p size, but it may
-      * impair performance.
-      *
-      * \sa compute() for an example.
-      */
-    explicit RealSchur(Index size = RowsAtCompileTime==Dynamic ? 1 : RowsAtCompileTime)
-            : m_matT(size, size),
-              m_matU(size, size),
-              m_workspaceVector(size),
-              m_hess(size),
-              m_isInitialized(false),
-              m_matUisUptodate(false),
-              m_maxIters(-1)
-    { }
-
-    /** \brief Constructor; computes real Schur decomposition of given matrix. 
-      * 
-      * \param[in]  matrix    Square matrix whose Schur decomposition is to be computed.
-      * \param[in]  computeU  If true, both T and U are computed; if false, only T is computed.
-      *
-      * This constructor calls compute() to compute the Schur decomposition.
-      *
-      * Example: \include RealSchur_RealSchur_MatrixType.cpp
-      * Output: \verbinclude RealSchur_RealSchur_MatrixType.out
-      */
-    template<typename InputType>
-    explicit RealSchur(const EigenBase<InputType>& matrix, bool computeU = true)
-            : m_matT(matrix.rows(),matrix.cols()),
-              m_matU(matrix.rows(),matrix.cols()),
-              m_workspaceVector(matrix.rows()),
-              m_hess(matrix.rows()),
-              m_isInitialized(false),
-              m_matUisUptodate(false),
-              m_maxIters(-1)
-    {
-      compute(matrix.derived(), computeU);
-    }
-
-    /** \brief Returns the orthogonal matrix in the Schur decomposition. 
-      *
-      * \returns A const reference to the matrix U.
-      *
-      * \pre Either the constructor RealSchur(const MatrixType&, bool) or the
-      * member function compute(const MatrixType&, bool) has been called before
-      * to compute the Schur decomposition of a matrix, and \p computeU was set
-      * to true (the default value).
-      *
-      * \sa RealSchur(const MatrixType&, bool) for an example
-      */
-    const MatrixType& matrixU() const
-    {
-      eigen_assert(m_isInitialized && "RealSchur is not initialized.");
-      eigen_assert(m_matUisUptodate && "The matrix U has not been computed during the RealSchur decomposition.");
-      return m_matU;
-    }
-
-    /** \brief Returns the quasi-triangular matrix in the Schur decomposition. 
-      *
-      * \returns A const reference to the matrix T.
-      *
-      * \pre Either the constructor RealSchur(const MatrixType&, bool) or the
-      * member function compute(const MatrixType&, bool) has been called before
-      * to compute the Schur decomposition of a matrix.
-      *
-      * \sa RealSchur(const MatrixType&, bool) for an example
-      */
-    const MatrixType& matrixT() const
-    {
-      eigen_assert(m_isInitialized && "RealSchur is not initialized.");
-      return m_matT;
-    }
-  
-    /** \brief Computes Schur decomposition of given matrix. 
-      * 
-      * \param[in]  matrix    Square matrix whose Schur decomposition is to be computed.
-      * \param[in]  computeU  If true, both T and U are computed; if false, only T is computed.
-      * \returns    Reference to \c *this
-      *
-      * The Schur decomposition is computed by first reducing the matrix to
-      * Hessenberg form using the class HessenbergDecomposition. The Hessenberg
-      * matrix is then reduced to triangular form by performing Francis QR
-      * iterations with implicit double shift. The cost of computing the Schur
-      * decomposition depends on the number of iterations; as a rough guide, it
-      * may be taken to be \f$25n^3\f$ flops if \a computeU is true and
-      * \f$10n^3\f$ flops if \a computeU is false.
-      *
-      * Example: \include RealSchur_compute.cpp
-      * Output: \verbinclude RealSchur_compute.out
-      *
-      * \sa compute(const MatrixType&, bool, Index)
-      */
-    template<typename InputType>
-    RealSchur& compute(const EigenBase<InputType>& matrix, bool computeU = true);
-
-    /** \brief Computes Schur decomposition of a Hessenberg matrix H = Z T Z^T
-     *  \param[in] matrixH Matrix in Hessenberg form H
-     *  \param[in] matrixQ orthogonal matrix Q that transform a matrix A to H : A = Q H Q^T
-     *  \param computeU Computes the matriX U of the Schur vectors
-     * \return Reference to \c *this
-     * 
-     *  This routine assumes that the matrix is already reduced in Hessenberg form matrixH
-     *  using either the class HessenbergDecomposition or another mean. 
-     *  It computes the upper quasi-triangular matrix T of the Schur decomposition of H
-     *  When computeU is true, this routine computes the matrix U such that 
-     *  A = U T U^T =  (QZ) T (QZ)^T = Q H Q^T where A is the initial matrix
-     * 
-     * NOTE Q is referenced if computeU is true; so, if the initial orthogonal matrix
-     * is not available, the user should give an identity matrix (Q.setIdentity())
-     * 
-     * \sa compute(const MatrixType&, bool)
-     */
-    template<typename HessMatrixType, typename OrthMatrixType>
-    RealSchur& computeFromHessenberg(const HessMatrixType& matrixH, const OrthMatrixType& matrixQ,  bool computeU);
-    /** \brief Reports whether previous computation was successful.
-      *
-      * \returns \c Success if computation was succesful, \c NoConvergence otherwise.
-      */
-    ComputationInfo info() const
-    {
-      eigen_assert(m_isInitialized && "RealSchur is not initialized.");
-      return m_info;
-    }
-
-    /** \brief Sets the maximum number of iterations allowed. 
-      *
-      * If not specified by the user, the maximum number of iterations is m_maxIterationsPerRow times the size
-      * of the matrix.
-      */
-    RealSchur& setMaxIterations(Index maxIters)
-    {
-      m_maxIters = maxIters;
-      return *this;
-    }
-
-    /** \brief Returns the maximum number of iterations. */
-    Index getMaxIterations()
-    {
-      return m_maxIters;
-    }
-
-    /** \brief Maximum number of iterations per row.
-      *
-      * If not otherwise specified, the maximum number of iterations is this number times the size of the
-      * matrix. It is currently set to 40.
-      */
-    static const int m_maxIterationsPerRow = 40;
-
-  private:
-    
-    MatrixType m_matT;
-    MatrixType m_matU;
-    ColumnVectorType m_workspaceVector;
-    HessenbergDecomposition<MatrixType> m_hess;
-    ComputationInfo m_info;
-    bool m_isInitialized;
-    bool m_matUisUptodate;
-    Index m_maxIters;
-
-    typedef Matrix<Scalar,3,1> Vector3s;
-
-    Scalar computeNormOfT();
-    Index findSmallSubdiagEntry(Index iu);
-    void splitOffTwoRows(Index iu, bool computeU, const Scalar& exshift);
-    void computeShift(Index iu, Index iter, Scalar& exshift, Vector3s& shiftInfo);
-    void initFrancisQRStep(Index il, Index iu, const Vector3s& shiftInfo, Index& im, Vector3s& firstHouseholderVector);
-    void performFrancisQRStep(Index il, Index im, Index iu, bool computeU, const Vector3s& firstHouseholderVector, Scalar* workspace);
-};
-
-
-template<typename MatrixType>
-template<typename InputType>
-RealSchur<MatrixType>& RealSchur<MatrixType>::compute(const EigenBase<InputType>& matrix, bool computeU)
-{
-  const Scalar considerAsZero = (std::numeric_limits<Scalar>::min)();
-
-  eigen_assert(matrix.cols() == matrix.rows());
-  Index maxIters = m_maxIters;
-  if (maxIters == -1)
-    maxIters = m_maxIterationsPerRow * matrix.rows();
-
-  Scalar scale = matrix.derived().cwiseAbs().maxCoeff();
-  if(scale<considerAsZero)
-  {
-    m_matT.setZero(matrix.rows(),matrix.cols());
-    if(computeU)
-      m_matU.setIdentity(matrix.rows(),matrix.cols());
-    m_info = Success;
-    m_isInitialized = true;
-    m_matUisUptodate = computeU;
-    return *this;
-  }
-
-  // Step 1. Reduce to Hessenberg form
-  m_hess.compute(matrix.derived()/scale);
-
-  // Step 2. Reduce to real Schur form  
-  computeFromHessenberg(m_hess.matrixH(), m_hess.matrixQ(), computeU);
-
-  m_matT *= scale;
-  
-  return *this;
-}
-template<typename MatrixType>
-template<typename HessMatrixType, typename OrthMatrixType>
-RealSchur<MatrixType>& RealSchur<MatrixType>::computeFromHessenberg(const HessMatrixType& matrixH, const OrthMatrixType& matrixQ,  bool computeU)
-{
-  using std::abs;
-
-  m_matT = matrixH;
-  if(computeU)
-    m_matU = matrixQ;
-  
-  Index maxIters = m_maxIters;
-  if (maxIters == -1)
-    maxIters = m_maxIterationsPerRow * matrixH.rows();
-  m_workspaceVector.resize(m_matT.cols());
-  Scalar* workspace = &m_workspaceVector.coeffRef(0);
-
-  // The matrix m_matT is divided in three parts. 
-  // Rows 0,...,il-1 are decoupled from the rest because m_matT(il,il-1) is zero. 
-  // Rows il,...,iu is the part we are working on (the active window).
-  // Rows iu+1,...,end are already brought in triangular form.
-  Index iu = m_matT.cols() - 1;
-  Index iter = 0;      // iteration count for current eigenvalue
-  Index totalIter = 0; // iteration count for whole matrix
-  Scalar exshift(0);   // sum of exceptional shifts
-  Scalar norm = computeNormOfT();
-
-  if(norm!=Scalar(0))
-  {
-    while (iu >= 0)
-    {
-      Index il = findSmallSubdiagEntry(iu);
-
-      // Check for convergence
-      if (il == iu) // One root found
-      {
-        m_matT.coeffRef(iu,iu) = m_matT.coeff(iu,iu) + exshift;
-        if (iu > 0)
-          m_matT.coeffRef(iu, iu-1) = Scalar(0);
-        iu--;
-        iter = 0;
-      }
-      else if (il == iu-1) // Two roots found
-      {
-        splitOffTwoRows(iu, computeU, exshift);
-        iu -= 2;
-        iter = 0;
-      }
-      else // No convergence yet
-      {
-        // The firstHouseholderVector vector has to be initialized to something to get rid of a silly GCC warning (-O1 -Wall -DNDEBUG )
-        Vector3s firstHouseholderVector = Vector3s::Zero(), shiftInfo;
-        computeShift(iu, iter, exshift, shiftInfo);
-        iter = iter + 1;
-        totalIter = totalIter + 1;
-        if (totalIter > maxIters) break;
-        Index im;
-        initFrancisQRStep(il, iu, shiftInfo, im, firstHouseholderVector);
-        performFrancisQRStep(il, im, iu, computeU, firstHouseholderVector, workspace);
-      }
-    }
-  }
-  if(totalIter <= maxIters)
-    m_info = Success;
-  else
-    m_info = NoConvergence;
-
-  m_isInitialized = true;
-  m_matUisUptodate = computeU;
-  return *this;
-}
-
-/** \internal Computes and returns vector L1 norm of T */
-template<typename MatrixType>
-inline typename MatrixType::Scalar RealSchur<MatrixType>::computeNormOfT()
-{
-  const Index size = m_matT.cols();
-  // FIXME to be efficient the following would requires a triangular reduxion code
-  // Scalar norm = m_matT.upper().cwiseAbs().sum() 
-  //               + m_matT.bottomLeftCorner(size-1,size-1).diagonal().cwiseAbs().sum();
-  Scalar norm(0);
-  for (Index j = 0; j < size; ++j)
-    norm += m_matT.col(j).segment(0, (std::min)(size,j+2)).cwiseAbs().sum();
-  return norm;
-}
-
-/** \internal Look for single small sub-diagonal element and returns its index */
-template<typename MatrixType>
-inline Index RealSchur<MatrixType>::findSmallSubdiagEntry(Index iu)
-{
-  using std::abs;
-  Index res = iu;
-  while (res > 0)
-  {
-    Scalar s = abs(m_matT.coeff(res-1,res-1)) + abs(m_matT.coeff(res,res));
-    if (abs(m_matT.coeff(res,res-1)) <= NumTraits<Scalar>::epsilon() * s)
-      break;
-    res--;
-  }
-  return res;
-}
-
-/** \internal Update T given that rows iu-1 and iu decouple from the rest. */
-template<typename MatrixType>
-inline void RealSchur<MatrixType>::splitOffTwoRows(Index iu, bool computeU, const Scalar& exshift)
-{
-  using std::sqrt;
-  using std::abs;
-  const Index size = m_matT.cols();
-
-  // The eigenvalues of the 2x2 matrix [a b; c d] are 
-  // trace +/- sqrt(discr/4) where discr = tr^2 - 4*det, tr = a + d, det = ad - bc
-  Scalar p = Scalar(0.5) * (m_matT.coeff(iu-1,iu-1) - m_matT.coeff(iu,iu));
-  Scalar q = p * p + m_matT.coeff(iu,iu-1) * m_matT.coeff(iu-1,iu);   // q = tr^2 / 4 - det = discr/4
-  m_matT.coeffRef(iu,iu) += exshift;
-  m_matT.coeffRef(iu-1,iu-1) += exshift;
-
-  if (q >= Scalar(0)) // Two real eigenvalues
-  {
-    Scalar z = sqrt(abs(q));
-    JacobiRotation<Scalar> rot;
-    if (p >= Scalar(0))
-      rot.makeGivens(p + z, m_matT.coeff(iu, iu-1));
-    else
-      rot.makeGivens(p - z, m_matT.coeff(iu, iu-1));
-
-    m_matT.rightCols(size-iu+1).applyOnTheLeft(iu-1, iu, rot.adjoint());
-    m_matT.topRows(iu+1).applyOnTheRight(iu-1, iu, rot);
-    m_matT.coeffRef(iu, iu-1) = Scalar(0); 
-    if (computeU)
-      m_matU.applyOnTheRight(iu-1, iu, rot);
-  }
-
-  if (iu > 1) 
-    m_matT.coeffRef(iu-1, iu-2) = Scalar(0);
-}
-
-/** \internal Form shift in shiftInfo, and update exshift if an exceptional shift is performed. */
-template<typename MatrixType>
-inline void RealSchur<MatrixType>::computeShift(Index iu, Index iter, Scalar& exshift, Vector3s& shiftInfo)
-{
-  using std::sqrt;
-  using std::abs;
-  shiftInfo.coeffRef(0) = m_matT.coeff(iu,iu);
-  shiftInfo.coeffRef(1) = m_matT.coeff(iu-1,iu-1);
-  shiftInfo.coeffRef(2) = m_matT.coeff(iu,iu-1) * m_matT.coeff(iu-1,iu);
-
-  // Wilkinson's original ad hoc shift
-  if (iter == 10)
-  {
-    exshift += shiftInfo.coeff(0);
-    for (Index i = 0; i <= iu; ++i)
-      m_matT.coeffRef(i,i) -= shiftInfo.coeff(0);
-    Scalar s = abs(m_matT.coeff(iu,iu-1)) + abs(m_matT.coeff(iu-1,iu-2));
-    shiftInfo.coeffRef(0) = Scalar(0.75) * s;
-    shiftInfo.coeffRef(1) = Scalar(0.75) * s;
-    shiftInfo.coeffRef(2) = Scalar(-0.4375) * s * s;
-  }
-
-  // MATLAB's new ad hoc shift
-  if (iter == 30)
-  {
-    Scalar s = (shiftInfo.coeff(1) - shiftInfo.coeff(0)) / Scalar(2.0);
-    s = s * s + shiftInfo.coeff(2);
-    if (s > Scalar(0))
-    {
-      s = sqrt(s);
-      if (shiftInfo.coeff(1) < shiftInfo.coeff(0))
-        s = -s;
-      s = s + (shiftInfo.coeff(1) - shiftInfo.coeff(0)) / Scalar(2.0);
-      s = shiftInfo.coeff(0) - shiftInfo.coeff(2) / s;
-      exshift += s;
-      for (Index i = 0; i <= iu; ++i)
-        m_matT.coeffRef(i,i) -= s;
-      shiftInfo.setConstant(Scalar(0.964));
-    }
-  }
-}
-
-/** \internal Compute index im at which Francis QR step starts and the first Householder vector. */
-template<typename MatrixType>
-inline void RealSchur<MatrixType>::initFrancisQRStep(Index il, Index iu, const Vector3s& shiftInfo, Index& im, Vector3s& firstHouseholderVector)
-{
-  using std::abs;
-  Vector3s& v = firstHouseholderVector; // alias to save typing
-
-  for (im = iu-2; im >= il; --im)
-  {
-    const Scalar Tmm = m_matT.coeff(im,im);
-    const Scalar r = shiftInfo.coeff(0) - Tmm;
-    const Scalar s = shiftInfo.coeff(1) - Tmm;
-    v.coeffRef(0) = (r * s - shiftInfo.coeff(2)) / m_matT.coeff(im+1,im) + m_matT.coeff(im,im+1);
-    v.coeffRef(1) = m_matT.coeff(im+1,im+1) - Tmm - r - s;
-    v.coeffRef(2) = m_matT.coeff(im+2,im+1);
-    if (im == il) {
-      break;
-    }
-    const Scalar lhs = m_matT.coeff(im,im-1) * (abs(v.coeff(1)) + abs(v.coeff(2)));
-    const Scalar rhs = v.coeff(0) * (abs(m_matT.coeff(im-1,im-1)) + abs(Tmm) + abs(m_matT.coeff(im+1,im+1)));
-    if (abs(lhs) < NumTraits<Scalar>::epsilon() * rhs)
-      break;
-  }
-}
-
-/** \internal Perform a Francis QR step involving rows il:iu and columns im:iu. */
-template<typename MatrixType>
-inline void RealSchur<MatrixType>::performFrancisQRStep(Index il, Index im, Index iu, bool computeU, const Vector3s& firstHouseholderVector, Scalar* workspace)
-{
-  eigen_assert(im >= il);
-  eigen_assert(im <= iu-2);
-
-  const Index size = m_matT.cols();
-
-  for (Index k = im; k <= iu-2; ++k)
-  {
-    bool firstIteration = (k == im);
-
-    Vector3s v;
-    if (firstIteration)
-      v = firstHouseholderVector;
-    else
-      v = m_matT.template block<3,1>(k,k-1);
-
-    Scalar tau, beta;
-    Matrix<Scalar, 2, 1> ess;
-    v.makeHouseholder(ess, tau, beta);
-    
-    if (beta != Scalar(0)) // if v is not zero
-    {
-      if (firstIteration && k > il)
-        m_matT.coeffRef(k,k-1) = -m_matT.coeff(k,k-1);
-      else if (!firstIteration)
-        m_matT.coeffRef(k,k-1) = beta;
-
-      // These Householder transformations form the O(n^3) part of the algorithm
-      m_matT.block(k, k, 3, size-k).applyHouseholderOnTheLeft(ess, tau, workspace);
-      m_matT.block(0, k, (std::min)(iu,k+3) + 1, 3).applyHouseholderOnTheRight(ess, tau, workspace);
-      if (computeU)
-        m_matU.block(0, k, size, 3).applyHouseholderOnTheRight(ess, tau, workspace);
-    }
-  }
-
-  Matrix<Scalar, 2, 1> v = m_matT.template block<2,1>(iu-1, iu-2);
-  Scalar tau, beta;
-  Matrix<Scalar, 1, 1> ess;
-  v.makeHouseholder(ess, tau, beta);
-
-  if (beta != Scalar(0)) // if v is not zero
-  {
-    m_matT.coeffRef(iu-1, iu-2) = beta;
-    m_matT.block(iu-1, iu-1, 2, size-iu+1).applyHouseholderOnTheLeft(ess, tau, workspace);
-    m_matT.block(0, iu-1, iu+1, 2).applyHouseholderOnTheRight(ess, tau, workspace);
-    if (computeU)
-      m_matU.block(0, iu-1, size, 2).applyHouseholderOnTheRight(ess, tau, workspace);
-  }
-
-  // clean up pollution due to round-off errors
-  for (Index i = im+2; i <= iu; ++i)
-  {
-    m_matT.coeffRef(i,i-2) = Scalar(0);
-    if (i > im+2)
-      m_matT.coeffRef(i,i-3) = Scalar(0);
-  }
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_REAL_SCHUR_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
deleted file mode 100644
index 9ddd553..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
+++ /dev/null
@@ -1,870 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_SELFADJOINTEIGENSOLVER_H
-#define EIGEN_SELFADJOINTEIGENSOLVER_H
-
-#include "./Tridiagonalization.h"
-
-namespace Eigen { 
-
-template<typename _MatrixType>
-class GeneralizedSelfAdjointEigenSolver;
-
-namespace internal {
-template<typename SolverType,int Size,bool IsComplex> struct direct_selfadjoint_eigenvalues;
-template<typename MatrixType, typename DiagType, typename SubDiagType>
-ComputationInfo computeFromTridiagonal_impl(DiagType& diag, SubDiagType& subdiag, const Index maxIterations, bool computeEigenvectors, MatrixType& eivec);
-}
-
-/** \eigenvalues_module \ingroup Eigenvalues_Module
-  *
-  *
-  * \class SelfAdjointEigenSolver
-  *
-  * \brief Computes eigenvalues and eigenvectors of selfadjoint matrices
-  *
-  * \tparam _MatrixType the type of the matrix of which we are computing the
-  * eigendecomposition; this is expected to be an instantiation of the Matrix
-  * class template.
-  *
-  * A matrix \f$ A \f$ is selfadjoint if it equals its adjoint. For real
-  * matrices, this means that the matrix is symmetric: it equals its
-  * transpose. This class computes the eigenvalues and eigenvectors of a
-  * selfadjoint matrix. These are the scalars \f$ \lambda \f$ and vectors
-  * \f$ v \f$ such that \f$ Av = \lambda v \f$.  The eigenvalues of a
-  * selfadjoint matrix are always real. If \f$ D \f$ is a diagonal matrix with
-  * the eigenvalues on the diagonal, and \f$ V \f$ is a matrix with the
-  * eigenvectors as its columns, then \f$ A = V D V^{-1} \f$ (for selfadjoint
-  * matrices, the matrix \f$ V \f$ is always invertible). This is called the
-  * eigendecomposition.
-  *
-  * The algorithm exploits the fact that the matrix is selfadjoint, making it
-  * faster and more accurate than the general purpose eigenvalue algorithms
-  * implemented in EigenSolver and ComplexEigenSolver.
-  *
-  * Only the \b lower \b triangular \b part of the input matrix is referenced.
-  *
-  * Call the function compute() to compute the eigenvalues and eigenvectors of
-  * a given matrix. Alternatively, you can use the
-  * SelfAdjointEigenSolver(const MatrixType&, int) constructor which computes
-  * the eigenvalues and eigenvectors at construction time. Once the eigenvalue
-  * and eigenvectors are computed, they can be retrieved with the eigenvalues()
-  * and eigenvectors() functions.
-  *
-  * The documentation for SelfAdjointEigenSolver(const MatrixType&, int)
-  * contains an example of the typical use of this class.
-  *
-  * To solve the \em generalized eigenvalue problem \f$ Av = \lambda Bv \f$ and
-  * the likes, see the class GeneralizedSelfAdjointEigenSolver.
-  *
-  * \sa MatrixBase::eigenvalues(), class EigenSolver, class ComplexEigenSolver
-  */
-template<typename _MatrixType> class SelfAdjointEigenSolver
-{
-  public:
-
-    typedef _MatrixType MatrixType;
-    enum {
-      Size = MatrixType::RowsAtCompileTime,
-      ColsAtCompileTime = MatrixType::ColsAtCompileTime,
-      Options = MatrixType::Options,
-      MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
-    };
-    
-    /** \brief Scalar type for matrices of type \p _MatrixType. */
-    typedef typename MatrixType::Scalar Scalar;
-    typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
-    
-    typedef Matrix<Scalar,Size,Size,ColMajor,MaxColsAtCompileTime,MaxColsAtCompileTime> EigenvectorsType;
-
-    /** \brief Real scalar type for \p _MatrixType.
-      *
-      * This is just \c Scalar if #Scalar is real (e.g., \c float or
-      * \c double), and the type of the real part of \c Scalar if #Scalar is
-      * complex.
-      */
-    typedef typename NumTraits<Scalar>::Real RealScalar;
-    
-    friend struct internal::direct_selfadjoint_eigenvalues<SelfAdjointEigenSolver,Size,NumTraits<Scalar>::IsComplex>;
-
-    /** \brief Type for vector of eigenvalues as returned by eigenvalues().
-      *
-      * This is a column vector with entries of type #RealScalar.
-      * The length of the vector is the size of \p _MatrixType.
-      */
-    typedef typename internal::plain_col_type<MatrixType, RealScalar>::type RealVectorType;
-    typedef Tridiagonalization<MatrixType> TridiagonalizationType;
-    typedef typename TridiagonalizationType::SubDiagonalType SubDiagonalType;
-
-    /** \brief Default constructor for fixed-size matrices.
-      *
-      * The default constructor is useful in cases in which the user intends to
-      * perform decompositions via compute(). This constructor
-      * can only be used if \p _MatrixType is a fixed-size matrix; use
-      * SelfAdjointEigenSolver(Index) for dynamic-size matrices.
-      *
-      * Example: \include SelfAdjointEigenSolver_SelfAdjointEigenSolver.cpp
-      * Output: \verbinclude SelfAdjointEigenSolver_SelfAdjointEigenSolver.out
-      */
-    EIGEN_DEVICE_FUNC
-    SelfAdjointEigenSolver()
-        : m_eivec(),
-          m_eivalues(),
-          m_subdiag(),
-          m_isInitialized(false)
-    { }
-
-    /** \brief Constructor, pre-allocates memory for dynamic-size matrices.
-      *
-      * \param [in]  size  Positive integer, size of the matrix whose
-      * eigenvalues and eigenvectors will be computed.
-      *
-      * This constructor is useful for dynamic-size matrices, when the user
-      * intends to perform decompositions via compute(). The \p size
-      * parameter is only used as a hint. It is not an error to give a wrong
-      * \p size, but it may impair performance.
-      *
-      * \sa compute() for an example
-      */
-    EIGEN_DEVICE_FUNC
-    explicit SelfAdjointEigenSolver(Index size)
-        : m_eivec(size, size),
-          m_eivalues(size),
-          m_subdiag(size > 1 ? size - 1 : 1),
-          m_isInitialized(false)
-    {}
-
-    /** \brief Constructor; computes eigendecomposition of given matrix.
-      *
-      * \param[in]  matrix  Selfadjoint matrix whose eigendecomposition is to
-      *    be computed. Only the lower triangular part of the matrix is referenced.
-      * \param[in]  options Can be #ComputeEigenvectors (default) or #EigenvaluesOnly.
-      *
-      * This constructor calls compute(const MatrixType&, int) to compute the
-      * eigenvalues of the matrix \p matrix. The eigenvectors are computed if
-      * \p options equals #ComputeEigenvectors.
-      *
-      * Example: \include SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType.cpp
-      * Output: \verbinclude SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType.out
-      *
-      * \sa compute(const MatrixType&, int)
-      */
-    template<typename InputType>
-    EIGEN_DEVICE_FUNC
-    explicit SelfAdjointEigenSolver(const EigenBase<InputType>& matrix, int options = ComputeEigenvectors)
-      : m_eivec(matrix.rows(), matrix.cols()),
-        m_eivalues(matrix.cols()),
-        m_subdiag(matrix.rows() > 1 ? matrix.rows() - 1 : 1),
-        m_isInitialized(false)
-    {
-      compute(matrix.derived(), options);
-    }
-
-    /** \brief Computes eigendecomposition of given matrix.
-      *
-      * \param[in]  matrix  Selfadjoint matrix whose eigendecomposition is to
-      *    be computed. Only the lower triangular part of the matrix is referenced.
-      * \param[in]  options Can be #ComputeEigenvectors (default) or #EigenvaluesOnly.
-      * \returns    Reference to \c *this
-      *
-      * This function computes the eigenvalues of \p matrix.  The eigenvalues()
-      * function can be used to retrieve them.  If \p options equals #ComputeEigenvectors,
-      * then the eigenvectors are also computed and can be retrieved by
-      * calling eigenvectors().
-      *
-      * This implementation uses a symmetric QR algorithm. The matrix is first
-      * reduced to tridiagonal form using the Tridiagonalization class. The
-      * tridiagonal matrix is then brought to diagonal form with implicit
-      * symmetric QR steps with Wilkinson shift. Details can be found in
-      * Section 8.3 of Golub \& Van Loan, <i>%Matrix Computations</i>.
-      *
-      * The cost of the computation is about \f$ 9n^3 \f$ if the eigenvectors
-      * are required and \f$ 4n^3/3 \f$ if they are not required.
-      *
-      * This method reuses the memory in the SelfAdjointEigenSolver object that
-      * was allocated when the object was constructed, if the size of the
-      * matrix does not change.
-      *
-      * Example: \include SelfAdjointEigenSolver_compute_MatrixType.cpp
-      * Output: \verbinclude SelfAdjointEigenSolver_compute_MatrixType.out
-      *
-      * \sa SelfAdjointEigenSolver(const MatrixType&, int)
-      */
-    template<typename InputType>
-    EIGEN_DEVICE_FUNC
-    SelfAdjointEigenSolver& compute(const EigenBase<InputType>& matrix, int options = ComputeEigenvectors);
-    
-    /** \brief Computes eigendecomposition of given matrix using a closed-form algorithm
-      *
-      * This is a variant of compute(const MatrixType&, int options) which
-      * directly solves the underlying polynomial equation.
-      * 
-      * Currently only 2x2 and 3x3 matrices for which the sizes are known at compile time are supported (e.g., Matrix3d).
-      * 
-      * This method is usually significantly faster than the QR iterative algorithm
-      * but it might also be less accurate. It is also worth noting that
-      * for 3x3 matrices it involves trigonometric operations which are
-      * not necessarily available for all scalar types.
-      * 
-      * For the 3x3 case, we observed the following worst case relative error regarding the eigenvalues:
-      *   - double: 1e-8
-      *   - float:  1e-3
-      *
-      * \sa compute(const MatrixType&, int options)
-      */
-    EIGEN_DEVICE_FUNC
-    SelfAdjointEigenSolver& computeDirect(const MatrixType& matrix, int options = ComputeEigenvectors);
-
-    /**
-      *\brief Computes the eigen decomposition from a tridiagonal symmetric matrix
-      *
-      * \param[in] diag The vector containing the diagonal of the matrix.
-      * \param[in] subdiag The subdiagonal of the matrix.
-      * \param[in] options Can be #ComputeEigenvectors (default) or #EigenvaluesOnly.
-      * \returns Reference to \c *this
-      *
-      * This function assumes that the matrix has been reduced to tridiagonal form.
-      *
-      * \sa compute(const MatrixType&, int) for more information
-      */
-    SelfAdjointEigenSolver& computeFromTridiagonal(const RealVectorType& diag, const SubDiagonalType& subdiag , int options=ComputeEigenvectors);
-
-    /** \brief Returns the eigenvectors of given matrix.
-      *
-      * \returns  A const reference to the matrix whose columns are the eigenvectors.
-      *
-      * \pre The eigenvectors have been computed before.
-      *
-      * Column \f$ k \f$ of the returned matrix is an eigenvector corresponding
-      * to eigenvalue number \f$ k \f$ as returned by eigenvalues().  The
-      * eigenvectors are normalized to have (Euclidean) norm equal to one. If
-      * this object was used to solve the eigenproblem for the selfadjoint
-      * matrix \f$ A \f$, then the matrix returned by this function is the
-      * matrix \f$ V \f$ in the eigendecomposition \f$ A = V D V^{-1} \f$.
-      *
-      * Example: \include SelfAdjointEigenSolver_eigenvectors.cpp
-      * Output: \verbinclude SelfAdjointEigenSolver_eigenvectors.out
-      *
-      * \sa eigenvalues()
-      */
-    EIGEN_DEVICE_FUNC
-    const EigenvectorsType& eigenvectors() const
-    {
-      eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized.");
-      eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues.");
-      return m_eivec;
-    }
-
-    /** \brief Returns the eigenvalues of given matrix.
-      *
-      * \returns A const reference to the column vector containing the eigenvalues.
-      *
-      * \pre The eigenvalues have been computed before.
-      *
-      * The eigenvalues are repeated according to their algebraic multiplicity,
-      * so there are as many eigenvalues as rows in the matrix. The eigenvalues
-      * are sorted in increasing order.
-      *
-      * Example: \include SelfAdjointEigenSolver_eigenvalues.cpp
-      * Output: \verbinclude SelfAdjointEigenSolver_eigenvalues.out
-      *
-      * \sa eigenvectors(), MatrixBase::eigenvalues()
-      */
-    EIGEN_DEVICE_FUNC
-    const RealVectorType& eigenvalues() const
-    {
-      eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized.");
-      return m_eivalues;
-    }
-
-    /** \brief Computes the positive-definite square root of the matrix.
-      *
-      * \returns the positive-definite square root of the matrix
-      *
-      * \pre The eigenvalues and eigenvectors of a positive-definite matrix
-      * have been computed before.
-      *
-      * The square root of a positive-definite matrix \f$ A \f$ is the
-      * positive-definite matrix whose square equals \f$ A \f$. This function
-      * uses the eigendecomposition \f$ A = V D V^{-1} \f$ to compute the
-      * square root as \f$ A^{1/2} = V D^{1/2} V^{-1} \f$.
-      *
-      * Example: \include SelfAdjointEigenSolver_operatorSqrt.cpp
-      * Output: \verbinclude SelfAdjointEigenSolver_operatorSqrt.out
-      *
-      * \sa operatorInverseSqrt(), <a href="unsupported/group__MatrixFunctions__Module.html">MatrixFunctions Module</a>
-      */
-    EIGEN_DEVICE_FUNC
-    MatrixType operatorSqrt() const
-    {
-      eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized.");
-      eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues.");
-      return m_eivec * m_eivalues.cwiseSqrt().asDiagonal() * m_eivec.adjoint();
-    }
-
-    /** \brief Computes the inverse square root of the matrix.
-      *
-      * \returns the inverse positive-definite square root of the matrix
-      *
-      * \pre The eigenvalues and eigenvectors of a positive-definite matrix
-      * have been computed before.
-      *
-      * This function uses the eigendecomposition \f$ A = V D V^{-1} \f$ to
-      * compute the inverse square root as \f$ V D^{-1/2} V^{-1} \f$. This is
-      * cheaper than first computing the square root with operatorSqrt() and
-      * then its inverse with MatrixBase::inverse().
-      *
-      * Example: \include SelfAdjointEigenSolver_operatorInverseSqrt.cpp
-      * Output: \verbinclude SelfAdjointEigenSolver_operatorInverseSqrt.out
-      *
-      * \sa operatorSqrt(), MatrixBase::inverse(), <a href="unsupported/group__MatrixFunctions__Module.html">MatrixFunctions Module</a>
-      */
-    EIGEN_DEVICE_FUNC
-    MatrixType operatorInverseSqrt() const
-    {
-      eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized.");
-      eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues.");
-      return m_eivec * m_eivalues.cwiseInverse().cwiseSqrt().asDiagonal() * m_eivec.adjoint();
-    }
-
-    /** \brief Reports whether previous computation was successful.
-      *
-      * \returns \c Success if computation was succesful, \c NoConvergence otherwise.
-      */
-    EIGEN_DEVICE_FUNC
-    ComputationInfo info() const
-    {
-      eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized.");
-      return m_info;
-    }
-
-    /** \brief Maximum number of iterations.
-      *
-      * The algorithm terminates if it does not converge within m_maxIterations * n iterations, where n
-      * denotes the size of the matrix. This value is currently set to 30 (copied from LAPACK).
-      */
-    static const int m_maxIterations = 30;
-
-  protected:
-    static void check_template_parameters()
-    {
-      EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
-    }
-    
-    EigenvectorsType m_eivec;
-    RealVectorType m_eivalues;
-    typename TridiagonalizationType::SubDiagonalType m_subdiag;
-    ComputationInfo m_info;
-    bool m_isInitialized;
-    bool m_eigenvectorsOk;
-};
-
-namespace internal {
-/** \internal
-  *
-  * \eigenvalues_module \ingroup Eigenvalues_Module
-  *
-  * Performs a QR step on a tridiagonal symmetric matrix represented as a
-  * pair of two vectors \a diag and \a subdiag.
-  *
-  * \param diag the diagonal part of the input selfadjoint tridiagonal matrix
-  * \param subdiag the sub-diagonal part of the input selfadjoint tridiagonal matrix
-  * \param start starting index of the submatrix to work on
-  * \param end last+1 index of the submatrix to work on
-  * \param matrixQ pointer to the column-major matrix holding the eigenvectors, can be 0
-  * \param n size of the input matrix
-  *
-  * For compilation efficiency reasons, this procedure does not use eigen expression
-  * for its arguments.
-  *
-  * Implemented from Golub's "Matrix Computations", algorithm 8.3.2:
-  * "implicit symmetric QR step with Wilkinson shift"
-  */
-template<int StorageOrder,typename RealScalar, typename Scalar, typename Index>
-EIGEN_DEVICE_FUNC
-static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n);
-}
-
-template<typename MatrixType>
-template<typename InputType>
-EIGEN_DEVICE_FUNC
-SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
-::compute(const EigenBase<InputType>& a_matrix, int options)
-{
-  check_template_parameters();
-  
-  const InputType &matrix(a_matrix.derived());
-  
-  using std::abs;
-  eigen_assert(matrix.cols() == matrix.rows());
-  eigen_assert((options&~(EigVecMask|GenEigMask))==0
-          && (options&EigVecMask)!=EigVecMask
-          && "invalid option parameter");
-  bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors;
-  Index n = matrix.cols();
-  m_eivalues.resize(n,1);
-
-  if(n==1)
-  {
-    m_eivec = matrix;
-    m_eivalues.coeffRef(0,0) = numext::real(m_eivec.coeff(0,0));
-    if(computeEigenvectors)
-      m_eivec.setOnes(n,n);
-    m_info = Success;
-    m_isInitialized = true;
-    m_eigenvectorsOk = computeEigenvectors;
-    return *this;
-  }
-
-  // declare some aliases
-  RealVectorType& diag = m_eivalues;
-  EigenvectorsType& mat = m_eivec;
-
-  // map the matrix coefficients to [-1:1] to avoid over- and underflow.
-  mat = matrix.template triangularView<Lower>();
-  RealScalar scale = mat.cwiseAbs().maxCoeff();
-  if(scale==RealScalar(0)) scale = RealScalar(1);
-  mat.template triangularView<Lower>() /= scale;
-  m_subdiag.resize(n-1);
-  internal::tridiagonalization_inplace(mat, diag, m_subdiag, computeEigenvectors);
-
-  m_info = internal::computeFromTridiagonal_impl(diag, m_subdiag, m_maxIterations, computeEigenvectors, m_eivec);
-  
-  // scale back the eigen values
-  m_eivalues *= scale;
-
-  m_isInitialized = true;
-  m_eigenvectorsOk = computeEigenvectors;
-  return *this;
-}
-
-template<typename MatrixType>
-SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
-::computeFromTridiagonal(const RealVectorType& diag, const SubDiagonalType& subdiag , int options)
-{
-  //TODO : Add an option to scale the values beforehand
-  bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors;
-
-  m_eivalues = diag;
-  m_subdiag = subdiag;
-  if (computeEigenvectors)
-  {
-    m_eivec.setIdentity(diag.size(), diag.size());
-  }
-  m_info = internal::computeFromTridiagonal_impl(m_eivalues, m_subdiag, m_maxIterations, computeEigenvectors, m_eivec);
-
-  m_isInitialized = true;
-  m_eigenvectorsOk = computeEigenvectors;
-  return *this;
-}
-
-namespace internal {
-/**
-  * \internal
-  * \brief Compute the eigendecomposition from a tridiagonal matrix
-  *
-  * \param[in,out] diag : On input, the diagonal of the matrix, on output the eigenvalues
-  * \param[in,out] subdiag : The subdiagonal part of the matrix (entries are modified during the decomposition)
-  * \param[in] maxIterations : the maximum number of iterations
-  * \param[in] computeEigenvectors : whether the eigenvectors have to be computed or not
-  * \param[out] eivec : The matrix to store the eigenvectors if computeEigenvectors==true. Must be allocated on input.
-  * \returns \c Success or \c NoConvergence
-  */
-template<typename MatrixType, typename DiagType, typename SubDiagType>
-ComputationInfo computeFromTridiagonal_impl(DiagType& diag, SubDiagType& subdiag, const Index maxIterations, bool computeEigenvectors, MatrixType& eivec)
-{
-  using std::abs;
-
-  ComputationInfo info;
-  typedef typename MatrixType::Scalar Scalar;
-
-  Index n = diag.size();
-  Index end = n-1;
-  Index start = 0;
-  Index iter = 0; // total number of iterations
-  
-  typedef typename DiagType::RealScalar RealScalar;
-  const RealScalar considerAsZero = (std::numeric_limits<RealScalar>::min)();
-  const RealScalar precision = RealScalar(2)*NumTraits<RealScalar>::epsilon();
-  
-  while (end>0)
-  {
-    for (Index i = start; i<end; ++i)
-      if (internal::isMuchSmallerThan(abs(subdiag[i]),(abs(diag[i])+abs(diag[i+1])),precision) || abs(subdiag[i]) <= considerAsZero)
-        subdiag[i] = 0;
-
-    // find the largest unreduced block
-    while (end>0 && subdiag[end-1]==RealScalar(0))
-    {
-      end--;
-    }
-    if (end<=0)
-      break;
-
-    // if we spent too many iterations, we give up
-    iter++;
-    if(iter > maxIterations * n) break;
-
-    start = end - 1;
-    while (start>0 && subdiag[start-1]!=0)
-      start--;
-
-    internal::tridiagonal_qr_step<MatrixType::Flags&RowMajorBit ? RowMajor : ColMajor>(diag.data(), subdiag.data(), start, end, computeEigenvectors ? eivec.data() : (Scalar*)0, n);
-  }
-  if (iter <= maxIterations * n)
-    info = Success;
-  else
-    info = NoConvergence;
-
-  // Sort eigenvalues and corresponding vectors.
-  // TODO make the sort optional ?
-  // TODO use a better sort algorithm !!
-  if (info == Success)
-  {
-    for (Index i = 0; i < n-1; ++i)
-    {
-      Index k;
-      diag.segment(i,n-i).minCoeff(&k);
-      if (k > 0)
-      {
-        std::swap(diag[i], diag[k+i]);
-        if(computeEigenvectors)
-          eivec.col(i).swap(eivec.col(k+i));
-      }
-    }
-  }
-  return info;
-}
-  
-template<typename SolverType,int Size,bool IsComplex> struct direct_selfadjoint_eigenvalues
-{
-  EIGEN_DEVICE_FUNC
-  static inline void run(SolverType& eig, const typename SolverType::MatrixType& A, int options)
-  { eig.compute(A,options); }
-};
-
-template<typename SolverType> struct direct_selfadjoint_eigenvalues<SolverType,3,false>
-{
-  typedef typename SolverType::MatrixType MatrixType;
-  typedef typename SolverType::RealVectorType VectorType;
-  typedef typename SolverType::Scalar Scalar;
-  typedef typename SolverType::EigenvectorsType EigenvectorsType;
-  
-
-  /** \internal
-   * Computes the roots of the characteristic polynomial of \a m.
-   * For numerical stability m.trace() should be near zero and to avoid over- or underflow m should be normalized.
-   */
-  EIGEN_DEVICE_FUNC
-  static inline void computeRoots(const MatrixType& m, VectorType& roots)
-  {
-    EIGEN_USING_STD_MATH(sqrt)
-    EIGEN_USING_STD_MATH(atan2)
-    EIGEN_USING_STD_MATH(cos)
-    EIGEN_USING_STD_MATH(sin)
-    const Scalar s_inv3 = Scalar(1)/Scalar(3);
-    const Scalar s_sqrt3 = sqrt(Scalar(3));
-
-    // The characteristic equation is x^3 - c2*x^2 + c1*x - c0 = 0.  The
-    // eigenvalues are the roots to this equation, all guaranteed to be
-    // real-valued, because the matrix is symmetric.
-    Scalar c0 = m(0,0)*m(1,1)*m(2,2) + Scalar(2)*m(1,0)*m(2,0)*m(2,1) - m(0,0)*m(2,1)*m(2,1) - m(1,1)*m(2,0)*m(2,0) - m(2,2)*m(1,0)*m(1,0);
-    Scalar c1 = m(0,0)*m(1,1) - m(1,0)*m(1,0) + m(0,0)*m(2,2) - m(2,0)*m(2,0) + m(1,1)*m(2,2) - m(2,1)*m(2,1);
-    Scalar c2 = m(0,0) + m(1,1) + m(2,2);
-
-    // Construct the parameters used in classifying the roots of the equation
-    // and in solving the equation for the roots in closed form.
-    Scalar c2_over_3 = c2*s_inv3;
-    Scalar a_over_3 = (c2*c2_over_3 - c1)*s_inv3;
-    a_over_3 = numext::maxi(a_over_3, Scalar(0));
-
-    Scalar half_b = Scalar(0.5)*(c0 + c2_over_3*(Scalar(2)*c2_over_3*c2_over_3 - c1));
-
-    Scalar q = a_over_3*a_over_3*a_over_3 - half_b*half_b;
-    q = numext::maxi(q, Scalar(0));
-
-    // Compute the eigenvalues by solving for the roots of the polynomial.
-    Scalar rho = sqrt(a_over_3);
-    Scalar theta = atan2(sqrt(q),half_b)*s_inv3;  // since sqrt(q) > 0, atan2 is in [0, pi] and theta is in [0, pi/3]
-    Scalar cos_theta = cos(theta);
-    Scalar sin_theta = sin(theta);
-    // roots are already sorted, since cos is monotonically decreasing on [0, pi]
-    roots(0) = c2_over_3 - rho*(cos_theta + s_sqrt3*sin_theta); // == 2*rho*cos(theta+2pi/3)
-    roots(1) = c2_over_3 - rho*(cos_theta - s_sqrt3*sin_theta); // == 2*rho*cos(theta+ pi/3)
-    roots(2) = c2_over_3 + Scalar(2)*rho*cos_theta;
-  }
-
-  EIGEN_DEVICE_FUNC
-  static inline bool extract_kernel(MatrixType& mat, Ref<VectorType> res, Ref<VectorType> representative)
-  {
-    using std::abs;
-    Index i0;
-    // Find non-zero column i0 (by construction, there must exist a non zero coefficient on the diagonal):
-    mat.diagonal().cwiseAbs().maxCoeff(&i0);
-    // mat.col(i0) is a good candidate for an orthogonal vector to the current eigenvector,
-    // so let's save it:
-    representative = mat.col(i0);
-    Scalar n0, n1;
-    VectorType c0, c1;
-    n0 = (c0 = representative.cross(mat.col((i0+1)%3))).squaredNorm();
-    n1 = (c1 = representative.cross(mat.col((i0+2)%3))).squaredNorm();
-    if(n0>n1) res = c0/std::sqrt(n0);
-    else      res = c1/std::sqrt(n1);
-
-    return true;
-  }
-
-  EIGEN_DEVICE_FUNC
-  static inline void run(SolverType& solver, const MatrixType& mat, int options)
-  {
-    eigen_assert(mat.cols() == 3 && mat.cols() == mat.rows());
-    eigen_assert((options&~(EigVecMask|GenEigMask))==0
-            && (options&EigVecMask)!=EigVecMask
-            && "invalid option parameter");
-    bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors;
-    
-    EigenvectorsType& eivecs = solver.m_eivec;
-    VectorType& eivals = solver.m_eivalues;
-  
-    // Shift the matrix to the mean eigenvalue and map the matrix coefficients to [-1:1] to avoid over- and underflow.
-    Scalar shift = mat.trace() / Scalar(3);
-    // TODO Avoid this copy. Currently it is necessary to suppress bogus values when determining maxCoeff and for computing the eigenvectors later
-    MatrixType scaledMat = mat.template selfadjointView<Lower>();
-    scaledMat.diagonal().array() -= shift;
-    Scalar scale = scaledMat.cwiseAbs().maxCoeff();
-    if(scale > 0) scaledMat /= scale;   // TODO for scale==0 we could save the remaining operations
-
-    // compute the eigenvalues
-    computeRoots(scaledMat,eivals);
-
-    // compute the eigenvectors
-    if(computeEigenvectors)
-    {
-      if((eivals(2)-eivals(0))<=Eigen::NumTraits<Scalar>::epsilon())
-      {
-        // All three eigenvalues are numerically the same
-        eivecs.setIdentity();
-      }
-      else
-      {
-        MatrixType tmp;
-        tmp = scaledMat;
-
-        // Compute the eigenvector of the most distinct eigenvalue
-        Scalar d0 = eivals(2) - eivals(1);
-        Scalar d1 = eivals(1) - eivals(0);
-        Index k(0), l(2);
-        if(d0 > d1)
-        {
-          numext::swap(k,l);
-          d0 = d1;
-        }
-
-        // Compute the eigenvector of index k
-        {
-          tmp.diagonal().array () -= eivals(k);
-          // By construction, 'tmp' is of rank 2, and its kernel corresponds to the respective eigenvector.
-          extract_kernel(tmp, eivecs.col(k), eivecs.col(l));
-        }
-
-        // Compute eigenvector of index l
-        if(d0<=2*Eigen::NumTraits<Scalar>::epsilon()*d1)
-        {
-          // If d0 is too small, then the two other eigenvalues are numerically the same,
-          // and thus we only have to ortho-normalize the near orthogonal vector we saved above.
-          eivecs.col(l) -= eivecs.col(k).dot(eivecs.col(l))*eivecs.col(l);
-          eivecs.col(l).normalize();
-        }
-        else
-        {
-          tmp = scaledMat;
-          tmp.diagonal().array () -= eivals(l);
-
-          VectorType dummy;
-          extract_kernel(tmp, eivecs.col(l), dummy);
-        }
-
-        // Compute last eigenvector from the other two
-        eivecs.col(1) = eivecs.col(2).cross(eivecs.col(0)).normalized();
-      }
-    }
-
-    // Rescale back to the original size.
-    eivals *= scale;
-    eivals.array() += shift;
-    
-    solver.m_info = Success;
-    solver.m_isInitialized = true;
-    solver.m_eigenvectorsOk = computeEigenvectors;
-  }
-};
-
-// 2x2 direct eigenvalues decomposition, code from Hauke Heibel
-template<typename SolverType> 
-struct direct_selfadjoint_eigenvalues<SolverType,2,false>
-{
-  typedef typename SolverType::MatrixType MatrixType;
-  typedef typename SolverType::RealVectorType VectorType;
-  typedef typename SolverType::Scalar Scalar;
-  typedef typename SolverType::EigenvectorsType EigenvectorsType;
-  
-  EIGEN_DEVICE_FUNC
-  static inline void computeRoots(const MatrixType& m, VectorType& roots)
-  {
-    using std::sqrt;
-    const Scalar t0 = Scalar(0.5) * sqrt( numext::abs2(m(0,0)-m(1,1)) + Scalar(4)*numext::abs2(m(1,0)));
-    const Scalar t1 = Scalar(0.5) * (m(0,0) + m(1,1));
-    roots(0) = t1 - t0;
-    roots(1) = t1 + t0;
-  }
-  
-  EIGEN_DEVICE_FUNC
-  static inline void run(SolverType& solver, const MatrixType& mat, int options)
-  {
-    EIGEN_USING_STD_MATH(sqrt);
-    EIGEN_USING_STD_MATH(abs);
-    
-    eigen_assert(mat.cols() == 2 && mat.cols() == mat.rows());
-    eigen_assert((options&~(EigVecMask|GenEigMask))==0
-            && (options&EigVecMask)!=EigVecMask
-            && "invalid option parameter");
-    bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors;
-    
-    EigenvectorsType& eivecs = solver.m_eivec;
-    VectorType& eivals = solver.m_eivalues;
-  
-    // Shift the matrix to the mean eigenvalue and map the matrix coefficients to [-1:1] to avoid over- and underflow.
-    Scalar shift = mat.trace() / Scalar(2);
-    MatrixType scaledMat = mat;
-    scaledMat.coeffRef(0,1) = mat.coeff(1,0);
-    scaledMat.diagonal().array() -= shift;
-    Scalar scale = scaledMat.cwiseAbs().maxCoeff();
-    if(scale > Scalar(0))
-      scaledMat /= scale;
-
-    // Compute the eigenvalues
-    computeRoots(scaledMat,eivals);
-
-    // compute the eigen vectors
-    if(computeEigenvectors)
-    {
-      if((eivals(1)-eivals(0))<=abs(eivals(1))*Eigen::NumTraits<Scalar>::epsilon())
-      {
-        eivecs.setIdentity();
-      }
-      else
-      {
-        scaledMat.diagonal().array () -= eivals(1);
-        Scalar a2 = numext::abs2(scaledMat(0,0));
-        Scalar c2 = numext::abs2(scaledMat(1,1));
-        Scalar b2 = numext::abs2(scaledMat(1,0));
-        if(a2>c2)
-        {
-          eivecs.col(1) << -scaledMat(1,0), scaledMat(0,0);
-          eivecs.col(1) /= sqrt(a2+b2);
-        }
-        else
-        {
-          eivecs.col(1) << -scaledMat(1,1), scaledMat(1,0);
-          eivecs.col(1) /= sqrt(c2+b2);
-        }
-
-        eivecs.col(0) << eivecs.col(1).unitOrthogonal();
-      }
-    }
-
-    // Rescale back to the original size.
-    eivals *= scale;
-    eivals.array() += shift;
-
-    solver.m_info = Success;
-    solver.m_isInitialized = true;
-    solver.m_eigenvectorsOk = computeEigenvectors;
-  }
-};
-
-}
-
-template<typename MatrixType>
-EIGEN_DEVICE_FUNC
-SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
-::computeDirect(const MatrixType& matrix, int options)
-{
-  internal::direct_selfadjoint_eigenvalues<SelfAdjointEigenSolver,Size,NumTraits<Scalar>::IsComplex>::run(*this,matrix,options);
-  return *this;
-}
-
-namespace internal {
-template<int StorageOrder,typename RealScalar, typename Scalar, typename Index>
-EIGEN_DEVICE_FUNC
-static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n)
-{
-  using std::abs;
-  RealScalar td = (diag[end-1] - diag[end])*RealScalar(0.5);
-  RealScalar e = subdiag[end-1];
-  // Note that thanks to scaling, e^2 or td^2 cannot overflow, however they can still
-  // underflow thus leading to inf/NaN values when using the following commented code:
-//   RealScalar e2 = numext::abs2(subdiag[end-1]);
-//   RealScalar mu = diag[end] - e2 / (td + (td>0 ? 1 : -1) * sqrt(td*td + e2));
-  // This explain the following, somewhat more complicated, version:
-  RealScalar mu = diag[end];
-  if(td==RealScalar(0))
-    mu -= abs(e);
-  else
-  {
-    RealScalar e2 = numext::abs2(subdiag[end-1]);
-    RealScalar h = numext::hypot(td,e);
-    if(e2==RealScalar(0)) mu -= (e / (td + (td>RealScalar(0) ? RealScalar(1) : RealScalar(-1)))) * (e / h);
-    else                  mu -= e2 / (td + (td>RealScalar(0) ? h : -h));
-  }
-  
-  RealScalar x = diag[start] - mu;
-  RealScalar z = subdiag[start];
-  for (Index k = start; k < end; ++k)
-  {
-    JacobiRotation<RealScalar> rot;
-    rot.makeGivens(x, z);
-
-    // do T = G' T G
-    RealScalar sdk = rot.s() * diag[k] + rot.c() * subdiag[k];
-    RealScalar dkp1 = rot.s() * subdiag[k] + rot.c() * diag[k+1];
-
-    diag[k] = rot.c() * (rot.c() * diag[k] - rot.s() * subdiag[k]) - rot.s() * (rot.c() * subdiag[k] - rot.s() * diag[k+1]);
-    diag[k+1] = rot.s() * sdk + rot.c() * dkp1;
-    subdiag[k] = rot.c() * sdk - rot.s() * dkp1;
-    
-
-    if (k > start)
-      subdiag[k - 1] = rot.c() * subdiag[k-1] - rot.s() * z;
-
-    x = subdiag[k];
-
-    if (k < end - 1)
-    {
-      z = -rot.s() * subdiag[k+1];
-      subdiag[k + 1] = rot.c() * subdiag[k+1];
-    }
-    
-    // apply the givens rotation to the unit matrix Q = Q * G
-    if (matrixQ)
-    {
-      // FIXME if StorageOrder == RowMajor this operation is not very efficient
-      Map<Matrix<Scalar,Dynamic,Dynamic,StorageOrder> > q(matrixQ,n,n);
-      q.applyOnTheRight(k,k+1,rot);
-    }
-  }
-}
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_SELFADJOINTEIGENSOLVER_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/Tridiagonalization.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/Tridiagonalization.h
deleted file mode 100644
index 1d102c1..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Eigenvalues/Tridiagonalization.h
+++ /dev/null
@@ -1,556 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_TRIDIAGONALIZATION_H
-#define EIGEN_TRIDIAGONALIZATION_H
-
-namespace Eigen { 
-
-namespace internal {
-  
-template<typename MatrixType> struct TridiagonalizationMatrixTReturnType;
-template<typename MatrixType>
-struct traits<TridiagonalizationMatrixTReturnType<MatrixType> >
-  : public traits<typename MatrixType::PlainObject>
-{
-  typedef typename MatrixType::PlainObject ReturnType; // FIXME shall it be a BandMatrix?
-  enum { Flags = 0 };
-};
-
-template<typename MatrixType, typename CoeffVectorType>
-void tridiagonalization_inplace(MatrixType& matA, CoeffVectorType& hCoeffs);
-}
-
-/** \eigenvalues_module \ingroup Eigenvalues_Module
-  *
-  *
-  * \class Tridiagonalization
-  *
-  * \brief Tridiagonal decomposition of a selfadjoint matrix
-  *
-  * \tparam _MatrixType the type of the matrix of which we are computing the
-  * tridiagonal decomposition; this is expected to be an instantiation of the
-  * Matrix class template.
-  *
-  * This class performs a tridiagonal decomposition of a selfadjoint matrix \f$ A \f$ such that:
-  * \f$ A = Q T Q^* \f$ where \f$ Q \f$ is unitary and \f$ T \f$ a real symmetric tridiagonal matrix.
-  *
-  * A tridiagonal matrix is a matrix which has nonzero elements only on the
-  * main diagonal and the first diagonal below and above it. The Hessenberg
-  * decomposition of a selfadjoint matrix is in fact a tridiagonal
-  * decomposition. This class is used in SelfAdjointEigenSolver to compute the
-  * eigenvalues and eigenvectors of a selfadjoint matrix.
-  *
-  * Call the function compute() to compute the tridiagonal decomposition of a
-  * given matrix. Alternatively, you can use the Tridiagonalization(const MatrixType&)
-  * constructor which computes the tridiagonal Schur decomposition at
-  * construction time. Once the decomposition is computed, you can use the
-  * matrixQ() and matrixT() functions to retrieve the matrices Q and T in the
-  * decomposition.
-  *
-  * The documentation of Tridiagonalization(const MatrixType&) contains an
-  * example of the typical use of this class.
-  *
-  * \sa class HessenbergDecomposition, class SelfAdjointEigenSolver
-  */
-template<typename _MatrixType> class Tridiagonalization
-{
-  public:
-
-    /** \brief Synonym for the template parameter \p _MatrixType. */
-    typedef _MatrixType MatrixType;
-
-    typedef typename MatrixType::Scalar Scalar;
-    typedef typename NumTraits<Scalar>::Real RealScalar;
-    typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
-
-    enum {
-      Size = MatrixType::RowsAtCompileTime,
-      SizeMinusOne = Size == Dynamic ? Dynamic : (Size > 1 ? Size - 1 : 1),
-      Options = MatrixType::Options,
-      MaxSize = MatrixType::MaxRowsAtCompileTime,
-      MaxSizeMinusOne = MaxSize == Dynamic ? Dynamic : (MaxSize > 1 ? MaxSize - 1 : 1)
-    };
-
-    typedef Matrix<Scalar, SizeMinusOne, 1, Options & ~RowMajor, MaxSizeMinusOne, 1> CoeffVectorType;
-    typedef typename internal::plain_col_type<MatrixType, RealScalar>::type DiagonalType;
-    typedef Matrix<RealScalar, SizeMinusOne, 1, Options & ~RowMajor, MaxSizeMinusOne, 1> SubDiagonalType;
-    typedef typename internal::remove_all<typename MatrixType::RealReturnType>::type MatrixTypeRealView;
-    typedef internal::TridiagonalizationMatrixTReturnType<MatrixTypeRealView> MatrixTReturnType;
-
-    typedef typename internal::conditional<NumTraits<Scalar>::IsComplex,
-              typename internal::add_const_on_value_type<typename Diagonal<const MatrixType>::RealReturnType>::type,
-              const Diagonal<const MatrixType>
-            >::type DiagonalReturnType;
-
-    typedef typename internal::conditional<NumTraits<Scalar>::IsComplex,
-              typename internal::add_const_on_value_type<typename Diagonal<const MatrixType, -1>::RealReturnType>::type,
-              const Diagonal<const MatrixType, -1>
-            >::type SubDiagonalReturnType;
-
-    /** \brief Return type of matrixQ() */
-    typedef HouseholderSequence<MatrixType,typename internal::remove_all<typename CoeffVectorType::ConjugateReturnType>::type> HouseholderSequenceType;
-
-    /** \brief Default constructor.
-      *
-      * \param [in]  size  Positive integer, size of the matrix whose tridiagonal
-      * decomposition will be computed.
-      *
-      * The default constructor is useful in cases in which the user intends to
-      * perform decompositions via compute().  The \p size parameter is only
-      * used as a hint. It is not an error to give a wrong \p size, but it may
-      * impair performance.
-      *
-      * \sa compute() for an example.
-      */
-    explicit Tridiagonalization(Index size = Size==Dynamic ? 2 : Size)
-      : m_matrix(size,size),
-        m_hCoeffs(size > 1 ? size-1 : 1),
-        m_isInitialized(false)
-    {}
-
-    /** \brief Constructor; computes tridiagonal decomposition of given matrix.
-      *
-      * \param[in]  matrix  Selfadjoint matrix whose tridiagonal decomposition
-      * is to be computed.
-      *
-      * This constructor calls compute() to compute the tridiagonal decomposition.
-      *
-      * Example: \include Tridiagonalization_Tridiagonalization_MatrixType.cpp
-      * Output: \verbinclude Tridiagonalization_Tridiagonalization_MatrixType.out
-      */
-    template<typename InputType>
-    explicit Tridiagonalization(const EigenBase<InputType>& matrix)
-      : m_matrix(matrix.derived()),
-        m_hCoeffs(matrix.cols() > 1 ? matrix.cols()-1 : 1),
-        m_isInitialized(false)
-    {
-      internal::tridiagonalization_inplace(m_matrix, m_hCoeffs);
-      m_isInitialized = true;
-    }
-
-    /** \brief Computes tridiagonal decomposition of given matrix.
-      *
-      * \param[in]  matrix  Selfadjoint matrix whose tridiagonal decomposition
-      * is to be computed.
-      * \returns    Reference to \c *this
-      *
-      * The tridiagonal decomposition is computed by bringing the columns of
-      * the matrix successively in the required form using Householder
-      * reflections. The cost is \f$ 4n^3/3 \f$ flops, where \f$ n \f$ denotes
-      * the size of the given matrix.
-      *
-      * This method reuses of the allocated data in the Tridiagonalization
-      * object, if the size of the matrix does not change.
-      *
-      * Example: \include Tridiagonalization_compute.cpp
-      * Output: \verbinclude Tridiagonalization_compute.out
-      */
-    template<typename InputType>
-    Tridiagonalization& compute(const EigenBase<InputType>& matrix)
-    {
-      m_matrix = matrix.derived();
-      m_hCoeffs.resize(matrix.rows()-1, 1);
-      internal::tridiagonalization_inplace(m_matrix, m_hCoeffs);
-      m_isInitialized = true;
-      return *this;
-    }
-
-    /** \brief Returns the Householder coefficients.
-      *
-      * \returns a const reference to the vector of Householder coefficients
-      *
-      * \pre Either the constructor Tridiagonalization(const MatrixType&) or
-      * the member function compute(const MatrixType&) has been called before
-      * to compute the tridiagonal decomposition of a matrix.
-      *
-      * The Householder coefficients allow the reconstruction of the matrix
-      * \f$ Q \f$ in the tridiagonal decomposition from the packed data.
-      *
-      * Example: \include Tridiagonalization_householderCoefficients.cpp
-      * Output: \verbinclude Tridiagonalization_householderCoefficients.out
-      *
-      * \sa packedMatrix(), \ref Householder_Module "Householder module"
-      */
-    inline CoeffVectorType householderCoefficients() const
-    {
-      eigen_assert(m_isInitialized && "Tridiagonalization is not initialized.");
-      return m_hCoeffs;
-    }
-
-    /** \brief Returns the internal representation of the decomposition
-      *
-      *	\returns a const reference to a matrix with the internal representation
-      *	         of the decomposition.
-      *
-      * \pre Either the constructor Tridiagonalization(const MatrixType&) or
-      * the member function compute(const MatrixType&) has been called before
-      * to compute the tridiagonal decomposition of a matrix.
-      *
-      * The returned matrix contains the following information:
-      *  - the strict upper triangular part is equal to the input matrix A.
-      *  - the diagonal and lower sub-diagonal represent the real tridiagonal
-      *    symmetric matrix T.
-      *  - the rest of the lower part contains the Householder vectors that,
-      *    combined with Householder coefficients returned by
-      *    householderCoefficients(), allows to reconstruct the matrix Q as
-      *       \f$ Q = H_{N-1} \ldots H_1 H_0 \f$.
-      *    Here, the matrices \f$ H_i \f$ are the Householder transformations
-      *       \f$ H_i = (I - h_i v_i v_i^T) \f$
-      *    where \f$ h_i \f$ is the \f$ i \f$th Householder coefficient and
-      *    \f$ v_i \f$ is the Householder vector defined by
-      *       \f$ v_i = [ 0, \ldots, 0, 1, M(i+2,i), \ldots, M(N-1,i) ]^T \f$
-      *    with M the matrix returned by this function.
-      *
-      * See LAPACK for further details on this packed storage.
-      *
-      * Example: \include Tridiagonalization_packedMatrix.cpp
-      * Output: \verbinclude Tridiagonalization_packedMatrix.out
-      *
-      * \sa householderCoefficients()
-      */
-    inline const MatrixType& packedMatrix() const
-    {
-      eigen_assert(m_isInitialized && "Tridiagonalization is not initialized.");
-      return m_matrix;
-    }
-
-    /** \brief Returns the unitary matrix Q in the decomposition
-      *
-      * \returns object representing the matrix Q
-      *
-      * \pre Either the constructor Tridiagonalization(const MatrixType&) or
-      * the member function compute(const MatrixType&) has been called before
-      * to compute the tridiagonal decomposition of a matrix.
-      *
-      * This function returns a light-weight object of template class
-      * HouseholderSequence. You can either apply it directly to a matrix or
-      * you can convert it to a matrix of type #MatrixType.
-      *
-      * \sa Tridiagonalization(const MatrixType&) for an example,
-      *     matrixT(), class HouseholderSequence
-      */
-    HouseholderSequenceType matrixQ() const
-    {
-      eigen_assert(m_isInitialized && "Tridiagonalization is not initialized.");
-      return HouseholderSequenceType(m_matrix, m_hCoeffs.conjugate())
-             .setLength(m_matrix.rows() - 1)
-             .setShift(1);
-    }
-
-    /** \brief Returns an expression of the tridiagonal matrix T in the decomposition
-      *
-      * \returns expression object representing the matrix T
-      *
-      * \pre Either the constructor Tridiagonalization(const MatrixType&) or
-      * the member function compute(const MatrixType&) has been called before
-      * to compute the tridiagonal decomposition of a matrix.
-      *
-      * Currently, this function can be used to extract the matrix T from internal
-      * data and copy it to a dense matrix object. In most cases, it may be
-      * sufficient to directly use the packed matrix or the vector expressions
-      * returned by diagonal() and subDiagonal() instead of creating a new
-      * dense copy matrix with this function.
-      *
-      * \sa Tridiagonalization(const MatrixType&) for an example,
-      * matrixQ(), packedMatrix(), diagonal(), subDiagonal()
-      */
-    MatrixTReturnType matrixT() const
-    {
-      eigen_assert(m_isInitialized && "Tridiagonalization is not initialized.");
-      return MatrixTReturnType(m_matrix.real());
-    }
-
-    /** \brief Returns the diagonal of the tridiagonal matrix T in the decomposition.
-      *
-      * \returns expression representing the diagonal of T
-      *
-      * \pre Either the constructor Tridiagonalization(const MatrixType&) or
-      * the member function compute(const MatrixType&) has been called before
-      * to compute the tridiagonal decomposition of a matrix.
-      *
-      * Example: \include Tridiagonalization_diagonal.cpp
-      * Output: \verbinclude Tridiagonalization_diagonal.out
-      *
-      * \sa matrixT(), subDiagonal()
-      */
-    DiagonalReturnType diagonal() const;
-
-    /** \brief Returns the subdiagonal of the tridiagonal matrix T in the decomposition.
-      *
-      * \returns expression representing the subdiagonal of T
-      *
-      * \pre Either the constructor Tridiagonalization(const MatrixType&) or
-      * the member function compute(const MatrixType&) has been called before
-      * to compute the tridiagonal decomposition of a matrix.
-      *
-      * \sa diagonal() for an example, matrixT()
-      */
-    SubDiagonalReturnType subDiagonal() const;
-
-  protected:
-
-    MatrixType m_matrix;
-    CoeffVectorType m_hCoeffs;
-    bool m_isInitialized;
-};
-
-template<typename MatrixType>
-typename Tridiagonalization<MatrixType>::DiagonalReturnType
-Tridiagonalization<MatrixType>::diagonal() const
-{
-  eigen_assert(m_isInitialized && "Tridiagonalization is not initialized.");
-  return m_matrix.diagonal().real();
-}
-
-template<typename MatrixType>
-typename Tridiagonalization<MatrixType>::SubDiagonalReturnType
-Tridiagonalization<MatrixType>::subDiagonal() const
-{
-  eigen_assert(m_isInitialized && "Tridiagonalization is not initialized.");
-  return m_matrix.template diagonal<-1>().real();
-}
-
-namespace internal {
-
-/** \internal
-  * Performs a tridiagonal decomposition of the selfadjoint matrix \a matA in-place.
-  *
-  * \param[in,out] matA On input the selfadjoint matrix. Only the \b lower triangular part is referenced.
-  *                     On output, the strict upper part is left unchanged, and the lower triangular part
-  *                     represents the T and Q matrices in packed format has detailed below.
-  * \param[out]    hCoeffs returned Householder coefficients (see below)
-  *
-  * On output, the tridiagonal selfadjoint matrix T is stored in the diagonal
-  * and lower sub-diagonal of the matrix \a matA.
-  * The unitary matrix Q is represented in a compact way as a product of
-  * Householder reflectors \f$ H_i \f$ such that:
-  *       \f$ Q = H_{N-1} \ldots H_1 H_0 \f$.
-  * The Householder reflectors are defined as
-  *       \f$ H_i = (I - h_i v_i v_i^T) \f$
-  * where \f$ h_i = hCoeffs[i]\f$ is the \f$ i \f$th Householder coefficient and
-  * \f$ v_i \f$ is the Householder vector defined by
-  *       \f$ v_i = [ 0, \ldots, 0, 1, matA(i+2,i), \ldots, matA(N-1,i) ]^T \f$.
-  *
-  * Implemented from Golub's "Matrix Computations", algorithm 8.3.1.
-  *
-  * \sa Tridiagonalization::packedMatrix()
-  */
-template<typename MatrixType, typename CoeffVectorType>
-void tridiagonalization_inplace(MatrixType& matA, CoeffVectorType& hCoeffs)
-{
-  using numext::conj;
-  typedef typename MatrixType::Scalar Scalar;
-  typedef typename MatrixType::RealScalar RealScalar;
-  Index n = matA.rows();
-  eigen_assert(n==matA.cols());
-  eigen_assert(n==hCoeffs.size()+1 || n==1);
-  
-  for (Index i = 0; i<n-1; ++i)
-  {
-    Index remainingSize = n-i-1;
-    RealScalar beta;
-    Scalar h;
-    matA.col(i).tail(remainingSize).makeHouseholderInPlace(h, beta);
-
-    // Apply similarity transformation to remaining columns,
-    // i.e., A = H A H' where H = I - h v v' and v = matA.col(i).tail(n-i-1)
-    matA.col(i).coeffRef(i+1) = 1;
-
-    hCoeffs.tail(n-i-1).noalias() = (matA.bottomRightCorner(remainingSize,remainingSize).template selfadjointView<Lower>()
-                                  * (conj(h) * matA.col(i).tail(remainingSize)));
-
-    hCoeffs.tail(n-i-1) += (conj(h)*RealScalar(-0.5)*(hCoeffs.tail(remainingSize).dot(matA.col(i).tail(remainingSize)))) * matA.col(i).tail(n-i-1);
-
-    matA.bottomRightCorner(remainingSize, remainingSize).template selfadjointView<Lower>()
-      .rankUpdate(matA.col(i).tail(remainingSize), hCoeffs.tail(remainingSize), Scalar(-1));
-
-    matA.col(i).coeffRef(i+1) = beta;
-    hCoeffs.coeffRef(i) = h;
-  }
-}
-
-// forward declaration, implementation at the end of this file
-template<typename MatrixType,
-         int Size=MatrixType::ColsAtCompileTime,
-         bool IsComplex=NumTraits<typename MatrixType::Scalar>::IsComplex>
-struct tridiagonalization_inplace_selector;
-
-/** \brief Performs a full tridiagonalization in place
-  *
-  * \param[in,out]  mat  On input, the selfadjoint matrix whose tridiagonal
-  *    decomposition is to be computed. Only the lower triangular part referenced.
-  *    The rest is left unchanged. On output, the orthogonal matrix Q
-  *    in the decomposition if \p extractQ is true.
-  * \param[out]  diag  The diagonal of the tridiagonal matrix T in the
-  *    decomposition.
-  * \param[out]  subdiag  The subdiagonal of the tridiagonal matrix T in
-  *    the decomposition.
-  * \param[in]  extractQ  If true, the orthogonal matrix Q in the
-  *    decomposition is computed and stored in \p mat.
-  *
-  * Computes the tridiagonal decomposition of the selfadjoint matrix \p mat in place
-  * such that \f$ mat = Q T Q^* \f$ where \f$ Q \f$ is unitary and \f$ T \f$ a real
-  * symmetric tridiagonal matrix.
-  *
-  * The tridiagonal matrix T is passed to the output parameters \p diag and \p subdiag. If
-  * \p extractQ is true, then the orthogonal matrix Q is passed to \p mat. Otherwise the lower
-  * part of the matrix \p mat is destroyed.
-  *
-  * The vectors \p diag and \p subdiag are not resized. The function
-  * assumes that they are already of the correct size. The length of the
-  * vector \p diag should equal the number of rows in \p mat, and the
-  * length of the vector \p subdiag should be one left.
-  *
-  * This implementation contains an optimized path for 3-by-3 matrices
-  * which is especially useful for plane fitting.
-  *
-  * \note Currently, it requires two temporary vectors to hold the intermediate
-  * Householder coefficients, and to reconstruct the matrix Q from the Householder
-  * reflectors.
-  *
-  * Example (this uses the same matrix as the example in
-  *    Tridiagonalization::Tridiagonalization(const MatrixType&)):
-  *    \include Tridiagonalization_decomposeInPlace.cpp
-  * Output: \verbinclude Tridiagonalization_decomposeInPlace.out
-  *
-  * \sa class Tridiagonalization
-  */
-template<typename MatrixType, typename DiagonalType, typename SubDiagonalType>
-void tridiagonalization_inplace(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, bool extractQ)
-{
-  eigen_assert(mat.cols()==mat.rows() && diag.size()==mat.rows() && subdiag.size()==mat.rows()-1);
-  tridiagonalization_inplace_selector<MatrixType>::run(mat, diag, subdiag, extractQ);
-}
-
-/** \internal
-  * General full tridiagonalization
-  */
-template<typename MatrixType, int Size, bool IsComplex>
-struct tridiagonalization_inplace_selector
-{
-  typedef typename Tridiagonalization<MatrixType>::CoeffVectorType CoeffVectorType;
-  typedef typename Tridiagonalization<MatrixType>::HouseholderSequenceType HouseholderSequenceType;
-  template<typename DiagonalType, typename SubDiagonalType>
-  static void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, bool extractQ)
-  {
-    CoeffVectorType hCoeffs(mat.cols()-1);
-    tridiagonalization_inplace(mat,hCoeffs);
-    diag = mat.diagonal().real();
-    subdiag = mat.template diagonal<-1>().real();
-    if(extractQ)
-      mat = HouseholderSequenceType(mat, hCoeffs.conjugate())
-            .setLength(mat.rows() - 1)
-            .setShift(1);
-  }
-};
-
-/** \internal
-  * Specialization for 3x3 real matrices.
-  * Especially useful for plane fitting.
-  */
-template<typename MatrixType>
-struct tridiagonalization_inplace_selector<MatrixType,3,false>
-{
-  typedef typename MatrixType::Scalar Scalar;
-  typedef typename MatrixType::RealScalar RealScalar;
-
-  template<typename DiagonalType, typename SubDiagonalType>
-  static void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, bool extractQ)
-  {
-    using std::sqrt;
-    const RealScalar tol = (std::numeric_limits<RealScalar>::min)();
-    diag[0] = mat(0,0);
-    RealScalar v1norm2 = numext::abs2(mat(2,0));
-    if(v1norm2 <= tol)
-    {
-      diag[1] = mat(1,1);
-      diag[2] = mat(2,2);
-      subdiag[0] = mat(1,0);
-      subdiag[1] = mat(2,1);
-      if (extractQ)
-        mat.setIdentity();
-    }
-    else
-    {
-      RealScalar beta = sqrt(numext::abs2(mat(1,0)) + v1norm2);
-      RealScalar invBeta = RealScalar(1)/beta;
-      Scalar m01 = mat(1,0) * invBeta;
-      Scalar m02 = mat(2,0) * invBeta;
-      Scalar q = RealScalar(2)*m01*mat(2,1) + m02*(mat(2,2) - mat(1,1));
-      diag[1] = mat(1,1) + m02*q;
-      diag[2] = mat(2,2) - m02*q;
-      subdiag[0] = beta;
-      subdiag[1] = mat(2,1) - m01 * q;
-      if (extractQ)
-      {
-        mat << 1,   0,    0,
-               0, m01,  m02,
-               0, m02, -m01;
-      }
-    }
-  }
-};
-
-/** \internal
-  * Trivial specialization for 1x1 matrices
-  */
-template<typename MatrixType, bool IsComplex>
-struct tridiagonalization_inplace_selector<MatrixType,1,IsComplex>
-{
-  typedef typename MatrixType::Scalar Scalar;
-
-  template<typename DiagonalType, typename SubDiagonalType>
-  static void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType&, bool extractQ)
-  {
-    diag(0,0) = numext::real(mat(0,0));
-    if(extractQ)
-      mat(0,0) = Scalar(1);
-  }
-};
-
-/** \internal
-  * \eigenvalues_module \ingroup Eigenvalues_Module
-  *
-  * \brief Expression type for return value of Tridiagonalization::matrixT()
-  *
-  * \tparam MatrixType type of underlying dense matrix
-  */
-template<typename MatrixType> struct TridiagonalizationMatrixTReturnType
-: public ReturnByValue<TridiagonalizationMatrixTReturnType<MatrixType> >
-{
-  public:
-    /** \brief Constructor.
-      *
-      * \param[in] mat The underlying dense matrix
-      */
-    TridiagonalizationMatrixTReturnType(const MatrixType& mat) : m_matrix(mat) { }
-
-    template <typename ResultType>
-    inline void evalTo(ResultType& result) const
-    {
-      result.setZero();
-      result.template diagonal<1>() = m_matrix.template diagonal<-1>().conjugate();
-      result.diagonal() = m_matrix.diagonal();
-      result.template diagonal<-1>() = m_matrix.template diagonal<-1>();
-    }
-
-    Index rows() const { return m_matrix.rows(); }
-    Index cols() const { return m_matrix.cols(); }
-
-  protected:
-    typename MatrixType::Nested m_matrix;
-};
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_TRIDIAGONALIZATION_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Householder/BlockHouseholder.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Householder/BlockHouseholder.h
deleted file mode 100644
index 01a7ed1..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Householder/BlockHouseholder.h
+++ /dev/null
@@ -1,103 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2010 Vincent Lejeune
-// Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_BLOCK_HOUSEHOLDER_H
-#define EIGEN_BLOCK_HOUSEHOLDER_H
-
-// This file contains some helper function to deal with block householder reflectors
-
-namespace Eigen { 
-
-namespace internal {
-  
-/** \internal */
-// template<typename TriangularFactorType,typename VectorsType,typename CoeffsType>
-// void make_block_householder_triangular_factor(TriangularFactorType& triFactor, const VectorsType& vectors, const CoeffsType& hCoeffs)
-// {
-//   typedef typename VectorsType::Scalar Scalar;
-//   const Index nbVecs = vectors.cols();
-//   eigen_assert(triFactor.rows() == nbVecs && triFactor.cols() == nbVecs && vectors.rows()>=nbVecs);
-// 
-//   for(Index i = 0; i < nbVecs; i++)
-//   {
-//     Index rs = vectors.rows() - i;
-//     // Warning, note that hCoeffs may alias with vectors.
-//     // It is then necessary to copy it before modifying vectors(i,i). 
-//     typename CoeffsType::Scalar h = hCoeffs(i);
-//     // This hack permits to pass trough nested Block<> and Transpose<> expressions.
-//     Scalar *Vii_ptr = const_cast<Scalar*>(vectors.data() + vectors.outerStride()*i + vectors.innerStride()*i);
-//     Scalar Vii = *Vii_ptr;
-//     *Vii_ptr = Scalar(1);
-//     triFactor.col(i).head(i).noalias() = -h * vectors.block(i, 0, rs, i).adjoint()
-//                                        * vectors.col(i).tail(rs);
-//     *Vii_ptr = Vii;
-//     // FIXME add .noalias() once the triangular product can work inplace
-//     triFactor.col(i).head(i) = triFactor.block(0,0,i,i).template triangularView<Upper>()
-//                              * triFactor.col(i).head(i);
-//     triFactor(i,i) = hCoeffs(i);
-//   }
-// }
-
-/** \internal */
-// This variant avoid modifications in vectors
-template<typename TriangularFactorType,typename VectorsType,typename CoeffsType>
-void make_block_householder_triangular_factor(TriangularFactorType& triFactor, const VectorsType& vectors, const CoeffsType& hCoeffs)
-{
-  const Index nbVecs = vectors.cols();
-  eigen_assert(triFactor.rows() == nbVecs && triFactor.cols() == nbVecs && vectors.rows()>=nbVecs);
-
-  for(Index i = nbVecs-1; i >=0 ; --i)
-  {
-    Index rs = vectors.rows() - i - 1;
-    Index rt = nbVecs-i-1;
-
-    if(rt>0)
-    {
-      triFactor.row(i).tail(rt).noalias() = -hCoeffs(i) * vectors.col(i).tail(rs).adjoint()
-                                                        * vectors.bottomRightCorner(rs, rt).template triangularView<UnitLower>();
-            
-      // FIXME add .noalias() once the triangular product can work inplace
-      triFactor.row(i).tail(rt) = triFactor.row(i).tail(rt) * triFactor.bottomRightCorner(rt,rt).template triangularView<Upper>();
-      
-    }
-    triFactor(i,i) = hCoeffs(i);
-  }
-}
-
-/** \internal
-  * if forward then perform   mat = H0 * H1 * H2 * mat
-  * otherwise perform         mat = H2 * H1 * H0 * mat
-  */
-template<typename MatrixType,typename VectorsType,typename CoeffsType>
-void apply_block_householder_on_the_left(MatrixType& mat, const VectorsType& vectors, const CoeffsType& hCoeffs, bool forward)
-{
-  enum { TFactorSize = MatrixType::ColsAtCompileTime };
-  Index nbVecs = vectors.cols();
-  Matrix<typename MatrixType::Scalar, TFactorSize, TFactorSize, RowMajor> T(nbVecs,nbVecs);
-  
-  if(forward) make_block_householder_triangular_factor(T, vectors, hCoeffs);
-  else        make_block_householder_triangular_factor(T, vectors, hCoeffs.conjugate());  
-  const TriangularView<const VectorsType, UnitLower> V(vectors);
-
-  // A -= V T V^* A
-  Matrix<typename MatrixType::Scalar,VectorsType::ColsAtCompileTime,MatrixType::ColsAtCompileTime,
-         (VectorsType::MaxColsAtCompileTime==1 && MatrixType::MaxColsAtCompileTime!=1)?RowMajor:ColMajor,
-         VectorsType::MaxColsAtCompileTime,MatrixType::MaxColsAtCompileTime> tmp = V.adjoint() * mat;
-  // FIXME add .noalias() once the triangular product can work inplace
-  if(forward) tmp = T.template triangularView<Upper>()           * tmp;
-  else        tmp = T.template triangularView<Upper>().adjoint() * tmp;
-  mat.noalias() -= V * tmp;
-}
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_BLOCK_HOUSEHOLDER_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Householder/Householder.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Householder/Householder.h
deleted file mode 100644
index 80de2c3..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Householder/Householder.h
+++ /dev/null
@@ -1,172 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_HOUSEHOLDER_H
-#define EIGEN_HOUSEHOLDER_H
-
-namespace Eigen { 
-
-namespace internal {
-template<int n> struct decrement_size
-{
-  enum {
-    ret = n==Dynamic ? n : n-1
-  };
-};
-}
-
-/** Computes the elementary reflector H such that:
-  * \f$ H *this = [ beta 0 ... 0]^T \f$
-  * where the transformation H is:
-  * \f$ H = I - tau v v^*\f$
-  * and the vector v is:
-  * \f$ v^T = [1 essential^T] \f$
-  *
-  * The essential part of the vector \c v is stored in *this.
-  * 
-  * On output:
-  * \param tau the scaling factor of the Householder transformation
-  * \param beta the result of H * \c *this
-  *
-  * \sa MatrixBase::makeHouseholder(), MatrixBase::applyHouseholderOnTheLeft(),
-  *     MatrixBase::applyHouseholderOnTheRight()
-  */
-template<typename Derived>
-void MatrixBase<Derived>::makeHouseholderInPlace(Scalar& tau, RealScalar& beta)
-{
-  VectorBlock<Derived, internal::decrement_size<Base::SizeAtCompileTime>::ret> essentialPart(derived(), 1, size()-1);
-  makeHouseholder(essentialPart, tau, beta);
-}
-
-/** Computes the elementary reflector H such that:
-  * \f$ H *this = [ beta 0 ... 0]^T \f$
-  * where the transformation H is:
-  * \f$ H = I - tau v v^*\f$
-  * and the vector v is:
-  * \f$ v^T = [1 essential^T] \f$
-  *
-  * On output:
-  * \param essential the essential part of the vector \c v
-  * \param tau the scaling factor of the Householder transformation
-  * \param beta the result of H * \c *this
-  *
-  * \sa MatrixBase::makeHouseholderInPlace(), MatrixBase::applyHouseholderOnTheLeft(),
-  *     MatrixBase::applyHouseholderOnTheRight()
-  */
-template<typename Derived>
-template<typename EssentialPart>
-void MatrixBase<Derived>::makeHouseholder(
-  EssentialPart& essential,
-  Scalar& tau,
-  RealScalar& beta) const
-{
-  using std::sqrt;
-  using numext::conj;
-  
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(EssentialPart)
-  VectorBlock<const Derived, EssentialPart::SizeAtCompileTime> tail(derived(), 1, size()-1);
-  
-  RealScalar tailSqNorm = size()==1 ? RealScalar(0) : tail.squaredNorm();
-  Scalar c0 = coeff(0);
-  const RealScalar tol = (std::numeric_limits<RealScalar>::min)();
-
-  if(tailSqNorm <= tol && numext::abs2(numext::imag(c0))<=tol)
-  {
-    tau = RealScalar(0);
-    beta = numext::real(c0);
-    essential.setZero();
-  }
-  else
-  {
-    beta = sqrt(numext::abs2(c0) + tailSqNorm);
-    if (numext::real(c0)>=RealScalar(0))
-      beta = -beta;
-    essential = tail / (c0 - beta);
-    tau = conj((beta - c0) / beta);
-  }
-}
-
-/** Apply the elementary reflector H given by
-  * \f$ H = I - tau v v^*\f$
-  * with
-  * \f$ v^T = [1 essential^T] \f$
-  * from the left to a vector or matrix.
-  *
-  * On input:
-  * \param essential the essential part of the vector \c v
-  * \param tau the scaling factor of the Householder transformation
-  * \param workspace a pointer to working space with at least
-  *                  this->cols() * essential.size() entries
-  *
-  * \sa MatrixBase::makeHouseholder(), MatrixBase::makeHouseholderInPlace(), 
-  *     MatrixBase::applyHouseholderOnTheRight()
-  */
-template<typename Derived>
-template<typename EssentialPart>
-void MatrixBase<Derived>::applyHouseholderOnTheLeft(
-  const EssentialPart& essential,
-  const Scalar& tau,
-  Scalar* workspace)
-{
-  if(rows() == 1)
-  {
-    *this *= Scalar(1)-tau;
-  }
-  else if(tau!=Scalar(0))
-  {
-    Map<typename internal::plain_row_type<PlainObject>::type> tmp(workspace,cols());
-    Block<Derived, EssentialPart::SizeAtCompileTime, Derived::ColsAtCompileTime> bottom(derived(), 1, 0, rows()-1, cols());
-    tmp.noalias() = essential.adjoint() * bottom;
-    tmp += this->row(0);
-    this->row(0) -= tau * tmp;
-    bottom.noalias() -= tau * essential * tmp;
-  }
-}
-
-/** Apply the elementary reflector H given by
-  * \f$ H = I - tau v v^*\f$
-  * with
-  * \f$ v^T = [1 essential^T] \f$
-  * from the right to a vector or matrix.
-  *
-  * On input:
-  * \param essential the essential part of the vector \c v
-  * \param tau the scaling factor of the Householder transformation
-  * \param workspace a pointer to working space with at least
-  *                  this->cols() * essential.size() entries
-  *
-  * \sa MatrixBase::makeHouseholder(), MatrixBase::makeHouseholderInPlace(), 
-  *     MatrixBase::applyHouseholderOnTheLeft()
-  */
-template<typename Derived>
-template<typename EssentialPart>
-void MatrixBase<Derived>::applyHouseholderOnTheRight(
-  const EssentialPart& essential,
-  const Scalar& tau,
-  Scalar* workspace)
-{
-  if(cols() == 1)
-  {
-    *this *= Scalar(1)-tau;
-  }
-  else if(tau!=Scalar(0))
-  {
-    Map<typename internal::plain_col_type<PlainObject>::type> tmp(workspace,rows());
-    Block<Derived, Derived::RowsAtCompileTime, EssentialPart::SizeAtCompileTime> right(derived(), 0, 1, rows(), cols()-1);
-    tmp.noalias() = right * essential.conjugate();
-    tmp += this->col(0);
-    this->col(0) -= tau * tmp;
-    right.noalias() -= tau * tmp * essential.transpose();
-  }
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_HOUSEHOLDER_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Householder/HouseholderSequence.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Householder/HouseholderSequence.h
deleted file mode 100644
index 3ce0a69..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Householder/HouseholderSequence.h
+++ /dev/null
@@ -1,470 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_HOUSEHOLDER_SEQUENCE_H
-#define EIGEN_HOUSEHOLDER_SEQUENCE_H
-
-namespace Eigen { 
-
-/** \ingroup Householder_Module
-  * \householder_module
-  * \class HouseholderSequence
-  * \brief Sequence of Householder reflections acting on subspaces with decreasing size
-  * \tparam VectorsType type of matrix containing the Householder vectors
-  * \tparam CoeffsType  type of vector containing the Householder coefficients
-  * \tparam Side        either OnTheLeft (the default) or OnTheRight
-  *
-  * This class represents a product sequence of Householder reflections where the first Householder reflection
-  * acts on the whole space, the second Householder reflection leaves the one-dimensional subspace spanned by
-  * the first unit vector invariant, the third Householder reflection leaves the two-dimensional subspace
-  * spanned by the first two unit vectors invariant, and so on up to the last reflection which leaves all but
-  * one dimensions invariant and acts only on the last dimension. Such sequences of Householder reflections
-  * are used in several algorithms to zero out certain parts of a matrix. Indeed, the methods
-  * HessenbergDecomposition::matrixQ(), Tridiagonalization::matrixQ(), HouseholderQR::householderQ(),
-  * and ColPivHouseholderQR::householderQ() all return a %HouseholderSequence.
-  *
-  * More precisely, the class %HouseholderSequence represents an \f$ n \times n \f$ matrix \f$ H \f$ of the
-  * form \f$ H = \prod_{i=0}^{n-1} H_i \f$ where the i-th Householder reflection is \f$ H_i = I - h_i v_i
-  * v_i^* \f$. The i-th Householder coefficient \f$ h_i \f$ is a scalar and the i-th Householder vector \f$
-  * v_i \f$ is a vector of the form
-  * \f[ 
-  * v_i = [\underbrace{0, \ldots, 0}_{i-1\mbox{ zeros}}, 1, \underbrace{*, \ldots,*}_{n-i\mbox{ arbitrary entries}} ]. 
-  * \f]
-  * The last \f$ n-i \f$ entries of \f$ v_i \f$ are called the essential part of the Householder vector.
-  *
-  * Typical usages are listed below, where H is a HouseholderSequence:
-  * \code
-  * A.applyOnTheRight(H);             // A = A * H
-  * A.applyOnTheLeft(H);              // A = H * A
-  * A.applyOnTheRight(H.adjoint());   // A = A * H^*
-  * A.applyOnTheLeft(H.adjoint());    // A = H^* * A
-  * MatrixXd Q = H;                   // conversion to a dense matrix
-  * \endcode
-  * In addition to the adjoint, you can also apply the inverse (=adjoint), the transpose, and the conjugate operators.
-  *
-  * See the documentation for HouseholderSequence(const VectorsType&, const CoeffsType&) for an example.
-  *
-  * \sa MatrixBase::applyOnTheLeft(), MatrixBase::applyOnTheRight()
-  */
-
-namespace internal {
-
-template<typename VectorsType, typename CoeffsType, int Side>
-struct traits<HouseholderSequence<VectorsType,CoeffsType,Side> >
-{
-  typedef typename VectorsType::Scalar Scalar;
-  typedef typename VectorsType::StorageIndex StorageIndex;
-  typedef typename VectorsType::StorageKind StorageKind;
-  enum {
-    RowsAtCompileTime = Side==OnTheLeft ? traits<VectorsType>::RowsAtCompileTime
-                                        : traits<VectorsType>::ColsAtCompileTime,
-    ColsAtCompileTime = RowsAtCompileTime,
-    MaxRowsAtCompileTime = Side==OnTheLeft ? traits<VectorsType>::MaxRowsAtCompileTime
-                                           : traits<VectorsType>::MaxColsAtCompileTime,
-    MaxColsAtCompileTime = MaxRowsAtCompileTime,
-    Flags = 0
-  };
-};
-
-struct HouseholderSequenceShape {};
-
-template<typename VectorsType, typename CoeffsType, int Side>
-struct evaluator_traits<HouseholderSequence<VectorsType,CoeffsType,Side> >
-  : public evaluator_traits_base<HouseholderSequence<VectorsType,CoeffsType,Side> >
-{
-  typedef HouseholderSequenceShape Shape;
-};
-
-template<typename VectorsType, typename CoeffsType, int Side>
-struct hseq_side_dependent_impl
-{
-  typedef Block<const VectorsType, Dynamic, 1> EssentialVectorType;
-  typedef HouseholderSequence<VectorsType, CoeffsType, OnTheLeft> HouseholderSequenceType;
-  static inline const EssentialVectorType essentialVector(const HouseholderSequenceType& h, Index k)
-  {
-    Index start = k+1+h.m_shift;
-    return Block<const VectorsType,Dynamic,1>(h.m_vectors, start, k, h.rows()-start, 1);
-  }
-};
-
-template<typename VectorsType, typename CoeffsType>
-struct hseq_side_dependent_impl<VectorsType, CoeffsType, OnTheRight>
-{
-  typedef Transpose<Block<const VectorsType, 1, Dynamic> > EssentialVectorType;
-  typedef HouseholderSequence<VectorsType, CoeffsType, OnTheRight> HouseholderSequenceType;
-  static inline const EssentialVectorType essentialVector(const HouseholderSequenceType& h, Index k)
-  {
-    Index start = k+1+h.m_shift;
-    return Block<const VectorsType,1,Dynamic>(h.m_vectors, k, start, 1, h.rows()-start).transpose();
-  }
-};
-
-template<typename OtherScalarType, typename MatrixType> struct matrix_type_times_scalar_type
-{
-  typedef typename ScalarBinaryOpTraits<OtherScalarType, typename MatrixType::Scalar>::ReturnType
-    ResultScalar;
-  typedef Matrix<ResultScalar, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime,
-                 0, MatrixType::MaxRowsAtCompileTime, MatrixType::MaxColsAtCompileTime> Type;
-};
-
-} // end namespace internal
-
-template<typename VectorsType, typename CoeffsType, int Side> class HouseholderSequence
-  : public EigenBase<HouseholderSequence<VectorsType,CoeffsType,Side> >
-{
-    typedef typename internal::hseq_side_dependent_impl<VectorsType,CoeffsType,Side>::EssentialVectorType EssentialVectorType;
-  
-  public:
-    enum {
-      RowsAtCompileTime = internal::traits<HouseholderSequence>::RowsAtCompileTime,
-      ColsAtCompileTime = internal::traits<HouseholderSequence>::ColsAtCompileTime,
-      MaxRowsAtCompileTime = internal::traits<HouseholderSequence>::MaxRowsAtCompileTime,
-      MaxColsAtCompileTime = internal::traits<HouseholderSequence>::MaxColsAtCompileTime
-    };
-    typedef typename internal::traits<HouseholderSequence>::Scalar Scalar;
-
-    typedef HouseholderSequence<
-      typename internal::conditional<NumTraits<Scalar>::IsComplex,
-        typename internal::remove_all<typename VectorsType::ConjugateReturnType>::type,
-        VectorsType>::type,
-      typename internal::conditional<NumTraits<Scalar>::IsComplex,
-        typename internal::remove_all<typename CoeffsType::ConjugateReturnType>::type,
-        CoeffsType>::type,
-      Side
-    > ConjugateReturnType;
-
-    /** \brief Constructor.
-      * \param[in]  v      %Matrix containing the essential parts of the Householder vectors
-      * \param[in]  h      Vector containing the Householder coefficients
-      *
-      * Constructs the Householder sequence with coefficients given by \p h and vectors given by \p v. The
-      * i-th Householder coefficient \f$ h_i \f$ is given by \p h(i) and the essential part of the i-th
-      * Householder vector \f$ v_i \f$ is given by \p v(k,i) with \p k > \p i (the subdiagonal part of the
-      * i-th column). If \p v has fewer columns than rows, then the Householder sequence contains as many
-      * Householder reflections as there are columns.
-      *
-      * \note The %HouseholderSequence object stores \p v and \p h by reference.
-      *
-      * Example: \include HouseholderSequence_HouseholderSequence.cpp
-      * Output: \verbinclude HouseholderSequence_HouseholderSequence.out
-      *
-      * \sa setLength(), setShift()
-      */
-    HouseholderSequence(const VectorsType& v, const CoeffsType& h)
-      : m_vectors(v), m_coeffs(h), m_trans(false), m_length(v.diagonalSize()),
-        m_shift(0)
-    {
-    }
-
-    /** \brief Copy constructor. */
-    HouseholderSequence(const HouseholderSequence& other)
-      : m_vectors(other.m_vectors),
-        m_coeffs(other.m_coeffs),
-        m_trans(other.m_trans),
-        m_length(other.m_length),
-        m_shift(other.m_shift)
-    {
-    }
-
-    /** \brief Number of rows of transformation viewed as a matrix.
-      * \returns Number of rows 
-      * \details This equals the dimension of the space that the transformation acts on.
-      */
-    Index rows() const { return Side==OnTheLeft ? m_vectors.rows() : m_vectors.cols(); }
-
-    /** \brief Number of columns of transformation viewed as a matrix.
-      * \returns Number of columns
-      * \details This equals the dimension of the space that the transformation acts on.
-      */
-    Index cols() const { return rows(); }
-
-    /** \brief Essential part of a Householder vector.
-      * \param[in]  k  Index of Householder reflection
-      * \returns    Vector containing non-trivial entries of k-th Householder vector
-      *
-      * This function returns the essential part of the Householder vector \f$ v_i \f$. This is a vector of
-      * length \f$ n-i \f$ containing the last \f$ n-i \f$ entries of the vector
-      * \f[ 
-      * v_i = [\underbrace{0, \ldots, 0}_{i-1\mbox{ zeros}}, 1, \underbrace{*, \ldots,*}_{n-i\mbox{ arbitrary entries}} ]. 
-      * \f]
-      * The index \f$ i \f$ equals \p k + shift(), corresponding to the k-th column of the matrix \p v
-      * passed to the constructor.
-      *
-      * \sa setShift(), shift()
-      */
-    const EssentialVectorType essentialVector(Index k) const
-    {
-      eigen_assert(k >= 0 && k < m_length);
-      return internal::hseq_side_dependent_impl<VectorsType,CoeffsType,Side>::essentialVector(*this, k);
-    }
-
-    /** \brief %Transpose of the Householder sequence. */
-    HouseholderSequence transpose() const
-    {
-      return HouseholderSequence(*this).setTrans(!m_trans);
-    }
-
-    /** \brief Complex conjugate of the Householder sequence. */
-    ConjugateReturnType conjugate() const
-    {
-      return ConjugateReturnType(m_vectors.conjugate(), m_coeffs.conjugate())
-             .setTrans(m_trans)
-             .setLength(m_length)
-             .setShift(m_shift);
-    }
-
-    /** \brief Adjoint (conjugate transpose) of the Householder sequence. */
-    ConjugateReturnType adjoint() const
-    {
-      return conjugate().setTrans(!m_trans);
-    }
-
-    /** \brief Inverse of the Householder sequence (equals the adjoint). */
-    ConjugateReturnType inverse() const { return adjoint(); }
-
-    /** \internal */
-    template<typename DestType> inline void evalTo(DestType& dst) const
-    {
-      Matrix<Scalar, DestType::RowsAtCompileTime, 1,
-             AutoAlign|ColMajor, DestType::MaxRowsAtCompileTime, 1> workspace(rows());
-      evalTo(dst, workspace);
-    }
-
-    /** \internal */
-    template<typename Dest, typename Workspace>
-    void evalTo(Dest& dst, Workspace& workspace) const
-    {
-      workspace.resize(rows());
-      Index vecs = m_length;
-      if(internal::is_same_dense(dst,m_vectors))
-      {
-        // in-place
-        dst.diagonal().setOnes();
-        dst.template triangularView<StrictlyUpper>().setZero();
-        for(Index k = vecs-1; k >= 0; --k)
-        {
-          Index cornerSize = rows() - k - m_shift;
-          if(m_trans)
-            dst.bottomRightCorner(cornerSize, cornerSize)
-               .applyHouseholderOnTheRight(essentialVector(k), m_coeffs.coeff(k), workspace.data());
-          else
-            dst.bottomRightCorner(cornerSize, cornerSize)
-               .applyHouseholderOnTheLeft(essentialVector(k), m_coeffs.coeff(k), workspace.data());
-
-          // clear the off diagonal vector
-          dst.col(k).tail(rows()-k-1).setZero();
-        }
-        // clear the remaining columns if needed
-        for(Index k = 0; k<cols()-vecs ; ++k)
-          dst.col(k).tail(rows()-k-1).setZero();
-      }
-      else
-      {
-        dst.setIdentity(rows(), rows());
-        for(Index k = vecs-1; k >= 0; --k)
-        {
-          Index cornerSize = rows() - k - m_shift;
-          if(m_trans)
-            dst.bottomRightCorner(cornerSize, cornerSize)
-               .applyHouseholderOnTheRight(essentialVector(k), m_coeffs.coeff(k), &workspace.coeffRef(0));
-          else
-            dst.bottomRightCorner(cornerSize, cornerSize)
-               .applyHouseholderOnTheLeft(essentialVector(k), m_coeffs.coeff(k), &workspace.coeffRef(0));
-        }
-      }
-    }
-
-    /** \internal */
-    template<typename Dest> inline void applyThisOnTheRight(Dest& dst) const
-    {
-      Matrix<Scalar,1,Dest::RowsAtCompileTime,RowMajor,1,Dest::MaxRowsAtCompileTime> workspace(dst.rows());
-      applyThisOnTheRight(dst, workspace);
-    }
-
-    /** \internal */
-    template<typename Dest, typename Workspace>
-    inline void applyThisOnTheRight(Dest& dst, Workspace& workspace) const
-    {
-      workspace.resize(dst.rows());
-      for(Index k = 0; k < m_length; ++k)
-      {
-        Index actual_k = m_trans ? m_length-k-1 : k;
-        dst.rightCols(rows()-m_shift-actual_k)
-           .applyHouseholderOnTheRight(essentialVector(actual_k), m_coeffs.coeff(actual_k), workspace.data());
-      }
-    }
-
-    /** \internal */
-    template<typename Dest> inline void applyThisOnTheLeft(Dest& dst) const
-    {
-      Matrix<Scalar,1,Dest::ColsAtCompileTime,RowMajor,1,Dest::MaxColsAtCompileTime> workspace;
-      applyThisOnTheLeft(dst, workspace);
-    }
-
-    /** \internal */
-    template<typename Dest, typename Workspace>
-    inline void applyThisOnTheLeft(Dest& dst, Workspace& workspace) const
-    {
-      const Index BlockSize = 48;
-      // if the entries are large enough, then apply the reflectors by block
-      if(m_length>=BlockSize && dst.cols()>1)
-      {
-        for(Index i = 0; i < m_length; i+=BlockSize)
-        {
-          Index end = m_trans ? (std::min)(m_length,i+BlockSize) : m_length-i;
-          Index k = m_trans ? i : (std::max)(Index(0),end-BlockSize);
-          Index bs = end-k;
-          Index start = k + m_shift;
-          
-          typedef Block<typename internal::remove_all<VectorsType>::type,Dynamic,Dynamic> SubVectorsType;
-          SubVectorsType sub_vecs1(m_vectors.const_cast_derived(), Side==OnTheRight ? k : start,
-                                                                   Side==OnTheRight ? start : k,
-                                                                   Side==OnTheRight ? bs : m_vectors.rows()-start,
-                                                                   Side==OnTheRight ? m_vectors.cols()-start : bs);
-          typename internal::conditional<Side==OnTheRight, Transpose<SubVectorsType>, SubVectorsType&>::type sub_vecs(sub_vecs1);
-          Block<Dest,Dynamic,Dynamic> sub_dst(dst,dst.rows()-rows()+m_shift+k,0, rows()-m_shift-k,dst.cols());
-          apply_block_householder_on_the_left(sub_dst, sub_vecs, m_coeffs.segment(k, bs), !m_trans);
-        }
-      }
-      else
-      {
-        workspace.resize(dst.cols());
-        for(Index k = 0; k < m_length; ++k)
-        {
-          Index actual_k = m_trans ? k : m_length-k-1;
-          dst.bottomRows(rows()-m_shift-actual_k)
-            .applyHouseholderOnTheLeft(essentialVector(actual_k), m_coeffs.coeff(actual_k), workspace.data());
-        }
-      }
-    }
-
-    /** \brief Computes the product of a Householder sequence with a matrix.
-      * \param[in]  other  %Matrix being multiplied.
-      * \returns    Expression object representing the product.
-      *
-      * This function computes \f$ HM \f$ where \f$ H \f$ is the Householder sequence represented by \p *this
-      * and \f$ M \f$ is the matrix \p other.
-      */
-    template<typename OtherDerived>
-    typename internal::matrix_type_times_scalar_type<Scalar, OtherDerived>::Type operator*(const MatrixBase<OtherDerived>& other) const
-    {
-      typename internal::matrix_type_times_scalar_type<Scalar, OtherDerived>::Type
-        res(other.template cast<typename internal::matrix_type_times_scalar_type<Scalar,OtherDerived>::ResultScalar>());
-      applyThisOnTheLeft(res);
-      return res;
-    }
-
-    template<typename _VectorsType, typename _CoeffsType, int _Side> friend struct internal::hseq_side_dependent_impl;
-
-    /** \brief Sets the length of the Householder sequence.
-      * \param [in]  length  New value for the length.
-      *
-      * By default, the length \f$ n \f$ of the Householder sequence \f$ H = H_0 H_1 \ldots H_{n-1} \f$ is set
-      * to the number of columns of the matrix \p v passed to the constructor, or the number of rows if that
-      * is smaller. After this function is called, the length equals \p length.
-      *
-      * \sa length()
-      */
-    HouseholderSequence& setLength(Index length)
-    {
-      m_length = length;
-      return *this;
-    }
-
-    /** \brief Sets the shift of the Householder sequence.
-      * \param [in]  shift  New value for the shift.
-      *
-      * By default, a %HouseholderSequence object represents \f$ H = H_0 H_1 \ldots H_{n-1} \f$ and the i-th
-      * column of the matrix \p v passed to the constructor corresponds to the i-th Householder
-      * reflection. After this function is called, the object represents \f$ H = H_{\mathrm{shift}}
-      * H_{\mathrm{shift}+1} \ldots H_{n-1} \f$ and the i-th column of \p v corresponds to the (shift+i)-th
-      * Householder reflection.
-      *
-      * \sa shift()
-      */
-    HouseholderSequence& setShift(Index shift)
-    {
-      m_shift = shift;
-      return *this;
-    }
-
-    Index length() const { return m_length; }  /**< \brief Returns the length of the Householder sequence. */
-    Index shift() const { return m_shift; }    /**< \brief Returns the shift of the Householder sequence. */
-
-    /* Necessary for .adjoint() and .conjugate() */
-    template <typename VectorsType2, typename CoeffsType2, int Side2> friend class HouseholderSequence;
-
-  protected:
-
-    /** \brief Sets the transpose flag.
-      * \param [in]  trans  New value of the transpose flag.
-      *
-      * By default, the transpose flag is not set. If the transpose flag is set, then this object represents 
-      * \f$ H^T = H_{n-1}^T \ldots H_1^T H_0^T \f$ instead of \f$ H = H_0 H_1 \ldots H_{n-1} \f$.
-      *
-      * \sa trans()
-      */
-    HouseholderSequence& setTrans(bool trans)
-    {
-      m_trans = trans;
-      return *this;
-    }
-
-    bool trans() const { return m_trans; }     /**< \brief Returns the transpose flag. */
-
-    typename VectorsType::Nested m_vectors;
-    typename CoeffsType::Nested m_coeffs;
-    bool m_trans;
-    Index m_length;
-    Index m_shift;
-};
-
-/** \brief Computes the product of a matrix with a Householder sequence.
-  * \param[in]  other  %Matrix being multiplied.
-  * \param[in]  h      %HouseholderSequence being multiplied.
-  * \returns    Expression object representing the product.
-  *
-  * This function computes \f$ MH \f$ where \f$ M \f$ is the matrix \p other and \f$ H \f$ is the
-  * Householder sequence represented by \p h.
-  */
-template<typename OtherDerived, typename VectorsType, typename CoeffsType, int Side>
-typename internal::matrix_type_times_scalar_type<typename VectorsType::Scalar,OtherDerived>::Type operator*(const MatrixBase<OtherDerived>& other, const HouseholderSequence<VectorsType,CoeffsType,Side>& h)
-{
-  typename internal::matrix_type_times_scalar_type<typename VectorsType::Scalar,OtherDerived>::Type
-    res(other.template cast<typename internal::matrix_type_times_scalar_type<typename VectorsType::Scalar,OtherDerived>::ResultScalar>());
-  h.applyThisOnTheRight(res);
-  return res;
-}
-
-/** \ingroup Householder_Module \householder_module
-  * \brief Convenience function for constructing a Householder sequence. 
-  * \returns A HouseholderSequence constructed from the specified arguments.
-  */
-template<typename VectorsType, typename CoeffsType>
-HouseholderSequence<VectorsType,CoeffsType> householderSequence(const VectorsType& v, const CoeffsType& h)
-{
-  return HouseholderSequence<VectorsType,CoeffsType,OnTheLeft>(v, h);
-}
-
-/** \ingroup Householder_Module \householder_module
-  * \brief Convenience function for constructing a Householder sequence. 
-  * \returns A HouseholderSequence constructed from the specified arguments.
-  * \details This function differs from householderSequence() in that the template argument \p OnTheSide of
-  * the constructed HouseholderSequence is set to OnTheRight, instead of the default OnTheLeft.
-  */
-template<typename VectorsType, typename CoeffsType>
-HouseholderSequence<VectorsType,CoeffsType,OnTheRight> rightHouseholderSequence(const VectorsType& v, const CoeffsType& h)
-{
-  return HouseholderSequence<VectorsType,CoeffsType,OnTheRight>(v, h);
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_HOUSEHOLDER_SEQUENCE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/Jacobi/Jacobi.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/Jacobi/Jacobi.h
deleted file mode 100644
index 1998c63..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/Jacobi/Jacobi.h
+++ /dev/null
@@ -1,462 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_JACOBI_H
-#define EIGEN_JACOBI_H
-
-namespace Eigen { 
-
-/** \ingroup Jacobi_Module
-  * \jacobi_module
-  * \class JacobiRotation
-  * \brief Rotation given by a cosine-sine pair.
-  *
-  * This class represents a Jacobi or Givens rotation.
-  * This is a 2D rotation in the plane \c J of angle \f$ \theta \f$ defined by
-  * its cosine \c c and sine \c s as follow:
-  * \f$ J = \left ( \begin{array}{cc} c & \overline s \\ -s  & \overline c \end{array} \right ) \f$
-  *
-  * You can apply the respective counter-clockwise rotation to a column vector \c v by
-  * applying its adjoint on the left: \f$ v = J^* v \f$ that translates to the following Eigen code:
-  * \code
-  * v.applyOnTheLeft(J.adjoint());
-  * \endcode
-  *
-  * \sa MatrixBase::applyOnTheLeft(), MatrixBase::applyOnTheRight()
-  */
-template<typename Scalar> class JacobiRotation
-{
-  public:
-    typedef typename NumTraits<Scalar>::Real RealScalar;
-
-    /** Default constructor without any initialization. */
-    JacobiRotation() {}
-
-    /** Construct a planar rotation from a cosine-sine pair (\a c, \c s). */
-    JacobiRotation(const Scalar& c, const Scalar& s) : m_c(c), m_s(s) {}
-
-    Scalar& c() { return m_c; }
-    Scalar c() const { return m_c; }
-    Scalar& s() { return m_s; }
-    Scalar s() const { return m_s; }
-
-    /** Concatenates two planar rotation */
-    JacobiRotation operator*(const JacobiRotation& other)
-    {
-      using numext::conj;
-      return JacobiRotation(m_c * other.m_c - conj(m_s) * other.m_s,
-                            conj(m_c * conj(other.m_s) + conj(m_s) * conj(other.m_c)));
-    }
-
-    /** Returns the transposed transformation */
-    JacobiRotation transpose() const { using numext::conj; return JacobiRotation(m_c, -conj(m_s)); }
-
-    /** Returns the adjoint transformation */
-    JacobiRotation adjoint() const { using numext::conj; return JacobiRotation(conj(m_c), -m_s); }
-
-    template<typename Derived>
-    bool makeJacobi(const MatrixBase<Derived>&, Index p, Index q);
-    bool makeJacobi(const RealScalar& x, const Scalar& y, const RealScalar& z);
-
-    void makeGivens(const Scalar& p, const Scalar& q, Scalar* r=0);
-
-  protected:
-    void makeGivens(const Scalar& p, const Scalar& q, Scalar* r, internal::true_type);
-    void makeGivens(const Scalar& p, const Scalar& q, Scalar* r, internal::false_type);
-
-    Scalar m_c, m_s;
-};
-
-/** Makes \c *this as a Jacobi rotation \a J such that applying \a J on both the right and left sides of the selfadjoint 2x2 matrix
-  * \f$ B = \left ( \begin{array}{cc} x & y \\ \overline y & z \end{array} \right )\f$ yields a diagonal matrix \f$ A = J^* B J \f$
-  *
-  * \sa MatrixBase::makeJacobi(const MatrixBase<Derived>&, Index, Index), MatrixBase::applyOnTheLeft(), MatrixBase::applyOnTheRight()
-  */
-template<typename Scalar>
-bool JacobiRotation<Scalar>::makeJacobi(const RealScalar& x, const Scalar& y, const RealScalar& z)
-{
-  using std::sqrt;
-  using std::abs;
-  RealScalar deno = RealScalar(2)*abs(y);
-  if(deno < (std::numeric_limits<RealScalar>::min)())
-  {
-    m_c = Scalar(1);
-    m_s = Scalar(0);
-    return false;
-  }
-  else
-  {
-    RealScalar tau = (x-z)/deno;
-    RealScalar w = sqrt(numext::abs2(tau) + RealScalar(1));
-    RealScalar t;
-    if(tau>RealScalar(0))
-    {
-      t = RealScalar(1) / (tau + w);
-    }
-    else
-    {
-      t = RealScalar(1) / (tau - w);
-    }
-    RealScalar sign_t = t > RealScalar(0) ? RealScalar(1) : RealScalar(-1);
-    RealScalar n = RealScalar(1) / sqrt(numext::abs2(t)+RealScalar(1));
-    m_s = - sign_t * (numext::conj(y) / abs(y)) * abs(t) * n;
-    m_c = n;
-    return true;
-  }
-}
-
-/** Makes \c *this as a Jacobi rotation \c J such that applying \a J on both the right and left sides of the 2x2 selfadjoint matrix
-  * \f$ B = \left ( \begin{array}{cc} \text{this}_{pp} & \text{this}_{pq} \\ (\text{this}_{pq})^* & \text{this}_{qq} \end{array} \right )\f$ yields
-  * a diagonal matrix \f$ A = J^* B J \f$
-  *
-  * Example: \include Jacobi_makeJacobi.cpp
-  * Output: \verbinclude Jacobi_makeJacobi.out
-  *
-  * \sa JacobiRotation::makeJacobi(RealScalar, Scalar, RealScalar), MatrixBase::applyOnTheLeft(), MatrixBase::applyOnTheRight()
-  */
-template<typename Scalar>
-template<typename Derived>
-inline bool JacobiRotation<Scalar>::makeJacobi(const MatrixBase<Derived>& m, Index p, Index q)
-{
-  return makeJacobi(numext::real(m.coeff(p,p)), m.coeff(p,q), numext::real(m.coeff(q,q)));
-}
-
-/** Makes \c *this as a Givens rotation \c G such that applying \f$ G^* \f$ to the left of the vector
-  * \f$ V = \left ( \begin{array}{c} p \\ q \end{array} \right )\f$ yields:
-  * \f$ G^* V = \left ( \begin{array}{c} r \\ 0 \end{array} \right )\f$.
-  *
-  * The value of \a r is returned if \a r is not null (the default is null).
-  * Also note that G is built such that the cosine is always real.
-  *
-  * Example: \include Jacobi_makeGivens.cpp
-  * Output: \verbinclude Jacobi_makeGivens.out
-  *
-  * This function implements the continuous Givens rotation generation algorithm
-  * found in Anderson (2000), Discontinuous Plane Rotations and the Symmetric Eigenvalue Problem.
-  * LAPACK Working Note 150, University of Tennessee, UT-CS-00-454, December 4, 2000.
-  *
-  * \sa MatrixBase::applyOnTheLeft(), MatrixBase::applyOnTheRight()
-  */
-template<typename Scalar>
-void JacobiRotation<Scalar>::makeGivens(const Scalar& p, const Scalar& q, Scalar* r)
-{
-  makeGivens(p, q, r, typename internal::conditional<NumTraits<Scalar>::IsComplex, internal::true_type, internal::false_type>::type());
-}
-
-
-// specialization for complexes
-template<typename Scalar>
-void JacobiRotation<Scalar>::makeGivens(const Scalar& p, const Scalar& q, Scalar* r, internal::true_type)
-{
-  using std::sqrt;
-  using std::abs;
-  using numext::conj;
-  
-  if(q==Scalar(0))
-  {
-    m_c = numext::real(p)<0 ? Scalar(-1) : Scalar(1);
-    m_s = 0;
-    if(r) *r = m_c * p;
-  }
-  else if(p==Scalar(0))
-  {
-    m_c = 0;
-    m_s = -q/abs(q);
-    if(r) *r = abs(q);
-  }
-  else
-  {
-    RealScalar p1 = numext::norm1(p);
-    RealScalar q1 = numext::norm1(q);
-    if(p1>=q1)
-    {
-      Scalar ps = p / p1;
-      RealScalar p2 = numext::abs2(ps);
-      Scalar qs = q / p1;
-      RealScalar q2 = numext::abs2(qs);
-
-      RealScalar u = sqrt(RealScalar(1) + q2/p2);
-      if(numext::real(p)<RealScalar(0))
-        u = -u;
-
-      m_c = Scalar(1)/u;
-      m_s = -qs*conj(ps)*(m_c/p2);
-      if(r) *r = p * u;
-    }
-    else
-    {
-      Scalar ps = p / q1;
-      RealScalar p2 = numext::abs2(ps);
-      Scalar qs = q / q1;
-      RealScalar q2 = numext::abs2(qs);
-
-      RealScalar u = q1 * sqrt(p2 + q2);
-      if(numext::real(p)<RealScalar(0))
-        u = -u;
-
-      p1 = abs(p);
-      ps = p/p1;
-      m_c = p1/u;
-      m_s = -conj(ps) * (q/u);
-      if(r) *r = ps * u;
-    }
-  }
-}
-
-// specialization for reals
-template<typename Scalar>
-void JacobiRotation<Scalar>::makeGivens(const Scalar& p, const Scalar& q, Scalar* r, internal::false_type)
-{
-  using std::sqrt;
-  using std::abs;
-  if(q==Scalar(0))
-  {
-    m_c = p<Scalar(0) ? Scalar(-1) : Scalar(1);
-    m_s = Scalar(0);
-    if(r) *r = abs(p);
-  }
-  else if(p==Scalar(0))
-  {
-    m_c = Scalar(0);
-    m_s = q<Scalar(0) ? Scalar(1) : Scalar(-1);
-    if(r) *r = abs(q);
-  }
-  else if(abs(p) > abs(q))
-  {
-    Scalar t = q/p;
-    Scalar u = sqrt(Scalar(1) + numext::abs2(t));
-    if(p<Scalar(0))
-      u = -u;
-    m_c = Scalar(1)/u;
-    m_s = -t * m_c;
-    if(r) *r = p * u;
-  }
-  else
-  {
-    Scalar t = p/q;
-    Scalar u = sqrt(Scalar(1) + numext::abs2(t));
-    if(q<Scalar(0))
-      u = -u;
-    m_s = -Scalar(1)/u;
-    m_c = -t * m_s;
-    if(r) *r = q * u;
-  }
-
-}
-
-/****************************************************************************************
-*   Implementation of MatrixBase methods
-****************************************************************************************/
-
-namespace internal {
-/** \jacobi_module
-  * Applies the clock wise 2D rotation \a j to the set of 2D vectors of cordinates \a x and \a y:
-  * \f$ \left ( \begin{array}{cc} x \\ y \end{array} \right )  =  J \left ( \begin{array}{cc} x \\ y \end{array} \right ) \f$
-  *
-  * \sa MatrixBase::applyOnTheLeft(), MatrixBase::applyOnTheRight()
-  */
-template<typename VectorX, typename VectorY, typename OtherScalar>
-void apply_rotation_in_the_plane(DenseBase<VectorX>& xpr_x, DenseBase<VectorY>& xpr_y, const JacobiRotation<OtherScalar>& j);
-}
-
-/** \jacobi_module
-  * Applies the rotation in the plane \a j to the rows \a p and \a q of \c *this, i.e., it computes B = J * B,
-  * with \f$ B = \left ( \begin{array}{cc} \text{*this.row}(p) \\ \text{*this.row}(q) \end{array} \right ) \f$.
-  *
-  * \sa class JacobiRotation, MatrixBase::applyOnTheRight(), internal::apply_rotation_in_the_plane()
-  */
-template<typename Derived>
-template<typename OtherScalar>
-inline void MatrixBase<Derived>::applyOnTheLeft(Index p, Index q, const JacobiRotation<OtherScalar>& j)
-{
-  RowXpr x(this->row(p));
-  RowXpr y(this->row(q));
-  internal::apply_rotation_in_the_plane(x, y, j);
-}
-
-/** \ingroup Jacobi_Module
-  * Applies the rotation in the plane \a j to the columns \a p and \a q of \c *this, i.e., it computes B = B * J
-  * with \f$ B = \left ( \begin{array}{cc} \text{*this.col}(p) & \text{*this.col}(q) \end{array} \right ) \f$.
-  *
-  * \sa class JacobiRotation, MatrixBase::applyOnTheLeft(), internal::apply_rotation_in_the_plane()
-  */
-template<typename Derived>
-template<typename OtherScalar>
-inline void MatrixBase<Derived>::applyOnTheRight(Index p, Index q, const JacobiRotation<OtherScalar>& j)
-{
-  ColXpr x(this->col(p));
-  ColXpr y(this->col(q));
-  internal::apply_rotation_in_the_plane(x, y, j.transpose());
-}
-
-namespace internal {
-
-template<typename Scalar, typename OtherScalar,
-         int SizeAtCompileTime, int MinAlignment, bool Vectorizable>
-struct apply_rotation_in_the_plane_selector
-{
-  static inline void run(Scalar *x, Index incrx, Scalar *y, Index incry, Index size, OtherScalar c, OtherScalar s)
-  {
-    for(Index i=0; i<size; ++i)
-    {
-      Scalar xi = *x;
-      Scalar yi = *y;
-      *x =  c * xi + numext::conj(s) * yi;
-      *y = -s * xi + numext::conj(c) * yi;
-      x += incrx;
-      y += incry;
-    }
-  }
-};
-
-template<typename Scalar, typename OtherScalar,
-         int SizeAtCompileTime, int MinAlignment>
-struct apply_rotation_in_the_plane_selector<Scalar,OtherScalar,SizeAtCompileTime,MinAlignment,true /* vectorizable */>
-{
-  static inline void run(Scalar *x, Index incrx, Scalar *y, Index incry, Index size, OtherScalar c, OtherScalar s)
-  {
-    enum {
-      PacketSize = packet_traits<Scalar>::size,
-      OtherPacketSize = packet_traits<OtherScalar>::size
-    };
-    typedef typename packet_traits<Scalar>::type Packet;
-    typedef typename packet_traits<OtherScalar>::type OtherPacket;
-
-    /*** dynamic-size vectorized paths ***/
-    if(SizeAtCompileTime == Dynamic && ((incrx==1 && incry==1) || PacketSize == 1))
-    {
-      // both vectors are sequentially stored in memory => vectorization
-      enum { Peeling = 2 };
-
-      Index alignedStart = internal::first_default_aligned(y, size);
-      Index alignedEnd = alignedStart + ((size-alignedStart)/PacketSize)*PacketSize;
-
-      const OtherPacket pc = pset1<OtherPacket>(c);
-      const OtherPacket ps = pset1<OtherPacket>(s);
-      conj_helper<OtherPacket,Packet,NumTraits<OtherScalar>::IsComplex,false> pcj;
-      conj_helper<OtherPacket,Packet,false,false> pm;
-
-      for(Index i=0; i<alignedStart; ++i)
-      {
-        Scalar xi = x[i];
-        Scalar yi = y[i];
-        x[i] =  c * xi + numext::conj(s) * yi;
-        y[i] = -s * xi + numext::conj(c) * yi;
-      }
-
-      Scalar* EIGEN_RESTRICT px = x + alignedStart;
-      Scalar* EIGEN_RESTRICT py = y + alignedStart;
-
-      if(internal::first_default_aligned(x, size)==alignedStart)
-      {
-        for(Index i=alignedStart; i<alignedEnd; i+=PacketSize)
-        {
-          Packet xi = pload<Packet>(px);
-          Packet yi = pload<Packet>(py);
-          pstore(px, padd(pm.pmul(pc,xi),pcj.pmul(ps,yi)));
-          pstore(py, psub(pcj.pmul(pc,yi),pm.pmul(ps,xi)));
-          px += PacketSize;
-          py += PacketSize;
-        }
-      }
-      else
-      {
-        Index peelingEnd = alignedStart + ((size-alignedStart)/(Peeling*PacketSize))*(Peeling*PacketSize);
-        for(Index i=alignedStart; i<peelingEnd; i+=Peeling*PacketSize)
-        {
-          Packet xi   = ploadu<Packet>(px);
-          Packet xi1  = ploadu<Packet>(px+PacketSize);
-          Packet yi   = pload <Packet>(py);
-          Packet yi1  = pload <Packet>(py+PacketSize);
-          pstoreu(px, padd(pm.pmul(pc,xi),pcj.pmul(ps,yi)));
-          pstoreu(px+PacketSize, padd(pm.pmul(pc,xi1),pcj.pmul(ps,yi1)));
-          pstore (py, psub(pcj.pmul(pc,yi),pm.pmul(ps,xi)));
-          pstore (py+PacketSize, psub(pcj.pmul(pc,yi1),pm.pmul(ps,xi1)));
-          px += Peeling*PacketSize;
-          py += Peeling*PacketSize;
-        }
-        if(alignedEnd!=peelingEnd)
-        {
-          Packet xi = ploadu<Packet>(x+peelingEnd);
-          Packet yi = pload <Packet>(y+peelingEnd);
-          pstoreu(x+peelingEnd, padd(pm.pmul(pc,xi),pcj.pmul(ps,yi)));
-          pstore (y+peelingEnd, psub(pcj.pmul(pc,yi),pm.pmul(ps,xi)));
-        }
-      }
-
-      for(Index i=alignedEnd; i<size; ++i)
-      {
-        Scalar xi = x[i];
-        Scalar yi = y[i];
-        x[i] =  c * xi + numext::conj(s) * yi;
-        y[i] = -s * xi + numext::conj(c) * yi;
-      }
-    }
-
-    /*** fixed-size vectorized path ***/
-    else if(SizeAtCompileTime != Dynamic && MinAlignment>0) // FIXME should be compared to the required alignment
-    {
-      const OtherPacket pc = pset1<OtherPacket>(c);
-      const OtherPacket ps = pset1<OtherPacket>(s);
-      conj_helper<OtherPacket,Packet,NumTraits<OtherPacket>::IsComplex,false> pcj;
-      conj_helper<OtherPacket,Packet,false,false> pm;
-      Scalar* EIGEN_RESTRICT px = x;
-      Scalar* EIGEN_RESTRICT py = y;
-      for(Index i=0; i<size; i+=PacketSize)
-      {
-        Packet xi = pload<Packet>(px);
-        Packet yi = pload<Packet>(py);
-        pstore(px, padd(pm.pmul(pc,xi),pcj.pmul(ps,yi)));
-        pstore(py, psub(pcj.pmul(pc,yi),pm.pmul(ps,xi)));
-        px += PacketSize;
-        py += PacketSize;
-      }
-    }
-
-    /*** non-vectorized path ***/
-    else
-    {
-      apply_rotation_in_the_plane_selector<Scalar,OtherScalar,SizeAtCompileTime,MinAlignment,false>::run(x,incrx,y,incry,size,c,s);
-    }
-  }
-};
-
-template<typename VectorX, typename VectorY, typename OtherScalar>
-void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(DenseBase<VectorX>& xpr_x, DenseBase<VectorY>& xpr_y, const JacobiRotation<OtherScalar>& j)
-{
-  typedef typename VectorX::Scalar Scalar;
-  const bool Vectorizable =    (VectorX::Flags & VectorY::Flags & PacketAccessBit)
-                            && (int(packet_traits<Scalar>::size) == int(packet_traits<OtherScalar>::size));
-
-  eigen_assert(xpr_x.size() == xpr_y.size());
-  Index size = xpr_x.size();
-  Index incrx = xpr_x.derived().innerStride();
-  Index incry = xpr_y.derived().innerStride();
-
-  Scalar* EIGEN_RESTRICT x = &xpr_x.derived().coeffRef(0);
-  Scalar* EIGEN_RESTRICT y = &xpr_y.derived().coeffRef(0);
-  
-  OtherScalar c = j.c();
-  OtherScalar s = j.s();
-  if (c==OtherScalar(1) && s==OtherScalar(0))
-    return;
-
-  apply_rotation_in_the_plane_selector<
-    Scalar,OtherScalar,
-    VectorX::SizeAtCompileTime,
-    EIGEN_PLAIN_ENUM_MIN(evaluator<VectorX>::Alignment, evaluator<VectorY>::Alignment),
-    Vectorizable>::run(x,incrx,y,incry,size,c,s);
-}
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_JACOBI_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/LU/Determinant.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/LU/Determinant.h
deleted file mode 100644
index d6a3c1e..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/LU/Determinant.h
+++ /dev/null
@@ -1,101 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_DETERMINANT_H
-#define EIGEN_DETERMINANT_H
-
-namespace Eigen { 
-
-namespace internal {
-
-template<typename Derived>
-inline const typename Derived::Scalar bruteforce_det3_helper
-(const MatrixBase<Derived>& matrix, int a, int b, int c)
-{
-  return matrix.coeff(0,a)
-         * (matrix.coeff(1,b) * matrix.coeff(2,c) - matrix.coeff(1,c) * matrix.coeff(2,b));
-}
-
-template<typename Derived>
-const typename Derived::Scalar bruteforce_det4_helper
-(const MatrixBase<Derived>& matrix, int j, int k, int m, int n)
-{
-  return (matrix.coeff(j,0) * matrix.coeff(k,1) - matrix.coeff(k,0) * matrix.coeff(j,1))
-       * (matrix.coeff(m,2) * matrix.coeff(n,3) - matrix.coeff(n,2) * matrix.coeff(m,3));
-}
-
-template<typename Derived,
-         int DeterminantType = Derived::RowsAtCompileTime
-> struct determinant_impl
-{
-  static inline typename traits<Derived>::Scalar run(const Derived& m)
-  {
-    if(Derived::ColsAtCompileTime==Dynamic && m.rows()==0)
-      return typename traits<Derived>::Scalar(1);
-    return m.partialPivLu().determinant();
-  }
-};
-
-template<typename Derived> struct determinant_impl<Derived, 1>
-{
-  static inline typename traits<Derived>::Scalar run(const Derived& m)
-  {
-    return m.coeff(0,0);
-  }
-};
-
-template<typename Derived> struct determinant_impl<Derived, 2>
-{
-  static inline typename traits<Derived>::Scalar run(const Derived& m)
-  {
-    return m.coeff(0,0) * m.coeff(1,1) - m.coeff(1,0) * m.coeff(0,1);
-  }
-};
-
-template<typename Derived> struct determinant_impl<Derived, 3>
-{
-  static inline typename traits<Derived>::Scalar run(const Derived& m)
-  {
-    return bruteforce_det3_helper(m,0,1,2)
-          - bruteforce_det3_helper(m,1,0,2)
-          + bruteforce_det3_helper(m,2,0,1);
-  }
-};
-
-template<typename Derived> struct determinant_impl<Derived, 4>
-{
-  static typename traits<Derived>::Scalar run(const Derived& m)
-  {
-    // trick by Martin Costabel to compute 4x4 det with only 30 muls
-    return bruteforce_det4_helper(m,0,1,2,3)
-          - bruteforce_det4_helper(m,0,2,1,3)
-          + bruteforce_det4_helper(m,0,3,1,2)
-          + bruteforce_det4_helper(m,1,2,0,3)
-          - bruteforce_det4_helper(m,1,3,0,2)
-          + bruteforce_det4_helper(m,2,3,0,1);
-  }
-};
-
-} // end namespace internal
-
-/** \lu_module
-  *
-  * \returns the determinant of this matrix
-  */
-template<typename Derived>
-inline typename internal::traits<Derived>::Scalar MatrixBase<Derived>::determinant() const
-{
-  eigen_assert(rows() == cols());
-  typedef typename internal::nested_eval<Derived,Base::RowsAtCompileTime>::type Nested;
-  return internal::determinant_impl<typename internal::remove_all<Nested>::type>::run(derived());
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_DETERMINANT_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/LU/FullPivLU.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/LU/FullPivLU.h
deleted file mode 100644
index 03b6af7..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/LU/FullPivLU.h
+++ /dev/null
@@ -1,891 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_LU_H
-#define EIGEN_LU_H
-
-namespace Eigen {
-
-namespace internal {
-template<typename _MatrixType> struct traits<FullPivLU<_MatrixType> >
- : traits<_MatrixType>
-{
-  typedef MatrixXpr XprKind;
-  typedef SolverStorage StorageKind;
-  enum { Flags = 0 };
-};
-
-} // end namespace internal
-
-/** \ingroup LU_Module
-  *
-  * \class FullPivLU
-  *
-  * \brief LU decomposition of a matrix with complete pivoting, and related features
-  *
-  * \tparam _MatrixType the type of the matrix of which we are computing the LU decomposition
-  *
-  * This class represents a LU decomposition of any matrix, with complete pivoting: the matrix A is
-  * decomposed as \f$ A = P^{-1} L U Q^{-1} \f$ where L is unit-lower-triangular, U is
-  * upper-triangular, and P and Q are permutation matrices. This is a rank-revealing LU
-  * decomposition. The eigenvalues (diagonal coefficients) of U are sorted in such a way that any
-  * zeros are at the end.
-  *
-  * This decomposition provides the generic approach to solving systems of linear equations, computing
-  * the rank, invertibility, inverse, kernel, and determinant.
-  *
-  * This LU decomposition is very stable and well tested with large matrices. However there are use cases where the SVD
-  * decomposition is inherently more stable and/or flexible. For example, when computing the kernel of a matrix,
-  * working with the SVD allows to select the smallest singular values of the matrix, something that
-  * the LU decomposition doesn't see.
-  *
-  * The data of the LU decomposition can be directly accessed through the methods matrixLU(),
-  * permutationP(), permutationQ().
-  *
-  * As an exemple, here is how the original matrix can be retrieved:
-  * \include class_FullPivLU.cpp
-  * Output: \verbinclude class_FullPivLU.out
-  *
-  * This class supports the \link InplaceDecomposition inplace decomposition \endlink mechanism.
-  * 
-  * \sa MatrixBase::fullPivLu(), MatrixBase::determinant(), MatrixBase::inverse()
-  */
-template<typename _MatrixType> class FullPivLU
-  : public SolverBase<FullPivLU<_MatrixType> >
-{
-  public:
-    typedef _MatrixType MatrixType;
-    typedef SolverBase<FullPivLU> Base;
-
-    EIGEN_GENERIC_PUBLIC_INTERFACE(FullPivLU)
-    // FIXME StorageIndex defined in EIGEN_GENERIC_PUBLIC_INTERFACE should be int
-    enum {
-      MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
-      MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
-    };
-    typedef typename internal::plain_row_type<MatrixType, StorageIndex>::type IntRowVectorType;
-    typedef typename internal::plain_col_type<MatrixType, StorageIndex>::type IntColVectorType;
-    typedef PermutationMatrix<ColsAtCompileTime, MaxColsAtCompileTime> PermutationQType;
-    typedef PermutationMatrix<RowsAtCompileTime, MaxRowsAtCompileTime> PermutationPType;
-    typedef typename MatrixType::PlainObject PlainObject;
-
-    /**
-      * \brief Default Constructor.
-      *
-      * The default constructor is useful in cases in which the user intends to
-      * perform decompositions via LU::compute(const MatrixType&).
-      */
-    FullPivLU();
-
-    /** \brief Default Constructor with memory preallocation
-      *
-      * Like the default constructor but with preallocation of the internal data
-      * according to the specified problem \a size.
-      * \sa FullPivLU()
-      */
-    FullPivLU(Index rows, Index cols);
-
-    /** Constructor.
-      *
-      * \param matrix the matrix of which to compute the LU decomposition.
-      *               It is required to be nonzero.
-      */
-    template<typename InputType>
-    explicit FullPivLU(const EigenBase<InputType>& matrix);
-
-    /** \brief Constructs a LU factorization from a given matrix
-      *
-      * This overloaded constructor is provided for \link InplaceDecomposition inplace decomposition \endlink when \c MatrixType is a Eigen::Ref.
-      *
-      * \sa FullPivLU(const EigenBase&)
-      */
-    template<typename InputType>
-    explicit FullPivLU(EigenBase<InputType>& matrix);
-
-    /** Computes the LU decomposition of the given matrix.
-      *
-      * \param matrix the matrix of which to compute the LU decomposition.
-      *               It is required to be nonzero.
-      *
-      * \returns a reference to *this
-      */
-    template<typename InputType>
-    FullPivLU& compute(const EigenBase<InputType>& matrix) {
-      m_lu = matrix.derived();
-      computeInPlace();
-      return *this;
-    }
-
-    /** \returns the LU decomposition matrix: the upper-triangular part is U, the
-      * unit-lower-triangular part is L (at least for square matrices; in the non-square
-      * case, special care is needed, see the documentation of class FullPivLU).
-      *
-      * \sa matrixL(), matrixU()
-      */
-    inline const MatrixType& matrixLU() const
-    {
-      eigen_assert(m_isInitialized && "LU is not initialized.");
-      return m_lu;
-    }
-
-    /** \returns the number of nonzero pivots in the LU decomposition.
-      * Here nonzero is meant in the exact sense, not in a fuzzy sense.
-      * So that notion isn't really intrinsically interesting, but it is
-      * still useful when implementing algorithms.
-      *
-      * \sa rank()
-      */
-    inline Index nonzeroPivots() const
-    {
-      eigen_assert(m_isInitialized && "LU is not initialized.");
-      return m_nonzero_pivots;
-    }
-
-    /** \returns the absolute value of the biggest pivot, i.e. the biggest
-      *          diagonal coefficient of U.
-      */
-    RealScalar maxPivot() const { return m_maxpivot; }
-
-    /** \returns the permutation matrix P
-      *
-      * \sa permutationQ()
-      */
-    EIGEN_DEVICE_FUNC inline const PermutationPType& permutationP() const
-    {
-      eigen_assert(m_isInitialized && "LU is not initialized.");
-      return m_p;
-    }
-
-    /** \returns the permutation matrix Q
-      *
-      * \sa permutationP()
-      */
-    inline const PermutationQType& permutationQ() const
-    {
-      eigen_assert(m_isInitialized && "LU is not initialized.");
-      return m_q;
-    }
-
-    /** \returns the kernel of the matrix, also called its null-space. The columns of the returned matrix
-      * will form a basis of the kernel.
-      *
-      * \note If the kernel has dimension zero, then the returned matrix is a column-vector filled with zeros.
-      *
-      * \note This method has to determine which pivots should be considered nonzero.
-      *       For that, it uses the threshold value that you can control by calling
-      *       setThreshold(const RealScalar&).
-      *
-      * Example: \include FullPivLU_kernel.cpp
-      * Output: \verbinclude FullPivLU_kernel.out
-      *
-      * \sa image()
-      */
-    inline const internal::kernel_retval<FullPivLU> kernel() const
-    {
-      eigen_assert(m_isInitialized && "LU is not initialized.");
-      return internal::kernel_retval<FullPivLU>(*this);
-    }
-
-    /** \returns the image of the matrix, also called its column-space. The columns of the returned matrix
-      * will form a basis of the image (column-space).
-      *
-      * \param originalMatrix the original matrix, of which *this is the LU decomposition.
-      *                       The reason why it is needed to pass it here, is that this allows
-      *                       a large optimization, as otherwise this method would need to reconstruct it
-      *                       from the LU decomposition.
-      *
-      * \note If the image has dimension zero, then the returned matrix is a column-vector filled with zeros.
-      *
-      * \note This method has to determine which pivots should be considered nonzero.
-      *       For that, it uses the threshold value that you can control by calling
-      *       setThreshold(const RealScalar&).
-      *
-      * Example: \include FullPivLU_image.cpp
-      * Output: \verbinclude FullPivLU_image.out
-      *
-      * \sa kernel()
-      */
-    inline const internal::image_retval<FullPivLU>
-      image(const MatrixType& originalMatrix) const
-    {
-      eigen_assert(m_isInitialized && "LU is not initialized.");
-      return internal::image_retval<FullPivLU>(*this, originalMatrix);
-    }
-
-    /** \return a solution x to the equation Ax=b, where A is the matrix of which
-      * *this is the LU decomposition.
-      *
-      * \param b the right-hand-side of the equation to solve. Can be a vector or a matrix,
-      *          the only requirement in order for the equation to make sense is that
-      *          b.rows()==A.rows(), where A is the matrix of which *this is the LU decomposition.
-      *
-      * \returns a solution.
-      *
-      * \note_about_checking_solutions
-      *
-      * \note_about_arbitrary_choice_of_solution
-      * \note_about_using_kernel_to_study_multiple_solutions
-      *
-      * Example: \include FullPivLU_solve.cpp
-      * Output: \verbinclude FullPivLU_solve.out
-      *
-      * \sa TriangularView::solve(), kernel(), inverse()
-      */
-    // FIXME this is a copy-paste of the base-class member to add the isInitialized assertion.
-    template<typename Rhs>
-    inline const Solve<FullPivLU, Rhs>
-    solve(const MatrixBase<Rhs>& b) const
-    {
-      eigen_assert(m_isInitialized && "LU is not initialized.");
-      return Solve<FullPivLU, Rhs>(*this, b.derived());
-    }
-
-    /** \returns an estimate of the reciprocal condition number of the matrix of which \c *this is
-        the LU decomposition.
-      */
-    inline RealScalar rcond() const
-    {
-      eigen_assert(m_isInitialized && "PartialPivLU is not initialized.");
-      return internal::rcond_estimate_helper(m_l1_norm, *this);
-    }
-
-    /** \returns the determinant of the matrix of which
-      * *this is the LU decomposition. It has only linear complexity
-      * (that is, O(n) where n is the dimension of the square matrix)
-      * as the LU decomposition has already been computed.
-      *
-      * \note This is only for square matrices.
-      *
-      * \note For fixed-size matrices of size up to 4, MatrixBase::determinant() offers
-      *       optimized paths.
-      *
-      * \warning a determinant can be very big or small, so for matrices
-      * of large enough dimension, there is a risk of overflow/underflow.
-      *
-      * \sa MatrixBase::determinant()
-      */
-    typename internal::traits<MatrixType>::Scalar determinant() const;
-
-    /** Allows to prescribe a threshold to be used by certain methods, such as rank(),
-      * who need to determine when pivots are to be considered nonzero. This is not used for the
-      * LU decomposition itself.
-      *
-      * When it needs to get the threshold value, Eigen calls threshold(). By default, this
-      * uses a formula to automatically determine a reasonable threshold.
-      * Once you have called the present method setThreshold(const RealScalar&),
-      * your value is used instead.
-      *
-      * \param threshold The new value to use as the threshold.
-      *
-      * A pivot will be considered nonzero if its absolute value is strictly greater than
-      *  \f$ \vert pivot \vert \leqslant threshold \times \vert maxpivot \vert \f$
-      * where maxpivot is the biggest pivot.
-      *
-      * If you want to come back to the default behavior, call setThreshold(Default_t)
-      */
-    FullPivLU& setThreshold(const RealScalar& threshold)
-    {
-      m_usePrescribedThreshold = true;
-      m_prescribedThreshold = threshold;
-      return *this;
-    }
-
-    /** Allows to come back to the default behavior, letting Eigen use its default formula for
-      * determining the threshold.
-      *
-      * You should pass the special object Eigen::Default as parameter here.
-      * \code lu.setThreshold(Eigen::Default); \endcode
-      *
-      * See the documentation of setThreshold(const RealScalar&).
-      */
-    FullPivLU& setThreshold(Default_t)
-    {
-      m_usePrescribedThreshold = false;
-      return *this;
-    }
-
-    /** Returns the threshold that will be used by certain methods such as rank().
-      *
-      * See the documentation of setThreshold(const RealScalar&).
-      */
-    RealScalar threshold() const
-    {
-      eigen_assert(m_isInitialized || m_usePrescribedThreshold);
-      return m_usePrescribedThreshold ? m_prescribedThreshold
-      // this formula comes from experimenting (see "LU precision tuning" thread on the list)
-      // and turns out to be identical to Higham's formula used already in LDLt.
-                                      : NumTraits<Scalar>::epsilon() * m_lu.diagonalSize();
-    }
-
-    /** \returns the rank of the matrix of which *this is the LU decomposition.
-      *
-      * \note This method has to determine which pivots should be considered nonzero.
-      *       For that, it uses the threshold value that you can control by calling
-      *       setThreshold(const RealScalar&).
-      */
-    inline Index rank() const
-    {
-      using std::abs;
-      eigen_assert(m_isInitialized && "LU is not initialized.");
-      RealScalar premultiplied_threshold = abs(m_maxpivot) * threshold();
-      Index result = 0;
-      for(Index i = 0; i < m_nonzero_pivots; ++i)
-        result += (abs(m_lu.coeff(i,i)) > premultiplied_threshold);
-      return result;
-    }
-
-    /** \returns the dimension of the kernel of the matrix of which *this is the LU decomposition.
-      *
-      * \note This method has to determine which pivots should be considered nonzero.
-      *       For that, it uses the threshold value that you can control by calling
-      *       setThreshold(const RealScalar&).
-      */
-    inline Index dimensionOfKernel() const
-    {
-      eigen_assert(m_isInitialized && "LU is not initialized.");
-      return cols() - rank();
-    }
-
-    /** \returns true if the matrix of which *this is the LU decomposition represents an injective
-      *          linear map, i.e. has trivial kernel; false otherwise.
-      *
-      * \note This method has to determine which pivots should be considered nonzero.
-      *       For that, it uses the threshold value that you can control by calling
-      *       setThreshold(const RealScalar&).
-      */
-    inline bool isInjective() const
-    {
-      eigen_assert(m_isInitialized && "LU is not initialized.");
-      return rank() == cols();
-    }
-
-    /** \returns true if the matrix of which *this is the LU decomposition represents a surjective
-      *          linear map; false otherwise.
-      *
-      * \note This method has to determine which pivots should be considered nonzero.
-      *       For that, it uses the threshold value that you can control by calling
-      *       setThreshold(const RealScalar&).
-      */
-    inline bool isSurjective() const
-    {
-      eigen_assert(m_isInitialized && "LU is not initialized.");
-      return rank() == rows();
-    }
-
-    /** \returns true if the matrix of which *this is the LU decomposition is invertible.
-      *
-      * \note This method has to determine which pivots should be considered nonzero.
-      *       For that, it uses the threshold value that you can control by calling
-      *       setThreshold(const RealScalar&).
-      */
-    inline bool isInvertible() const
-    {
-      eigen_assert(m_isInitialized && "LU is not initialized.");
-      return isInjective() && (m_lu.rows() == m_lu.cols());
-    }
-
-    /** \returns the inverse of the matrix of which *this is the LU decomposition.
-      *
-      * \note If this matrix is not invertible, the returned matrix has undefined coefficients.
-      *       Use isInvertible() to first determine whether this matrix is invertible.
-      *
-      * \sa MatrixBase::inverse()
-      */
-    inline const Inverse<FullPivLU> inverse() const
-    {
-      eigen_assert(m_isInitialized && "LU is not initialized.");
-      eigen_assert(m_lu.rows() == m_lu.cols() && "You can't take the inverse of a non-square matrix!");
-      return Inverse<FullPivLU>(*this);
-    }
-
-    MatrixType reconstructedMatrix() const;
-
-    EIGEN_DEVICE_FUNC inline Index rows() const { return m_lu.rows(); }
-    EIGEN_DEVICE_FUNC inline Index cols() const { return m_lu.cols(); }
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    template<typename RhsType, typename DstType>
-    EIGEN_DEVICE_FUNC
-    void _solve_impl(const RhsType &rhs, DstType &dst) const;
-
-    template<bool Conjugate, typename RhsType, typename DstType>
-    EIGEN_DEVICE_FUNC
-    void _solve_impl_transposed(const RhsType &rhs, DstType &dst) const;
-    #endif
-
-  protected:
-
-    static void check_template_parameters()
-    {
-      EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
-    }
-
-    void computeInPlace();
-
-    MatrixType m_lu;
-    PermutationPType m_p;
-    PermutationQType m_q;
-    IntColVectorType m_rowsTranspositions;
-    IntRowVectorType m_colsTranspositions;
-    Index m_nonzero_pivots;
-    RealScalar m_l1_norm;
-    RealScalar m_maxpivot, m_prescribedThreshold;
-    signed char m_det_pq;
-    bool m_isInitialized, m_usePrescribedThreshold;
-};
-
-template<typename MatrixType>
-FullPivLU<MatrixType>::FullPivLU()
-  : m_isInitialized(false), m_usePrescribedThreshold(false)
-{
-}
-
-template<typename MatrixType>
-FullPivLU<MatrixType>::FullPivLU(Index rows, Index cols)
-  : m_lu(rows, cols),
-    m_p(rows),
-    m_q(cols),
-    m_rowsTranspositions(rows),
-    m_colsTranspositions(cols),
-    m_isInitialized(false),
-    m_usePrescribedThreshold(false)
-{
-}
-
-template<typename MatrixType>
-template<typename InputType>
-FullPivLU<MatrixType>::FullPivLU(const EigenBase<InputType>& matrix)
-  : m_lu(matrix.rows(), matrix.cols()),
-    m_p(matrix.rows()),
-    m_q(matrix.cols()),
-    m_rowsTranspositions(matrix.rows()),
-    m_colsTranspositions(matrix.cols()),
-    m_isInitialized(false),
-    m_usePrescribedThreshold(false)
-{
-  compute(matrix.derived());
-}
-
-template<typename MatrixType>
-template<typename InputType>
-FullPivLU<MatrixType>::FullPivLU(EigenBase<InputType>& matrix)
-  : m_lu(matrix.derived()),
-    m_p(matrix.rows()),
-    m_q(matrix.cols()),
-    m_rowsTranspositions(matrix.rows()),
-    m_colsTranspositions(matrix.cols()),
-    m_isInitialized(false),
-    m_usePrescribedThreshold(false)
-{
-  computeInPlace();
-}
-
-template<typename MatrixType>
-void FullPivLU<MatrixType>::computeInPlace()
-{
-  check_template_parameters();
-
-  // the permutations are stored as int indices, so just to be sure:
-  eigen_assert(m_lu.rows()<=NumTraits<int>::highest() && m_lu.cols()<=NumTraits<int>::highest());
-
-  m_l1_norm = m_lu.cwiseAbs().colwise().sum().maxCoeff();
-
-  const Index size = m_lu.diagonalSize();
-  const Index rows = m_lu.rows();
-  const Index cols = m_lu.cols();
-
-  // will store the transpositions, before we accumulate them at the end.
-  // can't accumulate on-the-fly because that will be done in reverse order for the rows.
-  m_rowsTranspositions.resize(m_lu.rows());
-  m_colsTranspositions.resize(m_lu.cols());
-  Index number_of_transpositions = 0; // number of NONTRIVIAL transpositions, i.e. m_rowsTranspositions[i]!=i
-
-  m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
-  m_maxpivot = RealScalar(0);
-
-  for(Index k = 0; k < size; ++k)
-  {
-    // First, we need to find the pivot.
-
-    // biggest coefficient in the remaining bottom-right corner (starting at row k, col k)
-    Index row_of_biggest_in_corner, col_of_biggest_in_corner;
-    typedef internal::scalar_score_coeff_op<Scalar> Scoring;
-    typedef typename Scoring::result_type Score;
-    Score biggest_in_corner;
-    biggest_in_corner = m_lu.bottomRightCorner(rows-k, cols-k)
-                        .unaryExpr(Scoring())
-                        .maxCoeff(&row_of_biggest_in_corner, &col_of_biggest_in_corner);
-    row_of_biggest_in_corner += k; // correct the values! since they were computed in the corner,
-    col_of_biggest_in_corner += k; // need to add k to them.
-
-    if(biggest_in_corner==Score(0))
-    {
-      // before exiting, make sure to initialize the still uninitialized transpositions
-      // in a sane state without destroying what we already have.
-      m_nonzero_pivots = k;
-      for(Index i = k; i < size; ++i)
-      {
-        m_rowsTranspositions.coeffRef(i) = i;
-        m_colsTranspositions.coeffRef(i) = i;
-      }
-      break;
-    }
-
-    RealScalar abs_pivot = internal::abs_knowing_score<Scalar>()(m_lu(row_of_biggest_in_corner, col_of_biggest_in_corner), biggest_in_corner);
-    if(abs_pivot > m_maxpivot) m_maxpivot = abs_pivot;
-
-    // Now that we've found the pivot, we need to apply the row/col swaps to
-    // bring it to the location (k,k).
-
-    m_rowsTranspositions.coeffRef(k) = row_of_biggest_in_corner;
-    m_colsTranspositions.coeffRef(k) = col_of_biggest_in_corner;
-    if(k != row_of_biggest_in_corner) {
-      m_lu.row(k).swap(m_lu.row(row_of_biggest_in_corner));
-      ++number_of_transpositions;
-    }
-    if(k != col_of_biggest_in_corner) {
-      m_lu.col(k).swap(m_lu.col(col_of_biggest_in_corner));
-      ++number_of_transpositions;
-    }
-
-    // Now that the pivot is at the right location, we update the remaining
-    // bottom-right corner by Gaussian elimination.
-
-    if(k<rows-1)
-      m_lu.col(k).tail(rows-k-1) /= m_lu.coeff(k,k);
-    if(k<size-1)
-      m_lu.block(k+1,k+1,rows-k-1,cols-k-1).noalias() -= m_lu.col(k).tail(rows-k-1) * m_lu.row(k).tail(cols-k-1);
-  }
-
-  // the main loop is over, we still have to accumulate the transpositions to find the
-  // permutations P and Q
-
-  m_p.setIdentity(rows);
-  for(Index k = size-1; k >= 0; --k)
-    m_p.applyTranspositionOnTheRight(k, m_rowsTranspositions.coeff(k));
-
-  m_q.setIdentity(cols);
-  for(Index k = 0; k < size; ++k)
-    m_q.applyTranspositionOnTheRight(k, m_colsTranspositions.coeff(k));
-
-  m_det_pq = (number_of_transpositions%2) ? -1 : 1;
-
-  m_isInitialized = true;
-}
-
-template<typename MatrixType>
-typename internal::traits<MatrixType>::Scalar FullPivLU<MatrixType>::determinant() const
-{
-  eigen_assert(m_isInitialized && "LU is not initialized.");
-  eigen_assert(m_lu.rows() == m_lu.cols() && "You can't take the determinant of a non-square matrix!");
-  return Scalar(m_det_pq) * Scalar(m_lu.diagonal().prod());
-}
-
-/** \returns the matrix represented by the decomposition,
- * i.e., it returns the product: \f$ P^{-1} L U Q^{-1} \f$.
- * This function is provided for debug purposes. */
-template<typename MatrixType>
-MatrixType FullPivLU<MatrixType>::reconstructedMatrix() const
-{
-  eigen_assert(m_isInitialized && "LU is not initialized.");
-  const Index smalldim = (std::min)(m_lu.rows(), m_lu.cols());
-  // LU
-  MatrixType res(m_lu.rows(),m_lu.cols());
-  // FIXME the .toDenseMatrix() should not be needed...
-  res = m_lu.leftCols(smalldim)
-            .template triangularView<UnitLower>().toDenseMatrix()
-      * m_lu.topRows(smalldim)
-            .template triangularView<Upper>().toDenseMatrix();
-
-  // P^{-1}(LU)
-  res = m_p.inverse() * res;
-
-  // (P^{-1}LU)Q^{-1}
-  res = res * m_q.inverse();
-
-  return res;
-}
-
-/********* Implementation of kernel() **************************************************/
-
-namespace internal {
-template<typename _MatrixType>
-struct kernel_retval<FullPivLU<_MatrixType> >
-  : kernel_retval_base<FullPivLU<_MatrixType> >
-{
-  EIGEN_MAKE_KERNEL_HELPERS(FullPivLU<_MatrixType>)
-
-  enum { MaxSmallDimAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(
-            MatrixType::MaxColsAtCompileTime,
-            MatrixType::MaxRowsAtCompileTime)
-  };
-
-  template<typename Dest> void evalTo(Dest& dst) const
-  {
-    using std::abs;
-    const Index cols = dec().matrixLU().cols(), dimker = cols - rank();
-    if(dimker == 0)
-    {
-      // The Kernel is just {0}, so it doesn't have a basis properly speaking, but let's
-      // avoid crashing/asserting as that depends on floating point calculations. Let's
-      // just return a single column vector filled with zeros.
-      dst.setZero();
-      return;
-    }
-
-    /* Let us use the following lemma:
-      *
-      * Lemma: If the matrix A has the LU decomposition PAQ = LU,
-      * then Ker A = Q(Ker U).
-      *
-      * Proof: trivial: just keep in mind that P, Q, L are invertible.
-      */
-
-    /* Thus, all we need to do is to compute Ker U, and then apply Q.
-      *
-      * U is upper triangular, with eigenvalues sorted so that any zeros appear at the end.
-      * Thus, the diagonal of U ends with exactly
-      * dimKer zero's. Let us use that to construct dimKer linearly
-      * independent vectors in Ker U.
-      */
-
-    Matrix<Index, Dynamic, 1, 0, MaxSmallDimAtCompileTime, 1> pivots(rank());
-    RealScalar premultiplied_threshold = dec().maxPivot() * dec().threshold();
-    Index p = 0;
-    for(Index i = 0; i < dec().nonzeroPivots(); ++i)
-      if(abs(dec().matrixLU().coeff(i,i)) > premultiplied_threshold)
-        pivots.coeffRef(p++) = i;
-    eigen_internal_assert(p == rank());
-
-    // we construct a temporaty trapezoid matrix m, by taking the U matrix and
-    // permuting the rows and cols to bring the nonnegligible pivots to the top of
-    // the main diagonal. We need that to be able to apply our triangular solvers.
-    // FIXME when we get triangularView-for-rectangular-matrices, this can be simplified
-    Matrix<typename MatrixType::Scalar, Dynamic, Dynamic, MatrixType::Options,
-           MaxSmallDimAtCompileTime, MatrixType::MaxColsAtCompileTime>
-      m(dec().matrixLU().block(0, 0, rank(), cols));
-    for(Index i = 0; i < rank(); ++i)
-    {
-      if(i) m.row(i).head(i).setZero();
-      m.row(i).tail(cols-i) = dec().matrixLU().row(pivots.coeff(i)).tail(cols-i);
-    }
-    m.block(0, 0, rank(), rank());
-    m.block(0, 0, rank(), rank()).template triangularView<StrictlyLower>().setZero();
-    for(Index i = 0; i < rank(); ++i)
-      m.col(i).swap(m.col(pivots.coeff(i)));
-
-    // ok, we have our trapezoid matrix, we can apply the triangular solver.
-    // notice that the math behind this suggests that we should apply this to the
-    // negative of the RHS, but for performance we just put the negative sign elsewhere, see below.
-    m.topLeftCorner(rank(), rank())
-     .template triangularView<Upper>().solveInPlace(
-        m.topRightCorner(rank(), dimker)
-      );
-
-    // now we must undo the column permutation that we had applied!
-    for(Index i = rank()-1; i >= 0; --i)
-      m.col(i).swap(m.col(pivots.coeff(i)));
-
-    // see the negative sign in the next line, that's what we were talking about above.
-    for(Index i = 0; i < rank(); ++i) dst.row(dec().permutationQ().indices().coeff(i)) = -m.row(i).tail(dimker);
-    for(Index i = rank(); i < cols; ++i) dst.row(dec().permutationQ().indices().coeff(i)).setZero();
-    for(Index k = 0; k < dimker; ++k) dst.coeffRef(dec().permutationQ().indices().coeff(rank()+k), k) = Scalar(1);
-  }
-};
-
-/***** Implementation of image() *****************************************************/
-
-template<typename _MatrixType>
-struct image_retval<FullPivLU<_MatrixType> >
-  : image_retval_base<FullPivLU<_MatrixType> >
-{
-  EIGEN_MAKE_IMAGE_HELPERS(FullPivLU<_MatrixType>)
-
-  enum { MaxSmallDimAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(
-            MatrixType::MaxColsAtCompileTime,
-            MatrixType::MaxRowsAtCompileTime)
-  };
-
-  template<typename Dest> void evalTo(Dest& dst) const
-  {
-    using std::abs;
-    if(rank() == 0)
-    {
-      // The Image is just {0}, so it doesn't have a basis properly speaking, but let's
-      // avoid crashing/asserting as that depends on floating point calculations. Let's
-      // just return a single column vector filled with zeros.
-      dst.setZero();
-      return;
-    }
-
-    Matrix<Index, Dynamic, 1, 0, MaxSmallDimAtCompileTime, 1> pivots(rank());
-    RealScalar premultiplied_threshold = dec().maxPivot() * dec().threshold();
-    Index p = 0;
-    for(Index i = 0; i < dec().nonzeroPivots(); ++i)
-      if(abs(dec().matrixLU().coeff(i,i)) > premultiplied_threshold)
-        pivots.coeffRef(p++) = i;
-    eigen_internal_assert(p == rank());
-
-    for(Index i = 0; i < rank(); ++i)
-      dst.col(i) = originalMatrix().col(dec().permutationQ().indices().coeff(pivots.coeff(i)));
-  }
-};
-
-/***** Implementation of solve() *****************************************************/
-
-} // end namespace internal
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-template<typename _MatrixType>
-template<typename RhsType, typename DstType>
-void FullPivLU<_MatrixType>::_solve_impl(const RhsType &rhs, DstType &dst) const
-{
-  /* The decomposition PAQ = LU can be rewritten as A = P^{-1} L U Q^{-1}.
-  * So we proceed as follows:
-  * Step 1: compute c = P * rhs.
-  * Step 2: replace c by the solution x to Lx = c. Exists because L is invertible.
-  * Step 3: replace c by the solution x to Ux = c. May or may not exist.
-  * Step 4: result = Q * c;
-  */
-
-  const Index rows = this->rows(),
-              cols = this->cols(),
-              nonzero_pivots = this->rank();
-  eigen_assert(rhs.rows() == rows);
-  const Index smalldim = (std::min)(rows, cols);
-
-  if(nonzero_pivots == 0)
-  {
-    dst.setZero();
-    return;
-  }
-
-  typename RhsType::PlainObject c(rhs.rows(), rhs.cols());
-
-  // Step 1
-  c = permutationP() * rhs;
-
-  // Step 2
-  m_lu.topLeftCorner(smalldim,smalldim)
-      .template triangularView<UnitLower>()
-      .solveInPlace(c.topRows(smalldim));
-  if(rows>cols)
-    c.bottomRows(rows-cols) -= m_lu.bottomRows(rows-cols) * c.topRows(cols);
-
-  // Step 3
-  m_lu.topLeftCorner(nonzero_pivots, nonzero_pivots)
-      .template triangularView<Upper>()
-      .solveInPlace(c.topRows(nonzero_pivots));
-
-  // Step 4
-  for(Index i = 0; i < nonzero_pivots; ++i)
-    dst.row(permutationQ().indices().coeff(i)) = c.row(i);
-  for(Index i = nonzero_pivots; i < m_lu.cols(); ++i)
-    dst.row(permutationQ().indices().coeff(i)).setZero();
-}
-
-template<typename _MatrixType>
-template<bool Conjugate, typename RhsType, typename DstType>
-void FullPivLU<_MatrixType>::_solve_impl_transposed(const RhsType &rhs, DstType &dst) const
-{
-  /* The decomposition PAQ = LU can be rewritten as A = P^{-1} L U Q^{-1},
-   * and since permutations are real and unitary, we can write this
-   * as   A^T = Q U^T L^T P,
-   * So we proceed as follows:
-   * Step 1: compute c = Q^T rhs.
-   * Step 2: replace c by the solution x to U^T x = c. May or may not exist.
-   * Step 3: replace c by the solution x to L^T x = c.
-   * Step 4: result = P^T c.
-   * If Conjugate is true, replace "^T" by "^*" above.
-   */
-
-  const Index rows = this->rows(), cols = this->cols(),
-    nonzero_pivots = this->rank();
-   eigen_assert(rhs.rows() == cols);
-  const Index smalldim = (std::min)(rows, cols);
-
-  if(nonzero_pivots == 0)
-  {
-    dst.setZero();
-    return;
-  }
-
-  typename RhsType::PlainObject c(rhs.rows(), rhs.cols());
-
-  // Step 1
-  c = permutationQ().inverse() * rhs;
-
-  if (Conjugate) {
-    // Step 2
-    m_lu.topLeftCorner(nonzero_pivots, nonzero_pivots)
-        .template triangularView<Upper>()
-        .adjoint()
-        .solveInPlace(c.topRows(nonzero_pivots));
-    // Step 3
-    m_lu.topLeftCorner(smalldim, smalldim)
-        .template triangularView<UnitLower>()
-        .adjoint()
-        .solveInPlace(c.topRows(smalldim));
-  } else {
-    // Step 2
-    m_lu.topLeftCorner(nonzero_pivots, nonzero_pivots)
-        .template triangularView<Upper>()
-        .transpose()
-        .solveInPlace(c.topRows(nonzero_pivots));
-    // Step 3
-    m_lu.topLeftCorner(smalldim, smalldim)
-        .template triangularView<UnitLower>()
-        .transpose()
-        .solveInPlace(c.topRows(smalldim));
-  }
-
-  // Step 4
-  PermutationPType invp = permutationP().inverse().eval();
-  for(Index i = 0; i < smalldim; ++i)
-    dst.row(invp.indices().coeff(i)) = c.row(i);
-  for(Index i = smalldim; i < rows; ++i)
-    dst.row(invp.indices().coeff(i)).setZero();
-}
-
-#endif
-
-namespace internal {
-
-
-/***** Implementation of inverse() *****************************************************/
-template<typename DstXprType, typename MatrixType>
-struct Assignment<DstXprType, Inverse<FullPivLU<MatrixType> >, internal::assign_op<typename DstXprType::Scalar,typename FullPivLU<MatrixType>::Scalar>, Dense2Dense>
-{
-  typedef FullPivLU<MatrixType> LuType;
-  typedef Inverse<LuType> SrcXprType;
-  static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar,typename MatrixType::Scalar> &)
-  {
-    dst = src.nestedExpression().solve(MatrixType::Identity(src.rows(), src.cols()));
-  }
-};
-} // end namespace internal
-
-/******* MatrixBase methods *****************************************************************/
-
-/** \lu_module
-  *
-  * \return the full-pivoting LU decomposition of \c *this.
-  *
-  * \sa class FullPivLU
-  */
-template<typename Derived>
-inline const FullPivLU<typename MatrixBase<Derived>::PlainObject>
-MatrixBase<Derived>::fullPivLu() const
-{
-  return FullPivLU<PlainObject>(eval());
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_LU_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/LU/InverseImpl.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/LU/InverseImpl.h
deleted file mode 100644
index f49f233..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/LU/InverseImpl.h
+++ /dev/null
@@ -1,415 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2014 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_INVERSE_IMPL_H
-#define EIGEN_INVERSE_IMPL_H
-
-namespace Eigen { 
-
-namespace internal {
-
-/**********************************
-*** General case implementation ***
-**********************************/
-
-template<typename MatrixType, typename ResultType, int Size = MatrixType::RowsAtCompileTime>
-struct compute_inverse
-{
-  EIGEN_DEVICE_FUNC
-  static inline void run(const MatrixType& matrix, ResultType& result)
-  {
-    result = matrix.partialPivLu().inverse();
-  }
-};
-
-template<typename MatrixType, typename ResultType, int Size = MatrixType::RowsAtCompileTime>
-struct compute_inverse_and_det_with_check { /* nothing! general case not supported. */ };
-
-/****************************
-*** Size 1 implementation ***
-****************************/
-
-template<typename MatrixType, typename ResultType>
-struct compute_inverse<MatrixType, ResultType, 1>
-{
-  EIGEN_DEVICE_FUNC
-  static inline void run(const MatrixType& matrix, ResultType& result)
-  {
-    typedef typename MatrixType::Scalar Scalar;
-    internal::evaluator<MatrixType> matrixEval(matrix);
-    result.coeffRef(0,0) = Scalar(1) / matrixEval.coeff(0,0);
-  }
-};
-
-template<typename MatrixType, typename ResultType>
-struct compute_inverse_and_det_with_check<MatrixType, ResultType, 1>
-{
-  EIGEN_DEVICE_FUNC
-  static inline void run(
-    const MatrixType& matrix,
-    const typename MatrixType::RealScalar& absDeterminantThreshold,
-    ResultType& result,
-    typename ResultType::Scalar& determinant,
-    bool& invertible
-  )
-  {
-    using std::abs;
-    determinant = matrix.coeff(0,0);
-    invertible = abs(determinant) > absDeterminantThreshold;
-    if(invertible) result.coeffRef(0,0) = typename ResultType::Scalar(1) / determinant;
-  }
-};
-
-/****************************
-*** Size 2 implementation ***
-****************************/
-
-template<typename MatrixType, typename ResultType>
-EIGEN_DEVICE_FUNC 
-inline void compute_inverse_size2_helper(
-    const MatrixType& matrix, const typename ResultType::Scalar& invdet,
-    ResultType& result)
-{
-  result.coeffRef(0,0) =  matrix.coeff(1,1) * invdet;
-  result.coeffRef(1,0) = -matrix.coeff(1,0) * invdet;
-  result.coeffRef(0,1) = -matrix.coeff(0,1) * invdet;
-  result.coeffRef(1,1) =  matrix.coeff(0,0) * invdet;
-}
-
-template<typename MatrixType, typename ResultType>
-struct compute_inverse<MatrixType, ResultType, 2>
-{
-  EIGEN_DEVICE_FUNC
-  static inline void run(const MatrixType& matrix, ResultType& result)
-  {
-    typedef typename ResultType::Scalar Scalar;
-    const Scalar invdet = typename MatrixType::Scalar(1) / matrix.determinant();
-    compute_inverse_size2_helper(matrix, invdet, result);
-  }
-};
-
-template<typename MatrixType, typename ResultType>
-struct compute_inverse_and_det_with_check<MatrixType, ResultType, 2>
-{
-  EIGEN_DEVICE_FUNC
-  static inline void run(
-    const MatrixType& matrix,
-    const typename MatrixType::RealScalar& absDeterminantThreshold,
-    ResultType& inverse,
-    typename ResultType::Scalar& determinant,
-    bool& invertible
-  )
-  {
-    using std::abs;
-    typedef typename ResultType::Scalar Scalar;
-    determinant = matrix.determinant();
-    invertible = abs(determinant) > absDeterminantThreshold;
-    if(!invertible) return;
-    const Scalar invdet = Scalar(1) / determinant;
-    compute_inverse_size2_helper(matrix, invdet, inverse);
-  }
-};
-
-/****************************
-*** Size 3 implementation ***
-****************************/
-
-template<typename MatrixType, int i, int j>
-EIGEN_DEVICE_FUNC 
-inline typename MatrixType::Scalar cofactor_3x3(const MatrixType& m)
-{
-  enum {
-    i1 = (i+1) % 3,
-    i2 = (i+2) % 3,
-    j1 = (j+1) % 3,
-    j2 = (j+2) % 3
-  };
-  return m.coeff(i1, j1) * m.coeff(i2, j2)
-       - m.coeff(i1, j2) * m.coeff(i2, j1);
-}
-
-template<typename MatrixType, typename ResultType>
-EIGEN_DEVICE_FUNC
-inline void compute_inverse_size3_helper(
-    const MatrixType& matrix,
-    const typename ResultType::Scalar& invdet,
-    const Matrix<typename ResultType::Scalar,3,1>& cofactors_col0,
-    ResultType& result)
-{
-  result.row(0) = cofactors_col0 * invdet;
-  result.coeffRef(1,0) =  cofactor_3x3<MatrixType,0,1>(matrix) * invdet;
-  result.coeffRef(1,1) =  cofactor_3x3<MatrixType,1,1>(matrix) * invdet;
-  result.coeffRef(1,2) =  cofactor_3x3<MatrixType,2,1>(matrix) * invdet;
-  result.coeffRef(2,0) =  cofactor_3x3<MatrixType,0,2>(matrix) * invdet;
-  result.coeffRef(2,1) =  cofactor_3x3<MatrixType,1,2>(matrix) * invdet;
-  result.coeffRef(2,2) =  cofactor_3x3<MatrixType,2,2>(matrix) * invdet;
-}
-
-template<typename MatrixType, typename ResultType>
-struct compute_inverse<MatrixType, ResultType, 3>
-{
-  EIGEN_DEVICE_FUNC
-  static inline void run(const MatrixType& matrix, ResultType& result)
-  {
-    typedef typename ResultType::Scalar Scalar;
-    Matrix<typename MatrixType::Scalar,3,1> cofactors_col0;
-    cofactors_col0.coeffRef(0) =  cofactor_3x3<MatrixType,0,0>(matrix);
-    cofactors_col0.coeffRef(1) =  cofactor_3x3<MatrixType,1,0>(matrix);
-    cofactors_col0.coeffRef(2) =  cofactor_3x3<MatrixType,2,0>(matrix);
-    const Scalar det = (cofactors_col0.cwiseProduct(matrix.col(0))).sum();
-    const Scalar invdet = Scalar(1) / det;
-    compute_inverse_size3_helper(matrix, invdet, cofactors_col0, result);
-  }
-};
-
-template<typename MatrixType, typename ResultType>
-struct compute_inverse_and_det_with_check<MatrixType, ResultType, 3>
-{
-  EIGEN_DEVICE_FUNC
-  static inline void run(
-    const MatrixType& matrix,
-    const typename MatrixType::RealScalar& absDeterminantThreshold,
-    ResultType& inverse,
-    typename ResultType::Scalar& determinant,
-    bool& invertible
-  )
-  {
-    using std::abs;
-    typedef typename ResultType::Scalar Scalar;
-    Matrix<Scalar,3,1> cofactors_col0;
-    cofactors_col0.coeffRef(0) =  cofactor_3x3<MatrixType,0,0>(matrix);
-    cofactors_col0.coeffRef(1) =  cofactor_3x3<MatrixType,1,0>(matrix);
-    cofactors_col0.coeffRef(2) =  cofactor_3x3<MatrixType,2,0>(matrix);
-    determinant = (cofactors_col0.cwiseProduct(matrix.col(0))).sum();
-    invertible = abs(determinant) > absDeterminantThreshold;
-    if(!invertible) return;
-    const Scalar invdet = Scalar(1) / determinant;
-    compute_inverse_size3_helper(matrix, invdet, cofactors_col0, inverse);
-  }
-};
-
-/****************************
-*** Size 4 implementation ***
-****************************/
-
-template<typename Derived>
-EIGEN_DEVICE_FUNC 
-inline const typename Derived::Scalar general_det3_helper
-(const MatrixBase<Derived>& matrix, int i1, int i2, int i3, int j1, int j2, int j3)
-{
-  return matrix.coeff(i1,j1)
-         * (matrix.coeff(i2,j2) * matrix.coeff(i3,j3) - matrix.coeff(i2,j3) * matrix.coeff(i3,j2));
-}
-
-template<typename MatrixType, int i, int j>
-EIGEN_DEVICE_FUNC 
-inline typename MatrixType::Scalar cofactor_4x4(const MatrixType& matrix)
-{
-  enum {
-    i1 = (i+1) % 4,
-    i2 = (i+2) % 4,
-    i3 = (i+3) % 4,
-    j1 = (j+1) % 4,
-    j2 = (j+2) % 4,
-    j3 = (j+3) % 4
-  };
-  return general_det3_helper(matrix, i1, i2, i3, j1, j2, j3)
-       + general_det3_helper(matrix, i2, i3, i1, j1, j2, j3)
-       + general_det3_helper(matrix, i3, i1, i2, j1, j2, j3);
-}
-
-template<int Arch, typename Scalar, typename MatrixType, typename ResultType>
-struct compute_inverse_size4
-{
-  EIGEN_DEVICE_FUNC
-  static void run(const MatrixType& matrix, ResultType& result)
-  {
-    result.coeffRef(0,0) =  cofactor_4x4<MatrixType,0,0>(matrix);
-    result.coeffRef(1,0) = -cofactor_4x4<MatrixType,0,1>(matrix);
-    result.coeffRef(2,0) =  cofactor_4x4<MatrixType,0,2>(matrix);
-    result.coeffRef(3,0) = -cofactor_4x4<MatrixType,0,3>(matrix);
-    result.coeffRef(0,2) =  cofactor_4x4<MatrixType,2,0>(matrix);
-    result.coeffRef(1,2) = -cofactor_4x4<MatrixType,2,1>(matrix);
-    result.coeffRef(2,2) =  cofactor_4x4<MatrixType,2,2>(matrix);
-    result.coeffRef(3,2) = -cofactor_4x4<MatrixType,2,3>(matrix);
-    result.coeffRef(0,1) = -cofactor_4x4<MatrixType,1,0>(matrix);
-    result.coeffRef(1,1) =  cofactor_4x4<MatrixType,1,1>(matrix);
-    result.coeffRef(2,1) = -cofactor_4x4<MatrixType,1,2>(matrix);
-    result.coeffRef(3,1) =  cofactor_4x4<MatrixType,1,3>(matrix);
-    result.coeffRef(0,3) = -cofactor_4x4<MatrixType,3,0>(matrix);
-    result.coeffRef(1,3) =  cofactor_4x4<MatrixType,3,1>(matrix);
-    result.coeffRef(2,3) = -cofactor_4x4<MatrixType,3,2>(matrix);
-    result.coeffRef(3,3) =  cofactor_4x4<MatrixType,3,3>(matrix);
-    result /= (matrix.col(0).cwiseProduct(result.row(0).transpose())).sum();
-  }
-};
-
-template<typename MatrixType, typename ResultType>
-struct compute_inverse<MatrixType, ResultType, 4>
- : compute_inverse_size4<Architecture::Target, typename MatrixType::Scalar,
-                            MatrixType, ResultType>
-{
-};
-
-template<typename MatrixType, typename ResultType>
-struct compute_inverse_and_det_with_check<MatrixType, ResultType, 4>
-{
-  EIGEN_DEVICE_FUNC
-  static inline void run(
-    const MatrixType& matrix,
-    const typename MatrixType::RealScalar& absDeterminantThreshold,
-    ResultType& inverse,
-    typename ResultType::Scalar& determinant,
-    bool& invertible
-  )
-  {
-    using std::abs;
-    determinant = matrix.determinant();
-    invertible = abs(determinant) > absDeterminantThreshold;
-    if(invertible) compute_inverse<MatrixType, ResultType>::run(matrix, inverse);
-  }
-};
-
-/*************************
-*** MatrixBase methods ***
-*************************/
-
-} // end namespace internal
-
-namespace internal {
-
-// Specialization for "dense = dense_xpr.inverse()"
-template<typename DstXprType, typename XprType>
-struct Assignment<DstXprType, Inverse<XprType>, internal::assign_op<typename DstXprType::Scalar,typename XprType::Scalar>, Dense2Dense>
-{
-  typedef Inverse<XprType> SrcXprType;
-  static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar,typename XprType::Scalar> &)
-  {
-    Index dstRows = src.rows();
-    Index dstCols = src.cols();
-    if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
-      dst.resize(dstRows, dstCols);
-    
-    const int Size = EIGEN_PLAIN_ENUM_MIN(XprType::ColsAtCompileTime,DstXprType::ColsAtCompileTime);
-    EIGEN_ONLY_USED_FOR_DEBUG(Size);
-    eigen_assert(( (Size<=1) || (Size>4) || (extract_data(src.nestedExpression())!=extract_data(dst)))
-              && "Aliasing problem detected in inverse(), you need to do inverse().eval() here.");
-
-    typedef typename internal::nested_eval<XprType,XprType::ColsAtCompileTime>::type  ActualXprType;
-    typedef typename internal::remove_all<ActualXprType>::type                        ActualXprTypeCleanded;
-    
-    ActualXprType actual_xpr(src.nestedExpression());
-    
-    compute_inverse<ActualXprTypeCleanded, DstXprType>::run(actual_xpr, dst);
-  }
-};
-
-  
-} // end namespace internal
-
-/** \lu_module
-  *
-  * \returns the matrix inverse of this matrix.
-  *
-  * For small fixed sizes up to 4x4, this method uses cofactors.
-  * In the general case, this method uses class PartialPivLU.
-  *
-  * \note This matrix must be invertible, otherwise the result is undefined. If you need an
-  * invertibility check, do the following:
-  * \li for fixed sizes up to 4x4, use computeInverseAndDetWithCheck().
-  * \li for the general case, use class FullPivLU.
-  *
-  * Example: \include MatrixBase_inverse.cpp
-  * Output: \verbinclude MatrixBase_inverse.out
-  *
-  * \sa computeInverseAndDetWithCheck()
-  */
-template<typename Derived>
-inline const Inverse<Derived> MatrixBase<Derived>::inverse() const
-{
-  EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::IsInteger,THIS_FUNCTION_IS_NOT_FOR_INTEGER_NUMERIC_TYPES)
-  eigen_assert(rows() == cols());
-  return Inverse<Derived>(derived());
-}
-
-/** \lu_module
-  *
-  * Computation of matrix inverse and determinant, with invertibility check.
-  *
-  * This is only for fixed-size square matrices of size up to 4x4.
-  *
-  * \param inverse Reference to the matrix in which to store the inverse.
-  * \param determinant Reference to the variable in which to store the determinant.
-  * \param invertible Reference to the bool variable in which to store whether the matrix is invertible.
-  * \param absDeterminantThreshold Optional parameter controlling the invertibility check.
-  *                                The matrix will be declared invertible if the absolute value of its
-  *                                determinant is greater than this threshold.
-  *
-  * Example: \include MatrixBase_computeInverseAndDetWithCheck.cpp
-  * Output: \verbinclude MatrixBase_computeInverseAndDetWithCheck.out
-  *
-  * \sa inverse(), computeInverseWithCheck()
-  */
-template<typename Derived>
-template<typename ResultType>
-inline void MatrixBase<Derived>::computeInverseAndDetWithCheck(
-    ResultType& inverse,
-    typename ResultType::Scalar& determinant,
-    bool& invertible,
-    const RealScalar& absDeterminantThreshold
-  ) const
-{
-  // i'd love to put some static assertions there, but SFINAE means that they have no effect...
-  eigen_assert(rows() == cols());
-  // for 2x2, it's worth giving a chance to avoid evaluating.
-  // for larger sizes, evaluating has negligible cost and limits code size.
-  typedef typename internal::conditional<
-    RowsAtCompileTime == 2,
-    typename internal::remove_all<typename internal::nested_eval<Derived, 2>::type>::type,
-    PlainObject
-  >::type MatrixType;
-  internal::compute_inverse_and_det_with_check<MatrixType, ResultType>::run
-    (derived(), absDeterminantThreshold, inverse, determinant, invertible);
-}
-
-/** \lu_module
-  *
-  * Computation of matrix inverse, with invertibility check.
-  *
-  * This is only for fixed-size square matrices of size up to 4x4.
-  *
-  * \param inverse Reference to the matrix in which to store the inverse.
-  * \param invertible Reference to the bool variable in which to store whether the matrix is invertible.
-  * \param absDeterminantThreshold Optional parameter controlling the invertibility check.
-  *                                The matrix will be declared invertible if the absolute value of its
-  *                                determinant is greater than this threshold.
-  *
-  * Example: \include MatrixBase_computeInverseWithCheck.cpp
-  * Output: \verbinclude MatrixBase_computeInverseWithCheck.out
-  *
-  * \sa inverse(), computeInverseAndDetWithCheck()
-  */
-template<typename Derived>
-template<typename ResultType>
-inline void MatrixBase<Derived>::computeInverseWithCheck(
-    ResultType& inverse,
-    bool& invertible,
-    const RealScalar& absDeterminantThreshold
-  ) const
-{
-  Scalar determinant;
-  // i'd love to put some static assertions there, but SFINAE means that they have no effect...
-  eigen_assert(rows() == cols());
-  computeInverseAndDetWithCheck(inverse,determinant,invertible,absDeterminantThreshold);
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_INVERSE_IMPL_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/LU/PartialPivLU.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/LU/PartialPivLU.h
deleted file mode 100644
index d439618..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/LU/PartialPivLU.h
+++ /dev/null
@@ -1,611 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_PARTIALLU_H
-#define EIGEN_PARTIALLU_H
-
-namespace Eigen {
-
-namespace internal {
-template<typename _MatrixType> struct traits<PartialPivLU<_MatrixType> >
- : traits<_MatrixType>
-{
-  typedef MatrixXpr XprKind;
-  typedef SolverStorage StorageKind;
-  typedef traits<_MatrixType> BaseTraits;
-  enum {
-    Flags = BaseTraits::Flags & RowMajorBit,
-    CoeffReadCost = Dynamic
-  };
-};
-
-template<typename T,typename Derived>
-struct enable_if_ref;
-// {
-//   typedef Derived type;
-// };
-
-template<typename T,typename Derived>
-struct enable_if_ref<Ref<T>,Derived> {
-  typedef Derived type;
-};
-
-} // end namespace internal
-
-/** \ingroup LU_Module
-  *
-  * \class PartialPivLU
-  *
-  * \brief LU decomposition of a matrix with partial pivoting, and related features
-  *
-  * \tparam _MatrixType the type of the matrix of which we are computing the LU decomposition
-  *
-  * This class represents a LU decomposition of a \b square \b invertible matrix, with partial pivoting: the matrix A
-  * is decomposed as A = PLU where L is unit-lower-triangular, U is upper-triangular, and P
-  * is a permutation matrix.
-  *
-  * Typically, partial pivoting LU decomposition is only considered numerically stable for square invertible
-  * matrices. Thus LAPACK's dgesv and dgesvx require the matrix to be square and invertible. The present class
-  * does the same. It will assert that the matrix is square, but it won't (actually it can't) check that the
-  * matrix is invertible: it is your task to check that you only use this decomposition on invertible matrices.
-  *
-  * The guaranteed safe alternative, working for all matrices, is the full pivoting LU decomposition, provided
-  * by class FullPivLU.
-  *
-  * This is \b not a rank-revealing LU decomposition. Many features are intentionally absent from this class,
-  * such as rank computation. If you need these features, use class FullPivLU.
-  *
-  * This LU decomposition is suitable to invert invertible matrices. It is what MatrixBase::inverse() uses
-  * in the general case.
-  * On the other hand, it is \b not suitable to determine whether a given matrix is invertible.
-  *
-  * The data of the LU decomposition can be directly accessed through the methods matrixLU(), permutationP().
-  *
-  * This class supports the \link InplaceDecomposition inplace decomposition \endlink mechanism.
-  * 
-  * \sa MatrixBase::partialPivLu(), MatrixBase::determinant(), MatrixBase::inverse(), MatrixBase::computeInverse(), class FullPivLU
-  */
-template<typename _MatrixType> class PartialPivLU
-  : public SolverBase<PartialPivLU<_MatrixType> >
-{
-  public:
-
-    typedef _MatrixType MatrixType;
-    typedef SolverBase<PartialPivLU> Base;
-    EIGEN_GENERIC_PUBLIC_INTERFACE(PartialPivLU)
-    // FIXME StorageIndex defined in EIGEN_GENERIC_PUBLIC_INTERFACE should be int
-    enum {
-      MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
-      MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
-    };
-    typedef PermutationMatrix<RowsAtCompileTime, MaxRowsAtCompileTime> PermutationType;
-    typedef Transpositions<RowsAtCompileTime, MaxRowsAtCompileTime> TranspositionType;
-    typedef typename MatrixType::PlainObject PlainObject;
-
-    /**
-      * \brief Default Constructor.
-      *
-      * The default constructor is useful in cases in which the user intends to
-      * perform decompositions via PartialPivLU::compute(const MatrixType&).
-      */
-    PartialPivLU();
-
-    /** \brief Default Constructor with memory preallocation
-      *
-      * Like the default constructor but with preallocation of the internal data
-      * according to the specified problem \a size.
-      * \sa PartialPivLU()
-      */
-    explicit PartialPivLU(Index size);
-
-    /** Constructor.
-      *
-      * \param matrix the matrix of which to compute the LU decomposition.
-      *
-      * \warning The matrix should have full rank (e.g. if it's square, it should be invertible).
-      * If you need to deal with non-full rank, use class FullPivLU instead.
-      */
-    template<typename InputType>
-    explicit PartialPivLU(const EigenBase<InputType>& matrix);
-
-    /** Constructor for \link InplaceDecomposition inplace decomposition \endlink
-      *
-      * \param matrix the matrix of which to compute the LU decomposition.
-      *
-      * \warning The matrix should have full rank (e.g. if it's square, it should be invertible).
-      * If you need to deal with non-full rank, use class FullPivLU instead.
-      */
-    template<typename InputType>
-    explicit PartialPivLU(EigenBase<InputType>& matrix);
-
-    template<typename InputType>
-    PartialPivLU& compute(const EigenBase<InputType>& matrix) {
-      m_lu = matrix.derived();
-      compute();
-      return *this;
-    }
-
-    /** \returns the LU decomposition matrix: the upper-triangular part is U, the
-      * unit-lower-triangular part is L (at least for square matrices; in the non-square
-      * case, special care is needed, see the documentation of class FullPivLU).
-      *
-      * \sa matrixL(), matrixU()
-      */
-    inline const MatrixType& matrixLU() const
-    {
-      eigen_assert(m_isInitialized && "PartialPivLU is not initialized.");
-      return m_lu;
-    }
-
-    /** \returns the permutation matrix P.
-      */
-    inline const PermutationType& permutationP() const
-    {
-      eigen_assert(m_isInitialized && "PartialPivLU is not initialized.");
-      return m_p;
-    }
-
-    /** This method returns the solution x to the equation Ax=b, where A is the matrix of which
-      * *this is the LU decomposition.
-      *
-      * \param b the right-hand-side of the equation to solve. Can be a vector or a matrix,
-      *          the only requirement in order for the equation to make sense is that
-      *          b.rows()==A.rows(), where A is the matrix of which *this is the LU decomposition.
-      *
-      * \returns the solution.
-      *
-      * Example: \include PartialPivLU_solve.cpp
-      * Output: \verbinclude PartialPivLU_solve.out
-      *
-      * Since this PartialPivLU class assumes anyway that the matrix A is invertible, the solution
-      * theoretically exists and is unique regardless of b.
-      *
-      * \sa TriangularView::solve(), inverse(), computeInverse()
-      */
-    // FIXME this is a copy-paste of the base-class member to add the isInitialized assertion.
-    template<typename Rhs>
-    inline const Solve<PartialPivLU, Rhs>
-    solve(const MatrixBase<Rhs>& b) const
-    {
-      eigen_assert(m_isInitialized && "PartialPivLU is not initialized.");
-      return Solve<PartialPivLU, Rhs>(*this, b.derived());
-    }
-
-    /** \returns an estimate of the reciprocal condition number of the matrix of which \c *this is
-        the LU decomposition.
-      */
-    inline RealScalar rcond() const
-    {
-      eigen_assert(m_isInitialized && "PartialPivLU is not initialized.");
-      return internal::rcond_estimate_helper(m_l1_norm, *this);
-    }
-
-    /** \returns the inverse of the matrix of which *this is the LU decomposition.
-      *
-      * \warning The matrix being decomposed here is assumed to be invertible. If you need to check for
-      *          invertibility, use class FullPivLU instead.
-      *
-      * \sa MatrixBase::inverse(), LU::inverse()
-      */
-    inline const Inverse<PartialPivLU> inverse() const
-    {
-      eigen_assert(m_isInitialized && "PartialPivLU is not initialized.");
-      return Inverse<PartialPivLU>(*this);
-    }
-
-    /** \returns the determinant of the matrix of which
-      * *this is the LU decomposition. It has only linear complexity
-      * (that is, O(n) where n is the dimension of the square matrix)
-      * as the LU decomposition has already been computed.
-      *
-      * \note For fixed-size matrices of size up to 4, MatrixBase::determinant() offers
-      *       optimized paths.
-      *
-      * \warning a determinant can be very big or small, so for matrices
-      * of large enough dimension, there is a risk of overflow/underflow.
-      *
-      * \sa MatrixBase::determinant()
-      */
-    Scalar determinant() const;
-
-    MatrixType reconstructedMatrix() const;
-
-    inline Index rows() const { return m_lu.rows(); }
-    inline Index cols() const { return m_lu.cols(); }
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    template<typename RhsType, typename DstType>
-    EIGEN_DEVICE_FUNC
-    void _solve_impl(const RhsType &rhs, DstType &dst) const {
-     /* The decomposition PA = LU can be rewritten as A = P^{-1} L U.
-      * So we proceed as follows:
-      * Step 1: compute c = Pb.
-      * Step 2: replace c by the solution x to Lx = c.
-      * Step 3: replace c by the solution x to Ux = c.
-      */
-
-      eigen_assert(rhs.rows() == m_lu.rows());
-
-      // Step 1
-      dst = permutationP() * rhs;
-
-      // Step 2
-      m_lu.template triangularView<UnitLower>().solveInPlace(dst);
-
-      // Step 3
-      m_lu.template triangularView<Upper>().solveInPlace(dst);
-    }
-
-    template<bool Conjugate, typename RhsType, typename DstType>
-    EIGEN_DEVICE_FUNC
-    void _solve_impl_transposed(const RhsType &rhs, DstType &dst) const {
-     /* The decomposition PA = LU can be rewritten as A = P^{-1} L U.
-      * So we proceed as follows:
-      * Step 1: compute c = Pb.
-      * Step 2: replace c by the solution x to Lx = c.
-      * Step 3: replace c by the solution x to Ux = c.
-      */
-
-      eigen_assert(rhs.rows() == m_lu.cols());
-
-      if (Conjugate) {
-        // Step 1
-        dst = m_lu.template triangularView<Upper>().adjoint().solve(rhs);
-        // Step 2
-        m_lu.template triangularView<UnitLower>().adjoint().solveInPlace(dst);
-      } else {
-        // Step 1
-        dst = m_lu.template triangularView<Upper>().transpose().solve(rhs);
-        // Step 2
-        m_lu.template triangularView<UnitLower>().transpose().solveInPlace(dst);
-      }
-      // Step 3
-      dst = permutationP().transpose() * dst;
-    }
-    #endif
-
-  protected:
-
-    static void check_template_parameters()
-    {
-      EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
-    }
-
-    void compute();
-
-    MatrixType m_lu;
-    PermutationType m_p;
-    TranspositionType m_rowsTranspositions;
-    RealScalar m_l1_norm;
-    signed char m_det_p;
-    bool m_isInitialized;
-};
-
-template<typename MatrixType>
-PartialPivLU<MatrixType>::PartialPivLU()
-  : m_lu(),
-    m_p(),
-    m_rowsTranspositions(),
-    m_l1_norm(0),
-    m_det_p(0),
-    m_isInitialized(false)
-{
-}
-
-template<typename MatrixType>
-PartialPivLU<MatrixType>::PartialPivLU(Index size)
-  : m_lu(size, size),
-    m_p(size),
-    m_rowsTranspositions(size),
-    m_l1_norm(0),
-    m_det_p(0),
-    m_isInitialized(false)
-{
-}
-
-template<typename MatrixType>
-template<typename InputType>
-PartialPivLU<MatrixType>::PartialPivLU(const EigenBase<InputType>& matrix)
-  : m_lu(matrix.rows(),matrix.cols()),
-    m_p(matrix.rows()),
-    m_rowsTranspositions(matrix.rows()),
-    m_l1_norm(0),
-    m_det_p(0),
-    m_isInitialized(false)
-{
-  compute(matrix.derived());
-}
-
-template<typename MatrixType>
-template<typename InputType>
-PartialPivLU<MatrixType>::PartialPivLU(EigenBase<InputType>& matrix)
-  : m_lu(matrix.derived()),
-    m_p(matrix.rows()),
-    m_rowsTranspositions(matrix.rows()),
-    m_l1_norm(0),
-    m_det_p(0),
-    m_isInitialized(false)
-{
-  compute();
-}
-
-namespace internal {
-
-/** \internal This is the blocked version of fullpivlu_unblocked() */
-template<typename Scalar, int StorageOrder, typename PivIndex>
-struct partial_lu_impl
-{
-  // FIXME add a stride to Map, so that the following mapping becomes easier,
-  // another option would be to create an expression being able to automatically
-  // warp any Map, Matrix, and Block expressions as a unique type, but since that's exactly
-  // a Map + stride, why not adding a stride to Map, and convenient ctors from a Matrix,
-  // and Block.
-  typedef Map<Matrix<Scalar, Dynamic, Dynamic, StorageOrder> > MapLU;
-  typedef Block<MapLU, Dynamic, Dynamic> MatrixType;
-  typedef Block<MatrixType,Dynamic,Dynamic> BlockType;
-  typedef typename MatrixType::RealScalar RealScalar;
-
-  /** \internal performs the LU decomposition in-place of the matrix \a lu
-    * using an unblocked algorithm.
-    *
-    * In addition, this function returns the row transpositions in the
-    * vector \a row_transpositions which must have a size equal to the number
-    * of columns of the matrix \a lu, and an integer \a nb_transpositions
-    * which returns the actual number of transpositions.
-    *
-    * \returns The index of the first pivot which is exactly zero if any, or a negative number otherwise.
-    */
-  static Index unblocked_lu(MatrixType& lu, PivIndex* row_transpositions, PivIndex& nb_transpositions)
-  {
-    typedef scalar_score_coeff_op<Scalar> Scoring;
-    typedef typename Scoring::result_type Score;
-    const Index rows = lu.rows();
-    const Index cols = lu.cols();
-    const Index size = (std::min)(rows,cols);
-    nb_transpositions = 0;
-    Index first_zero_pivot = -1;
-    for(Index k = 0; k < size; ++k)
-    {
-      Index rrows = rows-k-1;
-      Index rcols = cols-k-1;
-
-      Index row_of_biggest_in_col;
-      Score biggest_in_corner
-        = lu.col(k).tail(rows-k).unaryExpr(Scoring()).maxCoeff(&row_of_biggest_in_col);
-      row_of_biggest_in_col += k;
-
-      row_transpositions[k] = PivIndex(row_of_biggest_in_col);
-
-      if(biggest_in_corner != Score(0))
-      {
-        if(k != row_of_biggest_in_col)
-        {
-          lu.row(k).swap(lu.row(row_of_biggest_in_col));
-          ++nb_transpositions;
-        }
-
-        // FIXME shall we introduce a safe quotient expression in cas 1/lu.coeff(k,k)
-        // overflow but not the actual quotient?
-        lu.col(k).tail(rrows) /= lu.coeff(k,k);
-      }
-      else if(first_zero_pivot==-1)
-      {
-        // the pivot is exactly zero, we record the index of the first pivot which is exactly 0,
-        // and continue the factorization such we still have A = PLU
-        first_zero_pivot = k;
-      }
-
-      if(k<rows-1)
-        lu.bottomRightCorner(rrows,rcols).noalias() -= lu.col(k).tail(rrows) * lu.row(k).tail(rcols);
-    }
-    return first_zero_pivot;
-  }
-
-  /** \internal performs the LU decomposition in-place of the matrix represented
-    * by the variables \a rows, \a cols, \a lu_data, and \a lu_stride using a
-    * recursive, blocked algorithm.
-    *
-    * In addition, this function returns the row transpositions in the
-    * vector \a row_transpositions which must have a size equal to the number
-    * of columns of the matrix \a lu, and an integer \a nb_transpositions
-    * which returns the actual number of transpositions.
-    *
-    * \returns The index of the first pivot which is exactly zero if any, or a negative number otherwise.
-    *
-    * \note This very low level interface using pointers, etc. is to:
-    *   1 - reduce the number of instanciations to the strict minimum
-    *   2 - avoid infinite recursion of the instanciations with Block<Block<Block<...> > >
-    */
-  static Index blocked_lu(Index rows, Index cols, Scalar* lu_data, Index luStride, PivIndex* row_transpositions, PivIndex& nb_transpositions, Index maxBlockSize=256)
-  {
-    MapLU lu1(lu_data,StorageOrder==RowMajor?rows:luStride,StorageOrder==RowMajor?luStride:cols);
-    MatrixType lu(lu1,0,0,rows,cols);
-
-    const Index size = (std::min)(rows,cols);
-
-    // if the matrix is too small, no blocking:
-    if(size<=16)
-    {
-      return unblocked_lu(lu, row_transpositions, nb_transpositions);
-    }
-
-    // automatically adjust the number of subdivisions to the size
-    // of the matrix so that there is enough sub blocks:
-    Index blockSize;
-    {
-      blockSize = size/8;
-      blockSize = (blockSize/16)*16;
-      blockSize = (std::min)((std::max)(blockSize,Index(8)), maxBlockSize);
-    }
-
-    nb_transpositions = 0;
-    Index first_zero_pivot = -1;
-    for(Index k = 0; k < size; k+=blockSize)
-    {
-      Index bs = (std::min)(size-k,blockSize); // actual size of the block
-      Index trows = rows - k - bs; // trailing rows
-      Index tsize = size - k - bs; // trailing size
-
-      // partition the matrix:
-      //                          A00 | A01 | A02
-      // lu  = A_0 | A_1 | A_2 =  A10 | A11 | A12
-      //                          A20 | A21 | A22
-      BlockType A_0(lu,0,0,rows,k);
-      BlockType A_2(lu,0,k+bs,rows,tsize);
-      BlockType A11(lu,k,k,bs,bs);
-      BlockType A12(lu,k,k+bs,bs,tsize);
-      BlockType A21(lu,k+bs,k,trows,bs);
-      BlockType A22(lu,k+bs,k+bs,trows,tsize);
-
-      PivIndex nb_transpositions_in_panel;
-      // recursively call the blocked LU algorithm on [A11^T A21^T]^T
-      // with a very small blocking size:
-      Index ret = blocked_lu(trows+bs, bs, &lu.coeffRef(k,k), luStride,
-                   row_transpositions+k, nb_transpositions_in_panel, 16);
-      if(ret>=0 && first_zero_pivot==-1)
-        first_zero_pivot = k+ret;
-
-      nb_transpositions += nb_transpositions_in_panel;
-      // update permutations and apply them to A_0
-      for(Index i=k; i<k+bs; ++i)
-      {
-        Index piv = (row_transpositions[i] += internal::convert_index<PivIndex>(k));
-        A_0.row(i).swap(A_0.row(piv));
-      }
-
-      if(trows)
-      {
-        // apply permutations to A_2
-        for(Index i=k;i<k+bs; ++i)
-          A_2.row(i).swap(A_2.row(row_transpositions[i]));
-
-        // A12 = A11^-1 A12
-        A11.template triangularView<UnitLower>().solveInPlace(A12);
-
-        A22.noalias() -= A21 * A12;
-      }
-    }
-    return first_zero_pivot;
-  }
-};
-
-/** \internal performs the LU decomposition with partial pivoting in-place.
-  */
-template<typename MatrixType, typename TranspositionType>
-void partial_lu_inplace(MatrixType& lu, TranspositionType& row_transpositions, typename TranspositionType::StorageIndex& nb_transpositions)
-{
-  eigen_assert(lu.cols() == row_transpositions.size());
-  eigen_assert((&row_transpositions.coeffRef(1)-&row_transpositions.coeffRef(0)) == 1);
-
-  partial_lu_impl
-    <typename MatrixType::Scalar, MatrixType::Flags&RowMajorBit?RowMajor:ColMajor, typename TranspositionType::StorageIndex>
-    ::blocked_lu(lu.rows(), lu.cols(), &lu.coeffRef(0,0), lu.outerStride(), &row_transpositions.coeffRef(0), nb_transpositions);
-}
-
-} // end namespace internal
-
-template<typename MatrixType>
-void PartialPivLU<MatrixType>::compute()
-{
-  check_template_parameters();
-
-  // the row permutation is stored as int indices, so just to be sure:
-  eigen_assert(m_lu.rows()<NumTraits<int>::highest());
-
-  m_l1_norm = m_lu.cwiseAbs().colwise().sum().maxCoeff();
-
-  eigen_assert(m_lu.rows() == m_lu.cols() && "PartialPivLU is only for square (and moreover invertible) matrices");
-  const Index size = m_lu.rows();
-
-  m_rowsTranspositions.resize(size);
-
-  typename TranspositionType::StorageIndex nb_transpositions;
-  internal::partial_lu_inplace(m_lu, m_rowsTranspositions, nb_transpositions);
-  m_det_p = (nb_transpositions%2) ? -1 : 1;
-
-  m_p = m_rowsTranspositions;
-
-  m_isInitialized = true;
-}
-
-template<typename MatrixType>
-typename PartialPivLU<MatrixType>::Scalar PartialPivLU<MatrixType>::determinant() const
-{
-  eigen_assert(m_isInitialized && "PartialPivLU is not initialized.");
-  return Scalar(m_det_p) * m_lu.diagonal().prod();
-}
-
-/** \returns the matrix represented by the decomposition,
- * i.e., it returns the product: P^{-1} L U.
- * This function is provided for debug purpose. */
-template<typename MatrixType>
-MatrixType PartialPivLU<MatrixType>::reconstructedMatrix() const
-{
-  eigen_assert(m_isInitialized && "LU is not initialized.");
-  // LU
-  MatrixType res = m_lu.template triangularView<UnitLower>().toDenseMatrix()
-                 * m_lu.template triangularView<Upper>();
-
-  // P^{-1}(LU)
-  res = m_p.inverse() * res;
-
-  return res;
-}
-
-/***** Implementation details *****************************************************/
-
-namespace internal {
-
-/***** Implementation of inverse() *****************************************************/
-template<typename DstXprType, typename MatrixType>
-struct Assignment<DstXprType, Inverse<PartialPivLU<MatrixType> >, internal::assign_op<typename DstXprType::Scalar,typename PartialPivLU<MatrixType>::Scalar>, Dense2Dense>
-{
-  typedef PartialPivLU<MatrixType> LuType;
-  typedef Inverse<LuType> SrcXprType;
-  static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar,typename LuType::Scalar> &)
-  {
-    dst = src.nestedExpression().solve(MatrixType::Identity(src.rows(), src.cols()));
-  }
-};
-} // end namespace internal
-
-/******** MatrixBase methods *******/
-
-/** \lu_module
-  *
-  * \return the partial-pivoting LU decomposition of \c *this.
-  *
-  * \sa class PartialPivLU
-  */
-template<typename Derived>
-inline const PartialPivLU<typename MatrixBase<Derived>::PlainObject>
-MatrixBase<Derived>::partialPivLu() const
-{
-  return PartialPivLU<PlainObject>(eval());
-}
-
-/** \lu_module
-  *
-  * Synonym of partialPivLu().
-  *
-  * \return the partial-pivoting LU decomposition of \c *this.
-  *
-  * \sa class PartialPivLU
-  */
-template<typename Derived>
-inline const PartialPivLU<typename MatrixBase<Derived>::PlainObject>
-MatrixBase<Derived>::lu() const
-{
-  return PartialPivLU<PlainObject>(eval());
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_PARTIALLU_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/LU/arch/Inverse_SSE.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/LU/arch/Inverse_SSE.h
deleted file mode 100644
index ebb64a6..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/LU/arch/Inverse_SSE.h
+++ /dev/null
@@ -1,338 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2001 Intel Corporation
-// Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-// The SSE code for the 4x4 float and double matrix inverse in this file
-// comes from the following Intel's library:
-// http://software.intel.com/en-us/articles/optimized-matrix-library-for-use-with-the-intel-pentiumr-4-processors-sse2-instructions/
-//
-// Here is the respective copyright and license statement:
-//
-//   Copyright (c) 2001 Intel Corporation.
-//
-// Permition is granted to use, copy, distribute and prepare derivative works
-// of this library for any purpose and without fee, provided, that the above
-// copyright notice and this statement appear in all copies.
-// Intel makes no representations about the suitability of this software for
-// any purpose, and specifically disclaims all warranties.
-// See LEGAL.TXT for all the legal information.
-
-#ifndef EIGEN_INVERSE_SSE_H
-#define EIGEN_INVERSE_SSE_H
-
-namespace Eigen { 
-
-namespace internal {
-
-template<typename MatrixType, typename ResultType>
-struct compute_inverse_size4<Architecture::SSE, float, MatrixType, ResultType>
-{
-  enum {
-    MatrixAlignment     = traits<MatrixType>::Alignment,
-    ResultAlignment     = traits<ResultType>::Alignment,
-    StorageOrdersMatch  = (MatrixType::Flags&RowMajorBit) == (ResultType::Flags&RowMajorBit)
-  };
-  typedef typename conditional<(MatrixType::Flags&LinearAccessBit),MatrixType const &,typename MatrixType::PlainObject>::type ActualMatrixType;
-  
-  static void run(const MatrixType& mat, ResultType& result)
-  {
-    ActualMatrixType matrix(mat);
-    EIGEN_ALIGN16 const unsigned int _Sign_PNNP[4] = { 0x00000000, 0x80000000, 0x80000000, 0x00000000 };
-
-    // Load the full matrix into registers
-    __m128 _L1 = matrix.template packet<MatrixAlignment>( 0);
-    __m128 _L2 = matrix.template packet<MatrixAlignment>( 4);
-    __m128 _L3 = matrix.template packet<MatrixAlignment>( 8);
-    __m128 _L4 = matrix.template packet<MatrixAlignment>(12);
-
-    // The inverse is calculated using "Divide and Conquer" technique. The
-    // original matrix is divide into four 2x2 sub-matrices. Since each
-    // register holds four matrix element, the smaller matrices are
-    // represented as a registers. Hence we get a better locality of the
-    // calculations.
-
-    __m128 A, B, C, D; // the four sub-matrices
-    if(!StorageOrdersMatch)
-    {
-      A = _mm_unpacklo_ps(_L1, _L2);
-      B = _mm_unpacklo_ps(_L3, _L4);
-      C = _mm_unpackhi_ps(_L1, _L2);
-      D = _mm_unpackhi_ps(_L3, _L4);
-    }
-    else
-    {
-      A = _mm_movelh_ps(_L1, _L2);
-      B = _mm_movehl_ps(_L2, _L1);
-      C = _mm_movelh_ps(_L3, _L4);
-      D = _mm_movehl_ps(_L4, _L3);
-    }
-
-    __m128 iA, iB, iC, iD,                 // partial inverse of the sub-matrices
-            DC, AB;
-    __m128 dA, dB, dC, dD;                 // determinant of the sub-matrices
-    __m128 det, d, d1, d2;
-    __m128 rd;                             // reciprocal of the determinant
-
-    //  AB = A# * B
-    AB = _mm_mul_ps(_mm_shuffle_ps(A,A,0x0F), B);
-    AB = _mm_sub_ps(AB,_mm_mul_ps(_mm_shuffle_ps(A,A,0xA5), _mm_shuffle_ps(B,B,0x4E)));
-    //  DC = D# * C
-    DC = _mm_mul_ps(_mm_shuffle_ps(D,D,0x0F), C);
-    DC = _mm_sub_ps(DC,_mm_mul_ps(_mm_shuffle_ps(D,D,0xA5), _mm_shuffle_ps(C,C,0x4E)));
-
-    //  dA = |A|
-    dA = _mm_mul_ps(_mm_shuffle_ps(A, A, 0x5F),A);
-    dA = _mm_sub_ss(dA, _mm_movehl_ps(dA,dA));
-    //  dB = |B|
-    dB = _mm_mul_ps(_mm_shuffle_ps(B, B, 0x5F),B);
-    dB = _mm_sub_ss(dB, _mm_movehl_ps(dB,dB));
-
-    //  dC = |C|
-    dC = _mm_mul_ps(_mm_shuffle_ps(C, C, 0x5F),C);
-    dC = _mm_sub_ss(dC, _mm_movehl_ps(dC,dC));
-    //  dD = |D|
-    dD = _mm_mul_ps(_mm_shuffle_ps(D, D, 0x5F),D);
-    dD = _mm_sub_ss(dD, _mm_movehl_ps(dD,dD));
-
-    //  d = trace(AB*DC) = trace(A#*B*D#*C)
-    d = _mm_mul_ps(_mm_shuffle_ps(DC,DC,0xD8),AB);
-
-    //  iD = C*A#*B
-    iD = _mm_mul_ps(_mm_shuffle_ps(C,C,0xA0), _mm_movelh_ps(AB,AB));
-    iD = _mm_add_ps(iD,_mm_mul_ps(_mm_shuffle_ps(C,C,0xF5), _mm_movehl_ps(AB,AB)));
-    //  iA = B*D#*C
-    iA = _mm_mul_ps(_mm_shuffle_ps(B,B,0xA0), _mm_movelh_ps(DC,DC));
-    iA = _mm_add_ps(iA,_mm_mul_ps(_mm_shuffle_ps(B,B,0xF5), _mm_movehl_ps(DC,DC)));
-
-    //  d = trace(AB*DC) = trace(A#*B*D#*C) [continue]
-    d  = _mm_add_ps(d, _mm_movehl_ps(d, d));
-    d  = _mm_add_ss(d, _mm_shuffle_ps(d, d, 1));
-    d1 = _mm_mul_ss(dA,dD);
-    d2 = _mm_mul_ss(dB,dC);
-
-    //  iD = D*|A| - C*A#*B
-    iD = _mm_sub_ps(_mm_mul_ps(D,_mm_shuffle_ps(dA,dA,0)), iD);
-
-    //  iA = A*|D| - B*D#*C;
-    iA = _mm_sub_ps(_mm_mul_ps(A,_mm_shuffle_ps(dD,dD,0)), iA);
-
-    //  det = |A|*|D| + |B|*|C| - trace(A#*B*D#*C)
-    det = _mm_sub_ss(_mm_add_ss(d1,d2),d);
-    rd  = _mm_div_ss(_mm_set_ss(1.0f), det);
-
-//     #ifdef ZERO_SINGULAR
-//         rd = _mm_and_ps(_mm_cmpneq_ss(det,_mm_setzero_ps()), rd);
-//     #endif
-
-    //  iB = D * (A#B)# = D*B#*A
-    iB = _mm_mul_ps(D, _mm_shuffle_ps(AB,AB,0x33));
-    iB = _mm_sub_ps(iB, _mm_mul_ps(_mm_shuffle_ps(D,D,0xB1), _mm_shuffle_ps(AB,AB,0x66)));
-    //  iC = A * (D#C)# = A*C#*D
-    iC = _mm_mul_ps(A, _mm_shuffle_ps(DC,DC,0x33));
-    iC = _mm_sub_ps(iC, _mm_mul_ps(_mm_shuffle_ps(A,A,0xB1), _mm_shuffle_ps(DC,DC,0x66)));
-
-    rd = _mm_shuffle_ps(rd,rd,0);
-    rd = _mm_xor_ps(rd, _mm_load_ps((float*)_Sign_PNNP));
-
-    //  iB = C*|B| - D*B#*A
-    iB = _mm_sub_ps(_mm_mul_ps(C,_mm_shuffle_ps(dB,dB,0)), iB);
-
-    //  iC = B*|C| - A*C#*D;
-    iC = _mm_sub_ps(_mm_mul_ps(B,_mm_shuffle_ps(dC,dC,0)), iC);
-
-    //  iX = iX / det
-    iA = _mm_mul_ps(rd,iA);
-    iB = _mm_mul_ps(rd,iB);
-    iC = _mm_mul_ps(rd,iC);
-    iD = _mm_mul_ps(rd,iD);
-
-    Index res_stride = result.outerStride();
-    float* res = result.data();
-    pstoret<float, Packet4f, ResultAlignment>(res+0,            _mm_shuffle_ps(iA,iB,0x77));
-    pstoret<float, Packet4f, ResultAlignment>(res+res_stride,   _mm_shuffle_ps(iA,iB,0x22));
-    pstoret<float, Packet4f, ResultAlignment>(res+2*res_stride, _mm_shuffle_ps(iC,iD,0x77));
-    pstoret<float, Packet4f, ResultAlignment>(res+3*res_stride, _mm_shuffle_ps(iC,iD,0x22));
-  }
-
-};
-
-template<typename MatrixType, typename ResultType>
-struct compute_inverse_size4<Architecture::SSE, double, MatrixType, ResultType>
-{
-  enum {
-    MatrixAlignment     = traits<MatrixType>::Alignment,
-    ResultAlignment     = traits<ResultType>::Alignment,
-    StorageOrdersMatch  = (MatrixType::Flags&RowMajorBit) == (ResultType::Flags&RowMajorBit)
-  };
-  typedef typename conditional<(MatrixType::Flags&LinearAccessBit),MatrixType const &,typename MatrixType::PlainObject>::type ActualMatrixType;
-  
-  static void run(const MatrixType& mat, ResultType& result)
-  {
-    ActualMatrixType matrix(mat);
-    const __m128d _Sign_NP = _mm_castsi128_pd(_mm_set_epi32(0x0,0x0,0x80000000,0x0));
-    const __m128d _Sign_PN = _mm_castsi128_pd(_mm_set_epi32(0x80000000,0x0,0x0,0x0));
-
-    // The inverse is calculated using "Divide and Conquer" technique. The
-    // original matrix is divide into four 2x2 sub-matrices. Since each
-    // register of the matrix holds two elements, the smaller matrices are
-    // consisted of two registers. Hence we get a better locality of the
-    // calculations.
-
-    // the four sub-matrices
-    __m128d A1, A2, B1, B2, C1, C2, D1, D2;
-    
-    if(StorageOrdersMatch)
-    {
-      A1 = matrix.template packet<MatrixAlignment>( 0); B1 = matrix.template packet<MatrixAlignment>( 2);
-      A2 = matrix.template packet<MatrixAlignment>( 4); B2 = matrix.template packet<MatrixAlignment>( 6);
-      C1 = matrix.template packet<MatrixAlignment>( 8); D1 = matrix.template packet<MatrixAlignment>(10);
-      C2 = matrix.template packet<MatrixAlignment>(12); D2 = matrix.template packet<MatrixAlignment>(14);
-    }
-    else
-    {
-      __m128d tmp;
-      A1 = matrix.template packet<MatrixAlignment>( 0); C1 = matrix.template packet<MatrixAlignment>( 2);
-      A2 = matrix.template packet<MatrixAlignment>( 4); C2 = matrix.template packet<MatrixAlignment>( 6);
-      tmp = A1;
-      A1 = _mm_unpacklo_pd(A1,A2);
-      A2 = _mm_unpackhi_pd(tmp,A2);
-      tmp = C1;
-      C1 = _mm_unpacklo_pd(C1,C2);
-      C2 = _mm_unpackhi_pd(tmp,C2);
-      
-      B1 = matrix.template packet<MatrixAlignment>( 8); D1 = matrix.template packet<MatrixAlignment>(10);
-      B2 = matrix.template packet<MatrixAlignment>(12); D2 = matrix.template packet<MatrixAlignment>(14);
-      tmp = B1;
-      B1 = _mm_unpacklo_pd(B1,B2);
-      B2 = _mm_unpackhi_pd(tmp,B2);
-      tmp = D1;
-      D1 = _mm_unpacklo_pd(D1,D2);
-      D2 = _mm_unpackhi_pd(tmp,D2);
-    }
-    
-    __m128d iA1, iA2, iB1, iB2, iC1, iC2, iD1, iD2,     // partial invese of the sub-matrices
-            DC1, DC2, AB1, AB2;
-    __m128d dA, dB, dC, dD;     // determinant of the sub-matrices
-    __m128d det, d1, d2, rd;
-
-    //  dA = |A|
-    dA = _mm_shuffle_pd(A2, A2, 1);
-    dA = _mm_mul_pd(A1, dA);
-    dA = _mm_sub_sd(dA, _mm_shuffle_pd(dA,dA,3));
-    //  dB = |B|
-    dB = _mm_shuffle_pd(B2, B2, 1);
-    dB = _mm_mul_pd(B1, dB);
-    dB = _mm_sub_sd(dB, _mm_shuffle_pd(dB,dB,3));
-
-    //  AB = A# * B
-    AB1 = _mm_mul_pd(B1, _mm_shuffle_pd(A2,A2,3));
-    AB2 = _mm_mul_pd(B2, _mm_shuffle_pd(A1,A1,0));
-    AB1 = _mm_sub_pd(AB1, _mm_mul_pd(B2, _mm_shuffle_pd(A1,A1,3)));
-    AB2 = _mm_sub_pd(AB2, _mm_mul_pd(B1, _mm_shuffle_pd(A2,A2,0)));
-
-    //  dC = |C|
-    dC = _mm_shuffle_pd(C2, C2, 1);
-    dC = _mm_mul_pd(C1, dC);
-    dC = _mm_sub_sd(dC, _mm_shuffle_pd(dC,dC,3));
-    //  dD = |D|
-    dD = _mm_shuffle_pd(D2, D2, 1);
-    dD = _mm_mul_pd(D1, dD);
-    dD = _mm_sub_sd(dD, _mm_shuffle_pd(dD,dD,3));
-
-    //  DC = D# * C
-    DC1 = _mm_mul_pd(C1, _mm_shuffle_pd(D2,D2,3));
-    DC2 = _mm_mul_pd(C2, _mm_shuffle_pd(D1,D1,0));
-    DC1 = _mm_sub_pd(DC1, _mm_mul_pd(C2, _mm_shuffle_pd(D1,D1,3)));
-    DC2 = _mm_sub_pd(DC2, _mm_mul_pd(C1, _mm_shuffle_pd(D2,D2,0)));
-
-    //  rd = trace(AB*DC) = trace(A#*B*D#*C)
-    d1 = _mm_mul_pd(AB1, _mm_shuffle_pd(DC1, DC2, 0));
-    d2 = _mm_mul_pd(AB2, _mm_shuffle_pd(DC1, DC2, 3));
-    rd = _mm_add_pd(d1, d2);
-    rd = _mm_add_sd(rd, _mm_shuffle_pd(rd, rd,3));
-
-    //  iD = C*A#*B
-    iD1 = _mm_mul_pd(AB1, _mm_shuffle_pd(C1,C1,0));
-    iD2 = _mm_mul_pd(AB1, _mm_shuffle_pd(C2,C2,0));
-    iD1 = _mm_add_pd(iD1, _mm_mul_pd(AB2, _mm_shuffle_pd(C1,C1,3)));
-    iD2 = _mm_add_pd(iD2, _mm_mul_pd(AB2, _mm_shuffle_pd(C2,C2,3)));
-
-    //  iA = B*D#*C
-    iA1 = _mm_mul_pd(DC1, _mm_shuffle_pd(B1,B1,0));
-    iA2 = _mm_mul_pd(DC1, _mm_shuffle_pd(B2,B2,0));
-    iA1 = _mm_add_pd(iA1, _mm_mul_pd(DC2, _mm_shuffle_pd(B1,B1,3)));
-    iA2 = _mm_add_pd(iA2, _mm_mul_pd(DC2, _mm_shuffle_pd(B2,B2,3)));
-
-    //  iD = D*|A| - C*A#*B
-    dA = _mm_shuffle_pd(dA,dA,0);
-    iD1 = _mm_sub_pd(_mm_mul_pd(D1, dA), iD1);
-    iD2 = _mm_sub_pd(_mm_mul_pd(D2, dA), iD2);
-
-    //  iA = A*|D| - B*D#*C;
-    dD = _mm_shuffle_pd(dD,dD,0);
-    iA1 = _mm_sub_pd(_mm_mul_pd(A1, dD), iA1);
-    iA2 = _mm_sub_pd(_mm_mul_pd(A2, dD), iA2);
-
-    d1 = _mm_mul_sd(dA, dD);
-    d2 = _mm_mul_sd(dB, dC);
-
-    //  iB = D * (A#B)# = D*B#*A
-    iB1 = _mm_mul_pd(D1, _mm_shuffle_pd(AB2,AB1,1));
-    iB2 = _mm_mul_pd(D2, _mm_shuffle_pd(AB2,AB1,1));
-    iB1 = _mm_sub_pd(iB1, _mm_mul_pd(_mm_shuffle_pd(D1,D1,1), _mm_shuffle_pd(AB2,AB1,2)));
-    iB2 = _mm_sub_pd(iB2, _mm_mul_pd(_mm_shuffle_pd(D2,D2,1), _mm_shuffle_pd(AB2,AB1,2)));
-
-    //  det = |A|*|D| + |B|*|C| - trace(A#*B*D#*C)
-    det = _mm_add_sd(d1, d2);
-    det = _mm_sub_sd(det, rd);
-
-    //  iC = A * (D#C)# = A*C#*D
-    iC1 = _mm_mul_pd(A1, _mm_shuffle_pd(DC2,DC1,1));
-    iC2 = _mm_mul_pd(A2, _mm_shuffle_pd(DC2,DC1,1));
-    iC1 = _mm_sub_pd(iC1, _mm_mul_pd(_mm_shuffle_pd(A1,A1,1), _mm_shuffle_pd(DC2,DC1,2)));
-    iC2 = _mm_sub_pd(iC2, _mm_mul_pd(_mm_shuffle_pd(A2,A2,1), _mm_shuffle_pd(DC2,DC1,2)));
-
-    rd = _mm_div_sd(_mm_set_sd(1.0), det);
-//     #ifdef ZERO_SINGULAR
-//         rd = _mm_and_pd(_mm_cmpneq_sd(det,_mm_setzero_pd()), rd);
-//     #endif
-    rd = _mm_shuffle_pd(rd,rd,0);
-
-    //  iB = C*|B| - D*B#*A
-    dB = _mm_shuffle_pd(dB,dB,0);
-    iB1 = _mm_sub_pd(_mm_mul_pd(C1, dB), iB1);
-    iB2 = _mm_sub_pd(_mm_mul_pd(C2, dB), iB2);
-
-    d1 = _mm_xor_pd(rd, _Sign_PN);
-    d2 = _mm_xor_pd(rd, _Sign_NP);
-
-    //  iC = B*|C| - A*C#*D;
-    dC = _mm_shuffle_pd(dC,dC,0);
-    iC1 = _mm_sub_pd(_mm_mul_pd(B1, dC), iC1);
-    iC2 = _mm_sub_pd(_mm_mul_pd(B2, dC), iC2);
-
-    Index res_stride = result.outerStride();
-    double* res = result.data();
-    pstoret<double, Packet2d, ResultAlignment>(res+0,             _mm_mul_pd(_mm_shuffle_pd(iA2, iA1, 3), d1));
-    pstoret<double, Packet2d, ResultAlignment>(res+res_stride,    _mm_mul_pd(_mm_shuffle_pd(iA2, iA1, 0), d2));
-    pstoret<double, Packet2d, ResultAlignment>(res+2,             _mm_mul_pd(_mm_shuffle_pd(iB2, iB1, 3), d1));
-    pstoret<double, Packet2d, ResultAlignment>(res+res_stride+2,  _mm_mul_pd(_mm_shuffle_pd(iB2, iB1, 0), d2));
-    pstoret<double, Packet2d, ResultAlignment>(res+2*res_stride,  _mm_mul_pd(_mm_shuffle_pd(iC2, iC1, 3), d1));
-    pstoret<double, Packet2d, ResultAlignment>(res+3*res_stride,  _mm_mul_pd(_mm_shuffle_pd(iC2, iC1, 0), d2));
-    pstoret<double, Packet2d, ResultAlignment>(res+2*res_stride+2,_mm_mul_pd(_mm_shuffle_pd(iD2, iD1, 3), d1));
-    pstoret<double, Packet2d, ResultAlignment>(res+3*res_stride+2,_mm_mul_pd(_mm_shuffle_pd(iD2, iD1, 0), d2));
-  }
-};
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_INVERSE_SSE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/QR/ColPivHouseholderQR.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/QR/ColPivHouseholderQR.h
deleted file mode 100644
index a7b47d5..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/QR/ColPivHouseholderQR.h
+++ /dev/null
@@ -1,653 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_COLPIVOTINGHOUSEHOLDERQR_H
-#define EIGEN_COLPIVOTINGHOUSEHOLDERQR_H
-
-namespace Eigen {
-
-namespace internal {
-template<typename _MatrixType> struct traits<ColPivHouseholderQR<_MatrixType> >
- : traits<_MatrixType>
-{
-  enum { Flags = 0 };
-};
-
-} // end namespace internal
-
-/** \ingroup QR_Module
-  *
-  * \class ColPivHouseholderQR
-  *
-  * \brief Householder rank-revealing QR decomposition of a matrix with column-pivoting
-  *
-  * \tparam _MatrixType the type of the matrix of which we are computing the QR decomposition
-  *
-  * This class performs a rank-revealing QR decomposition of a matrix \b A into matrices \b P, \b Q and \b R
-  * such that
-  * \f[
-  *  \mathbf{A} \, \mathbf{P} = \mathbf{Q} \, \mathbf{R}
-  * \f]
-  * by using Householder transformations. Here, \b P is a permutation matrix, \b Q a unitary matrix and \b R an
-  * upper triangular matrix.
-  *
-  * This decomposition performs column pivoting in order to be rank-revealing and improve
-  * numerical stability. It is slower than HouseholderQR, and faster than FullPivHouseholderQR.
-  *
-  * This class supports the \link InplaceDecomposition inplace decomposition \endlink mechanism.
-  * 
-  * \sa MatrixBase::colPivHouseholderQr()
-  */
-template<typename _MatrixType> class ColPivHouseholderQR
-{
-  public:
-
-    typedef _MatrixType MatrixType;
-    enum {
-      RowsAtCompileTime = MatrixType::RowsAtCompileTime,
-      ColsAtCompileTime = MatrixType::ColsAtCompileTime,
-      MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
-      MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
-    };
-    typedef typename MatrixType::Scalar Scalar;
-    typedef typename MatrixType::RealScalar RealScalar;
-    // FIXME should be int
-    typedef typename MatrixType::StorageIndex StorageIndex;
-    typedef typename internal::plain_diag_type<MatrixType>::type HCoeffsType;
-    typedef PermutationMatrix<ColsAtCompileTime, MaxColsAtCompileTime> PermutationType;
-    typedef typename internal::plain_row_type<MatrixType, Index>::type IntRowVectorType;
-    typedef typename internal::plain_row_type<MatrixType>::type RowVectorType;
-    typedef typename internal::plain_row_type<MatrixType, RealScalar>::type RealRowVectorType;
-    typedef HouseholderSequence<MatrixType,typename internal::remove_all<typename HCoeffsType::ConjugateReturnType>::type> HouseholderSequenceType;
-    typedef typename MatrixType::PlainObject PlainObject;
-
-  private:
-
-    typedef typename PermutationType::StorageIndex PermIndexType;
-
-  public:
-
-    /**
-    * \brief Default Constructor.
-    *
-    * The default constructor is useful in cases in which the user intends to
-    * perform decompositions via ColPivHouseholderQR::compute(const MatrixType&).
-    */
-    ColPivHouseholderQR()
-      : m_qr(),
-        m_hCoeffs(),
-        m_colsPermutation(),
-        m_colsTranspositions(),
-        m_temp(),
-        m_colNormsUpdated(),
-        m_colNormsDirect(),
-        m_isInitialized(false),
-        m_usePrescribedThreshold(false) {}
-
-    /** \brief Default Constructor with memory preallocation
-      *
-      * Like the default constructor but with preallocation of the internal data
-      * according to the specified problem \a size.
-      * \sa ColPivHouseholderQR()
-      */
-    ColPivHouseholderQR(Index rows, Index cols)
-      : m_qr(rows, cols),
-        m_hCoeffs((std::min)(rows,cols)),
-        m_colsPermutation(PermIndexType(cols)),
-        m_colsTranspositions(cols),
-        m_temp(cols),
-        m_colNormsUpdated(cols),
-        m_colNormsDirect(cols),
-        m_isInitialized(false),
-        m_usePrescribedThreshold(false) {}
-
-    /** \brief Constructs a QR factorization from a given matrix
-      *
-      * This constructor computes the QR factorization of the matrix \a matrix by calling
-      * the method compute(). It is a short cut for:
-      *
-      * \code
-      * ColPivHouseholderQR<MatrixType> qr(matrix.rows(), matrix.cols());
-      * qr.compute(matrix);
-      * \endcode
-      *
-      * \sa compute()
-      */
-    template<typename InputType>
-    explicit ColPivHouseholderQR(const EigenBase<InputType>& matrix)
-      : m_qr(matrix.rows(), matrix.cols()),
-        m_hCoeffs((std::min)(matrix.rows(),matrix.cols())),
-        m_colsPermutation(PermIndexType(matrix.cols())),
-        m_colsTranspositions(matrix.cols()),
-        m_temp(matrix.cols()),
-        m_colNormsUpdated(matrix.cols()),
-        m_colNormsDirect(matrix.cols()),
-        m_isInitialized(false),
-        m_usePrescribedThreshold(false)
-    {
-      compute(matrix.derived());
-    }
-
-    /** \brief Constructs a QR factorization from a given matrix
-      *
-      * This overloaded constructor is provided for \link InplaceDecomposition inplace decomposition \endlink when \c MatrixType is a Eigen::Ref.
-      *
-      * \sa ColPivHouseholderQR(const EigenBase&)
-      */
-    template<typename InputType>
-    explicit ColPivHouseholderQR(EigenBase<InputType>& matrix)
-      : m_qr(matrix.derived()),
-        m_hCoeffs((std::min)(matrix.rows(),matrix.cols())),
-        m_colsPermutation(PermIndexType(matrix.cols())),
-        m_colsTranspositions(matrix.cols()),
-        m_temp(matrix.cols()),
-        m_colNormsUpdated(matrix.cols()),
-        m_colNormsDirect(matrix.cols()),
-        m_isInitialized(false),
-        m_usePrescribedThreshold(false)
-    {
-      computeInPlace();
-    }
-
-    /** This method finds a solution x to the equation Ax=b, where A is the matrix of which
-      * *this is the QR decomposition, if any exists.
-      *
-      * \param b the right-hand-side of the equation to solve.
-      *
-      * \returns a solution.
-      *
-      * \note_about_checking_solutions
-      *
-      * \note_about_arbitrary_choice_of_solution
-      *
-      * Example: \include ColPivHouseholderQR_solve.cpp
-      * Output: \verbinclude ColPivHouseholderQR_solve.out
-      */
-    template<typename Rhs>
-    inline const Solve<ColPivHouseholderQR, Rhs>
-    solve(const MatrixBase<Rhs>& b) const
-    {
-      eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
-      return Solve<ColPivHouseholderQR, Rhs>(*this, b.derived());
-    }
-
-    HouseholderSequenceType householderQ() const;
-    HouseholderSequenceType matrixQ() const
-    {
-      return householderQ();
-    }
-
-    /** \returns a reference to the matrix where the Householder QR decomposition is stored
-      */
-    const MatrixType& matrixQR() const
-    {
-      eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
-      return m_qr;
-    }
-
-    /** \returns a reference to the matrix where the result Householder QR is stored
-     * \warning The strict lower part of this matrix contains internal values.
-     * Only the upper triangular part should be referenced. To get it, use
-     * \code matrixR().template triangularView<Upper>() \endcode
-     * For rank-deficient matrices, use
-     * \code
-     * matrixR().topLeftCorner(rank(), rank()).template triangularView<Upper>()
-     * \endcode
-     */
-    const MatrixType& matrixR() const
-    {
-      eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
-      return m_qr;
-    }
-
-    template<typename InputType>
-    ColPivHouseholderQR& compute(const EigenBase<InputType>& matrix);
-
-    /** \returns a const reference to the column permutation matrix */
-    const PermutationType& colsPermutation() const
-    {
-      eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
-      return m_colsPermutation;
-    }
-
-    /** \returns the absolute value of the determinant of the matrix of which
-      * *this is the QR decomposition. It has only linear complexity
-      * (that is, O(n) where n is the dimension of the square matrix)
-      * as the QR decomposition has already been computed.
-      *
-      * \note This is only for square matrices.
-      *
-      * \warning a determinant can be very big or small, so for matrices
-      * of large enough dimension, there is a risk of overflow/underflow.
-      * One way to work around that is to use logAbsDeterminant() instead.
-      *
-      * \sa logAbsDeterminant(), MatrixBase::determinant()
-      */
-    typename MatrixType::RealScalar absDeterminant() const;
-
-    /** \returns the natural log of the absolute value of the determinant of the matrix of which
-      * *this is the QR decomposition. It has only linear complexity
-      * (that is, O(n) where n is the dimension of the square matrix)
-      * as the QR decomposition has already been computed.
-      *
-      * \note This is only for square matrices.
-      *
-      * \note This method is useful to work around the risk of overflow/underflow that's inherent
-      * to determinant computation.
-      *
-      * \sa absDeterminant(), MatrixBase::determinant()
-      */
-    typename MatrixType::RealScalar logAbsDeterminant() const;
-
-    /** \returns the rank of the matrix of which *this is the QR decomposition.
-      *
-      * \note This method has to determine which pivots should be considered nonzero.
-      *       For that, it uses the threshold value that you can control by calling
-      *       setThreshold(const RealScalar&).
-      */
-    inline Index rank() const
-    {
-      using std::abs;
-      eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
-      RealScalar premultiplied_threshold = abs(m_maxpivot) * threshold();
-      Index result = 0;
-      for(Index i = 0; i < m_nonzero_pivots; ++i)
-        result += (abs(m_qr.coeff(i,i)) > premultiplied_threshold);
-      return result;
-    }
-
-    /** \returns the dimension of the kernel of the matrix of which *this is the QR decomposition.
-      *
-      * \note This method has to determine which pivots should be considered nonzero.
-      *       For that, it uses the threshold value that you can control by calling
-      *       setThreshold(const RealScalar&).
-      */
-    inline Index dimensionOfKernel() const
-    {
-      eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
-      return cols() - rank();
-    }
-
-    /** \returns true if the matrix of which *this is the QR decomposition represents an injective
-      *          linear map, i.e. has trivial kernel; false otherwise.
-      *
-      * \note This method has to determine which pivots should be considered nonzero.
-      *       For that, it uses the threshold value that you can control by calling
-      *       setThreshold(const RealScalar&).
-      */
-    inline bool isInjective() const
-    {
-      eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
-      return rank() == cols();
-    }
-
-    /** \returns true if the matrix of which *this is the QR decomposition represents a surjective
-      *          linear map; false otherwise.
-      *
-      * \note This method has to determine which pivots should be considered nonzero.
-      *       For that, it uses the threshold value that you can control by calling
-      *       setThreshold(const RealScalar&).
-      */
-    inline bool isSurjective() const
-    {
-      eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
-      return rank() == rows();
-    }
-
-    /** \returns true if the matrix of which *this is the QR decomposition is invertible.
-      *
-      * \note This method has to determine which pivots should be considered nonzero.
-      *       For that, it uses the threshold value that you can control by calling
-      *       setThreshold(const RealScalar&).
-      */
-    inline bool isInvertible() const
-    {
-      eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
-      return isInjective() && isSurjective();
-    }
-
-    /** \returns the inverse of the matrix of which *this is the QR decomposition.
-      *
-      * \note If this matrix is not invertible, the returned matrix has undefined coefficients.
-      *       Use isInvertible() to first determine whether this matrix is invertible.
-      */
-    inline const Inverse<ColPivHouseholderQR> inverse() const
-    {
-      eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
-      return Inverse<ColPivHouseholderQR>(*this);
-    }
-
-    inline Index rows() const { return m_qr.rows(); }
-    inline Index cols() const { return m_qr.cols(); }
-
-    /** \returns a const reference to the vector of Householder coefficients used to represent the factor \c Q.
-      *
-      * For advanced uses only.
-      */
-    const HCoeffsType& hCoeffs() const { return m_hCoeffs; }
-
-    /** Allows to prescribe a threshold to be used by certain methods, such as rank(),
-      * who need to determine when pivots are to be considered nonzero. This is not used for the
-      * QR decomposition itself.
-      *
-      * When it needs to get the threshold value, Eigen calls threshold(). By default, this
-      * uses a formula to automatically determine a reasonable threshold.
-      * Once you have called the present method setThreshold(const RealScalar&),
-      * your value is used instead.
-      *
-      * \param threshold The new value to use as the threshold.
-      *
-      * A pivot will be considered nonzero if its absolute value is strictly greater than
-      *  \f$ \vert pivot \vert \leqslant threshold \times \vert maxpivot \vert \f$
-      * where maxpivot is the biggest pivot.
-      *
-      * If you want to come back to the default behavior, call setThreshold(Default_t)
-      */
-    ColPivHouseholderQR& setThreshold(const RealScalar& threshold)
-    {
-      m_usePrescribedThreshold = true;
-      m_prescribedThreshold = threshold;
-      return *this;
-    }
-
-    /** Allows to come back to the default behavior, letting Eigen use its default formula for
-      * determining the threshold.
-      *
-      * You should pass the special object Eigen::Default as parameter here.
-      * \code qr.setThreshold(Eigen::Default); \endcode
-      *
-      * See the documentation of setThreshold(const RealScalar&).
-      */
-    ColPivHouseholderQR& setThreshold(Default_t)
-    {
-      m_usePrescribedThreshold = false;
-      return *this;
-    }
-
-    /** Returns the threshold that will be used by certain methods such as rank().
-      *
-      * See the documentation of setThreshold(const RealScalar&).
-      */
-    RealScalar threshold() const
-    {
-      eigen_assert(m_isInitialized || m_usePrescribedThreshold);
-      return m_usePrescribedThreshold ? m_prescribedThreshold
-      // this formula comes from experimenting (see "LU precision tuning" thread on the list)
-      // and turns out to be identical to Higham's formula used already in LDLt.
-                                      : NumTraits<Scalar>::epsilon() * RealScalar(m_qr.diagonalSize());
-    }
-
-    /** \returns the number of nonzero pivots in the QR decomposition.
-      * Here nonzero is meant in the exact sense, not in a fuzzy sense.
-      * So that notion isn't really intrinsically interesting, but it is
-      * still useful when implementing algorithms.
-      *
-      * \sa rank()
-      */
-    inline Index nonzeroPivots() const
-    {
-      eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
-      return m_nonzero_pivots;
-    }
-
-    /** \returns the absolute value of the biggest pivot, i.e. the biggest
-      *          diagonal coefficient of R.
-      */
-    RealScalar maxPivot() const { return m_maxpivot; }
-
-    /** \brief Reports whether the QR factorization was succesful.
-      *
-      * \note This function always returns \c Success. It is provided for compatibility
-      * with other factorization routines.
-      * \returns \c Success
-      */
-    ComputationInfo info() const
-    {
-      eigen_assert(m_isInitialized && "Decomposition is not initialized.");
-      return Success;
-    }
-
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    template<typename RhsType, typename DstType>
-    EIGEN_DEVICE_FUNC
-    void _solve_impl(const RhsType &rhs, DstType &dst) const;
-    #endif
-
-  protected:
-
-    friend class CompleteOrthogonalDecomposition<MatrixType>;
-
-    static void check_template_parameters()
-    {
-      EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
-    }
-
-    void computeInPlace();
-
-    MatrixType m_qr;
-    HCoeffsType m_hCoeffs;
-    PermutationType m_colsPermutation;
-    IntRowVectorType m_colsTranspositions;
-    RowVectorType m_temp;
-    RealRowVectorType m_colNormsUpdated;
-    RealRowVectorType m_colNormsDirect;
-    bool m_isInitialized, m_usePrescribedThreshold;
-    RealScalar m_prescribedThreshold, m_maxpivot;
-    Index m_nonzero_pivots;
-    Index m_det_pq;
-};
-
-template<typename MatrixType>
-typename MatrixType::RealScalar ColPivHouseholderQR<MatrixType>::absDeterminant() const
-{
-  using std::abs;
-  eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
-  eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
-  return abs(m_qr.diagonal().prod());
-}
-
-template<typename MatrixType>
-typename MatrixType::RealScalar ColPivHouseholderQR<MatrixType>::logAbsDeterminant() const
-{
-  eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
-  eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
-  return m_qr.diagonal().cwiseAbs().array().log().sum();
-}
-
-/** Performs the QR factorization of the given matrix \a matrix. The result of
-  * the factorization is stored into \c *this, and a reference to \c *this
-  * is returned.
-  *
-  * \sa class ColPivHouseholderQR, ColPivHouseholderQR(const MatrixType&)
-  */
-template<typename MatrixType>
-template<typename InputType>
-ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const EigenBase<InputType>& matrix)
-{
-  m_qr = matrix.derived();
-  computeInPlace();
-  return *this;
-}
-
-template<typename MatrixType>
-void ColPivHouseholderQR<MatrixType>::computeInPlace()
-{
-  check_template_parameters();
-
-  // the column permutation is stored as int indices, so just to be sure:
-  eigen_assert(m_qr.cols()<=NumTraits<int>::highest());
-
-  using std::abs;
-
-  Index rows = m_qr.rows();
-  Index cols = m_qr.cols();
-  Index size = m_qr.diagonalSize();
-
-  m_hCoeffs.resize(size);
-
-  m_temp.resize(cols);
-
-  m_colsTranspositions.resize(m_qr.cols());
-  Index number_of_transpositions = 0;
-
-  m_colNormsUpdated.resize(cols);
-  m_colNormsDirect.resize(cols);
-  for (Index k = 0; k < cols; ++k) {
-    // colNormsDirect(k) caches the most recent directly computed norm of
-    // column k.
-    m_colNormsDirect.coeffRef(k) = m_qr.col(k).norm();
-    m_colNormsUpdated.coeffRef(k) = m_colNormsDirect.coeffRef(k);
-  }
-
-  RealScalar threshold_helper =  numext::abs2<RealScalar>(m_colNormsUpdated.maxCoeff() * NumTraits<RealScalar>::epsilon()) / RealScalar(rows);
-  RealScalar norm_downdate_threshold = numext::sqrt(NumTraits<RealScalar>::epsilon());
-
-  m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
-  m_maxpivot = RealScalar(0);
-
-  for(Index k = 0; k < size; ++k)
-  {
-    // first, we look up in our table m_colNormsUpdated which column has the biggest norm
-    Index biggest_col_index;
-    RealScalar biggest_col_sq_norm = numext::abs2(m_colNormsUpdated.tail(cols-k).maxCoeff(&biggest_col_index));
-    biggest_col_index += k;
-
-    // Track the number of meaningful pivots but do not stop the decomposition to make
-    // sure that the initial matrix is properly reproduced. See bug 941.
-    if(m_nonzero_pivots==size && biggest_col_sq_norm < threshold_helper * RealScalar(rows-k))
-      m_nonzero_pivots = k;
-
-    // apply the transposition to the columns
-    m_colsTranspositions.coeffRef(k) = biggest_col_index;
-    if(k != biggest_col_index) {
-      m_qr.col(k).swap(m_qr.col(biggest_col_index));
-      std::swap(m_colNormsUpdated.coeffRef(k), m_colNormsUpdated.coeffRef(biggest_col_index));
-      std::swap(m_colNormsDirect.coeffRef(k), m_colNormsDirect.coeffRef(biggest_col_index));
-      ++number_of_transpositions;
-    }
-
-    // generate the householder vector, store it below the diagonal
-    RealScalar beta;
-    m_qr.col(k).tail(rows-k).makeHouseholderInPlace(m_hCoeffs.coeffRef(k), beta);
-
-    // apply the householder transformation to the diagonal coefficient
-    m_qr.coeffRef(k,k) = beta;
-
-    // remember the maximum absolute value of diagonal coefficients
-    if(abs(beta) > m_maxpivot) m_maxpivot = abs(beta);
-
-    // apply the householder transformation
-    m_qr.bottomRightCorner(rows-k, cols-k-1)
-        .applyHouseholderOnTheLeft(m_qr.col(k).tail(rows-k-1), m_hCoeffs.coeffRef(k), &m_temp.coeffRef(k+1));
-
-    // update our table of norms of the columns
-    for (Index j = k + 1; j < cols; ++j) {
-      // The following implements the stable norm downgrade step discussed in
-      // http://www.netlib.org/lapack/lawnspdf/lawn176.pdf
-      // and used in LAPACK routines xGEQPF and xGEQP3.
-      // See lines 278-297 in http://www.netlib.org/lapack/explore-html/dc/df4/sgeqpf_8f_source.html
-      if (m_colNormsUpdated.coeffRef(j) != RealScalar(0)) {
-        RealScalar temp = abs(m_qr.coeffRef(k, j)) / m_colNormsUpdated.coeffRef(j);
-        temp = (RealScalar(1) + temp) * (RealScalar(1) - temp);
-        temp = temp <  RealScalar(0) ? RealScalar(0) : temp;
-        RealScalar temp2 = temp * numext::abs2<RealScalar>(m_colNormsUpdated.coeffRef(j) /
-                                                           m_colNormsDirect.coeffRef(j));
-        if (temp2 <= norm_downdate_threshold) {
-          // The updated norm has become too inaccurate so re-compute the column
-          // norm directly.
-          m_colNormsDirect.coeffRef(j) = m_qr.col(j).tail(rows - k - 1).norm();
-          m_colNormsUpdated.coeffRef(j) = m_colNormsDirect.coeffRef(j);
-        } else {
-          m_colNormsUpdated.coeffRef(j) *= numext::sqrt(temp);
-        }
-      }
-    }
-  }
-
-  m_colsPermutation.setIdentity(PermIndexType(cols));
-  for(PermIndexType k = 0; k < size/*m_nonzero_pivots*/; ++k)
-    m_colsPermutation.applyTranspositionOnTheRight(k, PermIndexType(m_colsTranspositions.coeff(k)));
-
-  m_det_pq = (number_of_transpositions%2) ? -1 : 1;
-  m_isInitialized = true;
-}
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-template<typename _MatrixType>
-template<typename RhsType, typename DstType>
-void ColPivHouseholderQR<_MatrixType>::_solve_impl(const RhsType &rhs, DstType &dst) const
-{
-  eigen_assert(rhs.rows() == rows());
-
-  const Index nonzero_pivots = nonzeroPivots();
-
-  if(nonzero_pivots == 0)
-  {
-    dst.setZero();
-    return;
-  }
-
-  typename RhsType::PlainObject c(rhs);
-
-  // Note that the matrix Q = H_0^* H_1^*... so its inverse is Q^* = (H_0 H_1 ...)^T
-  c.applyOnTheLeft(householderSequence(m_qr, m_hCoeffs)
-                    .setLength(nonzero_pivots)
-                    .transpose()
-    );
-
-  m_qr.topLeftCorner(nonzero_pivots, nonzero_pivots)
-      .template triangularView<Upper>()
-      .solveInPlace(c.topRows(nonzero_pivots));
-
-  for(Index i = 0; i < nonzero_pivots; ++i) dst.row(m_colsPermutation.indices().coeff(i)) = c.row(i);
-  for(Index i = nonzero_pivots; i < cols(); ++i) dst.row(m_colsPermutation.indices().coeff(i)).setZero();
-}
-#endif
-
-namespace internal {
-
-template<typename DstXprType, typename MatrixType>
-struct Assignment<DstXprType, Inverse<ColPivHouseholderQR<MatrixType> >, internal::assign_op<typename DstXprType::Scalar,typename ColPivHouseholderQR<MatrixType>::Scalar>, Dense2Dense>
-{
-  typedef ColPivHouseholderQR<MatrixType> QrType;
-  typedef Inverse<QrType> SrcXprType;
-  static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar,typename QrType::Scalar> &)
-  {
-    dst = src.nestedExpression().solve(MatrixType::Identity(src.rows(), src.cols()));
-  }
-};
-
-} // end namespace internal
-
-/** \returns the matrix Q as a sequence of householder transformations.
-  * You can extract the meaningful part only by using:
-  * \code qr.householderQ().setLength(qr.nonzeroPivots()) \endcode*/
-template<typename MatrixType>
-typename ColPivHouseholderQR<MatrixType>::HouseholderSequenceType ColPivHouseholderQR<MatrixType>
-  ::householderQ() const
-{
-  eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
-  return HouseholderSequenceType(m_qr, m_hCoeffs.conjugate());
-}
-
-/** \return the column-pivoting Householder QR decomposition of \c *this.
-  *
-  * \sa class ColPivHouseholderQR
-  */
-template<typename Derived>
-const ColPivHouseholderQR<typename MatrixBase<Derived>::PlainObject>
-MatrixBase<Derived>::colPivHouseholderQr() const
-{
-  return ColPivHouseholderQR<PlainObject>(eval());
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_COLPIVOTINGHOUSEHOLDERQR_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/QR/CompleteOrthogonalDecomposition.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/QR/CompleteOrthogonalDecomposition.h
deleted file mode 100644
index 34c637b..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/QR/CompleteOrthogonalDecomposition.h
+++ /dev/null
@@ -1,562 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2016 Rasmus Munk Larsen <rmlarsen@google.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_COMPLETEORTHOGONALDECOMPOSITION_H
-#define EIGEN_COMPLETEORTHOGONALDECOMPOSITION_H
-
-namespace Eigen {
-
-namespace internal {
-template <typename _MatrixType>
-struct traits<CompleteOrthogonalDecomposition<_MatrixType> >
-    : traits<_MatrixType> {
-  enum { Flags = 0 };
-};
-
-}  // end namespace internal
-
-/** \ingroup QR_Module
-  *
-  * \class CompleteOrthogonalDecomposition
-  *
-  * \brief Complete orthogonal decomposition (COD) of a matrix.
-  *
-  * \param MatrixType the type of the matrix of which we are computing the COD.
-  *
-  * This class performs a rank-revealing complete orthogonal decomposition of a
-  * matrix  \b A into matrices \b P, \b Q, \b T, and \b Z such that
-  * \f[
-  *  \mathbf{A} \, \mathbf{P} = \mathbf{Q} \,
-  *                     \begin{bmatrix} \mathbf{T} &  \mathbf{0} \\
-  *                                     \mathbf{0} & \mathbf{0} \end{bmatrix} \, \mathbf{Z}
-  * \f]
-  * by using Householder transformations. Here, \b P is a permutation matrix,
-  * \b Q and \b Z are unitary matrices and \b T an upper triangular matrix of
-  * size rank-by-rank. \b A may be rank deficient.
-  *
-  * This class supports the \link InplaceDecomposition inplace decomposition \endlink mechanism.
-  * 
-  * \sa MatrixBase::completeOrthogonalDecomposition()
-  */
-template <typename _MatrixType>
-class CompleteOrthogonalDecomposition {
- public:
-  typedef _MatrixType MatrixType;
-  enum {
-    RowsAtCompileTime = MatrixType::RowsAtCompileTime,
-    ColsAtCompileTime = MatrixType::ColsAtCompileTime,
-    MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
-    MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
-  };
-  typedef typename MatrixType::Scalar Scalar;
-  typedef typename MatrixType::RealScalar RealScalar;
-  typedef typename MatrixType::StorageIndex StorageIndex;
-  typedef typename internal::plain_diag_type<MatrixType>::type HCoeffsType;
-  typedef PermutationMatrix<ColsAtCompileTime, MaxColsAtCompileTime>
-      PermutationType;
-  typedef typename internal::plain_row_type<MatrixType, Index>::type
-      IntRowVectorType;
-  typedef typename internal::plain_row_type<MatrixType>::type RowVectorType;
-  typedef typename internal::plain_row_type<MatrixType, RealScalar>::type
-      RealRowVectorType;
-  typedef HouseholderSequence<
-      MatrixType, typename internal::remove_all<
-                      typename HCoeffsType::ConjugateReturnType>::type>
-      HouseholderSequenceType;
-  typedef typename MatrixType::PlainObject PlainObject;
-
- private:
-  typedef typename PermutationType::Index PermIndexType;
-
- public:
-  /**
-   * \brief Default Constructor.
-   *
-   * The default constructor is useful in cases in which the user intends to
-   * perform decompositions via
-   * \c CompleteOrthogonalDecomposition::compute(const* MatrixType&).
-   */
-  CompleteOrthogonalDecomposition() : m_cpqr(), m_zCoeffs(), m_temp() {}
-
-  /** \brief Default Constructor with memory preallocation
-   *
-   * Like the default constructor but with preallocation of the internal data
-   * according to the specified problem \a size.
-   * \sa CompleteOrthogonalDecomposition()
-   */
-  CompleteOrthogonalDecomposition(Index rows, Index cols)
-      : m_cpqr(rows, cols), m_zCoeffs((std::min)(rows, cols)), m_temp(cols) {}
-
-  /** \brief Constructs a complete orthogonal decomposition from a given
-   * matrix.
-   *
-   * This constructor computes the complete orthogonal decomposition of the
-   * matrix \a matrix by calling the method compute(). The default
-   * threshold for rank determination will be used. It is a short cut for:
-   *
-   * \code
-   * CompleteOrthogonalDecomposition<MatrixType> cod(matrix.rows(),
-   *                                                 matrix.cols());
-   * cod.setThreshold(Default);
-   * cod.compute(matrix);
-   * \endcode
-   *
-   * \sa compute()
-   */
-  template <typename InputType>
-  explicit CompleteOrthogonalDecomposition(const EigenBase<InputType>& matrix)
-      : m_cpqr(matrix.rows(), matrix.cols()),
-        m_zCoeffs((std::min)(matrix.rows(), matrix.cols())),
-        m_temp(matrix.cols())
-  {
-    compute(matrix.derived());
-  }
-
-  /** \brief Constructs a complete orthogonal decomposition from a given matrix
-    *
-    * This overloaded constructor is provided for \link InplaceDecomposition inplace decomposition \endlink when \c MatrixType is a Eigen::Ref.
-    *
-    * \sa CompleteOrthogonalDecomposition(const EigenBase&)
-    */
-  template<typename InputType>
-  explicit CompleteOrthogonalDecomposition(EigenBase<InputType>& matrix)
-    : m_cpqr(matrix.derived()),
-      m_zCoeffs((std::min)(matrix.rows(), matrix.cols())),
-      m_temp(matrix.cols())
-  {
-    computeInPlace();
-  }
-
-
-  /** This method computes the minimum-norm solution X to a least squares
-   * problem \f[\mathrm{minimize} \|A X - B\|, \f] where \b A is the matrix of
-   * which \c *this is the complete orthogonal decomposition.
-   *
-   * \param b the right-hand sides of the problem to solve.
-   *
-   * \returns a solution.
-   *
-   */
-  template <typename Rhs>
-  inline const Solve<CompleteOrthogonalDecomposition, Rhs> solve(
-      const MatrixBase<Rhs>& b) const {
-    eigen_assert(m_cpqr.m_isInitialized &&
-                 "CompleteOrthogonalDecomposition is not initialized.");
-    return Solve<CompleteOrthogonalDecomposition, Rhs>(*this, b.derived());
-  }
-
-  HouseholderSequenceType householderQ(void) const;
-  HouseholderSequenceType matrixQ(void) const { return m_cpqr.householderQ(); }
-
-  /** \returns the matrix \b Z.
-   */
-  MatrixType matrixZ() const {
-    MatrixType Z = MatrixType::Identity(m_cpqr.cols(), m_cpqr.cols());
-    applyZAdjointOnTheLeftInPlace(Z);
-    return Z.adjoint();
-  }
-
-  /** \returns a reference to the matrix where the complete orthogonal
-   * decomposition is stored
-   */
-  const MatrixType& matrixQTZ() const { return m_cpqr.matrixQR(); }
-
-  /** \returns a reference to the matrix where the complete orthogonal
-   * decomposition is stored.
-   * \warning The strict lower part and \code cols() - rank() \endcode right
-   * columns of this matrix contains internal values.
-   * Only the upper triangular part should be referenced. To get it, use
-   * \code matrixT().template triangularView<Upper>() \endcode
-   * For rank-deficient matrices, use
-   * \code
-   * matrixR().topLeftCorner(rank(), rank()).template triangularView<Upper>()
-   * \endcode
-   */
-  const MatrixType& matrixT() const { return m_cpqr.matrixQR(); }
-
-  template <typename InputType>
-  CompleteOrthogonalDecomposition& compute(const EigenBase<InputType>& matrix) {
-    // Compute the column pivoted QR factorization A P = Q R.
-    m_cpqr.compute(matrix);
-    computeInPlace();
-    return *this;
-  }
-
-  /** \returns a const reference to the column permutation matrix */
-  const PermutationType& colsPermutation() const {
-    return m_cpqr.colsPermutation();
-  }
-
-  /** \returns the absolute value of the determinant of the matrix of which
-   * *this is the complete orthogonal decomposition. It has only linear
-   * complexity (that is, O(n) where n is the dimension of the square matrix)
-   * as the complete orthogonal decomposition has already been computed.
-   *
-   * \note This is only for square matrices.
-   *
-   * \warning a determinant can be very big or small, so for matrices
-   * of large enough dimension, there is a risk of overflow/underflow.
-   * One way to work around that is to use logAbsDeterminant() instead.
-   *
-   * \sa logAbsDeterminant(), MatrixBase::determinant()
-   */
-  typename MatrixType::RealScalar absDeterminant() const;
-
-  /** \returns the natural log of the absolute value of the determinant of the
-   * matrix of which *this is the complete orthogonal decomposition. It has
-   * only linear complexity (that is, O(n) where n is the dimension of the
-   * square matrix) as the complete orthogonal decomposition has already been
-   * computed.
-   *
-   * \note This is only for square matrices.
-   *
-   * \note This method is useful to work around the risk of overflow/underflow
-   * that's inherent to determinant computation.
-   *
-   * \sa absDeterminant(), MatrixBase::determinant()
-   */
-  typename MatrixType::RealScalar logAbsDeterminant() const;
-
-  /** \returns the rank of the matrix of which *this is the complete orthogonal
-   * decomposition.
-   *
-   * \note This method has to determine which pivots should be considered
-   * nonzero. For that, it uses the threshold value that you can control by
-   * calling setThreshold(const RealScalar&).
-   */
-  inline Index rank() const { return m_cpqr.rank(); }
-
-  /** \returns the dimension of the kernel of the matrix of which *this is the
-   * complete orthogonal decomposition.
-   *
-   * \note This method has to determine which pivots should be considered
-   * nonzero. For that, it uses the threshold value that you can control by
-   * calling setThreshold(const RealScalar&).
-   */
-  inline Index dimensionOfKernel() const { return m_cpqr.dimensionOfKernel(); }
-
-  /** \returns true if the matrix of which *this is the decomposition represents
-   * an injective linear map, i.e. has trivial kernel; false otherwise.
-   *
-   * \note This method has to determine which pivots should be considered
-   * nonzero. For that, it uses the threshold value that you can control by
-   * calling setThreshold(const RealScalar&).
-   */
-  inline bool isInjective() const { return m_cpqr.isInjective(); }
-
-  /** \returns true if the matrix of which *this is the decomposition represents
-   * a surjective linear map; false otherwise.
-   *
-   * \note This method has to determine which pivots should be considered
-   * nonzero. For that, it uses the threshold value that you can control by
-   * calling setThreshold(const RealScalar&).
-   */
-  inline bool isSurjective() const { return m_cpqr.isSurjective(); }
-
-  /** \returns true if the matrix of which *this is the complete orthogonal
-   * decomposition is invertible.
-   *
-   * \note This method has to determine which pivots should be considered
-   * nonzero. For that, it uses the threshold value that you can control by
-   * calling setThreshold(const RealScalar&).
-   */
-  inline bool isInvertible() const { return m_cpqr.isInvertible(); }
-
-  /** \returns the pseudo-inverse of the matrix of which *this is the complete
-   * orthogonal decomposition.
-   * \warning: Do not compute \c this->pseudoInverse()*rhs to solve a linear systems.
-   * It is more efficient and numerically stable to call \c this->solve(rhs).
-   */
-  inline const Inverse<CompleteOrthogonalDecomposition> pseudoInverse() const
-  {
-    return Inverse<CompleteOrthogonalDecomposition>(*this);
-  }
-
-  inline Index rows() const { return m_cpqr.rows(); }
-  inline Index cols() const { return m_cpqr.cols(); }
-
-  /** \returns a const reference to the vector of Householder coefficients used
-   * to represent the factor \c Q.
-   *
-   * For advanced uses only.
-   */
-  inline const HCoeffsType& hCoeffs() const { return m_cpqr.hCoeffs(); }
-
-  /** \returns a const reference to the vector of Householder coefficients
-   * used to represent the factor \c Z.
-   *
-   * For advanced uses only.
-   */
-  const HCoeffsType& zCoeffs() const { return m_zCoeffs; }
-
-  /** Allows to prescribe a threshold to be used by certain methods, such as
-   * rank(), who need to determine when pivots are to be considered nonzero.
-   * Most be called before calling compute().
-   *
-   * When it needs to get the threshold value, Eigen calls threshold(). By
-   * default, this uses a formula to automatically determine a reasonable
-   * threshold. Once you have called the present method
-   * setThreshold(const RealScalar&), your value is used instead.
-   *
-   * \param threshold The new value to use as the threshold.
-   *
-   * A pivot will be considered nonzero if its absolute value is strictly
-   * greater than
-   *  \f$ \vert pivot \vert \leqslant threshold \times \vert maxpivot \vert \f$
-   * where maxpivot is the biggest pivot.
-   *
-   * If you want to come back to the default behavior, call
-   * setThreshold(Default_t)
-   */
-  CompleteOrthogonalDecomposition& setThreshold(const RealScalar& threshold) {
-    m_cpqr.setThreshold(threshold);
-    return *this;
-  }
-
-  /** Allows to come back to the default behavior, letting Eigen use its default
-   * formula for determining the threshold.
-   *
-   * You should pass the special object Eigen::Default as parameter here.
-   * \code qr.setThreshold(Eigen::Default); \endcode
-   *
-   * See the documentation of setThreshold(const RealScalar&).
-   */
-  CompleteOrthogonalDecomposition& setThreshold(Default_t) {
-    m_cpqr.setThreshold(Default);
-    return *this;
-  }
-
-  /** Returns the threshold that will be used by certain methods such as rank().
-   *
-   * See the documentation of setThreshold(const RealScalar&).
-   */
-  RealScalar threshold() const { return m_cpqr.threshold(); }
-
-  /** \returns the number of nonzero pivots in the complete orthogonal
-   * decomposition. Here nonzero is meant in the exact sense, not in a
-   * fuzzy sense. So that notion isn't really intrinsically interesting,
-   * but it is still useful when implementing algorithms.
-   *
-   * \sa rank()
-   */
-  inline Index nonzeroPivots() const { return m_cpqr.nonzeroPivots(); }
-
-  /** \returns the absolute value of the biggest pivot, i.e. the biggest
-   *          diagonal coefficient of R.
-   */
-  inline RealScalar maxPivot() const { return m_cpqr.maxPivot(); }
-
-  /** \brief Reports whether the complete orthogonal decomposition was
-   * succesful.
-   *
-   * \note This function always returns \c Success. It is provided for
-   * compatibility
-   * with other factorization routines.
-   * \returns \c Success
-   */
-  ComputationInfo info() const {
-    eigen_assert(m_cpqr.m_isInitialized && "Decomposition is not initialized.");
-    return Success;
-  }
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-  template <typename RhsType, typename DstType>
-  EIGEN_DEVICE_FUNC void _solve_impl(const RhsType& rhs, DstType& dst) const;
-#endif
-
- protected:
-  static void check_template_parameters() {
-    EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
-  }
-
-  void computeInPlace();
-
-  /** Overwrites \b rhs with \f$ \mathbf{Z}^* * \mathbf{rhs} \f$.
-   */
-  template <typename Rhs>
-  void applyZAdjointOnTheLeftInPlace(Rhs& rhs) const;
-
-  ColPivHouseholderQR<MatrixType> m_cpqr;
-  HCoeffsType m_zCoeffs;
-  RowVectorType m_temp;
-};
-
-template <typename MatrixType>
-typename MatrixType::RealScalar
-CompleteOrthogonalDecomposition<MatrixType>::absDeterminant() const {
-  return m_cpqr.absDeterminant();
-}
-
-template <typename MatrixType>
-typename MatrixType::RealScalar
-CompleteOrthogonalDecomposition<MatrixType>::logAbsDeterminant() const {
-  return m_cpqr.logAbsDeterminant();
-}
-
-/** Performs the complete orthogonal decomposition of the given matrix \a
- * matrix. The result of the factorization is stored into \c *this, and a
- * reference to \c *this is returned.
- *
- * \sa class CompleteOrthogonalDecomposition,
- * CompleteOrthogonalDecomposition(const MatrixType&)
- */
-template <typename MatrixType>
-void CompleteOrthogonalDecomposition<MatrixType>::computeInPlace()
-{
-  check_template_parameters();
-
-  // the column permutation is stored as int indices, so just to be sure:
-  eigen_assert(m_cpqr.cols() <= NumTraits<int>::highest());
-
-  const Index rank = m_cpqr.rank();
-  const Index cols = m_cpqr.cols();
-  const Index rows = m_cpqr.rows();
-  m_zCoeffs.resize((std::min)(rows, cols));
-  m_temp.resize(cols);
-
-  if (rank < cols) {
-    // We have reduced the (permuted) matrix to the form
-    //   [R11 R12]
-    //   [ 0  R22]
-    // where R11 is r-by-r (r = rank) upper triangular, R12 is
-    // r-by-(n-r), and R22 is empty or the norm of R22 is negligible.
-    // We now compute the complete orthogonal decomposition by applying
-    // Householder transformations from the right to the upper trapezoidal
-    // matrix X = [R11 R12] to zero out R12 and obtain the factorization
-    // [R11 R12] = [T11 0] * Z, where T11 is r-by-r upper triangular and
-    // Z = Z(0) * Z(1) ... Z(r-1) is an n-by-n orthogonal matrix.
-    // We store the data representing Z in R12 and m_zCoeffs.
-    for (Index k = rank - 1; k >= 0; --k) {
-      if (k != rank - 1) {
-        // Given the API for Householder reflectors, it is more convenient if
-        // we swap the leading parts of columns k and r-1 (zero-based) to form
-        // the matrix X_k = [X(0:k, k), X(0:k, r:n)]
-        m_cpqr.m_qr.col(k).head(k + 1).swap(
-            m_cpqr.m_qr.col(rank - 1).head(k + 1));
-      }
-      // Construct Householder reflector Z(k) to zero out the last row of X_k,
-      // i.e. choose Z(k) such that
-      // [X(k, k), X(k, r:n)] * Z(k) = [beta, 0, .., 0].
-      RealScalar beta;
-      m_cpqr.m_qr.row(k)
-          .tail(cols - rank + 1)
-          .makeHouseholderInPlace(m_zCoeffs(k), beta);
-      m_cpqr.m_qr(k, rank - 1) = beta;
-      if (k > 0) {
-        // Apply Z(k) to the first k rows of X_k
-        m_cpqr.m_qr.topRightCorner(k, cols - rank + 1)
-            .applyHouseholderOnTheRight(
-                m_cpqr.m_qr.row(k).tail(cols - rank).transpose(), m_zCoeffs(k),
-                &m_temp(0));
-      }
-      if (k != rank - 1) {
-        // Swap X(0:k,k) back to its proper location.
-        m_cpqr.m_qr.col(k).head(k + 1).swap(
-            m_cpqr.m_qr.col(rank - 1).head(k + 1));
-      }
-    }
-  }
-}
-
-template <typename MatrixType>
-template <typename Rhs>
-void CompleteOrthogonalDecomposition<MatrixType>::applyZAdjointOnTheLeftInPlace(
-    Rhs& rhs) const {
-  const Index cols = this->cols();
-  const Index nrhs = rhs.cols();
-  const Index rank = this->rank();
-  Matrix<typename MatrixType::Scalar, Dynamic, 1> temp((std::max)(cols, nrhs));
-  for (Index k = 0; k < rank; ++k) {
-    if (k != rank - 1) {
-      rhs.row(k).swap(rhs.row(rank - 1));
-    }
-    rhs.middleRows(rank - 1, cols - rank + 1)
-        .applyHouseholderOnTheLeft(
-            matrixQTZ().row(k).tail(cols - rank).adjoint(), zCoeffs()(k),
-            &temp(0));
-    if (k != rank - 1) {
-      rhs.row(k).swap(rhs.row(rank - 1));
-    }
-  }
-}
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-template <typename _MatrixType>
-template <typename RhsType, typename DstType>
-void CompleteOrthogonalDecomposition<_MatrixType>::_solve_impl(
-    const RhsType& rhs, DstType& dst) const {
-  eigen_assert(rhs.rows() == this->rows());
-
-  const Index rank = this->rank();
-  if (rank == 0) {
-    dst.setZero();
-    return;
-  }
-
-  // Compute c = Q^* * rhs
-  // Note that the matrix Q = H_0^* H_1^*... so its inverse is
-  // Q^* = (H_0 H_1 ...)^T
-  typename RhsType::PlainObject c(rhs);
-  c.applyOnTheLeft(
-      householderSequence(matrixQTZ(), hCoeffs()).setLength(rank).transpose());
-
-  // Solve T z = c(1:rank, :)
-  dst.topRows(rank) = matrixT()
-                          .topLeftCorner(rank, rank)
-                          .template triangularView<Upper>()
-                          .solve(c.topRows(rank));
-
-  const Index cols = this->cols();
-  if (rank < cols) {
-    // Compute y = Z^* * [ z ]
-    //                   [ 0 ]
-    dst.bottomRows(cols - rank).setZero();
-    applyZAdjointOnTheLeftInPlace(dst);
-  }
-
-  // Undo permutation to get x = P^{-1} * y.
-  dst = colsPermutation() * dst;
-}
-#endif
-
-namespace internal {
-
-template<typename DstXprType, typename MatrixType>
-struct Assignment<DstXprType, Inverse<CompleteOrthogonalDecomposition<MatrixType> >, internal::assign_op<typename DstXprType::Scalar,typename CompleteOrthogonalDecomposition<MatrixType>::Scalar>, Dense2Dense>
-{
-  typedef CompleteOrthogonalDecomposition<MatrixType> CodType;
-  typedef Inverse<CodType> SrcXprType;
-  static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar,typename CodType::Scalar> &)
-  {
-    dst = src.nestedExpression().solve(MatrixType::Identity(src.rows(), src.rows()));
-  }
-};
-
-} // end namespace internal
-
-/** \returns the matrix Q as a sequence of householder transformations */
-template <typename MatrixType>
-typename CompleteOrthogonalDecomposition<MatrixType>::HouseholderSequenceType
-CompleteOrthogonalDecomposition<MatrixType>::householderQ() const {
-  return m_cpqr.householderQ();
-}
-
-/** \return the complete orthogonal decomposition of \c *this.
-  *
-  * \sa class CompleteOrthogonalDecomposition
-  */
-template <typename Derived>
-const CompleteOrthogonalDecomposition<typename MatrixBase<Derived>::PlainObject>
-MatrixBase<Derived>::completeOrthogonalDecomposition() const {
-  return CompleteOrthogonalDecomposition<PlainObject>(eval());
-}
-
-}  // end namespace Eigen
-
-#endif  // EIGEN_COMPLETEORTHOGONALDECOMPOSITION_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/QR/FullPivHouseholderQR.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/QR/FullPivHouseholderQR.h
deleted file mode 100644
index e489bdd..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/QR/FullPivHouseholderQR.h
+++ /dev/null
@@ -1,676 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_FULLPIVOTINGHOUSEHOLDERQR_H
-#define EIGEN_FULLPIVOTINGHOUSEHOLDERQR_H
-
-namespace Eigen { 
-
-namespace internal {
-
-template<typename _MatrixType> struct traits<FullPivHouseholderQR<_MatrixType> >
- : traits<_MatrixType>
-{
-  enum { Flags = 0 };
-};
-
-template<typename MatrixType> struct FullPivHouseholderQRMatrixQReturnType;
-
-template<typename MatrixType>
-struct traits<FullPivHouseholderQRMatrixQReturnType<MatrixType> >
-{
-  typedef typename MatrixType::PlainObject ReturnType;
-};
-
-} // end namespace internal
-
-/** \ingroup QR_Module
-  *
-  * \class FullPivHouseholderQR
-  *
-  * \brief Householder rank-revealing QR decomposition of a matrix with full pivoting
-  *
-  * \tparam _MatrixType the type of the matrix of which we are computing the QR decomposition
-  *
-  * This class performs a rank-revealing QR decomposition of a matrix \b A into matrices \b P, \b P', \b Q and \b R
-  * such that 
-  * \f[
-  *  \mathbf{P} \, \mathbf{A} \, \mathbf{P}' = \mathbf{Q} \, \mathbf{R}
-  * \f]
-  * by using Householder transformations. Here, \b P and \b P' are permutation matrices, \b Q a unitary matrix 
-  * and \b R an upper triangular matrix.
-  *
-  * This decomposition performs a very prudent full pivoting in order to be rank-revealing and achieve optimal
-  * numerical stability. The trade-off is that it is slower than HouseholderQR and ColPivHouseholderQR.
-  *
-  * This class supports the \link InplaceDecomposition inplace decomposition \endlink mechanism.
-  * 
-  * \sa MatrixBase::fullPivHouseholderQr()
-  */
-template<typename _MatrixType> class FullPivHouseholderQR
-{
-  public:
-
-    typedef _MatrixType MatrixType;
-    enum {
-      RowsAtCompileTime = MatrixType::RowsAtCompileTime,
-      ColsAtCompileTime = MatrixType::ColsAtCompileTime,
-      MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
-      MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
-    };
-    typedef typename MatrixType::Scalar Scalar;
-    typedef typename MatrixType::RealScalar RealScalar;
-    // FIXME should be int
-    typedef typename MatrixType::StorageIndex StorageIndex;
-    typedef internal::FullPivHouseholderQRMatrixQReturnType<MatrixType> MatrixQReturnType;
-    typedef typename internal::plain_diag_type<MatrixType>::type HCoeffsType;
-    typedef Matrix<StorageIndex, 1,
-                   EIGEN_SIZE_MIN_PREFER_DYNAMIC(ColsAtCompileTime,RowsAtCompileTime), RowMajor, 1,
-                   EIGEN_SIZE_MIN_PREFER_FIXED(MaxColsAtCompileTime,MaxRowsAtCompileTime)> IntDiagSizeVectorType;
-    typedef PermutationMatrix<ColsAtCompileTime, MaxColsAtCompileTime> PermutationType;
-    typedef typename internal::plain_row_type<MatrixType>::type RowVectorType;
-    typedef typename internal::plain_col_type<MatrixType>::type ColVectorType;
-    typedef typename MatrixType::PlainObject PlainObject;
-
-    /** \brief Default Constructor.
-      *
-      * The default constructor is useful in cases in which the user intends to
-      * perform decompositions via FullPivHouseholderQR::compute(const MatrixType&).
-      */
-    FullPivHouseholderQR()
-      : m_qr(),
-        m_hCoeffs(),
-        m_rows_transpositions(),
-        m_cols_transpositions(),
-        m_cols_permutation(),
-        m_temp(),
-        m_isInitialized(false),
-        m_usePrescribedThreshold(false) {}
-
-    /** \brief Default Constructor with memory preallocation
-      *
-      * Like the default constructor but with preallocation of the internal data
-      * according to the specified problem \a size.
-      * \sa FullPivHouseholderQR()
-      */
-    FullPivHouseholderQR(Index rows, Index cols)
-      : m_qr(rows, cols),
-        m_hCoeffs((std::min)(rows,cols)),
-        m_rows_transpositions((std::min)(rows,cols)),
-        m_cols_transpositions((std::min)(rows,cols)),
-        m_cols_permutation(cols),
-        m_temp(cols),
-        m_isInitialized(false),
-        m_usePrescribedThreshold(false) {}
-
-    /** \brief Constructs a QR factorization from a given matrix
-      *
-      * This constructor computes the QR factorization of the matrix \a matrix by calling
-      * the method compute(). It is a short cut for:
-      * 
-      * \code
-      * FullPivHouseholderQR<MatrixType> qr(matrix.rows(), matrix.cols());
-      * qr.compute(matrix);
-      * \endcode
-      * 
-      * \sa compute()
-      */
-    template<typename InputType>
-    explicit FullPivHouseholderQR(const EigenBase<InputType>& matrix)
-      : m_qr(matrix.rows(), matrix.cols()),
-        m_hCoeffs((std::min)(matrix.rows(), matrix.cols())),
-        m_rows_transpositions((std::min)(matrix.rows(), matrix.cols())),
-        m_cols_transpositions((std::min)(matrix.rows(), matrix.cols())),
-        m_cols_permutation(matrix.cols()),
-        m_temp(matrix.cols()),
-        m_isInitialized(false),
-        m_usePrescribedThreshold(false)
-    {
-      compute(matrix.derived());
-    }
-
-    /** \brief Constructs a QR factorization from a given matrix
-      *
-      * This overloaded constructor is provided for \link InplaceDecomposition inplace decomposition \endlink when \c MatrixType is a Eigen::Ref.
-      *
-      * \sa FullPivHouseholderQR(const EigenBase&)
-      */
-    template<typename InputType>
-    explicit FullPivHouseholderQR(EigenBase<InputType>& matrix)
-      : m_qr(matrix.derived()),
-        m_hCoeffs((std::min)(matrix.rows(), matrix.cols())),
-        m_rows_transpositions((std::min)(matrix.rows(), matrix.cols())),
-        m_cols_transpositions((std::min)(matrix.rows(), matrix.cols())),
-        m_cols_permutation(matrix.cols()),
-        m_temp(matrix.cols()),
-        m_isInitialized(false),
-        m_usePrescribedThreshold(false)
-    {
-      computeInPlace();
-    }
-
-    /** This method finds a solution x to the equation Ax=b, where A is the matrix of which
-      * \c *this is the QR decomposition.
-      *
-      * \param b the right-hand-side of the equation to solve.
-      *
-      * \returns the exact or least-square solution if the rank is greater or equal to the number of columns of A,
-      * and an arbitrary solution otherwise.
-      *
-      * \note_about_checking_solutions
-      *
-      * \note_about_arbitrary_choice_of_solution
-      *
-      * Example: \include FullPivHouseholderQR_solve.cpp
-      * Output: \verbinclude FullPivHouseholderQR_solve.out
-      */
-    template<typename Rhs>
-    inline const Solve<FullPivHouseholderQR, Rhs>
-    solve(const MatrixBase<Rhs>& b) const
-    {
-      eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
-      return Solve<FullPivHouseholderQR, Rhs>(*this, b.derived());
-    }
-
-    /** \returns Expression object representing the matrix Q
-      */
-    MatrixQReturnType matrixQ(void) const;
-
-    /** \returns a reference to the matrix where the Householder QR decomposition is stored
-      */
-    const MatrixType& matrixQR() const
-    {
-      eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
-      return m_qr;
-    }
-
-    template<typename InputType>
-    FullPivHouseholderQR& compute(const EigenBase<InputType>& matrix);
-
-    /** \returns a const reference to the column permutation matrix */
-    const PermutationType& colsPermutation() const
-    {
-      eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
-      return m_cols_permutation;
-    }
-
-    /** \returns a const reference to the vector of indices representing the rows transpositions */
-    const IntDiagSizeVectorType& rowsTranspositions() const
-    {
-      eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
-      return m_rows_transpositions;
-    }
-
-    /** \returns the absolute value of the determinant of the matrix of which
-      * *this is the QR decomposition. It has only linear complexity
-      * (that is, O(n) where n is the dimension of the square matrix)
-      * as the QR decomposition has already been computed.
-      *
-      * \note This is only for square matrices.
-      *
-      * \warning a determinant can be very big or small, so for matrices
-      * of large enough dimension, there is a risk of overflow/underflow.
-      * One way to work around that is to use logAbsDeterminant() instead.
-      *
-      * \sa logAbsDeterminant(), MatrixBase::determinant()
-      */
-    typename MatrixType::RealScalar absDeterminant() const;
-
-    /** \returns the natural log of the absolute value of the determinant of the matrix of which
-      * *this is the QR decomposition. It has only linear complexity
-      * (that is, O(n) where n is the dimension of the square matrix)
-      * as the QR decomposition has already been computed.
-      *
-      * \note This is only for square matrices.
-      *
-      * \note This method is useful to work around the risk of overflow/underflow that's inherent
-      * to determinant computation.
-      *
-      * \sa absDeterminant(), MatrixBase::determinant()
-      */
-    typename MatrixType::RealScalar logAbsDeterminant() const;
-
-    /** \returns the rank of the matrix of which *this is the QR decomposition.
-      *
-      * \note This method has to determine which pivots should be considered nonzero.
-      *       For that, it uses the threshold value that you can control by calling
-      *       setThreshold(const RealScalar&).
-      */
-    inline Index rank() const
-    {
-      using std::abs;
-      eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
-      RealScalar premultiplied_threshold = abs(m_maxpivot) * threshold();
-      Index result = 0;
-      for(Index i = 0; i < m_nonzero_pivots; ++i)
-        result += (abs(m_qr.coeff(i,i)) > premultiplied_threshold);
-      return result;
-    }
-
-    /** \returns the dimension of the kernel of the matrix of which *this is the QR decomposition.
-      *
-      * \note This method has to determine which pivots should be considered nonzero.
-      *       For that, it uses the threshold value that you can control by calling
-      *       setThreshold(const RealScalar&).
-      */
-    inline Index dimensionOfKernel() const
-    {
-      eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
-      return cols() - rank();
-    }
-
-    /** \returns true if the matrix of which *this is the QR decomposition represents an injective
-      *          linear map, i.e. has trivial kernel; false otherwise.
-      *
-      * \note This method has to determine which pivots should be considered nonzero.
-      *       For that, it uses the threshold value that you can control by calling
-      *       setThreshold(const RealScalar&).
-      */
-    inline bool isInjective() const
-    {
-      eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
-      return rank() == cols();
-    }
-
-    /** \returns true if the matrix of which *this is the QR decomposition represents a surjective
-      *          linear map; false otherwise.
-      *
-      * \note This method has to determine which pivots should be considered nonzero.
-      *       For that, it uses the threshold value that you can control by calling
-      *       setThreshold(const RealScalar&).
-      */
-    inline bool isSurjective() const
-    {
-      eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
-      return rank() == rows();
-    }
-
-    /** \returns true if the matrix of which *this is the QR decomposition is invertible.
-      *
-      * \note This method has to determine which pivots should be considered nonzero.
-      *       For that, it uses the threshold value that you can control by calling
-      *       setThreshold(const RealScalar&).
-      */
-    inline bool isInvertible() const
-    {
-      eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
-      return isInjective() && isSurjective();
-    }
-
-    /** \returns the inverse of the matrix of which *this is the QR decomposition.
-      *
-      * \note If this matrix is not invertible, the returned matrix has undefined coefficients.
-      *       Use isInvertible() to first determine whether this matrix is invertible.
-      */
-    inline const Inverse<FullPivHouseholderQR> inverse() const
-    {
-      eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
-      return Inverse<FullPivHouseholderQR>(*this);
-    }
-
-    inline Index rows() const { return m_qr.rows(); }
-    inline Index cols() const { return m_qr.cols(); }
-    
-    /** \returns a const reference to the vector of Householder coefficients used to represent the factor \c Q.
-      * 
-      * For advanced uses only.
-      */
-    const HCoeffsType& hCoeffs() const { return m_hCoeffs; }
-
-    /** Allows to prescribe a threshold to be used by certain methods, such as rank(),
-      * who need to determine when pivots are to be considered nonzero. This is not used for the
-      * QR decomposition itself.
-      *
-      * When it needs to get the threshold value, Eigen calls threshold(). By default, this
-      * uses a formula to automatically determine a reasonable threshold.
-      * Once you have called the present method setThreshold(const RealScalar&),
-      * your value is used instead.
-      *
-      * \param threshold The new value to use as the threshold.
-      *
-      * A pivot will be considered nonzero if its absolute value is strictly greater than
-      *  \f$ \vert pivot \vert \leqslant threshold \times \vert maxpivot \vert \f$
-      * where maxpivot is the biggest pivot.
-      *
-      * If you want to come back to the default behavior, call setThreshold(Default_t)
-      */
-    FullPivHouseholderQR& setThreshold(const RealScalar& threshold)
-    {
-      m_usePrescribedThreshold = true;
-      m_prescribedThreshold = threshold;
-      return *this;
-    }
-
-    /** Allows to come back to the default behavior, letting Eigen use its default formula for
-      * determining the threshold.
-      *
-      * You should pass the special object Eigen::Default as parameter here.
-      * \code qr.setThreshold(Eigen::Default); \endcode
-      *
-      * See the documentation of setThreshold(const RealScalar&).
-      */
-    FullPivHouseholderQR& setThreshold(Default_t)
-    {
-      m_usePrescribedThreshold = false;
-      return *this;
-    }
-
-    /** Returns the threshold that will be used by certain methods such as rank().
-      *
-      * See the documentation of setThreshold(const RealScalar&).
-      */
-    RealScalar threshold() const
-    {
-      eigen_assert(m_isInitialized || m_usePrescribedThreshold);
-      return m_usePrescribedThreshold ? m_prescribedThreshold
-      // this formula comes from experimenting (see "LU precision tuning" thread on the list)
-      // and turns out to be identical to Higham's formula used already in LDLt.
-                                      : NumTraits<Scalar>::epsilon() * RealScalar(m_qr.diagonalSize());
-    }
-
-    /** \returns the number of nonzero pivots in the QR decomposition.
-      * Here nonzero is meant in the exact sense, not in a fuzzy sense.
-      * So that notion isn't really intrinsically interesting, but it is
-      * still useful when implementing algorithms.
-      *
-      * \sa rank()
-      */
-    inline Index nonzeroPivots() const
-    {
-      eigen_assert(m_isInitialized && "LU is not initialized.");
-      return m_nonzero_pivots;
-    }
-
-    /** \returns the absolute value of the biggest pivot, i.e. the biggest
-      *          diagonal coefficient of U.
-      */
-    RealScalar maxPivot() const { return m_maxpivot; }
-    
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    template<typename RhsType, typename DstType>
-    EIGEN_DEVICE_FUNC
-    void _solve_impl(const RhsType &rhs, DstType &dst) const;
-    #endif
-
-  protected:
-    
-    static void check_template_parameters()
-    {
-      EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
-    }
-    
-    void computeInPlace();
-    
-    MatrixType m_qr;
-    HCoeffsType m_hCoeffs;
-    IntDiagSizeVectorType m_rows_transpositions;
-    IntDiagSizeVectorType m_cols_transpositions;
-    PermutationType m_cols_permutation;
-    RowVectorType m_temp;
-    bool m_isInitialized, m_usePrescribedThreshold;
-    RealScalar m_prescribedThreshold, m_maxpivot;
-    Index m_nonzero_pivots;
-    RealScalar m_precision;
-    Index m_det_pq;
-};
-
-template<typename MatrixType>
-typename MatrixType::RealScalar FullPivHouseholderQR<MatrixType>::absDeterminant() const
-{
-  using std::abs;
-  eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
-  eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
-  return abs(m_qr.diagonal().prod());
-}
-
-template<typename MatrixType>
-typename MatrixType::RealScalar FullPivHouseholderQR<MatrixType>::logAbsDeterminant() const
-{
-  eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
-  eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
-  return m_qr.diagonal().cwiseAbs().array().log().sum();
-}
-
-/** Performs the QR factorization of the given matrix \a matrix. The result of
-  * the factorization is stored into \c *this, and a reference to \c *this
-  * is returned.
-  *
-  * \sa class FullPivHouseholderQR, FullPivHouseholderQR(const MatrixType&)
-  */
-template<typename MatrixType>
-template<typename InputType>
-FullPivHouseholderQR<MatrixType>& FullPivHouseholderQR<MatrixType>::compute(const EigenBase<InputType>& matrix)
-{
-  m_qr = matrix.derived();
-  computeInPlace();
-  return *this;
-}
-
-template<typename MatrixType>
-void FullPivHouseholderQR<MatrixType>::computeInPlace()
-{
-  check_template_parameters();
-
-  using std::abs;
-  Index rows = m_qr.rows();
-  Index cols = m_qr.cols();
-  Index size = (std::min)(rows,cols);
-
-  
-  m_hCoeffs.resize(size);
-
-  m_temp.resize(cols);
-
-  m_precision = NumTraits<Scalar>::epsilon() * RealScalar(size);
-
-  m_rows_transpositions.resize(size);
-  m_cols_transpositions.resize(size);
-  Index number_of_transpositions = 0;
-
-  RealScalar biggest(0);
-
-  m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
-  m_maxpivot = RealScalar(0);
-
-  for (Index k = 0; k < size; ++k)
-  {
-    Index row_of_biggest_in_corner, col_of_biggest_in_corner;
-    typedef internal::scalar_score_coeff_op<Scalar> Scoring;
-    typedef typename Scoring::result_type Score;
-
-    Score score = m_qr.bottomRightCorner(rows-k, cols-k)
-                      .unaryExpr(Scoring())
-                      .maxCoeff(&row_of_biggest_in_corner, &col_of_biggest_in_corner);
-    row_of_biggest_in_corner += k;
-    col_of_biggest_in_corner += k;
-    RealScalar biggest_in_corner = internal::abs_knowing_score<Scalar>()(m_qr(row_of_biggest_in_corner, col_of_biggest_in_corner), score);
-    if(k==0) biggest = biggest_in_corner;
-
-    // if the corner is negligible, then we have less than full rank, and we can finish early
-    if(internal::isMuchSmallerThan(biggest_in_corner, biggest, m_precision))
-    {
-      m_nonzero_pivots = k;
-      for(Index i = k; i < size; i++)
-      {
-        m_rows_transpositions.coeffRef(i) = i;
-        m_cols_transpositions.coeffRef(i) = i;
-        m_hCoeffs.coeffRef(i) = Scalar(0);
-      }
-      break;
-    }
-
-    m_rows_transpositions.coeffRef(k) = row_of_biggest_in_corner;
-    m_cols_transpositions.coeffRef(k) = col_of_biggest_in_corner;
-    if(k != row_of_biggest_in_corner) {
-      m_qr.row(k).tail(cols-k).swap(m_qr.row(row_of_biggest_in_corner).tail(cols-k));
-      ++number_of_transpositions;
-    }
-    if(k != col_of_biggest_in_corner) {
-      m_qr.col(k).swap(m_qr.col(col_of_biggest_in_corner));
-      ++number_of_transpositions;
-    }
-
-    RealScalar beta;
-    m_qr.col(k).tail(rows-k).makeHouseholderInPlace(m_hCoeffs.coeffRef(k), beta);
-    m_qr.coeffRef(k,k) = beta;
-
-    // remember the maximum absolute value of diagonal coefficients
-    if(abs(beta) > m_maxpivot) m_maxpivot = abs(beta);
-
-    m_qr.bottomRightCorner(rows-k, cols-k-1)
-        .applyHouseholderOnTheLeft(m_qr.col(k).tail(rows-k-1), m_hCoeffs.coeffRef(k), &m_temp.coeffRef(k+1));
-  }
-
-  m_cols_permutation.setIdentity(cols);
-  for(Index k = 0; k < size; ++k)
-    m_cols_permutation.applyTranspositionOnTheRight(k, m_cols_transpositions.coeff(k));
-
-  m_det_pq = (number_of_transpositions%2) ? -1 : 1;
-  m_isInitialized = true;
-}
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-template<typename _MatrixType>
-template<typename RhsType, typename DstType>
-void FullPivHouseholderQR<_MatrixType>::_solve_impl(const RhsType &rhs, DstType &dst) const
-{
-  eigen_assert(rhs.rows() == rows());
-  const Index l_rank = rank();
-
-  // FIXME introduce nonzeroPivots() and use it here. and more generally,
-  // make the same improvements in this dec as in FullPivLU.
-  if(l_rank==0)
-  {
-    dst.setZero();
-    return;
-  }
-
-  typename RhsType::PlainObject c(rhs);
-
-  Matrix<Scalar,1,RhsType::ColsAtCompileTime> temp(rhs.cols());
-  for (Index k = 0; k < l_rank; ++k)
-  {
-    Index remainingSize = rows()-k;
-    c.row(k).swap(c.row(m_rows_transpositions.coeff(k)));
-    c.bottomRightCorner(remainingSize, rhs.cols())
-      .applyHouseholderOnTheLeft(m_qr.col(k).tail(remainingSize-1),
-                               m_hCoeffs.coeff(k), &temp.coeffRef(0));
-  }
-
-  m_qr.topLeftCorner(l_rank, l_rank)
-      .template triangularView<Upper>()
-      .solveInPlace(c.topRows(l_rank));
-
-  for(Index i = 0; i < l_rank; ++i) dst.row(m_cols_permutation.indices().coeff(i)) = c.row(i);
-  for(Index i = l_rank; i < cols(); ++i) dst.row(m_cols_permutation.indices().coeff(i)).setZero();
-}
-#endif
-
-namespace internal {
-  
-template<typename DstXprType, typename MatrixType>
-struct Assignment<DstXprType, Inverse<FullPivHouseholderQR<MatrixType> >, internal::assign_op<typename DstXprType::Scalar,typename FullPivHouseholderQR<MatrixType>::Scalar>, Dense2Dense>
-{
-  typedef FullPivHouseholderQR<MatrixType> QrType;
-  typedef Inverse<QrType> SrcXprType;
-  static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar,typename QrType::Scalar> &)
-  {    
-    dst = src.nestedExpression().solve(MatrixType::Identity(src.rows(), src.cols()));
-  }
-};
-
-/** \ingroup QR_Module
-  *
-  * \brief Expression type for return value of FullPivHouseholderQR::matrixQ()
-  *
-  * \tparam MatrixType type of underlying dense matrix
-  */
-template<typename MatrixType> struct FullPivHouseholderQRMatrixQReturnType
-  : public ReturnByValue<FullPivHouseholderQRMatrixQReturnType<MatrixType> >
-{
-public:
-  typedef typename FullPivHouseholderQR<MatrixType>::IntDiagSizeVectorType IntDiagSizeVectorType;
-  typedef typename internal::plain_diag_type<MatrixType>::type HCoeffsType;
-  typedef Matrix<typename MatrixType::Scalar, 1, MatrixType::RowsAtCompileTime, RowMajor, 1,
-                 MatrixType::MaxRowsAtCompileTime> WorkVectorType;
-
-  FullPivHouseholderQRMatrixQReturnType(const MatrixType&       qr,
-                                        const HCoeffsType&      hCoeffs,
-                                        const IntDiagSizeVectorType& rowsTranspositions)
-    : m_qr(qr),
-      m_hCoeffs(hCoeffs),
-      m_rowsTranspositions(rowsTranspositions)
-  {}
-
-  template <typename ResultType>
-  void evalTo(ResultType& result) const
-  {
-    const Index rows = m_qr.rows();
-    WorkVectorType workspace(rows);
-    evalTo(result, workspace);
-  }
-
-  template <typename ResultType>
-  void evalTo(ResultType& result, WorkVectorType& workspace) const
-  {
-    using numext::conj;
-    // compute the product H'_0 H'_1 ... H'_n-1,
-    // where H_k is the k-th Householder transformation I - h_k v_k v_k'
-    // and v_k is the k-th Householder vector [1,m_qr(k+1,k), m_qr(k+2,k), ...]
-    const Index rows = m_qr.rows();
-    const Index cols = m_qr.cols();
-    const Index size = (std::min)(rows, cols);
-    workspace.resize(rows);
-    result.setIdentity(rows, rows);
-    for (Index k = size-1; k >= 0; k--)
-    {
-      result.block(k, k, rows-k, rows-k)
-            .applyHouseholderOnTheLeft(m_qr.col(k).tail(rows-k-1), conj(m_hCoeffs.coeff(k)), &workspace.coeffRef(k));
-      result.row(k).swap(result.row(m_rowsTranspositions.coeff(k)));
-    }
-  }
-
-  Index rows() const { return m_qr.rows(); }
-  Index cols() const { return m_qr.rows(); }
-
-protected:
-  typename MatrixType::Nested m_qr;
-  typename HCoeffsType::Nested m_hCoeffs;
-  typename IntDiagSizeVectorType::Nested m_rowsTranspositions;
-};
-
-// template<typename MatrixType>
-// struct evaluator<FullPivHouseholderQRMatrixQReturnType<MatrixType> >
-//  : public evaluator<ReturnByValue<FullPivHouseholderQRMatrixQReturnType<MatrixType> > >
-// {};
-
-} // end namespace internal
-
-template<typename MatrixType>
-inline typename FullPivHouseholderQR<MatrixType>::MatrixQReturnType FullPivHouseholderQR<MatrixType>::matrixQ() const
-{
-  eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
-  return MatrixQReturnType(m_qr, m_hCoeffs, m_rows_transpositions);
-}
-
-/** \return the full-pivoting Householder QR decomposition of \c *this.
-  *
-  * \sa class FullPivHouseholderQR
-  */
-template<typename Derived>
-const FullPivHouseholderQR<typename MatrixBase<Derived>::PlainObject>
-MatrixBase<Derived>::fullPivHouseholderQr() const
-{
-  return FullPivHouseholderQR<PlainObject>(eval());
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_FULLPIVOTINGHOUSEHOLDERQR_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/QR/HouseholderQR.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/QR/HouseholderQR.h
deleted file mode 100644
index 3513d99..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/QR/HouseholderQR.h
+++ /dev/null
@@ -1,409 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2010 Vincent Lejeune
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_QR_H
-#define EIGEN_QR_H
-
-namespace Eigen { 
-
-/** \ingroup QR_Module
-  *
-  *
-  * \class HouseholderQR
-  *
-  * \brief Householder QR decomposition of a matrix
-  *
-  * \tparam _MatrixType the type of the matrix of which we are computing the QR decomposition
-  *
-  * This class performs a QR decomposition of a matrix \b A into matrices \b Q and \b R
-  * such that 
-  * \f[
-  *  \mathbf{A} = \mathbf{Q} \, \mathbf{R}
-  * \f]
-  * by using Householder transformations. Here, \b Q a unitary matrix and \b R an upper triangular matrix.
-  * The result is stored in a compact way compatible with LAPACK.
-  *
-  * Note that no pivoting is performed. This is \b not a rank-revealing decomposition.
-  * If you want that feature, use FullPivHouseholderQR or ColPivHouseholderQR instead.
-  *
-  * This Householder QR decomposition is faster, but less numerically stable and less feature-full than
-  * FullPivHouseholderQR or ColPivHouseholderQR.
-  *
-  * This class supports the \link InplaceDecomposition inplace decomposition \endlink mechanism.
-  *
-  * \sa MatrixBase::householderQr()
-  */
-template<typename _MatrixType> class HouseholderQR
-{
-  public:
-
-    typedef _MatrixType MatrixType;
-    enum {
-      RowsAtCompileTime = MatrixType::RowsAtCompileTime,
-      ColsAtCompileTime = MatrixType::ColsAtCompileTime,
-      MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
-      MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
-    };
-    typedef typename MatrixType::Scalar Scalar;
-    typedef typename MatrixType::RealScalar RealScalar;
-    // FIXME should be int
-    typedef typename MatrixType::StorageIndex StorageIndex;
-    typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime, (MatrixType::Flags&RowMajorBit) ? RowMajor : ColMajor, MaxRowsAtCompileTime, MaxRowsAtCompileTime> MatrixQType;
-    typedef typename internal::plain_diag_type<MatrixType>::type HCoeffsType;
-    typedef typename internal::plain_row_type<MatrixType>::type RowVectorType;
-    typedef HouseholderSequence<MatrixType,typename internal::remove_all<typename HCoeffsType::ConjugateReturnType>::type> HouseholderSequenceType;
-
-    /**
-      * \brief Default Constructor.
-      *
-      * The default constructor is useful in cases in which the user intends to
-      * perform decompositions via HouseholderQR::compute(const MatrixType&).
-      */
-    HouseholderQR() : m_qr(), m_hCoeffs(), m_temp(), m_isInitialized(false) {}
-
-    /** \brief Default Constructor with memory preallocation
-      *
-      * Like the default constructor but with preallocation of the internal data
-      * according to the specified problem \a size.
-      * \sa HouseholderQR()
-      */
-    HouseholderQR(Index rows, Index cols)
-      : m_qr(rows, cols),
-        m_hCoeffs((std::min)(rows,cols)),
-        m_temp(cols),
-        m_isInitialized(false) {}
-
-    /** \brief Constructs a QR factorization from a given matrix
-      *
-      * This constructor computes the QR factorization of the matrix \a matrix by calling
-      * the method compute(). It is a short cut for:
-      * 
-      * \code
-      * HouseholderQR<MatrixType> qr(matrix.rows(), matrix.cols());
-      * qr.compute(matrix);
-      * \endcode
-      * 
-      * \sa compute()
-      */
-    template<typename InputType>
-    explicit HouseholderQR(const EigenBase<InputType>& matrix)
-      : m_qr(matrix.rows(), matrix.cols()),
-        m_hCoeffs((std::min)(matrix.rows(),matrix.cols())),
-        m_temp(matrix.cols()),
-        m_isInitialized(false)
-    {
-      compute(matrix.derived());
-    }
-
-
-    /** \brief Constructs a QR factorization from a given matrix
-      *
-      * This overloaded constructor is provided for \link InplaceDecomposition inplace decomposition \endlink when
-      * \c MatrixType is a Eigen::Ref.
-      *
-      * \sa HouseholderQR(const EigenBase&)
-      */
-    template<typename InputType>
-    explicit HouseholderQR(EigenBase<InputType>& matrix)
-      : m_qr(matrix.derived()),
-        m_hCoeffs((std::min)(matrix.rows(),matrix.cols())),
-        m_temp(matrix.cols()),
-        m_isInitialized(false)
-    {
-      computeInPlace();
-    }
-
-    /** This method finds a solution x to the equation Ax=b, where A is the matrix of which
-      * *this is the QR decomposition, if any exists.
-      *
-      * \param b the right-hand-side of the equation to solve.
-      *
-      * \returns a solution.
-      *
-      * \note_about_checking_solutions
-      *
-      * \note_about_arbitrary_choice_of_solution
-      *
-      * Example: \include HouseholderQR_solve.cpp
-      * Output: \verbinclude HouseholderQR_solve.out
-      */
-    template<typename Rhs>
-    inline const Solve<HouseholderQR, Rhs>
-    solve(const MatrixBase<Rhs>& b) const
-    {
-      eigen_assert(m_isInitialized && "HouseholderQR is not initialized.");
-      return Solve<HouseholderQR, Rhs>(*this, b.derived());
-    }
-
-    /** This method returns an expression of the unitary matrix Q as a sequence of Householder transformations.
-      *
-      * The returned expression can directly be used to perform matrix products. It can also be assigned to a dense Matrix object.
-      * Here is an example showing how to recover the full or thin matrix Q, as well as how to perform matrix products using operator*:
-      *
-      * Example: \include HouseholderQR_householderQ.cpp
-      * Output: \verbinclude HouseholderQR_householderQ.out
-      */
-    HouseholderSequenceType householderQ() const
-    {
-      eigen_assert(m_isInitialized && "HouseholderQR is not initialized.");
-      return HouseholderSequenceType(m_qr, m_hCoeffs.conjugate());
-    }
-
-    /** \returns a reference to the matrix where the Householder QR decomposition is stored
-      * in a LAPACK-compatible way.
-      */
-    const MatrixType& matrixQR() const
-    {
-        eigen_assert(m_isInitialized && "HouseholderQR is not initialized.");
-        return m_qr;
-    }
-
-    template<typename InputType>
-    HouseholderQR& compute(const EigenBase<InputType>& matrix) {
-      m_qr = matrix.derived();
-      computeInPlace();
-      return *this;
-    }
-
-    /** \returns the absolute value of the determinant of the matrix of which
-      * *this is the QR decomposition. It has only linear complexity
-      * (that is, O(n) where n is the dimension of the square matrix)
-      * as the QR decomposition has already been computed.
-      *
-      * \note This is only for square matrices.
-      *
-      * \warning a determinant can be very big or small, so for matrices
-      * of large enough dimension, there is a risk of overflow/underflow.
-      * One way to work around that is to use logAbsDeterminant() instead.
-      *
-      * \sa logAbsDeterminant(), MatrixBase::determinant()
-      */
-    typename MatrixType::RealScalar absDeterminant() const;
-
-    /** \returns the natural log of the absolute value of the determinant of the matrix of which
-      * *this is the QR decomposition. It has only linear complexity
-      * (that is, O(n) where n is the dimension of the square matrix)
-      * as the QR decomposition has already been computed.
-      *
-      * \note This is only for square matrices.
-      *
-      * \note This method is useful to work around the risk of overflow/underflow that's inherent
-      * to determinant computation.
-      *
-      * \sa absDeterminant(), MatrixBase::determinant()
-      */
-    typename MatrixType::RealScalar logAbsDeterminant() const;
-
-    inline Index rows() const { return m_qr.rows(); }
-    inline Index cols() const { return m_qr.cols(); }
-    
-    /** \returns a const reference to the vector of Householder coefficients used to represent the factor \c Q.
-      * 
-      * For advanced uses only.
-      */
-    const HCoeffsType& hCoeffs() const { return m_hCoeffs; }
-    
-    #ifndef EIGEN_PARSED_BY_DOXYGEN
-    template<typename RhsType, typename DstType>
-    EIGEN_DEVICE_FUNC
-    void _solve_impl(const RhsType &rhs, DstType &dst) const;
-    #endif
-
-  protected:
-    
-    static void check_template_parameters()
-    {
-      EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
-    }
-
-    void computeInPlace();
-    
-    MatrixType m_qr;
-    HCoeffsType m_hCoeffs;
-    RowVectorType m_temp;
-    bool m_isInitialized;
-};
-
-template<typename MatrixType>
-typename MatrixType::RealScalar HouseholderQR<MatrixType>::absDeterminant() const
-{
-  using std::abs;
-  eigen_assert(m_isInitialized && "HouseholderQR is not initialized.");
-  eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
-  return abs(m_qr.diagonal().prod());
-}
-
-template<typename MatrixType>
-typename MatrixType::RealScalar HouseholderQR<MatrixType>::logAbsDeterminant() const
-{
-  eigen_assert(m_isInitialized && "HouseholderQR is not initialized.");
-  eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
-  return m_qr.diagonal().cwiseAbs().array().log().sum();
-}
-
-namespace internal {
-
-/** \internal */
-template<typename MatrixQR, typename HCoeffs>
-void householder_qr_inplace_unblocked(MatrixQR& mat, HCoeffs& hCoeffs, typename MatrixQR::Scalar* tempData = 0)
-{
-  typedef typename MatrixQR::Scalar Scalar;
-  typedef typename MatrixQR::RealScalar RealScalar;
-  Index rows = mat.rows();
-  Index cols = mat.cols();
-  Index size = (std::min)(rows,cols);
-
-  eigen_assert(hCoeffs.size() == size);
-
-  typedef Matrix<Scalar,MatrixQR::ColsAtCompileTime,1> TempType;
-  TempType tempVector;
-  if(tempData==0)
-  {
-    tempVector.resize(cols);
-    tempData = tempVector.data();
-  }
-
-  for(Index k = 0; k < size; ++k)
-  {
-    Index remainingRows = rows - k;
-    Index remainingCols = cols - k - 1;
-
-    RealScalar beta;
-    mat.col(k).tail(remainingRows).makeHouseholderInPlace(hCoeffs.coeffRef(k), beta);
-    mat.coeffRef(k,k) = beta;
-
-    // apply H to remaining part of m_qr from the left
-    mat.bottomRightCorner(remainingRows, remainingCols)
-        .applyHouseholderOnTheLeft(mat.col(k).tail(remainingRows-1), hCoeffs.coeffRef(k), tempData+k+1);
-  }
-}
-
-/** \internal */
-template<typename MatrixQR, typename HCoeffs,
-  typename MatrixQRScalar = typename MatrixQR::Scalar,
-  bool InnerStrideIsOne = (MatrixQR::InnerStrideAtCompileTime == 1 && HCoeffs::InnerStrideAtCompileTime == 1)>
-struct householder_qr_inplace_blocked
-{
-  // This is specialized for MKL-supported Scalar types in HouseholderQR_MKL.h
-  static void run(MatrixQR& mat, HCoeffs& hCoeffs, Index maxBlockSize=32,
-      typename MatrixQR::Scalar* tempData = 0)
-  {
-    typedef typename MatrixQR::Scalar Scalar;
-    typedef Block<MatrixQR,Dynamic,Dynamic> BlockType;
-
-    Index rows = mat.rows();
-    Index cols = mat.cols();
-    Index size = (std::min)(rows, cols);
-
-    typedef Matrix<Scalar,Dynamic,1,ColMajor,MatrixQR::MaxColsAtCompileTime,1> TempType;
-    TempType tempVector;
-    if(tempData==0)
-    {
-      tempVector.resize(cols);
-      tempData = tempVector.data();
-    }
-
-    Index blockSize = (std::min)(maxBlockSize,size);
-
-    Index k = 0;
-    for (k = 0; k < size; k += blockSize)
-    {
-      Index bs = (std::min)(size-k,blockSize);  // actual size of the block
-      Index tcols = cols - k - bs;              // trailing columns
-      Index brows = rows-k;                     // rows of the block
-
-      // partition the matrix:
-      //        A00 | A01 | A02
-      // mat  = A10 | A11 | A12
-      //        A20 | A21 | A22
-      // and performs the qr dec of [A11^T A12^T]^T
-      // and update [A21^T A22^T]^T using level 3 operations.
-      // Finally, the algorithm continue on A22
-
-      BlockType A11_21 = mat.block(k,k,brows,bs);
-      Block<HCoeffs,Dynamic,1> hCoeffsSegment = hCoeffs.segment(k,bs);
-
-      householder_qr_inplace_unblocked(A11_21, hCoeffsSegment, tempData);
-
-      if(tcols)
-      {
-        BlockType A21_22 = mat.block(k,k+bs,brows,tcols);
-        apply_block_householder_on_the_left(A21_22,A11_21,hCoeffsSegment, false); // false == backward
-      }
-    }
-  }
-};
-
-} // end namespace internal
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-template<typename _MatrixType>
-template<typename RhsType, typename DstType>
-void HouseholderQR<_MatrixType>::_solve_impl(const RhsType &rhs, DstType &dst) const
-{
-  const Index rank = (std::min)(rows(), cols());
-  eigen_assert(rhs.rows() == rows());
-
-  typename RhsType::PlainObject c(rhs);
-
-  // Note that the matrix Q = H_0^* H_1^*... so its inverse is Q^* = (H_0 H_1 ...)^T
-  c.applyOnTheLeft(householderSequence(
-    m_qr.leftCols(rank),
-    m_hCoeffs.head(rank)).transpose()
-  );
-
-  m_qr.topLeftCorner(rank, rank)
-      .template triangularView<Upper>()
-      .solveInPlace(c.topRows(rank));
-
-  dst.topRows(rank) = c.topRows(rank);
-  dst.bottomRows(cols()-rank).setZero();
-}
-#endif
-
-/** Performs the QR factorization of the given matrix \a matrix. The result of
-  * the factorization is stored into \c *this, and a reference to \c *this
-  * is returned.
-  *
-  * \sa class HouseholderQR, HouseholderQR(const MatrixType&)
-  */
-template<typename MatrixType>
-void HouseholderQR<MatrixType>::computeInPlace()
-{
-  check_template_parameters();
-  
-  Index rows = m_qr.rows();
-  Index cols = m_qr.cols();
-  Index size = (std::min)(rows,cols);
-
-  m_hCoeffs.resize(size);
-
-  m_temp.resize(cols);
-
-  internal::householder_qr_inplace_blocked<MatrixType, HCoeffsType>::run(m_qr, m_hCoeffs, 48, m_temp.data());
-
-  m_isInitialized = true;
-}
-
-/** \return the Householder QR decomposition of \c *this.
-  *
-  * \sa class HouseholderQR
-  */
-template<typename Derived>
-const HouseholderQR<typename MatrixBase<Derived>::PlainObject>
-MatrixBase<Derived>::householderQr() const
-{
-  return HouseholderQR<PlainObject>(eval());
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_QR_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/SVD/BDCSVD.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/SVD/BDCSVD.h
deleted file mode 100644
index 1134d66..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/SVD/BDCSVD.h
+++ /dev/null
@@ -1,1246 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-// 
-// We used the "A Divide-And-Conquer Algorithm for the Bidiagonal SVD"
-// research report written by Ming Gu and Stanley C.Eisenstat
-// The code variable names correspond to the names they used in their 
-// report
-//
-// Copyright (C) 2013 Gauthier Brun <brun.gauthier@gmail.com>
-// Copyright (C) 2013 Nicolas Carre <nicolas.carre@ensimag.fr>
-// Copyright (C) 2013 Jean Ceccato <jean.ceccato@ensimag.fr>
-// Copyright (C) 2013 Pierre Zoppitelli <pierre.zoppitelli@ensimag.fr>
-// Copyright (C) 2013 Jitse Niesen <jitse@maths.leeds.ac.uk>
-// Copyright (C) 2014-2017 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_BDCSVD_H
-#define EIGEN_BDCSVD_H
-// #define EIGEN_BDCSVD_DEBUG_VERBOSE
-// #define EIGEN_BDCSVD_SANITY_CHECKS
-
-namespace Eigen {
-
-#ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
-IOFormat bdcsvdfmt(8, 0, ", ", "\n", "  [", "]");
-#endif
-  
-template<typename _MatrixType> class BDCSVD;
-
-namespace internal {
-
-template<typename _MatrixType> 
-struct traits<BDCSVD<_MatrixType> >
-{
-  typedef _MatrixType MatrixType;
-};  
-
-} // end namespace internal
-  
-  
-/** \ingroup SVD_Module
- *
- *
- * \class BDCSVD
- *
- * \brief class Bidiagonal Divide and Conquer SVD
- *
- * \tparam _MatrixType the type of the matrix of which we are computing the SVD decomposition
- *
- * This class first reduces the input matrix to bi-diagonal form using class UpperBidiagonalization,
- * and then performs a divide-and-conquer diagonalization. Small blocks are diagonalized using class JacobiSVD.
- * You can control the switching size with the setSwitchSize() method, default is 16.
- * For small matrice (<16), it is thus preferable to directly use JacobiSVD. For larger ones, BDCSVD is highly
- * recommended and can several order of magnitude faster.
- *
- * \warning this algorithm is unlikely to provide accurate result when compiled with unsafe math optimizations.
- * For instance, this concerns Intel's compiler (ICC), which perfroms such optimization by default unless
- * you compile with the \c -fp-model \c precise option. Likewise, the \c -ffast-math option of GCC or clang will
- * significantly degrade the accuracy.
- *
- * \sa class JacobiSVD
- */
-template<typename _MatrixType> 
-class BDCSVD : public SVDBase<BDCSVD<_MatrixType> >
-{
-  typedef SVDBase<BDCSVD> Base;
-    
-public:
-  using Base::rows;
-  using Base::cols;
-  using Base::computeU;
-  using Base::computeV;
-  
-  typedef _MatrixType MatrixType;
-  typedef typename MatrixType::Scalar Scalar;
-  typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
-  typedef typename NumTraits<RealScalar>::Literal Literal;
-  enum {
-    RowsAtCompileTime = MatrixType::RowsAtCompileTime, 
-    ColsAtCompileTime = MatrixType::ColsAtCompileTime, 
-    DiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime, ColsAtCompileTime), 
-    MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, 
-    MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, 
-    MaxDiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(MaxRowsAtCompileTime, MaxColsAtCompileTime), 
-    MatrixOptions = MatrixType::Options
-  };
-
-  typedef typename Base::MatrixUType MatrixUType;
-  typedef typename Base::MatrixVType MatrixVType;
-  typedef typename Base::SingularValuesType SingularValuesType;
-  
-  typedef Matrix<Scalar, Dynamic, Dynamic, ColMajor> MatrixX;
-  typedef Matrix<RealScalar, Dynamic, Dynamic, ColMajor> MatrixXr;
-  typedef Matrix<RealScalar, Dynamic, 1> VectorType;
-  typedef Array<RealScalar, Dynamic, 1> ArrayXr;
-  typedef Array<Index,1,Dynamic> ArrayXi;
-  typedef Ref<ArrayXr> ArrayRef;
-  typedef Ref<ArrayXi> IndicesRef;
-
-  /** \brief Default Constructor.
-   *
-   * The default constructor is useful in cases in which the user intends to
-   * perform decompositions via BDCSVD::compute(const MatrixType&).
-   */
-  BDCSVD() : m_algoswap(16), m_numIters(0)
-  {}
-
-
-  /** \brief Default Constructor with memory preallocation
-   *
-   * Like the default constructor but with preallocation of the internal data
-   * according to the specified problem size.
-   * \sa BDCSVD()
-   */
-  BDCSVD(Index rows, Index cols, unsigned int computationOptions = 0)
-    : m_algoswap(16), m_numIters(0)
-  {
-    allocate(rows, cols, computationOptions);
-  }
-
-  /** \brief Constructor performing the decomposition of given matrix.
-   *
-   * \param matrix the matrix to decompose
-   * \param computationOptions optional parameter allowing to specify if you want full or thin U or V unitaries to be computed.
-   *                           By default, none is computed. This is a bit - field, the possible bits are #ComputeFullU, #ComputeThinU, 
-   *                           #ComputeFullV, #ComputeThinV.
-   *
-   * Thin unitaries are only available if your matrix type has a Dynamic number of columns (for example MatrixXf). They also are not
-   * available with the (non - default) FullPivHouseholderQR preconditioner.
-   */
-  BDCSVD(const MatrixType& matrix, unsigned int computationOptions = 0)
-    : m_algoswap(16), m_numIters(0)
-  {
-    compute(matrix, computationOptions);
-  }
-
-  ~BDCSVD() 
-  {
-  }
-  
-  /** \brief Method performing the decomposition of given matrix using custom options.
-   *
-   * \param matrix the matrix to decompose
-   * \param computationOptions optional parameter allowing to specify if you want full or thin U or V unitaries to be computed.
-   *                           By default, none is computed. This is a bit - field, the possible bits are #ComputeFullU, #ComputeThinU, 
-   *                           #ComputeFullV, #ComputeThinV.
-   *
-   * Thin unitaries are only available if your matrix type has a Dynamic number of columns (for example MatrixXf). They also are not
-   * available with the (non - default) FullPivHouseholderQR preconditioner.
-   */
-  BDCSVD& compute(const MatrixType& matrix, unsigned int computationOptions);
-
-  /** \brief Method performing the decomposition of given matrix using current options.
-   *
-   * \param matrix the matrix to decompose
-   *
-   * This method uses the current \a computationOptions, as already passed to the constructor or to compute(const MatrixType&, unsigned int).
-   */
-  BDCSVD& compute(const MatrixType& matrix)
-  {
-    return compute(matrix, this->m_computationOptions);
-  }
-
-  void setSwitchSize(int s) 
-  {
-    eigen_assert(s>3 && "BDCSVD the size of the algo switch has to be greater than 3");
-    m_algoswap = s;
-  }
- 
-private:
-  void allocate(Index rows, Index cols, unsigned int computationOptions);
-  void divide(Index firstCol, Index lastCol, Index firstRowW, Index firstColW, Index shift);
-  void computeSVDofM(Index firstCol, Index n, MatrixXr& U, VectorType& singVals, MatrixXr& V);
-  void computeSingVals(const ArrayRef& col0, const ArrayRef& diag, const IndicesRef& perm, VectorType& singVals, ArrayRef shifts, ArrayRef mus);
-  void perturbCol0(const ArrayRef& col0, const ArrayRef& diag, const IndicesRef& perm, const VectorType& singVals, const ArrayRef& shifts, const ArrayRef& mus, ArrayRef zhat);
-  void computeSingVecs(const ArrayRef& zhat, const ArrayRef& diag, const IndicesRef& perm, const VectorType& singVals, const ArrayRef& shifts, const ArrayRef& mus, MatrixXr& U, MatrixXr& V);
-  void deflation43(Index firstCol, Index shift, Index i, Index size);
-  void deflation44(Index firstColu , Index firstColm, Index firstRowW, Index firstColW, Index i, Index j, Index size);
-  void deflation(Index firstCol, Index lastCol, Index k, Index firstRowW, Index firstColW, Index shift);
-  template<typename HouseholderU, typename HouseholderV, typename NaiveU, typename NaiveV>
-  void copyUV(const HouseholderU &householderU, const HouseholderV &householderV, const NaiveU &naiveU, const NaiveV &naivev);
-  void structured_update(Block<MatrixXr,Dynamic,Dynamic> A, const MatrixXr &B, Index n1);
-  static RealScalar secularEq(RealScalar x, const ArrayRef& col0, const ArrayRef& diag, const IndicesRef &perm, const ArrayRef& diagShifted, RealScalar shift);
-
-protected:
-  MatrixXr m_naiveU, m_naiveV;
-  MatrixXr m_computed;
-  Index m_nRec;
-  ArrayXr m_workspace;
-  ArrayXi m_workspaceI;
-  int m_algoswap;
-  bool m_isTranspose, m_compU, m_compV;
-  
-  using Base::m_singularValues;
-  using Base::m_diagSize;
-  using Base::m_computeFullU;
-  using Base::m_computeFullV;
-  using Base::m_computeThinU;
-  using Base::m_computeThinV;
-  using Base::m_matrixU;
-  using Base::m_matrixV;
-  using Base::m_isInitialized;
-  using Base::m_nonzeroSingularValues;
-
-public:  
-  int m_numIters;
-}; //end class BDCSVD
-
-
-// Method to allocate and initialize matrix and attributes
-template<typename MatrixType>
-void BDCSVD<MatrixType>::allocate(Index rows, Index cols, unsigned int computationOptions)
-{
-  m_isTranspose = (cols > rows);
-
-  if (Base::allocate(rows, cols, computationOptions))
-    return;
-  
-  m_computed = MatrixXr::Zero(m_diagSize + 1, m_diagSize );
-  m_compU = computeV();
-  m_compV = computeU();
-  if (m_isTranspose)
-    std::swap(m_compU, m_compV);
-  
-  if (m_compU) m_naiveU = MatrixXr::Zero(m_diagSize + 1, m_diagSize + 1 );
-  else         m_naiveU = MatrixXr::Zero(2, m_diagSize + 1 );
-  
-  if (m_compV) m_naiveV = MatrixXr::Zero(m_diagSize, m_diagSize);
-  
-  m_workspace.resize((m_diagSize+1)*(m_diagSize+1)*3);
-  m_workspaceI.resize(3*m_diagSize);
-}// end allocate
-
-template<typename MatrixType>
-BDCSVD<MatrixType>& BDCSVD<MatrixType>::compute(const MatrixType& matrix, unsigned int computationOptions) 
-{
-#ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
-  std::cout << "\n\n\n======================================================================================================================\n\n\n";
-#endif
-  allocate(matrix.rows(), matrix.cols(), computationOptions);
-  using std::abs;
-
-  const RealScalar considerZero = (std::numeric_limits<RealScalar>::min)();
-  
-  //**** step -1 - If the problem is too small, directly falls back to JacobiSVD and return
-  if(matrix.cols() < m_algoswap)
-  {
-    // FIXME this line involves temporaries
-    JacobiSVD<MatrixType> jsvd(matrix,computationOptions);
-    if(computeU()) m_matrixU = jsvd.matrixU();
-    if(computeV()) m_matrixV = jsvd.matrixV();
-    m_singularValues = jsvd.singularValues();
-    m_nonzeroSingularValues = jsvd.nonzeroSingularValues();
-    m_isInitialized = true;
-    return *this;
-  }
-  
-  //**** step 0 - Copy the input matrix and apply scaling to reduce over/under-flows
-  RealScalar scale = matrix.cwiseAbs().maxCoeff();
-  if(scale==Literal(0)) scale = Literal(1);
-  MatrixX copy;
-  if (m_isTranspose) copy = matrix.adjoint()/scale;
-  else               copy = matrix/scale;
-  
-  //**** step 1 - Bidiagonalization
-  // FIXME this line involves temporaries
-  internal::UpperBidiagonalization<MatrixX> bid(copy);
-
-  //**** step 2 - Divide & Conquer
-  m_naiveU.setZero();
-  m_naiveV.setZero();
-  // FIXME this line involves a temporary matrix
-  m_computed.topRows(m_diagSize) = bid.bidiagonal().toDenseMatrix().transpose();
-  m_computed.template bottomRows<1>().setZero();
-  divide(0, m_diagSize - 1, 0, 0, 0);
-
-  //**** step 3 - Copy singular values and vectors
-  for (int i=0; i<m_diagSize; i++)
-  {
-    RealScalar a = abs(m_computed.coeff(i, i));
-    m_singularValues.coeffRef(i) = a * scale;
-    if (a<considerZero)
-    {
-      m_nonzeroSingularValues = i;
-      m_singularValues.tail(m_diagSize - i - 1).setZero();
-      break;
-    }
-    else if (i == m_diagSize - 1)
-    {
-      m_nonzeroSingularValues = i + 1;
-      break;
-    }
-  }
-
-#ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
-//   std::cout << "m_naiveU\n" << m_naiveU << "\n\n";
-//   std::cout << "m_naiveV\n" << m_naiveV << "\n\n";
-#endif
-  if(m_isTranspose) copyUV(bid.householderV(), bid.householderU(), m_naiveV, m_naiveU);
-  else              copyUV(bid.householderU(), bid.householderV(), m_naiveU, m_naiveV);
-
-  m_isInitialized = true;
-  return *this;
-}// end compute
-
-
-template<typename MatrixType>
-template<typename HouseholderU, typename HouseholderV, typename NaiveU, typename NaiveV>
-void BDCSVD<MatrixType>::copyUV(const HouseholderU &householderU, const HouseholderV &householderV, const NaiveU &naiveU, const NaiveV &naiveV)
-{
-  // Note exchange of U and V: m_matrixU is set from m_naiveV and vice versa
-  if (computeU())
-  {
-    Index Ucols = m_computeThinU ? m_diagSize : householderU.cols();
-    m_matrixU = MatrixX::Identity(householderU.cols(), Ucols);
-    m_matrixU.topLeftCorner(m_diagSize, m_diagSize) = naiveV.template cast<Scalar>().topLeftCorner(m_diagSize, m_diagSize);
-    householderU.applyThisOnTheLeft(m_matrixU); // FIXME this line involves a temporary buffer
-  }
-  if (computeV())
-  {
-    Index Vcols = m_computeThinV ? m_diagSize : householderV.cols();
-    m_matrixV = MatrixX::Identity(householderV.cols(), Vcols);
-    m_matrixV.topLeftCorner(m_diagSize, m_diagSize) = naiveU.template cast<Scalar>().topLeftCorner(m_diagSize, m_diagSize);
-    householderV.applyThisOnTheLeft(m_matrixV); // FIXME this line involves a temporary buffer
-  }
-}
-
-/** \internal
-  * Performs A = A * B exploiting the special structure of the matrix A. Splitting A as:
-  *  A = [A1]
-  *      [A2]
-  * such that A1.rows()==n1, then we assume that at least half of the columns of A1 and A2 are zeros.
-  * We can thus pack them prior to the the matrix product. However, this is only worth the effort if the matrix is large
-  * enough.
-  */
-template<typename MatrixType>
-void BDCSVD<MatrixType>::structured_update(Block<MatrixXr,Dynamic,Dynamic> A, const MatrixXr &B, Index n1)
-{
-  Index n = A.rows();
-  if(n>100)
-  {
-    // If the matrices are large enough, let's exploit the sparse structure of A by
-    // splitting it in half (wrt n1), and packing the non-zero columns.
-    Index n2 = n - n1;
-    Map<MatrixXr> A1(m_workspace.data()      , n1, n);
-    Map<MatrixXr> A2(m_workspace.data()+ n1*n, n2, n);
-    Map<MatrixXr> B1(m_workspace.data()+  n*n, n,  n);
-    Map<MatrixXr> B2(m_workspace.data()+2*n*n, n,  n);
-    Index k1=0, k2=0;
-    for(Index j=0; j<n; ++j)
-    {
-      if( (A.col(j).head(n1).array()!=Literal(0)).any() )
-      {
-        A1.col(k1) = A.col(j).head(n1);
-        B1.row(k1) = B.row(j);
-        ++k1;
-      }
-      if( (A.col(j).tail(n2).array()!=Literal(0)).any() )
-      {
-        A2.col(k2) = A.col(j).tail(n2);
-        B2.row(k2) = B.row(j);
-        ++k2;
-      }
-    }
-  
-    A.topRows(n1).noalias()    = A1.leftCols(k1) * B1.topRows(k1);
-    A.bottomRows(n2).noalias() = A2.leftCols(k2) * B2.topRows(k2);
-  }
-  else
-  {
-    Map<MatrixXr,Aligned> tmp(m_workspace.data(),n,n);
-    tmp.noalias() = A*B;
-    A = tmp;
-  }
-}
-
-// The divide algorithm is done "in place", we are always working on subsets of the same matrix. The divide methods takes as argument the 
-// place of the submatrix we are currently working on.
-
-//@param firstCol : The Index of the first column of the submatrix of m_computed and for m_naiveU;
-//@param lastCol : The Index of the last column of the submatrix of m_computed and for m_naiveU; 
-// lastCol + 1 - firstCol is the size of the submatrix.
-//@param firstRowW : The Index of the first row of the matrix W that we are to change. (see the reference paper section 1 for more information on W)
-//@param firstRowW : Same as firstRowW with the column.
-//@param shift : Each time one takes the left submatrix, one must add 1 to the shift. Why? Because! We actually want the last column of the U submatrix 
-// to become the first column (*coeff) and to shift all the other columns to the right. There are more details on the reference paper.
-template<typename MatrixType>
-void BDCSVD<MatrixType>::divide (Index firstCol, Index lastCol, Index firstRowW, Index firstColW, Index shift)
-{
-  // requires rows = cols + 1;
-  using std::pow;
-  using std::sqrt;
-  using std::abs;
-  const Index n = lastCol - firstCol + 1;
-  const Index k = n/2;
-  const RealScalar considerZero = (std::numeric_limits<RealScalar>::min)();
-  RealScalar alphaK;
-  RealScalar betaK; 
-  RealScalar r0; 
-  RealScalar lambda, phi, c0, s0;
-  VectorType l, f;
-  // We use the other algorithm which is more efficient for small 
-  // matrices.
-  if (n < m_algoswap)
-  {
-    // FIXME this line involves temporaries
-    JacobiSVD<MatrixXr> b(m_computed.block(firstCol, firstCol, n + 1, n), ComputeFullU | (m_compV ? ComputeFullV : 0));
-    if (m_compU)
-      m_naiveU.block(firstCol, firstCol, n + 1, n + 1).real() = b.matrixU();
-    else 
-    {
-      m_naiveU.row(0).segment(firstCol, n + 1).real() = b.matrixU().row(0);
-      m_naiveU.row(1).segment(firstCol, n + 1).real() = b.matrixU().row(n);
-    }
-    if (m_compV) m_naiveV.block(firstRowW, firstColW, n, n).real() = b.matrixV();
-    m_computed.block(firstCol + shift, firstCol + shift, n + 1, n).setZero();
-    m_computed.diagonal().segment(firstCol + shift, n) = b.singularValues().head(n);
-    return;
-  }
-  // We use the divide and conquer algorithm
-  alphaK =  m_computed(firstCol + k, firstCol + k);
-  betaK = m_computed(firstCol + k + 1, firstCol + k);
-  // The divide must be done in that order in order to have good results. Divide change the data inside the submatrices
-  // and the divide of the right submatrice reads one column of the left submatrice. That's why we need to treat the 
-  // right submatrix before the left one. 
-  divide(k + 1 + firstCol, lastCol, k + 1 + firstRowW, k + 1 + firstColW, shift);
-  divide(firstCol, k - 1 + firstCol, firstRowW, firstColW + 1, shift + 1);
-
-  if (m_compU)
-  {
-    lambda = m_naiveU(firstCol + k, firstCol + k);
-    phi = m_naiveU(firstCol + k + 1, lastCol + 1);
-  } 
-  else 
-  {
-    lambda = m_naiveU(1, firstCol + k);
-    phi = m_naiveU(0, lastCol + 1);
-  }
-  r0 = sqrt((abs(alphaK * lambda) * abs(alphaK * lambda)) + abs(betaK * phi) * abs(betaK * phi));
-  if (m_compU)
-  {
-    l = m_naiveU.row(firstCol + k).segment(firstCol, k);
-    f = m_naiveU.row(firstCol + k + 1).segment(firstCol + k + 1, n - k - 1);
-  } 
-  else 
-  {
-    l = m_naiveU.row(1).segment(firstCol, k);
-    f = m_naiveU.row(0).segment(firstCol + k + 1, n - k - 1);
-  }
-  if (m_compV) m_naiveV(firstRowW+k, firstColW) = Literal(1);
-  if (r0<considerZero)
-  {
-    c0 = Literal(1);
-    s0 = Literal(0);
-  }
-  else
-  {
-    c0 = alphaK * lambda / r0;
-    s0 = betaK * phi / r0;
-  }
-  
-#ifdef EIGEN_BDCSVD_SANITY_CHECKS
-  assert(m_naiveU.allFinite());
-  assert(m_naiveV.allFinite());
-  assert(m_computed.allFinite());
-#endif
-  
-  if (m_compU)
-  {
-    MatrixXr q1 (m_naiveU.col(firstCol + k).segment(firstCol, k + 1));     
-    // we shiftW Q1 to the right
-    for (Index i = firstCol + k - 1; i >= firstCol; i--) 
-      m_naiveU.col(i + 1).segment(firstCol, k + 1) = m_naiveU.col(i).segment(firstCol, k + 1);
-    // we shift q1 at the left with a factor c0
-    m_naiveU.col(firstCol).segment( firstCol, k + 1) = (q1 * c0);
-    // last column = q1 * - s0
-    m_naiveU.col(lastCol + 1).segment(firstCol, k + 1) = (q1 * ( - s0));
-    // first column = q2 * s0
-    m_naiveU.col(firstCol).segment(firstCol + k + 1, n - k) = m_naiveU.col(lastCol + 1).segment(firstCol + k + 1, n - k) * s0; 
-    // q2 *= c0
-    m_naiveU.col(lastCol + 1).segment(firstCol + k + 1, n - k) *= c0;
-  } 
-  else 
-  {
-    RealScalar q1 = m_naiveU(0, firstCol + k);
-    // we shift Q1 to the right
-    for (Index i = firstCol + k - 1; i >= firstCol; i--) 
-      m_naiveU(0, i + 1) = m_naiveU(0, i);
-    // we shift q1 at the left with a factor c0
-    m_naiveU(0, firstCol) = (q1 * c0);
-    // last column = q1 * - s0
-    m_naiveU(0, lastCol + 1) = (q1 * ( - s0));
-    // first column = q2 * s0
-    m_naiveU(1, firstCol) = m_naiveU(1, lastCol + 1) *s0; 
-    // q2 *= c0
-    m_naiveU(1, lastCol + 1) *= c0;
-    m_naiveU.row(1).segment(firstCol + 1, k).setZero();
-    m_naiveU.row(0).segment(firstCol + k + 1, n - k - 1).setZero();
-  }
-  
-#ifdef EIGEN_BDCSVD_SANITY_CHECKS
-  assert(m_naiveU.allFinite());
-  assert(m_naiveV.allFinite());
-  assert(m_computed.allFinite());
-#endif
-  
-  m_computed(firstCol + shift, firstCol + shift) = r0;
-  m_computed.col(firstCol + shift).segment(firstCol + shift + 1, k) = alphaK * l.transpose().real();
-  m_computed.col(firstCol + shift).segment(firstCol + shift + k + 1, n - k - 1) = betaK * f.transpose().real();
-
-#ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
-  ArrayXr tmp1 = (m_computed.block(firstCol+shift, firstCol+shift, n, n)).jacobiSvd().singularValues();
-#endif
-  // Second part: try to deflate singular values in combined matrix
-  deflation(firstCol, lastCol, k, firstRowW, firstColW, shift);
-#ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
-  ArrayXr tmp2 = (m_computed.block(firstCol+shift, firstCol+shift, n, n)).jacobiSvd().singularValues();
-  std::cout << "\n\nj1 = " << tmp1.transpose().format(bdcsvdfmt) << "\n";
-  std::cout << "j2 = " << tmp2.transpose().format(bdcsvdfmt) << "\n\n";
-  std::cout << "err:      " << ((tmp1-tmp2).abs()>1e-12*tmp2.abs()).transpose() << "\n";
-  static int count = 0;
-  std::cout << "# " << ++count << "\n\n";
-  assert((tmp1-tmp2).matrix().norm() < 1e-14*tmp2.matrix().norm());
-//   assert(count<681);
-//   assert(((tmp1-tmp2).abs()<1e-13*tmp2.abs()).all());
-#endif
-  
-  // Third part: compute SVD of combined matrix
-  MatrixXr UofSVD, VofSVD;
-  VectorType singVals;
-  computeSVDofM(firstCol + shift, n, UofSVD, singVals, VofSVD);
-  
-#ifdef EIGEN_BDCSVD_SANITY_CHECKS
-  assert(UofSVD.allFinite());
-  assert(VofSVD.allFinite());
-#endif
-  
-  if (m_compU)
-    structured_update(m_naiveU.block(firstCol, firstCol, n + 1, n + 1), UofSVD, (n+2)/2);
-  else
-  {
-    Map<Matrix<RealScalar,2,Dynamic>,Aligned> tmp(m_workspace.data(),2,n+1);
-    tmp.noalias() = m_naiveU.middleCols(firstCol, n+1) * UofSVD;
-    m_naiveU.middleCols(firstCol, n + 1) = tmp;
-  }
-  
-  if (m_compV)  structured_update(m_naiveV.block(firstRowW, firstColW, n, n), VofSVD, (n+1)/2);
-  
-#ifdef EIGEN_BDCSVD_SANITY_CHECKS
-  assert(m_naiveU.allFinite());
-  assert(m_naiveV.allFinite());
-  assert(m_computed.allFinite());
-#endif
-  
-  m_computed.block(firstCol + shift, firstCol + shift, n, n).setZero();
-  m_computed.block(firstCol + shift, firstCol + shift, n, n).diagonal() = singVals;
-}// end divide
-
-// Compute SVD of m_computed.block(firstCol, firstCol, n + 1, n); this block only has non-zeros in
-// the first column and on the diagonal and has undergone deflation, so diagonal is in increasing
-// order except for possibly the (0,0) entry. The computed SVD is stored U, singVals and V, except
-// that if m_compV is false, then V is not computed. Singular values are sorted in decreasing order.
-//
-// TODO Opportunities for optimization: better root finding algo, better stopping criterion, better
-// handling of round-off errors, be consistent in ordering
-// For instance, to solve the secular equation using FMM, see http://www.stat.uchicago.edu/~lekheng/courses/302/classics/greengard-rokhlin.pdf
-template <typename MatrixType>
-void BDCSVD<MatrixType>::computeSVDofM(Index firstCol, Index n, MatrixXr& U, VectorType& singVals, MatrixXr& V)
-{
-  const RealScalar considerZero = (std::numeric_limits<RealScalar>::min)();
-  using std::abs;
-  ArrayRef col0 = m_computed.col(firstCol).segment(firstCol, n);
-  m_workspace.head(n) =  m_computed.block(firstCol, firstCol, n, n).diagonal();
-  ArrayRef diag = m_workspace.head(n);
-  diag(0) = Literal(0);
-
-  // Allocate space for singular values and vectors
-  singVals.resize(n);
-  U.resize(n+1, n+1);
-  if (m_compV) V.resize(n, n);
-
-#ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
-  if (col0.hasNaN() || diag.hasNaN())
-    std::cout << "\n\nHAS NAN\n\n";
-#endif
-  
-  // Many singular values might have been deflated, the zero ones have been moved to the end,
-  // but others are interleaved and we must ignore them at this stage.
-  // To this end, let's compute a permutation skipping them:
-  Index actual_n = n;
-  while(actual_n>1 && diag(actual_n-1)==Literal(0)) --actual_n;
-  Index m = 0; // size of the deflated problem
-  for(Index k=0;k<actual_n;++k)
-    if(abs(col0(k))>considerZero)
-      m_workspaceI(m++) = k;
-  Map<ArrayXi> perm(m_workspaceI.data(),m);
-  
-  Map<ArrayXr> shifts(m_workspace.data()+1*n, n);
-  Map<ArrayXr> mus(m_workspace.data()+2*n, n);
-  Map<ArrayXr> zhat(m_workspace.data()+3*n, n);
-
-#ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
-  std::cout << "computeSVDofM using:\n";
-  std::cout << "  z: " << col0.transpose() << "\n";
-  std::cout << "  d: " << diag.transpose() << "\n";
-#endif
-  
-  // Compute singVals, shifts, and mus
-  computeSingVals(col0, diag, perm, singVals, shifts, mus);
-  
-#ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
-  std::cout << "  j:        " << (m_computed.block(firstCol, firstCol, n, n)).jacobiSvd().singularValues().transpose().reverse() << "\n\n";
-  std::cout << "  sing-val: " << singVals.transpose() << "\n";
-  std::cout << "  mu:       " << mus.transpose() << "\n";
-  std::cout << "  shift:    " << shifts.transpose() << "\n";
-  
-  {
-    Index actual_n = n;
-    while(actual_n>1 && abs(col0(actual_n-1))<considerZero) --actual_n;
-    std::cout << "\n\n    mus:    " << mus.head(actual_n).transpose() << "\n\n";
-    std::cout << "    check1 (expect0) : " << ((singVals.array()-(shifts+mus)) / singVals.array()).head(actual_n).transpose() << "\n\n";
-    std::cout << "    check2 (>0)      : " << ((singVals.array()-diag) / singVals.array()).head(actual_n).transpose() << "\n\n";
-    std::cout << "    check3 (>0)      : " << ((diag.segment(1,actual_n-1)-singVals.head(actual_n-1).array()) / singVals.head(actual_n-1).array()).transpose() << "\n\n\n";
-    std::cout << "    check4 (>0)      : " << ((singVals.segment(1,actual_n-1)-singVals.head(actual_n-1))).transpose() << "\n\n\n";
-  }
-#endif
-  
-#ifdef EIGEN_BDCSVD_SANITY_CHECKS
-  assert(singVals.allFinite());
-  assert(mus.allFinite());
-  assert(shifts.allFinite());
-#endif
-  
-  // Compute zhat
-  perturbCol0(col0, diag, perm, singVals, shifts, mus, zhat);
-#ifdef  EIGEN_BDCSVD_DEBUG_VERBOSE
-  std::cout << "  zhat: " << zhat.transpose() << "\n";
-#endif
-  
-#ifdef EIGEN_BDCSVD_SANITY_CHECKS
-  assert(zhat.allFinite());
-#endif
-  
-  computeSingVecs(zhat, diag, perm, singVals, shifts, mus, U, V);
-  
-#ifdef  EIGEN_BDCSVD_DEBUG_VERBOSE
-  std::cout << "U^T U: " << (U.transpose() * U - MatrixXr(MatrixXr::Identity(U.cols(),U.cols()))).norm() << "\n";
-  std::cout << "V^T V: " << (V.transpose() * V - MatrixXr(MatrixXr::Identity(V.cols(),V.cols()))).norm() << "\n";
-#endif
-  
-#ifdef EIGEN_BDCSVD_SANITY_CHECKS
-  assert(U.allFinite());
-  assert(V.allFinite());
-  assert((U.transpose() * U - MatrixXr(MatrixXr::Identity(U.cols(),U.cols()))).norm() < 1e-14 * n);
-  assert((V.transpose() * V - MatrixXr(MatrixXr::Identity(V.cols(),V.cols()))).norm() < 1e-14 * n);
-  assert(m_naiveU.allFinite());
-  assert(m_naiveV.allFinite());
-  assert(m_computed.allFinite());
-#endif
-  
-  // Because of deflation, the singular values might not be completely sorted.
-  // Fortunately, reordering them is a O(n) problem
-  for(Index i=0; i<actual_n-1; ++i)
-  {
-    if(singVals(i)>singVals(i+1))
-    {
-      using std::swap;
-      swap(singVals(i),singVals(i+1));
-      U.col(i).swap(U.col(i+1));
-      if(m_compV) V.col(i).swap(V.col(i+1));
-    }
-  }
-  
-  // Reverse order so that singular values in increased order
-  // Because of deflation, the zeros singular-values are already at the end
-  singVals.head(actual_n).reverseInPlace();
-  U.leftCols(actual_n).rowwise().reverseInPlace();
-  if (m_compV) V.leftCols(actual_n).rowwise().reverseInPlace();
-  
-#ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
-  JacobiSVD<MatrixXr> jsvd(m_computed.block(firstCol, firstCol, n, n) );
-  std::cout << "  * j:        " << jsvd.singularValues().transpose() << "\n\n";
-  std::cout << "  * sing-val: " << singVals.transpose() << "\n";
-//   std::cout << "  * err:      " << ((jsvd.singularValues()-singVals)>1e-13*singVals.norm()).transpose() << "\n";
-#endif
-}
-
-template <typename MatrixType>
-typename BDCSVD<MatrixType>::RealScalar BDCSVD<MatrixType>::secularEq(RealScalar mu, const ArrayRef& col0, const ArrayRef& diag, const IndicesRef &perm, const ArrayRef& diagShifted, RealScalar shift)
-{
-  Index m = perm.size();
-  RealScalar res = Literal(1);
-  for(Index i=0; i<m; ++i)
-  {
-    Index j = perm(i);
-    // The following expression could be rewritten to involve only a single division,
-    // but this would make the expression more sensitive to overflow.
-    res += (col0(j) / (diagShifted(j) - mu)) * (col0(j) / (diag(j) + shift + mu));
-  }
-  return res;
-
-}
-
-template <typename MatrixType>
-void BDCSVD<MatrixType>::computeSingVals(const ArrayRef& col0, const ArrayRef& diag, const IndicesRef &perm,
-                                         VectorType& singVals, ArrayRef shifts, ArrayRef mus)
-{
-  using std::abs;
-  using std::swap;
-  using std::sqrt;
-
-  Index n = col0.size();
-  Index actual_n = n;
-  // Note that here actual_n is computed based on col0(i)==0 instead of diag(i)==0 as above
-  // because 1) we have diag(i)==0 => col0(i)==0 and 2) if col0(i)==0, then diag(i) is already a singular value.
-  while(actual_n>1 && col0(actual_n-1)==Literal(0)) --actual_n;
-
-  for (Index k = 0; k < n; ++k)
-  {
-    if (col0(k) == Literal(0) || actual_n==1)
-    {
-      // if col0(k) == 0, then entry is deflated, so singular value is on diagonal
-      // if actual_n==1, then the deflated problem is already diagonalized
-      singVals(k) = k==0 ? col0(0) : diag(k);
-      mus(k) = Literal(0);
-      shifts(k) = k==0 ? col0(0) : diag(k);
-      continue;
-    } 
-
-    // otherwise, use secular equation to find singular value
-    RealScalar left = diag(k);
-    RealScalar right; // was: = (k != actual_n-1) ? diag(k+1) : (diag(actual_n-1) + col0.matrix().norm());
-    if(k==actual_n-1)
-      right = (diag(actual_n-1) + col0.matrix().norm());
-    else
-    {
-      // Skip deflated singular values,
-      // recall that at this stage we assume that z[j]!=0 and all entries for which z[j]==0 have been put aside.
-      // This should be equivalent to using perm[]
-      Index l = k+1;
-      while(col0(l)==Literal(0)) { ++l; eigen_internal_assert(l<actual_n); }
-      right = diag(l);
-    }
-
-    // first decide whether it's closer to the left end or the right end
-    RealScalar mid = left + (right-left) / Literal(2);
-    RealScalar fMid = secularEq(mid, col0, diag, perm, diag, Literal(0));
-#ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
-    std::cout << right-left << "\n";
-    std::cout << "fMid = " << fMid << " " << secularEq(mid-left, col0, diag, perm, diag-left, left) << " " << secularEq(mid-right, col0, diag, perm, diag-right, right)   << "\n";
-    std::cout << "     = " << secularEq(0.1*(left+right), col0, diag, perm, diag, 0)
-              << " "       << secularEq(0.2*(left+right), col0, diag, perm, diag, 0)
-              << " "       << secularEq(0.3*(left+right), col0, diag, perm, diag, 0)
-              << " "       << secularEq(0.4*(left+right), col0, diag, perm, diag, 0)
-              << " "       << secularEq(0.49*(left+right), col0, diag, perm, diag, 0)
-              << " "       << secularEq(0.5*(left+right), col0, diag, perm, diag, 0)
-              << " "       << secularEq(0.51*(left+right), col0, diag, perm, diag, 0)
-              << " "       << secularEq(0.6*(left+right), col0, diag, perm, diag, 0)
-              << " "       << secularEq(0.7*(left+right), col0, diag, perm, diag, 0)
-              << " "       << secularEq(0.8*(left+right), col0, diag, perm, diag, 0)
-              << " "       << secularEq(0.9*(left+right), col0, diag, perm, diag, 0) << "\n";
-#endif
-    RealScalar shift = (k == actual_n-1 || fMid > Literal(0)) ? left : right;
-    
-    // measure everything relative to shift
-    Map<ArrayXr> diagShifted(m_workspace.data()+4*n, n);
-    diagShifted = diag - shift;
-    
-    // initial guess
-    RealScalar muPrev, muCur;
-    if (shift == left)
-    {
-      muPrev = (right - left) * RealScalar(0.1);
-      if (k == actual_n-1) muCur = right - left;
-      else                 muCur = (right - left) * RealScalar(0.5);
-    }
-    else
-    {
-      muPrev = -(right - left) * RealScalar(0.1);
-      muCur = -(right - left) * RealScalar(0.5);
-    }
-
-    RealScalar fPrev = secularEq(muPrev, col0, diag, perm, diagShifted, shift);
-    RealScalar fCur = secularEq(muCur, col0, diag, perm, diagShifted, shift);
-    if (abs(fPrev) < abs(fCur))
-    {
-      swap(fPrev, fCur);
-      swap(muPrev, muCur);
-    }
-
-    // rational interpolation: fit a function of the form a / mu + b through the two previous
-    // iterates and use its zero to compute the next iterate
-    bool useBisection = fPrev*fCur>Literal(0);
-    while (fCur!=Literal(0) && abs(muCur - muPrev) > Literal(8) * NumTraits<RealScalar>::epsilon() * numext::maxi<RealScalar>(abs(muCur), abs(muPrev)) && abs(fCur - fPrev)>NumTraits<RealScalar>::epsilon() && !useBisection)
-    {
-      ++m_numIters;
-
-      // Find a and b such that the function f(mu) = a / mu + b matches the current and previous samples.
-      RealScalar a = (fCur - fPrev) / (Literal(1)/muCur - Literal(1)/muPrev);
-      RealScalar b = fCur - a / muCur;
-      // And find mu such that f(mu)==0:
-      RealScalar muZero = -a/b;
-      RealScalar fZero = secularEq(muZero, col0, diag, perm, diagShifted, shift);
-      
-      muPrev = muCur;
-      fPrev = fCur;
-      muCur = muZero;
-      fCur = fZero;
-      
-      
-      if (shift == left  && (muCur < Literal(0) || muCur > right - left)) useBisection = true;
-      if (shift == right && (muCur < -(right - left) || muCur > Literal(0))) useBisection = true;
-      if (abs(fCur)>abs(fPrev)) useBisection = true;
-    }
-
-    // fall back on bisection method if rational interpolation did not work
-    if (useBisection)
-    {
-#ifdef  EIGEN_BDCSVD_DEBUG_VERBOSE
-      std::cout << "useBisection for k = " << k << ", actual_n = " << actual_n << "\n";
-#endif
-      RealScalar leftShifted, rightShifted;
-      if (shift == left)
-      {
-        // to avoid overflow, we must have mu > max(real_min, |z(k)|/sqrt(real_max)),
-        // the factor 2 is to be more conservative
-        leftShifted = numext::maxi<RealScalar>( (std::numeric_limits<RealScalar>::min)(), Literal(2) * abs(col0(k)) / sqrt((std::numeric_limits<RealScalar>::max)()) );
-
-        // check that we did it right:
-        eigen_internal_assert( (numext::isfinite)( (col0(k)/leftShifted)*(col0(k)/(diag(k)+shift+leftShifted)) ) );
-        // I don't understand why the case k==0 would be special there:
-        // if (k == 0) rightShifted = right - left; else
-        rightShifted = (k==actual_n-1) ? right : ((right - left) * RealScalar(0.51)); // theoretically we can take 0.5, but let's be safe
-      }
-      else
-      {
-        leftShifted = -(right - left) * RealScalar(0.51);
-        if(k+1<n)
-          rightShifted = -numext::maxi<RealScalar>( (std::numeric_limits<RealScalar>::min)(), abs(col0(k+1)) / sqrt((std::numeric_limits<RealScalar>::max)()) );
-        else
-          rightShifted = -(std::numeric_limits<RealScalar>::min)();
-      }
-      
-      RealScalar fLeft = secularEq(leftShifted, col0, diag, perm, diagShifted, shift);
-
-#if defined EIGEN_INTERNAL_DEBUGGING || defined EIGEN_BDCSVD_DEBUG_VERBOSE
-      RealScalar fRight = secularEq(rightShifted, col0, diag, perm, diagShifted, shift);
-#endif
-
-#ifdef  EIGEN_BDCSVD_DEBUG_VERBOSE
-      if(!(fLeft * fRight<0))
-      {
-        std::cout << "fLeft: " << leftShifted << " - " << diagShifted.head(10).transpose()  << "\n ; " << bool(left==shift) << " " << (left-shift) << "\n";
-        std::cout << k << " : " <<  fLeft << " * " << fRight << " == " << fLeft * fRight << "  ;  " << left << " - " << right << " -> " <<  leftShifted << " " << rightShifted << "   shift=" << shift << "\n";
-      }
-#endif
-      eigen_internal_assert(fLeft * fRight < Literal(0));
-      
-      while (rightShifted - leftShifted > Literal(2) * NumTraits<RealScalar>::epsilon() * numext::maxi<RealScalar>(abs(leftShifted), abs(rightShifted)))
-      {
-        RealScalar midShifted = (leftShifted + rightShifted) / Literal(2);
-        fMid = secularEq(midShifted, col0, diag, perm, diagShifted, shift);
-        if (fLeft * fMid < Literal(0))
-        {
-          rightShifted = midShifted;
-        }
-        else
-        {
-          leftShifted = midShifted;
-          fLeft = fMid;
-        }
-      }
-
-      muCur = (leftShifted + rightShifted) / Literal(2);
-    }
-      
-    singVals[k] = shift + muCur;
-    shifts[k] = shift;
-    mus[k] = muCur;
-
-    // perturb singular value slightly if it equals diagonal entry to avoid division by zero later
-    // (deflation is supposed to avoid this from happening)
-    // - this does no seem to be necessary anymore -
-//     if (singVals[k] == left) singVals[k] *= 1 + NumTraits<RealScalar>::epsilon();
-//     if (singVals[k] == right) singVals[k] *= 1 - NumTraits<RealScalar>::epsilon();
-  }
-}
-
-
-// zhat is perturbation of col0 for which singular vectors can be computed stably (see Section 3.1)
-template <typename MatrixType>
-void BDCSVD<MatrixType>::perturbCol0
-   (const ArrayRef& col0, const ArrayRef& diag, const IndicesRef &perm, const VectorType& singVals,
-    const ArrayRef& shifts, const ArrayRef& mus, ArrayRef zhat)
-{
-  using std::sqrt;
-  Index n = col0.size();
-  Index m = perm.size();
-  if(m==0)
-  {
-    zhat.setZero();
-    return;
-  }
-  Index last = perm(m-1);
-  // The offset permits to skip deflated entries while computing zhat
-  for (Index k = 0; k < n; ++k)
-  {
-    if (col0(k) == Literal(0)) // deflated
-      zhat(k) = Literal(0);
-    else
-    {
-      // see equation (3.6)
-      RealScalar dk = diag(k);
-      RealScalar prod = (singVals(last) + dk) * (mus(last) + (shifts(last) - dk));
-
-      for(Index l = 0; l<m; ++l)
-      {
-        Index i = perm(l);
-        if(i!=k)
-        {
-          Index j = i<k ? i : perm(l-1);
-          prod *= ((singVals(j)+dk) / ((diag(i)+dk))) * ((mus(j)+(shifts(j)-dk)) / ((diag(i)-dk)));
-#ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
-          if(i!=k && std::abs(((singVals(j)+dk)*(mus(j)+(shifts(j)-dk)))/((diag(i)+dk)*(diag(i)-dk)) - 1) > 0.9 )
-            std::cout << "     " << ((singVals(j)+dk)*(mus(j)+(shifts(j)-dk)))/((diag(i)+dk)*(diag(i)-dk)) << " == (" << (singVals(j)+dk) << " * " << (mus(j)+(shifts(j)-dk))
-                       << ") / (" << (diag(i)+dk) << " * " << (diag(i)-dk) << ")\n";
-#endif
-        }
-      }
-#ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
-      std::cout << "zhat(" << k << ") =  sqrt( " << prod << ")  ;  " << (singVals(last) + dk) << " * " << mus(last) + shifts(last) << " - " << dk << "\n";
-#endif
-      RealScalar tmp = sqrt(prod);
-      zhat(k) = col0(k) > Literal(0) ? tmp : -tmp;
-    }
-  }
-}
-
-// compute singular vectors
-template <typename MatrixType>
-void BDCSVD<MatrixType>::computeSingVecs
-   (const ArrayRef& zhat, const ArrayRef& diag, const IndicesRef &perm, const VectorType& singVals,
-    const ArrayRef& shifts, const ArrayRef& mus, MatrixXr& U, MatrixXr& V)
-{
-  Index n = zhat.size();
-  Index m = perm.size();
-  
-  for (Index k = 0; k < n; ++k)
-  {
-    if (zhat(k) == Literal(0))
-    {
-      U.col(k) = VectorType::Unit(n+1, k);
-      if (m_compV) V.col(k) = VectorType::Unit(n, k);
-    }
-    else
-    {
-      U.col(k).setZero();
-      for(Index l=0;l<m;++l)
-      {
-        Index i = perm(l);
-        U(i,k) = zhat(i)/(((diag(i) - shifts(k)) - mus(k)) )/( (diag(i) + singVals[k]));
-      }
-      U(n,k) = Literal(0);
-      U.col(k).normalize();
-    
-      if (m_compV)
-      {
-        V.col(k).setZero();
-        for(Index l=1;l<m;++l)
-        {
-          Index i = perm(l);
-          V(i,k) = diag(i) * zhat(i) / (((diag(i) - shifts(k)) - mus(k)) )/( (diag(i) + singVals[k]));
-        }
-        V(0,k) = Literal(-1);
-        V.col(k).normalize();
-      }
-    }
-  }
-  U.col(n) = VectorType::Unit(n+1, n);
-}
-
-
-// page 12_13
-// i >= 1, di almost null and zi non null.
-// We use a rotation to zero out zi applied to the left of M
-template <typename MatrixType>
-void BDCSVD<MatrixType>::deflation43(Index firstCol, Index shift, Index i, Index size)
-{
-  using std::abs;
-  using std::sqrt;
-  using std::pow;
-  Index start = firstCol + shift;
-  RealScalar c = m_computed(start, start);
-  RealScalar s = m_computed(start+i, start);
-  RealScalar r = numext::hypot(c,s);
-  if (r == Literal(0))
-  {
-    m_computed(start+i, start+i) = Literal(0);
-    return;
-  }
-  m_computed(start,start) = r;  
-  m_computed(start+i, start) = Literal(0);
-  m_computed(start+i, start+i) = Literal(0);
-  
-  JacobiRotation<RealScalar> J(c/r,-s/r);
-  if (m_compU)  m_naiveU.middleRows(firstCol, size+1).applyOnTheRight(firstCol, firstCol+i, J);
-  else          m_naiveU.applyOnTheRight(firstCol, firstCol+i, J);
-}// end deflation 43
-
-
-// page 13
-// i,j >= 1, i!=j and |di - dj| < epsilon * norm2(M)
-// We apply two rotations to have zj = 0;
-// TODO deflation44 is still broken and not properly tested
-template <typename MatrixType>
-void BDCSVD<MatrixType>::deflation44(Index firstColu , Index firstColm, Index firstRowW, Index firstColW, Index i, Index j, Index size)
-{
-  using std::abs;
-  using std::sqrt;
-  using std::conj;
-  using std::pow;
-  RealScalar c = m_computed(firstColm+i, firstColm);
-  RealScalar s = m_computed(firstColm+j, firstColm);
-  RealScalar r = sqrt(numext::abs2(c) + numext::abs2(s));
-#ifdef  EIGEN_BDCSVD_DEBUG_VERBOSE
-  std::cout << "deflation 4.4: " << i << "," << j << " -> " << c << " " << s << " " << r << " ; "
-    << m_computed(firstColm + i-1, firstColm)  << " "
-    << m_computed(firstColm + i, firstColm)  << " "
-    << m_computed(firstColm + i+1, firstColm) << " "
-    << m_computed(firstColm + i+2, firstColm) << "\n";
-  std::cout << m_computed(firstColm + i-1, firstColm + i-1)  << " "
-    << m_computed(firstColm + i, firstColm+i)  << " "
-    << m_computed(firstColm + i+1, firstColm+i+1) << " "
-    << m_computed(firstColm + i+2, firstColm+i+2) << "\n";
-#endif
-  if (r==Literal(0))
-  {
-    m_computed(firstColm + i, firstColm + i) = m_computed(firstColm + j, firstColm + j);
-    return;
-  }
-  c/=r;
-  s/=r;
-  m_computed(firstColm + i, firstColm) = r;  
-  m_computed(firstColm + j, firstColm + j) = m_computed(firstColm + i, firstColm + i);
-  m_computed(firstColm + j, firstColm) = Literal(0);
-
-  JacobiRotation<RealScalar> J(c,-s);
-  if (m_compU)  m_naiveU.middleRows(firstColu, size+1).applyOnTheRight(firstColu + i, firstColu + j, J);
-  else          m_naiveU.applyOnTheRight(firstColu+i, firstColu+j, J);
-  if (m_compV)  m_naiveV.middleRows(firstRowW, size).applyOnTheRight(firstColW + i, firstColW + j, J);
-}// end deflation 44
-
-
-// acts on block from (firstCol+shift, firstCol+shift) to (lastCol+shift, lastCol+shift) [inclusive]
-template <typename MatrixType>
-void BDCSVD<MatrixType>::deflation(Index firstCol, Index lastCol, Index k, Index firstRowW, Index firstColW, Index shift)
-{
-  using std::sqrt;
-  using std::abs;
-  const Index length = lastCol + 1 - firstCol;
-  
-  Block<MatrixXr,Dynamic,1> col0(m_computed, firstCol+shift, firstCol+shift, length, 1);
-  Diagonal<MatrixXr> fulldiag(m_computed);
-  VectorBlock<Diagonal<MatrixXr>,Dynamic> diag(fulldiag, firstCol+shift, length);
-  
-  const RealScalar considerZero = (std::numeric_limits<RealScalar>::min)();
-  RealScalar maxDiag = diag.tail((std::max)(Index(1),length-1)).cwiseAbs().maxCoeff();
-  RealScalar epsilon_strict = numext::maxi<RealScalar>(considerZero,NumTraits<RealScalar>::epsilon() * maxDiag);
-  RealScalar epsilon_coarse = Literal(8) * NumTraits<RealScalar>::epsilon() * numext::maxi<RealScalar>(col0.cwiseAbs().maxCoeff(), maxDiag);
-  
-#ifdef EIGEN_BDCSVD_SANITY_CHECKS
-  assert(m_naiveU.allFinite());
-  assert(m_naiveV.allFinite());
-  assert(m_computed.allFinite());
-#endif
-
-#ifdef  EIGEN_BDCSVD_DEBUG_VERBOSE  
-  std::cout << "\ndeflate:" << diag.head(k+1).transpose() << "  |  " << diag.segment(k+1,length-k-1).transpose() << "\n";
-#endif
-  
-  //condition 4.1
-  if (diag(0) < epsilon_coarse)
-  { 
-#ifdef  EIGEN_BDCSVD_DEBUG_VERBOSE
-    std::cout << "deflation 4.1, because " << diag(0) << " < " << epsilon_coarse << "\n";
-#endif
-    diag(0) = epsilon_coarse;
-  }
-
-  //condition 4.2
-  for (Index i=1;i<length;++i)
-    if (abs(col0(i)) < epsilon_strict)
-    {
-#ifdef  EIGEN_BDCSVD_DEBUG_VERBOSE
-      std::cout << "deflation 4.2, set z(" << i << ") to zero because " << abs(col0(i)) << " < " << epsilon_strict << "  (diag(" << i << ")=" << diag(i) << ")\n";
-#endif
-      col0(i) = Literal(0);
-    }
-
-  //condition 4.3
-  for (Index i=1;i<length; i++)
-    if (diag(i) < epsilon_coarse)
-    {
-#ifdef  EIGEN_BDCSVD_DEBUG_VERBOSE
-      std::cout << "deflation 4.3, cancel z(" << i << ")=" << col0(i) << " because diag(" << i << ")=" << diag(i) << " < " << epsilon_coarse << "\n";
-#endif
-      deflation43(firstCol, shift, i, length);
-    }
-
-#ifdef EIGEN_BDCSVD_SANITY_CHECKS
-  assert(m_naiveU.allFinite());
-  assert(m_naiveV.allFinite());
-  assert(m_computed.allFinite());
-#endif
-#ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
-  std::cout << "to be sorted: " << diag.transpose() << "\n\n";
-#endif
-  {
-    // Check for total deflation
-    // If we have a total deflation, then we have to consider col0(0)==diag(0) as a singular value during sorting
-    bool total_deflation = (col0.tail(length-1).array()<considerZero).all();
-    
-    // Sort the diagonal entries, since diag(1:k-1) and diag(k:length) are already sorted, let's do a sorted merge.
-    // First, compute the respective permutation.
-    Index *permutation = m_workspaceI.data();
-    {
-      permutation[0] = 0;
-      Index p = 1;
-      
-      // Move deflated diagonal entries at the end.
-      for(Index i=1; i<length; ++i)
-        if(abs(diag(i))<considerZero)
-          permutation[p++] = i;
-        
-      Index i=1, j=k+1;
-      for( ; p < length; ++p)
-      {
-             if (i > k)             permutation[p] = j++;
-        else if (j >= length)       permutation[p] = i++;
-        else if (diag(i) < diag(j)) permutation[p] = j++;
-        else                        permutation[p] = i++;
-      }
-    }
-    
-    // If we have a total deflation, then we have to insert diag(0) at the right place
-    if(total_deflation)
-    {
-      for(Index i=1; i<length; ++i)
-      {
-        Index pi = permutation[i];
-        if(abs(diag(pi))<considerZero || diag(0)<diag(pi))
-          permutation[i-1] = permutation[i];
-        else
-        {
-          permutation[i-1] = 0;
-          break;
-        }
-      }
-    }
-    
-    // Current index of each col, and current column of each index
-    Index *realInd = m_workspaceI.data()+length;
-    Index *realCol = m_workspaceI.data()+2*length;
-    
-    for(int pos = 0; pos< length; pos++)
-    {
-      realCol[pos] = pos;
-      realInd[pos] = pos;
-    }
-    
-    for(Index i = total_deflation?0:1; i < length; i++)
-    {
-      const Index pi = permutation[length - (total_deflation ? i+1 : i)];
-      const Index J = realCol[pi];
-      
-      using std::swap;
-      // swap diagonal and first column entries:
-      swap(diag(i), diag(J));
-      if(i!=0 && J!=0) swap(col0(i), col0(J));
-
-      // change columns
-      if (m_compU) m_naiveU.col(firstCol+i).segment(firstCol, length + 1).swap(m_naiveU.col(firstCol+J).segment(firstCol, length + 1));
-      else         m_naiveU.col(firstCol+i).segment(0, 2)                .swap(m_naiveU.col(firstCol+J).segment(0, 2));
-      if (m_compV) m_naiveV.col(firstColW + i).segment(firstRowW, length).swap(m_naiveV.col(firstColW + J).segment(firstRowW, length));
-
-      //update real pos
-      const Index realI = realInd[i];
-      realCol[realI] = J;
-      realCol[pi] = i;
-      realInd[J] = realI;
-      realInd[i] = pi;
-    }
-  }
-#ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
-  std::cout << "sorted: " << diag.transpose().format(bdcsvdfmt) << "\n";
-  std::cout << "      : " << col0.transpose() << "\n\n";
-#endif
-    
-  //condition 4.4
-  {
-    Index i = length-1;
-    while(i>0 && (abs(diag(i))<considerZero || abs(col0(i))<considerZero)) --i;
-    for(; i>1;--i)
-       if( (diag(i) - diag(i-1)) < NumTraits<RealScalar>::epsilon()*maxDiag )
-      {
-#ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
-        std::cout << "deflation 4.4 with i = " << i << " because " << (diag(i) - diag(i-1)) << " < " << NumTraits<RealScalar>::epsilon()*diag(i) << "\n";
-#endif
-        eigen_internal_assert(abs(diag(i) - diag(i-1))<epsilon_coarse && " diagonal entries are not properly sorted");
-        deflation44(firstCol, firstCol + shift, firstRowW, firstColW, i-1, i, length);
-      }
-  }
-  
-#ifdef EIGEN_BDCSVD_SANITY_CHECKS
-  for(Index j=2;j<length;++j)
-    assert(diag(j-1)<=diag(j) || abs(diag(j))<considerZero);
-#endif
-  
-#ifdef EIGEN_BDCSVD_SANITY_CHECKS
-  assert(m_naiveU.allFinite());
-  assert(m_naiveV.allFinite());
-  assert(m_computed.allFinite());
-#endif
-}//end deflation
-
-#ifndef __CUDACC__
-/** \svd_module
-  *
-  * \return the singular value decomposition of \c *this computed by Divide & Conquer algorithm
-  *
-  * \sa class BDCSVD
-  */
-template<typename Derived>
-BDCSVD<typename MatrixBase<Derived>::PlainObject>
-MatrixBase<Derived>::bdcSvd(unsigned int computationOptions) const
-{
-  return BDCSVD<PlainObject>(*this, computationOptions);
-}
-#endif
-
-} // end namespace Eigen
-
-#endif
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/SVD/JacobiSVD.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/SVD/JacobiSVD.h
deleted file mode 100644
index 43488b1..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/SVD/JacobiSVD.h
+++ /dev/null
@@ -1,804 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2013-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_JACOBISVD_H
-#define EIGEN_JACOBISVD_H
-
-namespace Eigen { 
-
-namespace internal {
-// forward declaration (needed by ICC)
-// the empty body is required by MSVC
-template<typename MatrixType, int QRPreconditioner,
-         bool IsComplex = NumTraits<typename MatrixType::Scalar>::IsComplex>
-struct svd_precondition_2x2_block_to_be_real {};
-
-/*** QR preconditioners (R-SVD)
- ***
- *** Their role is to reduce the problem of computing the SVD to the case of a square matrix.
- *** This approach, known as R-SVD, is an optimization for rectangular-enough matrices, and is a requirement for
- *** JacobiSVD which by itself is only able to work on square matrices.
- ***/
-
-enum { PreconditionIfMoreColsThanRows, PreconditionIfMoreRowsThanCols };
-
-template<typename MatrixType, int QRPreconditioner, int Case>
-struct qr_preconditioner_should_do_anything
-{
-  enum { a = MatrixType::RowsAtCompileTime != Dynamic &&
-             MatrixType::ColsAtCompileTime != Dynamic &&
-             MatrixType::ColsAtCompileTime <= MatrixType::RowsAtCompileTime,
-         b = MatrixType::RowsAtCompileTime != Dynamic &&
-             MatrixType::ColsAtCompileTime != Dynamic &&
-             MatrixType::RowsAtCompileTime <= MatrixType::ColsAtCompileTime,
-         ret = !( (QRPreconditioner == NoQRPreconditioner) ||
-                  (Case == PreconditionIfMoreColsThanRows && bool(a)) ||
-                  (Case == PreconditionIfMoreRowsThanCols && bool(b)) )
-  };
-};
-
-template<typename MatrixType, int QRPreconditioner, int Case,
-         bool DoAnything = qr_preconditioner_should_do_anything<MatrixType, QRPreconditioner, Case>::ret
-> struct qr_preconditioner_impl {};
-
-template<typename MatrixType, int QRPreconditioner, int Case>
-class qr_preconditioner_impl<MatrixType, QRPreconditioner, Case, false>
-{
-public:
-  void allocate(const JacobiSVD<MatrixType, QRPreconditioner>&) {}
-  bool run(JacobiSVD<MatrixType, QRPreconditioner>&, const MatrixType&)
-  {
-    return false;
-  }
-};
-
-/*** preconditioner using FullPivHouseholderQR ***/
-
-template<typename MatrixType>
-class qr_preconditioner_impl<MatrixType, FullPivHouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true>
-{
-public:
-  typedef typename MatrixType::Scalar Scalar;
-  enum
-  {
-    RowsAtCompileTime = MatrixType::RowsAtCompileTime,
-    MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime
-  };
-  typedef Matrix<Scalar, 1, RowsAtCompileTime, RowMajor, 1, MaxRowsAtCompileTime> WorkspaceType;
-
-  void allocate(const JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd)
-  {
-    if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols())
-    {
-      m_qr.~QRType();
-      ::new (&m_qr) QRType(svd.rows(), svd.cols());
-    }
-    if (svd.m_computeFullU) m_workspace.resize(svd.rows());
-  }
-
-  bool run(JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix)
-  {
-    if(matrix.rows() > matrix.cols())
-    {
-      m_qr.compute(matrix);
-      svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView<Upper>();
-      if(svd.m_computeFullU) m_qr.matrixQ().evalTo(svd.m_matrixU, m_workspace);
-      if(svd.computeV()) svd.m_matrixV = m_qr.colsPermutation();
-      return true;
-    }
-    return false;
-  }
-private:
-  typedef FullPivHouseholderQR<MatrixType> QRType;
-  QRType m_qr;
-  WorkspaceType m_workspace;
-};
-
-template<typename MatrixType>
-class qr_preconditioner_impl<MatrixType, FullPivHouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true>
-{
-public:
-  typedef typename MatrixType::Scalar Scalar;
-  enum
-  {
-    RowsAtCompileTime = MatrixType::RowsAtCompileTime,
-    ColsAtCompileTime = MatrixType::ColsAtCompileTime,
-    MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
-    MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
-    TrOptions = RowsAtCompileTime==1 ? (MatrixType::Options & ~(RowMajor))
-              : ColsAtCompileTime==1 ? (MatrixType::Options |   RowMajor)
-              : MatrixType::Options
-  };
-  typedef Matrix<Scalar, ColsAtCompileTime, RowsAtCompileTime, TrOptions, MaxColsAtCompileTime, MaxRowsAtCompileTime>
-          TransposeTypeWithSameStorageOrder;
-
-  void allocate(const JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd)
-  {
-    if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols())
-    {
-      m_qr.~QRType();
-      ::new (&m_qr) QRType(svd.cols(), svd.rows());
-    }
-    m_adjoint.resize(svd.cols(), svd.rows());
-    if (svd.m_computeFullV) m_workspace.resize(svd.cols());
-  }
-
-  bool run(JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix)
-  {
-    if(matrix.cols() > matrix.rows())
-    {
-      m_adjoint = matrix.adjoint();
-      m_qr.compute(m_adjoint);
-      svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView<Upper>().adjoint();
-      if(svd.m_computeFullV) m_qr.matrixQ().evalTo(svd.m_matrixV, m_workspace);
-      if(svd.computeU()) svd.m_matrixU = m_qr.colsPermutation();
-      return true;
-    }
-    else return false;
-  }
-private:
-  typedef FullPivHouseholderQR<TransposeTypeWithSameStorageOrder> QRType;
-  QRType m_qr;
-  TransposeTypeWithSameStorageOrder m_adjoint;
-  typename internal::plain_row_type<MatrixType>::type m_workspace;
-};
-
-/*** preconditioner using ColPivHouseholderQR ***/
-
-template<typename MatrixType>
-class qr_preconditioner_impl<MatrixType, ColPivHouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true>
-{
-public:
-  void allocate(const JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd)
-  {
-    if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols())
-    {
-      m_qr.~QRType();
-      ::new (&m_qr) QRType(svd.rows(), svd.cols());
-    }
-    if (svd.m_computeFullU) m_workspace.resize(svd.rows());
-    else if (svd.m_computeThinU) m_workspace.resize(svd.cols());
-  }
-
-  bool run(JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix)
-  {
-    if(matrix.rows() > matrix.cols())
-    {
-      m_qr.compute(matrix);
-      svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView<Upper>();
-      if(svd.m_computeFullU) m_qr.householderQ().evalTo(svd.m_matrixU, m_workspace);
-      else if(svd.m_computeThinU)
-      {
-        svd.m_matrixU.setIdentity(matrix.rows(), matrix.cols());
-        m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixU, m_workspace);
-      }
-      if(svd.computeV()) svd.m_matrixV = m_qr.colsPermutation();
-      return true;
-    }
-    return false;
-  }
-
-private:
-  typedef ColPivHouseholderQR<MatrixType> QRType;
-  QRType m_qr;
-  typename internal::plain_col_type<MatrixType>::type m_workspace;
-};
-
-template<typename MatrixType>
-class qr_preconditioner_impl<MatrixType, ColPivHouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true>
-{
-public:
-  typedef typename MatrixType::Scalar Scalar;
-  enum
-  {
-    RowsAtCompileTime = MatrixType::RowsAtCompileTime,
-    ColsAtCompileTime = MatrixType::ColsAtCompileTime,
-    MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
-    MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
-    TrOptions = RowsAtCompileTime==1 ? (MatrixType::Options & ~(RowMajor))
-              : ColsAtCompileTime==1 ? (MatrixType::Options |   RowMajor)
-              : MatrixType::Options
-  };
-
-  typedef Matrix<Scalar, ColsAtCompileTime, RowsAtCompileTime, TrOptions, MaxColsAtCompileTime, MaxRowsAtCompileTime>
-          TransposeTypeWithSameStorageOrder;
-
-  void allocate(const JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd)
-  {
-    if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols())
-    {
-      m_qr.~QRType();
-      ::new (&m_qr) QRType(svd.cols(), svd.rows());
-    }
-    if (svd.m_computeFullV) m_workspace.resize(svd.cols());
-    else if (svd.m_computeThinV) m_workspace.resize(svd.rows());
-    m_adjoint.resize(svd.cols(), svd.rows());
-  }
-
-  bool run(JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix)
-  {
-    if(matrix.cols() > matrix.rows())
-    {
-      m_adjoint = matrix.adjoint();
-      m_qr.compute(m_adjoint);
-
-      svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView<Upper>().adjoint();
-      if(svd.m_computeFullV) m_qr.householderQ().evalTo(svd.m_matrixV, m_workspace);
-      else if(svd.m_computeThinV)
-      {
-        svd.m_matrixV.setIdentity(matrix.cols(), matrix.rows());
-        m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixV, m_workspace);
-      }
-      if(svd.computeU()) svd.m_matrixU = m_qr.colsPermutation();
-      return true;
-    }
-    else return false;
-  }
-
-private:
-  typedef ColPivHouseholderQR<TransposeTypeWithSameStorageOrder> QRType;
-  QRType m_qr;
-  TransposeTypeWithSameStorageOrder m_adjoint;
-  typename internal::plain_row_type<MatrixType>::type m_workspace;
-};
-
-/*** preconditioner using HouseholderQR ***/
-
-template<typename MatrixType>
-class qr_preconditioner_impl<MatrixType, HouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true>
-{
-public:
-  void allocate(const JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd)
-  {
-    if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols())
-    {
-      m_qr.~QRType();
-      ::new (&m_qr) QRType(svd.rows(), svd.cols());
-    }
-    if (svd.m_computeFullU) m_workspace.resize(svd.rows());
-    else if (svd.m_computeThinU) m_workspace.resize(svd.cols());
-  }
-
-  bool run(JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd, const MatrixType& matrix)
-  {
-    if(matrix.rows() > matrix.cols())
-    {
-      m_qr.compute(matrix);
-      svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView<Upper>();
-      if(svd.m_computeFullU) m_qr.householderQ().evalTo(svd.m_matrixU, m_workspace);
-      else if(svd.m_computeThinU)
-      {
-        svd.m_matrixU.setIdentity(matrix.rows(), matrix.cols());
-        m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixU, m_workspace);
-      }
-      if(svd.computeV()) svd.m_matrixV.setIdentity(matrix.cols(), matrix.cols());
-      return true;
-    }
-    return false;
-  }
-private:
-  typedef HouseholderQR<MatrixType> QRType;
-  QRType m_qr;
-  typename internal::plain_col_type<MatrixType>::type m_workspace;
-};
-
-template<typename MatrixType>
-class qr_preconditioner_impl<MatrixType, HouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true>
-{
-public:
-  typedef typename MatrixType::Scalar Scalar;
-  enum
-  {
-    RowsAtCompileTime = MatrixType::RowsAtCompileTime,
-    ColsAtCompileTime = MatrixType::ColsAtCompileTime,
-    MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
-    MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
-    Options = MatrixType::Options
-  };
-
-  typedef Matrix<Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime>
-          TransposeTypeWithSameStorageOrder;
-
-  void allocate(const JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd)
-  {
-    if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols())
-    {
-      m_qr.~QRType();
-      ::new (&m_qr) QRType(svd.cols(), svd.rows());
-    }
-    if (svd.m_computeFullV) m_workspace.resize(svd.cols());
-    else if (svd.m_computeThinV) m_workspace.resize(svd.rows());
-    m_adjoint.resize(svd.cols(), svd.rows());
-  }
-
-  bool run(JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd, const MatrixType& matrix)
-  {
-    if(matrix.cols() > matrix.rows())
-    {
-      m_adjoint = matrix.adjoint();
-      m_qr.compute(m_adjoint);
-
-      svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView<Upper>().adjoint();
-      if(svd.m_computeFullV) m_qr.householderQ().evalTo(svd.m_matrixV, m_workspace);
-      else if(svd.m_computeThinV)
-      {
-        svd.m_matrixV.setIdentity(matrix.cols(), matrix.rows());
-        m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixV, m_workspace);
-      }
-      if(svd.computeU()) svd.m_matrixU.setIdentity(matrix.rows(), matrix.rows());
-      return true;
-    }
-    else return false;
-  }
-
-private:
-  typedef HouseholderQR<TransposeTypeWithSameStorageOrder> QRType;
-  QRType m_qr;
-  TransposeTypeWithSameStorageOrder m_adjoint;
-  typename internal::plain_row_type<MatrixType>::type m_workspace;
-};
-
-/*** 2x2 SVD implementation
- ***
- *** JacobiSVD consists in performing a series of 2x2 SVD subproblems
- ***/
-
-template<typename MatrixType, int QRPreconditioner>
-struct svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner, false>
-{
-  typedef JacobiSVD<MatrixType, QRPreconditioner> SVD;
-  typedef typename MatrixType::RealScalar RealScalar;
-  static bool run(typename SVD::WorkMatrixType&, SVD&, Index, Index, RealScalar&) { return true; }
-};
-
-template<typename MatrixType, int QRPreconditioner>
-struct svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner, true>
-{
-  typedef JacobiSVD<MatrixType, QRPreconditioner> SVD;
-  typedef typename MatrixType::Scalar Scalar;
-  typedef typename MatrixType::RealScalar RealScalar;
-  static bool run(typename SVD::WorkMatrixType& work_matrix, SVD& svd, Index p, Index q, RealScalar& maxDiagEntry)
-  {
-    using std::sqrt;
-    using std::abs;
-    Scalar z;
-    JacobiRotation<Scalar> rot;
-    RealScalar n = sqrt(numext::abs2(work_matrix.coeff(p,p)) + numext::abs2(work_matrix.coeff(q,p)));
-
-    const RealScalar considerAsZero = (std::numeric_limits<RealScalar>::min)();
-    const RealScalar precision = NumTraits<Scalar>::epsilon();
-
-    if(n==0)
-    {
-      // make sure first column is zero
-      work_matrix.coeffRef(p,p) = work_matrix.coeffRef(q,p) = Scalar(0);
-
-      if(abs(numext::imag(work_matrix.coeff(p,q)))>considerAsZero)
-      {
-        // work_matrix.coeff(p,q) can be zero if work_matrix.coeff(q,p) is not zero but small enough to underflow when computing n
-        z = abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q);
-        work_matrix.row(p) *= z;
-        if(svd.computeU()) svd.m_matrixU.col(p) *= conj(z);
-      }
-      if(abs(numext::imag(work_matrix.coeff(q,q)))>considerAsZero)
-      {
-        z = abs(work_matrix.coeff(q,q)) / work_matrix.coeff(q,q);
-        work_matrix.row(q) *= z;
-        if(svd.computeU()) svd.m_matrixU.col(q) *= conj(z);
-      }
-      // otherwise the second row is already zero, so we have nothing to do.
-    }
-    else
-    {
-      rot.c() = conj(work_matrix.coeff(p,p)) / n;
-      rot.s() = work_matrix.coeff(q,p) / n;
-      work_matrix.applyOnTheLeft(p,q,rot);
-      if(svd.computeU()) svd.m_matrixU.applyOnTheRight(p,q,rot.adjoint());
-      if(abs(numext::imag(work_matrix.coeff(p,q)))>considerAsZero)
-      {
-        z = abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q);
-        work_matrix.col(q) *= z;
-        if(svd.computeV()) svd.m_matrixV.col(q) *= z;
-      }
-      if(abs(numext::imag(work_matrix.coeff(q,q)))>considerAsZero)
-      {
-        z = abs(work_matrix.coeff(q,q)) / work_matrix.coeff(q,q);
-        work_matrix.row(q) *= z;
-        if(svd.computeU()) svd.m_matrixU.col(q) *= conj(z);
-      }
-    }
-
-    // update largest diagonal entry
-    maxDiagEntry = numext::maxi<RealScalar>(maxDiagEntry,numext::maxi<RealScalar>(abs(work_matrix.coeff(p,p)), abs(work_matrix.coeff(q,q))));
-    // and check whether the 2x2 block is already diagonal
-    RealScalar threshold = numext::maxi<RealScalar>(considerAsZero, precision * maxDiagEntry);
-    return abs(work_matrix.coeff(p,q))>threshold || abs(work_matrix.coeff(q,p)) > threshold;
-  }
-};
-
-template<typename _MatrixType, int QRPreconditioner> 
-struct traits<JacobiSVD<_MatrixType,QRPreconditioner> >
-{
-  typedef _MatrixType MatrixType;
-};
-
-} // end namespace internal
-
-/** \ingroup SVD_Module
-  *
-  *
-  * \class JacobiSVD
-  *
-  * \brief Two-sided Jacobi SVD decomposition of a rectangular matrix
-  *
-  * \tparam _MatrixType the type of the matrix of which we are computing the SVD decomposition
-  * \tparam QRPreconditioner this optional parameter allows to specify the type of QR decomposition that will be used internally
-  *                        for the R-SVD step for non-square matrices. See discussion of possible values below.
-  *
-  * SVD decomposition consists in decomposing any n-by-p matrix \a A as a product
-  *   \f[ A = U S V^* \f]
-  * where \a U is a n-by-n unitary, \a V is a p-by-p unitary, and \a S is a n-by-p real positive matrix which is zero outside of its main diagonal;
-  * the diagonal entries of S are known as the \em singular \em values of \a A and the columns of \a U and \a V are known as the left
-  * and right \em singular \em vectors of \a A respectively.
-  *
-  * Singular values are always sorted in decreasing order.
-  *
-  * This JacobiSVD decomposition computes only the singular values by default. If you want \a U or \a V, you need to ask for them explicitly.
-  *
-  * You can ask for only \em thin \a U or \a V to be computed, meaning the following. In case of a rectangular n-by-p matrix, letting \a m be the
-  * smaller value among \a n and \a p, there are only \a m singular vectors; the remaining columns of \a U and \a V do not correspond to actual
-  * singular vectors. Asking for \em thin \a U or \a V means asking for only their \a m first columns to be formed. So \a U is then a n-by-m matrix,
-  * and \a V is then a p-by-m matrix. Notice that thin \a U and \a V are all you need for (least squares) solving.
-  *
-  * Here's an example demonstrating basic usage:
-  * \include JacobiSVD_basic.cpp
-  * Output: \verbinclude JacobiSVD_basic.out
-  *
-  * This JacobiSVD class is a two-sided Jacobi R-SVD decomposition, ensuring optimal reliability and accuracy. The downside is that it's slower than
-  * bidiagonalizing SVD algorithms for large square matrices; however its complexity is still \f$ O(n^2p) \f$ where \a n is the smaller dimension and
-  * \a p is the greater dimension, meaning that it is still of the same order of complexity as the faster bidiagonalizing R-SVD algorithms.
-  * In particular, like any R-SVD, it takes advantage of non-squareness in that its complexity is only linear in the greater dimension.
-  *
-  * If the input matrix has inf or nan coefficients, the result of the computation is undefined, but the computation is guaranteed to
-  * terminate in finite (and reasonable) time.
-  *
-  * The possible values for QRPreconditioner are:
-  * \li ColPivHouseholderQRPreconditioner is the default. In practice it's very safe. It uses column-pivoting QR.
-  * \li FullPivHouseholderQRPreconditioner, is the safest and slowest. It uses full-pivoting QR.
-  *     Contrary to other QRs, it doesn't allow computing thin unitaries.
-  * \li HouseholderQRPreconditioner is the fastest, and less safe and accurate than the pivoting variants. It uses non-pivoting QR.
-  *     This is very similar in safety and accuracy to the bidiagonalization process used by bidiagonalizing SVD algorithms (since bidiagonalization
-  *     is inherently non-pivoting). However the resulting SVD is still more reliable than bidiagonalizing SVDs because the Jacobi-based iterarive
-  *     process is more reliable than the optimized bidiagonal SVD iterations.
-  * \li NoQRPreconditioner allows not to use a QR preconditioner at all. This is useful if you know that you will only be computing
-  *     JacobiSVD decompositions of square matrices. Non-square matrices require a QR preconditioner. Using this option will result in
-  *     faster compilation and smaller executable code. It won't significantly speed up computation, since JacobiSVD is always checking
-  *     if QR preconditioning is needed before applying it anyway.
-  *
-  * \sa MatrixBase::jacobiSvd()
-  */
-template<typename _MatrixType, int QRPreconditioner> class JacobiSVD
- : public SVDBase<JacobiSVD<_MatrixType,QRPreconditioner> >
-{
-    typedef SVDBase<JacobiSVD> Base;
-  public:
-
-    typedef _MatrixType MatrixType;
-    typedef typename MatrixType::Scalar Scalar;
-    typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
-    enum {
-      RowsAtCompileTime = MatrixType::RowsAtCompileTime,
-      ColsAtCompileTime = MatrixType::ColsAtCompileTime,
-      DiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime,ColsAtCompileTime),
-      MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
-      MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
-      MaxDiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(MaxRowsAtCompileTime,MaxColsAtCompileTime),
-      MatrixOptions = MatrixType::Options
-    };
-
-    typedef typename Base::MatrixUType MatrixUType;
-    typedef typename Base::MatrixVType MatrixVType;
-    typedef typename Base::SingularValuesType SingularValuesType;
-    
-    typedef typename internal::plain_row_type<MatrixType>::type RowType;
-    typedef typename internal::plain_col_type<MatrixType>::type ColType;
-    typedef Matrix<Scalar, DiagSizeAtCompileTime, DiagSizeAtCompileTime,
-                   MatrixOptions, MaxDiagSizeAtCompileTime, MaxDiagSizeAtCompileTime>
-            WorkMatrixType;
-
-    /** \brief Default Constructor.
-      *
-      * The default constructor is useful in cases in which the user intends to
-      * perform decompositions via JacobiSVD::compute(const MatrixType&).
-      */
-    JacobiSVD()
-    {}
-
-
-    /** \brief Default Constructor with memory preallocation
-      *
-      * Like the default constructor but with preallocation of the internal data
-      * according to the specified problem size.
-      * \sa JacobiSVD()
-      */
-    JacobiSVD(Index rows, Index cols, unsigned int computationOptions = 0)
-    {
-      allocate(rows, cols, computationOptions);
-    }
-
-    /** \brief Constructor performing the decomposition of given matrix.
-     *
-     * \param matrix the matrix to decompose
-     * \param computationOptions optional parameter allowing to specify if you want full or thin U or V unitaries to be computed.
-     *                           By default, none is computed. This is a bit-field, the possible bits are #ComputeFullU, #ComputeThinU,
-     *                           #ComputeFullV, #ComputeThinV.
-     *
-     * Thin unitaries are only available if your matrix type has a Dynamic number of columns (for example MatrixXf). They also are not
-     * available with the (non-default) FullPivHouseholderQR preconditioner.
-     */
-    explicit JacobiSVD(const MatrixType& matrix, unsigned int computationOptions = 0)
-    {
-      compute(matrix, computationOptions);
-    }
-
-    /** \brief Method performing the decomposition of given matrix using custom options.
-     *
-     * \param matrix the matrix to decompose
-     * \param computationOptions optional parameter allowing to specify if you want full or thin U or V unitaries to be computed.
-     *                           By default, none is computed. This is a bit-field, the possible bits are #ComputeFullU, #ComputeThinU,
-     *                           #ComputeFullV, #ComputeThinV.
-     *
-     * Thin unitaries are only available if your matrix type has a Dynamic number of columns (for example MatrixXf). They also are not
-     * available with the (non-default) FullPivHouseholderQR preconditioner.
-     */
-    JacobiSVD& compute(const MatrixType& matrix, unsigned int computationOptions);
-
-    /** \brief Method performing the decomposition of given matrix using current options.
-     *
-     * \param matrix the matrix to decompose
-     *
-     * This method uses the current \a computationOptions, as already passed to the constructor or to compute(const MatrixType&, unsigned int).
-     */
-    JacobiSVD& compute(const MatrixType& matrix)
-    {
-      return compute(matrix, m_computationOptions);
-    }
-
-    using Base::computeU;
-    using Base::computeV;
-    using Base::rows;
-    using Base::cols;
-    using Base::rank;
-
-  private:
-    void allocate(Index rows, Index cols, unsigned int computationOptions);
-
-  protected:
-    using Base::m_matrixU;
-    using Base::m_matrixV;
-    using Base::m_singularValues;
-    using Base::m_isInitialized;
-    using Base::m_isAllocated;
-    using Base::m_usePrescribedThreshold;
-    using Base::m_computeFullU;
-    using Base::m_computeThinU;
-    using Base::m_computeFullV;
-    using Base::m_computeThinV;
-    using Base::m_computationOptions;
-    using Base::m_nonzeroSingularValues;
-    using Base::m_rows;
-    using Base::m_cols;
-    using Base::m_diagSize;
-    using Base::m_prescribedThreshold;
-    WorkMatrixType m_workMatrix;
-
-    template<typename __MatrixType, int _QRPreconditioner, bool _IsComplex>
-    friend struct internal::svd_precondition_2x2_block_to_be_real;
-    template<typename __MatrixType, int _QRPreconditioner, int _Case, bool _DoAnything>
-    friend struct internal::qr_preconditioner_impl;
-
-    internal::qr_preconditioner_impl<MatrixType, QRPreconditioner, internal::PreconditionIfMoreColsThanRows> m_qr_precond_morecols;
-    internal::qr_preconditioner_impl<MatrixType, QRPreconditioner, internal::PreconditionIfMoreRowsThanCols> m_qr_precond_morerows;
-    MatrixType m_scaledMatrix;
-};
-
-template<typename MatrixType, int QRPreconditioner>
-void JacobiSVD<MatrixType, QRPreconditioner>::allocate(Index rows, Index cols, unsigned int computationOptions)
-{
-  eigen_assert(rows >= 0 && cols >= 0);
-
-  if (m_isAllocated &&
-      rows == m_rows &&
-      cols == m_cols &&
-      computationOptions == m_computationOptions)
-  {
-    return;
-  }
-
-  m_rows = rows;
-  m_cols = cols;
-  m_isInitialized = false;
-  m_isAllocated = true;
-  m_computationOptions = computationOptions;
-  m_computeFullU = (computationOptions & ComputeFullU) != 0;
-  m_computeThinU = (computationOptions & ComputeThinU) != 0;
-  m_computeFullV = (computationOptions & ComputeFullV) != 0;
-  m_computeThinV = (computationOptions & ComputeThinV) != 0;
-  eigen_assert(!(m_computeFullU && m_computeThinU) && "JacobiSVD: you can't ask for both full and thin U");
-  eigen_assert(!(m_computeFullV && m_computeThinV) && "JacobiSVD: you can't ask for both full and thin V");
-  eigen_assert(EIGEN_IMPLIES(m_computeThinU || m_computeThinV, MatrixType::ColsAtCompileTime==Dynamic) &&
-              "JacobiSVD: thin U and V are only available when your matrix has a dynamic number of columns.");
-  if (QRPreconditioner == FullPivHouseholderQRPreconditioner)
-  {
-      eigen_assert(!(m_computeThinU || m_computeThinV) &&
-              "JacobiSVD: can't compute thin U or thin V with the FullPivHouseholderQR preconditioner. "
-              "Use the ColPivHouseholderQR preconditioner instead.");
-  }
-  m_diagSize = (std::min)(m_rows, m_cols);
-  m_singularValues.resize(m_diagSize);
-  if(RowsAtCompileTime==Dynamic)
-    m_matrixU.resize(m_rows, m_computeFullU ? m_rows
-                            : m_computeThinU ? m_diagSize
-                            : 0);
-  if(ColsAtCompileTime==Dynamic)
-    m_matrixV.resize(m_cols, m_computeFullV ? m_cols
-                            : m_computeThinV ? m_diagSize
-                            : 0);
-  m_workMatrix.resize(m_diagSize, m_diagSize);
-  
-  if(m_cols>m_rows)   m_qr_precond_morecols.allocate(*this);
-  if(m_rows>m_cols)   m_qr_precond_morerows.allocate(*this);
-  if(m_rows!=m_cols)  m_scaledMatrix.resize(rows,cols);
-}
-
-template<typename MatrixType, int QRPreconditioner>
-JacobiSVD<MatrixType, QRPreconditioner>&
-JacobiSVD<MatrixType, QRPreconditioner>::compute(const MatrixType& matrix, unsigned int computationOptions)
-{
-  using std::abs;
-  allocate(matrix.rows(), matrix.cols(), computationOptions);
-
-  // currently we stop when we reach precision 2*epsilon as the last bit of precision can require an unreasonable number of iterations,
-  // only worsening the precision of U and V as we accumulate more rotations
-  const RealScalar precision = RealScalar(2) * NumTraits<Scalar>::epsilon();
-
-  // limit for denormal numbers to be considered zero in order to avoid infinite loops (see bug 286)
-  const RealScalar considerAsZero = (std::numeric_limits<RealScalar>::min)();
-
-  // Scaling factor to reduce over/under-flows
-  RealScalar scale = matrix.cwiseAbs().maxCoeff();
-  if(scale==RealScalar(0)) scale = RealScalar(1);
-  
-  /*** step 1. The R-SVD step: we use a QR decomposition to reduce to the case of a square matrix */
-
-  if(m_rows!=m_cols)
-  {
-    m_scaledMatrix = matrix / scale;
-    m_qr_precond_morecols.run(*this, m_scaledMatrix);
-    m_qr_precond_morerows.run(*this, m_scaledMatrix);
-  }
-  else
-  {
-    m_workMatrix = matrix.block(0,0,m_diagSize,m_diagSize) / scale;
-    if(m_computeFullU) m_matrixU.setIdentity(m_rows,m_rows);
-    if(m_computeThinU) m_matrixU.setIdentity(m_rows,m_diagSize);
-    if(m_computeFullV) m_matrixV.setIdentity(m_cols,m_cols);
-    if(m_computeThinV) m_matrixV.setIdentity(m_cols, m_diagSize);
-  }
-
-  /*** step 2. The main Jacobi SVD iteration. ***/
-  RealScalar maxDiagEntry = m_workMatrix.cwiseAbs().diagonal().maxCoeff();
-
-  bool finished = false;
-  while(!finished)
-  {
-    finished = true;
-
-    // do a sweep: for all index pairs (p,q), perform SVD of the corresponding 2x2 sub-matrix
-
-    for(Index p = 1; p < m_diagSize; ++p)
-    {
-      for(Index q = 0; q < p; ++q)
-      {
-        // if this 2x2 sub-matrix is not diagonal already...
-        // notice that this comparison will evaluate to false if any NaN is involved, ensuring that NaN's don't
-        // keep us iterating forever. Similarly, small denormal numbers are considered zero.
-        RealScalar threshold = numext::maxi<RealScalar>(considerAsZero, precision * maxDiagEntry);
-        if(abs(m_workMatrix.coeff(p,q))>threshold || abs(m_workMatrix.coeff(q,p)) > threshold)
-        {
-          finished = false;
-          // perform SVD decomposition of 2x2 sub-matrix corresponding to indices p,q to make it diagonal
-          // the complex to real operation returns true if the updated 2x2 block is not already diagonal
-          if(internal::svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner>::run(m_workMatrix, *this, p, q, maxDiagEntry))
-          {
-            JacobiRotation<RealScalar> j_left, j_right;
-            internal::real_2x2_jacobi_svd(m_workMatrix, p, q, &j_left, &j_right);
-
-            // accumulate resulting Jacobi rotations
-            m_workMatrix.applyOnTheLeft(p,q,j_left);
-            if(computeU()) m_matrixU.applyOnTheRight(p,q,j_left.transpose());
-
-            m_workMatrix.applyOnTheRight(p,q,j_right);
-            if(computeV()) m_matrixV.applyOnTheRight(p,q,j_right);
-
-            // keep track of the largest diagonal coefficient
-            maxDiagEntry = numext::maxi<RealScalar>(maxDiagEntry,numext::maxi<RealScalar>(abs(m_workMatrix.coeff(p,p)), abs(m_workMatrix.coeff(q,q))));
-          }
-        }
-      }
-    }
-  }
-
-  /*** step 3. The work matrix is now diagonal, so ensure it's positive so its diagonal entries are the singular values ***/
-
-  for(Index i = 0; i < m_diagSize; ++i)
-  {
-    // For a complex matrix, some diagonal coefficients might note have been
-    // treated by svd_precondition_2x2_block_to_be_real, and the imaginary part
-    // of some diagonal entry might not be null.
-    if(NumTraits<Scalar>::IsComplex && abs(numext::imag(m_workMatrix.coeff(i,i)))>considerAsZero)
-    {
-      RealScalar a = abs(m_workMatrix.coeff(i,i));
-      m_singularValues.coeffRef(i) = abs(a);
-      if(computeU()) m_matrixU.col(i) *= m_workMatrix.coeff(i,i)/a;
-    }
-    else
-    {
-      // m_workMatrix.coeff(i,i) is already real, no difficulty:
-      RealScalar a = numext::real(m_workMatrix.coeff(i,i));
-      m_singularValues.coeffRef(i) = abs(a);
-      if(computeU() && (a<RealScalar(0))) m_matrixU.col(i) = -m_matrixU.col(i);
-    }
-  }
-  
-  m_singularValues *= scale;
-
-  /*** step 4. Sort singular values in descending order and compute the number of nonzero singular values ***/
-
-  m_nonzeroSingularValues = m_diagSize;
-  for(Index i = 0; i < m_diagSize; i++)
-  {
-    Index pos;
-    RealScalar maxRemainingSingularValue = m_singularValues.tail(m_diagSize-i).maxCoeff(&pos);
-    if(maxRemainingSingularValue == RealScalar(0))
-    {
-      m_nonzeroSingularValues = i;
-      break;
-    }
-    if(pos)
-    {
-      pos += i;
-      std::swap(m_singularValues.coeffRef(i), m_singularValues.coeffRef(pos));
-      if(computeU()) m_matrixU.col(pos).swap(m_matrixU.col(i));
-      if(computeV()) m_matrixV.col(pos).swap(m_matrixV.col(i));
-    }
-  }
-
-  m_isInitialized = true;
-  return *this;
-}
-
-/** \svd_module
-  *
-  * \return the singular value decomposition of \c *this computed by two-sided
-  * Jacobi transformations.
-  *
-  * \sa class JacobiSVD
-  */
-template<typename Derived>
-JacobiSVD<typename MatrixBase<Derived>::PlainObject>
-MatrixBase<Derived>::jacobiSvd(unsigned int computationOptions) const
-{
-  return JacobiSVD<PlainObject>(*this, computationOptions);
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_JACOBISVD_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/SVD/SVDBase.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/SVD/SVDBase.h
deleted file mode 100644
index 3d1ef37..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/SVD/SVDBase.h
+++ /dev/null
@@ -1,315 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2014 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// Copyright (C) 2013 Gauthier Brun <brun.gauthier@gmail.com>
-// Copyright (C) 2013 Nicolas Carre <nicolas.carre@ensimag.fr>
-// Copyright (C) 2013 Jean Ceccato <jean.ceccato@ensimag.fr>
-// Copyright (C) 2013 Pierre Zoppitelli <pierre.zoppitelli@ensimag.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_SVDBASE_H
-#define EIGEN_SVDBASE_H
-
-namespace Eigen {
-/** \ingroup SVD_Module
- *
- *
- * \class SVDBase
- *
- * \brief Base class of SVD algorithms
- *
- * \tparam Derived the type of the actual SVD decomposition
- *
- * SVD decomposition consists in decomposing any n-by-p matrix \a A as a product
- *   \f[ A = U S V^* \f]
- * where \a U is a n-by-n unitary, \a V is a p-by-p unitary, and \a S is a n-by-p real positive matrix which is zero outside of its main diagonal;
- * the diagonal entries of S are known as the \em singular \em values of \a A and the columns of \a U and \a V are known as the left
- * and right \em singular \em vectors of \a A respectively.
- *
- * Singular values are always sorted in decreasing order.
- *
- * 
- * You can ask for only \em thin \a U or \a V to be computed, meaning the following. In case of a rectangular n-by-p matrix, letting \a m be the
- * smaller value among \a n and \a p, there are only \a m singular vectors; the remaining columns of \a U and \a V do not correspond to actual
- * singular vectors. Asking for \em thin \a U or \a V means asking for only their \a m first columns to be formed. So \a U is then a n-by-m matrix,
- * and \a V is then a p-by-m matrix. Notice that thin \a U and \a V are all you need for (least squares) solving.
- *  
- * If the input matrix has inf or nan coefficients, the result of the computation is undefined, but the computation is guaranteed to
- * terminate in finite (and reasonable) time.
- * \sa class BDCSVD, class JacobiSVD
- */
-template<typename Derived>
-class SVDBase
-{
-
-public:
-  typedef typename internal::traits<Derived>::MatrixType MatrixType;
-  typedef typename MatrixType::Scalar Scalar;
-  typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
-  typedef typename MatrixType::StorageIndex StorageIndex;
-  typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
-  enum {
-    RowsAtCompileTime = MatrixType::RowsAtCompileTime,
-    ColsAtCompileTime = MatrixType::ColsAtCompileTime,
-    DiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime,ColsAtCompileTime),
-    MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
-    MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
-    MaxDiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(MaxRowsAtCompileTime,MaxColsAtCompileTime),
-    MatrixOptions = MatrixType::Options
-  };
-
-  typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime, MatrixOptions, MaxRowsAtCompileTime, MaxRowsAtCompileTime> MatrixUType;
-  typedef Matrix<Scalar, ColsAtCompileTime, ColsAtCompileTime, MatrixOptions, MaxColsAtCompileTime, MaxColsAtCompileTime> MatrixVType;
-  typedef typename internal::plain_diag_type<MatrixType, RealScalar>::type SingularValuesType;
-  
-  Derived& derived() { return *static_cast<Derived*>(this); }
-  const Derived& derived() const { return *static_cast<const Derived*>(this); }
-
-  /** \returns the \a U matrix.
-   *
-   * For the SVD decomposition of a n-by-p matrix, letting \a m be the minimum of \a n and \a p,
-   * the U matrix is n-by-n if you asked for \link Eigen::ComputeFullU ComputeFullU \endlink, and is n-by-m if you asked for \link Eigen::ComputeThinU ComputeThinU \endlink.
-   *
-   * The \a m first columns of \a U are the left singular vectors of the matrix being decomposed.
-   *
-   * This method asserts that you asked for \a U to be computed.
-   */
-  const MatrixUType& matrixU() const
-  {
-    eigen_assert(m_isInitialized && "SVD is not initialized.");
-    eigen_assert(computeU() && "This SVD decomposition didn't compute U. Did you ask for it?");
-    return m_matrixU;
-  }
-
-  /** \returns the \a V matrix.
-   *
-   * For the SVD decomposition of a n-by-p matrix, letting \a m be the minimum of \a n and \a p,
-   * the V matrix is p-by-p if you asked for \link Eigen::ComputeFullV ComputeFullV \endlink, and is p-by-m if you asked for \link Eigen::ComputeThinV ComputeThinV \endlink.
-   *
-   * The \a m first columns of \a V are the right singular vectors of the matrix being decomposed.
-   *
-   * This method asserts that you asked for \a V to be computed.
-   */
-  const MatrixVType& matrixV() const
-  {
-    eigen_assert(m_isInitialized && "SVD is not initialized.");
-    eigen_assert(computeV() && "This SVD decomposition didn't compute V. Did you ask for it?");
-    return m_matrixV;
-  }
-
-  /** \returns the vector of singular values.
-   *
-   * For the SVD decomposition of a n-by-p matrix, letting \a m be the minimum of \a n and \a p, the
-   * returned vector has size \a m.  Singular values are always sorted in decreasing order.
-   */
-  const SingularValuesType& singularValues() const
-  {
-    eigen_assert(m_isInitialized && "SVD is not initialized.");
-    return m_singularValues;
-  }
-
-  /** \returns the number of singular values that are not exactly 0 */
-  Index nonzeroSingularValues() const
-  {
-    eigen_assert(m_isInitialized && "SVD is not initialized.");
-    return m_nonzeroSingularValues;
-  }
-  
-  /** \returns the rank of the matrix of which \c *this is the SVD.
-    *
-    * \note This method has to determine which singular values should be considered nonzero.
-    *       For that, it uses the threshold value that you can control by calling
-    *       setThreshold(const RealScalar&).
-    */
-  inline Index rank() const
-  {
-    using std::abs;
-    eigen_assert(m_isInitialized && "JacobiSVD is not initialized.");
-    if(m_singularValues.size()==0) return 0;
-    RealScalar premultiplied_threshold = numext::maxi<RealScalar>(m_singularValues.coeff(0) * threshold(), (std::numeric_limits<RealScalar>::min)());
-    Index i = m_nonzeroSingularValues-1;
-    while(i>=0 && m_singularValues.coeff(i) < premultiplied_threshold) --i;
-    return i+1;
-  }
-  
-  /** Allows to prescribe a threshold to be used by certain methods, such as rank() and solve(),
-    * which need to determine when singular values are to be considered nonzero.
-    * This is not used for the SVD decomposition itself.
-    *
-    * When it needs to get the threshold value, Eigen calls threshold().
-    * The default is \c NumTraits<Scalar>::epsilon()
-    *
-    * \param threshold The new value to use as the threshold.
-    *
-    * A singular value will be considered nonzero if its value is strictly greater than
-    *  \f$ \vert singular value \vert \leqslant threshold \times \vert max singular value \vert \f$.
-    *
-    * If you want to come back to the default behavior, call setThreshold(Default_t)
-    */
-  Derived& setThreshold(const RealScalar& threshold)
-  {
-    m_usePrescribedThreshold = true;
-    m_prescribedThreshold = threshold;
-    return derived();
-  }
-
-  /** Allows to come back to the default behavior, letting Eigen use its default formula for
-    * determining the threshold.
-    *
-    * You should pass the special object Eigen::Default as parameter here.
-    * \code svd.setThreshold(Eigen::Default); \endcode
-    *
-    * See the documentation of setThreshold(const RealScalar&).
-    */
-  Derived& setThreshold(Default_t)
-  {
-    m_usePrescribedThreshold = false;
-    return derived();
-  }
-
-  /** Returns the threshold that will be used by certain methods such as rank().
-    *
-    * See the documentation of setThreshold(const RealScalar&).
-    */
-  RealScalar threshold() const
-  {
-    eigen_assert(m_isInitialized || m_usePrescribedThreshold);
-    // this temporary is needed to workaround a MSVC issue
-    Index diagSize = (std::max<Index>)(1,m_diagSize);
-    return m_usePrescribedThreshold ? m_prescribedThreshold
-                                    : diagSize*NumTraits<Scalar>::epsilon();
-  }
-
-  /** \returns true if \a U (full or thin) is asked for in this SVD decomposition */
-  inline bool computeU() const { return m_computeFullU || m_computeThinU; }
-  /** \returns true if \a V (full or thin) is asked for in this SVD decomposition */
-  inline bool computeV() const { return m_computeFullV || m_computeThinV; }
-
-  inline Index rows() const { return m_rows; }
-  inline Index cols() const { return m_cols; }
-  
-  /** \returns a (least squares) solution of \f$ A x = b \f$ using the current SVD decomposition of A.
-    *
-    * \param b the right-hand-side of the equation to solve.
-    *
-    * \note Solving requires both U and V to be computed. Thin U and V are enough, there is no need for full U or V.
-    *
-    * \note SVD solving is implicitly least-squares. Thus, this method serves both purposes of exact solving and least-squares solving.
-    * In other words, the returned solution is guaranteed to minimize the Euclidean norm \f$ \Vert A x - b \Vert \f$.
-    */
-  template<typename Rhs>
-  inline const Solve<Derived, Rhs>
-  solve(const MatrixBase<Rhs>& b) const
-  {
-    eigen_assert(m_isInitialized && "SVD is not initialized.");
-    eigen_assert(computeU() && computeV() && "SVD::solve() requires both unitaries U and V to be computed (thin unitaries suffice).");
-    return Solve<Derived, Rhs>(derived(), b.derived());
-  }
-  
-  #ifndef EIGEN_PARSED_BY_DOXYGEN
-  template<typename RhsType, typename DstType>
-  EIGEN_DEVICE_FUNC
-  void _solve_impl(const RhsType &rhs, DstType &dst) const;
-  #endif
-
-protected:
-  
-  static void check_template_parameters()
-  {
-    EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
-  }
-  
-  // return true if already allocated
-  bool allocate(Index rows, Index cols, unsigned int computationOptions) ;
-
-  MatrixUType m_matrixU;
-  MatrixVType m_matrixV;
-  SingularValuesType m_singularValues;
-  bool m_isInitialized, m_isAllocated, m_usePrescribedThreshold;
-  bool m_computeFullU, m_computeThinU;
-  bool m_computeFullV, m_computeThinV;
-  unsigned int m_computationOptions;
-  Index m_nonzeroSingularValues, m_rows, m_cols, m_diagSize;
-  RealScalar m_prescribedThreshold;
-
-  /** \brief Default Constructor.
-   *
-   * Default constructor of SVDBase
-   */
-  SVDBase()
-    : m_isInitialized(false),
-      m_isAllocated(false),
-      m_usePrescribedThreshold(false),
-      m_computationOptions(0),
-      m_rows(-1), m_cols(-1), m_diagSize(0)
-  {
-    check_template_parameters();
-  }
-
-
-};
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-template<typename Derived>
-template<typename RhsType, typename DstType>
-void SVDBase<Derived>::_solve_impl(const RhsType &rhs, DstType &dst) const
-{
-  eigen_assert(rhs.rows() == rows());
-
-  // A = U S V^*
-  // So A^{-1} = V S^{-1} U^*
-
-  Matrix<Scalar, Dynamic, RhsType::ColsAtCompileTime, 0, MatrixType::MaxRowsAtCompileTime, RhsType::MaxColsAtCompileTime> tmp;
-  Index l_rank = rank();
-  tmp.noalias() =  m_matrixU.leftCols(l_rank).adjoint() * rhs;
-  tmp = m_singularValues.head(l_rank).asDiagonal().inverse() * tmp;
-  dst = m_matrixV.leftCols(l_rank) * tmp;
-}
-#endif
-
-template<typename MatrixType>
-bool SVDBase<MatrixType>::allocate(Index rows, Index cols, unsigned int computationOptions)
-{
-  eigen_assert(rows >= 0 && cols >= 0);
-
-  if (m_isAllocated &&
-      rows == m_rows &&
-      cols == m_cols &&
-      computationOptions == m_computationOptions)
-  {
-    return true;
-  }
-
-  m_rows = rows;
-  m_cols = cols;
-  m_isInitialized = false;
-  m_isAllocated = true;
-  m_computationOptions = computationOptions;
-  m_computeFullU = (computationOptions & ComputeFullU) != 0;
-  m_computeThinU = (computationOptions & ComputeThinU) != 0;
-  m_computeFullV = (computationOptions & ComputeFullV) != 0;
-  m_computeThinV = (computationOptions & ComputeThinV) != 0;
-  eigen_assert(!(m_computeFullU && m_computeThinU) && "SVDBase: you can't ask for both full and thin U");
-  eigen_assert(!(m_computeFullV && m_computeThinV) && "SVDBase: you can't ask for both full and thin V");
-  eigen_assert(EIGEN_IMPLIES(m_computeThinU || m_computeThinV, MatrixType::ColsAtCompileTime==Dynamic) &&
-	       "SVDBase: thin U and V are only available when your matrix has a dynamic number of columns.");
-
-  m_diagSize = (std::min)(m_rows, m_cols);
-  m_singularValues.resize(m_diagSize);
-  if(RowsAtCompileTime==Dynamic)
-    m_matrixU.resize(m_rows, m_computeFullU ? m_rows : m_computeThinU ? m_diagSize : 0);
-  if(ColsAtCompileTime==Dynamic)
-    m_matrixV.resize(m_cols, m_computeFullV ? m_cols : m_computeThinV ? m_diagSize : 0);
-
-  return false;
-}
-
-}// end namespace
-
-#endif // EIGEN_SVDBASE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/SVD/UpperBidiagonalization.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/SVD/UpperBidiagonalization.h
deleted file mode 100644
index 11ac847..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/SVD/UpperBidiagonalization.h
+++ /dev/null
@@ -1,414 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2013-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_BIDIAGONALIZATION_H
-#define EIGEN_BIDIAGONALIZATION_H
-
-namespace Eigen { 
-
-namespace internal {
-// UpperBidiagonalization will probably be replaced by a Bidiagonalization class, don't want to make it stable API.
-// At the same time, it's useful to keep for now as it's about the only thing that is testing the BandMatrix class.
-
-template<typename _MatrixType> class UpperBidiagonalization
-{
-  public:
-
-    typedef _MatrixType MatrixType;
-    enum {
-      RowsAtCompileTime = MatrixType::RowsAtCompileTime,
-      ColsAtCompileTime = MatrixType::ColsAtCompileTime,
-      ColsAtCompileTimeMinusOne = internal::decrement_size<ColsAtCompileTime>::ret
-    };
-    typedef typename MatrixType::Scalar Scalar;
-    typedef typename MatrixType::RealScalar RealScalar;
-    typedef Eigen::Index Index; ///< \deprecated since Eigen 3.3
-    typedef Matrix<Scalar, 1, ColsAtCompileTime> RowVectorType;
-    typedef Matrix<Scalar, RowsAtCompileTime, 1> ColVectorType;
-    typedef BandMatrix<RealScalar, ColsAtCompileTime, ColsAtCompileTime, 1, 0, RowMajor> BidiagonalType;
-    typedef Matrix<Scalar, ColsAtCompileTime, 1> DiagVectorType;
-    typedef Matrix<Scalar, ColsAtCompileTimeMinusOne, 1> SuperDiagVectorType;
-    typedef HouseholderSequence<
-              const MatrixType,
-              const typename internal::remove_all<typename Diagonal<const MatrixType,0>::ConjugateReturnType>::type
-            > HouseholderUSequenceType;
-    typedef HouseholderSequence<
-              const typename internal::remove_all<typename MatrixType::ConjugateReturnType>::type,
-              Diagonal<const MatrixType,1>,
-              OnTheRight
-            > HouseholderVSequenceType;
-    
-    /**
-    * \brief Default Constructor.
-    *
-    * The default constructor is useful in cases in which the user intends to
-    * perform decompositions via Bidiagonalization::compute(const MatrixType&).
-    */
-    UpperBidiagonalization() : m_householder(), m_bidiagonal(), m_isInitialized(false) {}
-
-    explicit UpperBidiagonalization(const MatrixType& matrix)
-      : m_householder(matrix.rows(), matrix.cols()),
-        m_bidiagonal(matrix.cols(), matrix.cols()),
-        m_isInitialized(false)
-    {
-      compute(matrix);
-    }
-    
-    UpperBidiagonalization& compute(const MatrixType& matrix);
-    UpperBidiagonalization& computeUnblocked(const MatrixType& matrix);
-    
-    const MatrixType& householder() const { return m_householder; }
-    const BidiagonalType& bidiagonal() const { return m_bidiagonal; }
-    
-    const HouseholderUSequenceType householderU() const
-    {
-      eigen_assert(m_isInitialized && "UpperBidiagonalization is not initialized.");
-      return HouseholderUSequenceType(m_householder, m_householder.diagonal().conjugate());
-    }
-
-    const HouseholderVSequenceType householderV() // const here gives nasty errors and i'm lazy
-    {
-      eigen_assert(m_isInitialized && "UpperBidiagonalization is not initialized.");
-      return HouseholderVSequenceType(m_householder.conjugate(), m_householder.const_derived().template diagonal<1>())
-             .setLength(m_householder.cols()-1)
-             .setShift(1);
-    }
-    
-  protected:
-    MatrixType m_householder;
-    BidiagonalType m_bidiagonal;
-    bool m_isInitialized;
-};
-
-// Standard upper bidiagonalization without fancy optimizations
-// This version should be faster for small matrix size
-template<typename MatrixType>
-void upperbidiagonalization_inplace_unblocked(MatrixType& mat,
-                                              typename MatrixType::RealScalar *diagonal,
-                                              typename MatrixType::RealScalar *upper_diagonal,
-                                              typename MatrixType::Scalar* tempData = 0)
-{
-  typedef typename MatrixType::Scalar Scalar;
-
-  Index rows = mat.rows();
-  Index cols = mat.cols();
-
-  typedef Matrix<Scalar,Dynamic,1,ColMajor,MatrixType::MaxRowsAtCompileTime,1> TempType;
-  TempType tempVector;
-  if(tempData==0)
-  {
-    tempVector.resize(rows);
-    tempData = tempVector.data();
-  }
-
-  for (Index k = 0; /* breaks at k==cols-1 below */ ; ++k)
-  {
-    Index remainingRows = rows - k;
-    Index remainingCols = cols - k - 1;
-
-    // construct left householder transform in-place in A
-    mat.col(k).tail(remainingRows)
-       .makeHouseholderInPlace(mat.coeffRef(k,k), diagonal[k]);
-    // apply householder transform to remaining part of A on the left
-    mat.bottomRightCorner(remainingRows, remainingCols)
-       .applyHouseholderOnTheLeft(mat.col(k).tail(remainingRows-1), mat.coeff(k,k), tempData);
-
-    if(k == cols-1) break;
-
-    // construct right householder transform in-place in mat
-    mat.row(k).tail(remainingCols)
-       .makeHouseholderInPlace(mat.coeffRef(k,k+1), upper_diagonal[k]);
-    // apply householder transform to remaining part of mat on the left
-    mat.bottomRightCorner(remainingRows-1, remainingCols)
-       .applyHouseholderOnTheRight(mat.row(k).tail(remainingCols-1).transpose(), mat.coeff(k,k+1), tempData);
-  }
-}
-
-/** \internal
-  * Helper routine for the block reduction to upper bidiagonal form.
-  *
-  * Let's partition the matrix A:
-  * 
-  *      | A00 A01 |
-  *  A = |         |
-  *      | A10 A11 |
-  *
-  * This function reduces to bidiagonal form the left \c rows x \a blockSize vertical panel [A00/A10]
-  * and the \a blockSize x \c cols horizontal panel [A00 A01] of the matrix \a A. The bottom-right block A11
-  * is updated using matrix-matrix products:
-  *   A22 -= V * Y^T - X * U^T
-  * where V and U contains the left and right Householder vectors. U and V are stored in A10, and A01
-  * respectively, and the update matrices X and Y are computed during the reduction.
-  * 
-  */
-template<typename MatrixType>
-void upperbidiagonalization_blocked_helper(MatrixType& A,
-                                           typename MatrixType::RealScalar *diagonal,
-                                           typename MatrixType::RealScalar *upper_diagonal,
-                                           Index bs,
-                                           Ref<Matrix<typename MatrixType::Scalar, Dynamic, Dynamic,
-                                                      traits<MatrixType>::Flags & RowMajorBit> > X,
-                                           Ref<Matrix<typename MatrixType::Scalar, Dynamic, Dynamic,
-                                                      traits<MatrixType>::Flags & RowMajorBit> > Y)
-{
-  typedef typename MatrixType::Scalar Scalar;
-  typedef typename MatrixType::RealScalar RealScalar;
-  typedef typename NumTraits<RealScalar>::Literal Literal;
-  enum { StorageOrder = traits<MatrixType>::Flags & RowMajorBit };
-  typedef InnerStride<int(StorageOrder) == int(ColMajor) ? 1 : Dynamic> ColInnerStride;
-  typedef InnerStride<int(StorageOrder) == int(ColMajor) ? Dynamic : 1> RowInnerStride;
-  typedef Ref<Matrix<Scalar, Dynamic, 1>, 0, ColInnerStride>    SubColumnType;
-  typedef Ref<Matrix<Scalar, 1, Dynamic>, 0, RowInnerStride>    SubRowType;
-  typedef Ref<Matrix<Scalar, Dynamic, Dynamic, StorageOrder > > SubMatType;
-  
-  Index brows = A.rows();
-  Index bcols = A.cols();
-
-  Scalar tau_u, tau_u_prev(0), tau_v;
-
-  for(Index k = 0; k < bs; ++k)
-  {
-    Index remainingRows = brows - k;
-    Index remainingCols = bcols - k - 1;
-
-    SubMatType X_k1( X.block(k,0, remainingRows,k) );
-    SubMatType V_k1( A.block(k,0, remainingRows,k) );
-
-    // 1 - update the k-th column of A
-    SubColumnType v_k = A.col(k).tail(remainingRows);
-          v_k -= V_k1 * Y.row(k).head(k).adjoint();
-    if(k) v_k -= X_k1 * A.col(k).head(k);
-    
-    // 2 - construct left Householder transform in-place
-    v_k.makeHouseholderInPlace(tau_v, diagonal[k]);
-       
-    if(k+1<bcols)
-    {
-      SubMatType Y_k  ( Y.block(k+1,0, remainingCols, k+1) );
-      SubMatType U_k1 ( A.block(0,k+1, k,remainingCols) );
-      
-      // this eases the application of Householder transforAions
-      // A(k,k) will store tau_v later
-      A(k,k) = Scalar(1);
-
-      // 3 - Compute y_k^T = tau_v * ( A^T*v_k - Y_k-1*V_k-1^T*v_k - U_k-1*X_k-1^T*v_k )
-      {
-        SubColumnType y_k( Y.col(k).tail(remainingCols) );
-        
-        // let's use the begining of column k of Y as a temporary vector
-        SubColumnType tmp( Y.col(k).head(k) );
-        y_k.noalias()  = A.block(k,k+1, remainingRows,remainingCols).adjoint() * v_k; // bottleneck
-        tmp.noalias()  = V_k1.adjoint()  * v_k;
-        y_k.noalias() -= Y_k.leftCols(k) * tmp;
-        tmp.noalias()  = X_k1.adjoint()  * v_k;
-        y_k.noalias() -= U_k1.adjoint()  * tmp;
-        y_k *= numext::conj(tau_v);
-      }
-
-      // 4 - update k-th row of A (it will become u_k)
-      SubRowType u_k( A.row(k).tail(remainingCols) );
-      u_k = u_k.conjugate();
-      {
-        u_k -= Y_k * A.row(k).head(k+1).adjoint();
-        if(k) u_k -= U_k1.adjoint() * X.row(k).head(k).adjoint();
-      }
-
-      // 5 - construct right Householder transform in-place
-      u_k.makeHouseholderInPlace(tau_u, upper_diagonal[k]);
-
-      // this eases the application of Householder transformations
-      // A(k,k+1) will store tau_u later
-      A(k,k+1) = Scalar(1);
-
-      // 6 - Compute x_k = tau_u * ( A*u_k - X_k-1*U_k-1^T*u_k - V_k*Y_k^T*u_k )
-      {
-        SubColumnType x_k ( X.col(k).tail(remainingRows-1) );
-        
-        // let's use the begining of column k of X as a temporary vectors
-        // note that tmp0 and tmp1 overlaps
-        SubColumnType tmp0 ( X.col(k).head(k) ),
-                      tmp1 ( X.col(k).head(k+1) );
-                    
-        x_k.noalias()   = A.block(k+1,k+1, remainingRows-1,remainingCols) * u_k.transpose(); // bottleneck
-        tmp0.noalias()  = U_k1 * u_k.transpose();
-        x_k.noalias()  -= X_k1.bottomRows(remainingRows-1) * tmp0;
-        tmp1.noalias()  = Y_k.adjoint() * u_k.transpose();
-        x_k.noalias()  -= A.block(k+1,0, remainingRows-1,k+1) * tmp1;
-        x_k *= numext::conj(tau_u);
-        tau_u = numext::conj(tau_u);
-        u_k = u_k.conjugate();
-      }
-
-      if(k>0) A.coeffRef(k-1,k) = tau_u_prev;
-      tau_u_prev = tau_u;
-    }
-    else
-      A.coeffRef(k-1,k) = tau_u_prev;
-
-    A.coeffRef(k,k) = tau_v;
-  }
-  
-  if(bs<bcols)
-    A.coeffRef(bs-1,bs) = tau_u_prev;
-
-  // update A22
-  if(bcols>bs && brows>bs)
-  {
-    SubMatType A11( A.bottomRightCorner(brows-bs,bcols-bs) );
-    SubMatType A10( A.block(bs,0, brows-bs,bs) );
-    SubMatType A01( A.block(0,bs, bs,bcols-bs) );
-    Scalar tmp = A01(bs-1,0);
-    A01(bs-1,0) = Literal(1);
-    A11.noalias() -= A10 * Y.topLeftCorner(bcols,bs).bottomRows(bcols-bs).adjoint();
-    A11.noalias() -= X.topLeftCorner(brows,bs).bottomRows(brows-bs) * A01;
-    A01(bs-1,0) = tmp;
-  }
-}
-
-/** \internal
-  *
-  * Implementation of a block-bidiagonal reduction.
-  * It is based on the following paper:
-  *   The Design of a Parallel Dense Linear Algebra Software Library: Reduction to Hessenberg, Tridiagonal, and Bidiagonal Form.
-  *   by Jaeyoung Choi, Jack J. Dongarra, David W. Walker. (1995)
-  *   section 3.3
-  */
-template<typename MatrixType, typename BidiagType>
-void upperbidiagonalization_inplace_blocked(MatrixType& A, BidiagType& bidiagonal,
-                                            Index maxBlockSize=32,
-                                            typename MatrixType::Scalar* /*tempData*/ = 0)
-{
-  typedef typename MatrixType::Scalar Scalar;
-  typedef Block<MatrixType,Dynamic,Dynamic> BlockType;
-
-  Index rows = A.rows();
-  Index cols = A.cols();
-  Index size = (std::min)(rows, cols);
-
-  // X and Y are work space
-  enum { StorageOrder = traits<MatrixType>::Flags & RowMajorBit };
-  Matrix<Scalar,
-         MatrixType::RowsAtCompileTime,
-         Dynamic,
-         StorageOrder,
-         MatrixType::MaxRowsAtCompileTime> X(rows,maxBlockSize);
-  Matrix<Scalar,
-         MatrixType::ColsAtCompileTime,
-         Dynamic,
-         StorageOrder,
-         MatrixType::MaxColsAtCompileTime> Y(cols,maxBlockSize);
-  Index blockSize = (std::min)(maxBlockSize,size);
-
-  Index k = 0;
-  for(k = 0; k < size; k += blockSize)
-  {
-    Index bs = (std::min)(size-k,blockSize);  // actual size of the block
-    Index brows = rows - k;                   // rows of the block
-    Index bcols = cols - k;                   // columns of the block
-
-    // partition the matrix A:
-    // 
-    //      | A00 A01 A02 |
-    //      |             |
-    // A  = | A10 A11 A12 |
-    //      |             |
-    //      | A20 A21 A22 |
-    //
-    // where A11 is a bs x bs diagonal block,
-    // and let:
-    //      | A11 A12 |
-    //  B = |         |
-    //      | A21 A22 |
-
-    BlockType B = A.block(k,k,brows,bcols);
-    
-    // This stage performs the bidiagonalization of A11, A21, A12, and updating of A22.
-    // Finally, the algorithm continue on the updated A22.
-    //
-    // However, if B is too small, or A22 empty, then let's use an unblocked strategy
-    if(k+bs==cols || bcols<48) // somewhat arbitrary threshold
-    {
-      upperbidiagonalization_inplace_unblocked(B,
-                                               &(bidiagonal.template diagonal<0>().coeffRef(k)),
-                                               &(bidiagonal.template diagonal<1>().coeffRef(k)),
-                                               X.data()
-                                              );
-      break; // We're done
-    }
-    else
-    {
-      upperbidiagonalization_blocked_helper<BlockType>( B,
-                                                        &(bidiagonal.template diagonal<0>().coeffRef(k)),
-                                                        &(bidiagonal.template diagonal<1>().coeffRef(k)),
-                                                        bs,
-                                                        X.topLeftCorner(brows,bs),
-                                                        Y.topLeftCorner(bcols,bs)
-                                                      );
-    }
-  }
-}
-
-template<typename _MatrixType>
-UpperBidiagonalization<_MatrixType>& UpperBidiagonalization<_MatrixType>::computeUnblocked(const _MatrixType& matrix)
-{
-  Index rows = matrix.rows();
-  Index cols = matrix.cols();
-  EIGEN_ONLY_USED_FOR_DEBUG(cols);
-
-  eigen_assert(rows >= cols && "UpperBidiagonalization is only for Arices satisfying rows>=cols.");
-
-  m_householder = matrix;
-
-  ColVectorType temp(rows);
-
-  upperbidiagonalization_inplace_unblocked(m_householder,
-                                           &(m_bidiagonal.template diagonal<0>().coeffRef(0)),
-                                           &(m_bidiagonal.template diagonal<1>().coeffRef(0)),
-                                           temp.data());
-
-  m_isInitialized = true;
-  return *this;
-}
-
-template<typename _MatrixType>
-UpperBidiagonalization<_MatrixType>& UpperBidiagonalization<_MatrixType>::compute(const _MatrixType& matrix)
-{
-  Index rows = matrix.rows();
-  Index cols = matrix.cols();
-  EIGEN_ONLY_USED_FOR_DEBUG(rows);
-  EIGEN_ONLY_USED_FOR_DEBUG(cols);
-
-  eigen_assert(rows >= cols && "UpperBidiagonalization is only for Arices satisfying rows>=cols.");
-
-  m_householder = matrix;
-  upperbidiagonalization_inplace_blocked(m_householder, m_bidiagonal);
-            
-  m_isInitialized = true;
-  return *this;
-}
-
-#if 0
-/** \return the Householder QR decomposition of \c *this.
-  *
-  * \sa class Bidiagonalization
-  */
-template<typename Derived>
-const UpperBidiagonalization<typename MatrixBase<Derived>::PlainObject>
-MatrixBase<Derived>::bidiagonalization() const
-{
-  return UpperBidiagonalization<PlainObject>(eval());
-}
-#endif
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_BIDIAGONALIZATION_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/StlSupport/StdDeque.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/StlSupport/StdDeque.h
deleted file mode 100644
index cf1fedf..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/StlSupport/StdDeque.h
+++ /dev/null
@@ -1,126 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_STDDEQUE_H
-#define EIGEN_STDDEQUE_H
-
-#include "details.h"
-
-/**
- * This section contains a convenience MACRO which allows an easy specialization of
- * std::deque such that for data types with alignment issues the correct allocator
- * is used automatically.
- */
-#define EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(...) \
-namespace std \
-{ \
-  template<> \
-  class deque<__VA_ARGS__, std::allocator<__VA_ARGS__> >           \
-    : public deque<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > \
-  { \
-    typedef deque<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > deque_base; \
-  public: \
-    typedef __VA_ARGS__ value_type; \
-    typedef deque_base::allocator_type allocator_type; \
-    typedef deque_base::size_type size_type;  \
-    typedef deque_base::iterator iterator;  \
-    explicit deque(const allocator_type& a = allocator_type()) : deque_base(a) {}  \
-    template<typename InputIterator> \
-    deque(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) : deque_base(first, last, a) {} \
-    deque(const deque& c) : deque_base(c) {}  \
-    explicit deque(size_type num, const value_type& val = value_type()) : deque_base(num, val) {} \
-    deque(iterator start, iterator end) : deque_base(start, end) {}  \
-    deque& operator=(const deque& x) {  \
-      deque_base::operator=(x);  \
-      return *this;  \
-    } \
-  }; \
-}
-
-// check whether we really need the std::deque specialization
-#if !EIGEN_HAS_CXX11_CONTAINERS && !(defined(_GLIBCXX_DEQUE) && (!EIGEN_GNUC_AT_LEAST(4,1))) /* Note that before gcc-4.1 we already have: std::deque::resize(size_type,const T&). */
-
-namespace std {
-
-#define EIGEN_STD_DEQUE_SPECIALIZATION_BODY \
-  public:  \
-    typedef T value_type; \
-    typedef typename deque_base::allocator_type allocator_type; \
-    typedef typename deque_base::size_type size_type;  \
-    typedef typename deque_base::iterator iterator;  \
-    typedef typename deque_base::const_iterator const_iterator;  \
-    explicit deque(const allocator_type& a = allocator_type()) : deque_base(a) {}  \
-    template<typename InputIterator> \
-    deque(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) \
-    : deque_base(first, last, a) {} \
-    deque(const deque& c) : deque_base(c) {}  \
-    explicit deque(size_type num, const value_type& val = value_type()) : deque_base(num, val) {} \
-    deque(iterator start, iterator end) : deque_base(start, end) {}  \
-    deque& operator=(const deque& x) {  \
-      deque_base::operator=(x);  \
-      return *this;  \
-    }
-
-  template<typename T>
-  class deque<T,EIGEN_ALIGNED_ALLOCATOR<T> >
-    : public deque<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T),
-                   Eigen::aligned_allocator_indirection<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T)> >
-{
-  typedef deque<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T),
-                Eigen::aligned_allocator_indirection<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T)> > deque_base;
-  EIGEN_STD_DEQUE_SPECIALIZATION_BODY
-
-  void resize(size_type new_size)
-  { resize(new_size, T()); }
-
-#if defined(_DEQUE_)
-  // workaround MSVC std::deque implementation
-  void resize(size_type new_size, const value_type& x)
-  {
-    if (deque_base::size() < new_size)
-      deque_base::_Insert_n(deque_base::end(), new_size - deque_base::size(), x);
-    else if (new_size < deque_base::size())
-      deque_base::erase(deque_base::begin() + new_size, deque_base::end());
-  }
-  void push_back(const value_type& x)
-  { deque_base::push_back(x); } 
-  void push_front(const value_type& x)
-  { deque_base::push_front(x); }
-  using deque_base::insert;  
-  iterator insert(const_iterator position, const value_type& x)
-  { return deque_base::insert(position,x); }
-  void insert(const_iterator position, size_type new_size, const value_type& x)
-  { deque_base::insert(position, new_size, x); }
-#elif defined(_GLIBCXX_DEQUE) && EIGEN_GNUC_AT_LEAST(4,2)
-  // workaround GCC std::deque implementation
-  void resize(size_type new_size, const value_type& x)
-  {
-    if (new_size < deque_base::size())
-      deque_base::_M_erase_at_end(this->_M_impl._M_start + new_size);
-    else
-      deque_base::insert(deque_base::end(), new_size - deque_base::size(), x);
-  }
-#else
-  // either GCC 4.1 or non-GCC
-  // default implementation which should always work.
-  void resize(size_type new_size, const value_type& x)
-  {
-    if (new_size < deque_base::size())
-      deque_base::erase(deque_base::begin() + new_size, deque_base::end());
-    else if (new_size > deque_base::size())
-      deque_base::insert(deque_base::end(), new_size - deque_base::size(), x);
-  }
-#endif
-  };
-}
-
-#endif // check whether specialization is actually required
-
-#endif // EIGEN_STDDEQUE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/StlSupport/StdList.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/StlSupport/StdList.h
deleted file mode 100644
index e1eba49..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/StlSupport/StdList.h
+++ /dev/null
@@ -1,106 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_STDLIST_H
-#define EIGEN_STDLIST_H
-
-#include "details.h"
-
-/**
- * This section contains a convenience MACRO which allows an easy specialization of
- * std::list such that for data types with alignment issues the correct allocator
- * is used automatically.
- */
-#define EIGEN_DEFINE_STL_LIST_SPECIALIZATION(...) \
-namespace std \
-{ \
-  template<> \
-  class list<__VA_ARGS__, std::allocator<__VA_ARGS__> >           \
-    : public list<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > \
-  { \
-    typedef list<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > list_base; \
-  public: \
-    typedef __VA_ARGS__ value_type; \
-    typedef list_base::allocator_type allocator_type; \
-    typedef list_base::size_type size_type;  \
-    typedef list_base::iterator iterator;  \
-    explicit list(const allocator_type& a = allocator_type()) : list_base(a) {}  \
-    template<typename InputIterator> \
-    list(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) : list_base(first, last, a) {} \
-    list(const list& c) : list_base(c) {}  \
-    explicit list(size_type num, const value_type& val = value_type()) : list_base(num, val) {} \
-    list(iterator start, iterator end) : list_base(start, end) {}  \
-    list& operator=(const list& x) {  \
-      list_base::operator=(x);  \
-      return *this;  \
-    } \
-  }; \
-}
-
-// check whether we really need the std::list specialization
-#if !EIGEN_HAS_CXX11_CONTAINERS && !(defined(_GLIBCXX_LIST) && (!EIGEN_GNUC_AT_LEAST(4,1))) /* Note that before gcc-4.1 we already have: std::list::resize(size_type,const T&). */
-
-namespace std
-{
-
-#define EIGEN_STD_LIST_SPECIALIZATION_BODY \
-  public:  \
-    typedef T value_type; \
-    typedef typename list_base::allocator_type allocator_type; \
-    typedef typename list_base::size_type size_type;  \
-    typedef typename list_base::iterator iterator;  \
-    typedef typename list_base::const_iterator const_iterator;  \
-    explicit list(const allocator_type& a = allocator_type()) : list_base(a) {}  \
-    template<typename InputIterator> \
-    list(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) \
-    : list_base(first, last, a) {} \
-    list(const list& c) : list_base(c) {}  \
-    explicit list(size_type num, const value_type& val = value_type()) : list_base(num, val) {} \
-    list(iterator start, iterator end) : list_base(start, end) {}  \
-    list& operator=(const list& x) {  \
-    list_base::operator=(x);  \
-    return *this; \
-  }
-
-  template<typename T>
-  class list<T,EIGEN_ALIGNED_ALLOCATOR<T> >
-    : public list<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T),
-                  Eigen::aligned_allocator_indirection<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T)> >
-  {
-    typedef list<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T),
-                 Eigen::aligned_allocator_indirection<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T)> > list_base;
-    EIGEN_STD_LIST_SPECIALIZATION_BODY
-
-    void resize(size_type new_size)
-    { resize(new_size, T()); }
-
-    void resize(size_type new_size, const value_type& x)
-    {
-      if (list_base::size() < new_size)
-        list_base::insert(list_base::end(), new_size - list_base::size(), x);
-      else
-        while (new_size < list_base::size()) list_base::pop_back();
-    }
-
-#if defined(_LIST_)
-    // workaround MSVC std::list implementation
-    void push_back(const value_type& x)
-    { list_base::push_back(x); } 
-    using list_base::insert;  
-    iterator insert(const_iterator position, const value_type& x)
-    { return list_base::insert(position,x); }
-    void insert(const_iterator position, size_type new_size, const value_type& x)
-    { list_base::insert(position, new_size, x); }
-#endif
-  };
-}
-
-#endif // check whether specialization is actually required
-
-#endif // EIGEN_STDLIST_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/StlSupport/StdVector.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/StlSupport/StdVector.h
deleted file mode 100644
index ec22821..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/StlSupport/StdVector.h
+++ /dev/null
@@ -1,131 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_STDVECTOR_H
-#define EIGEN_STDVECTOR_H
-
-#include "details.h"
-
-/**
- * This section contains a convenience MACRO which allows an easy specialization of
- * std::vector such that for data types with alignment issues the correct allocator
- * is used automatically.
- */
-#define EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(...) \
-namespace std \
-{ \
-  template<> \
-  class vector<__VA_ARGS__, std::allocator<__VA_ARGS__> >  \
-    : public vector<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > \
-  { \
-    typedef vector<__VA_ARGS__, EIGEN_ALIGNED_ALLOCATOR<__VA_ARGS__> > vector_base; \
-  public: \
-    typedef __VA_ARGS__ value_type; \
-    typedef vector_base::allocator_type allocator_type; \
-    typedef vector_base::size_type size_type;  \
-    typedef vector_base::iterator iterator;  \
-    explicit vector(const allocator_type& a = allocator_type()) : vector_base(a) {}  \
-    template<typename InputIterator> \
-    vector(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) : vector_base(first, last, a) {} \
-    vector(const vector& c) : vector_base(c) {}  \
-    explicit vector(size_type num, const value_type& val = value_type()) : vector_base(num, val) {} \
-    vector(iterator start, iterator end) : vector_base(start, end) {}  \
-    vector& operator=(const vector& x) {  \
-      vector_base::operator=(x);  \
-      return *this;  \
-    } \
-  }; \
-}
-
-// Don't specialize if containers are implemented according to C++11
-#if !EIGEN_HAS_CXX11_CONTAINERS
-
-namespace std {
-
-#define EIGEN_STD_VECTOR_SPECIALIZATION_BODY \
-  public:  \
-    typedef T value_type; \
-    typedef typename vector_base::allocator_type allocator_type; \
-    typedef typename vector_base::size_type size_type;  \
-    typedef typename vector_base::iterator iterator;  \
-    typedef typename vector_base::const_iterator const_iterator;  \
-    explicit vector(const allocator_type& a = allocator_type()) : vector_base(a) {}  \
-    template<typename InputIterator> \
-    vector(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) \
-    : vector_base(first, last, a) {} \
-    vector(const vector& c) : vector_base(c) {}  \
-    explicit vector(size_type num, const value_type& val = value_type()) : vector_base(num, val) {} \
-    vector(iterator start, iterator end) : vector_base(start, end) {}  \
-    vector& operator=(const vector& x) {  \
-      vector_base::operator=(x);  \
-      return *this;  \
-    }
-
-  template<typename T>
-  class vector<T,EIGEN_ALIGNED_ALLOCATOR<T> >
-    : public vector<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T),
-                    Eigen::aligned_allocator_indirection<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T)> >
-{
-  typedef vector<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T),
-                 Eigen::aligned_allocator_indirection<EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T)> > vector_base;
-  EIGEN_STD_VECTOR_SPECIALIZATION_BODY
-
-  void resize(size_type new_size)
-  { resize(new_size, T()); }
-
-#if defined(_VECTOR_)
-  // workaround MSVC std::vector implementation
-  void resize(size_type new_size, const value_type& x)
-  {
-    if (vector_base::size() < new_size)
-      vector_base::_Insert_n(vector_base::end(), new_size - vector_base::size(), x);
-    else if (new_size < vector_base::size())
-      vector_base::erase(vector_base::begin() + new_size, vector_base::end());
-  }
-  void push_back(const value_type& x)
-  { vector_base::push_back(x); } 
-  using vector_base::insert;  
-  iterator insert(const_iterator position, const value_type& x)
-  { return vector_base::insert(position,x); }
-  void insert(const_iterator position, size_type new_size, const value_type& x)
-  { vector_base::insert(position, new_size, x); }
-#elif defined(_GLIBCXX_VECTOR) && (!(EIGEN_GNUC_AT_LEAST(4,1)))
-  /* Note that before gcc-4.1 we already have: std::vector::resize(size_type,const T&).
-   * However, this specialization is still needed to make the above EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION trick to work. */
-  void resize(size_type new_size, const value_type& x)
-  {
-    vector_base::resize(new_size,x);
-  }
-#elif defined(_GLIBCXX_VECTOR) && EIGEN_GNUC_AT_LEAST(4,2)
-  // workaround GCC std::vector implementation
-  void resize(size_type new_size, const value_type& x)
-  {
-    if (new_size < vector_base::size())
-      vector_base::_M_erase_at_end(this->_M_impl._M_start + new_size);
-    else
-      vector_base::insert(vector_base::end(), new_size - vector_base::size(), x);
-  }
-#else
-  // either GCC 4.1 or non-GCC
-  // default implementation which should always work.
-  void resize(size_type new_size, const value_type& x)
-  {
-    if (new_size < vector_base::size())
-      vector_base::erase(vector_base::begin() + new_size, vector_base::end());
-    else if (new_size > vector_base::size())
-      vector_base::insert(vector_base::end(), new_size - vector_base::size(), x);
-  }
-#endif
-  };
-}
-#endif // !EIGEN_HAS_CXX11_CONTAINERS
-
-
-#endif // EIGEN_STDVECTOR_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/StlSupport/details.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/StlSupport/details.h
deleted file mode 100644
index 2cfd13e..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/StlSupport/details.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2009 Hauke Heibel <hauke.heibel@googlemail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_STL_DETAILS_H
-#define EIGEN_STL_DETAILS_H
-
-#ifndef EIGEN_ALIGNED_ALLOCATOR
-  #define EIGEN_ALIGNED_ALLOCATOR Eigen::aligned_allocator
-#endif
-
-namespace Eigen {
-
-  // This one is needed to prevent reimplementing the whole std::vector.
-  template <class T>
-  class aligned_allocator_indirection : public EIGEN_ALIGNED_ALLOCATOR<T>
-  {
-  public:
-    typedef std::size_t     size_type;
-    typedef std::ptrdiff_t  difference_type;
-    typedef T*              pointer;
-    typedef const T*        const_pointer;
-    typedef T&              reference;
-    typedef const T&        const_reference;
-    typedef T               value_type;
-
-    template<class U>
-    struct rebind
-    {
-      typedef aligned_allocator_indirection<U> other;
-    };
-
-    aligned_allocator_indirection() {}
-    aligned_allocator_indirection(const aligned_allocator_indirection& ) : EIGEN_ALIGNED_ALLOCATOR<T>() {}
-    aligned_allocator_indirection(const EIGEN_ALIGNED_ALLOCATOR<T>& ) {}
-    template<class U>
-    aligned_allocator_indirection(const aligned_allocator_indirection<U>& ) {}
-    template<class U>
-    aligned_allocator_indirection(const EIGEN_ALIGNED_ALLOCATOR<U>& ) {}
-    ~aligned_allocator_indirection() {}
-  };
-
-#if EIGEN_COMP_MSVC
-
-  // sometimes, MSVC detects, at compile time, that the argument x
-  // in std::vector::resize(size_t s,T x) won't be aligned and generate an error
-  // even if this function is never called. Whence this little wrapper.
-#define EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T) \
-  typename Eigen::internal::conditional< \
-    Eigen::internal::is_arithmetic<T>::value, \
-    T, \
-    Eigen::internal::workaround_msvc_stl_support<T> \
-  >::type
-
-  namespace internal {
-  template<typename T> struct workaround_msvc_stl_support : public T
-  {
-    inline workaround_msvc_stl_support() : T() {}
-    inline workaround_msvc_stl_support(const T& other) : T(other) {}
-    inline operator T& () { return *static_cast<T*>(this); }
-    inline operator const T& () const { return *static_cast<const T*>(this); }
-    template<typename OtherT>
-    inline T& operator=(const OtherT& other)
-    { T::operator=(other); return *this; }
-    inline workaround_msvc_stl_support& operator=(const workaround_msvc_stl_support& other)
-    { T::operator=(other); return *this; }
-  };
-  }
-
-#else
-
-#define EIGEN_WORKAROUND_MSVC_STL_SUPPORT(T) T
-
-#endif
-
-}
-
-#endif // EIGEN_STL_DETAILS_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/misc/Image.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/misc/Image.h
deleted file mode 100644
index b8b8a04..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/misc/Image.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_MISC_IMAGE_H
-#define EIGEN_MISC_IMAGE_H
-
-namespace Eigen { 
-
-namespace internal {
-
-/** \class image_retval_base
-  *
-  */
-template<typename DecompositionType>
-struct traits<image_retval_base<DecompositionType> >
-{
-  typedef typename DecompositionType::MatrixType MatrixType;
-  typedef Matrix<
-    typename MatrixType::Scalar,
-    MatrixType::RowsAtCompileTime, // the image is a subspace of the destination space, whose
-                                   // dimension is the number of rows of the original matrix
-    Dynamic,                       // we don't know at compile time the dimension of the image (the rank)
-    MatrixType::Options,
-    MatrixType::MaxRowsAtCompileTime, // the image matrix will consist of columns from the original matrix,
-    MatrixType::MaxColsAtCompileTime  // so it has the same number of rows and at most as many columns.
-  > ReturnType;
-};
-
-template<typename _DecompositionType> struct image_retval_base
- : public ReturnByValue<image_retval_base<_DecompositionType> >
-{
-  typedef _DecompositionType DecompositionType;
-  typedef typename DecompositionType::MatrixType MatrixType;
-  typedef ReturnByValue<image_retval_base> Base;
-
-  image_retval_base(const DecompositionType& dec, const MatrixType& originalMatrix)
-    : m_dec(dec), m_rank(dec.rank()),
-      m_cols(m_rank == 0 ? 1 : m_rank),
-      m_originalMatrix(originalMatrix)
-  {}
-
-  inline Index rows() const { return m_dec.rows(); }
-  inline Index cols() const { return m_cols; }
-  inline Index rank() const { return m_rank; }
-  inline const DecompositionType& dec() const { return m_dec; }
-  inline const MatrixType& originalMatrix() const { return m_originalMatrix; }
-
-  template<typename Dest> inline void evalTo(Dest& dst) const
-  {
-    static_cast<const image_retval<DecompositionType>*>(this)->evalTo(dst);
-  }
-
-  protected:
-    const DecompositionType& m_dec;
-    Index m_rank, m_cols;
-    const MatrixType& m_originalMatrix;
-};
-
-} // end namespace internal
-
-#define EIGEN_MAKE_IMAGE_HELPERS(DecompositionType) \
-  typedef typename DecompositionType::MatrixType MatrixType; \
-  typedef typename MatrixType::Scalar Scalar; \
-  typedef typename MatrixType::RealScalar RealScalar; \
-  typedef Eigen::internal::image_retval_base<DecompositionType> Base; \
-  using Base::dec; \
-  using Base::originalMatrix; \
-  using Base::rank; \
-  using Base::rows; \
-  using Base::cols; \
-  image_retval(const DecompositionType& dec, const MatrixType& originalMatrix) \
-    : Base(dec, originalMatrix) {}
-
-} // end namespace Eigen
-
-#endif // EIGEN_MISC_IMAGE_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/misc/Kernel.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/misc/Kernel.h
deleted file mode 100644
index bef5d6f..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/misc/Kernel.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_MISC_KERNEL_H
-#define EIGEN_MISC_KERNEL_H
-
-namespace Eigen { 
-
-namespace internal {
-
-/** \class kernel_retval_base
-  *
-  */
-template<typename DecompositionType>
-struct traits<kernel_retval_base<DecompositionType> >
-{
-  typedef typename DecompositionType::MatrixType MatrixType;
-  typedef Matrix<
-    typename MatrixType::Scalar,
-    MatrixType::ColsAtCompileTime, // the number of rows in the "kernel matrix"
-                                   // is the number of cols of the original matrix
-                                   // so that the product "matrix * kernel = zero" makes sense
-    Dynamic,                       // we don't know at compile-time the dimension of the kernel
-    MatrixType::Options,
-    MatrixType::MaxColsAtCompileTime, // see explanation for 2nd template parameter
-    MatrixType::MaxColsAtCompileTime // the kernel is a subspace of the domain space,
-                                     // whose dimension is the number of columns of the original matrix
-  > ReturnType;
-};
-
-template<typename _DecompositionType> struct kernel_retval_base
- : public ReturnByValue<kernel_retval_base<_DecompositionType> >
-{
-  typedef _DecompositionType DecompositionType;
-  typedef ReturnByValue<kernel_retval_base> Base;
-
-  explicit kernel_retval_base(const DecompositionType& dec)
-    : m_dec(dec),
-      m_rank(dec.rank()),
-      m_cols(m_rank==dec.cols() ? 1 : dec.cols() - m_rank)
-  {}
-
-  inline Index rows() const { return m_dec.cols(); }
-  inline Index cols() const { return m_cols; }
-  inline Index rank() const { return m_rank; }
-  inline const DecompositionType& dec() const { return m_dec; }
-
-  template<typename Dest> inline void evalTo(Dest& dst) const
-  {
-    static_cast<const kernel_retval<DecompositionType>*>(this)->evalTo(dst);
-  }
-
-  protected:
-    const DecompositionType& m_dec;
-    Index m_rank, m_cols;
-};
-
-} // end namespace internal
-
-#define EIGEN_MAKE_KERNEL_HELPERS(DecompositionType) \
-  typedef typename DecompositionType::MatrixType MatrixType; \
-  typedef typename MatrixType::Scalar Scalar; \
-  typedef typename MatrixType::RealScalar RealScalar; \
-  typedef Eigen::internal::kernel_retval_base<DecompositionType> Base; \
-  using Base::dec; \
-  using Base::rank; \
-  using Base::rows; \
-  using Base::cols; \
-  kernel_retval(const DecompositionType& dec) : Base(dec) {}
-
-} // end namespace Eigen
-
-#endif // EIGEN_MISC_KERNEL_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/misc/RealSvd2x2.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/misc/RealSvd2x2.h
deleted file mode 100644
index abb4d3c..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/misc/RealSvd2x2.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
-// Copyright (C) 2013-2016 Gael Guennebaud <gael.guennebaud@inria.fr>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_REALSVD2X2_H
-#define EIGEN_REALSVD2X2_H
-
-namespace Eigen {
-
-namespace internal {
-
-template<typename MatrixType, typename RealScalar, typename Index>
-void real_2x2_jacobi_svd(const MatrixType& matrix, Index p, Index q,
-                         JacobiRotation<RealScalar> *j_left,
-                         JacobiRotation<RealScalar> *j_right)
-{
-  using std::sqrt;
-  using std::abs;
-  Matrix<RealScalar,2,2> m;
-  m << numext::real(matrix.coeff(p,p)), numext::real(matrix.coeff(p,q)),
-       numext::real(matrix.coeff(q,p)), numext::real(matrix.coeff(q,q));
-  JacobiRotation<RealScalar> rot1;
-  RealScalar t = m.coeff(0,0) + m.coeff(1,1);
-  RealScalar d = m.coeff(1,0) - m.coeff(0,1);
-
-  if(abs(d) < (std::numeric_limits<RealScalar>::min)())
-  {
-    rot1.s() = RealScalar(0);
-    rot1.c() = RealScalar(1);
-  }
-  else
-  {
-    // If d!=0, then t/d cannot overflow because the magnitude of the
-    // entries forming d are not too small compared to the ones forming t.
-    RealScalar u = t / d;
-    RealScalar tmp = sqrt(RealScalar(1) + numext::abs2(u));
-    rot1.s() = RealScalar(1) / tmp;
-    rot1.c() = u / tmp;
-  }
-  m.applyOnTheLeft(0,1,rot1);
-  j_right->makeJacobi(m,0,1);
-  *j_left = rot1 * j_right->transpose();
-}
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_REALSVD2X2_H
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/plugins/ArrayCwiseBinaryOps.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/plugins/ArrayCwiseBinaryOps.h
deleted file mode 100644
index 1f8a531..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/plugins/ArrayCwiseBinaryOps.h
+++ /dev/null
@@ -1,332 +0,0 @@
-
-/** \returns an expression of the coefficient wise product of \c *this and \a other
-  *
-  * \sa MatrixBase::cwiseProduct
-  */
-template<typename OtherDerived>
-EIGEN_DEVICE_FUNC
-EIGEN_STRONG_INLINE const EIGEN_CWISE_BINARY_RETURN_TYPE(Derived,OtherDerived,product)
-operator*(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
-{
-  return EIGEN_CWISE_BINARY_RETURN_TYPE(Derived,OtherDerived,product)(derived(), other.derived());
-}
-
-/** \returns an expression of the coefficient wise quotient of \c *this and \a other
-  *
-  * \sa MatrixBase::cwiseQuotient
-  */
-template<typename OtherDerived>
-EIGEN_DEVICE_FUNC
-EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_quotient_op<Scalar,typename OtherDerived::Scalar>, const Derived, const OtherDerived>
-operator/(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
-{
-  return CwiseBinaryOp<internal::scalar_quotient_op<Scalar,typename OtherDerived::Scalar>, const Derived, const OtherDerived>(derived(), other.derived());
-}
-
-/** \returns an expression of the coefficient-wise min of \c *this and \a other
-  *
-  * Example: \include Cwise_min.cpp
-  * Output: \verbinclude Cwise_min.out
-  *
-  * \sa max()
-  */
-EIGEN_MAKE_CWISE_BINARY_OP(min,min)
-
-/** \returns an expression of the coefficient-wise min of \c *this and scalar \a other
-  *
-  * \sa max()
-  */
-EIGEN_DEVICE_FUNC
-EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_min_op<Scalar,Scalar>, const Derived,
-                                        const CwiseNullaryOp<internal::scalar_constant_op<Scalar>, PlainObject> >
-#ifdef EIGEN_PARSED_BY_DOXYGEN
-min
-#else
-(min)
-#endif
-(const Scalar &other) const
-{
-  return (min)(Derived::PlainObject::Constant(rows(), cols(), other));
-}
-
-/** \returns an expression of the coefficient-wise max of \c *this and \a other
-  *
-  * Example: \include Cwise_max.cpp
-  * Output: \verbinclude Cwise_max.out
-  *
-  * \sa min()
-  */
-EIGEN_MAKE_CWISE_BINARY_OP(max,max)
-
-/** \returns an expression of the coefficient-wise max of \c *this and scalar \a other
-  *
-  * \sa min()
-  */
-EIGEN_DEVICE_FUNC
-EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_max_op<Scalar,Scalar>, const Derived,
-                                        const CwiseNullaryOp<internal::scalar_constant_op<Scalar>, PlainObject> >
-#ifdef EIGEN_PARSED_BY_DOXYGEN
-max
-#else
-(max)
-#endif
-(const Scalar &other) const
-{
-  return (max)(Derived::PlainObject::Constant(rows(), cols(), other));
-}
-
-/** \returns an expression of the coefficient-wise power of \c *this to the given array of \a exponents.
-  *
-  * This function computes the coefficient-wise power.
-  *
-  * Example: \include Cwise_array_power_array.cpp
-  * Output: \verbinclude Cwise_array_power_array.out
-  */
-EIGEN_MAKE_CWISE_BINARY_OP(pow,pow)
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-EIGEN_MAKE_SCALAR_BINARY_OP_ONTHERIGHT(pow,pow)
-#else
-/** \returns an expression of the coefficients of \c *this rasied to the constant power \a exponent
-  *
-  * \tparam T is the scalar type of \a exponent. It must be compatible with the scalar type of the given expression.
-  *
-  * This function computes the coefficient-wise power. The function MatrixBase::pow() in the
-  * unsupported module MatrixFunctions computes the matrix power.
-  *
-  * Example: \include Cwise_pow.cpp
-  * Output: \verbinclude Cwise_pow.out
-  *
-  * \sa ArrayBase::pow(ArrayBase), square(), cube(), exp(), log()
-  */
-template<typename T>
-const CwiseBinaryOp<internal::scalar_pow_op<Scalar,T>,Derived,Constant<T> > pow(const T& exponent) const;
-#endif
-
-
-// TODO code generating macros could be moved to Macros.h and could include generation of documentation
-#define EIGEN_MAKE_CWISE_COMP_OP(OP, COMPARATOR) \
-template<typename OtherDerived> \
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_cmp_op<Scalar, typename OtherDerived::Scalar, internal::cmp_ ## COMPARATOR>, const Derived, const OtherDerived> \
-OP(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const \
-{ \
-  return CwiseBinaryOp<internal::scalar_cmp_op<Scalar, typename OtherDerived::Scalar, internal::cmp_ ## COMPARATOR>, const Derived, const OtherDerived>(derived(), other.derived()); \
-}\
-typedef CwiseBinaryOp<internal::scalar_cmp_op<Scalar,Scalar, internal::cmp_ ## COMPARATOR>, const Derived, const CwiseNullaryOp<internal::scalar_constant_op<Scalar>, PlainObject> > Cmp ## COMPARATOR ## ReturnType; \
-typedef CwiseBinaryOp<internal::scalar_cmp_op<Scalar,Scalar, internal::cmp_ ## COMPARATOR>, const CwiseNullaryOp<internal::scalar_constant_op<Scalar>, PlainObject>, const Derived > RCmp ## COMPARATOR ## ReturnType; \
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Cmp ## COMPARATOR ## ReturnType \
-OP(const Scalar& s) const { \
-  return this->OP(Derived::PlainObject::Constant(rows(), cols(), s)); \
-} \
-EIGEN_DEVICE_FUNC friend EIGEN_STRONG_INLINE const RCmp ## COMPARATOR ## ReturnType \
-OP(const Scalar& s, const Derived& d) { \
-  return Derived::PlainObject::Constant(d.rows(), d.cols(), s).OP(d); \
-}
-
-#define EIGEN_MAKE_CWISE_COMP_R_OP(OP, R_OP, RCOMPARATOR) \
-template<typename OtherDerived> \
-EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_cmp_op<typename OtherDerived::Scalar, Scalar, internal::cmp_##RCOMPARATOR>, const OtherDerived, const Derived> \
-OP(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const \
-{ \
-  return CwiseBinaryOp<internal::scalar_cmp_op<typename OtherDerived::Scalar, Scalar, internal::cmp_##RCOMPARATOR>, const OtherDerived, const Derived>(other.derived(), derived()); \
-} \
-EIGEN_DEVICE_FUNC \
-inline const RCmp ## RCOMPARATOR ## ReturnType \
-OP(const Scalar& s) const { \
-  return Derived::PlainObject::Constant(rows(), cols(), s).R_OP(*this); \
-} \
-friend inline const Cmp ## RCOMPARATOR ## ReturnType \
-OP(const Scalar& s, const Derived& d) { \
-  return d.R_OP(Derived::PlainObject::Constant(d.rows(), d.cols(), s)); \
-}
-
-
-
-/** \returns an expression of the coefficient-wise \< operator of *this and \a other
-  *
-  * Example: \include Cwise_less.cpp
-  * Output: \verbinclude Cwise_less.out
-  *
-  * \sa all(), any(), operator>(), operator<=()
-  */
-EIGEN_MAKE_CWISE_COMP_OP(operator<, LT)
-
-/** \returns an expression of the coefficient-wise \<= operator of *this and \a other
-  *
-  * Example: \include Cwise_less_equal.cpp
-  * Output: \verbinclude Cwise_less_equal.out
-  *
-  * \sa all(), any(), operator>=(), operator<()
-  */
-EIGEN_MAKE_CWISE_COMP_OP(operator<=, LE)
-
-/** \returns an expression of the coefficient-wise \> operator of *this and \a other
-  *
-  * Example: \include Cwise_greater.cpp
-  * Output: \verbinclude Cwise_greater.out
-  *
-  * \sa all(), any(), operator>=(), operator<()
-  */
-EIGEN_MAKE_CWISE_COMP_R_OP(operator>, operator<, LT)
-
-/** \returns an expression of the coefficient-wise \>= operator of *this and \a other
-  *
-  * Example: \include Cwise_greater_equal.cpp
-  * Output: \verbinclude Cwise_greater_equal.out
-  *
-  * \sa all(), any(), operator>(), operator<=()
-  */
-EIGEN_MAKE_CWISE_COMP_R_OP(operator>=, operator<=, LE)
-
-/** \returns an expression of the coefficient-wise == operator of *this and \a other
-  *
-  * \warning this performs an exact comparison, which is generally a bad idea with floating-point types.
-  * In order to check for equality between two vectors or matrices with floating-point coefficients, it is
-  * generally a far better idea to use a fuzzy comparison as provided by isApprox() and
-  * isMuchSmallerThan().
-  *
-  * Example: \include Cwise_equal_equal.cpp
-  * Output: \verbinclude Cwise_equal_equal.out
-  *
-  * \sa all(), any(), isApprox(), isMuchSmallerThan()
-  */
-EIGEN_MAKE_CWISE_COMP_OP(operator==, EQ)
-
-/** \returns an expression of the coefficient-wise != operator of *this and \a other
-  *
-  * \warning this performs an exact comparison, which is generally a bad idea with floating-point types.
-  * In order to check for equality between two vectors or matrices with floating-point coefficients, it is
-  * generally a far better idea to use a fuzzy comparison as provided by isApprox() and
-  * isMuchSmallerThan().
-  *
-  * Example: \include Cwise_not_equal.cpp
-  * Output: \verbinclude Cwise_not_equal.out
-  *
-  * \sa all(), any(), isApprox(), isMuchSmallerThan()
-  */
-EIGEN_MAKE_CWISE_COMP_OP(operator!=, NEQ)
-
-
-#undef EIGEN_MAKE_CWISE_COMP_OP
-#undef EIGEN_MAKE_CWISE_COMP_R_OP
-
-// scalar addition
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-EIGEN_MAKE_SCALAR_BINARY_OP(operator+,sum)
-#else
-/** \returns an expression of \c *this with each coeff incremented by the constant \a scalar
-  *
-  * \tparam T is the scalar type of \a scalar. It must be compatible with the scalar type of the given expression.
-  *
-  * Example: \include Cwise_plus.cpp
-  * Output: \verbinclude Cwise_plus.out
-  *
-  * \sa operator+=(), operator-()
-  */
-template<typename T>
-const CwiseBinaryOp<internal::scalar_sum_op<Scalar,T>,Derived,Constant<T> > operator+(const T& scalar) const;
-/** \returns an expression of \a expr with each coeff incremented by the constant \a scalar
-  *
-  * \tparam T is the scalar type of \a scalar. It must be compatible with the scalar type of the given expression.
-  */
-template<typename T> friend
-const CwiseBinaryOp<internal::scalar_sum_op<T,Scalar>,Constant<T>,Derived> operator+(const T& scalar, const StorageBaseType& expr);
-#endif
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-EIGEN_MAKE_SCALAR_BINARY_OP(operator-,difference)
-#else
-/** \returns an expression of \c *this with each coeff decremented by the constant \a scalar
-  *
-  * \tparam T is the scalar type of \a scalar. It must be compatible with the scalar type of the given expression.
-  *
-  * Example: \include Cwise_minus.cpp
-  * Output: \verbinclude Cwise_minus.out
-  *
-  * \sa operator+=(), operator-()
-  */
-template<typename T>
-const CwiseBinaryOp<internal::scalar_difference_op<Scalar,T>,Derived,Constant<T> > operator-(const T& scalar) const;
-/** \returns an expression of the constant matrix of value \a scalar decremented by the coefficients of \a expr
-  *
-  * \tparam T is the scalar type of \a scalar. It must be compatible with the scalar type of the given expression.
-  */
-template<typename T> friend
-const CwiseBinaryOp<internal::scalar_difference_op<T,Scalar>,Constant<T>,Derived> operator-(const T& scalar, const StorageBaseType& expr);
-#endif
-
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-  EIGEN_MAKE_SCALAR_BINARY_OP_ONTHELEFT(operator/,quotient)
-#else
-  /**
-    * \brief Component-wise division of the scalar \a s by array elements of \a a.
-    *
-    * \tparam Scalar is the scalar type of \a x. It must be compatible with the scalar type of the given array expression (\c Derived::Scalar).
-    */
-  template<typename T> friend
-  inline const CwiseBinaryOp<internal::scalar_quotient_op<T,Scalar>,Constant<T>,Derived>
-  operator/(const T& s,const StorageBaseType& a);
-#endif
-
-/** \returns an expression of the coefficient-wise ^ operator of *this and \a other
- *
- * \warning this operator is for expression of bool only.
- *
- * Example: \include Cwise_boolean_xor.cpp
- * Output: \verbinclude Cwise_boolean_xor.out
- *
- * \sa operator&&(), select()
- */
-template<typename OtherDerived>
-EIGEN_DEVICE_FUNC
-inline const CwiseBinaryOp<internal::scalar_boolean_xor_op, const Derived, const OtherDerived>
-operator^(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
-{
-  EIGEN_STATIC_ASSERT((internal::is_same<bool,Scalar>::value && internal::is_same<bool,typename OtherDerived::Scalar>::value),
-                      THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL);
-  return CwiseBinaryOp<internal::scalar_boolean_xor_op, const Derived, const OtherDerived>(derived(),other.derived());
-}
-
-// NOTE disabled until we agree on argument order
-#if 0
-/** \cpp11 \returns an expression of the coefficient-wise polygamma function.
-  *
-  * \specialfunctions_module
-  *
-  * It returns the \a n -th derivative of the digamma(psi) evaluated at \c *this.
-  *
-  * \warning Be careful with the order of the parameters: x.polygamma(n) is equivalent to polygamma(n,x)
-  *
-  * \sa Eigen::polygamma()
-  */
-template<typename DerivedN>
-inline const CwiseBinaryOp<internal::scalar_polygamma_op<Scalar>, const DerivedN, const Derived>
-polygamma(const EIGEN_CURRENT_STORAGE_BASE_CLASS<DerivedN> &n) const
-{
-  return CwiseBinaryOp<internal::scalar_polygamma_op<Scalar>, const DerivedN, const Derived>(n.derived(), this->derived());
-}
-#endif
-
-/** \returns an expression of the coefficient-wise zeta function.
-  *
-  * \specialfunctions_module
-  *
-  * It returns the Riemann zeta function of two arguments \c *this and \a q:
-  *
-  * \param *this is the exposent, it must be > 1
-  * \param q is the shift, it must be > 0
-  *
-  * \note This function supports only float and double scalar types. To support other scalar types, the user has
-  * to provide implementations of zeta(T,T) for any scalar type T to be supported.
-  *
-  * This method is an alias for zeta(*this,q);
-  *
-  * \sa Eigen::zeta()
-  */
-template<typename DerivedQ>
-inline const CwiseBinaryOp<internal::scalar_zeta_op<Scalar>, const Derived, const DerivedQ>
-zeta(const EIGEN_CURRENT_STORAGE_BASE_CLASS<DerivedQ> &q) const
-{
-  return CwiseBinaryOp<internal::scalar_zeta_op<Scalar>, const Derived, const DerivedQ>(this->derived(), q.derived());
-}
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/plugins/ArrayCwiseUnaryOps.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/plugins/ArrayCwiseUnaryOps.h
deleted file mode 100644
index ebaa3f1..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/plugins/ArrayCwiseUnaryOps.h
+++ /dev/null
@@ -1,552 +0,0 @@
-
-
-typedef CwiseUnaryOp<internal::scalar_abs_op<Scalar>, const Derived> AbsReturnType;
-typedef CwiseUnaryOp<internal::scalar_arg_op<Scalar>, const Derived> ArgReturnType;
-typedef CwiseUnaryOp<internal::scalar_abs2_op<Scalar>, const Derived> Abs2ReturnType;
-typedef CwiseUnaryOp<internal::scalar_sqrt_op<Scalar>, const Derived> SqrtReturnType;
-typedef CwiseUnaryOp<internal::scalar_rsqrt_op<Scalar>, const Derived> RsqrtReturnType;
-typedef CwiseUnaryOp<internal::scalar_sign_op<Scalar>, const Derived> SignReturnType;
-typedef CwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const Derived> InverseReturnType;
-typedef CwiseUnaryOp<internal::scalar_boolean_not_op<Scalar>, const Derived> BooleanNotReturnType;
-
-typedef CwiseUnaryOp<internal::scalar_exp_op<Scalar>, const Derived> ExpReturnType;
-typedef CwiseUnaryOp<internal::scalar_log_op<Scalar>, const Derived> LogReturnType;
-typedef CwiseUnaryOp<internal::scalar_log1p_op<Scalar>, const Derived> Log1pReturnType;
-typedef CwiseUnaryOp<internal::scalar_log10_op<Scalar>, const Derived> Log10ReturnType;
-typedef CwiseUnaryOp<internal::scalar_cos_op<Scalar>, const Derived> CosReturnType;
-typedef CwiseUnaryOp<internal::scalar_sin_op<Scalar>, const Derived> SinReturnType;
-typedef CwiseUnaryOp<internal::scalar_tan_op<Scalar>, const Derived> TanReturnType;
-typedef CwiseUnaryOp<internal::scalar_acos_op<Scalar>, const Derived> AcosReturnType;
-typedef CwiseUnaryOp<internal::scalar_asin_op<Scalar>, const Derived> AsinReturnType;
-typedef CwiseUnaryOp<internal::scalar_atan_op<Scalar>, const Derived> AtanReturnType;
-typedef CwiseUnaryOp<internal::scalar_tanh_op<Scalar>, const Derived> TanhReturnType;
-typedef CwiseUnaryOp<internal::scalar_sinh_op<Scalar>, const Derived> SinhReturnType;
-typedef CwiseUnaryOp<internal::scalar_cosh_op<Scalar>, const Derived> CoshReturnType;
-typedef CwiseUnaryOp<internal::scalar_square_op<Scalar>, const Derived> SquareReturnType;
-typedef CwiseUnaryOp<internal::scalar_cube_op<Scalar>, const Derived> CubeReturnType;
-typedef CwiseUnaryOp<internal::scalar_round_op<Scalar>, const Derived> RoundReturnType;
-typedef CwiseUnaryOp<internal::scalar_floor_op<Scalar>, const Derived> FloorReturnType;
-typedef CwiseUnaryOp<internal::scalar_ceil_op<Scalar>, const Derived> CeilReturnType;
-typedef CwiseUnaryOp<internal::scalar_isnan_op<Scalar>, const Derived> IsNaNReturnType;
-typedef CwiseUnaryOp<internal::scalar_isinf_op<Scalar>, const Derived> IsInfReturnType;
-typedef CwiseUnaryOp<internal::scalar_isfinite_op<Scalar>, const Derived> IsFiniteReturnType;
-
-/** \returns an expression of the coefficient-wise absolute value of \c *this
-  *
-  * Example: \include Cwise_abs.cpp
-  * Output: \verbinclude Cwise_abs.out
-  *
-  * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_abs">Math functions</a>, abs2()
-  */
-EIGEN_DEVICE_FUNC
-EIGEN_STRONG_INLINE const AbsReturnType
-abs() const
-{
-  return AbsReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise phase angle of \c *this
-  *
-  * Example: \include Cwise_arg.cpp
-  * Output: \verbinclude Cwise_arg.out
-  *
-  * \sa abs()
-  */
-EIGEN_DEVICE_FUNC
-EIGEN_STRONG_INLINE const ArgReturnType
-arg() const
-{
-  return ArgReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise squared absolute value of \c *this
-  *
-  * Example: \include Cwise_abs2.cpp
-  * Output: \verbinclude Cwise_abs2.out
-  *
-  * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_abs2">Math functions</a>, abs(), square()
-  */
-EIGEN_DEVICE_FUNC
-EIGEN_STRONG_INLINE const Abs2ReturnType
-abs2() const
-{
-  return Abs2ReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise exponential of *this.
-  *
-  * This function computes the coefficient-wise exponential. The function MatrixBase::exp() in the
-  * unsupported module MatrixFunctions computes the matrix exponential.
-  *
-  * Example: \include Cwise_exp.cpp
-  * Output: \verbinclude Cwise_exp.out
-  *
-  * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_exp">Math functions</a>, pow(), log(), sin(), cos()
-  */
-EIGEN_DEVICE_FUNC
-inline const ExpReturnType
-exp() const
-{
-  return ExpReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise logarithm of *this.
-  *
-  * This function computes the coefficient-wise logarithm. The function MatrixBase::log() in the
-  * unsupported module MatrixFunctions computes the matrix logarithm.
-  *
-  * Example: \include Cwise_log.cpp
-  * Output: \verbinclude Cwise_log.out
-  *
-  * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_log">Math functions</a>, exp()
-  */
-EIGEN_DEVICE_FUNC
-inline const LogReturnType
-log() const
-{
-  return LogReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise logarithm of 1 plus \c *this.
-  *
-  * In exact arithmetic, \c x.log() is equivalent to \c (x+1).log(),
-  * however, with finite precision, this function is much more accurate when \c x is close to zero.
-  *
-  * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_log1p">Math functions</a>, log()
-  */
-EIGEN_DEVICE_FUNC
-inline const Log1pReturnType
-log1p() const
-{
-  return Log1pReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise base-10 logarithm of *this.
-  *
-  * This function computes the coefficient-wise base-10 logarithm.
-  *
-  * Example: \include Cwise_log10.cpp
-  * Output: \verbinclude Cwise_log10.out
-  *
-  * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_log10">Math functions</a>, log()
-  */
-EIGEN_DEVICE_FUNC
-inline const Log10ReturnType
-log10() const
-{
-  return Log10ReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise square root of *this.
-  *
-  * This function computes the coefficient-wise square root. The function MatrixBase::sqrt() in the
-  * unsupported module MatrixFunctions computes the matrix square root.
-  *
-  * Example: \include Cwise_sqrt.cpp
-  * Output: \verbinclude Cwise_sqrt.out
-  *
-  * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_sqrt">Math functions</a>, pow(), square()
-  */
-EIGEN_DEVICE_FUNC
-inline const SqrtReturnType
-sqrt() const
-{
-  return SqrtReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise inverse square root of *this.
-  *
-  * This function computes the coefficient-wise inverse square root.
-  *
-  * Example: \include Cwise_sqrt.cpp
-  * Output: \verbinclude Cwise_sqrt.out
-  *
-  * \sa pow(), square()
-  */
-EIGEN_DEVICE_FUNC
-inline const RsqrtReturnType
-rsqrt() const
-{
-  return RsqrtReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise signum of *this.
-  *
-  * This function computes the coefficient-wise signum.
-  *
-  * Example: \include Cwise_sign.cpp
-  * Output: \verbinclude Cwise_sign.out
-  *
-  * \sa pow(), square()
-  */
-EIGEN_DEVICE_FUNC
-inline const SignReturnType
-sign() const
-{
-  return SignReturnType(derived());
-}
-
-
-/** \returns an expression of the coefficient-wise cosine of *this.
-  *
-  * This function computes the coefficient-wise cosine. The function MatrixBase::cos() in the
-  * unsupported module MatrixFunctions computes the matrix cosine.
-  *
-  * Example: \include Cwise_cos.cpp
-  * Output: \verbinclude Cwise_cos.out
-  *
-  * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_cos">Math functions</a>, sin(), acos()
-  */
-EIGEN_DEVICE_FUNC
-inline const CosReturnType
-cos() const
-{
-  return CosReturnType(derived());
-}
-
-
-/** \returns an expression of the coefficient-wise sine of *this.
-  *
-  * This function computes the coefficient-wise sine. The function MatrixBase::sin() in the
-  * unsupported module MatrixFunctions computes the matrix sine.
-  *
-  * Example: \include Cwise_sin.cpp
-  * Output: \verbinclude Cwise_sin.out
-  *
-  * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_sin">Math functions</a>, cos(), asin()
-  */
-EIGEN_DEVICE_FUNC
-inline const SinReturnType
-sin() const
-{
-  return SinReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise tan of *this.
-  *
-  * Example: \include Cwise_tan.cpp
-  * Output: \verbinclude Cwise_tan.out
-  *
-  * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_tan">Math functions</a>, cos(), sin()
-  */
-EIGEN_DEVICE_FUNC
-inline const TanReturnType
-tan() const
-{
-  return TanReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise arc tan of *this.
-  *
-  * Example: \include Cwise_atan.cpp
-  * Output: \verbinclude Cwise_atan.out
-  *
-  * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_atan">Math functions</a>, tan(), asin(), acos()
-  */
-EIGEN_DEVICE_FUNC
-inline const AtanReturnType
-atan() const
-{
-  return AtanReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise arc cosine of *this.
-  *
-  * Example: \include Cwise_acos.cpp
-  * Output: \verbinclude Cwise_acos.out
-  *
-  * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_acos">Math functions</a>, cos(), asin()
-  */
-EIGEN_DEVICE_FUNC
-inline const AcosReturnType
-acos() const
-{
-  return AcosReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise arc sine of *this.
-  *
-  * Example: \include Cwise_asin.cpp
-  * Output: \verbinclude Cwise_asin.out
-  *
-  * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_asin">Math functions</a>, sin(), acos()
-  */
-EIGEN_DEVICE_FUNC
-inline const AsinReturnType
-asin() const
-{
-  return AsinReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise hyperbolic tan of *this.
-  *
-  * Example: \include Cwise_tanh.cpp
-  * Output: \verbinclude Cwise_tanh.out
-  *
-  * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_tanh">Math functions</a>, tan(), sinh(), cosh()
-  */
-EIGEN_DEVICE_FUNC
-inline const TanhReturnType
-tanh() const
-{
-  return TanhReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise hyperbolic sin of *this.
-  *
-  * Example: \include Cwise_sinh.cpp
-  * Output: \verbinclude Cwise_sinh.out
-  *
-  * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_sinh">Math functions</a>, sin(), tanh(), cosh()
-  */
-EIGEN_DEVICE_FUNC
-inline const SinhReturnType
-sinh() const
-{
-  return SinhReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise hyperbolic cos of *this.
-  *
-  * Example: \include Cwise_cosh.cpp
-  * Output: \verbinclude Cwise_cosh.out
-  *
-  * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_cosh">Math functions</a>, tan(), sinh(), cosh()
-  */
-EIGEN_DEVICE_FUNC
-inline const CoshReturnType
-cosh() const
-{
-  return CoshReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise inverse of *this.
-  *
-  * Example: \include Cwise_inverse.cpp
-  * Output: \verbinclude Cwise_inverse.out
-  *
-  * \sa operator/(), operator*()
-  */
-EIGEN_DEVICE_FUNC
-inline const InverseReturnType
-inverse() const
-{
-  return InverseReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise square of *this.
-  *
-  * Example: \include Cwise_square.cpp
-  * Output: \verbinclude Cwise_square.out
-  *
-  * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_squareE">Math functions</a>, abs2(), cube(), pow()
-  */
-EIGEN_DEVICE_FUNC
-inline const SquareReturnType
-square() const
-{
-  return SquareReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise cube of *this.
-  *
-  * Example: \include Cwise_cube.cpp
-  * Output: \verbinclude Cwise_cube.out
-  *
-  * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_cube">Math functions</a>, square(), pow()
-  */
-EIGEN_DEVICE_FUNC
-inline const CubeReturnType
-cube() const
-{
-  return CubeReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise round of *this.
-  *
-  * Example: \include Cwise_round.cpp
-  * Output: \verbinclude Cwise_round.out
-  *
-  * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_round">Math functions</a>, ceil(), floor()
-  */
-EIGEN_DEVICE_FUNC
-inline const RoundReturnType
-round() const
-{
-  return RoundReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise floor of *this.
-  *
-  * Example: \include Cwise_floor.cpp
-  * Output: \verbinclude Cwise_floor.out
-  *
-  * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_floor">Math functions</a>, ceil(), round()
-  */
-EIGEN_DEVICE_FUNC
-inline const FloorReturnType
-floor() const
-{
-  return FloorReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise ceil of *this.
-  *
-  * Example: \include Cwise_ceil.cpp
-  * Output: \verbinclude Cwise_ceil.out
-  *
-  * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_ceil">Math functions</a>, floor(), round()
-  */
-EIGEN_DEVICE_FUNC
-inline const CeilReturnType
-ceil() const
-{
-  return CeilReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise isnan of *this.
-  *
-  * Example: \include Cwise_isNaN.cpp
-  * Output: \verbinclude Cwise_isNaN.out
-  *
-  * \sa isfinite(), isinf()
-  */
-EIGEN_DEVICE_FUNC
-inline const IsNaNReturnType
-isNaN() const
-{
-  return IsNaNReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise isinf of *this.
-  *
-  * Example: \include Cwise_isInf.cpp
-  * Output: \verbinclude Cwise_isInf.out
-  *
-  * \sa isnan(), isfinite()
-  */
-EIGEN_DEVICE_FUNC
-inline const IsInfReturnType
-isInf() const
-{
-  return IsInfReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise isfinite of *this.
-  *
-  * Example: \include Cwise_isFinite.cpp
-  * Output: \verbinclude Cwise_isFinite.out
-  *
-  * \sa isnan(), isinf()
-  */
-EIGEN_DEVICE_FUNC
-inline const IsFiniteReturnType
-isFinite() const
-{
-  return IsFiniteReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise ! operator of *this
-  *
-  * \warning this operator is for expression of bool only.
-  *
-  * Example: \include Cwise_boolean_not.cpp
-  * Output: \verbinclude Cwise_boolean_not.out
-  *
-  * \sa operator!=()
-  */
-EIGEN_DEVICE_FUNC
-inline const BooleanNotReturnType
-operator!() const
-{
-  EIGEN_STATIC_ASSERT((internal::is_same<bool,Scalar>::value),
-                      THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL);
-  return BooleanNotReturnType(derived());
-}
-
-
-// --- SpecialFunctions module ---
-
-typedef CwiseUnaryOp<internal::scalar_lgamma_op<Scalar>, const Derived> LgammaReturnType;
-typedef CwiseUnaryOp<internal::scalar_digamma_op<Scalar>, const Derived> DigammaReturnType;
-typedef CwiseUnaryOp<internal::scalar_erf_op<Scalar>, const Derived> ErfReturnType;
-typedef CwiseUnaryOp<internal::scalar_erfc_op<Scalar>, const Derived> ErfcReturnType;
-
-/** \cpp11 \returns an expression of the coefficient-wise ln(|gamma(*this)|).
-  *
-  * \specialfunctions_module
-  *
-  * Example: \include Cwise_lgamma.cpp
-  * Output: \verbinclude Cwise_lgamma.out
-  *
-  * \note This function supports only float and double scalar types in c++11 mode. To support other scalar types,
-  * or float/double in non c++11 mode, the user has to provide implementations of lgamma(T) for any scalar
-  * type T to be supported.
-  *
-  * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_lgamma">Math functions</a>, digamma()
-  */
-EIGEN_DEVICE_FUNC
-inline const LgammaReturnType
-lgamma() const
-{
-  return LgammaReturnType(derived());
-}
-
-/** \returns an expression of the coefficient-wise digamma (psi, derivative of lgamma).
-  *
-  * \specialfunctions_module
-  *
-  * \note This function supports only float and double scalar types. To support other scalar types,
-  * the user has to provide implementations of digamma(T) for any scalar
-  * type T to be supported.
-  *
-  * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_digamma">Math functions</a>, Eigen::digamma(), Eigen::polygamma(), lgamma()
-  */
-EIGEN_DEVICE_FUNC
-inline const DigammaReturnType
-digamma() const
-{
-  return DigammaReturnType(derived());
-}
-
-/** \cpp11 \returns an expression of the coefficient-wise Gauss error
-  * function of *this.
-  *
-  * \specialfunctions_module
-  *
-  * Example: \include Cwise_erf.cpp
-  * Output: \verbinclude Cwise_erf.out
-  *
-  * \note This function supports only float and double scalar types in c++11 mode. To support other scalar types,
-  * or float/double in non c++11 mode, the user has to provide implementations of erf(T) for any scalar
-  * type T to be supported.
-  *
-  * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_erf">Math functions</a>, erfc()
-  */
-EIGEN_DEVICE_FUNC
-inline const ErfReturnType
-erf() const
-{
-  return ErfReturnType(derived());
-}
-
-/** \cpp11 \returns an expression of the coefficient-wise Complementary error
-  * function of *this.
-  *
-  * \specialfunctions_module
-  *
-  * Example: \include Cwise_erfc.cpp
-  * Output: \verbinclude Cwise_erfc.out
-  *
-  * \note This function supports only float and double scalar types in c++11 mode. To support other scalar types,
-  * or float/double in non c++11 mode, the user has to provide implementations of erfc(T) for any scalar
-  * type T to be supported.
-  *
-  * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_erfc">Math functions</a>, erf()
-  */
-EIGEN_DEVICE_FUNC
-inline const ErfcReturnType
-erfc() const
-{
-  return ErfcReturnType(derived());
-}
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/plugins/BlockMethods.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/plugins/BlockMethods.h
deleted file mode 100644
index ac35a00..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/plugins/BlockMethods.h
+++ /dev/null
@@ -1,1058 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-
-/// \internal expression type of a column */
-typedef Block<Derived, internal::traits<Derived>::RowsAtCompileTime, 1, !IsRowMajor> ColXpr;
-typedef const Block<const Derived, internal::traits<Derived>::RowsAtCompileTime, 1, !IsRowMajor> ConstColXpr;
-/// \internal expression type of a row */
-typedef Block<Derived, 1, internal::traits<Derived>::ColsAtCompileTime, IsRowMajor> RowXpr;
-typedef const Block<const Derived, 1, internal::traits<Derived>::ColsAtCompileTime, IsRowMajor> ConstRowXpr;
-/// \internal expression type of a block of whole columns */
-typedef Block<Derived, internal::traits<Derived>::RowsAtCompileTime, Dynamic, !IsRowMajor> ColsBlockXpr;
-typedef const Block<const Derived, internal::traits<Derived>::RowsAtCompileTime, Dynamic, !IsRowMajor> ConstColsBlockXpr;
-/// \internal expression type of a block of whole rows */
-typedef Block<Derived, Dynamic, internal::traits<Derived>::ColsAtCompileTime, IsRowMajor> RowsBlockXpr;
-typedef const Block<const Derived, Dynamic, internal::traits<Derived>::ColsAtCompileTime, IsRowMajor> ConstRowsBlockXpr;
-/// \internal expression type of a block of whole columns */
-template<int N> struct NColsBlockXpr { typedef Block<Derived, internal::traits<Derived>::RowsAtCompileTime, N, !IsRowMajor> Type; };
-template<int N> struct ConstNColsBlockXpr { typedef const Block<const Derived, internal::traits<Derived>::RowsAtCompileTime, N, !IsRowMajor> Type; };
-/// \internal expression type of a block of whole rows */
-template<int N> struct NRowsBlockXpr { typedef Block<Derived, N, internal::traits<Derived>::ColsAtCompileTime, IsRowMajor> Type; };
-template<int N> struct ConstNRowsBlockXpr { typedef const Block<const Derived, N, internal::traits<Derived>::ColsAtCompileTime, IsRowMajor> Type; };
-/// \internal expression of a block */
-typedef Block<Derived> BlockXpr;
-typedef const Block<const Derived> ConstBlockXpr;
-/// \internal expression of a block of fixed sizes */
-template<int Rows, int Cols> struct FixedBlockXpr { typedef Block<Derived,Rows,Cols> Type; };
-template<int Rows, int Cols> struct ConstFixedBlockXpr { typedef Block<const Derived,Rows,Cols> Type; };
-
-typedef VectorBlock<Derived> SegmentReturnType;
-typedef const VectorBlock<const Derived> ConstSegmentReturnType;
-template<int Size> struct FixedSegmentReturnType { typedef VectorBlock<Derived, Size> Type; };
-template<int Size> struct ConstFixedSegmentReturnType { typedef const VectorBlock<const Derived, Size> Type; };
-
-#endif // not EIGEN_PARSED_BY_DOXYGEN
-
-/// \returns a dynamic-size expression of a block in *this.
-///
-/// \param startRow the first row in the block
-/// \param startCol the first column in the block
-/// \param blockRows the number of rows in the block
-/// \param blockCols the number of columns in the block
-///
-/// Example: \include MatrixBase_block_int_int_int_int.cpp
-/// Output: \verbinclude MatrixBase_block_int_int_int_int.out
-///
-/// \note Even though the returned expression has dynamic size, in the case
-/// when it is applied to a fixed-size matrix, it inherits a fixed maximal size,
-/// which means that evaluating it does not cause a dynamic memory allocation.
-///
-EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
-///
-/// \sa class Block, block(Index,Index)
-///
-EIGEN_DEVICE_FUNC
-inline BlockXpr block(Index startRow, Index startCol, Index blockRows, Index blockCols)
-{
-  return BlockXpr(derived(), startRow, startCol, blockRows, blockCols);
-}
-
-/// This is the const version of block(Index,Index,Index,Index). */
-EIGEN_DEVICE_FUNC
-inline const ConstBlockXpr block(Index startRow, Index startCol, Index blockRows, Index blockCols) const
-{
-  return ConstBlockXpr(derived(), startRow, startCol, blockRows, blockCols);
-}
-
-
-
-
-/// \returns a dynamic-size expression of a top-right corner of *this.
-///
-/// \param cRows the number of rows in the corner
-/// \param cCols the number of columns in the corner
-///
-/// Example: \include MatrixBase_topRightCorner_int_int.cpp
-/// Output: \verbinclude MatrixBase_topRightCorner_int_int.out
-///
-EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
-///
-/// \sa class Block, block(Index,Index,Index,Index)
-///
-EIGEN_DEVICE_FUNC
-inline BlockXpr topRightCorner(Index cRows, Index cCols)
-{
-  return BlockXpr(derived(), 0, cols() - cCols, cRows, cCols);
-}
-
-/// This is the const version of topRightCorner(Index, Index).
-EIGEN_DEVICE_FUNC
-inline const ConstBlockXpr topRightCorner(Index cRows, Index cCols) const
-{
-  return ConstBlockXpr(derived(), 0, cols() - cCols, cRows, cCols);
-}
-
-/// \returns an expression of a fixed-size top-right corner of *this.
-///
-/// \tparam CRows the number of rows in the corner
-/// \tparam CCols the number of columns in the corner
-///
-/// Example: \include MatrixBase_template_int_int_topRightCorner.cpp
-/// Output: \verbinclude MatrixBase_template_int_int_topRightCorner.out
-///
-EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
-///
-/// \sa class Block, block<int,int>(Index,Index)
-///
-template<int CRows, int CCols>
-EIGEN_DEVICE_FUNC
-inline typename FixedBlockXpr<CRows,CCols>::Type topRightCorner()
-{
-  return typename FixedBlockXpr<CRows,CCols>::Type(derived(), 0, cols() - CCols);
-}
-
-/// This is the const version of topRightCorner<int, int>().
-template<int CRows, int CCols>
-EIGEN_DEVICE_FUNC
-inline const typename ConstFixedBlockXpr<CRows,CCols>::Type topRightCorner() const
-{
-  return typename ConstFixedBlockXpr<CRows,CCols>::Type(derived(), 0, cols() - CCols);
-}
-
-/// \returns an expression of a top-right corner of *this.
-///
-/// \tparam CRows number of rows in corner as specified at compile-time
-/// \tparam CCols number of columns in corner as specified at compile-time
-/// \param  cRows number of rows in corner as specified at run-time
-/// \param  cCols number of columns in corner as specified at run-time
-///
-/// This function is mainly useful for corners where the number of rows is specified at compile-time
-/// and the number of columns is specified at run-time, or vice versa. The compile-time and run-time
-/// information should not contradict. In other words, \a cRows should equal \a CRows unless
-/// \a CRows is \a Dynamic, and the same for the number of columns.
-///
-/// Example: \include MatrixBase_template_int_int_topRightCorner_int_int.cpp
-/// Output: \verbinclude MatrixBase_template_int_int_topRightCorner_int_int.out
-///
-EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
-///
-/// \sa class Block
-///
-template<int CRows, int CCols>
-inline typename FixedBlockXpr<CRows,CCols>::Type topRightCorner(Index cRows, Index cCols)
-{
-  return typename FixedBlockXpr<CRows,CCols>::Type(derived(), 0, cols() - cCols, cRows, cCols);
-}
-
-/// This is the const version of topRightCorner<int, int>(Index, Index).
-template<int CRows, int CCols>
-inline const typename ConstFixedBlockXpr<CRows,CCols>::Type topRightCorner(Index cRows, Index cCols) const
-{
-  return typename ConstFixedBlockXpr<CRows,CCols>::Type(derived(), 0, cols() - cCols, cRows, cCols);
-}
-
-
-
-/// \returns a dynamic-size expression of a top-left corner of *this.
-///
-/// \param cRows the number of rows in the corner
-/// \param cCols the number of columns in the corner
-///
-/// Example: \include MatrixBase_topLeftCorner_int_int.cpp
-/// Output: \verbinclude MatrixBase_topLeftCorner_int_int.out
-///
-EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
-///
-/// \sa class Block, block(Index,Index,Index,Index)
-///
-EIGEN_DEVICE_FUNC
-inline BlockXpr topLeftCorner(Index cRows, Index cCols)
-{
-  return BlockXpr(derived(), 0, 0, cRows, cCols);
-}
-
-/// This is the const version of topLeftCorner(Index, Index).
-EIGEN_DEVICE_FUNC
-inline const ConstBlockXpr topLeftCorner(Index cRows, Index cCols) const
-{
-  return ConstBlockXpr(derived(), 0, 0, cRows, cCols);
-}
-
-/// \returns an expression of a fixed-size top-left corner of *this.
-///
-/// The template parameters CRows and CCols are the number of rows and columns in the corner.
-///
-/// Example: \include MatrixBase_template_int_int_topLeftCorner.cpp
-/// Output: \verbinclude MatrixBase_template_int_int_topLeftCorner.out
-///
-EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
-///
-/// \sa class Block, block(Index,Index,Index,Index)
-///
-template<int CRows, int CCols>
-EIGEN_DEVICE_FUNC
-inline typename FixedBlockXpr<CRows,CCols>::Type topLeftCorner()
-{
-  return typename FixedBlockXpr<CRows,CCols>::Type(derived(), 0, 0);
-}
-
-/// This is the const version of topLeftCorner<int, int>().
-template<int CRows, int CCols>
-EIGEN_DEVICE_FUNC
-inline const typename ConstFixedBlockXpr<CRows,CCols>::Type topLeftCorner() const
-{
-  return typename ConstFixedBlockXpr<CRows,CCols>::Type(derived(), 0, 0);
-}
-
-/// \returns an expression of a top-left corner of *this.
-///
-/// \tparam CRows number of rows in corner as specified at compile-time
-/// \tparam CCols number of columns in corner as specified at compile-time
-/// \param  cRows number of rows in corner as specified at run-time
-/// \param  cCols number of columns in corner as specified at run-time
-///
-/// This function is mainly useful for corners where the number of rows is specified at compile-time
-/// and the number of columns is specified at run-time, or vice versa. The compile-time and run-time
-/// information should not contradict. In other words, \a cRows should equal \a CRows unless
-/// \a CRows is \a Dynamic, and the same for the number of columns.
-///
-/// Example: \include MatrixBase_template_int_int_topLeftCorner_int_int.cpp
-/// Output: \verbinclude MatrixBase_template_int_int_topLeftCorner_int_int.out
-///
-EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
-///
-/// \sa class Block
-///
-template<int CRows, int CCols>
-inline typename FixedBlockXpr<CRows,CCols>::Type topLeftCorner(Index cRows, Index cCols)
-{
-  return typename FixedBlockXpr<CRows,CCols>::Type(derived(), 0, 0, cRows, cCols);
-}
-
-/// This is the const version of topLeftCorner<int, int>(Index, Index).
-template<int CRows, int CCols>
-inline const typename ConstFixedBlockXpr<CRows,CCols>::Type topLeftCorner(Index cRows, Index cCols) const
-{
-  return typename ConstFixedBlockXpr<CRows,CCols>::Type(derived(), 0, 0, cRows, cCols);
-}
-
-
-
-/// \returns a dynamic-size expression of a bottom-right corner of *this.
-///
-/// \param cRows the number of rows in the corner
-/// \param cCols the number of columns in the corner
-///
-/// Example: \include MatrixBase_bottomRightCorner_int_int.cpp
-/// Output: \verbinclude MatrixBase_bottomRightCorner_int_int.out
-///
-EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
-///
-/// \sa class Block, block(Index,Index,Index,Index)
-///
-EIGEN_DEVICE_FUNC
-inline BlockXpr bottomRightCorner(Index cRows, Index cCols)
-{
-  return BlockXpr(derived(), rows() - cRows, cols() - cCols, cRows, cCols);
-}
-
-/// This is the const version of bottomRightCorner(Index, Index).
-EIGEN_DEVICE_FUNC
-inline const ConstBlockXpr bottomRightCorner(Index cRows, Index cCols) const
-{
-  return ConstBlockXpr(derived(), rows() - cRows, cols() - cCols, cRows, cCols);
-}
-
-/// \returns an expression of a fixed-size bottom-right corner of *this.
-///
-/// The template parameters CRows and CCols are the number of rows and columns in the corner.
-///
-/// Example: \include MatrixBase_template_int_int_bottomRightCorner.cpp
-/// Output: \verbinclude MatrixBase_template_int_int_bottomRightCorner.out
-///
-EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
-///
-/// \sa class Block, block(Index,Index,Index,Index)
-///
-template<int CRows, int CCols>
-EIGEN_DEVICE_FUNC
-inline typename FixedBlockXpr<CRows,CCols>::Type bottomRightCorner()
-{
-  return typename FixedBlockXpr<CRows,CCols>::Type(derived(), rows() - CRows, cols() - CCols);
-}
-
-/// This is the const version of bottomRightCorner<int, int>().
-template<int CRows, int CCols>
-EIGEN_DEVICE_FUNC
-inline const typename ConstFixedBlockXpr<CRows,CCols>::Type bottomRightCorner() const
-{
-  return typename ConstFixedBlockXpr<CRows,CCols>::Type(derived(), rows() - CRows, cols() - CCols);
-}
-
-/// \returns an expression of a bottom-right corner of *this.
-///
-/// \tparam CRows number of rows in corner as specified at compile-time
-/// \tparam CCols number of columns in corner as specified at compile-time
-/// \param  cRows number of rows in corner as specified at run-time
-/// \param  cCols number of columns in corner as specified at run-time
-///
-/// This function is mainly useful for corners where the number of rows is specified at compile-time
-/// and the number of columns is specified at run-time, or vice versa. The compile-time and run-time
-/// information should not contradict. In other words, \a cRows should equal \a CRows unless
-/// \a CRows is \a Dynamic, and the same for the number of columns.
-///
-/// Example: \include MatrixBase_template_int_int_bottomRightCorner_int_int.cpp
-/// Output: \verbinclude MatrixBase_template_int_int_bottomRightCorner_int_int.out
-///
-EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
-///
-/// \sa class Block
-///
-template<int CRows, int CCols>
-inline typename FixedBlockXpr<CRows,CCols>::Type bottomRightCorner(Index cRows, Index cCols)
-{
-  return typename FixedBlockXpr<CRows,CCols>::Type(derived(), rows() - cRows, cols() - cCols, cRows, cCols);
-}
-
-/// This is the const version of bottomRightCorner<int, int>(Index, Index).
-template<int CRows, int CCols>
-inline const typename ConstFixedBlockXpr<CRows,CCols>::Type bottomRightCorner(Index cRows, Index cCols) const
-{
-  return typename ConstFixedBlockXpr<CRows,CCols>::Type(derived(), rows() - cRows, cols() - cCols, cRows, cCols);
-}
-
-
-
-/// \returns a dynamic-size expression of a bottom-left corner of *this.
-///
-/// \param cRows the number of rows in the corner
-/// \param cCols the number of columns in the corner
-///
-/// Example: \include MatrixBase_bottomLeftCorner_int_int.cpp
-/// Output: \verbinclude MatrixBase_bottomLeftCorner_int_int.out
-///
-EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
-///
-/// \sa class Block, block(Index,Index,Index,Index)
-///
-EIGEN_DEVICE_FUNC
-inline BlockXpr bottomLeftCorner(Index cRows, Index cCols)
-{
-  return BlockXpr(derived(), rows() - cRows, 0, cRows, cCols);
-}
-
-/// This is the const version of bottomLeftCorner(Index, Index).
-EIGEN_DEVICE_FUNC
-inline const ConstBlockXpr bottomLeftCorner(Index cRows, Index cCols) const
-{
-  return ConstBlockXpr(derived(), rows() - cRows, 0, cRows, cCols);
-}
-
-/// \returns an expression of a fixed-size bottom-left corner of *this.
-///
-/// The template parameters CRows and CCols are the number of rows and columns in the corner.
-///
-/// Example: \include MatrixBase_template_int_int_bottomLeftCorner.cpp
-/// Output: \verbinclude MatrixBase_template_int_int_bottomLeftCorner.out
-///
-EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
-///
-/// \sa class Block, block(Index,Index,Index,Index)
-///
-template<int CRows, int CCols>
-EIGEN_DEVICE_FUNC
-inline typename FixedBlockXpr<CRows,CCols>::Type bottomLeftCorner()
-{
-  return typename FixedBlockXpr<CRows,CCols>::Type(derived(), rows() - CRows, 0);
-}
-
-/// This is the const version of bottomLeftCorner<int, int>().
-template<int CRows, int CCols>
-EIGEN_DEVICE_FUNC
-inline const typename ConstFixedBlockXpr<CRows,CCols>::Type bottomLeftCorner() const
-{
-  return typename ConstFixedBlockXpr<CRows,CCols>::Type(derived(), rows() - CRows, 0);
-}
-
-/// \returns an expression of a bottom-left corner of *this.
-///
-/// \tparam CRows number of rows in corner as specified at compile-time
-/// \tparam CCols number of columns in corner as specified at compile-time
-/// \param  cRows number of rows in corner as specified at run-time
-/// \param  cCols number of columns in corner as specified at run-time
-///
-/// This function is mainly useful for corners where the number of rows is specified at compile-time
-/// and the number of columns is specified at run-time, or vice versa. The compile-time and run-time
-/// information should not contradict. In other words, \a cRows should equal \a CRows unless
-/// \a CRows is \a Dynamic, and the same for the number of columns.
-///
-/// Example: \include MatrixBase_template_int_int_bottomLeftCorner_int_int.cpp
-/// Output: \verbinclude MatrixBase_template_int_int_bottomLeftCorner_int_int.out
-///
-EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
-///
-/// \sa class Block
-///
-template<int CRows, int CCols>
-inline typename FixedBlockXpr<CRows,CCols>::Type bottomLeftCorner(Index cRows, Index cCols)
-{
-  return typename FixedBlockXpr<CRows,CCols>::Type(derived(), rows() - cRows, 0, cRows, cCols);
-}
-
-/// This is the const version of bottomLeftCorner<int, int>(Index, Index).
-template<int CRows, int CCols>
-inline const typename ConstFixedBlockXpr<CRows,CCols>::Type bottomLeftCorner(Index cRows, Index cCols) const
-{
-  return typename ConstFixedBlockXpr<CRows,CCols>::Type(derived(), rows() - cRows, 0, cRows, cCols);
-}
-
-
-
-/// \returns a block consisting of the top rows of *this.
-///
-/// \param n the number of rows in the block
-///
-/// Example: \include MatrixBase_topRows_int.cpp
-/// Output: \verbinclude MatrixBase_topRows_int.out
-///
-EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(row-major)
-///
-/// \sa class Block, block(Index,Index,Index,Index)
-///
-EIGEN_DEVICE_FUNC
-inline RowsBlockXpr topRows(Index n)
-{
-  return RowsBlockXpr(derived(), 0, 0, n, cols());
-}
-
-/// This is the const version of topRows(Index).
-EIGEN_DEVICE_FUNC
-inline ConstRowsBlockXpr topRows(Index n) const
-{
-  return ConstRowsBlockXpr(derived(), 0, 0, n, cols());
-}
-
-/// \returns a block consisting of the top rows of *this.
-///
-/// \tparam N the number of rows in the block as specified at compile-time
-/// \param n the number of rows in the block as specified at run-time
-///
-/// The compile-time and run-time information should not contradict. In other words,
-/// \a n should equal \a N unless \a N is \a Dynamic.
-///
-/// Example: \include MatrixBase_template_int_topRows.cpp
-/// Output: \verbinclude MatrixBase_template_int_topRows.out
-///
-EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(row-major)
-///
-/// \sa class Block, block(Index,Index,Index,Index)
-///
-template<int N>
-EIGEN_DEVICE_FUNC
-inline typename NRowsBlockXpr<N>::Type topRows(Index n = N)
-{
-  return typename NRowsBlockXpr<N>::Type(derived(), 0, 0, n, cols());
-}
-
-/// This is the const version of topRows<int>().
-template<int N>
-EIGEN_DEVICE_FUNC
-inline typename ConstNRowsBlockXpr<N>::Type topRows(Index n = N) const
-{
-  return typename ConstNRowsBlockXpr<N>::Type(derived(), 0, 0, n, cols());
-}
-
-
-
-/// \returns a block consisting of the bottom rows of *this.
-///
-/// \param n the number of rows in the block
-///
-/// Example: \include MatrixBase_bottomRows_int.cpp
-/// Output: \verbinclude MatrixBase_bottomRows_int.out
-///
-EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(row-major)
-///
-/// \sa class Block, block(Index,Index,Index,Index)
-///
-EIGEN_DEVICE_FUNC
-inline RowsBlockXpr bottomRows(Index n)
-{
-  return RowsBlockXpr(derived(), rows() - n, 0, n, cols());
-}
-
-/// This is the const version of bottomRows(Index).
-EIGEN_DEVICE_FUNC
-inline ConstRowsBlockXpr bottomRows(Index n) const
-{
-  return ConstRowsBlockXpr(derived(), rows() - n, 0, n, cols());
-}
-
-/// \returns a block consisting of the bottom rows of *this.
-///
-/// \tparam N the number of rows in the block as specified at compile-time
-/// \param n the number of rows in the block as specified at run-time
-///
-/// The compile-time and run-time information should not contradict. In other words,
-/// \a n should equal \a N unless \a N is \a Dynamic.
-///
-/// Example: \include MatrixBase_template_int_bottomRows.cpp
-/// Output: \verbinclude MatrixBase_template_int_bottomRows.out
-///
-EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(row-major)
-///
-/// \sa class Block, block(Index,Index,Index,Index)
-///
-template<int N>
-EIGEN_DEVICE_FUNC
-inline typename NRowsBlockXpr<N>::Type bottomRows(Index n = N)
-{
-  return typename NRowsBlockXpr<N>::Type(derived(), rows() - n, 0, n, cols());
-}
-
-/// This is the const version of bottomRows<int>().
-template<int N>
-EIGEN_DEVICE_FUNC
-inline typename ConstNRowsBlockXpr<N>::Type bottomRows(Index n = N) const
-{
-  return typename ConstNRowsBlockXpr<N>::Type(derived(), rows() - n, 0, n, cols());
-}
-
-
-
-/// \returns a block consisting of a range of rows of *this.
-///
-/// \param startRow the index of the first row in the block
-/// \param n the number of rows in the block
-///
-/// Example: \include DenseBase_middleRows_int.cpp
-/// Output: \verbinclude DenseBase_middleRows_int.out
-///
-EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(row-major)
-///
-/// \sa class Block, block(Index,Index,Index,Index)
-///
-EIGEN_DEVICE_FUNC
-inline RowsBlockXpr middleRows(Index startRow, Index n)
-{
-  return RowsBlockXpr(derived(), startRow, 0, n, cols());
-}
-
-/// This is the const version of middleRows(Index,Index).
-EIGEN_DEVICE_FUNC
-inline ConstRowsBlockXpr middleRows(Index startRow, Index n) const
-{
-  return ConstRowsBlockXpr(derived(), startRow, 0, n, cols());
-}
-
-/// \returns a block consisting of a range of rows of *this.
-///
-/// \tparam N the number of rows in the block as specified at compile-time
-/// \param startRow the index of the first row in the block
-/// \param n the number of rows in the block as specified at run-time
-///
-/// The compile-time and run-time information should not contradict. In other words,
-/// \a n should equal \a N unless \a N is \a Dynamic.
-///
-/// Example: \include DenseBase_template_int_middleRows.cpp
-/// Output: \verbinclude DenseBase_template_int_middleRows.out
-///
-EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(row-major)
-///
-/// \sa class Block, block(Index,Index,Index,Index)
-///
-template<int N>
-EIGEN_DEVICE_FUNC
-inline typename NRowsBlockXpr<N>::Type middleRows(Index startRow, Index n = N)
-{
-  return typename NRowsBlockXpr<N>::Type(derived(), startRow, 0, n, cols());
-}
-
-/// This is the const version of middleRows<int>().
-template<int N>
-EIGEN_DEVICE_FUNC
-inline typename ConstNRowsBlockXpr<N>::Type middleRows(Index startRow, Index n = N) const
-{
-  return typename ConstNRowsBlockXpr<N>::Type(derived(), startRow, 0, n, cols());
-}
-
-
-
-/// \returns a block consisting of the left columns of *this.
-///
-/// \param n the number of columns in the block
-///
-/// Example: \include MatrixBase_leftCols_int.cpp
-/// Output: \verbinclude MatrixBase_leftCols_int.out
-///
-EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(column-major)
-///
-/// \sa class Block, block(Index,Index,Index,Index)
-///
-EIGEN_DEVICE_FUNC
-inline ColsBlockXpr leftCols(Index n)
-{
-  return ColsBlockXpr(derived(), 0, 0, rows(), n);
-}
-
-/// This is the const version of leftCols(Index).
-EIGEN_DEVICE_FUNC
-inline ConstColsBlockXpr leftCols(Index n) const
-{
-  return ConstColsBlockXpr(derived(), 0, 0, rows(), n);
-}
-
-/// \returns a block consisting of the left columns of *this.
-///
-/// \tparam N the number of columns in the block as specified at compile-time
-/// \param n the number of columns in the block as specified at run-time
-///
-/// The compile-time and run-time information should not contradict. In other words,
-/// \a n should equal \a N unless \a N is \a Dynamic.
-///
-/// Example: \include MatrixBase_template_int_leftCols.cpp
-/// Output: \verbinclude MatrixBase_template_int_leftCols.out
-///
-EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(column-major)
-///
-/// \sa class Block, block(Index,Index,Index,Index)
-///
-template<int N>
-EIGEN_DEVICE_FUNC
-inline typename NColsBlockXpr<N>::Type leftCols(Index n = N)
-{
-  return typename NColsBlockXpr<N>::Type(derived(), 0, 0, rows(), n);
-}
-
-/// This is the const version of leftCols<int>().
-template<int N>
-EIGEN_DEVICE_FUNC
-inline typename ConstNColsBlockXpr<N>::Type leftCols(Index n = N) const
-{
-  return typename ConstNColsBlockXpr<N>::Type(derived(), 0, 0, rows(), n);
-}
-
-
-
-/// \returns a block consisting of the right columns of *this.
-///
-/// \param n the number of columns in the block
-///
-/// Example: \include MatrixBase_rightCols_int.cpp
-/// Output: \verbinclude MatrixBase_rightCols_int.out
-///
-EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(column-major)
-///
-/// \sa class Block, block(Index,Index,Index,Index)
-///
-EIGEN_DEVICE_FUNC
-inline ColsBlockXpr rightCols(Index n)
-{
-  return ColsBlockXpr(derived(), 0, cols() - n, rows(), n);
-}
-
-/// This is the const version of rightCols(Index).
-EIGEN_DEVICE_FUNC
-inline ConstColsBlockXpr rightCols(Index n) const
-{
-  return ConstColsBlockXpr(derived(), 0, cols() - n, rows(), n);
-}
-
-/// \returns a block consisting of the right columns of *this.
-///
-/// \tparam N the number of columns in the block as specified at compile-time
-/// \param n the number of columns in the block as specified at run-time
-///
-/// The compile-time and run-time information should not contradict. In other words,
-/// \a n should equal \a N unless \a N is \a Dynamic.
-///
-/// Example: \include MatrixBase_template_int_rightCols.cpp
-/// Output: \verbinclude MatrixBase_template_int_rightCols.out
-///
-EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(column-major)
-///
-/// \sa class Block, block(Index,Index,Index,Index)
-///
-template<int N>
-EIGEN_DEVICE_FUNC
-inline typename NColsBlockXpr<N>::Type rightCols(Index n = N)
-{
-  return typename NColsBlockXpr<N>::Type(derived(), 0, cols() - n, rows(), n);
-}
-
-/// This is the const version of rightCols<int>().
-template<int N>
-EIGEN_DEVICE_FUNC
-inline typename ConstNColsBlockXpr<N>::Type rightCols(Index n = N) const
-{
-  return typename ConstNColsBlockXpr<N>::Type(derived(), 0, cols() - n, rows(), n);
-}
-
-
-
-/// \returns a block consisting of a range of columns of *this.
-///
-/// \param startCol the index of the first column in the block
-/// \param numCols the number of columns in the block
-///
-/// Example: \include DenseBase_middleCols_int.cpp
-/// Output: \verbinclude DenseBase_middleCols_int.out
-///
-EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(column-major)
-///
-/// \sa class Block, block(Index,Index,Index,Index)
-///
-EIGEN_DEVICE_FUNC
-inline ColsBlockXpr middleCols(Index startCol, Index numCols)
-{
-  return ColsBlockXpr(derived(), 0, startCol, rows(), numCols);
-}
-
-/// This is the const version of middleCols(Index,Index).
-EIGEN_DEVICE_FUNC
-inline ConstColsBlockXpr middleCols(Index startCol, Index numCols) const
-{
-  return ConstColsBlockXpr(derived(), 0, startCol, rows(), numCols);
-}
-
-/// \returns a block consisting of a range of columns of *this.
-///
-/// \tparam N the number of columns in the block as specified at compile-time
-/// \param startCol the index of the first column in the block
-/// \param n the number of columns in the block as specified at run-time
-///
-/// The compile-time and run-time information should not contradict. In other words,
-/// \a n should equal \a N unless \a N is \a Dynamic.
-///
-/// Example: \include DenseBase_template_int_middleCols.cpp
-/// Output: \verbinclude DenseBase_template_int_middleCols.out
-///
-EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(column-major)
-///
-/// \sa class Block, block(Index,Index,Index,Index)
-///
-template<int N>
-EIGEN_DEVICE_FUNC
-inline typename NColsBlockXpr<N>::Type middleCols(Index startCol, Index n = N)
-{
-  return typename NColsBlockXpr<N>::Type(derived(), 0, startCol, rows(), n);
-}
-
-/// This is the const version of middleCols<int>().
-template<int N>
-EIGEN_DEVICE_FUNC
-inline typename ConstNColsBlockXpr<N>::Type middleCols(Index startCol, Index n = N) const
-{
-  return typename ConstNColsBlockXpr<N>::Type(derived(), 0, startCol, rows(), n);
-}
-
-
-
-/// \returns a fixed-size expression of a block in *this.
-///
-/// The template parameters \a NRows and \a NCols are the number of
-/// rows and columns in the block.
-///
-/// \param startRow the first row in the block
-/// \param startCol the first column in the block
-///
-/// Example: \include MatrixBase_block_int_int.cpp
-/// Output: \verbinclude MatrixBase_block_int_int.out
-///
-/// \note since block is a templated member, the keyword template has to be used
-/// if the matrix type is also a template parameter: \code m.template block<3,3>(1,1); \endcode
-///
-EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
-///
-/// \sa class Block, block(Index,Index,Index,Index)
-///
-template<int NRows, int NCols>
-EIGEN_DEVICE_FUNC
-inline typename FixedBlockXpr<NRows,NCols>::Type block(Index startRow, Index startCol)
-{
-  return typename FixedBlockXpr<NRows,NCols>::Type(derived(), startRow, startCol);
-}
-
-/// This is the const version of block<>(Index, Index). */
-template<int NRows, int NCols>
-EIGEN_DEVICE_FUNC
-inline const typename ConstFixedBlockXpr<NRows,NCols>::Type block(Index startRow, Index startCol) const
-{
-  return typename ConstFixedBlockXpr<NRows,NCols>::Type(derived(), startRow, startCol);
-}
-
-/// \returns an expression of a block in *this.
-///
-/// \tparam NRows number of rows in block as specified at compile-time
-/// \tparam NCols number of columns in block as specified at compile-time
-/// \param  startRow  the first row in the block
-/// \param  startCol  the first column in the block
-/// \param  blockRows number of rows in block as specified at run-time
-/// \param  blockCols number of columns in block as specified at run-time
-///
-/// This function is mainly useful for blocks where the number of rows is specified at compile-time
-/// and the number of columns is specified at run-time, or vice versa. The compile-time and run-time
-/// information should not contradict. In other words, \a blockRows should equal \a NRows unless
-/// \a NRows is \a Dynamic, and the same for the number of columns.
-///
-/// Example: \include MatrixBase_template_int_int_block_int_int_int_int.cpp
-/// Output: \verbinclude MatrixBase_template_int_int_block_int_int_int_int.cpp
-///
-EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL
-///
-/// \sa class Block, block(Index,Index,Index,Index)
-///
-template<int NRows, int NCols>
-inline typename FixedBlockXpr<NRows,NCols>::Type block(Index startRow, Index startCol,
-                                                  Index blockRows, Index blockCols)
-{
-  return typename FixedBlockXpr<NRows,NCols>::Type(derived(), startRow, startCol, blockRows, blockCols);
-}
-
-/// This is the const version of block<>(Index, Index, Index, Index).
-template<int NRows, int NCols>
-inline const typename ConstFixedBlockXpr<NRows,NCols>::Type block(Index startRow, Index startCol,
-                                                              Index blockRows, Index blockCols) const
-{
-  return typename ConstFixedBlockXpr<NRows,NCols>::Type(derived(), startRow, startCol, blockRows, blockCols);
-}
-
-/// \returns an expression of the \a i-th column of *this. Note that the numbering starts at 0.
-///
-/// Example: \include MatrixBase_col.cpp
-/// Output: \verbinclude MatrixBase_col.out
-///
-EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(column-major)
-/**
-  * \sa row(), class Block */
-EIGEN_DEVICE_FUNC
-inline ColXpr col(Index i)
-{
-  return ColXpr(derived(), i);
-}
-
-/// This is the const version of col().
-EIGEN_DEVICE_FUNC
-inline ConstColXpr col(Index i) const
-{
-  return ConstColXpr(derived(), i);
-}
-
-/// \returns an expression of the \a i-th row of *this. Note that the numbering starts at 0.
-///
-/// Example: \include MatrixBase_row.cpp
-/// Output: \verbinclude MatrixBase_row.out
-///
-EIGEN_DOC_BLOCK_ADDONS_INNER_PANEL_IF(row-major)
-/**
-  * \sa col(), class Block */
-EIGEN_DEVICE_FUNC
-inline RowXpr row(Index i)
-{
-  return RowXpr(derived(), i);
-}
-
-/// This is the const version of row(). */
-EIGEN_DEVICE_FUNC
-inline ConstRowXpr row(Index i) const
-{
-  return ConstRowXpr(derived(), i);
-}
-
-/// \returns a dynamic-size expression of a segment (i.e. a vector block) in *this.
-///
-/// \only_for_vectors
-///
-/// \param start the first coefficient in the segment
-/// \param n the number of coefficients in the segment
-///
-/// Example: \include MatrixBase_segment_int_int.cpp
-/// Output: \verbinclude MatrixBase_segment_int_int.out
-///
-/// \note Even though the returned expression has dynamic size, in the case
-/// when it is applied to a fixed-size vector, it inherits a fixed maximal size,
-/// which means that evaluating it does not cause a dynamic memory allocation.
-///
-/// \sa class Block, segment(Index)
-///
-EIGEN_DEVICE_FUNC
-inline SegmentReturnType segment(Index start, Index n)
-{
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
-  return SegmentReturnType(derived(), start, n);
-}
-
-
-/// This is the const version of segment(Index,Index).
-EIGEN_DEVICE_FUNC
-inline ConstSegmentReturnType segment(Index start, Index n) const
-{
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
-  return ConstSegmentReturnType(derived(), start, n);
-}
-
-/// \returns a dynamic-size expression of the first coefficients of *this.
-///
-/// \only_for_vectors
-///
-/// \param n the number of coefficients in the segment
-///
-/// Example: \include MatrixBase_start_int.cpp
-/// Output: \verbinclude MatrixBase_start_int.out
-///
-/// \note Even though the returned expression has dynamic size, in the case
-/// when it is applied to a fixed-size vector, it inherits a fixed maximal size,
-/// which means that evaluating it does not cause a dynamic memory allocation.
-///
-/// \sa class Block, block(Index,Index)
-///
-EIGEN_DEVICE_FUNC
-inline SegmentReturnType head(Index n)
-{
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
-  return SegmentReturnType(derived(), 0, n);
-}
-
-/// This is the const version of head(Index).
-EIGEN_DEVICE_FUNC
-inline ConstSegmentReturnType head(Index n) const
-{
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
-  return ConstSegmentReturnType(derived(), 0, n);
-}
-
-/// \returns a dynamic-size expression of the last coefficients of *this.
-///
-/// \only_for_vectors
-///
-/// \param n the number of coefficients in the segment
-///
-/// Example: \include MatrixBase_end_int.cpp
-/// Output: \verbinclude MatrixBase_end_int.out
-///
-/// \note Even though the returned expression has dynamic size, in the case
-/// when it is applied to a fixed-size vector, it inherits a fixed maximal size,
-/// which means that evaluating it does not cause a dynamic memory allocation.
-///
-/// \sa class Block, block(Index,Index)
-///
-EIGEN_DEVICE_FUNC
-inline SegmentReturnType tail(Index n)
-{
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
-  return SegmentReturnType(derived(), this->size() - n, n);
-}
-
-/// This is the const version of tail(Index).
-EIGEN_DEVICE_FUNC
-inline ConstSegmentReturnType tail(Index n) const
-{
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
-  return ConstSegmentReturnType(derived(), this->size() - n, n);
-}
-
-/// \returns a fixed-size expression of a segment (i.e. a vector block) in \c *this
-///
-/// \only_for_vectors
-///
-/// \tparam N the number of coefficients in the segment as specified at compile-time
-/// \param start the index of the first element in the segment
-/// \param n the number of coefficients in the segment as specified at compile-time
-///
-/// The compile-time and run-time information should not contradict. In other words,
-/// \a n should equal \a N unless \a N is \a Dynamic.
-///
-/// Example: \include MatrixBase_template_int_segment.cpp
-/// Output: \verbinclude MatrixBase_template_int_segment.out
-///
-/// \sa class Block
-///
-template<int N>
-EIGEN_DEVICE_FUNC
-inline typename FixedSegmentReturnType<N>::Type segment(Index start, Index n = N)
-{
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
-  return typename FixedSegmentReturnType<N>::Type(derived(), start, n);
-}
-
-/// This is the const version of segment<int>(Index).
-template<int N>
-EIGEN_DEVICE_FUNC
-inline typename ConstFixedSegmentReturnType<N>::Type segment(Index start, Index n = N) const
-{
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
-  return typename ConstFixedSegmentReturnType<N>::Type(derived(), start, n);
-}
-
-/// \returns a fixed-size expression of the first coefficients of *this.
-///
-/// \only_for_vectors
-///
-/// \tparam N the number of coefficients in the segment as specified at compile-time
-/// \param  n the number of coefficients in the segment as specified at run-time
-///
-/// The compile-time and run-time information should not contradict. In other words,
-/// \a n should equal \a N unless \a N is \a Dynamic.
-///
-/// Example: \include MatrixBase_template_int_start.cpp
-/// Output: \verbinclude MatrixBase_template_int_start.out
-///
-/// \sa class Block
-///
-template<int N>
-EIGEN_DEVICE_FUNC
-inline typename FixedSegmentReturnType<N>::Type head(Index n = N)
-{
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
-  return typename FixedSegmentReturnType<N>::Type(derived(), 0, n);
-}
-
-/// This is the const version of head<int>().
-template<int N>
-EIGEN_DEVICE_FUNC
-inline typename ConstFixedSegmentReturnType<N>::Type head(Index n = N) const
-{
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
-  return typename ConstFixedSegmentReturnType<N>::Type(derived(), 0, n);
-}
-
-/// \returns a fixed-size expression of the last coefficients of *this.
-///
-/// \only_for_vectors
-///
-/// \tparam N the number of coefficients in the segment as specified at compile-time
-/// \param  n the number of coefficients in the segment as specified at run-time
-///
-/// The compile-time and run-time information should not contradict. In other words,
-/// \a n should equal \a N unless \a N is \a Dynamic.
-///
-/// Example: \include MatrixBase_template_int_end.cpp
-/// Output: \verbinclude MatrixBase_template_int_end.out
-///
-/// \sa class Block
-///
-template<int N>
-EIGEN_DEVICE_FUNC
-inline typename FixedSegmentReturnType<N>::Type tail(Index n = N)
-{
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
-  return typename FixedSegmentReturnType<N>::Type(derived(), size() - n);
-}
-
-/// This is the const version of tail<int>.
-template<int N>
-EIGEN_DEVICE_FUNC
-inline typename ConstFixedSegmentReturnType<N>::Type tail(Index n = N) const
-{
-  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
-  return typename ConstFixedSegmentReturnType<N>::Type(derived(), size() - n);
-}
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/plugins/CommonCwiseBinaryOps.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/plugins/CommonCwiseBinaryOps.h
deleted file mode 100644
index 8b6730e..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/plugins/CommonCwiseBinaryOps.h
+++ /dev/null
@@ -1,115 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2016 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-// This file is a base class plugin containing common coefficient wise functions.
-
-/** \returns an expression of the difference of \c *this and \a other
-  *
-  * \note If you want to substract a given scalar from all coefficients, see Cwise::operator-().
-  *
-  * \sa class CwiseBinaryOp, operator-=()
-  */
-EIGEN_MAKE_CWISE_BINARY_OP(operator-,difference)
-
-/** \returns an expression of the sum of \c *this and \a other
-  *
-  * \note If you want to add a given scalar to all coefficients, see Cwise::operator+().
-  *
-  * \sa class CwiseBinaryOp, operator+=()
-  */
-EIGEN_MAKE_CWISE_BINARY_OP(operator+,sum)
-
-/** \returns an expression of a custom coefficient-wise operator \a func of *this and \a other
-  *
-  * The template parameter \a CustomBinaryOp is the type of the functor
-  * of the custom operator (see class CwiseBinaryOp for an example)
-  *
-  * Here is an example illustrating the use of custom functors:
-  * \include class_CwiseBinaryOp.cpp
-  * Output: \verbinclude class_CwiseBinaryOp.out
-  *
-  * \sa class CwiseBinaryOp, operator+(), operator-(), cwiseProduct()
-  */
-template<typename CustomBinaryOp, typename OtherDerived>
-EIGEN_DEVICE_FUNC
-EIGEN_STRONG_INLINE const CwiseBinaryOp<CustomBinaryOp, const Derived, const OtherDerived>
-binaryExpr(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other, const CustomBinaryOp& func = CustomBinaryOp()) const
-{
-  return CwiseBinaryOp<CustomBinaryOp, const Derived, const OtherDerived>(derived(), other.derived(), func);
-}
-
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-EIGEN_MAKE_SCALAR_BINARY_OP(operator*,product)
-#else
-/** \returns an expression of \c *this scaled by the scalar factor \a scalar
-  *
-  * \tparam T is the scalar type of \a scalar. It must be compatible with the scalar type of the given expression.
-  */
-template<typename T>
-const CwiseBinaryOp<internal::scalar_product_op<Scalar,T>,Derived,Constant<T> > operator*(const T& scalar) const;
-/** \returns an expression of \a expr scaled by the scalar factor \a scalar
-  *
-  * \tparam T is the scalar type of \a scalar. It must be compatible with the scalar type of the given expression.
-  */
-template<typename T> friend
-const CwiseBinaryOp<internal::scalar_product_op<T,Scalar>,Constant<T>,Derived> operator*(const T& scalar, const StorageBaseType& expr);
-#endif
-
-
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-EIGEN_MAKE_SCALAR_BINARY_OP_ONTHERIGHT(operator/,quotient)
-#else
-/** \returns an expression of \c *this divided by the scalar value \a scalar
-  *
-  * \tparam T is the scalar type of \a scalar. It must be compatible with the scalar type of the given expression.
-  */
-template<typename T>
-const CwiseBinaryOp<internal::scalar_quotient_op<Scalar,T>,Derived,Constant<T> > operator/(const T& scalar) const;
-#endif
-
-/** \returns an expression of the coefficient-wise boolean \b and operator of \c *this and \a other
-  *
-  * \warning this operator is for expression of bool only.
-  *
-  * Example: \include Cwise_boolean_and.cpp
-  * Output: \verbinclude Cwise_boolean_and.out
-  *
-  * \sa operator||(), select()
-  */
-template<typename OtherDerived>
-EIGEN_DEVICE_FUNC
-inline const CwiseBinaryOp<internal::scalar_boolean_and_op, const Derived, const OtherDerived>
-operator&&(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
-{
-  EIGEN_STATIC_ASSERT((internal::is_same<bool,Scalar>::value && internal::is_same<bool,typename OtherDerived::Scalar>::value),
-                      THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL);
-  return CwiseBinaryOp<internal::scalar_boolean_and_op, const Derived, const OtherDerived>(derived(),other.derived());
-}
-
-/** \returns an expression of the coefficient-wise boolean \b or operator of \c *this and \a other
-  *
-  * \warning this operator is for expression of bool only.
-  *
-  * Example: \include Cwise_boolean_or.cpp
-  * Output: \verbinclude Cwise_boolean_or.out
-  *
-  * \sa operator&&(), select()
-  */
-template<typename OtherDerived>
-EIGEN_DEVICE_FUNC
-inline const CwiseBinaryOp<internal::scalar_boolean_or_op, const Derived, const OtherDerived>
-operator||(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
-{
-  EIGEN_STATIC_ASSERT((internal::is_same<bool,Scalar>::value && internal::is_same<bool,typename OtherDerived::Scalar>::value),
-                      THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL);
-  return CwiseBinaryOp<internal::scalar_boolean_or_op, const Derived, const OtherDerived>(derived(),other.derived());
-}
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/plugins/CommonCwiseUnaryOps.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/plugins/CommonCwiseUnaryOps.h
deleted file mode 100644
index 89f4faa..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/plugins/CommonCwiseUnaryOps.h
+++ /dev/null
@@ -1,163 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-// This file is a base class plugin containing common coefficient wise functions.
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-
-/** \internal the return type of conjugate() */
-typedef typename internal::conditional<NumTraits<Scalar>::IsComplex,
-                    const CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, const Derived>,
-                    const Derived&
-                  >::type ConjugateReturnType;
-/** \internal the return type of real() const */
-typedef typename internal::conditional<NumTraits<Scalar>::IsComplex,
-                    const CwiseUnaryOp<internal::scalar_real_op<Scalar>, const Derived>,
-                    const Derived&
-                  >::type RealReturnType;
-/** \internal the return type of real() */
-typedef typename internal::conditional<NumTraits<Scalar>::IsComplex,
-                    CwiseUnaryView<internal::scalar_real_ref_op<Scalar>, Derived>,
-                    Derived&
-                  >::type NonConstRealReturnType;
-/** \internal the return type of imag() const */
-typedef CwiseUnaryOp<internal::scalar_imag_op<Scalar>, const Derived> ImagReturnType;
-/** \internal the return type of imag() */
-typedef CwiseUnaryView<internal::scalar_imag_ref_op<Scalar>, Derived> NonConstImagReturnType;
-
-typedef CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const Derived> NegativeReturnType;
-
-#endif // not EIGEN_PARSED_BY_DOXYGEN
-
-/// \returns an expression of the opposite of \c *this
-///
-EIGEN_DOC_UNARY_ADDONS(operator-,opposite)
-///
-EIGEN_DEVICE_FUNC
-inline const NegativeReturnType
-operator-() const { return NegativeReturnType(derived()); }
-
-
-template<class NewType> struct CastXpr { typedef typename internal::cast_return_type<Derived,const CwiseUnaryOp<internal::scalar_cast_op<Scalar, NewType>, const Derived> >::type Type; };
-
-/// \returns an expression of \c *this with the \a Scalar type casted to
-/// \a NewScalar.
-///
-/// The template parameter \a NewScalar is the type we are casting the scalars to.
-///
-EIGEN_DOC_UNARY_ADDONS(cast,conversion function)
-///
-/// \sa class CwiseUnaryOp
-///
-template<typename NewType>
-EIGEN_DEVICE_FUNC
-typename CastXpr<NewType>::Type
-cast() const
-{
-  return typename CastXpr<NewType>::Type(derived());
-}
-
-/// \returns an expression of the complex conjugate of \c *this.
-///
-EIGEN_DOC_UNARY_ADDONS(conjugate,complex conjugate)
-///
-/// \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_conj">Math functions</a>, MatrixBase::adjoint()
-EIGEN_DEVICE_FUNC
-inline ConjugateReturnType
-conjugate() const
-{
-  return ConjugateReturnType(derived());
-}
-
-/// \returns a read-only expression of the real part of \c *this.
-///
-EIGEN_DOC_UNARY_ADDONS(real,real part function)
-///
-/// \sa imag()
-EIGEN_DEVICE_FUNC
-inline RealReturnType
-real() const { return RealReturnType(derived()); }
-
-/// \returns an read-only expression of the imaginary part of \c *this.
-///
-EIGEN_DOC_UNARY_ADDONS(imag,imaginary part function)
-///
-/// \sa real()
-EIGEN_DEVICE_FUNC
-inline const ImagReturnType
-imag() const { return ImagReturnType(derived()); }
-
-/// \brief Apply a unary operator coefficient-wise
-/// \param[in]  func  Functor implementing the unary operator
-/// \tparam  CustomUnaryOp Type of \a func
-/// \returns An expression of a custom coefficient-wise unary operator \a func of *this
-///
-/// The function \c ptr_fun() from the C++ standard library can be used to make functors out of normal functions.
-///
-/// Example:
-/// \include class_CwiseUnaryOp_ptrfun.cpp
-/// Output: \verbinclude class_CwiseUnaryOp_ptrfun.out
-///
-/// Genuine functors allow for more possibilities, for instance it may contain a state.
-///
-/// Example:
-/// \include class_CwiseUnaryOp.cpp
-/// Output: \verbinclude class_CwiseUnaryOp.out
-///
-EIGEN_DOC_UNARY_ADDONS(unaryExpr,unary function)
-///
-/// \sa unaryViewExpr, binaryExpr, class CwiseUnaryOp
-///
-template<typename CustomUnaryOp>
-EIGEN_DEVICE_FUNC
-inline const CwiseUnaryOp<CustomUnaryOp, const Derived>
-unaryExpr(const CustomUnaryOp& func = CustomUnaryOp()) const
-{
-  return CwiseUnaryOp<CustomUnaryOp, const Derived>(derived(), func);
-}
-
-/// \returns an expression of a custom coefficient-wise unary operator \a func of *this
-///
-/// The template parameter \a CustomUnaryOp is the type of the functor
-/// of the custom unary operator.
-///
-/// Example:
-/// \include class_CwiseUnaryOp.cpp
-/// Output: \verbinclude class_CwiseUnaryOp.out
-///
-EIGEN_DOC_UNARY_ADDONS(unaryViewExpr,unary function)
-///
-/// \sa unaryExpr, binaryExpr class CwiseUnaryOp
-///
-template<typename CustomViewOp>
-EIGEN_DEVICE_FUNC
-inline const CwiseUnaryView<CustomViewOp, const Derived>
-unaryViewExpr(const CustomViewOp& func = CustomViewOp()) const
-{
-  return CwiseUnaryView<CustomViewOp, const Derived>(derived(), func);
-}
-
-/// \returns a non const expression of the real part of \c *this.
-///
-EIGEN_DOC_UNARY_ADDONS(real,real part function)
-///
-/// \sa imag()
-EIGEN_DEVICE_FUNC
-inline NonConstRealReturnType
-real() { return NonConstRealReturnType(derived()); }
-
-/// \returns a non const expression of the imaginary part of \c *this.
-///
-EIGEN_DOC_UNARY_ADDONS(imag,imaginary part function)
-///
-/// \sa real()
-EIGEN_DEVICE_FUNC
-inline NonConstImagReturnType
-imag() { return NonConstImagReturnType(derived()); }
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/plugins/MatrixCwiseBinaryOps.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/plugins/MatrixCwiseBinaryOps.h
deleted file mode 100644
index f1084ab..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/plugins/MatrixCwiseBinaryOps.h
+++ /dev/null
@@ -1,152 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-// This file is a base class plugin containing matrix specifics coefficient wise functions.
-
-/** \returns an expression of the Schur product (coefficient wise product) of *this and \a other
-  *
-  * Example: \include MatrixBase_cwiseProduct.cpp
-  * Output: \verbinclude MatrixBase_cwiseProduct.out
-  *
-  * \sa class CwiseBinaryOp, cwiseAbs2
-  */
-template<typename OtherDerived>
-EIGEN_DEVICE_FUNC
-EIGEN_STRONG_INLINE const EIGEN_CWISE_BINARY_RETURN_TYPE(Derived,OtherDerived,product)
-cwiseProduct(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
-{
-  return EIGEN_CWISE_BINARY_RETURN_TYPE(Derived,OtherDerived,product)(derived(), other.derived());
-}
-
-/** \returns an expression of the coefficient-wise == operator of *this and \a other
-  *
-  * \warning this performs an exact comparison, which is generally a bad idea with floating-point types.
-  * In order to check for equality between two vectors or matrices with floating-point coefficients, it is
-  * generally a far better idea to use a fuzzy comparison as provided by isApprox() and
-  * isMuchSmallerThan().
-  *
-  * Example: \include MatrixBase_cwiseEqual.cpp
-  * Output: \verbinclude MatrixBase_cwiseEqual.out
-  *
-  * \sa cwiseNotEqual(), isApprox(), isMuchSmallerThan()
-  */
-template<typename OtherDerived>
-EIGEN_DEVICE_FUNC
-inline const CwiseBinaryOp<std::equal_to<Scalar>, const Derived, const OtherDerived>
-cwiseEqual(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
-{
-  return CwiseBinaryOp<std::equal_to<Scalar>, const Derived, const OtherDerived>(derived(), other.derived());
-}
-
-/** \returns an expression of the coefficient-wise != operator of *this and \a other
-  *
-  * \warning this performs an exact comparison, which is generally a bad idea with floating-point types.
-  * In order to check for equality between two vectors or matrices with floating-point coefficients, it is
-  * generally a far better idea to use a fuzzy comparison as provided by isApprox() and
-  * isMuchSmallerThan().
-  *
-  * Example: \include MatrixBase_cwiseNotEqual.cpp
-  * Output: \verbinclude MatrixBase_cwiseNotEqual.out
-  *
-  * \sa cwiseEqual(), isApprox(), isMuchSmallerThan()
-  */
-template<typename OtherDerived>
-EIGEN_DEVICE_FUNC
-inline const CwiseBinaryOp<std::not_equal_to<Scalar>, const Derived, const OtherDerived>
-cwiseNotEqual(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
-{
-  return CwiseBinaryOp<std::not_equal_to<Scalar>, const Derived, const OtherDerived>(derived(), other.derived());
-}
-
-/** \returns an expression of the coefficient-wise min of *this and \a other
-  *
-  * Example: \include MatrixBase_cwiseMin.cpp
-  * Output: \verbinclude MatrixBase_cwiseMin.out
-  *
-  * \sa class CwiseBinaryOp, max()
-  */
-template<typename OtherDerived>
-EIGEN_DEVICE_FUNC
-EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_min_op<Scalar,Scalar>, const Derived, const OtherDerived>
-cwiseMin(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
-{
-  return CwiseBinaryOp<internal::scalar_min_op<Scalar,Scalar>, const Derived, const OtherDerived>(derived(), other.derived());
-}
-
-/** \returns an expression of the coefficient-wise min of *this and scalar \a other
-  *
-  * \sa class CwiseBinaryOp, min()
-  */
-EIGEN_DEVICE_FUNC
-EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_min_op<Scalar,Scalar>, const Derived, const ConstantReturnType>
-cwiseMin(const Scalar &other) const
-{
-  return cwiseMin(Derived::Constant(rows(), cols(), other));
-}
-
-/** \returns an expression of the coefficient-wise max of *this and \a other
-  *
-  * Example: \include MatrixBase_cwiseMax.cpp
-  * Output: \verbinclude MatrixBase_cwiseMax.out
-  *
-  * \sa class CwiseBinaryOp, min()
-  */
-template<typename OtherDerived>
-EIGEN_DEVICE_FUNC
-EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_max_op<Scalar,Scalar>, const Derived, const OtherDerived>
-cwiseMax(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
-{
-  return CwiseBinaryOp<internal::scalar_max_op<Scalar,Scalar>, const Derived, const OtherDerived>(derived(), other.derived());
-}
-
-/** \returns an expression of the coefficient-wise max of *this and scalar \a other
-  *
-  * \sa class CwiseBinaryOp, min()
-  */
-EIGEN_DEVICE_FUNC
-EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_max_op<Scalar,Scalar>, const Derived, const ConstantReturnType>
-cwiseMax(const Scalar &other) const
-{
-  return cwiseMax(Derived::Constant(rows(), cols(), other));
-}
-
-
-/** \returns an expression of the coefficient-wise quotient of *this and \a other
-  *
-  * Example: \include MatrixBase_cwiseQuotient.cpp
-  * Output: \verbinclude MatrixBase_cwiseQuotient.out
-  *
-  * \sa class CwiseBinaryOp, cwiseProduct(), cwiseInverse()
-  */
-template<typename OtherDerived>
-EIGEN_DEVICE_FUNC
-EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_quotient_op<Scalar>, const Derived, const OtherDerived>
-cwiseQuotient(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
-{
-  return CwiseBinaryOp<internal::scalar_quotient_op<Scalar>, const Derived, const OtherDerived>(derived(), other.derived());
-}
-
-typedef CwiseBinaryOp<internal::scalar_cmp_op<Scalar,Scalar,internal::cmp_EQ>, const Derived, const ConstantReturnType> CwiseScalarEqualReturnType;
-
-/** \returns an expression of the coefficient-wise == operator of \c *this and a scalar \a s
-  *
-  * \warning this performs an exact comparison, which is generally a bad idea with floating-point types.
-  * In order to check for equality between two vectors or matrices with floating-point coefficients, it is
-  * generally a far better idea to use a fuzzy comparison as provided by isApprox() and
-  * isMuchSmallerThan().
-  *
-  * \sa cwiseEqual(const MatrixBase<OtherDerived> &) const
-  */
-EIGEN_DEVICE_FUNC
-inline const CwiseScalarEqualReturnType
-cwiseEqual(const Scalar& s) const
-{
-  return CwiseScalarEqualReturnType(derived(), Derived::Constant(rows(), cols(), s), internal::scalar_cmp_op<Scalar,Scalar,internal::cmp_EQ>());
-}
diff --git a/wpiutil/src/main/native/eigeninclude/Eigen/src/plugins/MatrixCwiseUnaryOps.h b/wpiutil/src/main/native/eigeninclude/Eigen/src/plugins/MatrixCwiseUnaryOps.h
deleted file mode 100644
index b1be3d5..0000000
--- a/wpiutil/src/main/native/eigeninclude/Eigen/src/plugins/MatrixCwiseUnaryOps.h
+++ /dev/null
@@ -1,85 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
-// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-// This file is included into the body of the base classes supporting matrix specific coefficient-wise functions.
-// This include MatrixBase and SparseMatrixBase.
-
-
-typedef CwiseUnaryOp<internal::scalar_abs_op<Scalar>, const Derived> CwiseAbsReturnType;
-typedef CwiseUnaryOp<internal::scalar_abs2_op<Scalar>, const Derived> CwiseAbs2ReturnType;
-typedef CwiseUnaryOp<internal::scalar_sqrt_op<Scalar>, const Derived> CwiseSqrtReturnType;
-typedef CwiseUnaryOp<internal::scalar_sign_op<Scalar>, const Derived> CwiseSignReturnType;
-typedef CwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const Derived> CwiseInverseReturnType;
-
-/// \returns an expression of the coefficient-wise absolute value of \c *this
-///
-/// Example: \include MatrixBase_cwiseAbs.cpp
-/// Output: \verbinclude MatrixBase_cwiseAbs.out
-///
-EIGEN_DOC_UNARY_ADDONS(cwiseAbs,absolute value)
-///
-/// \sa cwiseAbs2()
-///
-EIGEN_DEVICE_FUNC
-EIGEN_STRONG_INLINE const CwiseAbsReturnType
-cwiseAbs() const { return CwiseAbsReturnType(derived()); }
-
-/// \returns an expression of the coefficient-wise squared absolute value of \c *this
-///
-/// Example: \include MatrixBase_cwiseAbs2.cpp
-/// Output: \verbinclude MatrixBase_cwiseAbs2.out
-///
-EIGEN_DOC_UNARY_ADDONS(cwiseAbs2,squared absolute value)
-///
-/// \sa cwiseAbs()
-///
-EIGEN_DEVICE_FUNC
-EIGEN_STRONG_INLINE const CwiseAbs2ReturnType
-cwiseAbs2() const { return CwiseAbs2ReturnType(derived()); }
-
-/// \returns an expression of the coefficient-wise square root of *this.
-///
-/// Example: \include MatrixBase_cwiseSqrt.cpp
-/// Output: \verbinclude MatrixBase_cwiseSqrt.out
-///
-EIGEN_DOC_UNARY_ADDONS(cwiseSqrt,square-root)
-///
-/// \sa cwisePow(), cwiseSquare()
-///
-EIGEN_DEVICE_FUNC
-inline const CwiseSqrtReturnType
-cwiseSqrt() const { return CwiseSqrtReturnType(derived()); }
-
-/// \returns an expression of the coefficient-wise signum of *this.
-///
-/// Example: \include MatrixBase_cwiseSign.cpp
-/// Output: \verbinclude MatrixBase_cwiseSign.out
-///
-EIGEN_DOC_UNARY_ADDONS(cwiseSign,sign function)
-///
-EIGEN_DEVICE_FUNC
-inline const CwiseSignReturnType
-cwiseSign() const { return CwiseSignReturnType(derived()); }
-
-
-/// \returns an expression of the coefficient-wise inverse of *this.
-///
-/// Example: \include MatrixBase_cwiseInverse.cpp
-/// Output: \verbinclude MatrixBase_cwiseInverse.out
-///
-EIGEN_DOC_UNARY_ADDONS(cwiseInverse,inverse)
-///
-/// \sa cwiseProduct()
-///
-EIGEN_DEVICE_FUNC
-inline const CwiseInverseReturnType
-cwiseInverse() const { return CwiseInverseReturnType(derived()); }
-
-
diff --git a/wpiutil/src/main/native/eigeninclude/unsupported/Eigen/MatrixFunctions b/wpiutil/src/main/native/eigeninclude/unsupported/Eigen/MatrixFunctions
deleted file mode 100644
index 60dc0a6..0000000
--- a/wpiutil/src/main/native/eigeninclude/unsupported/Eigen/MatrixFunctions
+++ /dev/null
@@ -1,500 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009 Jitse Niesen <jitse@maths.leeds.ac.uk>
-// Copyright (C) 2012 Chen-Pang He <jdh8@ms63.hinet.net>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_MATRIX_FUNCTIONS
-#define EIGEN_MATRIX_FUNCTIONS
-
-#include <cfloat>
-#include <list>
-
-#include <Eigen/Core>
-#include <Eigen/LU>
-#include <Eigen/Eigenvalues>
-
-/**
-  * \defgroup MatrixFunctions_Module Matrix functions module
-  * \brief This module aims to provide various methods for the computation of
-  * matrix functions. 
-  *
-  * To use this module, add 
-  * \code
-  * #include <unsupported/Eigen/MatrixFunctions>
-  * \endcode
-  * at the start of your source file.
-  *
-  * This module defines the following MatrixBase methods.
-  *  - \ref matrixbase_cos "MatrixBase::cos()", for computing the matrix cosine
-  *  - \ref matrixbase_cosh "MatrixBase::cosh()", for computing the matrix hyperbolic cosine
-  *  - \ref matrixbase_exp "MatrixBase::exp()", for computing the matrix exponential
-  *  - \ref matrixbase_log "MatrixBase::log()", for computing the matrix logarithm
-  *  - \ref matrixbase_pow "MatrixBase::pow()", for computing the matrix power
-  *  - \ref matrixbase_matrixfunction "MatrixBase::matrixFunction()", for computing general matrix functions
-  *  - \ref matrixbase_sin "MatrixBase::sin()", for computing the matrix sine
-  *  - \ref matrixbase_sinh "MatrixBase::sinh()", for computing the matrix hyperbolic sine
-  *  - \ref matrixbase_sqrt "MatrixBase::sqrt()", for computing the matrix square root
-  *
-  * These methods are the main entry points to this module. 
-  *
-  * %Matrix functions are defined as follows.  Suppose that \f$ f \f$
-  * is an entire function (that is, a function on the complex plane
-  * that is everywhere complex differentiable).  Then its Taylor
-  * series
-  * \f[ f(0) + f'(0) x + \frac{f''(0)}{2} x^2 + \frac{f'''(0)}{3!} x^3 + \cdots \f]
-  * converges to \f$ f(x) \f$. In this case, we can define the matrix
-  * function by the same series:
-  * \f[ f(M) = f(0) + f'(0) M + \frac{f''(0)}{2} M^2 + \frac{f'''(0)}{3!} M^3 + \cdots \f]
-  *
-  */
-
-#include "src/MatrixFunctions/MatrixExponential.h"
-#include "src/MatrixFunctions/MatrixFunction.h"
-#include "src/MatrixFunctions/MatrixSquareRoot.h"
-#include "src/MatrixFunctions/MatrixLogarithm.h"
-#include "src/MatrixFunctions/MatrixPower.h"
-
-
-/** 
-\page matrixbaseextra_page
-\ingroup MatrixFunctions_Module
-
-\section matrixbaseextra MatrixBase methods defined in the MatrixFunctions module
-
-The remainder of the page documents the following MatrixBase methods
-which are defined in the MatrixFunctions module.
-
-
-
-\subsection matrixbase_cos MatrixBase::cos()
-
-Compute the matrix cosine.
-
-\code
-const MatrixFunctionReturnValue<Derived> MatrixBase<Derived>::cos() const
-\endcode
-
-\param[in]  M  a square matrix.
-\returns  expression representing \f$ \cos(M) \f$.
-
-This function computes the matrix cosine. Use ArrayBase::cos() for computing the entry-wise cosine.
-
-The implementation calls \ref matrixbase_matrixfunction "matrixFunction()" with StdStemFunctions::cos().
-
-\sa \ref matrixbase_sin "sin()" for an example.
-
-
-
-\subsection matrixbase_cosh MatrixBase::cosh()
-
-Compute the matrix hyberbolic cosine.
-
-\code
-const MatrixFunctionReturnValue<Derived> MatrixBase<Derived>::cosh() const
-\endcode
-
-\param[in]  M  a square matrix.
-\returns  expression representing \f$ \cosh(M) \f$
-
-This function calls \ref matrixbase_matrixfunction "matrixFunction()" with StdStemFunctions::cosh().
-
-\sa \ref matrixbase_sinh "sinh()" for an example.
-
-
-
-\subsection matrixbase_exp MatrixBase::exp()
-
-Compute the matrix exponential.
-
-\code
-const MatrixExponentialReturnValue<Derived> MatrixBase<Derived>::exp() const
-\endcode
-
-\param[in]  M  matrix whose exponential is to be computed.
-\returns    expression representing the matrix exponential of \p M.
-
-The matrix exponential of \f$ M \f$ is defined by
-\f[ \exp(M) = \sum_{k=0}^\infty \frac{M^k}{k!}. \f]
-The matrix exponential can be used to solve linear ordinary
-differential equations: the solution of \f$ y' = My \f$ with the
-initial condition \f$ y(0) = y_0 \f$ is given by
-\f$ y(t) = \exp(M) y_0 \f$.
-
-The matrix exponential is different from applying the exp function to all the entries in the matrix.
-Use ArrayBase::exp() if you want to do the latter.
-
-The cost of the computation is approximately \f$ 20 n^3 \f$ for
-matrices of size \f$ n \f$. The number 20 depends weakly on the
-norm of the matrix.
-
-The matrix exponential is computed using the scaling-and-squaring
-method combined with Pad&eacute; approximation. The matrix is first
-rescaled, then the exponential of the reduced matrix is computed
-approximant, and then the rescaling is undone by repeated
-squaring. The degree of the Pad&eacute; approximant is chosen such
-that the approximation error is less than the round-off
-error. However, errors may accumulate during the squaring phase.
-
-Details of the algorithm can be found in: Nicholas J. Higham, "The
-scaling and squaring method for the matrix exponential revisited,"
-<em>SIAM J. %Matrix Anal. Applic.</em>, <b>26</b>:1179&ndash;1193,
-2005.
-
-Example: The following program checks that
-\f[ \exp \left[ \begin{array}{ccc}
-      0 & \frac14\pi & 0 \\
-      -\frac14\pi & 0 & 0 \\
-      0 & 0 & 0
-    \end{array} \right] = \left[ \begin{array}{ccc}
-      \frac12\sqrt2 & -\frac12\sqrt2 & 0 \\
-      \frac12\sqrt2 & \frac12\sqrt2 & 0 \\
-      0 & 0 & 1
-    \end{array} \right]. \f]
-This corresponds to a rotation of \f$ \frac14\pi \f$ radians around
-the z-axis.
-
-\include MatrixExponential.cpp
-Output: \verbinclude MatrixExponential.out
-
-\note \p M has to be a matrix of \c float, \c double, `long double`
-\c complex<float>, \c complex<double>, or `complex<long double>` .
-
-
-\subsection matrixbase_log MatrixBase::log()
-
-Compute the matrix logarithm.
-
-\code
-const MatrixLogarithmReturnValue<Derived> MatrixBase<Derived>::log() const
-\endcode
-
-\param[in]  M  invertible matrix whose logarithm is to be computed.
-\returns    expression representing the matrix logarithm root of \p M.
-
-The matrix logarithm of \f$ M \f$ is a matrix \f$ X \f$ such that 
-\f$ \exp(X) = M \f$ where exp denotes the matrix exponential. As for
-the scalar logarithm, the equation \f$ \exp(X) = M \f$ may have
-multiple solutions; this function returns a matrix whose eigenvalues
-have imaginary part in the interval \f$ (-\pi,\pi] \f$.
-
-The matrix logarithm is different from applying the log function to all the entries in the matrix.
-Use ArrayBase::log() if you want to do the latter.
-
-In the real case, the matrix \f$ M \f$ should be invertible and
-it should have no eigenvalues which are real and negative (pairs of
-complex conjugate eigenvalues are allowed). In the complex case, it
-only needs to be invertible.
-
-This function computes the matrix logarithm using the Schur-Parlett
-algorithm as implemented by MatrixBase::matrixFunction(). The
-logarithm of an atomic block is computed by MatrixLogarithmAtomic,
-which uses direct computation for 1-by-1 and 2-by-2 blocks and an
-inverse scaling-and-squaring algorithm for bigger blocks, with the
-square roots computed by MatrixBase::sqrt().
-
-Details of the algorithm can be found in Section 11.6.2 of:
-Nicholas J. Higham,
-<em>Functions of Matrices: Theory and Computation</em>,
-SIAM 2008. ISBN 978-0-898716-46-7.
-
-Example: The following program checks that
-\f[ \log \left[ \begin{array}{ccc} 
-      \frac12\sqrt2 & -\frac12\sqrt2 & 0 \\
-      \frac12\sqrt2 & \frac12\sqrt2 & 0 \\
-      0 & 0 & 1
-    \end{array} \right] = \left[ \begin{array}{ccc}
-      0 & \frac14\pi & 0 \\ 
-      -\frac14\pi & 0 & 0 \\
-      0 & 0 & 0 
-    \end{array} \right]. \f]
-This corresponds to a rotation of \f$ \frac14\pi \f$ radians around
-the z-axis. This is the inverse of the example used in the
-documentation of \ref matrixbase_exp "exp()".
-
-\include MatrixLogarithm.cpp
-Output: \verbinclude MatrixLogarithm.out
-
-\note \p M has to be a matrix of \c float, \c double, `long
-double`, \c complex<float>, \c complex<double>, or `complex<long double>`.
-
-\sa MatrixBase::exp(), MatrixBase::matrixFunction(), 
-    class MatrixLogarithmAtomic, MatrixBase::sqrt().
-
-
-\subsection matrixbase_pow MatrixBase::pow()
-
-Compute the matrix raised to arbitrary real power.
-
-\code
-const MatrixPowerReturnValue<Derived> MatrixBase<Derived>::pow(RealScalar p) const
-\endcode
-
-\param[in]  M  base of the matrix power, should be a square matrix.
-\param[in]  p  exponent of the matrix power.
-
-The matrix power \f$ M^p \f$ is defined as \f$ \exp(p \log(M)) \f$,
-where exp denotes the matrix exponential, and log denotes the matrix
-logarithm. This is different from raising all the entries in the matrix
-to the p-th power. Use ArrayBase::pow() if you want to do the latter.
-
-If \p p is complex, the scalar type of \p M should be the type of \p
-p . \f$ M^p \f$ simply evaluates into \f$ \exp(p \log(M)) \f$.
-Therefore, the matrix \f$ M \f$ should meet the conditions to be an
-argument of matrix logarithm.
-
-If \p p is real, it is casted into the real scalar type of \p M. Then
-this function computes the matrix power using the Schur-Pad&eacute;
-algorithm as implemented by class MatrixPower. The exponent is split
-into integral part and fractional part, where the fractional part is
-in the interval \f$ (-1, 1) \f$. The main diagonal and the first
-super-diagonal is directly computed.
-
-If \p M is singular with a semisimple zero eigenvalue and \p p is
-positive, the Schur factor \f$ T \f$ is reordered with Givens
-rotations, i.e.
-
-\f[ T = \left[ \begin{array}{cc}
-      T_1 & T_2 \\
-      0   & 0
-    \end{array} \right] \f]
-
-where \f$ T_1 \f$ is invertible. Then \f$ T^p \f$ is given by
-
-\f[ T^p = \left[ \begin{array}{cc}
-      T_1^p & T_1^{-1} T_1^p T_2 \\
-      0     & 0
-    \end{array}. \right] \f]
-
-\warning Fractional power of a matrix with a non-semisimple zero
-eigenvalue is not well-defined. We introduce an assertion failure
-against inaccurate result, e.g. \code
-#include <unsupported/Eigen/MatrixFunctions>
-#include <iostream>
-
-int main()
-{
-  Eigen::Matrix4d A;
-  A << 0, 0, 2, 3,
-       0, 0, 4, 5,
-       0, 0, 6, 7,
-       0, 0, 8, 9;
-  std::cout << A.pow(0.37) << std::endl;
-  
-  // The 1 makes eigenvalue 0 non-semisimple.
-  A.coeffRef(0, 1) = 1;
-
-  // This fails if EIGEN_NO_DEBUG is undefined.
-  std::cout << A.pow(0.37) << std::endl;
-
-  return 0;
-}
-\endcode
-
-Details of the algorithm can be found in: Nicholas J. Higham and
-Lijing Lin, "A Schur-Pad&eacute; algorithm for fractional powers of a
-matrix," <em>SIAM J. %Matrix Anal. Applic.</em>,
-<b>32(3)</b>:1056&ndash;1078, 2011.
-
-Example: The following program checks that
-\f[ \left[ \begin{array}{ccc}
-      \cos1 & -\sin1 & 0 \\
-      \sin1 & \cos1 & 0 \\
-      0 & 0 & 1
-    \end{array} \right]^{\frac14\pi} = \left[ \begin{array}{ccc}
-      \frac12\sqrt2 & -\frac12\sqrt2 & 0 \\
-      \frac12\sqrt2 & \frac12\sqrt2 & 0 \\
-      0 & 0 & 1
-    \end{array} \right]. \f]
-This corresponds to \f$ \frac14\pi \f$ rotations of 1 radian around
-the z-axis.
-
-\include MatrixPower.cpp
-Output: \verbinclude MatrixPower.out
-
-MatrixBase::pow() is user-friendly. However, there are some
-circumstances under which you should use class MatrixPower directly.
-MatrixPower can save the result of Schur decomposition, so it's
-better for computing various powers for the same matrix.
-
-Example:
-\include MatrixPower_optimal.cpp
-Output: \verbinclude MatrixPower_optimal.out
-
-\note \p M has to be a matrix of \c float, \c double, `long
-double`, \c complex<float>, \c complex<double>, or
-\c complex<long double> .
-
-\sa MatrixBase::exp(), MatrixBase::log(), class MatrixPower.
-
-
-\subsection matrixbase_matrixfunction MatrixBase::matrixFunction()
-
-Compute a matrix function.
-
-\code
-const MatrixFunctionReturnValue<Derived> MatrixBase<Derived>::matrixFunction(typename internal::stem_function<typename internal::traits<Derived>::Scalar>::type f) const
-\endcode
-
-\param[in]  M  argument of matrix function, should be a square matrix.
-\param[in]  f  an entire function; \c f(x,n) should compute the n-th
-derivative of f at x.
-\returns  expression representing \p f applied to \p M.
-
-Suppose that \p M is a matrix whose entries have type \c Scalar. 
-Then, the second argument, \p f, should be a function with prototype
-\code 
-ComplexScalar f(ComplexScalar, int) 
-\endcode
-where \c ComplexScalar = \c std::complex<Scalar> if \c Scalar is
-real (e.g., \c float or \c double) and \c ComplexScalar =
-\c Scalar if \c Scalar is complex. The return value of \c f(x,n)
-should be \f$ f^{(n)}(x) \f$, the n-th derivative of f at x.
-
-This routine uses the algorithm described in:
-Philip Davies and Nicholas J. Higham, 
-"A Schur-Parlett algorithm for computing matrix functions", 
-<em>SIAM J. %Matrix Anal. Applic.</em>, <b>25</b>:464&ndash;485, 2003.
-
-The actual work is done by the MatrixFunction class.
-
-Example: The following program checks that
-\f[ \exp \left[ \begin{array}{ccc} 
-      0 & \frac14\pi & 0 \\ 
-      -\frac14\pi & 0 & 0 \\
-      0 & 0 & 0 
-    \end{array} \right] = \left[ \begin{array}{ccc}
-      \frac12\sqrt2 & -\frac12\sqrt2 & 0 \\
-      \frac12\sqrt2 & \frac12\sqrt2 & 0 \\
-      0 & 0 & 1
-    \end{array} \right]. \f]
-This corresponds to a rotation of \f$ \frac14\pi \f$ radians around
-the z-axis. This is the same example as used in the documentation
-of \ref matrixbase_exp "exp()".
-
-\include MatrixFunction.cpp
-Output: \verbinclude MatrixFunction.out
-
-Note that the function \c expfn is defined for complex numbers 
-\c x, even though the matrix \c A is over the reals. Instead of
-\c expfn, we could also have used StdStemFunctions::exp:
-\code
-A.matrixFunction(StdStemFunctions<std::complex<double> >::exp, &B);
-\endcode
-
-
-
-\subsection matrixbase_sin MatrixBase::sin()
-
-Compute the matrix sine.
-
-\code
-const MatrixFunctionReturnValue<Derived> MatrixBase<Derived>::sin() const
-\endcode
-
-\param[in]  M  a square matrix.
-\returns  expression representing \f$ \sin(M) \f$.
-
-This function computes the matrix sine. Use ArrayBase::sin() for computing the entry-wise sine.
-
-The implementation calls \ref matrixbase_matrixfunction "matrixFunction()" with StdStemFunctions::sin().
-
-Example: \include MatrixSine.cpp
-Output: \verbinclude MatrixSine.out
-
-
-
-\subsection matrixbase_sinh MatrixBase::sinh()
-
-Compute the matrix hyperbolic sine.
-
-\code
-MatrixFunctionReturnValue<Derived> MatrixBase<Derived>::sinh() const
-\endcode
-
-\param[in]  M  a square matrix.
-\returns  expression representing \f$ \sinh(M) \f$
-
-This function calls \ref matrixbase_matrixfunction "matrixFunction()" with StdStemFunctions::sinh().
-
-Example: \include MatrixSinh.cpp
-Output: \verbinclude MatrixSinh.out
-
-
-\subsection matrixbase_sqrt MatrixBase::sqrt()
-
-Compute the matrix square root.
-
-\code
-const MatrixSquareRootReturnValue<Derived> MatrixBase<Derived>::sqrt() const
-\endcode
-
-\param[in]  M  invertible matrix whose square root is to be computed.
-\returns    expression representing the matrix square root of \p M.
-
-The matrix square root of \f$ M \f$ is the matrix \f$ M^{1/2} \f$
-whose square is the original matrix; so if \f$ S = M^{1/2} \f$ then
-\f$ S^2 = M \f$. This is different from taking the square root of all
-the entries in the matrix; use ArrayBase::sqrt() if you want to do the
-latter.
-
-In the <b>real case</b>, the matrix \f$ M \f$ should be invertible and
-it should have no eigenvalues which are real and negative (pairs of
-complex conjugate eigenvalues are allowed). In that case, the matrix
-has a square root which is also real, and this is the square root
-computed by this function. 
-
-The matrix square root is computed by first reducing the matrix to
-quasi-triangular form with the real Schur decomposition. The square
-root of the quasi-triangular matrix can then be computed directly. The
-cost is approximately \f$ 25 n^3 \f$ real flops for the real Schur
-decomposition and \f$ 3\frac13 n^3 \f$ real flops for the remainder
-(though the computation time in practice is likely more than this
-indicates).
-
-Details of the algorithm can be found in: Nicholas J. Highan,
-"Computing real square roots of a real matrix", <em>Linear Algebra
-Appl.</em>, 88/89:405&ndash;430, 1987.
-
-If the matrix is <b>positive-definite symmetric</b>, then the square
-root is also positive-definite symmetric. In this case, it is best to
-use SelfAdjointEigenSolver::operatorSqrt() to compute it.
-
-In the <b>complex case</b>, the matrix \f$ M \f$ should be invertible;
-this is a restriction of the algorithm. The square root computed by
-this algorithm is the one whose eigenvalues have an argument in the
-interval \f$ (-\frac12\pi, \frac12\pi] \f$. This is the usual branch
-cut.
-
-The computation is the same as in the real case, except that the
-complex Schur decomposition is used to reduce the matrix to a
-triangular matrix. The theoretical cost is the same. Details are in:
-&Aring;ke Bj&ouml;rck and Sven Hammarling, "A Schur method for the
-square root of a matrix", <em>Linear Algebra Appl.</em>,
-52/53:127&ndash;140, 1983.
-
-Example: The following program checks that the square root of
-\f[ \left[ \begin{array}{cc} 
-              \cos(\frac13\pi) & -\sin(\frac13\pi) \\
-              \sin(\frac13\pi) & \cos(\frac13\pi)
-    \end{array} \right], \f]
-corresponding to a rotation over 60 degrees, is a rotation over 30 degrees:
-\f[ \left[ \begin{array}{cc} 
-              \cos(\frac16\pi) & -\sin(\frac16\pi) \\
-              \sin(\frac16\pi) & \cos(\frac16\pi)
-    \end{array} \right]. \f]
-
-\include MatrixSquareRoot.cpp
-Output: \verbinclude MatrixSquareRoot.out
-
-\sa class RealSchur, class ComplexSchur, class MatrixSquareRoot,
-    SelfAdjointEigenSolver::operatorSqrt().
-
-*/
-
-#endif // EIGEN_MATRIX_FUNCTIONS
-
diff --git a/wpiutil/src/main/native/eigeninclude/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h b/wpiutil/src/main/native/eigeninclude/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h
deleted file mode 100644
index e5ebbcf..0000000
--- a/wpiutil/src/main/native/eigeninclude/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h
+++ /dev/null
@@ -1,442 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009, 2010, 2013 Jitse Niesen <jitse@maths.leeds.ac.uk>
-// Copyright (C) 2011, 2013 Chen-Pang He <jdh8@ms63.hinet.net>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_MATRIX_EXPONENTIAL
-#define EIGEN_MATRIX_EXPONENTIAL
-
-#include "StemFunction.h"
-
-namespace Eigen {
-namespace internal {
-
-/** \brief Scaling operator.
- *
- * This struct is used by CwiseUnaryOp to scale a matrix by \f$ 2^{-s} \f$.
- */
-template <typename RealScalar>
-struct MatrixExponentialScalingOp
-{
-  /** \brief Constructor.
-   *
-   * \param[in] squarings  The integer \f$ s \f$ in this document.
-   */
-  MatrixExponentialScalingOp(int squarings) : m_squarings(squarings) { }
-
-
-  /** \brief Scale a matrix coefficient.
-   *
-   * \param[in,out] x  The scalar to be scaled, becoming \f$ 2^{-s} x \f$.
-   */
-  inline const RealScalar operator() (const RealScalar& x) const
-  {
-    using std::ldexp;
-    return ldexp(x, -m_squarings);
-  }
-
-  typedef std::complex<RealScalar> ComplexScalar;
-
-  /** \brief Scale a matrix coefficient.
-   *
-   * \param[in,out] x  The scalar to be scaled, becoming \f$ 2^{-s} x \f$.
-   */
-  inline const ComplexScalar operator() (const ComplexScalar& x) const
-  {
-    using std::ldexp;
-    return ComplexScalar(ldexp(x.real(), -m_squarings), ldexp(x.imag(), -m_squarings));
-  }
-
-  private:
-    int m_squarings;
-};
-
-/** \brief Compute the (3,3)-Pad&eacute; approximant to the exponential.
- *
- *  After exit, \f$ (V+U)(V-U)^{-1} \f$ is the Pad&eacute;
- *  approximant of \f$ \exp(A) \f$ around \f$ A = 0 \f$.
- */
-template <typename MatA, typename MatU, typename MatV>
-void matrix_exp_pade3(const MatA& A, MatU& U, MatV& V)
-{
-  typedef typename MatA::PlainObject MatrixType;
-  typedef typename NumTraits<typename traits<MatA>::Scalar>::Real RealScalar;
-  const RealScalar b[] = {120.L, 60.L, 12.L, 1.L};
-  const MatrixType A2 = A * A;
-  const MatrixType tmp = b[3] * A2 + b[1] * MatrixType::Identity(A.rows(), A.cols());
-  U.noalias() = A * tmp;
-  V = b[2] * A2 + b[0] * MatrixType::Identity(A.rows(), A.cols());
-}
-
-/** \brief Compute the (5,5)-Pad&eacute; approximant to the exponential.
- *
- *  After exit, \f$ (V+U)(V-U)^{-1} \f$ is the Pad&eacute;
- *  approximant of \f$ \exp(A) \f$ around \f$ A = 0 \f$.
- */
-template <typename MatA, typename MatU, typename MatV>
-void matrix_exp_pade5(const MatA& A, MatU& U, MatV& V)
-{
-  typedef typename MatA::PlainObject MatrixType;
-  typedef typename NumTraits<typename traits<MatrixType>::Scalar>::Real RealScalar;
-  const RealScalar b[] = {30240.L, 15120.L, 3360.L, 420.L, 30.L, 1.L};
-  const MatrixType A2 = A * A;
-  const MatrixType A4 = A2 * A2;
-  const MatrixType tmp = b[5] * A4 + b[3] * A2 + b[1] * MatrixType::Identity(A.rows(), A.cols());
-  U.noalias() = A * tmp;
-  V = b[4] * A4 + b[2] * A2 + b[0] * MatrixType::Identity(A.rows(), A.cols());
-}
-
-/** \brief Compute the (7,7)-Pad&eacute; approximant to the exponential.
- *
- *  After exit, \f$ (V+U)(V-U)^{-1} \f$ is the Pad&eacute;
- *  approximant of \f$ \exp(A) \f$ around \f$ A = 0 \f$.
- */
-template <typename MatA, typename MatU, typename MatV>
-void matrix_exp_pade7(const MatA& A, MatU& U, MatV& V)
-{
-  typedef typename MatA::PlainObject MatrixType;
-  typedef typename NumTraits<typename traits<MatrixType>::Scalar>::Real RealScalar;
-  const RealScalar b[] = {17297280.L, 8648640.L, 1995840.L, 277200.L, 25200.L, 1512.L, 56.L, 1.L};
-  const MatrixType A2 = A * A;
-  const MatrixType A4 = A2 * A2;
-  const MatrixType A6 = A4 * A2;
-  const MatrixType tmp = b[7] * A6 + b[5] * A4 + b[3] * A2 
-    + b[1] * MatrixType::Identity(A.rows(), A.cols());
-  U.noalias() = A * tmp;
-  V = b[6] * A6 + b[4] * A4 + b[2] * A2 + b[0] * MatrixType::Identity(A.rows(), A.cols());
-
-}
-
-/** \brief Compute the (9,9)-Pad&eacute; approximant to the exponential.
- *
- *  After exit, \f$ (V+U)(V-U)^{-1} \f$ is the Pad&eacute;
- *  approximant of \f$ \exp(A) \f$ around \f$ A = 0 \f$.
- */
-template <typename MatA, typename MatU, typename MatV>
-void matrix_exp_pade9(const MatA& A, MatU& U, MatV& V)
-{
-  typedef typename MatA::PlainObject MatrixType;
-  typedef typename NumTraits<typename traits<MatrixType>::Scalar>::Real RealScalar;
-  const RealScalar b[] = {17643225600.L, 8821612800.L, 2075673600.L, 302702400.L, 30270240.L,
-                          2162160.L, 110880.L, 3960.L, 90.L, 1.L};
-  const MatrixType A2 = A * A;
-  const MatrixType A4 = A2 * A2;
-  const MatrixType A6 = A4 * A2;
-  const MatrixType A8 = A6 * A2;
-  const MatrixType tmp = b[9] * A8 + b[7] * A6 + b[5] * A4 + b[3] * A2 
-    + b[1] * MatrixType::Identity(A.rows(), A.cols());
-  U.noalias() = A * tmp;
-  V = b[8] * A8 + b[6] * A6 + b[4] * A4 + b[2] * A2 + b[0] * MatrixType::Identity(A.rows(), A.cols());
-}
-
-/** \brief Compute the (13,13)-Pad&eacute; approximant to the exponential.
- *
- *  After exit, \f$ (V+U)(V-U)^{-1} \f$ is the Pad&eacute;
- *  approximant of \f$ \exp(A) \f$ around \f$ A = 0 \f$.
- */
-template <typename MatA, typename MatU, typename MatV>
-void matrix_exp_pade13(const MatA& A, MatU& U, MatV& V)
-{
-  typedef typename MatA::PlainObject MatrixType;
-  typedef typename NumTraits<typename traits<MatrixType>::Scalar>::Real RealScalar;
-  const RealScalar b[] = {64764752532480000.L, 32382376266240000.L, 7771770303897600.L,
-                          1187353796428800.L, 129060195264000.L, 10559470521600.L, 670442572800.L,
-                          33522128640.L, 1323241920.L, 40840800.L, 960960.L, 16380.L, 182.L, 1.L};
-  const MatrixType A2 = A * A;
-  const MatrixType A4 = A2 * A2;
-  const MatrixType A6 = A4 * A2;
-  V = b[13] * A6 + b[11] * A4 + b[9] * A2; // used for temporary storage
-  MatrixType tmp = A6 * V;
-  tmp += b[7] * A6 + b[5] * A4 + b[3] * A2 + b[1] * MatrixType::Identity(A.rows(), A.cols());
-  U.noalias() = A * tmp;
-  tmp = b[12] * A6 + b[10] * A4 + b[8] * A2;
-  V.noalias() = A6 * tmp;
-  V += b[6] * A6 + b[4] * A4 + b[2] * A2 + b[0] * MatrixType::Identity(A.rows(), A.cols());
-}
-
-/** \brief Compute the (17,17)-Pad&eacute; approximant to the exponential.
- *
- *  After exit, \f$ (V+U)(V-U)^{-1} \f$ is the Pad&eacute;
- *  approximant of \f$ \exp(A) \f$ around \f$ A = 0 \f$.
- *
- *  This function activates only if your long double is double-double or quadruple.
- */
-#if LDBL_MANT_DIG > 64
-template <typename MatA, typename MatU, typename MatV>
-void matrix_exp_pade17(const MatA& A, MatU& U, MatV& V)
-{
-  typedef typename MatA::PlainObject MatrixType;
-  typedef typename NumTraits<typename traits<MatrixType>::Scalar>::Real RealScalar;
-  const RealScalar b[] = {830034394580628357120000.L, 415017197290314178560000.L,
-                          100610229646136770560000.L, 15720348382208870400000.L,
-                          1774878043152614400000.L, 153822763739893248000.L, 10608466464820224000.L,
-                          595373117923584000.L, 27563570274240000.L, 1060137318240000.L,
-                          33924394183680.L, 899510451840.L, 19554575040.L, 341863200.L, 4651200.L,
-                          46512.L, 306.L, 1.L};
-  const MatrixType A2 = A * A;
-  const MatrixType A4 = A2 * A2;
-  const MatrixType A6 = A4 * A2;
-  const MatrixType A8 = A4 * A4;
-  V = b[17] * A8 + b[15] * A6 + b[13] * A4 + b[11] * A2; // used for temporary storage
-  MatrixType tmp = A8 * V;
-  tmp += b[9] * A8 + b[7] * A6 + b[5] * A4 + b[3] * A2 
-    + b[1] * MatrixType::Identity(A.rows(), A.cols());
-  U.noalias() = A * tmp;
-  tmp = b[16] * A8 + b[14] * A6 + b[12] * A4 + b[10] * A2;
-  V.noalias() = tmp * A8;
-  V += b[8] * A8 + b[6] * A6 + b[4] * A4 + b[2] * A2 
-    + b[0] * MatrixType::Identity(A.rows(), A.cols());
-}
-#endif
-
-template <typename MatrixType, typename RealScalar = typename NumTraits<typename traits<MatrixType>::Scalar>::Real>
-struct matrix_exp_computeUV
-{
-  /** \brief Compute Pad&eacute; approximant to the exponential.
-    *
-    * Computes \c U, \c V and \c squarings such that \f$ (V+U)(V-U)^{-1} \f$ is a Pad&eacute;
-    * approximant of \f$ \exp(2^{-\mbox{squarings}}M) \f$ around \f$ M = 0 \f$, where \f$ M \f$
-    * denotes the matrix \c arg. The degree of the Pad&eacute; approximant and the value of squarings
-    * are chosen such that the approximation error is no more than the round-off error.
-    */
-  static void run(const MatrixType& arg, MatrixType& U, MatrixType& V, int& squarings);
-};
-
-template <typename MatrixType>
-struct matrix_exp_computeUV<MatrixType, float>
-{
-  template <typename ArgType>
-  static void run(const ArgType& arg, MatrixType& U, MatrixType& V, int& squarings)
-  {
-    using std::frexp;
-    using std::pow;
-    const float l1norm = arg.cwiseAbs().colwise().sum().maxCoeff();
-    squarings = 0;
-    if (l1norm < 4.258730016922831e-001f) {
-      matrix_exp_pade3(arg, U, V);
-    } else if (l1norm < 1.880152677804762e+000f) {
-      matrix_exp_pade5(arg, U, V);
-    } else {
-      const float maxnorm = 3.925724783138660f;
-      frexp(l1norm / maxnorm, &squarings);
-      if (squarings < 0) squarings = 0;
-      MatrixType A = arg.unaryExpr(MatrixExponentialScalingOp<float>(squarings));
-      matrix_exp_pade7(A, U, V);
-    }
-  }
-};
-
-template <typename MatrixType>
-struct matrix_exp_computeUV<MatrixType, double>
-{
-  typedef typename NumTraits<typename traits<MatrixType>::Scalar>::Real RealScalar;
-  template <typename ArgType>
-  static void run(const ArgType& arg, MatrixType& U, MatrixType& V, int& squarings)
-  {
-    using std::frexp;
-    using std::pow;
-    const RealScalar l1norm = arg.cwiseAbs().colwise().sum().maxCoeff();
-    squarings = 0;
-    if (l1norm < 1.495585217958292e-002) {
-      matrix_exp_pade3(arg, U, V);
-    } else if (l1norm < 2.539398330063230e-001) {
-      matrix_exp_pade5(arg, U, V);
-    } else if (l1norm < 9.504178996162932e-001) {
-      matrix_exp_pade7(arg, U, V);
-    } else if (l1norm < 2.097847961257068e+000) {
-      matrix_exp_pade9(arg, U, V);
-    } else {
-      const RealScalar maxnorm = 5.371920351148152;
-      frexp(l1norm / maxnorm, &squarings);
-      if (squarings < 0) squarings = 0;
-      MatrixType A = arg.unaryExpr(MatrixExponentialScalingOp<RealScalar>(squarings));
-      matrix_exp_pade13(A, U, V);
-    }
-  }
-};
-  
-template <typename MatrixType>
-struct matrix_exp_computeUV<MatrixType, long double>
-{
-  template <typename ArgType>
-  static void run(const ArgType& arg, MatrixType& U, MatrixType& V, int& squarings)
-  {
-#if   LDBL_MANT_DIG == 53   // double precision
-    matrix_exp_computeUV<MatrixType, double>::run(arg, U, V, squarings);
-  
-#else
-  
-    using std::frexp;
-    using std::pow;
-    const long double l1norm = arg.cwiseAbs().colwise().sum().maxCoeff();
-    squarings = 0;
-  
-#if LDBL_MANT_DIG <= 64   // extended precision
-  
-    if (l1norm < 4.1968497232266989671e-003L) {
-      matrix_exp_pade3(arg, U, V);
-    } else if (l1norm < 1.1848116734693823091e-001L) {
-      matrix_exp_pade5(arg, U, V);
-    } else if (l1norm < 5.5170388480686700274e-001L) {
-      matrix_exp_pade7(arg, U, V);
-    } else if (l1norm < 1.3759868875587845383e+000L) {
-      matrix_exp_pade9(arg, U, V);
-    } else {
-      const long double maxnorm = 4.0246098906697353063L;
-      frexp(l1norm / maxnorm, &squarings);
-      if (squarings < 0) squarings = 0;
-      MatrixType A = arg.unaryExpr(MatrixExponentialScalingOp<long double>(squarings));
-      matrix_exp_pade13(A, U, V);
-    }
-  
-#elif LDBL_MANT_DIG <= 106  // double-double
-  
-    if (l1norm < 3.2787892205607026992947488108213e-005L) {
-      matrix_exp_pade3(arg, U, V);
-    } else if (l1norm < 6.4467025060072760084130906076332e-003L) {
-      matrix_exp_pade5(arg, U, V);
-    } else if (l1norm < 6.8988028496595374751374122881143e-002L) {
-      matrix_exp_pade7(arg, U, V);
-    } else if (l1norm < 2.7339737518502231741495857201670e-001L) {
-      matrix_exp_pade9(arg, U, V);
-    } else if (l1norm < 1.3203382096514474905666448850278e+000L) {
-      matrix_exp_pade13(arg, U, V);
-    } else {
-      const long double maxnorm = 3.2579440895405400856599663723517L;
-      frexp(l1norm / maxnorm, &squarings);
-      if (squarings < 0) squarings = 0;
-      MatrixType A = arg.unaryExpr(MatrixExponentialScalingOp<long double>(squarings));
-      matrix_exp_pade17(A, U, V);
-    }
-  
-#elif LDBL_MANT_DIG <= 112  // quadruple precison
-  
-    if (l1norm < 1.639394610288918690547467954466970e-005L) {
-      matrix_exp_pade3(arg, U, V);
-    } else if (l1norm < 4.253237712165275566025884344433009e-003L) {
-      matrix_exp_pade5(arg, U, V);
-    } else if (l1norm < 5.125804063165764409885122032933142e-002L) {
-      matrix_exp_pade7(arg, U, V);
-    } else if (l1norm < 2.170000765161155195453205651889853e-001L) {
-      matrix_exp_pade9(arg, U, V);
-    } else if (l1norm < 1.125358383453143065081397882891878e+000L) {
-      matrix_exp_pade13(arg, U, V);
-    } else {
-      const long double maxnorm = 2.884233277829519311757165057717815L;
-      frexp(l1norm / maxnorm, &squarings);
-      if (squarings < 0) squarings = 0;
-      MatrixType A = arg.unaryExpr(MatrixExponentialScalingOp<long double>(squarings));
-      matrix_exp_pade17(A, U, V);
-    }
-  
-#else
-  
-    // this case should be handled in compute()
-    eigen_assert(false && "Bug in MatrixExponential"); 
-  
-#endif
-#endif  // LDBL_MANT_DIG
-  }
-};
-
-template<typename T> struct is_exp_known_type : false_type {};
-template<> struct is_exp_known_type<float> : true_type {};
-template<> struct is_exp_known_type<double> : true_type {};
-#if LDBL_MANT_DIG <= 112
-template<> struct is_exp_known_type<long double> : true_type {};
-#endif
-
-template <typename ArgType, typename ResultType>
-void matrix_exp_compute(const ArgType& arg, ResultType &result, true_type) // natively supported scalar type
-{
-  typedef typename ArgType::PlainObject MatrixType;
-  MatrixType U, V;
-  int squarings;
-  matrix_exp_computeUV<MatrixType>::run(arg, U, V, squarings); // Pade approximant is (U+V) / (-U+V)
-  MatrixType numer = U + V;
-  MatrixType denom = -U + V;
-  result = denom.partialPivLu().solve(numer);
-  for (int i=0; i<squarings; i++)
-    result *= result;   // undo scaling by repeated squaring
-}
-
-
-/* Computes the matrix exponential
- *
- * \param arg    argument of matrix exponential (should be plain object)
- * \param result variable in which result will be stored
- */
-template <typename ArgType, typename ResultType>
-void matrix_exp_compute(const ArgType& arg, ResultType &result, false_type) // default
-{
-  typedef typename ArgType::PlainObject MatrixType;
-  typedef typename traits<MatrixType>::Scalar Scalar;
-  typedef typename NumTraits<Scalar>::Real RealScalar;
-  typedef typename std::complex<RealScalar> ComplexScalar;
-  result = arg.matrixFunction(internal::stem_function_exp<ComplexScalar>);
-}
-
-} // end namespace Eigen::internal
-
-/** \ingroup MatrixFunctions_Module
-  *
-  * \brief Proxy for the matrix exponential of some matrix (expression).
-  *
-  * \tparam Derived  Type of the argument to the matrix exponential.
-  *
-  * This class holds the argument to the matrix exponential until it is assigned or evaluated for
-  * some other reason (so the argument should not be changed in the meantime). It is the return type
-  * of MatrixBase::exp() and most of the time this is the only way it is used.
-  */
-template<typename Derived> struct MatrixExponentialReturnValue
-: public ReturnByValue<MatrixExponentialReturnValue<Derived> >
-{
-    typedef typename Derived::Index Index;
-  public:
-    /** \brief Constructor.
-      *
-      * \param src %Matrix (expression) forming the argument of the matrix exponential.
-      */
-    MatrixExponentialReturnValue(const Derived& src) : m_src(src) { }
-
-    /** \brief Compute the matrix exponential.
-      *
-      * \param result the matrix exponential of \p src in the constructor.
-      */
-    template <typename ResultType>
-    inline void evalTo(ResultType& result) const
-    {
-      const typename internal::nested_eval<Derived, 10>::type tmp(m_src);
-      internal::matrix_exp_compute(tmp, result, internal::is_exp_known_type<typename Derived::Scalar>());
-    }
-
-    Index rows() const { return m_src.rows(); }
-    Index cols() const { return m_src.cols(); }
-
-  protected:
-    const typename internal::ref_selector<Derived>::type m_src;
-};
-
-namespace internal {
-template<typename Derived>
-struct traits<MatrixExponentialReturnValue<Derived> >
-{
-  typedef typename Derived::PlainObject ReturnType;
-};
-}
-
-template <typename Derived>
-const MatrixExponentialReturnValue<Derived> MatrixBase<Derived>::exp() const
-{
-  eigen_assert(rows() == cols());
-  return MatrixExponentialReturnValue<Derived>(derived());
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_MATRIX_EXPONENTIAL
diff --git a/wpiutil/src/main/native/eigeninclude/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h b/wpiutil/src/main/native/eigeninclude/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h
deleted file mode 100644
index 3df8239..0000000
--- a/wpiutil/src/main/native/eigeninclude/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h
+++ /dev/null
@@ -1,580 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2009-2011, 2013 Jitse Niesen <jitse@maths.leeds.ac.uk>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_MATRIX_FUNCTION_H
-#define EIGEN_MATRIX_FUNCTION_H
-
-#include "StemFunction.h"
-
-
-namespace Eigen { 
-
-namespace internal {
-
-/** \brief Maximum distance allowed between eigenvalues to be considered "close". */
-static const float matrix_function_separation = 0.1f;
-
-/** \ingroup MatrixFunctions_Module
-  * \class MatrixFunctionAtomic
-  * \brief Helper class for computing matrix functions of atomic matrices.
-  *
-  * Here, an atomic matrix is a triangular matrix whose diagonal entries are close to each other.
-  */
-template <typename MatrixType>
-class MatrixFunctionAtomic 
-{
-  public:
-
-    typedef typename MatrixType::Scalar Scalar;
-    typedef typename stem_function<Scalar>::type StemFunction;
-
-    /** \brief Constructor
-      * \param[in]  f  matrix function to compute.
-      */
-    MatrixFunctionAtomic(StemFunction f) : m_f(f) { }
-
-    /** \brief Compute matrix function of atomic matrix
-      * \param[in]  A  argument of matrix function, should be upper triangular and atomic
-      * \returns  f(A), the matrix function evaluated at the given matrix
-      */
-    MatrixType compute(const MatrixType& A);
-
-  private:
-    StemFunction* m_f;
-};
-
-template <typename MatrixType>
-typename NumTraits<typename MatrixType::Scalar>::Real matrix_function_compute_mu(const MatrixType& A)
-{
-  typedef typename plain_col_type<MatrixType>::type VectorType;
-  typename MatrixType::Index rows = A.rows();
-  const MatrixType N = MatrixType::Identity(rows, rows) - A;
-  VectorType e = VectorType::Ones(rows);
-  N.template triangularView<Upper>().solveInPlace(e);
-  return e.cwiseAbs().maxCoeff();
-}
-
-template <typename MatrixType>
-MatrixType MatrixFunctionAtomic<MatrixType>::compute(const MatrixType& A)
-{
-  // TODO: Use that A is upper triangular
-  typedef typename NumTraits<Scalar>::Real RealScalar;
-  typedef typename MatrixType::Index Index;
-  Index rows = A.rows();
-  Scalar avgEival = A.trace() / Scalar(RealScalar(rows));
-  MatrixType Ashifted = A - avgEival * MatrixType::Identity(rows, rows);
-  RealScalar mu = matrix_function_compute_mu(Ashifted);
-  MatrixType F = m_f(avgEival, 0) * MatrixType::Identity(rows, rows);
-  MatrixType P = Ashifted;
-  MatrixType Fincr;
-  for (Index s = 1; s < 1.1 * rows + 10; s++) { // upper limit is fairly arbitrary
-    Fincr = m_f(avgEival, static_cast<int>(s)) * P;
-    F += Fincr;
-    P = Scalar(RealScalar(1.0/(s + 1))) * P * Ashifted;
-
-    // test whether Taylor series converged
-    const RealScalar F_norm = F.cwiseAbs().rowwise().sum().maxCoeff();
-    const RealScalar Fincr_norm = Fincr.cwiseAbs().rowwise().sum().maxCoeff();
-    if (Fincr_norm < NumTraits<Scalar>::epsilon() * F_norm) {
-      RealScalar delta = 0;
-      RealScalar rfactorial = 1;
-      for (Index r = 0; r < rows; r++) {
-        RealScalar mx = 0;
-        for (Index i = 0; i < rows; i++)
-          mx = (std::max)(mx, std::abs(m_f(Ashifted(i, i) + avgEival, static_cast<int>(s+r))));
-        if (r != 0)
-          rfactorial *= RealScalar(r);
-        delta = (std::max)(delta, mx / rfactorial);
-      }
-      const RealScalar P_norm = P.cwiseAbs().rowwise().sum().maxCoeff();
-      if (mu * delta * P_norm < NumTraits<Scalar>::epsilon() * F_norm) // series converged
-        break;
-    }
-  }
-  return F;
-}
-
-/** \brief Find cluster in \p clusters containing some value 
-  * \param[in] key Value to find
-  * \returns Iterator to cluster containing \p key, or \c clusters.end() if no cluster in \p m_clusters
-  * contains \p key.
-  */
-template <typename Index, typename ListOfClusters>
-typename ListOfClusters::iterator matrix_function_find_cluster(Index key, ListOfClusters& clusters)
-{
-  typename std::list<Index>::iterator j;
-  for (typename ListOfClusters::iterator i = clusters.begin(); i != clusters.end(); ++i) {
-    j = std::find(i->begin(), i->end(), key);
-    if (j != i->end())
-      return i;
-  }
-  return clusters.end();
-}
-
-/** \brief Partition eigenvalues in clusters of ei'vals close to each other
-  * 
-  * \param[in]  eivals    Eigenvalues
-  * \param[out] clusters  Resulting partition of eigenvalues
-  *
-  * The partition satisfies the following two properties:
-  * # Any eigenvalue in a certain cluster is at most matrix_function_separation() away from another eigenvalue
-  *   in the same cluster.
-  * # The distance between two eigenvalues in different clusters is more than matrix_function_separation().  
-  * The implementation follows Algorithm 4.1 in the paper of Davies and Higham.
-  */
-template <typename EivalsType, typename Cluster>
-void matrix_function_partition_eigenvalues(const EivalsType& eivals, std::list<Cluster>& clusters)
-{
-  typedef typename EivalsType::Index Index;
-  typedef typename EivalsType::RealScalar RealScalar;
-  for (Index i=0; i<eivals.rows(); ++i) {
-    // Find cluster containing i-th ei'val, adding a new cluster if necessary
-    typename std::list<Cluster>::iterator qi = matrix_function_find_cluster(i, clusters);
-    if (qi == clusters.end()) {
-      Cluster l;
-      l.push_back(i);
-      clusters.push_back(l);
-      qi = clusters.end();
-      --qi;
-    }
-
-    // Look for other element to add to the set
-    for (Index j=i+1; j<eivals.rows(); ++j) {
-      if (abs(eivals(j) - eivals(i)) <= RealScalar(matrix_function_separation)
-          && std::find(qi->begin(), qi->end(), j) == qi->end()) {
-        typename std::list<Cluster>::iterator qj = matrix_function_find_cluster(j, clusters);
-        if (qj == clusters.end()) {
-          qi->push_back(j);
-        } else {
-          qi->insert(qi->end(), qj->begin(), qj->end());
-          clusters.erase(qj);
-        }
-      }
-    }
-  }
-}
-
-/** \brief Compute size of each cluster given a partitioning */
-template <typename ListOfClusters, typename Index>
-void matrix_function_compute_cluster_size(const ListOfClusters& clusters, Matrix<Index, Dynamic, 1>& clusterSize)
-{
-  const Index numClusters = static_cast<Index>(clusters.size());
-  clusterSize.setZero(numClusters);
-  Index clusterIndex = 0;
-  for (typename ListOfClusters::const_iterator cluster = clusters.begin(); cluster != clusters.end(); ++cluster) {
-    clusterSize[clusterIndex] = cluster->size();
-    ++clusterIndex;
-  }
-}
-
-/** \brief Compute start of each block using clusterSize */
-template <typename VectorType>
-void matrix_function_compute_block_start(const VectorType& clusterSize, VectorType& blockStart)
-{
-  blockStart.resize(clusterSize.rows());
-  blockStart(0) = 0;
-  for (typename VectorType::Index i = 1; i < clusterSize.rows(); i++) {
-    blockStart(i) = blockStart(i-1) + clusterSize(i-1);
-  }
-}
-
-/** \brief Compute mapping of eigenvalue indices to cluster indices */
-template <typename EivalsType, typename ListOfClusters, typename VectorType>
-void matrix_function_compute_map(const EivalsType& eivals, const ListOfClusters& clusters, VectorType& eivalToCluster)
-{
-  typedef typename EivalsType::Index Index;
-  eivalToCluster.resize(eivals.rows());
-  Index clusterIndex = 0;
-  for (typename ListOfClusters::const_iterator cluster = clusters.begin(); cluster != clusters.end(); ++cluster) {
-    for (Index i = 0; i < eivals.rows(); ++i) {
-      if (std::find(cluster->begin(), cluster->end(), i) != cluster->end()) {
-        eivalToCluster[i] = clusterIndex;
-      }
-    }
-    ++clusterIndex;
-  }
-}
-
-/** \brief Compute permutation which groups ei'vals in same cluster together */
-template <typename DynVectorType, typename VectorType>
-void matrix_function_compute_permutation(const DynVectorType& blockStart, const DynVectorType& eivalToCluster, VectorType& permutation)
-{
-  typedef typename VectorType::Index Index;
-  DynVectorType indexNextEntry = blockStart;
-  permutation.resize(eivalToCluster.rows());
-  for (Index i = 0; i < eivalToCluster.rows(); i++) {
-    Index cluster = eivalToCluster[i];
-    permutation[i] = indexNextEntry[cluster];
-    ++indexNextEntry[cluster];
-  }
-}  
-
-/** \brief Permute Schur decomposition in U and T according to permutation */
-template <typename VectorType, typename MatrixType>
-void matrix_function_permute_schur(VectorType& permutation, MatrixType& U, MatrixType& T)
-{
-  typedef typename VectorType::Index Index;
-  for (Index i = 0; i < permutation.rows() - 1; i++) {
-    Index j;
-    for (j = i; j < permutation.rows(); j++) {
-      if (permutation(j) == i) break;
-    }
-    eigen_assert(permutation(j) == i);
-    for (Index k = j-1; k >= i; k--) {
-      JacobiRotation<typename MatrixType::Scalar> rotation;
-      rotation.makeGivens(T(k, k+1), T(k+1, k+1) - T(k, k));
-      T.applyOnTheLeft(k, k+1, rotation.adjoint());
-      T.applyOnTheRight(k, k+1, rotation);
-      U.applyOnTheRight(k, k+1, rotation);
-      std::swap(permutation.coeffRef(k), permutation.coeffRef(k+1));
-    }
-  }
-}
-
-/** \brief Compute block diagonal part of matrix function.
-  *
-  * This routine computes the matrix function applied to the block diagonal part of \p T (which should be
-  * upper triangular), with the blocking given by \p blockStart and \p clusterSize. The matrix function of
-  * each diagonal block is computed by \p atomic. The off-diagonal parts of \p fT are set to zero.
-  */
-template <typename MatrixType, typename AtomicType, typename VectorType>
-void matrix_function_compute_block_atomic(const MatrixType& T, AtomicType& atomic, const VectorType& blockStart, const VectorType& clusterSize, MatrixType& fT)
-{ 
-  fT.setZero(T.rows(), T.cols());
-  for (typename VectorType::Index i = 0; i < clusterSize.rows(); ++i) {
-    fT.block(blockStart(i), blockStart(i), clusterSize(i), clusterSize(i))
-      = atomic.compute(T.block(blockStart(i), blockStart(i), clusterSize(i), clusterSize(i)));
-  }
-}
-
-/** \brief Solve a triangular Sylvester equation AX + XB = C 
-  *
-  * \param[in]  A  the matrix A; should be square and upper triangular
-  * \param[in]  B  the matrix B; should be square and upper triangular
-  * \param[in]  C  the matrix C; should have correct size.
-  *
-  * \returns the solution X.
-  *
-  * If A is m-by-m and B is n-by-n, then both C and X are m-by-n.  The (i,j)-th component of the Sylvester
-  * equation is
-  * \f[ 
-  *     \sum_{k=i}^m A_{ik} X_{kj} + \sum_{k=1}^j X_{ik} B_{kj} = C_{ij}. 
-  * \f]
-  * This can be re-arranged to yield:
-  * \f[ 
-  *     X_{ij} = \frac{1}{A_{ii} + B_{jj}} \Bigl( C_{ij}
-  *     - \sum_{k=i+1}^m A_{ik} X_{kj} - \sum_{k=1}^{j-1} X_{ik} B_{kj} \Bigr).
-  * \f]
-  * It is assumed that A and B are such that the numerator is never zero (otherwise the Sylvester equation
-  * does not have a unique solution). In that case, these equations can be evaluated in the order 
-  * \f$ i=m,\ldots,1 \f$ and \f$ j=1,\ldots,n \f$.
-  */
-template <typename MatrixType>
-MatrixType matrix_function_solve_triangular_sylvester(const MatrixType& A, const MatrixType& B, const MatrixType& C)
-{
-  eigen_assert(A.rows() == A.cols());
-  eigen_assert(A.isUpperTriangular());
-  eigen_assert(B.rows() == B.cols());
-  eigen_assert(B.isUpperTriangular());
-  eigen_assert(C.rows() == A.rows());
-  eigen_assert(C.cols() == B.rows());
-
-  typedef typename MatrixType::Index Index;
-  typedef typename MatrixType::Scalar Scalar;
-
-  Index m = A.rows();
-  Index n = B.rows();
-  MatrixType X(m, n);
-
-  for (Index i = m - 1; i >= 0; --i) {
-    for (Index j = 0; j < n; ++j) {
-
-      // Compute AX = \sum_{k=i+1}^m A_{ik} X_{kj}
-      Scalar AX;
-      if (i == m - 1) {
-	AX = 0; 
-      } else {
-	Matrix<Scalar,1,1> AXmatrix = A.row(i).tail(m-1-i) * X.col(j).tail(m-1-i);
-	AX = AXmatrix(0,0);
-      }
-
-      // Compute XB = \sum_{k=1}^{j-1} X_{ik} B_{kj}
-      Scalar XB;
-      if (j == 0) {
-	XB = 0; 
-      } else {
-	Matrix<Scalar,1,1> XBmatrix = X.row(i).head(j) * B.col(j).head(j);
-	XB = XBmatrix(0,0);
-      }
-
-      X(i,j) = (C(i,j) - AX - XB) / (A(i,i) + B(j,j));
-    }
-  }
-  return X;
-}
-
-/** \brief Compute part of matrix function above block diagonal.
-  *
-  * This routine completes the computation of \p fT, denoting a matrix function applied to the triangular
-  * matrix \p T. It assumes that the block diagonal part of \p fT has already been computed. The part below
-  * the diagonal is zero, because \p T is upper triangular.
-  */
-template <typename MatrixType, typename VectorType>
-void matrix_function_compute_above_diagonal(const MatrixType& T, const VectorType& blockStart, const VectorType& clusterSize, MatrixType& fT)
-{ 
-  typedef internal::traits<MatrixType> Traits;
-  typedef typename MatrixType::Scalar Scalar;
-  typedef typename MatrixType::Index Index;
-  static const int RowsAtCompileTime = Traits::RowsAtCompileTime;
-  static const int ColsAtCompileTime = Traits::ColsAtCompileTime;
-  static const int Options = MatrixType::Options;
-  typedef Matrix<Scalar, Dynamic, Dynamic, Options, RowsAtCompileTime, ColsAtCompileTime> DynMatrixType;
-
-  for (Index k = 1; k < clusterSize.rows(); k++) {
-    for (Index i = 0; i < clusterSize.rows() - k; i++) {
-      // compute (i, i+k) block
-      DynMatrixType A = T.block(blockStart(i), blockStart(i), clusterSize(i), clusterSize(i));
-      DynMatrixType B = -T.block(blockStart(i+k), blockStart(i+k), clusterSize(i+k), clusterSize(i+k));
-      DynMatrixType C = fT.block(blockStart(i), blockStart(i), clusterSize(i), clusterSize(i))
-        * T.block(blockStart(i), blockStart(i+k), clusterSize(i), clusterSize(i+k));
-      C -= T.block(blockStart(i), blockStart(i+k), clusterSize(i), clusterSize(i+k))
-        * fT.block(blockStart(i+k), blockStart(i+k), clusterSize(i+k), clusterSize(i+k));
-      for (Index m = i + 1; m < i + k; m++) {
-        C += fT.block(blockStart(i), blockStart(m), clusterSize(i), clusterSize(m))
-          * T.block(blockStart(m), blockStart(i+k), clusterSize(m), clusterSize(i+k));
-        C -= T.block(blockStart(i), blockStart(m), clusterSize(i), clusterSize(m))
-          * fT.block(blockStart(m), blockStart(i+k), clusterSize(m), clusterSize(i+k));
-      }
-      fT.block(blockStart(i), blockStart(i+k), clusterSize(i), clusterSize(i+k))
-        = matrix_function_solve_triangular_sylvester(A, B, C);
-    }
-  }
-}
-
-/** \ingroup MatrixFunctions_Module
-  * \brief Class for computing matrix functions.
-  * \tparam  MatrixType  type of the argument of the matrix function,
-  *                      expected to be an instantiation of the Matrix class template.
-  * \tparam  AtomicType  type for computing matrix function of atomic blocks.
-  * \tparam  IsComplex   used internally to select correct specialization.
-  *
-  * This class implements the Schur-Parlett algorithm for computing matrix functions. The spectrum of the
-  * matrix is divided in clustered of eigenvalues that lies close together. This class delegates the
-  * computation of the matrix function on every block corresponding to these clusters to an object of type
-  * \p AtomicType and uses these results to compute the matrix function of the whole matrix. The class
-  * \p AtomicType should have a \p compute() member function for computing the matrix function of a block.
-  *
-  * \sa class MatrixFunctionAtomic, class MatrixLogarithmAtomic
-  */
-template <typename MatrixType, int IsComplex = NumTraits<typename internal::traits<MatrixType>::Scalar>::IsComplex>
-struct matrix_function_compute
-{  
-    /** \brief Compute the matrix function.
-      *
-      * \param[in]  A       argument of matrix function, should be a square matrix.
-      * \param[in]  atomic  class for computing matrix function of atomic blocks.
-      * \param[out] result  the function \p f applied to \p A, as
-      * specified in the constructor.
-      *
-      * See MatrixBase::matrixFunction() for details on how this computation
-      * is implemented.
-      */
-    template <typename AtomicType, typename ResultType> 
-    static void run(const MatrixType& A, AtomicType& atomic, ResultType &result);    
-};
-
-/** \internal \ingroup MatrixFunctions_Module 
-  * \brief Partial specialization of MatrixFunction for real matrices
-  *
-  * This converts the real matrix to a complex matrix, compute the matrix function of that matrix, and then
-  * converts the result back to a real matrix.
-  */
-template <typename MatrixType>
-struct matrix_function_compute<MatrixType, 0>
-{  
-  template <typename MatA, typename AtomicType, typename ResultType>
-  static void run(const MatA& A, AtomicType& atomic, ResultType &result)
-  {
-    typedef internal::traits<MatrixType> Traits;
-    typedef typename Traits::Scalar Scalar;
-    static const int Rows = Traits::RowsAtCompileTime, Cols = Traits::ColsAtCompileTime;
-    static const int MaxRows = Traits::MaxRowsAtCompileTime, MaxCols = Traits::MaxColsAtCompileTime;
-
-    typedef std::complex<Scalar> ComplexScalar;
-    typedef Matrix<ComplexScalar, Rows, Cols, 0, MaxRows, MaxCols> ComplexMatrix;
-
-    ComplexMatrix CA = A.template cast<ComplexScalar>();
-    ComplexMatrix Cresult;
-    matrix_function_compute<ComplexMatrix>::run(CA, atomic, Cresult);
-    result = Cresult.real();
-  }
-};
-
-/** \internal \ingroup MatrixFunctions_Module 
-  * \brief Partial specialization of MatrixFunction for complex matrices
-  */
-template <typename MatrixType>
-struct matrix_function_compute<MatrixType, 1>
-{
-  template <typename MatA, typename AtomicType, typename ResultType>
-  static void run(const MatA& A, AtomicType& atomic, ResultType &result)
-  {
-    typedef internal::traits<MatrixType> Traits;
-    
-    // compute Schur decomposition of A
-    const ComplexSchur<MatrixType> schurOfA(A);  
-    MatrixType T = schurOfA.matrixT();
-    MatrixType U = schurOfA.matrixU();
-
-    // partition eigenvalues into clusters of ei'vals "close" to each other
-    std::list<std::list<Index> > clusters; 
-    matrix_function_partition_eigenvalues(T.diagonal(), clusters);
-
-    // compute size of each cluster
-    Matrix<Index, Dynamic, 1> clusterSize;
-    matrix_function_compute_cluster_size(clusters, clusterSize);
-
-    // blockStart[i] is row index at which block corresponding to i-th cluster starts 
-    Matrix<Index, Dynamic, 1> blockStart; 
-    matrix_function_compute_block_start(clusterSize, blockStart);
-
-    // compute map so that eivalToCluster[i] = j means that i-th ei'val is in j-th cluster 
-    Matrix<Index, Dynamic, 1> eivalToCluster;
-    matrix_function_compute_map(T.diagonal(), clusters, eivalToCluster);
-
-    // compute permutation which groups ei'vals in same cluster together 
-    Matrix<Index, Traits::RowsAtCompileTime, 1> permutation;
-    matrix_function_compute_permutation(blockStart, eivalToCluster, permutation);
-
-    // permute Schur decomposition
-    matrix_function_permute_schur(permutation, U, T);
-
-    // compute result
-    MatrixType fT; // matrix function applied to T
-    matrix_function_compute_block_atomic(T, atomic, blockStart, clusterSize, fT);
-    matrix_function_compute_above_diagonal(T, blockStart, clusterSize, fT);
-    result = U * (fT.template triangularView<Upper>() * U.adjoint());
-  }
-};
-
-} // end of namespace internal
-
-/** \ingroup MatrixFunctions_Module
-  *
-  * \brief Proxy for the matrix function of some matrix (expression).
-  *
-  * \tparam Derived  Type of the argument to the matrix function.
-  *
-  * This class holds the argument to the matrix function until it is assigned or evaluated for some other
-  * reason (so the argument should not be changed in the meantime). It is the return type of
-  * matrixBase::matrixFunction() and related functions and most of the time this is the only way it is used.
-  */
-template<typename Derived> class MatrixFunctionReturnValue
-: public ReturnByValue<MatrixFunctionReturnValue<Derived> >
-{
-  public:
-    typedef typename Derived::Scalar Scalar;
-    typedef typename Derived::Index Index;
-    typedef typename internal::stem_function<Scalar>::type StemFunction;
-
-  protected:
-    typedef typename internal::ref_selector<Derived>::type DerivedNested;
-
-  public:
-
-    /** \brief Constructor.
-      *
-      * \param[in] A  %Matrix (expression) forming the argument of the matrix function.
-      * \param[in] f  Stem function for matrix function under consideration.
-      */
-    MatrixFunctionReturnValue(const Derived& A, StemFunction f) : m_A(A), m_f(f) { }
-
-    /** \brief Compute the matrix function.
-      *
-      * \param[out] result \p f applied to \p A, where \p f and \p A are as in the constructor.
-      */
-    template <typename ResultType>
-    inline void evalTo(ResultType& result) const
-    {
-      typedef typename internal::nested_eval<Derived, 10>::type NestedEvalType;
-      typedef typename internal::remove_all<NestedEvalType>::type NestedEvalTypeClean;
-      typedef internal::traits<NestedEvalTypeClean> Traits;
-      static const int RowsAtCompileTime = Traits::RowsAtCompileTime;
-      static const int ColsAtCompileTime = Traits::ColsAtCompileTime;
-      typedef std::complex<typename NumTraits<Scalar>::Real> ComplexScalar;
-      typedef Matrix<ComplexScalar, Dynamic, Dynamic, 0, RowsAtCompileTime, ColsAtCompileTime> DynMatrixType;
-
-      typedef internal::MatrixFunctionAtomic<DynMatrixType> AtomicType;
-      AtomicType atomic(m_f);
-
-      internal::matrix_function_compute<typename NestedEvalTypeClean::PlainObject>::run(m_A, atomic, result);
-    }
-
-    Index rows() const { return m_A.rows(); }
-    Index cols() const { return m_A.cols(); }
-
-  private:
-    const DerivedNested m_A;
-    StemFunction *m_f;
-};
-
-namespace internal {
-template<typename Derived>
-struct traits<MatrixFunctionReturnValue<Derived> >
-{
-  typedef typename Derived::PlainObject ReturnType;
-};
-}
-
-
-/********** MatrixBase methods **********/
-
-
-template <typename Derived>
-const MatrixFunctionReturnValue<Derived> MatrixBase<Derived>::matrixFunction(typename internal::stem_function<typename internal::traits<Derived>::Scalar>::type f) const
-{
-  eigen_assert(rows() == cols());
-  return MatrixFunctionReturnValue<Derived>(derived(), f);
-}
-
-template <typename Derived>
-const MatrixFunctionReturnValue<Derived> MatrixBase<Derived>::sin() const
-{
-  eigen_assert(rows() == cols());
-  typedef typename internal::stem_function<Scalar>::ComplexScalar ComplexScalar;
-  return MatrixFunctionReturnValue<Derived>(derived(), internal::stem_function_sin<ComplexScalar>);
-}
-
-template <typename Derived>
-const MatrixFunctionReturnValue<Derived> MatrixBase<Derived>::cos() const
-{
-  eigen_assert(rows() == cols());
-  typedef typename internal::stem_function<Scalar>::ComplexScalar ComplexScalar;
-  return MatrixFunctionReturnValue<Derived>(derived(), internal::stem_function_cos<ComplexScalar>);
-}
-
-template <typename Derived>
-const MatrixFunctionReturnValue<Derived> MatrixBase<Derived>::sinh() const
-{
-  eigen_assert(rows() == cols());
-  typedef typename internal::stem_function<Scalar>::ComplexScalar ComplexScalar;
-  return MatrixFunctionReturnValue<Derived>(derived(), internal::stem_function_sinh<ComplexScalar>);
-}
-
-template <typename Derived>
-const MatrixFunctionReturnValue<Derived> MatrixBase<Derived>::cosh() const
-{
-  eigen_assert(rows() == cols());
-  typedef typename internal::stem_function<Scalar>::ComplexScalar ComplexScalar;
-  return MatrixFunctionReturnValue<Derived>(derived(), internal::stem_function_cosh<ComplexScalar>);
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_MATRIX_FUNCTION_H
diff --git a/wpiutil/src/main/native/eigeninclude/unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h b/wpiutil/src/main/native/eigeninclude/unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h
deleted file mode 100644
index cf5fffa..0000000
--- a/wpiutil/src/main/native/eigeninclude/unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h
+++ /dev/null
@@ -1,373 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2011, 2013 Jitse Niesen <jitse@maths.leeds.ac.uk>
-// Copyright (C) 2011 Chen-Pang He <jdh8@ms63.hinet.net>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_MATRIX_LOGARITHM
-#define EIGEN_MATRIX_LOGARITHM
-
-namespace Eigen { 
-
-namespace internal { 
-
-template <typename Scalar>
-struct matrix_log_min_pade_degree 
-{
-  static const int value = 3;
-};
-
-template <typename Scalar>
-struct matrix_log_max_pade_degree 
-{
-  typedef typename NumTraits<Scalar>::Real RealScalar;
-  static const int value = std::numeric_limits<RealScalar>::digits<= 24?  5:  // single precision
-                           std::numeric_limits<RealScalar>::digits<= 53?  7:  // double precision
-                           std::numeric_limits<RealScalar>::digits<= 64?  8:  // extended precision
-                           std::numeric_limits<RealScalar>::digits<=106? 10:  // double-double
-                                                                         11;  // quadruple precision
-};
-
-/** \brief Compute logarithm of 2x2 triangular matrix. */
-template <typename MatrixType>
-void matrix_log_compute_2x2(const MatrixType& A, MatrixType& result)
-{
-  typedef typename MatrixType::Scalar Scalar;
-  typedef typename MatrixType::RealScalar RealScalar;
-  using std::abs;
-  using std::ceil;
-  using std::imag;
-  using std::log;
-
-  Scalar logA00 = log(A(0,0));
-  Scalar logA11 = log(A(1,1));
-
-  result(0,0) = logA00;
-  result(1,0) = Scalar(0);
-  result(1,1) = logA11;
-
-  Scalar y = A(1,1) - A(0,0);
-  if (y==Scalar(0))
-  {
-    result(0,1) = A(0,1) / A(0,0);
-  }
-  else if ((abs(A(0,0)) < RealScalar(0.5)*abs(A(1,1))) || (abs(A(0,0)) > 2*abs(A(1,1))))
-  {
-    result(0,1) = A(0,1) * (logA11 - logA00) / y;
-  }
-  else
-  {
-    // computation in previous branch is inaccurate if A(1,1) \approx A(0,0)
-    int unwindingNumber = static_cast<int>(ceil((imag(logA11 - logA00) - RealScalar(EIGEN_PI)) / RealScalar(2*EIGEN_PI)));
-    result(0,1) = A(0,1) * (numext::log1p(y/A(0,0)) + Scalar(0,2*EIGEN_PI*unwindingNumber)) / y;
-  }
-}
-
-/* \brief Get suitable degree for Pade approximation. (specialized for RealScalar = float) */
-inline int matrix_log_get_pade_degree(float normTminusI)
-{
-  const float maxNormForPade[] = { 2.5111573934555054e-1 /* degree = 3 */ , 4.0535837411880493e-1,
-            5.3149729967117310e-1 };
-  const int minPadeDegree = matrix_log_min_pade_degree<float>::value;
-  const int maxPadeDegree = matrix_log_max_pade_degree<float>::value;
-  int degree = minPadeDegree;
-  for (; degree <= maxPadeDegree; ++degree) 
-    if (normTminusI <= maxNormForPade[degree - minPadeDegree])
-      break;
-  return degree;
-}
-
-/* \brief Get suitable degree for Pade approximation. (specialized for RealScalar = double) */
-inline int matrix_log_get_pade_degree(double normTminusI)
-{
-  const double maxNormForPade[] = { 1.6206284795015624e-2 /* degree = 3 */ , 5.3873532631381171e-2,
-            1.1352802267628681e-1, 1.8662860613541288e-1, 2.642960831111435e-1 };
-  const int minPadeDegree = matrix_log_min_pade_degree<double>::value;
-  const int maxPadeDegree = matrix_log_max_pade_degree<double>::value;
-  int degree = minPadeDegree;
-  for (; degree <= maxPadeDegree; ++degree)
-    if (normTminusI <= maxNormForPade[degree - minPadeDegree])
-      break;
-  return degree;
-}
-
-/* \brief Get suitable degree for Pade approximation. (specialized for RealScalar = long double) */
-inline int matrix_log_get_pade_degree(long double normTminusI)
-{
-#if   LDBL_MANT_DIG == 53         // double precision
-  const long double maxNormForPade[] = { 1.6206284795015624e-2L /* degree = 3 */ , 5.3873532631381171e-2L,
-            1.1352802267628681e-1L, 1.8662860613541288e-1L, 2.642960831111435e-1L };
-#elif LDBL_MANT_DIG <= 64         // extended precision
-  const long double maxNormForPade[] = { 5.48256690357782863103e-3L /* degree = 3 */, 2.34559162387971167321e-2L,
-            5.84603923897347449857e-2L, 1.08486423756725170223e-1L, 1.68385767881294446649e-1L,
-            2.32777776523703892094e-1L };
-#elif LDBL_MANT_DIG <= 106        // double-double
-  const long double maxNormForPade[] = { 8.58970550342939562202529664318890e-5L /* degree = 3 */,
-            9.34074328446359654039446552677759e-4L, 4.26117194647672175773064114582860e-3L,
-            1.21546224740281848743149666560464e-2L, 2.61100544998339436713088248557444e-2L,
-            4.66170074627052749243018566390567e-2L, 7.32585144444135027565872014932387e-2L,
-            1.05026503471351080481093652651105e-1L };
-#else                             // quadruple precision
-  const long double maxNormForPade[] = { 4.7419931187193005048501568167858103e-5L /* degree = 3 */,
-            5.8853168473544560470387769480192666e-4L, 2.9216120366601315391789493628113520e-3L,
-            8.8415758124319434347116734705174308e-3L, 1.9850836029449446668518049562565291e-2L,
-            3.6688019729653446926585242192447447e-2L, 5.9290962294020186998954055264528393e-2L,
-            8.6998436081634343903250580992127677e-2L, 1.1880960220216759245467951592883642e-1L };
-#endif
-  const int minPadeDegree = matrix_log_min_pade_degree<long double>::value;
-  const int maxPadeDegree = matrix_log_max_pade_degree<long double>::value;
-  int degree = minPadeDegree;
-  for (; degree <= maxPadeDegree; ++degree)
-    if (normTminusI <= maxNormForPade[degree - minPadeDegree])
-      break;
-  return degree;
-}
-
-/* \brief Compute Pade approximation to matrix logarithm */
-template <typename MatrixType>
-void matrix_log_compute_pade(MatrixType& result, const MatrixType& T, int degree)
-{
-  typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
-  const int minPadeDegree = 3;
-  const int maxPadeDegree = 11;
-  assert(degree >= minPadeDegree && degree <= maxPadeDegree);
-
-  const RealScalar nodes[][maxPadeDegree] = { 
-    { 0.1127016653792583114820734600217600L, 0.5000000000000000000000000000000000L,  // degree 3
-      0.8872983346207416885179265399782400L }, 
-    { 0.0694318442029737123880267555535953L, 0.3300094782075718675986671204483777L,  // degree 4
-      0.6699905217924281324013328795516223L, 0.9305681557970262876119732444464048L },
-    { 0.0469100770306680036011865608503035L, 0.2307653449471584544818427896498956L,  // degree 5
-      0.5000000000000000000000000000000000L, 0.7692346550528415455181572103501044L,
-      0.9530899229693319963988134391496965L },
-    { 0.0337652428984239860938492227530027L, 0.1693953067668677431693002024900473L,  // degree 6
-      0.3806904069584015456847491391596440L, 0.6193095930415984543152508608403560L,
-      0.8306046932331322568306997975099527L, 0.9662347571015760139061507772469973L },
-    { 0.0254460438286207377369051579760744L, 0.1292344072003027800680676133596058L,  // degree 7
-      0.2970774243113014165466967939615193L, 0.5000000000000000000000000000000000L,
-      0.7029225756886985834533032060384807L, 0.8707655927996972199319323866403942L,
-      0.9745539561713792622630948420239256L },
-    { 0.0198550717512318841582195657152635L, 0.1016667612931866302042230317620848L,  // degree 8
-      0.2372337950418355070911304754053768L, 0.4082826787521750975302619288199080L,
-      0.5917173212478249024697380711800920L, 0.7627662049581644929088695245946232L,
-      0.8983332387068133697957769682379152L, 0.9801449282487681158417804342847365L },
-    { 0.0159198802461869550822118985481636L, 0.0819844463366821028502851059651326L,  // degree 9
-      0.1933142836497048013456489803292629L, 0.3378732882980955354807309926783317L,
-      0.5000000000000000000000000000000000L, 0.6621267117019044645192690073216683L,
-      0.8066857163502951986543510196707371L, 0.9180155536633178971497148940348674L,
-      0.9840801197538130449177881014518364L },
-    { 0.0130467357414141399610179939577740L, 0.0674683166555077446339516557882535L,  // degree 10
-      0.1602952158504877968828363174425632L, 0.2833023029353764046003670284171079L,
-      0.4255628305091843945575869994351400L, 0.5744371694908156054424130005648600L,
-      0.7166976970646235953996329715828921L, 0.8397047841495122031171636825574368L,
-      0.9325316833444922553660483442117465L, 0.9869532642585858600389820060422260L },
-    { 0.0108856709269715035980309994385713L, 0.0564687001159523504624211153480364L,  // degree 11
-      0.1349239972129753379532918739844233L, 0.2404519353965940920371371652706952L,
-      0.3652284220238275138342340072995692L, 0.5000000000000000000000000000000000L,
-      0.6347715779761724861657659927004308L, 0.7595480646034059079628628347293048L,
-      0.8650760027870246620467081260155767L, 0.9435312998840476495375788846519636L,
-      0.9891143290730284964019690005614287L } };
-
-  const RealScalar weights[][maxPadeDegree] = { 
-    { 0.2777777777777777777777777777777778L, 0.4444444444444444444444444444444444L,  // degree 3
-      0.2777777777777777777777777777777778L },
-    { 0.1739274225687269286865319746109997L, 0.3260725774312730713134680253890003L,  // degree 4
-      0.3260725774312730713134680253890003L, 0.1739274225687269286865319746109997L },
-    { 0.1184634425280945437571320203599587L, 0.2393143352496832340206457574178191L,  // degree 5
-      0.2844444444444444444444444444444444L, 0.2393143352496832340206457574178191L,
-      0.1184634425280945437571320203599587L },
-    { 0.0856622461895851725201480710863665L, 0.1803807865240693037849167569188581L,  // degree 6
-      0.2339569672863455236949351719947755L, 0.2339569672863455236949351719947755L,
-      0.1803807865240693037849167569188581L, 0.0856622461895851725201480710863665L },
-    { 0.0647424830844348466353057163395410L, 0.1398526957446383339507338857118898L,  // degree 7
-      0.1909150252525594724751848877444876L, 0.2089795918367346938775510204081633L,
-      0.1909150252525594724751848877444876L, 0.1398526957446383339507338857118898L,
-      0.0647424830844348466353057163395410L },
-    { 0.0506142681451881295762656771549811L, 0.1111905172266872352721779972131204L,  // degree 8
-      0.1568533229389436436689811009933007L, 0.1813418916891809914825752246385978L,
-      0.1813418916891809914825752246385978L, 0.1568533229389436436689811009933007L,
-      0.1111905172266872352721779972131204L, 0.0506142681451881295762656771549811L },
-    { 0.0406371941807872059859460790552618L, 0.0903240803474287020292360156214564L,  // degree 9
-      0.1303053482014677311593714347093164L, 0.1561735385200014200343152032922218L,
-      0.1651196775006298815822625346434870L, 0.1561735385200014200343152032922218L,
-      0.1303053482014677311593714347093164L, 0.0903240803474287020292360156214564L,
-      0.0406371941807872059859460790552618L },
-    { 0.0333356721543440687967844049466659L, 0.0747256745752902965728881698288487L,  // degree 10
-      0.1095431812579910219977674671140816L, 0.1346333596549981775456134607847347L,
-      0.1477621123573764350869464973256692L, 0.1477621123573764350869464973256692L,
-      0.1346333596549981775456134607847347L, 0.1095431812579910219977674671140816L,
-      0.0747256745752902965728881698288487L, 0.0333356721543440687967844049466659L },
-    { 0.0278342835580868332413768602212743L, 0.0627901847324523123173471496119701L,  // degree 11
-      0.0931451054638671257130488207158280L, 0.1165968822959952399592618524215876L,
-      0.1314022722551233310903444349452546L, 0.1364625433889503153572417641681711L,
-      0.1314022722551233310903444349452546L, 0.1165968822959952399592618524215876L,
-      0.0931451054638671257130488207158280L, 0.0627901847324523123173471496119701L,
-      0.0278342835580868332413768602212743L } };
-
-  MatrixType TminusI = T - MatrixType::Identity(T.rows(), T.rows());
-  result.setZero(T.rows(), T.rows());
-  for (int k = 0; k < degree; ++k) {
-    RealScalar weight = weights[degree-minPadeDegree][k];
-    RealScalar node = nodes[degree-minPadeDegree][k];
-    result += weight * (MatrixType::Identity(T.rows(), T.rows()) + node * TminusI)
-                       .template triangularView<Upper>().solve(TminusI);
-  }
-} 
-
-/** \brief Compute logarithm of triangular matrices with size > 2. 
-  * \details This uses a inverse scale-and-square algorithm. */
-template <typename MatrixType>
-void matrix_log_compute_big(const MatrixType& A, MatrixType& result)
-{
-  typedef typename MatrixType::Scalar Scalar;
-  typedef typename NumTraits<Scalar>::Real RealScalar;
-  using std::pow;
-
-  int numberOfSquareRoots = 0;
-  int numberOfExtraSquareRoots = 0;
-  int degree;
-  MatrixType T = A, sqrtT;
-
-  int maxPadeDegree = matrix_log_max_pade_degree<Scalar>::value;
-  const RealScalar maxNormForPade = maxPadeDegree<= 5? 5.3149729967117310e-1L:                    // single precision
-                                    maxPadeDegree<= 7? 2.6429608311114350e-1L:                    // double precision
-                                    maxPadeDegree<= 8? 2.32777776523703892094e-1L:                // extended precision
-                                    maxPadeDegree<=10? 1.05026503471351080481093652651105e-1L:    // double-double
-                                                       1.1880960220216759245467951592883642e-1L;  // quadruple precision
-
-  while (true) {
-    RealScalar normTminusI = (T - MatrixType::Identity(T.rows(), T.rows())).cwiseAbs().colwise().sum().maxCoeff();
-    if (normTminusI < maxNormForPade) {
-      degree = matrix_log_get_pade_degree(normTminusI);
-      int degree2 = matrix_log_get_pade_degree(normTminusI / RealScalar(2));
-      if ((degree - degree2 <= 1) || (numberOfExtraSquareRoots == 1)) 
-        break;
-      ++numberOfExtraSquareRoots;
-    }
-    matrix_sqrt_triangular(T, sqrtT);
-    T = sqrtT.template triangularView<Upper>();
-    ++numberOfSquareRoots;
-  }
-
-  matrix_log_compute_pade(result, T, degree);
-  result *= pow(RealScalar(2), numberOfSquareRoots);
-}
-
-/** \ingroup MatrixFunctions_Module
-  * \class MatrixLogarithmAtomic
-  * \brief Helper class for computing matrix logarithm of atomic matrices.
-  *
-  * Here, an atomic matrix is a triangular matrix whose diagonal entries are close to each other.
-  *
-  * \sa class MatrixFunctionAtomic, MatrixBase::log()
-  */
-template <typename MatrixType>
-class MatrixLogarithmAtomic
-{
-public:
-  /** \brief Compute matrix logarithm of atomic matrix
-    * \param[in]  A  argument of matrix logarithm, should be upper triangular and atomic
-    * \returns  The logarithm of \p A.
-    */
-  MatrixType compute(const MatrixType& A);
-};
-
-template <typename MatrixType>
-MatrixType MatrixLogarithmAtomic<MatrixType>::compute(const MatrixType& A)
-{
-  using std::log;
-  MatrixType result(A.rows(), A.rows());
-  if (A.rows() == 1)
-    result(0,0) = log(A(0,0));
-  else if (A.rows() == 2)
-    matrix_log_compute_2x2(A, result);
-  else
-    matrix_log_compute_big(A, result);
-  return result;
-}
-
-} // end of namespace internal
-
-/** \ingroup MatrixFunctions_Module
-  *
-  * \brief Proxy for the matrix logarithm of some matrix (expression).
-  *
-  * \tparam Derived  Type of the argument to the matrix function.
-  *
-  * This class holds the argument to the matrix function until it is
-  * assigned or evaluated for some other reason (so the argument
-  * should not be changed in the meantime). It is the return type of
-  * MatrixBase::log() and most of the time this is the only way it
-  * is used.
-  */
-template<typename Derived> class MatrixLogarithmReturnValue
-: public ReturnByValue<MatrixLogarithmReturnValue<Derived> >
-{
-public:
-  typedef typename Derived::Scalar Scalar;
-  typedef typename Derived::Index Index;
-
-protected:
-  typedef typename internal::ref_selector<Derived>::type DerivedNested;
-
-public:
-
-  /** \brief Constructor.
-    *
-    * \param[in]  A  %Matrix (expression) forming the argument of the matrix logarithm.
-    */
-  explicit MatrixLogarithmReturnValue(const Derived& A) : m_A(A) { }
-  
-  /** \brief Compute the matrix logarithm.
-    *
-    * \param[out]  result  Logarithm of \c A, where \c A is as specified in the constructor.
-    */
-  template <typename ResultType>
-  inline void evalTo(ResultType& result) const
-  {
-    typedef typename internal::nested_eval<Derived, 10>::type DerivedEvalType;
-    typedef typename internal::remove_all<DerivedEvalType>::type DerivedEvalTypeClean;
-    typedef internal::traits<DerivedEvalTypeClean> Traits;
-    static const int RowsAtCompileTime = Traits::RowsAtCompileTime;
-    static const int ColsAtCompileTime = Traits::ColsAtCompileTime;
-    typedef std::complex<typename NumTraits<Scalar>::Real> ComplexScalar;
-    typedef Matrix<ComplexScalar, Dynamic, Dynamic, 0, RowsAtCompileTime, ColsAtCompileTime> DynMatrixType;
-    typedef internal::MatrixLogarithmAtomic<DynMatrixType> AtomicType;
-    AtomicType atomic;
-    
-    internal::matrix_function_compute<typename DerivedEvalTypeClean::PlainObject>::run(m_A, atomic, result);
-  }
-
-  Index rows() const { return m_A.rows(); }
-  Index cols() const { return m_A.cols(); }
-  
-private:
-  const DerivedNested m_A;
-};
-
-namespace internal {
-  template<typename Derived>
-  struct traits<MatrixLogarithmReturnValue<Derived> >
-  {
-    typedef typename Derived::PlainObject ReturnType;
-  };
-}
-
-
-/********** MatrixBase method **********/
-
-
-template <typename Derived>
-const MatrixLogarithmReturnValue<Derived> MatrixBase<Derived>::log() const
-{
-  eigen_assert(rows() == cols());
-  return MatrixLogarithmReturnValue<Derived>(derived());
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_MATRIX_LOGARITHM
diff --git a/wpiutil/src/main/native/eigeninclude/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h b/wpiutil/src/main/native/eigeninclude/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h
deleted file mode 100644
index a3273da..0000000
--- a/wpiutil/src/main/native/eigeninclude/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h
+++ /dev/null
@@ -1,709 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2012, 2013 Chen-Pang He <jdh8@ms63.hinet.net>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_MATRIX_POWER
-#define EIGEN_MATRIX_POWER
-
-namespace Eigen {
-
-template<typename MatrixType> class MatrixPower;
-
-/**
- * \ingroup MatrixFunctions_Module
- *
- * \brief Proxy for the matrix power of some matrix.
- *
- * \tparam MatrixType  type of the base, a matrix.
- *
- * This class holds the arguments to the matrix power until it is
- * assigned or evaluated for some other reason (so the argument
- * should not be changed in the meantime). It is the return type of
- * MatrixPower::operator() and related functions and most of the
- * time this is the only way it is used.
- */
-/* TODO This class is only used by MatrixPower, so it should be nested
- * into MatrixPower, like MatrixPower::ReturnValue. However, my
- * compiler complained about unused template parameter in the
- * following declaration in namespace internal.
- *
- * template<typename MatrixType>
- * struct traits<MatrixPower<MatrixType>::ReturnValue>;
- */
-template<typename MatrixType>
-class MatrixPowerParenthesesReturnValue : public ReturnByValue< MatrixPowerParenthesesReturnValue<MatrixType> >
-{
-  public:
-    typedef typename MatrixType::RealScalar RealScalar;
-    typedef typename MatrixType::Index Index;
-
-    /**
-     * \brief Constructor.
-     *
-     * \param[in] pow  %MatrixPower storing the base.
-     * \param[in] p    scalar, the exponent of the matrix power.
-     */
-    MatrixPowerParenthesesReturnValue(MatrixPower<MatrixType>& pow, RealScalar p) : m_pow(pow), m_p(p)
-    { }
-
-    /**
-     * \brief Compute the matrix power.
-     *
-     * \param[out] result
-     */
-    template<typename ResultType>
-    inline void evalTo(ResultType& result) const
-    { m_pow.compute(result, m_p); }
-
-    Index rows() const { return m_pow.rows(); }
-    Index cols() const { return m_pow.cols(); }
-
-  private:
-    MatrixPower<MatrixType>& m_pow;
-    const RealScalar m_p;
-};
-
-/**
- * \ingroup MatrixFunctions_Module
- *
- * \brief Class for computing matrix powers.
- *
- * \tparam MatrixType  type of the base, expected to be an instantiation
- * of the Matrix class template.
- *
- * This class is capable of computing triangular real/complex matrices
- * raised to a power in the interval \f$ (-1, 1) \f$.
- *
- * \note Currently this class is only used by MatrixPower. One may
- * insist that this be nested into MatrixPower. This class is here to
- * faciliate future development of triangular matrix functions.
- */
-template<typename MatrixType>
-class MatrixPowerAtomic : internal::noncopyable
-{
-  private:
-    enum {
-      RowsAtCompileTime = MatrixType::RowsAtCompileTime,
-      MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime
-    };
-    typedef typename MatrixType::Scalar Scalar;
-    typedef typename MatrixType::RealScalar RealScalar;
-    typedef std::complex<RealScalar> ComplexScalar;
-    typedef typename MatrixType::Index Index;
-    typedef Block<MatrixType,Dynamic,Dynamic> ResultType;
-
-    const MatrixType& m_A;
-    RealScalar m_p;
-
-    void computePade(int degree, const MatrixType& IminusT, ResultType& res) const;
-    void compute2x2(ResultType& res, RealScalar p) const;
-    void computeBig(ResultType& res) const;
-    static int getPadeDegree(float normIminusT);
-    static int getPadeDegree(double normIminusT);
-    static int getPadeDegree(long double normIminusT);
-    static ComplexScalar computeSuperDiag(const ComplexScalar&, const ComplexScalar&, RealScalar p);
-    static RealScalar computeSuperDiag(RealScalar, RealScalar, RealScalar p);
-
-  public:
-    /**
-     * \brief Constructor.
-     *
-     * \param[in] T  the base of the matrix power.
-     * \param[in] p  the exponent of the matrix power, should be in
-     * \f$ (-1, 1) \f$.
-     *
-     * The class stores a reference to T, so it should not be changed
-     * (or destroyed) before evaluation. Only the upper triangular
-     * part of T is read.
-     */
-    MatrixPowerAtomic(const MatrixType& T, RealScalar p);
-    
-    /**
-     * \brief Compute the matrix power.
-     *
-     * \param[out] res  \f$ A^p \f$ where A and p are specified in the
-     * constructor.
-     */
-    void compute(ResultType& res) const;
-};
-
-template<typename MatrixType>
-MatrixPowerAtomic<MatrixType>::MatrixPowerAtomic(const MatrixType& T, RealScalar p) :
-  m_A(T), m_p(p)
-{
-  eigen_assert(T.rows() == T.cols());
-  eigen_assert(p > -1 && p < 1);
-}
-
-template<typename MatrixType>
-void MatrixPowerAtomic<MatrixType>::compute(ResultType& res) const
-{
-  using std::pow;
-  switch (m_A.rows()) {
-    case 0:
-      break;
-    case 1:
-      res(0,0) = pow(m_A(0,0), m_p);
-      break;
-    case 2:
-      compute2x2(res, m_p);
-      break;
-    default:
-      computeBig(res);
-  }
-}
-
-template<typename MatrixType>
-void MatrixPowerAtomic<MatrixType>::computePade(int degree, const MatrixType& IminusT, ResultType& res) const
-{
-  int i = 2*degree;
-  res = (m_p-degree) / (2*i-2) * IminusT;
-
-  for (--i; i; --i) {
-    res = (MatrixType::Identity(IminusT.rows(), IminusT.cols()) + res).template triangularView<Upper>()
-	.solve((i==1 ? -m_p : i&1 ? (-m_p-i/2)/(2*i) : (m_p-i/2)/(2*i-2)) * IminusT).eval();
-  }
-  res += MatrixType::Identity(IminusT.rows(), IminusT.cols());
-}
-
-// This function assumes that res has the correct size (see bug 614)
-template<typename MatrixType>
-void MatrixPowerAtomic<MatrixType>::compute2x2(ResultType& res, RealScalar p) const
-{
-  using std::abs;
-  using std::pow;
-  res.coeffRef(0,0) = pow(m_A.coeff(0,0), p);
-
-  for (Index i=1; i < m_A.cols(); ++i) {
-    res.coeffRef(i,i) = pow(m_A.coeff(i,i), p);
-    if (m_A.coeff(i-1,i-1) == m_A.coeff(i,i))
-      res.coeffRef(i-1,i) = p * pow(m_A.coeff(i,i), p-1);
-    else if (2*abs(m_A.coeff(i-1,i-1)) < abs(m_A.coeff(i,i)) || 2*abs(m_A.coeff(i,i)) < abs(m_A.coeff(i-1,i-1)))
-      res.coeffRef(i-1,i) = (res.coeff(i,i)-res.coeff(i-1,i-1)) / (m_A.coeff(i,i)-m_A.coeff(i-1,i-1));
-    else
-      res.coeffRef(i-1,i) = computeSuperDiag(m_A.coeff(i,i), m_A.coeff(i-1,i-1), p);
-    res.coeffRef(i-1,i) *= m_A.coeff(i-1,i);
-  }
-}
-
-template<typename MatrixType>
-void MatrixPowerAtomic<MatrixType>::computeBig(ResultType& res) const
-{
-  using std::ldexp;
-  const int digits = std::numeric_limits<RealScalar>::digits;
-  const RealScalar maxNormForPade = digits <=  24? 4.3386528e-1L                            // single precision
-                                  : digits <=  53? 2.789358995219730e-1L                    // double precision
-                                  : digits <=  64? 2.4471944416607995472e-1L                // extended precision
-                                  : digits <= 106? 1.1016843812851143391275867258512e-1L    // double-double
-                                  :                9.134603732914548552537150753385375e-2L; // quadruple precision
-  MatrixType IminusT, sqrtT, T = m_A.template triangularView<Upper>();
-  RealScalar normIminusT;
-  int degree, degree2, numberOfSquareRoots = 0;
-  bool hasExtraSquareRoot = false;
-
-  for (Index i=0; i < m_A.cols(); ++i)
-    eigen_assert(m_A(i,i) != RealScalar(0));
-
-  while (true) {
-    IminusT = MatrixType::Identity(m_A.rows(), m_A.cols()) - T;
-    normIminusT = IminusT.cwiseAbs().colwise().sum().maxCoeff();
-    if (normIminusT < maxNormForPade) {
-      degree = getPadeDegree(normIminusT);
-      degree2 = getPadeDegree(normIminusT/2);
-      if (degree - degree2 <= 1 || hasExtraSquareRoot)
-	break;
-      hasExtraSquareRoot = true;
-    }
-    matrix_sqrt_triangular(T, sqrtT);
-    T = sqrtT.template triangularView<Upper>();
-    ++numberOfSquareRoots;
-  }
-  computePade(degree, IminusT, res);
-
-  for (; numberOfSquareRoots; --numberOfSquareRoots) {
-    compute2x2(res, ldexp(m_p, -numberOfSquareRoots));
-    res = res.template triangularView<Upper>() * res;
-  }
-  compute2x2(res, m_p);
-}
-  
-template<typename MatrixType>
-inline int MatrixPowerAtomic<MatrixType>::getPadeDegree(float normIminusT)
-{
-  const float maxNormForPade[] = { 2.8064004e-1f /* degree = 3 */ , 4.3386528e-1f };
-  int degree = 3;
-  for (; degree <= 4; ++degree)
-    if (normIminusT <= maxNormForPade[degree - 3])
-      break;
-  return degree;
-}
-
-template<typename MatrixType>
-inline int MatrixPowerAtomic<MatrixType>::getPadeDegree(double normIminusT)
-{
-  const double maxNormForPade[] = { 1.884160592658218e-2 /* degree = 3 */ , 6.038881904059573e-2, 1.239917516308172e-1,
-      1.999045567181744e-1, 2.789358995219730e-1 };
-  int degree = 3;
-  for (; degree <= 7; ++degree)
-    if (normIminusT <= maxNormForPade[degree - 3])
-      break;
-  return degree;
-}
-
-template<typename MatrixType>
-inline int MatrixPowerAtomic<MatrixType>::getPadeDegree(long double normIminusT)
-{
-#if   LDBL_MANT_DIG == 53
-  const int maxPadeDegree = 7;
-  const double maxNormForPade[] = { 1.884160592658218e-2L /* degree = 3 */ , 6.038881904059573e-2L, 1.239917516308172e-1L,
-      1.999045567181744e-1L, 2.789358995219730e-1L };
-#elif LDBL_MANT_DIG <= 64
-  const int maxPadeDegree = 8;
-  const long double maxNormForPade[] = { 6.3854693117491799460e-3L /* degree = 3 */ , 2.6394893435456973676e-2L,
-      6.4216043030404063729e-2L, 1.1701165502926694307e-1L, 1.7904284231268670284e-1L, 2.4471944416607995472e-1L };
-#elif LDBL_MANT_DIG <= 106
-  const int maxPadeDegree = 10;
-  const double maxNormForPade[] = { 1.0007161601787493236741409687186e-4L /* degree = 3 */ ,
-      1.0007161601787493236741409687186e-3L, 4.7069769360887572939882574746264e-3L, 1.3220386624169159689406653101695e-2L,
-      2.8063482381631737920612944054906e-2L, 4.9625993951953473052385361085058e-2L, 7.7367040706027886224557538328171e-2L,
-      1.1016843812851143391275867258512e-1L };
-#else
-  const int maxPadeDegree = 10;
-  const double maxNormForPade[] = { 5.524506147036624377378713555116378e-5L /* degree = 3 */ ,
-      6.640600568157479679823602193345995e-4L, 3.227716520106894279249709728084626e-3L,
-      9.619593944683432960546978734646284e-3L, 2.134595382433742403911124458161147e-2L,
-      3.908166513900489428442993794761185e-2L, 6.266780814639442865832535460550138e-2L,
-      9.134603732914548552537150753385375e-2L };
-#endif
-  int degree = 3;
-  for (; degree <= maxPadeDegree; ++degree)
-    if (normIminusT <= maxNormForPade[degree - 3])
-      break;
-  return degree;
-}
-
-template<typename MatrixType>
-inline typename MatrixPowerAtomic<MatrixType>::ComplexScalar
-MatrixPowerAtomic<MatrixType>::computeSuperDiag(const ComplexScalar& curr, const ComplexScalar& prev, RealScalar p)
-{
-  using std::ceil;
-  using std::exp;
-  using std::log;
-  using std::sinh;
-
-  ComplexScalar logCurr = log(curr);
-  ComplexScalar logPrev = log(prev);
-  int unwindingNumber = ceil((numext::imag(logCurr - logPrev) - RealScalar(EIGEN_PI)) / RealScalar(2*EIGEN_PI));
-  ComplexScalar w = numext::log1p((curr-prev)/prev)/RealScalar(2) + ComplexScalar(0, EIGEN_PI*unwindingNumber);
-  return RealScalar(2) * exp(RealScalar(0.5) * p * (logCurr + logPrev)) * sinh(p * w) / (curr - prev);
-}
-
-template<typename MatrixType>
-inline typename MatrixPowerAtomic<MatrixType>::RealScalar
-MatrixPowerAtomic<MatrixType>::computeSuperDiag(RealScalar curr, RealScalar prev, RealScalar p)
-{
-  using std::exp;
-  using std::log;
-  using std::sinh;
-
-  RealScalar w = numext::log1p((curr-prev)/prev)/RealScalar(2);
-  return 2 * exp(p * (log(curr) + log(prev)) / 2) * sinh(p * w) / (curr - prev);
-}
-
-/**
- * \ingroup MatrixFunctions_Module
- *
- * \brief Class for computing matrix powers.
- *
- * \tparam MatrixType  type of the base, expected to be an instantiation
- * of the Matrix class template.
- *
- * This class is capable of computing real/complex matrices raised to
- * an arbitrary real power. Meanwhile, it saves the result of Schur
- * decomposition if an non-integral power has even been calculated.
- * Therefore, if you want to compute multiple (>= 2) matrix powers
- * for the same matrix, using the class directly is more efficient than
- * calling MatrixBase::pow().
- *
- * Example:
- * \include MatrixPower_optimal.cpp
- * Output: \verbinclude MatrixPower_optimal.out
- */
-template<typename MatrixType>
-class MatrixPower : internal::noncopyable
-{
-  private:
-    typedef typename MatrixType::Scalar Scalar;
-    typedef typename MatrixType::RealScalar RealScalar;
-    typedef typename MatrixType::Index Index;
-
-  public:
-    /**
-     * \brief Constructor.
-     *
-     * \param[in] A  the base of the matrix power.
-     *
-     * The class stores a reference to A, so it should not be changed
-     * (or destroyed) before evaluation.
-     */
-    explicit MatrixPower(const MatrixType& A) :
-      m_A(A),
-      m_conditionNumber(0),
-      m_rank(A.cols()),
-      m_nulls(0)
-    { eigen_assert(A.rows() == A.cols()); }
-
-    /**
-     * \brief Returns the matrix power.
-     *
-     * \param[in] p  exponent, a real scalar.
-     * \return The expression \f$ A^p \f$, where A is specified in the
-     * constructor.
-     */
-    const MatrixPowerParenthesesReturnValue<MatrixType> operator()(RealScalar p)
-    { return MatrixPowerParenthesesReturnValue<MatrixType>(*this, p); }
-
-    /**
-     * \brief Compute the matrix power.
-     *
-     * \param[in]  p    exponent, a real scalar.
-     * \param[out] res  \f$ A^p \f$ where A is specified in the
-     * constructor.
-     */
-    template<typename ResultType>
-    void compute(ResultType& res, RealScalar p);
-    
-    Index rows() const { return m_A.rows(); }
-    Index cols() const { return m_A.cols(); }
-
-  private:
-    typedef std::complex<RealScalar> ComplexScalar;
-    typedef Matrix<ComplexScalar, Dynamic, Dynamic, 0,
-              MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime> ComplexMatrix;
-
-    /** \brief Reference to the base of matrix power. */
-    typename MatrixType::Nested m_A;
-
-    /** \brief Temporary storage. */
-    MatrixType m_tmp;
-
-    /** \brief Store the result of Schur decomposition. */
-    ComplexMatrix m_T, m_U;
-    
-    /** \brief Store fractional power of m_T. */
-    ComplexMatrix m_fT;
-
-    /**
-     * \brief Condition number of m_A.
-     *
-     * It is initialized as 0 to avoid performing unnecessary Schur
-     * decomposition, which is the bottleneck.
-     */
-    RealScalar m_conditionNumber;
-
-    /** \brief Rank of m_A. */
-    Index m_rank;
-    
-    /** \brief Rank deficiency of m_A. */
-    Index m_nulls;
-
-    /**
-     * \brief Split p into integral part and fractional part.
-     *
-     * \param[in]  p        The exponent.
-     * \param[out] p        The fractional part ranging in \f$ (-1, 1) \f$.
-     * \param[out] intpart  The integral part.
-     *
-     * Only if the fractional part is nonzero, it calls initialize().
-     */
-    void split(RealScalar& p, RealScalar& intpart);
-
-    /** \brief Perform Schur decomposition for fractional power. */
-    void initialize();
-
-    template<typename ResultType>
-    void computeIntPower(ResultType& res, RealScalar p);
-
-    template<typename ResultType>
-    void computeFracPower(ResultType& res, RealScalar p);
-
-    template<int Rows, int Cols, int Options, int MaxRows, int MaxCols>
-    static void revertSchur(
-        Matrix<ComplexScalar, Rows, Cols, Options, MaxRows, MaxCols>& res,
-        const ComplexMatrix& T,
-        const ComplexMatrix& U);
-
-    template<int Rows, int Cols, int Options, int MaxRows, int MaxCols>
-    static void revertSchur(
-        Matrix<RealScalar, Rows, Cols, Options, MaxRows, MaxCols>& res,
-        const ComplexMatrix& T,
-        const ComplexMatrix& U);
-};
-
-template<typename MatrixType>
-template<typename ResultType>
-void MatrixPower<MatrixType>::compute(ResultType& res, RealScalar p)
-{
-  using std::pow;
-  switch (cols()) {
-    case 0:
-      break;
-    case 1:
-      res(0,0) = pow(m_A.coeff(0,0), p);
-      break;
-    default:
-      RealScalar intpart;
-      split(p, intpart);
-
-      res = MatrixType::Identity(rows(), cols());
-      computeIntPower(res, intpart);
-      if (p) computeFracPower(res, p);
-  }
-}
-
-template<typename MatrixType>
-void MatrixPower<MatrixType>::split(RealScalar& p, RealScalar& intpart)
-{
-  using std::floor;
-  using std::pow;
-
-  intpart = floor(p);
-  p -= intpart;
-
-  // Perform Schur decomposition if it is not yet performed and the power is
-  // not an integer.
-  if (!m_conditionNumber && p)
-    initialize();
-
-  // Choose the more stable of intpart = floor(p) and intpart = ceil(p).
-  if (p > RealScalar(0.5) && p > (1-p) * pow(m_conditionNumber, p)) {
-    --p;
-    ++intpart;
-  }
-}
-
-template<typename MatrixType>
-void MatrixPower<MatrixType>::initialize()
-{
-  const ComplexSchur<MatrixType> schurOfA(m_A);
-  JacobiRotation<ComplexScalar> rot;
-  ComplexScalar eigenvalue;
-
-  m_fT.resizeLike(m_A);
-  m_T = schurOfA.matrixT();
-  m_U = schurOfA.matrixU();
-  m_conditionNumber = m_T.diagonal().array().abs().maxCoeff() / m_T.diagonal().array().abs().minCoeff();
-
-  // Move zero eigenvalues to the bottom right corner.
-  for (Index i = cols()-1; i>=0; --i) {
-    if (m_rank <= 2)
-      return;
-    if (m_T.coeff(i,i) == RealScalar(0)) {
-      for (Index j=i+1; j < m_rank; ++j) {
-        eigenvalue = m_T.coeff(j,j);
-        rot.makeGivens(m_T.coeff(j-1,j), eigenvalue);
-        m_T.applyOnTheRight(j-1, j, rot);
-        m_T.applyOnTheLeft(j-1, j, rot.adjoint());
-        m_T.coeffRef(j-1,j-1) = eigenvalue;
-        m_T.coeffRef(j,j) = RealScalar(0);
-        m_U.applyOnTheRight(j-1, j, rot);
-      }
-      --m_rank;
-    }
-  }
-
-  m_nulls = rows() - m_rank;
-  if (m_nulls) {
-    eigen_assert(m_T.bottomRightCorner(m_nulls, m_nulls).isZero()
-        && "Base of matrix power should be invertible or with a semisimple zero eigenvalue.");
-    m_fT.bottomRows(m_nulls).fill(RealScalar(0));
-  }
-}
-
-template<typename MatrixType>
-template<typename ResultType>
-void MatrixPower<MatrixType>::computeIntPower(ResultType& res, RealScalar p)
-{
-  using std::abs;
-  using std::fmod;
-  RealScalar pp = abs(p);
-
-  if (p<0) 
-    m_tmp = m_A.inverse();
-  else     
-    m_tmp = m_A;
-
-  while (true) {
-    if (fmod(pp, 2) >= 1)
-      res = m_tmp * res;
-    pp /= 2;
-    if (pp < 1)
-      break;
-    m_tmp *= m_tmp;
-  }
-}
-
-template<typename MatrixType>
-template<typename ResultType>
-void MatrixPower<MatrixType>::computeFracPower(ResultType& res, RealScalar p)
-{
-  Block<ComplexMatrix,Dynamic,Dynamic> blockTp(m_fT, 0, 0, m_rank, m_rank);
-  eigen_assert(m_conditionNumber);
-  eigen_assert(m_rank + m_nulls == rows());
-
-  MatrixPowerAtomic<ComplexMatrix>(m_T.topLeftCorner(m_rank, m_rank), p).compute(blockTp);
-  if (m_nulls) {
-    m_fT.topRightCorner(m_rank, m_nulls) = m_T.topLeftCorner(m_rank, m_rank).template triangularView<Upper>()
-        .solve(blockTp * m_T.topRightCorner(m_rank, m_nulls));
-  }
-  revertSchur(m_tmp, m_fT, m_U);
-  res = m_tmp * res;
-}
-
-template<typename MatrixType>
-template<int Rows, int Cols, int Options, int MaxRows, int MaxCols>
-inline void MatrixPower<MatrixType>::revertSchur(
-    Matrix<ComplexScalar, Rows, Cols, Options, MaxRows, MaxCols>& res,
-    const ComplexMatrix& T,
-    const ComplexMatrix& U)
-{ res.noalias() = U * (T.template triangularView<Upper>() * U.adjoint()); }
-
-template<typename MatrixType>
-template<int Rows, int Cols, int Options, int MaxRows, int MaxCols>
-inline void MatrixPower<MatrixType>::revertSchur(
-    Matrix<RealScalar, Rows, Cols, Options, MaxRows, MaxCols>& res,
-    const ComplexMatrix& T,
-    const ComplexMatrix& U)
-{ res.noalias() = (U * (T.template triangularView<Upper>() * U.adjoint())).real(); }
-
-/**
- * \ingroup MatrixFunctions_Module
- *
- * \brief Proxy for the matrix power of some matrix (expression).
- *
- * \tparam Derived  type of the base, a matrix (expression).
- *
- * This class holds the arguments to the matrix power until it is
- * assigned or evaluated for some other reason (so the argument
- * should not be changed in the meantime). It is the return type of
- * MatrixBase::pow() and related functions and most of the
- * time this is the only way it is used.
- */
-template<typename Derived>
-class MatrixPowerReturnValue : public ReturnByValue< MatrixPowerReturnValue<Derived> >
-{
-  public:
-    typedef typename Derived::PlainObject PlainObject;
-    typedef typename Derived::RealScalar RealScalar;
-    typedef typename Derived::Index Index;
-
-    /**
-     * \brief Constructor.
-     *
-     * \param[in] A  %Matrix (expression), the base of the matrix power.
-     * \param[in] p  real scalar, the exponent of the matrix power.
-     */
-    MatrixPowerReturnValue(const Derived& A, RealScalar p) : m_A(A), m_p(p)
-    { }
-
-    /**
-     * \brief Compute the matrix power.
-     *
-     * \param[out] result  \f$ A^p \f$ where \p A and \p p are as in the
-     * constructor.
-     */
-    template<typename ResultType>
-    inline void evalTo(ResultType& result) const
-    { MatrixPower<PlainObject>(m_A.eval()).compute(result, m_p); }
-
-    Index rows() const { return m_A.rows(); }
-    Index cols() const { return m_A.cols(); }
-
-  private:
-    const Derived& m_A;
-    const RealScalar m_p;
-};
-
-/**
- * \ingroup MatrixFunctions_Module
- *
- * \brief Proxy for the matrix power of some matrix (expression).
- *
- * \tparam Derived  type of the base, a matrix (expression).
- *
- * This class holds the arguments to the matrix power until it is
- * assigned or evaluated for some other reason (so the argument
- * should not be changed in the meantime). It is the return type of
- * MatrixBase::pow() and related functions and most of the
- * time this is the only way it is used.
- */
-template<typename Derived>
-class MatrixComplexPowerReturnValue : public ReturnByValue< MatrixComplexPowerReturnValue<Derived> >
-{
-  public:
-    typedef typename Derived::PlainObject PlainObject;
-    typedef typename std::complex<typename Derived::RealScalar> ComplexScalar;
-    typedef typename Derived::Index Index;
-
-    /**
-     * \brief Constructor.
-     *
-     * \param[in] A  %Matrix (expression), the base of the matrix power.
-     * \param[in] p  complex scalar, the exponent of the matrix power.
-     */
-    MatrixComplexPowerReturnValue(const Derived& A, const ComplexScalar& p) : m_A(A), m_p(p)
-    { }
-
-    /**
-     * \brief Compute the matrix power.
-     *
-     * Because \p p is complex, \f$ A^p \f$ is simply evaluated as \f$
-     * \exp(p \log(A)) \f$.
-     *
-     * \param[out] result  \f$ A^p \f$ where \p A and \p p are as in the
-     * constructor.
-     */
-    template<typename ResultType>
-    inline void evalTo(ResultType& result) const
-    { result = (m_p * m_A.log()).exp(); }
-
-    Index rows() const { return m_A.rows(); }
-    Index cols() const { return m_A.cols(); }
-
-  private:
-    const Derived& m_A;
-    const ComplexScalar m_p;
-};
-
-namespace internal {
-
-template<typename MatrixPowerType>
-struct traits< MatrixPowerParenthesesReturnValue<MatrixPowerType> >
-{ typedef typename MatrixPowerType::PlainObject ReturnType; };
-
-template<typename Derived>
-struct traits< MatrixPowerReturnValue<Derived> >
-{ typedef typename Derived::PlainObject ReturnType; };
-
-template<typename Derived>
-struct traits< MatrixComplexPowerReturnValue<Derived> >
-{ typedef typename Derived::PlainObject ReturnType; };
-
-}
-
-template<typename Derived>
-const MatrixPowerReturnValue<Derived> MatrixBase<Derived>::pow(const RealScalar& p) const
-{ return MatrixPowerReturnValue<Derived>(derived(), p); }
-
-template<typename Derived>
-const MatrixComplexPowerReturnValue<Derived> MatrixBase<Derived>::pow(const std::complex<RealScalar>& p) const
-{ return MatrixComplexPowerReturnValue<Derived>(derived(), p); }
-
-} // namespace Eigen
-
-#endif // EIGEN_MATRIX_POWER
diff --git a/wpiutil/src/main/native/eigeninclude/unsupported/Eigen/src/MatrixFunctions/MatrixSquareRoot.h b/wpiutil/src/main/native/eigeninclude/unsupported/Eigen/src/MatrixFunctions/MatrixSquareRoot.h
deleted file mode 100644
index 2e5abda..0000000
--- a/wpiutil/src/main/native/eigeninclude/unsupported/Eigen/src/MatrixFunctions/MatrixSquareRoot.h
+++ /dev/null
@@ -1,366 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2011, 2013 Jitse Niesen <jitse@maths.leeds.ac.uk>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_MATRIX_SQUARE_ROOT
-#define EIGEN_MATRIX_SQUARE_ROOT
-
-namespace Eigen { 
-
-namespace internal {
-
-// pre:  T.block(i,i,2,2) has complex conjugate eigenvalues
-// post: sqrtT.block(i,i,2,2) is square root of T.block(i,i,2,2)
-template <typename MatrixType, typename ResultType>
-void matrix_sqrt_quasi_triangular_2x2_diagonal_block(const MatrixType& T, typename MatrixType::Index i, ResultType& sqrtT)
-{
-  // TODO: This case (2-by-2 blocks with complex conjugate eigenvalues) is probably hidden somewhere
-  //       in EigenSolver. If we expose it, we could call it directly from here.
-  typedef typename traits<MatrixType>::Scalar Scalar;
-  Matrix<Scalar,2,2> block = T.template block<2,2>(i,i);
-  EigenSolver<Matrix<Scalar,2,2> > es(block);
-  sqrtT.template block<2,2>(i,i)
-    = (es.eigenvectors() * es.eigenvalues().cwiseSqrt().asDiagonal() * es.eigenvectors().inverse()).real();
-}
-
-// pre:  block structure of T is such that (i,j) is a 1x1 block,
-//       all blocks of sqrtT to left of and below (i,j) are correct
-// post: sqrtT(i,j) has the correct value
-template <typename MatrixType, typename ResultType>
-void matrix_sqrt_quasi_triangular_1x1_off_diagonal_block(const MatrixType& T, typename MatrixType::Index i, typename MatrixType::Index j, ResultType& sqrtT)
-{
-  typedef typename traits<MatrixType>::Scalar Scalar;
-  Scalar tmp = (sqrtT.row(i).segment(i+1,j-i-1) * sqrtT.col(j).segment(i+1,j-i-1)).value();
-  sqrtT.coeffRef(i,j) = (T.coeff(i,j) - tmp) / (sqrtT.coeff(i,i) + sqrtT.coeff(j,j));
-}
-
-// similar to compute1x1offDiagonalBlock()
-template <typename MatrixType, typename ResultType>
-void matrix_sqrt_quasi_triangular_1x2_off_diagonal_block(const MatrixType& T, typename MatrixType::Index i, typename MatrixType::Index j, ResultType& sqrtT)
-{
-  typedef typename traits<MatrixType>::Scalar Scalar;
-  Matrix<Scalar,1,2> rhs = T.template block<1,2>(i,j);
-  if (j-i > 1)
-    rhs -= sqrtT.block(i, i+1, 1, j-i-1) * sqrtT.block(i+1, j, j-i-1, 2);
-  Matrix<Scalar,2,2> A = sqrtT.coeff(i,i) * Matrix<Scalar,2,2>::Identity();
-  A += sqrtT.template block<2,2>(j,j).transpose();
-  sqrtT.template block<1,2>(i,j).transpose() = A.fullPivLu().solve(rhs.transpose());
-}
-
-// similar to compute1x1offDiagonalBlock()
-template <typename MatrixType, typename ResultType>
-void matrix_sqrt_quasi_triangular_2x1_off_diagonal_block(const MatrixType& T, typename MatrixType::Index i, typename MatrixType::Index j, ResultType& sqrtT)
-{
-  typedef typename traits<MatrixType>::Scalar Scalar;
-  Matrix<Scalar,2,1> rhs = T.template block<2,1>(i,j);
-  if (j-i > 2)
-    rhs -= sqrtT.block(i, i+2, 2, j-i-2) * sqrtT.block(i+2, j, j-i-2, 1);
-  Matrix<Scalar,2,2> A = sqrtT.coeff(j,j) * Matrix<Scalar,2,2>::Identity();
-  A += sqrtT.template block<2,2>(i,i);
-  sqrtT.template block<2,1>(i,j) = A.fullPivLu().solve(rhs);
-}
-
-// solves the equation A X + X B = C where all matrices are 2-by-2
-template <typename MatrixType>
-void matrix_sqrt_quasi_triangular_solve_auxiliary_equation(MatrixType& X, const MatrixType& A, const MatrixType& B, const MatrixType& C)
-{
-  typedef typename traits<MatrixType>::Scalar Scalar;
-  Matrix<Scalar,4,4> coeffMatrix = Matrix<Scalar,4,4>::Zero();
-  coeffMatrix.coeffRef(0,0) = A.coeff(0,0) + B.coeff(0,0);
-  coeffMatrix.coeffRef(1,1) = A.coeff(0,0) + B.coeff(1,1);
-  coeffMatrix.coeffRef(2,2) = A.coeff(1,1) + B.coeff(0,0);
-  coeffMatrix.coeffRef(3,3) = A.coeff(1,1) + B.coeff(1,1);
-  coeffMatrix.coeffRef(0,1) = B.coeff(1,0);
-  coeffMatrix.coeffRef(0,2) = A.coeff(0,1);
-  coeffMatrix.coeffRef(1,0) = B.coeff(0,1);
-  coeffMatrix.coeffRef(1,3) = A.coeff(0,1);
-  coeffMatrix.coeffRef(2,0) = A.coeff(1,0);
-  coeffMatrix.coeffRef(2,3) = B.coeff(1,0);
-  coeffMatrix.coeffRef(3,1) = A.coeff(1,0);
-  coeffMatrix.coeffRef(3,2) = B.coeff(0,1);
-
-  Matrix<Scalar,4,1> rhs;
-  rhs.coeffRef(0) = C.coeff(0,0);
-  rhs.coeffRef(1) = C.coeff(0,1);
-  rhs.coeffRef(2) = C.coeff(1,0);
-  rhs.coeffRef(3) = C.coeff(1,1);
-
-  Matrix<Scalar,4,1> result;
-  result = coeffMatrix.fullPivLu().solve(rhs);
-
-  X.coeffRef(0,0) = result.coeff(0);
-  X.coeffRef(0,1) = result.coeff(1);
-  X.coeffRef(1,0) = result.coeff(2);
-  X.coeffRef(1,1) = result.coeff(3);
-}
-
-// similar to compute1x1offDiagonalBlock()
-template <typename MatrixType, typename ResultType>
-void matrix_sqrt_quasi_triangular_2x2_off_diagonal_block(const MatrixType& T, typename MatrixType::Index i, typename MatrixType::Index j, ResultType& sqrtT)
-{
-  typedef typename traits<MatrixType>::Scalar Scalar;
-  Matrix<Scalar,2,2> A = sqrtT.template block<2,2>(i,i);
-  Matrix<Scalar,2,2> B = sqrtT.template block<2,2>(j,j);
-  Matrix<Scalar,2,2> C = T.template block<2,2>(i,j);
-  if (j-i > 2)
-    C -= sqrtT.block(i, i+2, 2, j-i-2) * sqrtT.block(i+2, j, j-i-2, 2);
-  Matrix<Scalar,2,2> X;
-  matrix_sqrt_quasi_triangular_solve_auxiliary_equation(X, A, B, C);
-  sqrtT.template block<2,2>(i,j) = X;
-}
-
-// pre:  T is quasi-upper-triangular and sqrtT is a zero matrix of the same size
-// post: the diagonal blocks of sqrtT are the square roots of the diagonal blocks of T
-template <typename MatrixType, typename ResultType>
-void matrix_sqrt_quasi_triangular_diagonal(const MatrixType& T, ResultType& sqrtT)
-{
-  using std::sqrt;
-  const Index size = T.rows();
-  for (Index i = 0; i < size; i++) {
-    if (i == size - 1 || T.coeff(i+1, i) == 0) {
-      eigen_assert(T(i,i) >= 0);
-      sqrtT.coeffRef(i,i) = sqrt(T.coeff(i,i));
-    }
-    else {
-      matrix_sqrt_quasi_triangular_2x2_diagonal_block(T, i, sqrtT);
-      ++i;
-    }
-  }
-}
-
-// pre:  T is quasi-upper-triangular and diagonal blocks of sqrtT are square root of diagonal blocks of T.
-// post: sqrtT is the square root of T.
-template <typename MatrixType, typename ResultType>
-void matrix_sqrt_quasi_triangular_off_diagonal(const MatrixType& T, ResultType& sqrtT)
-{
-  const Index size = T.rows();
-  for (Index j = 1; j < size; j++) {
-      if (T.coeff(j, j-1) != 0)  // if T(j-1:j, j-1:j) is a 2-by-2 block
-	continue;
-    for (Index i = j-1; i >= 0; i--) {
-      if (i > 0 && T.coeff(i, i-1) != 0)  // if T(i-1:i, i-1:i) is a 2-by-2 block
-	continue;
-      bool iBlockIs2x2 = (i < size - 1) && (T.coeff(i+1, i) != 0);
-      bool jBlockIs2x2 = (j < size - 1) && (T.coeff(j+1, j) != 0);
-      if (iBlockIs2x2 && jBlockIs2x2) 
-        matrix_sqrt_quasi_triangular_2x2_off_diagonal_block(T, i, j, sqrtT);
-      else if (iBlockIs2x2 && !jBlockIs2x2) 
-        matrix_sqrt_quasi_triangular_2x1_off_diagonal_block(T, i, j, sqrtT);
-      else if (!iBlockIs2x2 && jBlockIs2x2) 
-        matrix_sqrt_quasi_triangular_1x2_off_diagonal_block(T, i, j, sqrtT);
-      else if (!iBlockIs2x2 && !jBlockIs2x2) 
-        matrix_sqrt_quasi_triangular_1x1_off_diagonal_block(T, i, j, sqrtT);
-    }
-  }
-}
-
-} // end of namespace internal
-
-/** \ingroup MatrixFunctions_Module
-  * \brief Compute matrix square root of quasi-triangular matrix.
-  *
-  * \tparam  MatrixType  type of \p arg, the argument of matrix square root,
-  *                      expected to be an instantiation of the Matrix class template.
-  * \tparam  ResultType  type of \p result, where result is to be stored.
-  * \param[in]  arg      argument of matrix square root.
-  * \param[out] result   matrix square root of upper Hessenberg part of \p arg.
-  *
-  * This function computes the square root of the upper quasi-triangular matrix stored in the upper
-  * Hessenberg part of \p arg.  Only the upper Hessenberg part of \p result is updated, the rest is
-  * not touched.  See MatrixBase::sqrt() for details on how this computation is implemented.
-  *
-  * \sa MatrixSquareRoot, MatrixSquareRootQuasiTriangular
-  */
-template <typename MatrixType, typename ResultType> 
-void matrix_sqrt_quasi_triangular(const MatrixType &arg, ResultType &result)
-{
-  eigen_assert(arg.rows() == arg.cols());
-  result.resize(arg.rows(), arg.cols());
-  internal::matrix_sqrt_quasi_triangular_diagonal(arg, result);
-  internal::matrix_sqrt_quasi_triangular_off_diagonal(arg, result);
-}
-
-
-/** \ingroup MatrixFunctions_Module
-  * \brief Compute matrix square root of triangular matrix.
-  *
-  * \tparam  MatrixType  type of \p arg, the argument of matrix square root,
-  *                      expected to be an instantiation of the Matrix class template.
-  * \tparam  ResultType  type of \p result, where result is to be stored.
-  * \param[in]  arg      argument of matrix square root.
-  * \param[out] result   matrix square root of upper triangular part of \p arg.
-  *
-  * Only the upper triangular part (including the diagonal) of \p result is updated, the rest is not
-  * touched.  See MatrixBase::sqrt() for details on how this computation is implemented.
-  *
-  * \sa MatrixSquareRoot, MatrixSquareRootQuasiTriangular
-  */
-template <typename MatrixType, typename ResultType> 
-void matrix_sqrt_triangular(const MatrixType &arg, ResultType &result)
-{
-  using std::sqrt;
-      typedef typename MatrixType::Scalar Scalar;
-
-  eigen_assert(arg.rows() == arg.cols());
-
-  // Compute square root of arg and store it in upper triangular part of result
-  // This uses that the square root of triangular matrices can be computed directly.
-  result.resize(arg.rows(), arg.cols());
-  for (Index i = 0; i < arg.rows(); i++) {
-    result.coeffRef(i,i) = sqrt(arg.coeff(i,i));
-  }
-  for (Index j = 1; j < arg.cols(); j++) {
-    for (Index i = j-1; i >= 0; i--) {
-      // if i = j-1, then segment has length 0 so tmp = 0
-      Scalar tmp = (result.row(i).segment(i+1,j-i-1) * result.col(j).segment(i+1,j-i-1)).value();
-      // denominator may be zero if original matrix is singular
-      result.coeffRef(i,j) = (arg.coeff(i,j) - tmp) / (result.coeff(i,i) + result.coeff(j,j));
-    }
-  }
-}
-
-
-namespace internal {
-
-/** \ingroup MatrixFunctions_Module
-  * \brief Helper struct for computing matrix square roots of general matrices.
-  * \tparam  MatrixType  type of the argument of the matrix square root,
-  *                      expected to be an instantiation of the Matrix class template.
-  *
-  * \sa MatrixSquareRootTriangular, MatrixSquareRootQuasiTriangular, MatrixBase::sqrt()
-  */
-template <typename MatrixType, int IsComplex = NumTraits<typename internal::traits<MatrixType>::Scalar>::IsComplex>
-struct matrix_sqrt_compute
-{
-  /** \brief Compute the matrix square root
-    *
-    * \param[in]  arg     matrix whose square root is to be computed.
-    * \param[out] result  square root of \p arg.
-    *
-    * See MatrixBase::sqrt() for details on how this computation is implemented.
-    */
-  template <typename ResultType> static void run(const MatrixType &arg, ResultType &result);    
-};
-
-
-// ********** Partial specialization for real matrices **********
-
-template <typename MatrixType>
-struct matrix_sqrt_compute<MatrixType, 0>
-{
-  template <typename ResultType>
-  static void run(const MatrixType &arg, ResultType &result)
-  {
-    eigen_assert(arg.rows() == arg.cols());
-
-    // Compute Schur decomposition of arg
-    const RealSchur<MatrixType> schurOfA(arg);  
-    const MatrixType& T = schurOfA.matrixT();
-    const MatrixType& U = schurOfA.matrixU();
-    
-    // Compute square root of T
-    MatrixType sqrtT = MatrixType::Zero(arg.rows(), arg.cols());
-    matrix_sqrt_quasi_triangular(T, sqrtT);
-    
-    // Compute square root of arg
-    result = U * sqrtT * U.adjoint();
-  }
-};
-
-
-// ********** Partial specialization for complex matrices **********
-
-template <typename MatrixType>
-struct matrix_sqrt_compute<MatrixType, 1>
-{
-  template <typename ResultType>
-  static void run(const MatrixType &arg, ResultType &result)
-  {
-    eigen_assert(arg.rows() == arg.cols());
-
-    // Compute Schur decomposition of arg
-    const ComplexSchur<MatrixType> schurOfA(arg);  
-    const MatrixType& T = schurOfA.matrixT();
-    const MatrixType& U = schurOfA.matrixU();
-    
-    // Compute square root of T
-    MatrixType sqrtT;
-    matrix_sqrt_triangular(T, sqrtT);
-    
-    // Compute square root of arg
-    result = U * (sqrtT.template triangularView<Upper>() * U.adjoint());
-  }
-};
-
-} // end namespace internal
-
-/** \ingroup MatrixFunctions_Module
-  *
-  * \brief Proxy for the matrix square root of some matrix (expression).
-  *
-  * \tparam Derived  Type of the argument to the matrix square root.
-  *
-  * This class holds the argument to the matrix square root until it
-  * is assigned or evaluated for some other reason (so the argument
-  * should not be changed in the meantime). It is the return type of
-  * MatrixBase::sqrt() and most of the time this is the only way it is
-  * used.
-  */
-template<typename Derived> class MatrixSquareRootReturnValue
-: public ReturnByValue<MatrixSquareRootReturnValue<Derived> >
-{
-  protected:
-    typedef typename internal::ref_selector<Derived>::type DerivedNested;
-
-  public:
-    /** \brief Constructor.
-      *
-      * \param[in]  src  %Matrix (expression) forming the argument of the
-      * matrix square root.
-      */
-    explicit MatrixSquareRootReturnValue(const Derived& src) : m_src(src) { }
-
-    /** \brief Compute the matrix square root.
-      *
-      * \param[out]  result  the matrix square root of \p src in the
-      * constructor.
-      */
-    template <typename ResultType>
-    inline void evalTo(ResultType& result) const
-    {
-      typedef typename internal::nested_eval<Derived, 10>::type DerivedEvalType;
-      typedef typename internal::remove_all<DerivedEvalType>::type DerivedEvalTypeClean;
-      DerivedEvalType tmp(m_src);
-      internal::matrix_sqrt_compute<DerivedEvalTypeClean>::run(tmp, result);
-    }
-
-    Index rows() const { return m_src.rows(); }
-    Index cols() const { return m_src.cols(); }
-
-  protected:
-    const DerivedNested m_src;
-};
-
-namespace internal {
-template<typename Derived>
-struct traits<MatrixSquareRootReturnValue<Derived> >
-{
-  typedef typename Derived::PlainObject ReturnType;
-};
-}
-
-template <typename Derived>
-const MatrixSquareRootReturnValue<Derived> MatrixBase<Derived>::sqrt() const
-{
-  eigen_assert(rows() == cols());
-  return MatrixSquareRootReturnValue<Derived>(derived());
-}
-
-} // end namespace Eigen
-
-#endif // EIGEN_MATRIX_FUNCTION
diff --git a/wpiutil/src/main/native/eigeninclude/unsupported/Eigen/src/MatrixFunctions/StemFunction.h b/wpiutil/src/main/native/eigeninclude/unsupported/Eigen/src/MatrixFunctions/StemFunction.h
deleted file mode 100644
index 7604df9..0000000
--- a/wpiutil/src/main/native/eigeninclude/unsupported/Eigen/src/MatrixFunctions/StemFunction.h
+++ /dev/null
@@ -1,117 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra.
-//
-// Copyright (C) 2010, 2013 Jitse Niesen <jitse@maths.leeds.ac.uk>
-//
-// This Source Code Form is subject to the terms of the Mozilla
-// Public License v. 2.0. If a copy of the MPL was not distributed
-// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef EIGEN_STEM_FUNCTION
-#define EIGEN_STEM_FUNCTION
-
-namespace Eigen { 
-
-namespace internal {
-
-/** \brief The exponential function (and its derivatives). */
-template <typename Scalar>
-Scalar stem_function_exp(Scalar x, int)
-{
-  using std::exp;
-  return exp(x);
-}
-
-/** \brief Cosine (and its derivatives). */
-template <typename Scalar>
-Scalar stem_function_cos(Scalar x, int n)
-{
-  using std::cos;
-  using std::sin;
-  Scalar res;
-
-  switch (n % 4) {
-  case 0: 
-    res = std::cos(x);
-    break;
-  case 1:
-    res = -std::sin(x);
-    break;
-  case 2:
-    res = -std::cos(x);
-    break;
-  case 3:
-    res = std::sin(x);
-    break;
-  }
-  return res;
-}
-
-/** \brief Sine (and its derivatives). */
-template <typename Scalar>
-Scalar stem_function_sin(Scalar x, int n)
-{
-  using std::cos;
-  using std::sin;
-  Scalar res;
-
-  switch (n % 4) {
-  case 0:
-    res = std::sin(x);
-    break;
-  case 1:
-    res = std::cos(x);
-    break;
-  case 2:
-    res = -std::sin(x);
-    break;
-  case 3:
-    res = -std::cos(x);
-    break;
-  }
-  return res;
-}
-
-/** \brief Hyperbolic cosine (and its derivatives). */
-template <typename Scalar>
-Scalar stem_function_cosh(Scalar x, int n)
-{
-  using std::cosh;
-  using std::sinh;
-  Scalar res;
-  
-  switch (n % 2) {
-  case 0:
-    res = std::cosh(x);
-    break;
-  case 1:
-    res = std::sinh(x);
-    break;
-  }
-  return res;
-}
-	
-/** \brief Hyperbolic sine (and its derivatives). */
-template <typename Scalar>
-Scalar stem_function_sinh(Scalar x, int n)
-{
-  using std::cosh;
-  using std::sinh;
-  Scalar res;
-  
-  switch (n % 2) {
-  case 0:
-    res = std::sinh(x);
-    break;
-  case 1:
-    res = std::cosh(x);
-    break;
-  }
-  return res;
-}
-
-} // end namespace internal
-
-} // end namespace Eigen
-
-#endif // EIGEN_STEM_FUNCTION
diff --git a/wpiutil/src/main/native/include/units/units.h b/wpiutil/src/main/native/include/units/units.h
deleted file mode 100644
index 4e4bdbd..0000000
--- a/wpiutil/src/main/native/include/units/units.h
+++ /dev/null
@@ -1,4857 +0,0 @@
-//--------------------------------------------------------------------------------------------------
-// 
-//	Units: A compile-time c++14 unit conversion library with no dependencies
-//
-//--------------------------------------------------------------------------------------------------
-//
-// The MIT License (MIT)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
-// and associated documentation files (the "Software"), to deal in the Software without 
-// restriction, including without limitation the rights to use, copy, modify, merge, publish, 
-// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 
-// Software is furnished to do so, subject to the following conditions:
-// 
-// The above copyright notice and this permission notice shall be included in all copies or 
-// substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
-// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-//--------------------------------------------------------------------------------------------------
-// 
-// Copyright (c) 2016 Nic Holthaus
-// 
-//--------------------------------------------------------------------------------------------------
-//
-// ATTRIBUTION:
-// Parts of this work have been adapted from: 
-// http://stackoverflow.com/questions/35069778/create-comparison-trait-for-template-classes-whose-parameters-are-in-a-different
-// http://stackoverflow.com/questions/28253399/check-traits-for-all-variadic-template-arguments/28253503
-// http://stackoverflow.com/questions/36321295/rational-approximation-of-square-root-of-stdratio-at-compile-time?noredirect=1#comment60266601_36321295
-//
-//--------------------------------------------------------------------------------------------------
-//
-/// @file	units.h
-/// @brief	Complete implementation of `units` - a compile-time, header-only, unit conversion 
-///			library built on c++14 with no dependencies.
-//
-//--------------------------------------------------------------------------------------------------
-
-#pragma once
-
-#ifndef units_h__
-#define units_h__
-
-#ifdef _MSC_VER
-#	pragma push_macro("pascal")
-#	undef pascal
-#	if _MSC_VER <= 1800
-#		define _ALLOW_KEYWORD_MACROS
-#		pragma warning(push)
-#		pragma warning(disable : 4520)
-#		pragma push_macro("constexpr")
-#		define constexpr /*constexpr*/
-#		pragma push_macro("noexcept")
-#		define noexcept throw()
-#	endif // _MSC_VER < 1800
-#endif // _MSC_VER
-
-#if !defined(_MSC_VER) || _MSC_VER > 1800
-#   define UNIT_HAS_LITERAL_SUPPORT
-#   define UNIT_HAS_VARIADIC_TEMPLATE_SUPPORT
-#endif
-
-#ifndef UNIT_LIB_DEFAULT_TYPE
-#   define UNIT_LIB_DEFAULT_TYPE double
-#endif
-
-//--------------------
-//	INCLUDES
-//--------------------
-
-#include <chrono>
-#include <ratio>
-#include <type_traits>
-#include <cstdint>
-#include <cmath>
-#include <limits>
-
-#if !defined(UNIT_LIB_DISABLE_IOSTREAM)
-	#include <iostream>
-	#include <string>
-	#include <locale>
-
-	//------------------------------
-	//	STRING FORMATTER
-	//------------------------------
-
-	namespace units
-	{
-		namespace detail
-		{
-			template <typename T> std::string to_string(const T& t)
-			{
-				std::string str{ std::to_string(t) };
-				int offset{ 1 };
-
-				// remove trailing decimal points for integer value units. Locale aware!
-				struct lconv * lc;
-				lc = localeconv();
-				char decimalPoint = *lc->decimal_point;
-				if (str.find_last_not_of('0') == str.find(decimalPoint)) { offset = 0; }
-				str.erase(str.find_last_not_of('0') + offset, std::string::npos);
-				return str;
-			}
-		}
-	}
-#endif
-
-namespace units
-{
-	template<typename T> inline constexpr const char* name(const T&);
-	template<typename T> inline constexpr const char* abbreviation(const T&);
-}
-
-//------------------------------
-//	MACROS
-//------------------------------
-
-/**
- * @def			UNIT_ADD_UNIT_TAGS(namespaceName,nameSingular, namePlural, abbreviation, definition)
- * @brief		Helper macro for generating the boiler-plate code generating the tags of a new unit.
- * @details		The macro generates singular, plural, and abbreviated forms
- *				of the unit definition (e.g. `meter`, `meters`, and `m`), as aliases for the
- *				unit tag.
- * @param		namespaceName namespace in which the new units will be encapsulated.
- * @param		nameSingular singular version of the unit name, e.g. 'meter'
- * @param		namePlural - plural version of the unit name, e.g. 'meters'
- * @param		abbreviation - abbreviated unit name, e.g. 'm'
- * @param		definition - the variadic parameter is used for the definition of the unit
- *				(e.g. `unit<std::ratio<1>, units::category::length_unit>`)
- * @note		a variadic template is used for the definition to allow templates with
- *				commas to be easily expanded. All the variadic 'arguments' should together
- *				comprise the unit definition.
- */
-#define UNIT_ADD_UNIT_TAGS(namespaceName,nameSingular, namePlural, abbreviation, /*definition*/...)\
-	namespace namespaceName\
-	{\
-	/** @name Units (full names plural) */ /** @{ */ typedef __VA_ARGS__ namePlural; /** @} */\
-	/** @name Units (full names singular) */ /** @{ */ typedef namePlural nameSingular; /** @} */\
-	/** @name Units (abbreviated) */ /** @{ */ typedef namePlural abbreviation; /** @} */\
-	}
-
-/**
- * @def			UNIT_ADD_UNIT_DEFINITION(namespaceName,nameSingular)
- * @brief		Macro for generating the boiler-plate code for the unit_t type definition.
- * @details		The macro generates the definition of the unit container types, e.g. `meter_t`
- * @param		namespaceName namespace in which the new units will be encapsulated.
- * @param		nameSingular singular version of the unit name, e.g. 'meter'
- */
-#define UNIT_ADD_UNIT_DEFINITION(namespaceName,nameSingular)\
-	namespace namespaceName\
-	{\
-		/** @name Unit Containers */ /** @{ */ typedef unit_t<nameSingular> nameSingular ## _t; /** @} */\
-	}
-
-/**
- * @def			UNIT_ADD_CUSTOM_TYPE_UNIT_DEFINITION(namespaceName,nameSingular,underlyingType)
- * @brief		Macro for generating the boiler-plate code for a unit_t type definition with a non-default underlying type.
- * @details		The macro generates the definition of the unit container types, e.g. `meter_t`
- * @param		namespaceName namespace in which the new units will be encapsulated.
- * @param		nameSingular singular version of the unit name, e.g. 'meter'
- * @param		underlyingType the underlying type
- */
-#define UNIT_ADD_CUSTOM_TYPE_UNIT_DEFINITION(namespaceName,nameSingular, underlyingType)\
-	namespace namespaceName\
-	{\
-	/** @name Unit Containers */ /** @{ */ typedef unit_t<nameSingular,underlyingType> nameSingular ## _t; /** @} */\
-	}
-/**
- * @def			UNIT_ADD_IO(namespaceName,nameSingular, abbreviation)
- * @brief		Macro for generating the boiler-plate code needed for I/O for a new unit.
- * @details		The macro generates the code to insert units into an ostream. It
- *				prints both the value and abbreviation of the unit when invoked.
- * @param		namespaceName namespace in which the new units will be encapsulated.
- * @param		nameSingular singular version of the unit name, e.g. 'meter'
- * @param		abbrev - abbreviated unit name, e.g. 'm'
- * @note		When UNIT_LIB_DISABLE_IOSTREAM is defined, the macro does not generate any code
- */
-#if defined(UNIT_LIB_DISABLE_IOSTREAM)
-	#define UNIT_ADD_IO(namespaceName, nameSingular, abbrev)
-#else
-	#define UNIT_ADD_IO(namespaceName, nameSingular, abbrev)\
-	namespace namespaceName\
-	{\
-		inline std::ostream& operator<<(std::ostream& os, const nameSingular ## _t& obj) \
-		{\
-			os << obj() << " "#abbrev; return os; \
-		}\
-		inline std::string to_string(const nameSingular ## _t& obj)\
-		{\
-			return units::detail::to_string(obj()) + std::string(" "#abbrev);\
-		}\
-	}
-#endif
-
- /**
-  * @def		UNIT_ADD_NAME(namespaceName,nameSingular,abbreviation)
-  * @brief		Macro for generating constexpr names/abbreviations for units.
-  * @details	The macro generates names for units. E.g. name() of 1_m would be "meter", and 
-  *				abbreviation would be "m".
-  * @param		namespaceName namespace in which the new units will be encapsulated. All literal values
-  *				are placed in the `units::literals` namespace.
-  * @param		nameSingular singular version of the unit name, e.g. 'meter'
-  * @param		abbreviation - abbreviated unit name, e.g. 'm'
-  */
-#define UNIT_ADD_NAME(namespaceName, nameSingular, abbrev)\
-template<> inline constexpr const char* name(const namespaceName::nameSingular ## _t&)\
-{\
-	return #nameSingular;\
-}\
-template<> inline constexpr const char* abbreviation(const namespaceName::nameSingular ## _t&)\
-{\
-	return #abbrev;\
-}
-
-/**
- * @def			UNIT_ADD_LITERALS(namespaceName,nameSingular,abbreviation)
- * @brief		Macro for generating user-defined literals for units.
- * @details		The macro generates user-defined literals for units. A literal suffix is created
- *				using the abbreviation (e.g. `10.0_m`).
- * @param		namespaceName namespace in which the new units will be encapsulated. All literal values
- *				are placed in the `units::literals` namespace.
- * @param		nameSingular singular version of the unit name, e.g. 'meter'
- * @param		abbreviation - abbreviated unit name, e.g. 'm'
- * @note		When UNIT_HAS_LITERAL_SUPPORT is not defined, the macro does not generate any code
- */
-#if defined(UNIT_HAS_LITERAL_SUPPORT)
-	#define UNIT_ADD_LITERALS(namespaceName, nameSingular, abbreviation)\
-	namespace literals\
-	{\
-		inline constexpr namespaceName::nameSingular ## _t operator""_ ## abbreviation(long double d)\
-		{\
-			return namespaceName::nameSingular ## _t(static_cast<namespaceName::nameSingular ## _t::underlying_type>(d));\
-		}\
-		inline constexpr namespaceName::nameSingular ## _t operator""_ ## abbreviation (unsigned long long d)\
-		{\
-			return namespaceName::nameSingular ## _t(static_cast<namespaceName::nameSingular ## _t::underlying_type>(d));\
-		}\
-	}
-#else
-	#define UNIT_ADD_LITERALS(namespaceName, nameSingular, abbreviation)
-#endif
-
-/**
- * @def			UNIT_ADD(namespaceName,nameSingular, namePlural, abbreviation, definition)
- * @brief		Macro for generating the boiler-plate code needed for a new unit.
- * @details		The macro generates singular, plural, and abbreviated forms
- *				of the unit definition (e.g. `meter`, `meters`, and `m`), as well as the
- *				appropriately named unit container (e.g. `meter_t`). A literal suffix is created
- *				using the abbreviation (e.g. `10.0_m`). It also defines a class-specific
- *				cout function which prints both the value and abbreviation of the unit when invoked.
- * @param		namespaceName namespace in which the new units will be encapsulated. All literal values
- *				are placed in the `units::literals` namespace.
- * @param		nameSingular singular version of the unit name, e.g. 'meter'
- * @param		namePlural - plural version of the unit name, e.g. 'meters'
- * @param		abbreviation - abbreviated unit name, e.g. 'm'
- * @param		definition - the variadic parameter is used for the definition of the unit
- *				(e.g. `unit<std::ratio<1>, units::category::length_unit>`)
- * @note		a variadic template is used for the definition to allow templates with
- *				commas to be easily expanded. All the variadic 'arguments' should together
- *				comprise the unit definition.
- */
-#define UNIT_ADD(namespaceName, nameSingular, namePlural, abbreviation, /*definition*/...)\
-	UNIT_ADD_UNIT_TAGS(namespaceName,nameSingular, namePlural, abbreviation, __VA_ARGS__)\
-	UNIT_ADD_UNIT_DEFINITION(namespaceName,nameSingular)\
-	UNIT_ADD_NAME(namespaceName,nameSingular, abbreviation)\
-	UNIT_ADD_IO(namespaceName,nameSingular, abbreviation)\
-	UNIT_ADD_LITERALS(namespaceName,nameSingular, abbreviation)
-
-/**
- * @def			UNIT_ADD_WITH_CUSTOM_TYPE(namespaceName,nameSingular, namePlural, abbreviation, underlyingType, definition)
- * @brief		Macro for generating the boiler-plate code needed for a new unit with a non-default underlying type.
- * @details		The macro generates singular, plural, and abbreviated forms
- *				of the unit definition (e.g. `meter`, `meters`, and `m`), as well as the
- *				appropriately named unit container (e.g. `meter_t`). A literal suffix is created
- *				using the abbreviation (e.g. `10.0_m`). It also defines a class-specific
- *				cout function which prints both the value and abbreviation of the unit when invoked.
- * @param		namespaceName namespace in which the new units will be encapsulated. All literal values
- *				are placed in the `units::literals` namespace.
- * @param		nameSingular singular version of the unit name, e.g. 'meter'
- * @param		namePlural - plural version of the unit name, e.g. 'meters'
- * @param		abbreviation - abbreviated unit name, e.g. 'm'
- * @param		underlyingType - the underlying type, e.g. 'int' or 'float'
- * @param		definition - the variadic parameter is used for the definition of the unit
- *				(e.g. `unit<std::ratio<1>, units::category::length_unit>`)
- * @note		a variadic template is used for the definition to allow templates with
- *				commas to be easily expanded. All the variadic 'arguments' should together
- *				comprise the unit definition.
- */
-#define UNIT_ADD_WITH_CUSTOM_TYPE(namespaceName, nameSingular, namePlural, abbreviation, underlyingType, /*definition*/...)\
-	UNIT_ADD_UNIT_TAGS(namespaceName,nameSingular, namePlural, abbreviation, __VA_ARGS__)\
-	UNIT_ADD_CUSTOM_TYPE_UNIT_DEFINITION(namespaceName,nameSingular,underlyingType)\
-	UNIT_ADD_IO(namespaceName,nameSingular, abbreviation)\
-	UNIT_ADD_LITERALS(namespaceName,nameSingular, abbreviation)
-
-/**
- * @def			UNIT_ADD_DECIBEL(namespaceName, nameSingular, abbreviation)
- * @brief		Macro to create decibel container and literals for an existing unit type.
- * @details		This macro generates the decibel unit container, cout overload, and literal definitions.
- * @param		namespaceName namespace in which the new units will be encapsulated. All literal values
- *				are placed in the `units::literals` namespace.
- * @param		nameSingular singular version of the base unit name, e.g. 'watt'
- * @param		abbreviation - abbreviated decibel unit name, e.g. 'dBW'
- */
-#define UNIT_ADD_DECIBEL(namespaceName, nameSingular, abbreviation)\
-	namespace namespaceName\
-	{\
-		/** @name Unit Containers */ /** @{ */ typedef unit_t<nameSingular, UNIT_LIB_DEFAULT_TYPE, units::decibel_scale> abbreviation ## _t; /** @} */\
-	}\
-	UNIT_ADD_IO(namespaceName, abbreviation, abbreviation)\
-	UNIT_ADD_LITERALS(namespaceName, abbreviation, abbreviation)
-
-/**
- * @def			UNIT_ADD_CATEGORY_TRAIT(unitCategory, baseUnit)
- * @brief		Macro to create the `is_category_unit` type trait.
- * @details		This trait allows users to test whether a given type matches
- *				an intended category. This macro comprises all the boiler-plate
- *				code necessary to do so.
- * @param		unitCategory The name of the category of unit, e.g. length or mass.
- */
-
-#define UNIT_ADD_CATEGORY_TRAIT_DETAIL(unitCategory)\
-	namespace traits\
-	{\
-		/** @cond */\
-		namespace detail\
-		{\
-			template<typename T> struct is_ ## unitCategory ## _unit_impl : std::false_type {};\
-			template<typename C, typename U, typename P, typename T>\
-			struct is_ ## unitCategory ## _unit_impl<units::unit<C, U, P, T>> : std::is_same<units::traits::base_unit_of<typename units::traits::unit_traits<units::unit<C, U, P, T>>::base_unit_type>, units::category::unitCategory ## _unit>::type {};\
-			template<typename U, typename S, template<typename> class N>\
-			struct is_ ## unitCategory ## _unit_impl<units::unit_t<U, S, N>> : std::is_same<units::traits::base_unit_of<typename units::traits::unit_t_traits<units::unit_t<U, S, N>>::unit_type>, units::category::unitCategory ## _unit>::type {};\
-		}\
-		/** @endcond */\
-	}
-
-#if defined(UNIT_HAS_VARIADIC_TEMPLATE_SUPPORT)
-#define UNIT_ADD_IS_UNIT_CATEGORY_TRAIT(unitCategory)\
-	namespace traits\
-	{\
-		template<typename... T> struct is_ ## unitCategory ## _unit : std::integral_constant<bool, units::all_true<units::traits::detail::is_ ## unitCategory ## _unit_impl<std::decay_t<T>>::value...>::value> {};\
-	}
-#else
-#define UNIT_ADD_IS_UNIT_CATEGORY_TRAIT(unitCategory)\
-	namespace traits\
-	{\
-			template<typename T1, typename T2 = T1, typename T3 = T1>\
-			struct is_ ## unitCategory ## _unit : std::integral_constant<bool, units::traits::detail::is_ ## unitCategory ## _unit_impl<typename std::decay<T1>::type>::value &&\
-				units::traits::detail::is_ ## unitCategory ## _unit_impl<typename std::decay<T2>::type>::value &&\
-				units::traits::detail::is_ ## unitCategory ## _unit_impl<typename std::decay<T3>::type>::value>{};\
-	}
-#endif
-
-#define UNIT_ADD_CATEGORY_TRAIT(unitCategory)\
-	UNIT_ADD_CATEGORY_TRAIT_DETAIL(unitCategory)\
-    /** @ingroup	TypeTraits*/\
-	/** @brief		Trait which tests whether a type represents a unit of unitCategory*/\
-	/** @details	Inherits from `std::true_type` or `std::false_type`. Use `is_ ## unitCategory ## _unit<T>::value` to test the unit represents a unitCategory quantity.*/\
-	/** @tparam		T	one or more types to test*/\
-	UNIT_ADD_IS_UNIT_CATEGORY_TRAIT(unitCategory)
-
-/**
- * @def			UNIT_ADD_WITH_METRIC_PREFIXES(nameSingular, namePlural, abbreviation, definition)
- * @brief		Macro for generating the boiler-plate code needed for a new unit, including its metric
- *				prefixes from femto to peta.
- * @details		See UNIT_ADD. In addition to generating the unit definition and containers '(e.g. `meters` and 'meter_t',
- *				it also creates corresponding units with metric suffixes such as `millimeters`, and `millimeter_t`), as well as the
- *				literal suffixes (e.g. `10.0_mm`).
- * @param		namespaceName namespace in which the new units will be encapsulated. All literal values
- *				are placed in the `units::literals` namespace.
- * @param		nameSingular singular version of the unit name, e.g. 'meter'
- * @param		namePlural - plural version of the unit name, e.g. 'meters'
- * @param		abbreviation - abbreviated unit name, e.g. 'm'
- * @param		definition - the variadic parameter is used for the definition of the unit
- *				(e.g. `unit<std::ratio<1>, units::category::length_unit>`)
- * @note		a variadic template is used for the definition to allow templates with
- *				commas to be easily expanded. All the variadic 'arguments' should together
- *				comprise the unit definition.
- */
-#define UNIT_ADD_WITH_METRIC_PREFIXES(namespaceName, nameSingular, namePlural, abbreviation, /*definition*/...)\
-	UNIT_ADD(namespaceName, nameSingular, namePlural, abbreviation, __VA_ARGS__)\
-	UNIT_ADD(namespaceName, femto ## nameSingular, femto ## namePlural, f ## abbreviation, femto<namePlural>)\
-	UNIT_ADD(namespaceName, pico ## nameSingular, pico ## namePlural, p ## abbreviation, pico<namePlural>)\
-	UNIT_ADD(namespaceName, nano ## nameSingular, nano ## namePlural, n ## abbreviation, nano<namePlural>)\
-	UNIT_ADD(namespaceName, micro ## nameSingular, micro ## namePlural, u ## abbreviation, micro<namePlural>)\
-	UNIT_ADD(namespaceName, milli ## nameSingular, milli ## namePlural, m ## abbreviation, milli<namePlural>)\
-	UNIT_ADD(namespaceName, centi ## nameSingular, centi ## namePlural, c ## abbreviation, centi<namePlural>)\
-	UNIT_ADD(namespaceName, deci ## nameSingular, deci ## namePlural, d ## abbreviation, deci<namePlural>)\
-	UNIT_ADD(namespaceName, deca ## nameSingular, deca ## namePlural, da ## abbreviation, deca<namePlural>)\
-	UNIT_ADD(namespaceName, hecto ## nameSingular, hecto ## namePlural, h ## abbreviation, hecto<namePlural>)\
-	UNIT_ADD(namespaceName, kilo ## nameSingular, kilo ## namePlural, k ## abbreviation, kilo<namePlural>)\
-	UNIT_ADD(namespaceName, mega ## nameSingular, mega ## namePlural, M ## abbreviation, mega<namePlural>)\
-	UNIT_ADD(namespaceName, giga ## nameSingular, giga ## namePlural, G ## abbreviation, giga<namePlural>)\
-	UNIT_ADD(namespaceName, tera ## nameSingular, tera ## namePlural, T ## abbreviation, tera<namePlural>)\
-	UNIT_ADD(namespaceName, peta ## nameSingular, peta ## namePlural, P ## abbreviation, peta<namePlural>)\
-
- /**
-  * @def		UNIT_ADD_WITH_METRIC_AND_BINARY_PREFIXES(nameSingular, namePlural, abbreviation, definition)
-  * @brief		Macro for generating the boiler-plate code needed for a new unit, including its metric
-  *				prefixes from femto to peta, and binary prefixes from kibi to exbi.
-  * @details	See UNIT_ADD. In addition to generating the unit definition and containers '(e.g. `bytes` and 'byte_t',
-  *				it also creates corresponding units with metric suffixes such as `millimeters`, and `millimeter_t`), as well as the
-  *				literal suffixes (e.g. `10.0_B`).
-  * @param		namespaceName namespace in which the new units will be encapsulated. All literal values
-  *				are placed in the `units::literals` namespace.
-  * @param		nameSingular singular version of the unit name, e.g. 'byte'
-  * @param		namePlural - plural version of the unit name, e.g. 'bytes'
-  * @param		abbreviation - abbreviated unit name, e.g. 'B'
-  * @param		definition - the variadic parameter is used for the definition of the unit
-  *				(e.g. `unit<std::ratio<1>, units::category::data_unit>`)
-  * @note		a variadic template is used for the definition to allow templates with
-  *				commas to be easily expanded. All the variadic 'arguments' should together
-  *				comprise the unit definition.
-  */
-#define UNIT_ADD_WITH_METRIC_AND_BINARY_PREFIXES(namespaceName, nameSingular, namePlural, abbreviation, /*definition*/...)\
-	UNIT_ADD_WITH_METRIC_PREFIXES(namespaceName, nameSingular, namePlural, abbreviation, __VA_ARGS__)\
-	UNIT_ADD(namespaceName, kibi ## nameSingular, kibi ## namePlural, Ki ## abbreviation, kibi<namePlural>)\
-	UNIT_ADD(namespaceName, mebi ## nameSingular, mebi ## namePlural, Mi ## abbreviation, mebi<namePlural>)\
-	UNIT_ADD(namespaceName, gibi ## nameSingular, gibi ## namePlural, Gi ## abbreviation, gibi<namePlural>)\
-	UNIT_ADD(namespaceName, tebi ## nameSingular, tebi ## namePlural, Ti ## abbreviation, tebi<namePlural>)\
-	UNIT_ADD(namespaceName, pebi ## nameSingular, pebi ## namePlural, Pi ## abbreviation, pebi<namePlural>)\
-	UNIT_ADD(namespaceName, exbi ## nameSingular, exbi ## namePlural, Ei ## abbreviation, exbi<namePlural>)
-
-//--------------------
-//	UNITS NAMESPACE
-//--------------------
-
-/**
- * @namespace units
- * @brief Unit Conversion Library namespace
- */
-namespace units
-{
-	//----------------------------------
-	//	DOXYGEN
-	//----------------------------------
-
-	/**
-	 * @defgroup	UnitContainers Unit Containers
-	 * @brief		Defines a series of classes which contain dimensioned values. Unit containers
-	 *				store a value, and support various arithmetic operations.
-	 */
-
-	/**
-	 * @defgroup	UnitTypes Unit Types
-	 * @brief		Defines a series of classes which represent units. These types are tags used by
-	 *				the conversion function, to create compound units, or to create `unit_t` types.
-	 *				By themselves, they are not containers and have no stored value.
-	 */
-
-	/**
-	 * @defgroup	UnitManipulators Unit Manipulators
-	 * @brief		Defines a series of classes used to manipulate unit types, such as `inverse<>`, `squared<>`, and metric prefixes. 
-	 *				Unit manipulators can be chained together, e.g. `inverse<squared<pico<time::seconds>>>` to
-	 *				represent picoseconds^-2.
-	 */
-
-	 /**
-	  * @defgroup	CompileTimeUnitManipulators Compile-time Unit Manipulators
-	  * @brief		Defines a series of classes used to manipulate `unit_value_t` types at compile-time, such as `unit_value_add<>`, `unit_value_sqrt<>`, etc.
-	  *				Compile-time manipulators can be chained together, e.g. `unit_value_sqrt<unit_value_add<unit_value_power<a, 2>, unit_value_power<b, 2>>>` to
-	  *				represent `c = sqrt(a^2 + b^2).
-	  */
-
-	 /**
-	 * @defgroup	UnitMath Unit Math
-	 * @brief		Defines a collection of unit-enabled, strongly-typed versions of `<cmath>` functions.
-	 * @details		Includes most c++11 extensions.
-	 */
-
-	/**
-	 * @defgroup	Conversion Explicit Conversion
-	 * @brief		Functions used to convert values of one logical type to another.
-	 */
-
-	/**
-	 * @defgroup	TypeTraits Type Traits
-	 * @brief		Defines a series of classes to obtain unit type information at compile-time.
-	 */
-
-	//------------------------------
-	//	FORWARD DECLARATIONS
-	//------------------------------
-
-	/** @cond */	// DOXYGEN IGNORE
-	namespace constants
-	{
-		namespace detail
-		{
-			static constexpr const UNIT_LIB_DEFAULT_TYPE PI_VAL = 3.14159265358979323846264338327950288419716939937510;
-		}
-	}
-	/** @endcond */	// END DOXYGEN IGNORE
-
-	//------------------------------
-	//	RATIO TRAITS
-	//------------------------------
-
-	/**
-	 * @ingroup TypeTraits
-	 * @{
-	 */
-
-	/** @cond */	// DOXYGEN IGNORE
-	namespace detail
-	{
-		/// has_num implementation.
-		template<class T>
-		struct has_num_impl
-		{
-			template<class U>
-			static constexpr auto test(U*)->std::is_integral<decltype(U::num)> {return std::is_integral<decltype(U::num)>{}; }
-			template<typename>
-			static constexpr std::false_type test(...) { return std::false_type{}; }
-
-			using type = decltype(test<T>(0));
-		};
-	}
-
-	/**
-	 * @brief		Trait which checks for the existence of a static numerator.
-	 * @details		Inherits from `std::true_type` or `std::false_type`. Use `has_num<T>::value` to test
-	 *				whether `class T` has a numerator static member.
-	 */
-	template<class T>
-	struct has_num : units::detail::has_num_impl<T>::type {};
-
-	namespace detail
-	{
-		/// has_den implementation.
-		template<class T>
-		struct has_den_impl
-		{
-			template<class U>
-			static constexpr auto test(U*)->std::is_integral<decltype(U::den)> { return std::is_integral<decltype(U::den)>{}; }
-			template<typename>
-			static constexpr std::false_type test(...) { return std::false_type{}; }
-
-			using type = decltype(test<T>(0));
-		};
-	}
-
-	/**
-	 * @brief		Trait which checks for the existence of a static denominator.
-	 * @details		Inherits from `std::true_type` or `std::false_type`. Use `has_den<T>::value` to test
-	 *				whether `class T` has a denominator static member.
-	 */
-	template<class T>
-	struct has_den : units::detail::has_den_impl<T>::type {};
-
-	/** @endcond */	// END DOXYGEN IGNORE
-
-	namespace traits
-	{
-		/**
-		 * @brief		Trait that tests whether a type represents a std::ratio.
-		 * @details		Inherits from `std::true_type` or `std::false_type`. Use `is_ratio<T>::value` to test
-		 *				whether `class T` implements a std::ratio.
-		 */
-		template<class T>
-		struct is_ratio : std::integral_constant<bool,
-			has_num<T>::value &&
-			has_den<T>::value>
-		{};
-	}
-
-	//------------------------------
-	//	UNIT TRAITS
-	//------------------------------
-
-	/** @cond */	// DOXYGEN IGNORE
-	/**
-	 * @brief		void type.
-	 * @details		Helper class for creating type traits.
-	 */
-	template<class ...>
-	struct void_t { typedef void type; };
-
-	/**
-	 * @brief		parameter pack for boolean arguments.
-	 */
-	template<bool...> struct bool_pack {};
-
-	/**
-	 * @brief		Trait which tests that a set of other traits are all true.
-	 */
-	template<bool... Args>
-	struct all_true : std::is_same<units::bool_pack<true, Args...>, units::bool_pack<Args..., true>> {};
-	/** @endcond */	// DOXYGEN IGNORE
-	
-	/** 
-	 * @brief namespace representing type traits which can access the properties of types provided by the units library.
-	 */
-	namespace traits
-	{
-#ifdef FOR_DOXYGEN_PURPOSES_ONLY
-		/**
-		 * @ingroup		TypeTraits
-		 * @brief		Traits class defining the properties of units.
-		 * @details		The units library determines certain properties of the units passed to 
-		 *				them and what they represent by using the members of the corresponding 
-		 *				unit_traits instantiation.
-		 */
-		template<class T>
-		struct unit_traits
-		{
-			typedef typename T::base_unit_type base_unit_type;											///< Unit type that the unit was derived from. May be a `base_unit` or another `unit`. Use the `base_unit_of` trait to find the SI base unit type. This will be `void` if type `T` is not a unit.
-			typedef typename T::conversion_ratio conversion_ratio;										///< `std::ratio` representing the conversion factor to the `base_unit_type`. This will be `void` if type `T` is not a unit.
-			typedef typename T::pi_exponent_ratio pi_exponent_ratio;									///< `std::ratio` representing the exponent of pi to be used in the conversion. This will be `void` if type `T` is not a unit.
-			typedef typename T::translation_ratio translation_ratio;									///< `std::ratio` representing a datum translation to the base unit (i.e. degrees C to degrees F conversion). This will be `void` if type `T` is not a unit.
-		};
-#endif
-		/** @cond */	// DOXYGEN IGNORE
-		/**
-		 * @brief		unit traits implementation for classes which are not units.
-		 */
-		template<class T, typename = void>
-		struct unit_traits
-		{
-			typedef void base_unit_type;
-			typedef void conversion_ratio;
-			typedef void pi_exponent_ratio;
-			typedef void translation_ratio;
-		};
-
-		template<class T>
-		struct unit_traits
-			<T, typename void_t<
-			typename T::base_unit_type,
-			typename T::conversion_ratio,
-			typename T::pi_exponent_ratio,
-			typename T::translation_ratio>::type>
-		{
-			typedef typename T::base_unit_type base_unit_type;											///< Unit type that the unit was derived from. May be a `base_unit` or another `unit`. Use the `base_unit_of` trait to find the SI base unit type. This will be `void` if type `T` is not a unit.
-			typedef typename T::conversion_ratio conversion_ratio;										///< `std::ratio` representing the conversion factor to the `base_unit_type`. This will be `void` if type `T` is not a unit.
-			typedef typename T::pi_exponent_ratio pi_exponent_ratio;									///< `std::ratio` representing the exponent of pi to be used in the conversion. This will be `void` if type `T` is not a unit.
-			typedef typename T::translation_ratio translation_ratio;									///< `std::ratio` representing a datum translation to the base unit (i.e. degrees C to degrees F conversion). This will be `void` if type `T` is not a unit.
-		};
-		/** @endcond */	// END DOXYGEN IGNORE
-	}
-
-	/** @cond */	// DOXYGEN IGNORE
-	namespace detail
-	{
-		/**
-		 * @brief		helper type to identify base units.
-		 * @details		A non-templated base class for `base_unit` which enables RTTI testing.
-		 */
-		struct _base_unit_t {};
-	}
-	/** @endcond */	// END DOXYGEN IGNORE
-
-	namespace traits
-	{
-		/**
-		 * @ingroup		TypeTraits
-		 * @brief		Trait which tests if a class is a `base_unit` type.
-		 * @details		Inherits from `std::true_type` or `std::false_type`. Use `is_base_unit<T>::value` to test
-		 *				whether `class T` implements a `base_unit`.
-		 */
-		template<class T>
-		struct is_base_unit : std::is_base_of<units::detail::_base_unit_t, T> {};
-	}
-
-	/** @cond */	// DOXYGEN IGNORE
-	namespace detail
-	{
-		/**
-		 * @brief		helper type to identify units.
-		 * @details		A non-templated base class for `unit` which enables RTTI testing.
-		 */
-		struct _unit {};
-
-		template<std::intmax_t Num, std::intmax_t Den = 1>
-		using meter_ratio = std::ratio<Num, Den>;
-	}
-	/** @endcond */	// END DOXYGEN IGNORE
-
-	namespace traits
-	{
-		/**
-		 * @ingroup		TypeTraits
-		 * @brief		Traits which tests if a class is a `unit`
-		 * @details		Inherits from `std::true_type` or `std::false_type`. Use `is_unit<T>::value` to test
-		 *				whether `class T` implements a `unit`.
-		 */
-		template<class T>
-		struct is_unit : std::is_base_of<units::detail::_unit, T>::type {};
-	}
-
-	/** @} */ // end of TypeTraits
-
-	//------------------------------
-	//	BASE UNIT CLASS
-	//------------------------------
-
-	/**
-	 * @ingroup		UnitTypes
-	 * @brief		Class representing SI base unit types.
-	 * @details		Base units are represented by a combination of `std::ratio` template parameters, each
-	 *				describing the exponent of the type of unit they represent. Example: meters per second
-	 *				would be described by a +1 exponent for meters, and a -1 exponent for seconds, thus:
-	 *				`base_unit<std::ratio<1>, std::ratio<0>, std::ratio<-1>>`
-	 * @tparam		Meter		`std::ratio` representing the exponent value for meters.
-	 * @tparam		Kilogram	`std::ratio` representing the exponent value for kilograms.
-	 * @tparam		Second		`std::ratio` representing the exponent value for seconds.
-	 * @tparam		Radian		`std::ratio` representing the exponent value for radians. Although radians are not SI base units, they are included because radians are described by the SI as m * m^-1, which would make them indistinguishable from scalars.
-	 * @tparam		Ampere		`std::ratio` representing the exponent value for amperes.
-	 * @tparam		Kelvin		`std::ratio` representing the exponent value for Kelvin.
-	 * @tparam		Mole		`std::ratio` representing the exponent value for moles.
-	 * @tparam		Candela		`std::ratio` representing the exponent value for candelas.
-	 * @tparam		Byte		`std::ratio` representing the exponent value for bytes.
-	 * @sa			category	 for type aliases for SI base_unit types.
-	 */
-	template<class Meter = detail::meter_ratio<0>,
-	class Kilogram = std::ratio<0>,
-	class Second = std::ratio<0>,
-	class Radian = std::ratio<0>,
-	class Ampere = std::ratio<0>,
-	class Kelvin = std::ratio<0>,
-	class Mole = std::ratio<0>,
-	class Candela = std::ratio<0>,
-	class Byte = std::ratio<0>>
-	struct base_unit : units::detail::_base_unit_t
-	{
-		static_assert(traits::is_ratio<Meter>::value, "Template parameter `Meter` must be a `std::ratio` representing the exponent of meters the unit has");
-		static_assert(traits::is_ratio<Kilogram>::value, "Template parameter `Kilogram` must be a `std::ratio` representing the exponent of kilograms the unit has");
-		static_assert(traits::is_ratio<Second>::value, "Template parameter `Second` must be a `std::ratio` representing the exponent of seconds the unit has");
-		static_assert(traits::is_ratio<Ampere>::value, "Template parameter `Ampere` must be a `std::ratio` representing the exponent of amperes the unit has");
-		static_assert(traits::is_ratio<Kelvin>::value, "Template parameter `Kelvin` must be a `std::ratio` representing the exponent of kelvin the unit has");
-		static_assert(traits::is_ratio<Candela>::value, "Template parameter `Candela` must be a `std::ratio` representing the exponent of candelas the unit has");
-		static_assert(traits::is_ratio<Mole>::value, "Template parameter `Mole` must be a `std::ratio` representing the exponent of moles the unit has");
-		static_assert(traits::is_ratio<Radian>::value, "Template parameter `Radian` must be a `std::ratio` representing the exponent of radians the unit has");
-		static_assert(traits::is_ratio<Byte>::value, "Template parameter `Byte` must be a `std::ratio` representing the exponent of bytes the unit has");
-
-		typedef Meter meter_ratio;
-		typedef Kilogram kilogram_ratio;
-		typedef Second second_ratio;
-		typedef Radian radian_ratio;
-		typedef Ampere ampere_ratio;
-		typedef Kelvin kelvin_ratio;
-		typedef Mole mole_ratio;
-		typedef Candela candela_ratio;
-		typedef Byte byte_ratio;
-	};
-
-	//------------------------------
-	//	UNIT CATEGORIES
-	//------------------------------
-
-	/**
-	 * @brief		namespace representing the implemented base and derived unit types. These will not generally be needed by library users.
-	 * @sa			base_unit for the definition of the category parameters.
-	 */
-	namespace category
-	{
-		// SCALAR (DIMENSIONLESS) TYPES
-		typedef base_unit<> scalar_unit;			///< Represents a quantity with no dimension.
-		typedef base_unit<> dimensionless_unit;	///< Represents a quantity with no dimension.
-
-		// SI BASE UNIT TYPES
-		//					METERS			KILOGRAMS		SECONDS			RADIANS			AMPERES			KELVIN			MOLE			CANDELA			BYTE		---		CATEGORY
-		typedef base_unit<detail::meter_ratio<1>>																																		length_unit;			 		///< Represents an SI base unit of length
-		typedef base_unit<detail::meter_ratio<0>,	std::ratio<1>>																														mass_unit;				 		///< Represents an SI base unit of mass
-		typedef base_unit<detail::meter_ratio<0>,	std::ratio<0>,	std::ratio<1>>																										time_unit;				 		///< Represents an SI base unit of time
-		typedef base_unit<detail::meter_ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<1>>																						angle_unit;				 		///< Represents an SI base unit of angle
-		typedef base_unit<detail::meter_ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<1>>																		current_unit;			 		///< Represents an SI base unit of current
-		typedef base_unit<detail::meter_ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<1>>														temperature_unit;		 		///< Represents an SI base unit of temperature
-		typedef base_unit<detail::meter_ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<1>>										substance_unit;			 		///< Represents an SI base unit of amount of substance
-		typedef base_unit<detail::meter_ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<1>>						luminous_intensity_unit; 		///< Represents an SI base unit of luminous intensity
-
-		// SI DERIVED UNIT TYPES
-		//					METERS			KILOGRAMS		SECONDS			RADIANS			AMPERES			KELVIN			MOLE			CANDELA			BYTE		---		CATEGORY	
-		typedef base_unit<detail::meter_ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<2>,	std::ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<0>>						solid_angle_unit;				///< Represents an SI derived unit of solid angle
-		typedef base_unit<detail::meter_ratio<0>,	std::ratio<0>,	std::ratio<-1>>																										frequency_unit;					///< Represents an SI derived unit of frequency
-		typedef base_unit<detail::meter_ratio<1>,	std::ratio<0>,	std::ratio<-1>>																										velocity_unit;					///< Represents an SI derived unit of velocity
-		typedef base_unit<detail::meter_ratio<0>,	std::ratio<0>,	std::ratio<-1>,	std::ratio<1>>																						angular_velocity_unit;			///< Represents an SI derived unit of angular velocity
-		typedef base_unit<detail::meter_ratio<1>,	std::ratio<0>,	std::ratio<-2>>																										acceleration_unit;				///< Represents an SI derived unit of acceleration
-		typedef base_unit<detail::meter_ratio<1>,	std::ratio<1>,	std::ratio<-2>>																										force_unit;						///< Represents an SI derived unit of force
-		typedef base_unit<detail::meter_ratio<-1>,	std::ratio<1>,	std::ratio<-2>>																										pressure_unit;					///< Represents an SI derived unit of pressure
-		typedef base_unit<detail::meter_ratio<0>,	std::ratio<0>,	std::ratio<1>,	std::ratio<0>,	std::ratio<1>>																		charge_unit;					///< Represents an SI derived unit of charge
-		typedef base_unit<detail::meter_ratio<2>,	std::ratio<1>,	std::ratio<-2>>																										energy_unit;					///< Represents an SI derived unit of energy
-		typedef base_unit<detail::meter_ratio<2>,	std::ratio<1>,	std::ratio<-3>>																										power_unit;						///< Represents an SI derived unit of power
-		typedef base_unit<detail::meter_ratio<2>,	std::ratio<1>,	std::ratio<-3>,	std::ratio<0>,	std::ratio<-1>>																		voltage_unit;					///< Represents an SI derived unit of voltage
-		typedef base_unit<detail::meter_ratio<-2>,	std::ratio<-1>,	std::ratio<4>,	std::ratio<0>,	std::ratio<2>>																		capacitance_unit;				///< Represents an SI derived unit of capacitance
-		typedef base_unit<detail::meter_ratio<2>,	std::ratio<1>,	std::ratio<-3>,	std::ratio<0>,	std::ratio<-2>>																		impedance_unit;					///< Represents an SI derived unit of impedance
-		typedef base_unit<detail::meter_ratio<-2>,	std::ratio<-1>,	std::ratio<3>,	std::ratio<0>,	std::ratio<2>>																		conductance_unit;				///< Represents an SI derived unit of conductance
-		typedef base_unit<detail::meter_ratio<2>,	std::ratio<1>,	std::ratio<-2>,	std::ratio<0>,	std::ratio<-1>>																		magnetic_flux_unit;				///< Represents an SI derived unit of magnetic flux
-		typedef base_unit<detail::meter_ratio<0>,	std::ratio<1>,	std::ratio<-2>,	std::ratio<0>,	std::ratio<-1>>																		magnetic_field_strength_unit;	///< Represents an SI derived unit of magnetic field strength
-		typedef base_unit<detail::meter_ratio<2>,	std::ratio<1>,	std::ratio<-2>,	std::ratio<0>,	std::ratio<-2>>																		inductance_unit;				///< Represents an SI derived unit of inductance
-		typedef base_unit<detail::meter_ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<2>,	std::ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<1>>						luminous_flux_unit;				///< Represents an SI derived unit of luminous flux
-		typedef base_unit<detail::meter_ratio<-2>,	std::ratio<0>,	std::ratio<0>,	std::ratio<2>,	std::ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<1>>						illuminance_unit;				///< Represents an SI derived unit of illuminance
-		typedef base_unit<detail::meter_ratio<0>,	std::ratio<0>,	std::ratio<-1>>																										radioactivity_unit;				///< Represents an SI derived unit of radioactivity
-
-		// OTHER UNIT TYPES
-		//					METERS			KILOGRAMS		SECONDS			RADIANS			AMPERES			KELVIN			MOLE			CANDELA			BYTE		---		CATEGORY			
-		typedef base_unit<detail::meter_ratio<2>,	std::ratio<1>,	std::ratio<-2>>																										torque_unit;					///< Represents an SI derived unit of torque
-		typedef base_unit<detail::meter_ratio<2>>																																		area_unit;						///< Represents an SI derived unit of area
-		typedef base_unit<detail::meter_ratio<3>>																																		volume_unit;					///< Represents an SI derived unit of volume
-		typedef base_unit<detail::meter_ratio<-3>,	std::ratio<1>>																														density_unit;					///< Represents an SI derived unit of density
-		typedef base_unit<>																																						concentration_unit;				///< Represents a unit of concentration
-		typedef base_unit<detail::meter_ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<1>>		data_unit;						///< Represents a unit of data size
-		typedef base_unit<detail::meter_ratio<0>,	std::ratio<0>,	std::ratio<-1>,	std::ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<0>,	std::ratio<1>>		data_transfer_rate_unit;		///< Represents a unit of data transfer rate
-	}
-
-	//------------------------------
-	//	UNIT CLASSES
-	//------------------------------
-
-	/** @cond */	// DOXYGEN IGNORE
-	/**
-	 * @brief		unit type template specialization for units derived from base units.
-	 */
-	template <class, class, class, class> struct unit;
-	template<class Conversion, class... Exponents, class PiExponent, class Translation>
-	struct unit<Conversion, base_unit<Exponents...>, PiExponent, Translation> : units::detail::_unit
-	{
-		static_assert(traits::is_ratio<Conversion>::value, "Template parameter `Conversion` must be a `std::ratio` representing the conversion factor to `BaseUnit`.");
-		static_assert(traits::is_ratio<PiExponent>::value, "Template parameter `PiExponent` must be a `std::ratio` representing the exponents of Pi the unit has.");
-		static_assert(traits::is_ratio<Translation>::value, "Template parameter `Translation` must be a `std::ratio` representing an additive translation required by the unit conversion.");
-
-		typedef typename units::base_unit<Exponents...> base_unit_type;
-		typedef Conversion conversion_ratio;
-		typedef Translation translation_ratio;
-		typedef PiExponent pi_exponent_ratio;
-	};
-	/** @endcond */	// END DOXYGEN IGNORE
-
-	/**
-	 * @brief		Type representing an arbitrary unit.
-	 * @ingroup		UnitTypes
-	 * @details		`unit` types are used as tags for the `conversion` function. They are *not* containers
-	 *				(see `unit_t` for a  container class). Each unit is defined by:
-	 *
-	 *				- A `std::ratio` defining the conversion factor to the base unit type. (e.g. `std::ratio<1,12>` for inches to feet)
-	 *				- A base unit that the unit is derived from (or a unit category. Must be of type `unit` or `base_unit`)
-	 *				- An exponent representing factors of PI required by the conversion. (e.g. `std::ratio<-1>` for a radians to degrees conversion)
-	 *				- a ratio representing a datum translation required for the conversion (e.g. `std::ratio<32>` for a farenheit to celsius conversion)
-	 *
-	 *				Typically, a specific unit, like `meters`, would be implemented as a type alias
-	 *				of `unit`, i.e. `using meters = unit<std::ratio<1>, units::category::length_unit`, or
-	 *				`using inches = unit<std::ratio<1,12>, feet>`.
-	 * @tparam		Conversion	std::ratio representing scalar multiplication factor.
-	 * @tparam		BaseUnit	Unit type which this unit is derived from. May be a `base_unit`, or another `unit`.
-	 * @tparam		PiExponent	std::ratio representing the exponent of pi required by the conversion.
-	 * @tparam		Translation	std::ratio representing any datum translation required by the conversion.
-	 */
-	template<class Conversion, class BaseUnit, class PiExponent = std::ratio<0>, class Translation = std::ratio<0>>
-	struct unit : units::detail::_unit
-	{
-		static_assert(traits::is_unit<BaseUnit>::value, "Template parameter `BaseUnit` must be a `unit` type.");
-		static_assert(traits::is_ratio<Conversion>::value, "Template parameter `Conversion` must be a `std::ratio` representing the conversion factor to `BaseUnit`.");
-		static_assert(traits::is_ratio<PiExponent>::value, "Template parameter `PiExponent` must be a `std::ratio` representing the exponents of Pi the unit has.");
-
-		typedef typename units::traits::unit_traits<BaseUnit>::base_unit_type base_unit_type;
-		typedef typename std::ratio_multiply<typename BaseUnit::conversion_ratio, Conversion> conversion_ratio;
-		typedef typename std::ratio_add<typename BaseUnit::pi_exponent_ratio, PiExponent> pi_exponent_ratio;
-		typedef typename std::ratio_add<std::ratio_multiply<typename BaseUnit::conversion_ratio, Translation>, typename BaseUnit::translation_ratio> translation_ratio;
-	};
-
-	//------------------------------
-	//	BASE UNIT MANIPULATORS
-	//------------------------------
-
-	/** @cond */	// DOXYGEN IGNORE
-	namespace detail
-	{
-		/**
-		 * @brief		base_unit_of trait implementation
-		 * @details		recursively seeks base_unit type that a unit is derived from. Since units can be
-		 *				derived from other units, the `base_unit_type` typedef may not represent this value.
-		 */
-		template<class> struct base_unit_of_impl;
-		template<class Conversion, class BaseUnit, class PiExponent, class Translation>
-		struct base_unit_of_impl<unit<Conversion, BaseUnit, PiExponent, Translation>> : base_unit_of_impl<BaseUnit> {};
-		template<class... Exponents>
-		struct base_unit_of_impl<base_unit<Exponents...>>
-		{
-			typedef base_unit<Exponents...> type;
-		};
-		template<>
-		struct base_unit_of_impl<void>
-		{
-			typedef void type;
-		};
-	}
-	/** @endcond */	// END DOXYGEN IGNORE
-
-	namespace traits
-	{
-		/**
-		 * @brief		Trait which returns the `base_unit` type that a unit is originally derived from.
-		 * @details		Since units can be derived from other `unit` types in addition to `base_unit` types,
-		 *				the `base_unit_type` typedef will not always be a `base_unit` (or unit category).
-		 *				Since compatible
-		 */
-		template<class U>
-		using base_unit_of = typename units::detail::base_unit_of_impl<U>::type;
-	}
-
-	/** @cond */	// DOXYGEN IGNORE
-	namespace detail
-	{
-		/**
-		 * @brief		implementation of base_unit_multiply
-		 * @details		'multiples' (adds exponent ratios of) two base unit types. Base units can be found
-		 *				using `base_unit_of`.
-		 */
-		template<class, class> struct base_unit_multiply_impl;
-		template<class... Exponents1, class... Exponents2>
-		struct base_unit_multiply_impl<base_unit<Exponents1...>, base_unit<Exponents2...>> {
-			using type = base_unit<std::ratio_add<Exponents1, Exponents2>...>;
-		};
-
-		/**
-		 * @brief		represents type of two base units multiplied together
-		 */
-		template<class U1, class U2>
-		using base_unit_multiply = typename base_unit_multiply_impl<U1, U2>::type;
-
-		/**
-		 * @brief		implementation of base_unit_divide
-		 * @details		'dived' (subtracts exponent ratios of) two base unit types. Base units can be found
-		 *				using `base_unit_of`.
-		 */
-		template<class, class> struct base_unit_divide_impl;
-		template<class... Exponents1, class... Exponents2>
-		struct base_unit_divide_impl<base_unit<Exponents1...>, base_unit<Exponents2...>> {
-			using type = base_unit<std::ratio_subtract<Exponents1, Exponents2>...>;
-		};
-
-		/**
-		 * @brief		represents the resulting type of `base_unit` U1 divided by U2.
-		 */
-		template<class U1, class U2>
-		using base_unit_divide = typename base_unit_divide_impl<U1, U2>::type;
-
-		/**
-		 * @brief		implementation of inverse_base
-		 * @details		multiplies all `base_unit` exponent ratios by -1. The resulting type represents
-		 *				the inverse base unit of the given `base_unit` type.
-		 */
-		template<class> struct inverse_base_impl;
-
-		template<class... Exponents>
-		struct inverse_base_impl<base_unit<Exponents...>> {
-			using type = base_unit<std::ratio_multiply<Exponents, std::ratio<-1>>...>;
-		};
-
-		/**
-		 * @brief		represent the inverse type of `class U`
-		 * @details		E.g. if `U` is `length_unit`, then `inverse<U>` will represent `length_unit^-1`.
-		 */
-		template<class U> using inverse_base = typename inverse_base_impl<U>::type;
-
-		/**
-		 * @brief		implementation of `squared_base`
-		 * @details		multiplies all the exponent ratios of the given class by 2. The resulting type is
-		 *				equivalent to the given type squared.
-		 */
-		template<class U> struct squared_base_impl;
-		template<class... Exponents>
-		struct squared_base_impl<base_unit<Exponents...>> {
-			using type = base_unit<std::ratio_multiply<Exponents, std::ratio<2>>...>;
-		};
-
-		/**
-		 * @brief		represents the type of a `base_unit` squared.
-		 * @details		E.g. `squared<length_unit>` will represent `length_unit^2`.
-		 */
-		template<class U> using squared_base = typename squared_base_impl<U>::type;
-
-		/**
-		 * @brief		implementation of `cubed_base`
-		 * @details		multiplies all the exponent ratios of the given class by 3. The resulting type is
-		 *				equivalent to the given type cubed.
-		 */
-		template<class U> struct cubed_base_impl;
-		template<class... Exponents>
-		struct cubed_base_impl<base_unit<Exponents...>> {
-			using type = base_unit<std::ratio_multiply<Exponents, std::ratio<3>>...>;
-		};
-
-		/**
-		 * @brief		represents the type of a `base_unit` cubed.
-		 * @details		E.g. `cubed<length_unit>` will represent `length_unit^3`.
-		 */
-		template<class U> using cubed_base = typename cubed_base_impl<U>::type;
-
-		/**
-		 * @brief		implementation of `sqrt_base`
-		 * @details		divides all the exponent ratios of the given class by 2. The resulting type is
-		 *				equivalent to the square root of the given type.
-		 */
-		template<class U> struct sqrt_base_impl;
-		template<class... Exponents>
-		struct sqrt_base_impl<base_unit<Exponents...>> {
-			using type = base_unit<std::ratio_divide<Exponents, std::ratio<2>>...>;
-		};
-
-		/**
-		 * @brief		represents the square-root type of a `base_unit`.
-		 * @details		E.g. `sqrt<length_unit>` will represent `length_unit^(1/2)`.
-		 */
-		template<class U> using sqrt_base = typename sqrt_base_impl<U>::type;
-
-		/**
-		 * @brief		implementation of `cbrt_base`
-		 * @details		divides all the exponent ratios of the given class by 3. The resulting type is
-		 *				equivalent to the given type's cube-root.
-		 */
-		template<class U> struct cbrt_base_impl;
-		template<class... Exponents>
-		struct cbrt_base_impl<base_unit<Exponents...>> {
-			using type = base_unit<std::ratio_divide<Exponents, std::ratio<3>>...>;
-		};
-
-		/**
-		 * @brief		represents the cube-root type of a `base_unit` .
-		 * @details		E.g. `cbrt<length_unit>` will represent `length_unit^(1/3)`.
-		 */
-		template<class U> using cbrt_base = typename cbrt_base_impl<U>::type;
-	}
-	/** @endcond */	// END DOXYGEN IGNORE
-
-	//------------------------------
-	//	UNIT MANIPULATORS
-	//------------------------------
-
-	/** @cond */	// DOXYGEN IGNORE
-	namespace detail
-	{
-		/**
-		 * @brief		implementation of `unit_multiply`.
-		 * @details		multiplies two units. The base unit becomes the base units of each with their exponents
-		 *				added together. The conversion factors of each are multiplied by each other. Pi exponent ratios
-		 *				are added, and datum translations are removed.
-		 */
-		template<class Unit1, class Unit2>
-		struct unit_multiply_impl
-		{
-			using type = unit < std::ratio_multiply<typename Unit1::conversion_ratio, typename Unit2::conversion_ratio>,
-				base_unit_multiply <traits::base_unit_of<typename Unit1::base_unit_type>, traits::base_unit_of<typename Unit2::base_unit_type>>,
-				std::ratio_add<typename Unit1::pi_exponent_ratio, typename Unit2::pi_exponent_ratio>,
-				std::ratio < 0 >> ;
-		};
-
-		/**
-		 * @brief		represents the type of two units multiplied together.
-		 * @details		recalculates conversion and exponent ratios at compile-time.
-		 */
-		template<class U1, class U2>
-		using unit_multiply = typename unit_multiply_impl<U1, U2>::type;
-
-		/**
-		 * @brief		implementation of `unit_divide`.
-		 * @details		divides two units. The base unit becomes the base units of each with their exponents
-		 *				subtracted from each other. The conversion factors of each are divided by each other. Pi exponent ratios
-		 *				are subtracted, and datum translations are removed.
-		 */
-		template<class Unit1, class Unit2>
-		struct unit_divide_impl
-		{
-			using type = unit < std::ratio_divide<typename Unit1::conversion_ratio, typename Unit2::conversion_ratio>,
-				base_unit_divide<traits::base_unit_of<typename Unit1::base_unit_type>, traits::base_unit_of<typename Unit2::base_unit_type>>,
-				std::ratio_subtract<typename Unit1::pi_exponent_ratio, typename Unit2::pi_exponent_ratio>,
-				std::ratio < 0 >> ;
-		};
-
-		/**
-		 * @brief		represents the type of two units divided by each other.
-		 * @details		recalculates conversion and exponent ratios at compile-time.
-		 */
-		template<class U1, class U2>
-		using unit_divide = typename unit_divide_impl<U1, U2>::type;
-
-		/**
-		 * @brief		implementation of `inverse`
-		 * @details		inverts a unit (equivalent to 1/unit). The `base_unit` and pi exponents are all multiplied by
-		 *				-1. The conversion ratio numerator and denominator are swapped. Datum translation
-		 *				ratios are removed.
-		 */
-		template<class Unit>
-		struct inverse_impl
-		{
-			using type = unit < std::ratio<Unit::conversion_ratio::den, Unit::conversion_ratio::num>,
-				inverse_base<traits::base_unit_of<typename units::traits::unit_traits<Unit>::base_unit_type>>,
-				std::ratio_multiply<typename units::traits::unit_traits<Unit>::pi_exponent_ratio, std::ratio<-1>>,
-				std::ratio < 0 >> ;	// inverses are rates or change, the translation factor goes away.
-		};
-	}
-	/** @endcond */	// END DOXYGEN IGNORE
-
-	/**
-	 * @brief		represents the inverse unit type of `class U`.
-	 * @ingroup		UnitManipulators
-	 * @tparam		U	`unit` type to invert.
-	 * @details		E.g. `inverse<meters>` will represent meters^-1 (i.e. 1/meters).
-	 */
-	template<class U> using inverse = typename units::detail::inverse_impl<U>::type;
-
-	/** @cond */	// DOXYGEN IGNORE
-	namespace detail
-	{
-		/**
-		 * @brief		implementation of `squared`
-		 * @details		Squares the conversion ratio, `base_unit` exponents, pi exponents, and removes
-		 *				datum translation ratios.
-		 */
-		template<class Unit>
-		struct squared_impl
-		{
-			static_assert(traits::is_unit<Unit>::value, "Template parameter `Unit` must be a `unit` type.");
-			using Conversion = typename Unit::conversion_ratio;
-			using type = unit < std::ratio_multiply<Conversion, Conversion>,
-				squared_base<traits::base_unit_of<typename Unit::base_unit_type>>,
-				std::ratio_multiply<typename Unit::pi_exponent_ratio, std::ratio<2>>,
-				typename Unit::translation_ratio
-			> ;
-		};
-	}
-	/** @endcond */	// END DOXYGEN IGNORE
-
-	/**
-	 * @brief		represents the unit type of `class U` squared
-	 * @ingroup		UnitManipulators
-	 * @tparam		U	`unit` type to square.
-	 * @details		E.g. `square<meters>` will represent meters^2.
-	 */
-	template<class U>
-	using squared = typename units::detail::squared_impl<U>::type;
-
-	/** @cond */	// DOXYGEN IGNORE
-	namespace detail
-	{
-		/**
-			 * @brief		implementation of `cubed`
-			 * @details		Cubes the conversion ratio, `base_unit` exponents, pi exponents, and removes
-			 *				datum translation ratios.
-			 */
-		template<class Unit>
-		struct cubed_impl
-		{
-			static_assert(traits::is_unit<Unit>::value, "Template parameter `Unit` must be a `unit` type.");
-			using Conversion = typename Unit::conversion_ratio;
-			using type = unit < std::ratio_multiply<Conversion, std::ratio_multiply<Conversion, Conversion>>,
-				cubed_base<traits::base_unit_of<typename Unit::base_unit_type>>,
-				std::ratio_multiply<typename Unit::pi_exponent_ratio, std::ratio<3>>,
-				typename Unit::translation_ratio> ;
-		};
-	}
-	/** @endcond */	// END DOXYGEN IGNORE
-
-	/**
-	 * @brief		represents the type of `class U` cubed.
-	 * @ingroup		UnitManipulators
-	 * @tparam		U	`unit` type to cube.
-	 * @details		E.g. `cubed<meters>` will represent meters^3.
-	 */
-	template<class U>
-	using cubed = typename units::detail::cubed_impl<U>::type;
-
-	/** @cond */	// DOXYGEN IGNORE
-	namespace detail
-	{
-		//----------------------------------
-		//	RATIO_SQRT IMPLEMENTATION
-		//----------------------------------
-
-		using Zero = std::ratio<0>;
-		using One = std::ratio<1>;
-		template <typename R> using Square = std::ratio_multiply<R, R>;
-
-		// Find the largest std::integer N such that Predicate<N>::value is true.
-		template <template <std::intmax_t N> class Predicate, typename enabled = void>
-		struct BinarySearch {
-			template <std::intmax_t N>
-			struct SafeDouble_ {
-				static constexpr const std::intmax_t value = 2 * N;
-				static_assert(value > 0, "Overflows when computing 2 * N");
-			};
-
-			template <intmax_t Lower, intmax_t Upper, typename Condition1 = void, typename Condition2 = void>
-			struct DoubleSidedSearch_ : DoubleSidedSearch_<Lower, Upper,
-				std::integral_constant<bool, (Upper - Lower == 1)>,
-				std::integral_constant<bool, ((Upper - Lower>1 && Predicate<Lower + (Upper - Lower) / 2>::value))>> {};
-
-			template <intmax_t Lower, intmax_t Upper>
-			struct DoubleSidedSearch_<Lower, Upper, std::false_type, std::false_type> : DoubleSidedSearch_<Lower, Lower + (Upper - Lower) / 2> {};
-
-			template <intmax_t Lower, intmax_t Upper, typename Condition2>
-			struct DoubleSidedSearch_<Lower, Upper, std::true_type, Condition2> : std::integral_constant<intmax_t, Lower>{};
-
-			template <intmax_t Lower, intmax_t Upper, typename Condition1>
-			struct DoubleSidedSearch_<Lower, Upper, Condition1, std::true_type> : DoubleSidedSearch_<Lower + (Upper - Lower) / 2, Upper>{};
-
-			template <std::intmax_t Lower, class enabled1 = void>
-			struct SingleSidedSearch_ : SingleSidedSearch_<Lower, std::integral_constant<bool, Predicate<SafeDouble_<Lower>::value>::value>>{};
-
-			template <std::intmax_t Lower>
-			struct SingleSidedSearch_<Lower, std::false_type> : DoubleSidedSearch_<Lower, SafeDouble_<Lower>::value> {};
-
-			template <std::intmax_t Lower>
-			struct SingleSidedSearch_<Lower, std::true_type> : SingleSidedSearch_<SafeDouble_<Lower>::value>{};
-
-			static constexpr const std::intmax_t value = SingleSidedSearch_<1>::value;
- 		};
-
-		template <template <std::intmax_t N> class Predicate>
-		struct BinarySearch<Predicate, std::enable_if_t<!Predicate<1>::value>> : std::integral_constant<std::intmax_t, 0>{};
-
-		// Find largest std::integer N such that N<=sqrt(R)
-		template <typename R>
-		struct Integer {
-			template <std::intmax_t N> using Predicate_ = std::ratio_less_equal<std::ratio<N>, std::ratio_divide<R, std::ratio<N>>>;
-			static constexpr const std::intmax_t value = BinarySearch<Predicate_>::value;
-		};
-
-		template <typename R>
-		struct IsPerfectSquare {
-			static constexpr const std::intmax_t DenSqrt_ = Integer<std::ratio<R::den>>::value;
-			static constexpr const std::intmax_t NumSqrt_ = Integer<std::ratio<R::num>>::value;
-			static constexpr const bool value =( DenSqrt_ * DenSqrt_ == R::den && NumSqrt_ * NumSqrt_ == R::num);
-			using Sqrt = std::ratio<NumSqrt_, DenSqrt_>;
-		};
-
-		// Represents sqrt(P)-Q.
-		template <typename Tp, typename Tq>
-		struct Remainder {
-			using P = Tp;
-			using Q = Tq;
-		};
-
-		// Represents 1/R = I + Rem where R is a Remainder.
-		template <typename R>
-		struct Reciprocal {
-			using P_ = typename R::P;
-			using Q_ = typename R::Q;
-			using Den_ = std::ratio_subtract<P_, Square<Q_>>;
-			using A_ = std::ratio_divide<Q_, Den_>;
-			using B_ = std::ratio_divide<P_, Square<Den_>>;
-			static constexpr const std::intmax_t I_ = (A_::num + Integer<std::ratio_multiply<B_, Square<std::ratio<A_::den>>>>::value) / A_::den;
-			using I = std::ratio<I_>;
-			using Rem = Remainder<B_, std::ratio_subtract<I, A_>>;
-		};
-
-		// Expands sqrt(R) to continued fraction:
-		// f(x)=C1+1/(C2+1/(C3+1/(...+1/(Cn+x)))) = (U*x+V)/(W*x+1) and sqrt(R)=f(Rem).
-		// The error |f(Rem)-V| = |(U-W*V)x/(W*x+1)| <= |U-W*V|*Rem <= |U-W*V|/I' where
-		// I' is the std::integer part of reciprocal of Rem.
-		template <typename Tr, std::intmax_t N>
-		struct ContinuedFraction {
-			template <typename T>
-			using Abs_ = std::conditional_t<std::ratio_less<T, Zero>::value, std::ratio_subtract<Zero, T>, T>;
-
-			using R = Tr;
-			using Last_ = ContinuedFraction<R, N - 1>;
-			using Reciprocal_ = Reciprocal<typename Last_::Rem>;
-			using Rem = typename Reciprocal_::Rem;
-			using I_ = typename Reciprocal_::I;
-			using Den_ = std::ratio_add<typename Last_::W, I_>;
-			using U = std::ratio_divide<typename Last_::V, Den_>;
-			using V = std::ratio_divide<std::ratio_add<typename Last_::U, std::ratio_multiply<typename Last_::V, I_>>, Den_>;
-			using W = std::ratio_divide<One, Den_>;
-			using Error = Abs_<std::ratio_divide<std::ratio_subtract<U, std::ratio_multiply<V, W>>, typename Reciprocal<Rem>::I>>;
-		};
-
-		template <typename Tr>
-		struct ContinuedFraction<Tr, 1> {
-			using R = Tr;
-			using U = One;
-			using V = std::ratio<Integer<R>::value>;
-			using W = Zero;
-			using Rem = Remainder<R, V>;
-			using Error = std::ratio_divide<One, typename Reciprocal<Rem>::I>;
-		};
-
-		template <typename R, typename Eps, std::intmax_t N = 1, typename enabled = void>
-		struct Sqrt_ : Sqrt_<R, Eps, N + 1> {};
-
-		template <typename R, typename Eps, std::intmax_t N>
-		struct Sqrt_<R, Eps, N, std::enable_if_t<std::ratio_less_equal<typename ContinuedFraction<R, N>::Error, Eps>::value>> {
-			using type = typename ContinuedFraction<R, N>::V;
-		};
-
-		template <typename R, typename Eps, typename enabled = void>
-		struct Sqrt {
-			static_assert(std::ratio_greater_equal<R, Zero>::value, "R can't be negative");
-		};
-
-		template <typename R, typename Eps>
-		struct Sqrt<R, Eps, std::enable_if_t<std::ratio_greater_equal<R, Zero>::value && IsPerfectSquare<R>::value>> {
-			using type = typename IsPerfectSquare<R>::Sqrt;
-		};
-
-		template <typename R, typename Eps>
-		struct Sqrt<R, Eps, std::enable_if_t<(std::ratio_greater_equal<R, Zero>::value && !IsPerfectSquare<R>::value)>> : Sqrt_<R, Eps>{};
-	}
-	/** @endcond */	// END DOXYGEN IGNORE
-
-	/**
-	 * @ingroup		TypeTraits
-	 * @brief		Calculate square root of a ratio at compile-time
-	 * @details		Calculates a rational approximation of the square root of the ratio. The error
-	 *				in the calculation is bounded by 1/epsilon (Eps). E.g. for the default value
-	 *				of 10000000000, the maximum error will be a/10000000000, or 1e-8, or said another way,
-	 *				the error will be on the order of 10^-9. Since these calculations are done at 
-	 *				compile time, it is advisable to set epsilon to the highest value that does not
-	 *				cause an integer overflow in the calculation. If you can't compile `ratio_sqrt` 
-	 *				due to overflow errors, reducing the value of epsilon sufficiently will correct
-	 *				the problem.\n\n
-	 *				`ratio_sqrt` is guaranteed to converge for all values of `Ratio` which do not
-	 *				overflow. 
-	 * @note		This function provides a rational approximation, _NOT_ an exact value.
-	 * @tparam		Ratio	ratio to take the square root of. This can represent any rational value,
-	 *						_not_ just integers or values with integer roots.
-	 * @tparam		Eps		Value of epsilon, which represents the inverse of the maximum allowable
-	 *						error. This value should be chosen to be as high as possible before
-	 *						integer overflow errors occur in the compiler.
-	 */
-	template<typename Ratio, std::intmax_t Eps = 10000000000>
-	using ratio_sqrt = typename  units::detail::Sqrt<Ratio, std::ratio<1, Eps>>::type;
-
-	/** @cond */	// DOXYGEN IGNORE
-	namespace detail
-	{
-		/**
-		 * @brief		implementation of `sqrt`
-		 * @details		square roots the conversion ratio, `base_unit` exponents, pi exponents, and removes
-		 *				datum translation ratios.
-		 */
-		template<class Unit, std::intmax_t Eps>
-		struct sqrt_impl
-		{
-			static_assert(traits::is_unit<Unit>::value, "Template parameter `Unit` must be a `unit` type.");
-			using Conversion = typename Unit::conversion_ratio;
-			using type = unit <ratio_sqrt<Conversion, Eps>,
-				sqrt_base<traits::base_unit_of<typename Unit::base_unit_type>>,
-				std::ratio_divide<typename Unit::pi_exponent_ratio, std::ratio<2>>,
-				typename Unit::translation_ratio>;
-		};
-	}
-	/** @endcond */	// END DOXYGEN IGNORE
-
-	/**	 
-	 * @ingroup		UnitManipulators
-	 * @brief		represents the square root of type `class U`.
-	 * @details		Calculates a rational approximation of the square root of the unit. The error
-	 *				in the calculation is bounded by 1/epsilon (Eps). E.g. for the default value
-	 *				of 10000000000, the maximum error will be a/10000000000, or 1e-8, or said another way,
-	 *				the error will be on the order of 10^-9. Since these calculations are done at
-	 *				compile time, it is advisable to set epsilon to the highest value that does not
-	 *				cause an integer overflow in the calculation. If you can't compile `ratio_sqrt`
-	 *				due to overflow errors, reducing the value of epsilon sufficiently will correct
-	 *				the problem.\n\n
-	 *				`ratio_sqrt` is guaranteed to converge for all values of `Ratio` which do not
-	 *				overflow.
-	 * @tparam		U	`unit` type to take the square root of.
-	 * @tparam		Eps	Value of epsilon, which represents the inverse of the maximum allowable
-	 *					error. This value should be chosen to be as high as possible before
-	 *					integer overflow errors occur in the compiler. 
-	 * @note		USE WITH CAUTION. The is an approximate value. In general, squared<sqrt<meter>> != meter,
-	 *				i.e. the operation is not reversible, and it will result in propogated approximations.
-	 *				Use only when absolutely necessary.
-	 */
-	template<class U, std::intmax_t Eps = 10000000000>
-	using square_root = typename units::detail::sqrt_impl<U, Eps>::type;
-
-	//------------------------------
-	//	COMPOUND UNITS
-	//------------------------------
-
-	/** @cond */	// DOXYGEN IGNORE
-	namespace detail
-	{
-		/**
-			 * @brief		implementation of compound_unit
-			 * @details		multiplies a variadic list of units together, and is inherited from the resulting
-			 *				type.
-			 */
-		template<class U, class... Us> struct compound_impl;
-		template<class U> struct compound_impl<U> { using type = U; };
-		template<class U1, class U2, class...Us>
-		struct compound_impl<U1, U2, Us...>
-			: compound_impl<unit_multiply<U1, U2>, Us...> {};
-	}
-	/** @endcond */	// END DOXYGEN IGNORE
-
-	/**
-	 * @brief		Represents a unit type made up from other units.
-	 * @details		Compound units are formed by multiplying the units of all the types provided in
-	 *				the template argument. Types provided must inherit from `unit`. A compound unit can
-	 *				be formed from any number of other units, and unit manipulators like `inverse` and
-	 *				`squared` are supported. E.g. to specify acceleration, on could create
-	 *				`using acceleration = compound_unit<length::meters, inverse<squared<seconds>>;`
-	 * @tparam		U...	units which, when multiplied together, form the desired compound unit.
-	 * @ingroup		UnitTypes
-	 */
-	template<class U, class... Us>
-	using compound_unit = typename units::detail::compound_impl<U, Us...>::type;
-
-	//------------------------------
-	//	PREFIXES
-	//------------------------------
-
-	/** @cond */	// DOXYGEN IGNORE
-	namespace detail
-	{
-		/**
-		 * @brief		prefix applicator.
-		 * @details		creates a unit type from a prefix and a unit
-		 */
-		template<class Ratio, class Unit>
-		struct prefix
-		{
-			static_assert(traits::is_ratio<Ratio>::value, "Template parameter `Ratio` must be a `std::ratio`.");
-			static_assert(traits::is_unit<Unit>::value, "Template parameter `Unit` must be a `unit` type.");
-			typedef typename units::unit<Ratio, Unit> type;
-		};
-
-		/// recursive exponential implementation
-		template <int N, class U>
-		struct power_of_ratio
-		{
-			typedef std::ratio_multiply<U, typename power_of_ratio<N - 1, U>::type> type;
-		};
-
-		/// End recursion
-		template <class U>
-		struct power_of_ratio<1, U>
-		{
-			typedef U type;
-		};
-	}
-	/** @endcond */	// END DOXYGEN IGNORE
-
-	/**
-	 * @ingroup UnitManipulators
-	 * @{
-	 * @ingroup Decimal Prefixes
-	 * @{
-	 */
-	template<class U> using atto	= typename units::detail::prefix<std::atto,	U>::type;			///< Represents the type of `class U` with the metric 'atto' prefix appended.	@details E.g. atto<meters> represents meters*10^-18		@tparam U unit type to apply the prefix to.
-	template<class U> using femto	= typename units::detail::prefix<std::femto,U>::type;			///< Represents the type of `class U` with the metric 'femto' prefix appended.  @details E.g. femto<meters> represents meters*10^-15	@tparam U unit type to apply the prefix to.
-	template<class U> using pico	= typename units::detail::prefix<std::pico,	U>::type;			///< Represents the type of `class U` with the metric 'pico' prefix appended.	@details E.g. pico<meters> represents meters*10^-12		@tparam U unit type to apply the prefix to.
-	template<class U> using nano	= typename units::detail::prefix<std::nano,	U>::type;			///< Represents the type of `class U` with the metric 'nano' prefix appended.	@details E.g. nano<meters> represents meters*10^-9		@tparam U unit type to apply the prefix to.
-	template<class U> using micro	= typename units::detail::prefix<std::micro,U>::type;			///< Represents the type of `class U` with the metric 'micro' prefix appended.	@details E.g. micro<meters> represents meters*10^-6		@tparam U unit type to apply the prefix to.
-	template<class U> using milli	= typename units::detail::prefix<std::milli,U>::type;			///< Represents the type of `class U` with the metric 'milli' prefix appended.	@details E.g. milli<meters> represents meters*10^-3		@tparam U unit type to apply the prefix to.
-	template<class U> using centi	= typename units::detail::prefix<std::centi,U>::type;			///< Represents the type of `class U` with the metric 'centi' prefix appended.	@details E.g. centi<meters> represents meters*10^-2		@tparam U unit type to apply the prefix to.
-	template<class U> using deci	= typename units::detail::prefix<std::deci,	U>::type;			///< Represents the type of `class U` with the metric 'deci' prefix appended.	@details E.g. deci<meters> represents meters*10^-1		@tparam U unit type to apply the prefix to.
-	template<class U> using deca	= typename units::detail::prefix<std::deca,	U>::type;			///< Represents the type of `class U` with the metric 'deca' prefix appended.	@details E.g. deca<meters> represents meters*10^1		@tparam U unit type to apply the prefix to.
-	template<class U> using hecto	= typename units::detail::prefix<std::hecto,U>::type;			///< Represents the type of `class U` with the metric 'hecto' prefix appended.	@details E.g. hecto<meters> represents meters*10^2		@tparam U unit type to apply the prefix to.
-	template<class U> using kilo	= typename units::detail::prefix<std::kilo,	U>::type;			///< Represents the type of `class U` with the metric 'kilo' prefix appended.	@details E.g. kilo<meters> represents meters*10^3		@tparam U unit type to apply the prefix to.
-	template<class U> using mega	= typename units::detail::prefix<std::mega,	U>::type;			///< Represents the type of `class U` with the metric 'mega' prefix appended.	@details E.g. mega<meters> represents meters*10^6		@tparam U unit type to apply the prefix to.
-	template<class U> using giga	= typename units::detail::prefix<std::giga,	U>::type;			///< Represents the type of `class U` with the metric 'giga' prefix appended.	@details E.g. giga<meters> represents meters*10^9		@tparam U unit type to apply the prefix to.
-	template<class U> using tera	= typename units::detail::prefix<std::tera,	U>::type;			///< Represents the type of `class U` with the metric 'tera' prefix appended.	@details E.g. tera<meters> represents meters*10^12		@tparam U unit type to apply the prefix to.
-	template<class U> using peta	= typename units::detail::prefix<std::peta,	U>::type;			///< Represents the type of `class U` with the metric 'peta' prefix appended.	@details E.g. peta<meters> represents meters*10^15		@tparam U unit type to apply the prefix to.
-	template<class U> using exa		= typename units::detail::prefix<std::exa,	U>::type;			///< Represents the type of `class U` with the metric 'exa' prefix appended.	@details E.g. exa<meters> represents meters*10^18		@tparam U unit type to apply the prefix to.
-	/** @} @} */
-
-	/**
-	 * @ingroup UnitManipulators
-	 * @{
-	 * @ingroup Binary Prefixes
-	 * @{
-	 */
-	template<class U> using kibi	= typename units::detail::prefix<std::ratio<1024>,					U>::type;	///< Represents the type of `class U` with the binary 'kibi' prefix appended.	@details E.g. kibi<bytes> represents bytes*2^10	@tparam U unit type to apply the prefix to.
-	template<class U> using mebi	= typename units::detail::prefix<std::ratio<1048576>,				U>::type;	///< Represents the type of `class U` with the binary 'mibi' prefix appended.	@details E.g. mebi<bytes> represents bytes*2^20	@tparam U unit type to apply the prefix to.
-	template<class U> using gibi	= typename units::detail::prefix<std::ratio<1073741824>,			U>::type;	///< Represents the type of `class U` with the binary 'gibi' prefix appended.	@details E.g. gibi<bytes> represents bytes*2^30	@tparam U unit type to apply the prefix to.
-	template<class U> using tebi	= typename units::detail::prefix<std::ratio<1099511627776>,			U>::type;	///< Represents the type of `class U` with the binary 'tebi' prefix appended.	@details E.g. tebi<bytes> represents bytes*2^40	@tparam U unit type to apply the prefix to.
-	template<class U> using pebi	= typename units::detail::prefix<std::ratio<1125899906842624>,		U>::type;	///< Represents the type of `class U` with the binary 'pebi' prefix appended.	@details E.g. pebi<bytes> represents bytes*2^50	@tparam U unit type to apply the prefix to.
-	template<class U> using exbi	= typename units::detail::prefix<std::ratio<1152921504606846976>,	U>::type;	///< Represents the type of `class U` with the binary 'exbi' prefix appended.	@details E.g. exbi<bytes> represents bytes*2^60	@tparam U unit type to apply the prefix to.
-	/** @} @} */
-
-	//------------------------------
-	//	CONVERSION TRAITS
-	//------------------------------
-
-	namespace traits
-	{
-		/**
-		 * @ingroup		TypeTraits
-		 * @brief		Trait which checks whether two units can be converted to each other
-		 * @details		Inherits from `std::true_type` or `std::false_type`. Use `is_convertible_unit<U1, U2>::value` to test
-		 *				whether `class U1` is convertible to `class U2`. Note: convertible has both the semantic meaning,
-		 *				(i.e. meters can be converted to feet), and the c++ meaning of conversion (type meters can be
-		 *				converted to type feet). Conversion is always symmetric, so if U1 is convertible to U2, then
-		 *				U2 will be convertible to U1.
-		 * @tparam		U1 Unit to convert from.
-		 * @tparam		U2 Unit to convert to.
-		 * @sa			is_convertible_unit_t
-		 */
-		template<class U1, class U2>
-		struct is_convertible_unit : std::is_same <traits::base_unit_of<typename units::traits::unit_traits<U1>::base_unit_type>,
-			base_unit_of<typename units::traits::unit_traits<U2>::base_unit_type >> {};
-	}
-
-	//------------------------------
-	//	CONVERSION FUNCTION
-	//------------------------------
-
-	/** @cond */	// DOXYGEN IGNORE
-	namespace detail
-	{
-		constexpr inline UNIT_LIB_DEFAULT_TYPE pow(UNIT_LIB_DEFAULT_TYPE x, unsigned long long y)
-		{
-			return y == 0 ? 1.0 : x * pow(x, y - 1);
-		}
-
-		constexpr inline UNIT_LIB_DEFAULT_TYPE abs(UNIT_LIB_DEFAULT_TYPE x)
-		{
-			return x < 0 ? -x : x;
-		}
-
-		/// convert dispatch for units which are both the same
-		template<class UnitFrom, class UnitTo, class Ratio, class PiRatio, class Translation, typename T>
-		static inline constexpr T convert(const T& value, std::true_type, std::false_type, std::false_type) noexcept
-		{
-			return value;
-		}
-
-		/// convert dispatch for units which are both the same
-		template<class UnitFrom, class UnitTo, class Ratio, class PiRatio, class Translation, typename T>
-		static inline constexpr T convert(const T& value, std::true_type, std::false_type, std::true_type) noexcept
-		{
-			return value;
-		}
-
-		/// convert dispatch for units which are both the same
-		template<class UnitFrom, class UnitTo, class Ratio, class PiRatio, class Translation, typename T>
-		static inline constexpr T convert(const T& value, std::true_type, std::true_type, std::false_type) noexcept
-		{
-			return value;
-		}
-
-		/// convert dispatch for units which are both the same
-		template<class UnitFrom, class UnitTo, class Ratio, class PiRatio, class Translation, typename T>
-		static inline constexpr T convert(const T& value, std::true_type, std::true_type, std::true_type) noexcept
-		{
-			return value;
-		}
-
-		/// convert dispatch for units of different types w/ no translation and no PI
-		template<class UnitFrom, class UnitTo, class Ratio, class PiRatio, class Translation, typename T>
-		static inline constexpr T convert(const T& value, std::false_type, std::false_type, std::false_type) noexcept
-		{
-			return ((value * Ratio::num) / Ratio::den);
-		}
-
-		/// convert dispatch for units of different types w/ no translation, but has PI in numerator
-		// constepxr with PI in numerator
-		template<class UnitFrom, class UnitTo, class Ratio, class PiRatio, class Translation, typename T>
-		static inline constexpr
-		std::enable_if_t<(PiRatio::num / PiRatio::den >= 1 && PiRatio::num % PiRatio::den == 0), T>
-		convert(const T& value, std::false_type, std::true_type, std::false_type) noexcept
-		{
-			return ((value * pow(constants::detail::PI_VAL, PiRatio::num / PiRatio::den) * Ratio::num) / Ratio::den);
-		}
-
-		/// convert dispatch for units of different types w/ no translation, but has PI in denominator
-		// constexpr with PI in denominator
-		template<class UnitFrom, class UnitTo, class Ratio, class PiRatio, class Translation, typename T>
-		static inline constexpr
-		std::enable_if_t<(PiRatio::num / PiRatio::den <= -1 && PiRatio::num % PiRatio::den == 0), T>
- 		convert(const T& value, std::false_type, std::true_type, std::false_type) noexcept
- 		{
- 			return (value * Ratio::num) / (Ratio::den * pow(constants::detail::PI_VAL, -PiRatio::num / PiRatio::den));
- 		}
-
-		/// convert dispatch for units of different types w/ no translation, but has PI in numerator
-		// Not constexpr - uses std::pow
-		template<class UnitFrom, class UnitTo, class Ratio, class PiRatio, class Translation, typename T>
-		static inline // sorry, this can't be constexpr!
-		std::enable_if_t<(PiRatio::num / PiRatio::den < 1 && PiRatio::num / PiRatio::den > -1), T>
-		convert(const T& value, std::false_type, std::true_type, std::false_type) noexcept
-		{
-			return ((value * std::pow(constants::detail::PI_VAL, PiRatio::num / PiRatio::den)  * Ratio::num) / Ratio::den);
-		}
-
-		/// convert dispatch for units of different types with a translation, but no PI
-		template<class UnitFrom, class UnitTo, class Ratio, class PiRatio, class Translation, typename T>
-		static inline constexpr T convert(const T& value, std::false_type, std::false_type, std::true_type) noexcept
-		{
-			return ((value * Ratio::num) / Ratio::den) + (static_cast<UNIT_LIB_DEFAULT_TYPE>(Translation::num) / Translation::den);
-		}
-
-		/// convert dispatch for units of different types with a translation AND PI
-		template<class UnitFrom, class UnitTo, class Ratio, class PiRatio, class Translation, typename T>
-		static inline constexpr T convert(const T& value, const std::false_type, const std::true_type, const std::true_type) noexcept
-		{
-			return ((value * std::pow(constants::detail::PI_VAL, PiRatio::num / PiRatio::den) * Ratio::num) / Ratio::den) + (static_cast<UNIT_LIB_DEFAULT_TYPE>(Translation::num) / Translation::den);
-		}
-	}
-	/** @endcond */	// END DOXYGEN IGNORE
-
-	/**
-	 * @ingroup		Conversion
-	 * @brief		converts a <i>value</i> from one type to another.
-	 * @details		Converts a <i>value</i> of a built-in arithmetic type to another unit. This does not change
-	 *				the type of <i>value</i>, only what it contains. E.g. @code double result = convert<length::meters, length::feet>(1.0);	// result == 3.28084 @endcode
-	 * @sa			unit_t	for implicit conversion of unit containers.
-	 * @tparam		UnitFrom unit tag to convert <i>value</i> from. Must be a `unit` type (i.e. is_unit<UnitFrom>::value == true),
-	 *				and must be convertible to `UnitTo` (i.e. is_convertible_unit<UnitFrom, UnitTo>::value == true).
-	 * @tparam		UnitTo unit tag to convert <i>value</i> to. Must be a `unit` type (i.e. is_unit<UnitTo>::value == true),
-	 *				and must be convertible from `UnitFrom` (i.e. is_convertible_unit<UnitFrom, UnitTo>::value == true).
-	 * @tparam		T type of <i>value</i>. It is inferred from <i>value</i>, and is expected to be a built-in arithmetic type.
-	 * @param[in]	value Arithmetic value to convert from `UnitFrom` to `UnitTo`. The value should represent
-	 *				a quantity in units of `UnitFrom`.
-	 * @returns		value, converted from units of `UnitFrom` to `UnitTo`.
-	 */
-	template<class UnitFrom, class UnitTo, typename T = UNIT_LIB_DEFAULT_TYPE>
-	static inline constexpr T convert(const T& value) noexcept
-	{
-		static_assert(traits::is_unit<UnitFrom>::value, "Template parameter `UnitFrom` must be a `unit` type.");
-		static_assert(traits::is_unit<UnitTo>::value, "Template parameter `UnitTo` must be a `unit` type.");
-		static_assert(traits::is_convertible_unit<UnitFrom, UnitTo>::value, "Units are not compatible.");
-
-		using Ratio = std::ratio_divide<typename UnitFrom::conversion_ratio, typename UnitTo::conversion_ratio>;
-		using PiRatio = std::ratio_subtract<typename UnitFrom::pi_exponent_ratio, typename UnitTo::pi_exponent_ratio>;
-		using Translation = std::ratio_divide<std::ratio_subtract<typename UnitFrom::translation_ratio, typename UnitTo::translation_ratio>, typename UnitTo::conversion_ratio>;
-
-		using isSame = typename std::is_same<std::decay_t<UnitFrom>, std::decay_t<UnitTo>>::type;
-		using piRequired = std::integral_constant<bool, !(std::is_same<std::ratio<0>, PiRatio>::value)>;
-		using translationRequired = std::integral_constant<bool, !(std::is_same<std::ratio<0>, Translation>::value)>;
-
-		return units::detail::convert<UnitFrom, UnitTo, Ratio, PiRatio, Translation, T>
-			(value, isSame{}, piRequired{}, translationRequired{});
-	}
-
-	//----------------------------------
-	//	NON-LINEAR SCALE TRAITS
-	//----------------------------------
-
-	/** @cond */	// DOXYGEN IGNORE
-	namespace traits
-	{
-		namespace detail
-		{
-			/**
-			* @brief		implementation of has_operator_parenthesis
-			* @details		checks that operator() returns the same type as `Ret`
-			*/
-			template<class T, class Ret>
-			struct has_operator_parenthesis_impl
-			{
-				template<class U>
-				static constexpr auto test(U*) -> decltype(std::declval<U>()()) { return decltype(std::declval<U>()()){}; }
-				template<typename>
-				static constexpr std::false_type test(...) { return std::false_type{}; }
-
-				using type = typename std::is_same<Ret, decltype(test<T>(0))>::type;
-			};
-		}
-
-		/**
-		 * @brief		checks that `class T` has an `operator()` member which returns `Ret`
-		 * @details		used as part of the linear_scale concept.
-		 */
-		template<class T, class Ret>
-		struct has_operator_parenthesis : traits::detail::has_operator_parenthesis_impl<T, Ret>::type {};
-	}
-
-	namespace traits
-	{
-		namespace detail
-		{
-			/**
-			* @brief		implementation of has_value_member
-			* @details		checks for a member named `m_member` with type `Ret`
-			*/
-			template<class T, class Ret>
-			struct has_value_member_impl
-			{
-				template<class U>
-				static constexpr auto test(U* p) -> decltype(p->m_value) { return p->m_value; }
-				template<typename>
-				static constexpr auto test(...)->std::false_type { return std::false_type{}; }
-
-				using type = typename std::is_same<std::decay_t<Ret>, std::decay_t<decltype(test<T>(0))>>::type;
-			};
-		}
-
-		/**
-		 * @brief		checks for a member named `m_member` with type `Ret`
-		 * @details		used as part of the linear_scale concept checker.
-		 */
-		template<class T, class Ret>
-		struct has_value_member : traits::detail::has_value_member_impl<T, Ret>::type {};
-	}
-	/** @endcond */	// END DOXYGEN IGNORE
-
-	namespace traits
-	{
-		/**
-		 * @ingroup		TypeTraits
-		 * @brief		Trait which tests that `class T` meets the requirements for a non-linear scale
-		 * @details		A non-linear scale must:
-		 *				- be default constructible
-		 *				- have an `operator()` member which returns the non-linear value stored in the scale
-		 *				- have an accessible `m_value` member type which stores the linearized value in the scale.
-		 *
-		 *				Linear/nonlinear scales are used by `units::unit` to store values and scale them
-		 *				if they represent things like dB.
-		 */
-		template<class T, class Ret>
-		struct is_nonlinear_scale : std::integral_constant<bool,
-			std::is_default_constructible<T>::value &&
-			has_operator_parenthesis<T, Ret>::value &&
-			has_value_member<T, Ret>::value &&
-			std::is_trivial<T>::value>
-		{};
-	}
-
-	//------------------------------
-	//	UNIT_T TYPE TRAITS
-	//------------------------------
-
-	namespace traits
-	{
-#ifdef FOR_DOXYGEN_PURPOSOES_ONLY
-		/**
-		* @ingroup		TypeTraits
-		* @brief		Trait for accessing the publically defined types of `units::unit_t`
-		* @details		The units library determines certain properties of the unit_t types passed to them
-		*				and what they represent by using the members of the corresponding unit_t_traits instantiation.
-		*/
-		template<typename T>
-		struct unit_t_traits
-		{
-			typedef typename T::non_linear_scale_type non_linear_scale_type;	///< Type of the unit_t non_linear_scale (e.g. linear_scale, decibel_scale). This property is used to enable the proper linear or logarithmic arithmetic functions.
-			typedef typename T::underlying_type underlying_type;				///< Underlying storage type of the `unit_t`, e.g. `double`.
-			typedef typename T::value_type value_type;							///< Synonym for underlying type. May be removed in future versions. Prefer underlying_type.
-			typedef typename T::unit_type unit_type;							///< Type of unit the `unit_t` represents, e.g. `meters`
-		};
-#endif
-
-		/** @cond */	// DOXYGEN IGNORE
-		/**
-		 * @brief		unit_t_traits specialization for things which are not unit_t
-		 * @details
-		 */
-		template<typename T, typename = void>
-		struct unit_t_traits
-		{
-			typedef void non_linear_scale_type;
-			typedef void underlying_type;
-			typedef void value_type;
-			typedef void unit_type;
-		};
-	
-		/**
-		 * @ingroup		TypeTraits
-		 * @brief		Trait for accessing the publically defined types of `units::unit_t`
-		 * @details
-		 */
-		template<typename T>
-		struct unit_t_traits <T, typename void_t<
-			typename T::non_linear_scale_type,
-			typename T::underlying_type,
-			typename T::value_type,
-			typename T::unit_type>::type>
-		{
-			typedef typename T::non_linear_scale_type non_linear_scale_type;
-			typedef typename T::underlying_type underlying_type;
-			typedef typename T::value_type value_type;
-			typedef typename T::unit_type unit_type;
-		};
-		/** @endcond */	// END DOXYGEN IGNORE
-	}
-
-	namespace traits
-	{
-		/**
-		 * @ingroup		TypeTraits
-		 * @brief		Trait which tests whether two container types derived from `unit_t` are convertible to each other
-		 * @details		Inherits from `std::true_type` or `std::false_type`. Use `is_convertible_unit_t<U1, U2>::value` to test
-		 *				whether `class U1` is convertible to `class U2`. Note: convertible has both the semantic meaning,
-		 *				(i.e. meters can be converted to feet), and the c++ meaning of conversion (type meters can be
-		 *				converted to type feet). Conversion is always symmetric, so if U1 is convertible to U2, then
-		 *				U2 will be convertible to U1.
-		 * @tparam		U1 Unit to convert from.
-		 * @tparam		U2 Unit to convert to.
-		 * @sa			is_convertible_unit
-		 */
-		template<class U1, class U2>
-		struct is_convertible_unit_t : std::integral_constant<bool,
-			is_convertible_unit<typename units::traits::unit_t_traits<U1>::unit_type, typename units::traits::unit_t_traits<U2>::unit_type>::value>
-		{};
-	}
-
-	//---------------------------------- 
-	//	UNIT TYPE
-	//----------------------------------
-
-	/** @cond */	// DOXYGEN IGNORE
-	// forward declaration
-	template<typename T> struct linear_scale;
-	template<typename T> struct decibel_scale;
-
-	namespace detail
-	{
-		/**
-		* @brief		helper type to identify units.
-		* @details		A non-templated base class for `unit` which enables RTTI testing.
-		*/
-		struct _unit_t {};
-	}
-	/** @endcond */	// END DOXYGEN IGNORE
-
-	namespace traits
-	{
-		// forward declaration
-		#if !defined(_MSC_VER) || _MSC_VER > 1800 // bug in VS2013 prevents this from working
-		template<typename... T> struct is_dimensionless_unit;
-		#else
-		template<typename T1, typename T2 = T1, typename T3 = T1> struct is_dimensionless_unit;
-		#endif
-
-		/**
-		 * @ingroup		TypeTraits
-		 * @brief		Traits which tests if a class is a `unit`
-		 * @details		Inherits from `std::true_type` or `std::false_type`. Use `is_unit<T>::value` to test
-		 *				whether `class T` implements a `unit`.
-		 */
-		template<class T>
-		struct is_unit_t : std::is_base_of<units::detail::_unit_t, T>::type {};
-	}
-
-	/**
-	 * @ingroup		UnitContainers
-	 * @brief		Container for values which represent quantities of a given unit.
-	 * @details		Stores a value which represents a quantity in the given units. Unit containers
-	 *				(except scalar values) are *not* convertible to built-in c++ types, in order to
-	 *				provide type safety in dimensional analysis. Unit containers *are* implicitly
-	 *				convertible to other compatible unit container types. Unit containers support
-	 *				various types of arithmetic operations, depending on their scale type.
-	 *
-	 *				The value of a `unit_t` can only be changed on construction, or by assignment
-	 *				from another `unit_t` type. If necessary, the underlying value can be accessed
-	 *				using `operator()`: @code
-	 *				meter_t m(5.0);
-	 *				double val = m(); // val == 5.0	@endcode.
-	 * @tparam		Units unit tag for which type of units the `unit_t` represents (e.g. meters)
-	 * @tparam		T underlying type of the storage. Defaults to double.
-	 * @tparam		NonLinearScale optional scale class for the units. Defaults to linear (i.e. does
-	 *				not scale the unit value). Examples of non-linear scales could be logarithmic,
-	 *				decibel, or richter scales. Non-linear scales must adhere to the non-linear-scale
-	 *				concept, i.e. `is_nonlinear_scale<...>::value` must be `true`.
-	 * @sa
-	 *				- \ref lengthContainers "length unit containers"
-	 *				- \ref massContainers "mass unit containers"
-	 *				- \ref timeContainers "time unit containers"
-	 *				- \ref angleContainers "angle unit containers"
-	 *				- \ref currentContainers "current unit containers"
-	 *				- \ref temperatureContainers "temperature unit containers"
-	 *				- \ref substanceContainers "substance unit containers"
-	 *				- \ref luminousIntensityContainers "luminous intensity unit containers"
-	 *				- \ref solidAngleContainers "solid angle unit containers"
-	 *				- \ref frequencyContainers "frequency unit containers"
-	 *				- \ref velocityContainers "velocity unit containers"
-	 *				- \ref angularVelocityContainers "angular velocity unit containers"
-	 *				- \ref accelerationContainers "acceleration unit containers"
-	 *				- \ref forceContainers "force unit containers"
-	 *				- \ref pressureContainers "pressure unit containers"
-	 *				- \ref chargeContainers "charge unit containers"
-	 *				- \ref energyContainers "energy unit containers"
-	 *				- \ref powerContainers "power unit containers"
-	 *				- \ref voltageContainers "voltage unit containers"
-	 *				- \ref capacitanceContainers "capacitance unit containers"
-	 *				- \ref impedanceContainers "impedance unit containers"
-	 *				- \ref magneticFluxContainers "magnetic flux unit containers"
-	 *				- \ref magneticFieldStrengthContainers "magnetic field strength unit containers"
-	 *				- \ref inductanceContainers "inductance unit containers"
-	 *				- \ref luminousFluxContainers "luminous flux unit containers"
-	 *				- \ref illuminanceContainers "illuminance unit containers"
-	 *				- \ref radiationContainers "radiation unit containers"
-	 *				- \ref torqueContainers "torque unit containers"
-	 *				- \ref areaContainers "area unit containers"
-	 *				- \ref volumeContainers "volume unit containers"
-	 *				- \ref densityContainers "density unit containers"
-	 *				- \ref concentrationContainers "concentration unit containers"
-	 *				- \ref constantContainers "constant unit containers"
-	 */
-	template<class Units, typename T = UNIT_LIB_DEFAULT_TYPE, template<typename> class NonLinearScale = linear_scale>
-	class unit_t : public NonLinearScale<T>, units::detail::_unit_t
-	{
-		static_assert(traits::is_unit<Units>::value, "Template parameter `Units` must be a unit tag. Check that you aren't using a unit type (_t).");
-		static_assert(traits::is_nonlinear_scale<NonLinearScale<T>, T>::value, "Template parameter `NonLinearScale` does not conform to the `is_nonlinear_scale` concept.");
-
-	protected:
-
-		using nls = NonLinearScale<T>;
-		using nls::m_value;
-
-	public:
-
-		typedef NonLinearScale<T> non_linear_scale_type;											///< Type of the non-linear scale of the unit_t (e.g. linear_scale)
-		typedef T underlying_type;																	///< Type of the underlying storage of the unit_t (e.g. double)
-		typedef T value_type;																		///< Synonym for underlying type. May be removed in future versions. Prefer underlying_type.
-		typedef Units unit_type;																	///< Type of `unit` the `unit_t` represents (e.g. meters)
-
-		/**
-		 * @ingroup		Constructors
-		 * @brief		default constructor.
-		 */
-		constexpr unit_t() = default;
-
-		/**
-		 * @brief		constructor
-		 * @details		constructs a new unit_t using the non-linear scale's constructor.
-		 * @param[in]	value	unit value magnitude.
-		 * @param[in]	args	additional constructor arguments are forwarded to the non-linear scale constructor. Which
-		 *						args are required depends on which scale is used. For the default (linear) scale,
-		 *						no additional args are necessary.
-		 */
-		template<class... Args>
-		inline explicit constexpr unit_t(const T value, const Args&... args) noexcept : nls(value, args...) 
-		{
-
-		}
-
-		/**
-		 * @brief		constructor
-		 * @details		enable implicit conversions from T types ONLY for linear scalar units
-		 * @param[in]	value value of the unit_t
-		 */
-		template<class Ty, class = typename std::enable_if<traits::is_dimensionless_unit<Units>::value && std::is_arithmetic<Ty>::value>::type>
-		inline constexpr unit_t(const Ty value) noexcept : nls(value) 
-		{
-
-		}
-
-		/**
-		 * @brief		chrono constructor
-		 * @details		enable implicit conversions from std::chrono::duration types ONLY for time units
-		 * @param[in]	value value of the unit_t
-		 */
-		template<class Rep, class Period, class = std::enable_if_t<std::is_arithmetic<Rep>::value && traits::is_ratio<Period>::value>>
-		inline constexpr unit_t(const std::chrono::duration<Rep, Period>& value) noexcept : 
-		nls(units::convert<unit<std::ratio<1,1000000000>, category::time_unit>, Units>(static_cast<T>(std::chrono::duration_cast<std::chrono::nanoseconds>(value).count()))) 
-		{
-
-		}
-
-		/**
-		 * @brief		copy constructor (converting)
-		 * @details		performs implicit unit conversions if required.
-		 * @param[in]	rhs unit to copy.
-		 */
-		template<class UnitsRhs, typename Ty, template<typename> class NlsRhs>
-		inline constexpr unit_t(const unit_t<UnitsRhs, Ty, NlsRhs>& rhs) noexcept :
-		nls(units::convert<UnitsRhs, Units, T>(rhs.m_value), std::true_type() /*store linear value*/)
-		{
-
-		}
-
-		/**
-		 * @brief		assignment
-		 * @details		performs implicit unit conversions if required
-		 * @param[in]	rhs unit to copy.
-		 */
-		template<class UnitsRhs, typename Ty, template<typename> class NlsRhs>
-		inline unit_t& operator=(const unit_t<UnitsRhs, Ty, NlsRhs>& rhs) noexcept
-		{		
-			nls::m_value = units::convert<UnitsRhs, Units, T>(rhs.m_value);
-			return *this;
-		}
-
-		/**
-		* @brief		assignment
-		* @details		performs implicit conversions from built-in types ONLY for scalar units
-		* @param[in]	rhs value to copy.
-		*/
-		template<class Ty, class = std::enable_if_t<traits::is_dimensionless_unit<Units>::value && std::is_arithmetic<Ty>::value>>
-		inline unit_t& operator=(const Ty& rhs) noexcept
-		{
-			nls::m_value = rhs;
-			return *this;
-		}
-
-		/**
-		 * @brief		less-than
-		 * @details		compares the linearized value of two units. Performs unit conversions if necessary.
-		 * @param[in]	rhs right-hand side unit for the comparison
-		 * @returns		true IFF the value of `this` is less than the value of `rhs`
-		 */
-		template<class UnitsRhs, typename Ty, template<typename> class NlsRhs>
-		inline constexpr bool operator<(const unit_t<UnitsRhs, Ty, NlsRhs>& rhs) const noexcept
-		{
-			return (nls::m_value < units::convert<UnitsRhs, Units>(rhs.m_value));
-		}
-
-		/**
-		 * @brief		less-than or equal
-		 * @details		compares the linearized value of two units. Performs unit conversions if necessary.
-		 * @param[in]	rhs right-hand side unit for the comparison
-		 * @returns		true IFF the value of `this` is less than or equal to the value of `rhs`
-		 */
-		template<class UnitsRhs, typename Ty, template<typename> class NlsRhs>
-		inline constexpr bool operator<=(const unit_t<UnitsRhs, Ty, NlsRhs>& rhs) const noexcept
-		{
-			return (nls::m_value <= units::convert<UnitsRhs, Units>(rhs.m_value));
-		}
-
-		/**
-		 * @brief		greater-than
-		 * @details		compares the linearized value of two units. Performs unit conversions if necessary.
-		 * @param[in]	rhs right-hand side unit for the comparison
-		 * @returns		true IFF the value of `this` is greater than the value of `rhs`
-		 */
-		template<class UnitsRhs, typename Ty, template<typename> class NlsRhs>
-		inline constexpr bool operator>(const unit_t<UnitsRhs, Ty, NlsRhs>& rhs) const noexcept
-		{
-			return (nls::m_value > units::convert<UnitsRhs, Units>(rhs.m_value));
-		}
-
-		/**
-		 * @brief		greater-than or equal
-		 * @details		compares the linearized value of two units. Performs unit conversions if necessary.
-		 * @param[in]	rhs right-hand side unit for the comparison
-		 * @returns		true IFF the value of `this` is greater than or equal to the value of `rhs`
-		 */
-		template<class UnitsRhs, typename Ty, template<typename> class NlsRhs>
-		inline constexpr bool operator>=(const unit_t<UnitsRhs, Ty, NlsRhs>& rhs) const noexcept
-		{
-			return (nls::m_value >= units::convert<UnitsRhs, Units>(rhs.m_value));
-		}
-
-		/**
-		 * @brief		equality
-		 * @details		compares the linearized value of two units. Performs unit conversions if necessary.
-		 * @param[in]	rhs right-hand side unit for the comparison
-		 * @returns		true IFF the value of `this` exactly equal to the value of rhs.
-		 * @note		This may not be suitable for all applications when the underlying_type of unit_t is a double.
-		 */
-		template<class UnitsRhs, typename Ty, template<typename> class NlsRhs, std::enable_if_t<std::is_floating_point<T>::value || std::is_floating_point<Ty>::value, int> = 0>
-		inline constexpr bool operator==(const unit_t<UnitsRhs, Ty, NlsRhs>& rhs) const noexcept
-		{
-			return detail::abs(nls::m_value - units::convert<UnitsRhs, Units>(rhs.m_value)) < std::numeric_limits<T>::epsilon() * 
-				detail::abs(nls::m_value + units::convert<UnitsRhs, Units>(rhs.m_value)) ||
-				detail::abs(nls::m_value - units::convert<UnitsRhs, Units>(rhs.m_value)) < std::numeric_limits<T>::min();
-		}
-
-		template<class UnitsRhs, typename Ty, template<typename> class NlsRhs, std::enable_if_t<std::is_integral<T>::value && std::is_integral<Ty>::value, int> = 0>
-		inline constexpr bool operator==(const unit_t<UnitsRhs, Ty, NlsRhs>& rhs) const noexcept
-		{
-			return nls::m_value == units::convert<UnitsRhs, Units>(rhs.m_value);
-		}
-
-		/**
-		 * @brief		inequality
-		 * @details		compares the linearized value of two units. Performs unit conversions if necessary.
-		 * @param[in]	rhs right-hand side unit for the comparison
-		 * @returns		true IFF the value of `this` is not equal to the value of rhs.
-		 * @note		This may not be suitable for all applications when the underlying_type of unit_t is a double.
-		 */
-		template<class UnitsRhs, typename Ty, template<typename> class NlsRhs>
-		inline constexpr bool operator!=(const unit_t<UnitsRhs, Ty, NlsRhs>& rhs) const noexcept
-		{
-			return !(*this == rhs);
-		}
-
-		/**
-		 * @brief		unit value
-		 * @returns		value of the unit in it's underlying, non-safe type.
-		 */
-		inline constexpr underlying_type value() const noexcept
-		{
-			return static_cast<underlying_type>(*this);
-		}
-
-		/**
-		 * @brief		unit value
-		 * @returns		value of the unit converted to an arithmetic, non-safe type.
-		 */
-		template<typename Ty, class = std::enable_if_t<std::is_arithmetic<Ty>::value>>
-		inline constexpr Ty to() const noexcept
-		{
-			return static_cast<Ty>(*this);
-		}
-
-		/**
-		 * @brief		linearized unit value
-		 * @returns		linearized value of unit which has a non-linear scale. For `unit_t` types with
-		 *				linear scales, this is equivalent to `value`.
-		 */
-		template<typename Ty, class = std::enable_if_t<std::is_arithmetic<Ty>::value>>
-		inline constexpr Ty toLinearized() const noexcept
-		{
-			return static_cast<Ty>(m_value);
-		}
-
-		/**
-		 * @brief		conversion
-		 * @details		Converts to a different unit container. Units can be converted to other containers
-		 *				implicitly, but this can be used in cases where explicit notation of a conversion
-		 *				is beneficial, or where an r-value container is needed.
-		 * @tparam		U unit (not unit_t) to convert to
-		 * @returns		a unit container with the specified units containing the equivalent value to
-		 *				*this.
-		 */
-		template<class U>
-		inline constexpr unit_t<U> convert() const noexcept
-		{
-			static_assert(traits::is_unit<U>::value, "Template parameter `U` must be a unit type.");
-			return unit_t<U>(*this);
-		}
-
-		/**
-		 * @brief		implicit type conversion.
-		 * @details		only enabled for scalar unit types.
-		 */
-		template<class Ty, std::enable_if_t<traits::is_dimensionless_unit<Units>::value && std::is_arithmetic<Ty>::value, int> = 0>
-		inline constexpr operator Ty() const noexcept 
-		{ 
-			// this conversion also resolves any PI exponents, by converting from a non-zero PI ratio to a zero-pi ratio.
-			return static_cast<Ty>(units::convert<Units, unit<std::ratio<1>, units::category::scalar_unit>>((*this)()));
-		}
-
-		/**
-		 * @brief		explicit type conversion.
-		 * @details		only enabled for non-dimensionless unit types.
-		 */
-		template<class Ty, std::enable_if_t<!traits::is_dimensionless_unit<Units>::value && std::is_arithmetic<Ty>::value, int> = 0>
-		inline constexpr explicit operator Ty() const noexcept
-		{
-			return static_cast<Ty>((*this)());
-		}
-
-		/**
-		 * @brief		chrono implicit type conversion.
-		 * @details		only enabled for time unit types.
-		 */
-		template<typename U = Units, std::enable_if_t<units::traits::is_convertible_unit<U, unit<std::ratio<1>, category::time_unit>>::value, int> = 0>
-		inline constexpr operator std::chrono::nanoseconds() const noexcept
-		{
-			return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::duration<double, std::nano>(units::convert<Units, unit<std::ratio<1,1000000000>, category::time_unit>>((*this)())));
-		}
-
-		/**
-		 * @brief		returns the unit name
-		 */
-		inline constexpr const char* name() const noexcept
-		{
-			return units::name(*this);
-		}
-
-		/**
-		 * @brief		returns the unit abbreviation
-		 */
-		inline constexpr const char* abbreviation() const noexcept
-		{
-			return units::abbreviation(*this);
-		}
-
-	public:
-
-		template<class U, typename Ty, template<typename> class Nlt>
-		friend class unit_t;
-	};
-
-	//------------------------------
-	//	UNIT_T NON-MEMBER FUNCTIONS
-	//------------------------------
-
-	/**
-	 * @ingroup		UnitContainers
-	 * @brief		Constructs a unit container from an arithmetic type.
-	 * @details		make_unit can be used to construct a unit container from an arithmetic type, as an alternative to
-	 *				using the explicit constructor. Unlike the explicit constructor it forces the user to explicitly
-	 *				specify the units.
-	 * @tparam		UnitType Type to construct.
-	 * @tparam		Ty		Arithmetic type.
-	 * @param[in]	value	Arithmetic value that represents a quantity in units of `UnitType`.
-	 */
-	template<class UnitType, typename T, class = std::enable_if_t<std::is_arithmetic<T>::value>>
-	inline constexpr UnitType make_unit(const T value) noexcept
-	{
-		static_assert(traits::is_unit_t<UnitType>::value, "Template parameter `UnitType` must be a unit type (_t).");
-		
-		return UnitType(value);
-	}
-
-#if !defined(UNIT_LIB_DISABLE_IOSTREAM)
-	template<class Units, typename T, template<typename> class NonLinearScale>
-	inline std::ostream& operator<<(std::ostream& os, const unit_t<Units, T, NonLinearScale>& obj) noexcept
-	{
-		using BaseUnits = unit<std::ratio<1>, typename traits::unit_traits<Units>::base_unit_type>;
-		os << convert<Units, BaseUnits>(obj());
-
-		if (traits::unit_traits<Units>::base_unit_type::meter_ratio::num != 0) { os << " m"; }
-		if (traits::unit_traits<Units>::base_unit_type::meter_ratio::num != 0 && 
-			traits::unit_traits<Units>::base_unit_type::meter_ratio::num != 1) { os << "^" << traits::unit_traits<Units>::base_unit_type::meter_ratio::num; }
-		if (traits::unit_traits<Units>::base_unit_type::meter_ratio::den != 1) { os << "/"   << traits::unit_traits<Units>::base_unit_type::meter_ratio::den; }
-
-		if (traits::unit_traits<Units>::base_unit_type::kilogram_ratio::num != 0) { os << " kg"; }
-		if (traits::unit_traits<Units>::base_unit_type::kilogram_ratio::num != 0 &&
-			traits::unit_traits<Units>::base_unit_type::kilogram_ratio::num != 1) { os << "^" << traits::unit_traits<Units>::base_unit_type::kilogram_ratio::num; }
-		if (traits::unit_traits<Units>::base_unit_type::kilogram_ratio::den != 1) { os << "/" << traits::unit_traits<Units>::base_unit_type::kilogram_ratio::den; }
-
-		if (traits::unit_traits<Units>::base_unit_type::second_ratio::num != 0) { os << " s"; }
-		if (traits::unit_traits<Units>::base_unit_type::second_ratio::num != 0 &&
-			traits::unit_traits<Units>::base_unit_type::second_ratio::num != 1) { os << "^" << traits::unit_traits<Units>::base_unit_type::second_ratio::num; }
-		if (traits::unit_traits<Units>::base_unit_type::second_ratio::den != 1) { os << "/" << traits::unit_traits<Units>::base_unit_type::second_ratio::den; }
-
-		if (traits::unit_traits<Units>::base_unit_type::ampere_ratio::num != 0) { os << " A"; }
-		if (traits::unit_traits<Units>::base_unit_type::ampere_ratio::num != 0 &&
-			traits::unit_traits<Units>::base_unit_type::ampere_ratio::num != 1) { os << "^" << traits::unit_traits<Units>::base_unit_type::ampere_ratio::num; }
-		if (traits::unit_traits<Units>::base_unit_type::ampere_ratio::den != 1) { os << "/" << traits::unit_traits<Units>::base_unit_type::ampere_ratio::den; }
-
-		if (traits::unit_traits<Units>::base_unit_type::kelvin_ratio::num != 0) { os << " K"; }
-		if (traits::unit_traits<Units>::base_unit_type::kelvin_ratio::num != 0 &&
-			traits::unit_traits<Units>::base_unit_type::kelvin_ratio::num != 1) { os << "^" << traits::unit_traits<Units>::base_unit_type::kelvin_ratio::num; }
-		if (traits::unit_traits<Units>::base_unit_type::kelvin_ratio::den != 1) { os << "/" << traits::unit_traits<Units>::base_unit_type::kelvin_ratio::den; }
-
-		if (traits::unit_traits<Units>::base_unit_type::mole_ratio::num != 0) { os << " mol"; }
-		if (traits::unit_traits<Units>::base_unit_type::mole_ratio::num != 0 && 
-			traits::unit_traits<Units>::base_unit_type::mole_ratio::num != 1) { os << "^" << traits::unit_traits<Units>::base_unit_type::mole_ratio::num; }
-		if (traits::unit_traits<Units>::base_unit_type::mole_ratio::den != 1) { os << "/" << traits::unit_traits<Units>::base_unit_type::mole_ratio::den; }
-
-		if (traits::unit_traits<Units>::base_unit_type::candela_ratio::num != 0) { os << " cd"; }
-		if (traits::unit_traits<Units>::base_unit_type::candela_ratio::num != 0 &&
-			traits::unit_traits<Units>::base_unit_type::candela_ratio::num != 1) { os << "^" << traits::unit_traits<Units>::base_unit_type::candela_ratio::num; }
-		if (traits::unit_traits<Units>::base_unit_type::candela_ratio::den != 1) { os << "/" << traits::unit_traits<Units>::base_unit_type::candela_ratio::den; }
-
-		if (traits::unit_traits<Units>::base_unit_type::radian_ratio::num != 0) { os << " rad"; }
-		if (traits::unit_traits<Units>::base_unit_type::radian_ratio::num != 0 &&
-			traits::unit_traits<Units>::base_unit_type::radian_ratio::num != 1) { os << "^" << traits::unit_traits<Units>::base_unit_type::radian_ratio::num; }
-		if (traits::unit_traits<Units>::base_unit_type::radian_ratio::den != 1) { os << "/" << traits::unit_traits<Units>::base_unit_type::radian_ratio::den; }
-
-		if (traits::unit_traits<Units>::base_unit_type::byte_ratio::num != 0) { os << " b"; }
-		if (traits::unit_traits<Units>::base_unit_type::byte_ratio::num != 0 &&
-			traits::unit_traits<Units>::base_unit_type::byte_ratio::num != 1) { os << "^" << traits::unit_traits<Units>::base_unit_type::byte_ratio::num; }
-		if (traits::unit_traits<Units>::base_unit_type::byte_ratio::den != 1) { os << "/" << traits::unit_traits<Units>::base_unit_type::byte_ratio::den; }
-
-		return os;
-	}
-#endif
-
-	template<class Units, typename T, template<typename> class NonLinearScale, typename RhsType>
-	inline unit_t<Units, T, NonLinearScale>& operator+=(unit_t<Units, T, NonLinearScale>& lhs, const RhsType& rhs) noexcept
-	{
-		static_assert(traits::is_convertible_unit_t<unit_t<Units, T, NonLinearScale>, RhsType>::value ||
-			(traits::is_dimensionless_unit<decltype(lhs)>::value && std::is_arithmetic<RhsType>::value), 
-			"parameters are not compatible units.");
-
-		lhs = lhs + rhs;
-		return lhs;
-	}
-
-	template<class Units, typename T, template<typename> class NonLinearScale, typename RhsType>
-	inline unit_t<Units, T, NonLinearScale>& operator-=(unit_t<Units, T, NonLinearScale>& lhs, const RhsType& rhs) noexcept
-	{
-		static_assert(traits::is_convertible_unit_t<unit_t<Units, T, NonLinearScale>, RhsType>::value ||
-			(traits::is_dimensionless_unit<decltype(lhs)>::value && std::is_arithmetic<RhsType>::value),
-			"parameters are not compatible units.");
-
-		lhs = lhs - rhs;
-		return lhs;
-	}
-
-	template<class Units, typename T, template<typename> class NonLinearScale, typename RhsType>
-	inline unit_t<Units, T, NonLinearScale>& operator*=(unit_t<Units, T, NonLinearScale>& lhs, const RhsType& rhs) noexcept
-	{
-		static_assert((traits::is_dimensionless_unit<RhsType>::value || std::is_arithmetic<RhsType>::value),
-			"right-hand side parameter must be dimensionless.");
-
-		lhs = lhs * rhs;
-		return lhs;
-	}
-
-	template<class Units, typename T, template<typename> class NonLinearScale, typename RhsType>
-	inline unit_t<Units, T, NonLinearScale>& operator/=(unit_t<Units, T, NonLinearScale>& lhs, const RhsType& rhs) noexcept
-	{
-		static_assert((traits::is_dimensionless_unit<RhsType>::value || std::is_arithmetic<RhsType>::value),
-			"right-hand side parameter must be dimensionless.");
-
-		lhs = lhs / rhs;
-		return lhs;
-	}
-
-	//------------------------------
-	//	UNIT_T UNARY OPERATORS
-	//------------------------------
-
-	// unary addition: +T
-	template<class Units, typename T, template<typename> class NonLinearScale>
-	inline unit_t<Units, T, NonLinearScale> operator+(const unit_t<Units, T, NonLinearScale>& u) noexcept
-	{
-		return u;
-	}
-
-	// prefix increment: ++T
-	template<class Units, typename T, template<typename> class NonLinearScale>
-	inline unit_t<Units, T, NonLinearScale>& operator++(unit_t<Units, T, NonLinearScale>& u) noexcept
-	{
-		u = unit_t<Units, T, NonLinearScale>(u() + 1);
-		return u;
-	}
-
-	// postfix increment: T++
-	template<class Units, typename T, template<typename> class NonLinearScale>
-	inline unit_t<Units, T, NonLinearScale> operator++(unit_t<Units, T, NonLinearScale>& u, int) noexcept
-	{
-		auto ret = u;
-		u = unit_t<Units, T, NonLinearScale>(u() + 1);
-		return ret;
-	}
-
-	// unary addition: -T
-	template<class Units, typename T, template<typename> class NonLinearScale>
-	inline unit_t<Units, T, NonLinearScale> operator-(const unit_t<Units, T, NonLinearScale>& u) noexcept
-	{
-		return unit_t<Units, T, NonLinearScale>(-u());
-	}
-
-	// prefix increment: --T
-	template<class Units, typename T, template<typename> class NonLinearScale>
-	inline unit_t<Units, T, NonLinearScale>& operator--(unit_t<Units, T, NonLinearScale>& u) noexcept
-	{
-		u = unit_t<Units, T, NonLinearScale>(u() - 1);
-		return u;
-	}
-
-	// postfix increment: T--
-	template<class Units, typename T, template<typename> class NonLinearScale>
-	inline unit_t<Units, T, NonLinearScale> operator--(unit_t<Units, T, NonLinearScale>& u, int) noexcept
-	{
-		auto ret = u;
-		u = unit_t<Units, T, NonLinearScale>(u() - 1);
-		return ret;
-	}
-
-	//------------------------------
-	//	UNIT_CAST
-	//------------------------------	
-	
-	/** 
-	 * @ingroup		Conversion
-	 * @brief		Casts a unit container to an arithmetic type.
-	 * @details		unit_cast can be used to remove the strong typing from a unit class, and convert it
-	 *				to a built-in arithmetic type. This may be useful for compatibility with libraries
-	 *				and legacy code that don't support `unit_t` types. E.g 
-	 * @code		meter_t unitVal(5);
-	 *  double value = units::unit_cast<double>(unitVal);	// value = 5.0 
-	 * @endcode
-	 * @tparam		T		Type to cast the unit type to. Must be a built-in arithmetic type.
-	 * @param		value	Unit value to cast.
-	 * @sa			unit_t::to
-	 */
-	template<typename T, typename Units, class = std::enable_if_t<std::is_arithmetic<T>::value && traits::is_unit_t<Units>::value>>
-	inline constexpr T unit_cast(const Units& value) noexcept
-	{
-		return static_cast<T>(value);
-	}
-
-	//------------------------------
-	//	NON-LINEAR SCALE TRAITS
-	//------------------------------
-
-	// forward declaration
-	template<typename T> struct decibel_scale;
-
-	namespace traits
-	{
-		/**
-		 * @ingroup		TypeTraits
-		 * @brief		Trait which tests whether a type is inherited from a linear scale.
-		 * @details		Inherits from `std::true_type` or `std::false_type`. Use `has_linear_scale<U1 [, U2, ...]>::value` to test
-		 *				one or more types to see if they represent unit_t's whose scale is linear.
-		 * @tparam		T	one or more types to test.
-		 */
-#if !defined(_MSC_VER) || _MSC_VER > 1800	// bug in VS2013 prevents this from working
-		template<typename... T>
-		struct has_linear_scale : std::integral_constant<bool, units::all_true<std::is_base_of<units::linear_scale<typename units::traits::unit_t_traits<T>::underlying_type>, T>::value...>::value > {};
-#else
-		template<typename T1, typename T2 = T1, typename T3 = T1>
-		struct has_linear_scale : std::integral_constant<bool,
-			std::is_base_of<units::linear_scale<typename units::traits::unit_t_traits<T1>::underlying_type>, T1>::value &&
-			std::is_base_of<units::linear_scale<typename units::traits::unit_t_traits<T2>::underlying_type>, T2>::value &&
-			std::is_base_of<units::linear_scale<typename units::traits::unit_t_traits<T3>::underlying_type>, T3>::value> {};
-#endif
-
-		/**
-		 * @ingroup		TypeTraits
-		 * @brief		Trait which tests whether a type is inherited from a decibel scale.
-		 * @details		Inherits from `std::true_type` or `std::false_type`. Use `has_decibel_scale<U1 [, U2, ...]>::value` to test
-		 *				one or more types to see if they represent unit_t's whose scale is in decibels.
-		 * @tparam		T	one or more types to test.
-		 */
-#if !defined(_MSC_VER) || _MSC_VER > 1800	// bug in VS2013 prevents this from working
-		template<typename... T>
-		struct has_decibel_scale : std::integral_constant<bool,	units::all_true<std::is_base_of<units::decibel_scale<typename units::traits::unit_t_traits<T>::underlying_type>, T>::value...>::value> {};
-#else
-		template<typename T1, typename T2 = T1, typename T3 = T1>
-		struct has_decibel_scale : std::integral_constant<bool,
-			std::is_base_of<units::decibel_scale<typename units::traits::unit_t_traits<T1>::underlying_type>, T1>::value &&
-			std::is_base_of<units::decibel_scale<typename units::traits::unit_t_traits<T2>::underlying_type>, T2>::value &&
-			std::is_base_of<units::decibel_scale<typename units::traits::unit_t_traits<T2>::underlying_type>, T3>::value> {};
-#endif
-
-		/**
-		 * @ingroup		TypeTraits
-		 * @brief		Trait which tests whether two types has the same non-linear scale.
-		 * @details		Inherits from `std::true_type` or `std::false_type`. Use `is_same_scale<U1 , U2>::value` to test
-		 *				whether two types have the same non-linear scale.
-		 * @tparam		T1	left hand type.
-		 * @tparam		T2	right hand type
-		 */
-		template<typename T1, typename T2>
-		struct is_same_scale : std::integral_constant<bool,
-			std::is_same<typename units::traits::unit_t_traits<T1>::non_linear_scale_type, typename units::traits::unit_t_traits<T2>::non_linear_scale_type>::value>
-		{};
-	}
-
-	//----------------------------------
-	//	NON-LINEAR SCALES
-	//----------------------------------
-
-	// Non-linear transforms are used to pre and post scale units which are defined in terms of non-
-	// linear functions of their current value. A good example of a non-linear scale would be a 
-	// logarithmic or decibel scale
-
-	//------------------------------
-	//	LINEAR SCALE
-	//------------------------------
-
-	/**
-	 * @brief		unit_t scale which is linear
-	 * @details		Represents units on a linear scale. This is the appropriate unit_t scale for almost
-	 *				all units almost all of the time.
-	 * @tparam		T	underlying storage type
-	 * @sa			unit_t
-	 */
-	template<typename T>
-	struct linear_scale
-	{
-		inline constexpr linear_scale() = default;													///< default constructor.		
-		inline constexpr linear_scale(const linear_scale&) = default;
-		inline ~linear_scale() = default;
-		inline linear_scale& operator=(const linear_scale&) = default;
-#if defined(_MSC_VER) && (_MSC_VER > 1800)
-		inline constexpr linear_scale(linear_scale&&) = default;
-		inline linear_scale& operator=(linear_scale&&) = default;
-#endif
-		template<class... Args>
-		inline constexpr linear_scale(const T& value, Args&&...) noexcept : m_value(value) {}	///< constructor.
-		inline constexpr T operator()() const noexcept { return m_value; }							///< returns value.
-
-		T m_value;																					///< linearized value.	
-	};
-
-	//----------------------------------
-	//	SCALAR (LINEAR) UNITS
-	//----------------------------------
-
-	// Scalar units are the *ONLY* units implicitly convertible to/from built-in types.
-	namespace dimensionless
-	{
-		typedef unit<std::ratio<1>, units::category::scalar_unit> scalar;
-		typedef unit<std::ratio<1>, units::category::dimensionless_unit> dimensionless;
-
-		typedef unit_t<scalar> scalar_t;
-		typedef scalar_t dimensionless_t;
-	}
-
-// ignore the redeclaration of the default template parameters
-#if defined(_MSC_VER) 
-#	pragma warning(push)
-#	pragma warning(disable : 4348)
-#endif
-	UNIT_ADD_CATEGORY_TRAIT(scalar)
-	UNIT_ADD_CATEGORY_TRAIT(dimensionless)
-#if defined(_MSC_VER) 
-#	pragma warning(pop)
-#endif
-
-	//------------------------------
-	//	LINEAR ARITHMETIC
-	//------------------------------
-
-	template<class UnitTypeLhs, class UnitTypeRhs, std::enable_if_t<!traits::is_same_scale<UnitTypeLhs, UnitTypeRhs>::value, int> = 0>
-	constexpr inline int operator+(const UnitTypeLhs& /* lhs */, const UnitTypeRhs& /* rhs */) noexcept
-	{
-		static_assert(traits::is_same_scale<UnitTypeLhs, UnitTypeRhs>::value, "Cannot add units with different linear/non-linear scales.");
-		return 0;
-	}
-
-	/// Addition operator for unit_t types with a linear_scale.
-	template<class UnitTypeLhs, class UnitTypeRhs, std::enable_if_t<traits::has_linear_scale<UnitTypeLhs, UnitTypeRhs>::value, int> = 0>
-	inline constexpr UnitTypeLhs operator+(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept
-	{
-		using UnitsLhs = typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type;
-		using UnitsRhs = typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
-		return UnitTypeLhs(lhs() + convert<UnitsRhs, UnitsLhs>(rhs()));
-	}
-
-	/// Addition operator for scalar unit_t types with a linear_scale. Scalar types can be implicitly converted to built-in types.
-	template<typename T, std::enable_if_t<std::is_arithmetic<T>::value, int> = 0>
-	inline constexpr dimensionless::scalar_t operator+(const dimensionless::scalar_t& lhs, T rhs) noexcept
-	{
-		return dimensionless::scalar_t(lhs() + rhs);
-	}
-
-	/// Addition operator for scalar unit_t types with a linear_scale. Scalar types can be implicitly converted to built-in types.
-	template<typename T, std::enable_if_t<std::is_arithmetic<T>::value, int> = 0>
-	inline constexpr dimensionless::scalar_t operator+(T lhs, const dimensionless::scalar_t& rhs) noexcept
-	{
-		return dimensionless::scalar_t(lhs + rhs());
-	}
-
-	/// Subtraction operator for unit_t types with a linear_scale.
-	template<class UnitTypeLhs, class UnitTypeRhs, std::enable_if_t<traits::has_linear_scale<UnitTypeLhs, UnitTypeRhs>::value, int> = 0>
-	inline constexpr UnitTypeLhs operator-(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept
-	{
-		using UnitsLhs = typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type;
-		using UnitsRhs = typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
-		return UnitTypeLhs(lhs() - convert<UnitsRhs, UnitsLhs>(rhs()));
-	}
-
-	/// Subtraction operator for scalar unit_t types with a linear_scale. Scalar types can be implicitly converted to built-in types.
-	template<typename T, std::enable_if_t<std::is_arithmetic<T>::value, int> = 0>
-	inline constexpr dimensionless::scalar_t operator-(const dimensionless::scalar_t& lhs, T rhs) noexcept
-	{
-		return dimensionless::scalar_t(lhs() - rhs);
-	}
-
-	/// Subtraction operator for scalar unit_t types with a linear_scale. Scalar types can be implicitly converted to built-in types.
-	template<typename T, std::enable_if_t<std::is_arithmetic<T>::value, int> = 0>
-	inline constexpr dimensionless::scalar_t operator-(T lhs, const dimensionless::scalar_t& rhs) noexcept
-	{
-		return dimensionless::scalar_t(lhs - rhs());
-	}
-
-	/// Multiplication type for convertible unit_t types with a linear scale. @returns the multiplied value, with the same type as left-hand side unit.
-	template<class UnitTypeLhs, class UnitTypeRhs,
-		std::enable_if_t<traits::is_convertible_unit_t<UnitTypeLhs, UnitTypeRhs>::value && traits::has_linear_scale<UnitTypeLhs, UnitTypeRhs>::value, int> = 0>
-		inline constexpr auto operator*(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept -> unit_t<compound_unit<squared<typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type>>>
-	{
-		using UnitsLhs = typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type;
-		using UnitsRhs = typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
-		return  unit_t<compound_unit<squared<typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type>>>
-			(lhs() * convert<UnitsRhs, UnitsLhs>(rhs()));
-	}
-	
-	/// Multiplication type for non-convertible unit_t types with a linear scale. @returns the multiplied value, whose type is a compound unit of the left and right hand side values.
-	template<class UnitTypeLhs, class UnitTypeRhs,
-		std::enable_if_t<!traits::is_convertible_unit_t<UnitTypeLhs, UnitTypeRhs>::value && traits::has_linear_scale<UnitTypeLhs, UnitTypeRhs>::value && !traits::is_dimensionless_unit<UnitTypeLhs>::value && !traits::is_dimensionless_unit<UnitTypeRhs>::value, int> = 0>
-		inline constexpr auto operator*(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept -> unit_t<compound_unit<typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type, typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type>>
-	{
-		using UnitsLhs = typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type;
-		using UnitsRhs = typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
-		return unit_t<compound_unit<UnitsLhs, UnitsRhs>>
-			(lhs() * rhs());
-	}
-
-	/// Multiplication by a dimensionless unit for unit_t types with a linear scale.
-	template<class UnitTypeLhs, typename UnitTypeRhs,
-		std::enable_if_t<traits::has_linear_scale<UnitTypeLhs, UnitTypeRhs>::value && !traits::is_dimensionless_unit<UnitTypeLhs>::value && traits::is_dimensionless_unit<UnitTypeRhs>::value, int> = 0>
-		inline constexpr UnitTypeLhs operator*(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept
-	{
-		// the cast makes sure factors of PI are handled as expected
-		return UnitTypeLhs(lhs() * static_cast<UNIT_LIB_DEFAULT_TYPE>(rhs));
-	}
-
-	/// Multiplication by a dimensionless unit for unit_t types with a linear scale.
-	template<class UnitTypeLhs, typename UnitTypeRhs,
-		std::enable_if_t<traits::has_linear_scale<UnitTypeLhs, UnitTypeRhs>::value && traits::is_dimensionless_unit<UnitTypeLhs>::value && !traits::is_dimensionless_unit<UnitTypeRhs>::value, int> = 0>
-		inline constexpr UnitTypeRhs operator*(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept
-	{
-		// the cast makes sure factors of PI are handled as expected
-		return UnitTypeRhs(static_cast<UNIT_LIB_DEFAULT_TYPE>(lhs) * rhs());
-	}
-
-	/// Multiplication by a scalar for unit_t types with a linear scale.
-	template<class UnitTypeLhs, typename T,
-		std::enable_if_t<std::is_arithmetic<T>::value && traits::has_linear_scale<UnitTypeLhs>::value, int> = 0>
-		inline constexpr UnitTypeLhs operator*(const UnitTypeLhs& lhs, T rhs) noexcept
-	{
-		return UnitTypeLhs(lhs() * rhs);
-	}
-
-	/// Multiplication by a scalar for unit_t types with a linear scale.
-	template<class UnitTypeRhs, typename T,
-		std::enable_if_t<std::is_arithmetic<T>::value && traits::has_linear_scale<UnitTypeRhs>::value, int> = 0>
-		inline constexpr UnitTypeRhs operator*(T lhs, const UnitTypeRhs& rhs) noexcept
-	{
-		return UnitTypeRhs(lhs * rhs());
-	}
-
-	/// Division for convertible unit_t types with a linear scale. @returns the lhs divided by rhs value, whose type is a scalar
-	template<class UnitTypeLhs, class UnitTypeRhs,
-		std::enable_if_t<traits::is_convertible_unit_t<UnitTypeLhs, UnitTypeRhs>::value && traits::has_linear_scale<UnitTypeLhs, UnitTypeRhs>::value, int> = 0>
-		inline constexpr dimensionless::scalar_t operator/(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept
-	{
-		using UnitsLhs = typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type;
-		using UnitsRhs = typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
-		return dimensionless::scalar_t(lhs() / convert<UnitsRhs, UnitsLhs>(rhs()));
-	}
-
-	/// Division for non-convertible unit_t types with a linear scale. @returns the lhs divided by the rhs, with a compound unit type of lhs/rhs 
-	template<class UnitTypeLhs, class UnitTypeRhs,
-		std::enable_if_t<!traits::is_convertible_unit_t<UnitTypeLhs, UnitTypeRhs>::value && traits::has_linear_scale<UnitTypeLhs, UnitTypeRhs>::value && !traits::is_dimensionless_unit<UnitTypeLhs>::value && !traits::is_dimensionless_unit<UnitTypeRhs>::value, int> = 0>
-		inline constexpr auto operator/(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept ->  unit_t<compound_unit<typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type, inverse<typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type>>>
-	{
-		using UnitsLhs = typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type;
-		using UnitsRhs = typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
-		return unit_t<compound_unit<UnitsLhs, inverse<UnitsRhs>>>
-			(lhs() / rhs());
-	}
-
-	/// Division by a dimensionless unit for unit_t types with a linear scale
-	template<class UnitTypeLhs, class UnitTypeRhs,
-		std::enable_if_t<traits::has_linear_scale<UnitTypeLhs, UnitTypeRhs>::value && !traits::is_dimensionless_unit<UnitTypeLhs>::value && traits::is_dimensionless_unit<UnitTypeRhs>::value, int> = 0>
-		inline constexpr UnitTypeLhs operator/(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept
-	{
-		return UnitTypeLhs(lhs() / static_cast<UNIT_LIB_DEFAULT_TYPE>(rhs));
-	}
-
-	/// Division of a dimensionless unit  by a unit_t type with a linear scale
-	template<class UnitTypeLhs, class UnitTypeRhs,
-		std::enable_if_t<traits::has_linear_scale<UnitTypeLhs, UnitTypeRhs>::value && traits::is_dimensionless_unit<UnitTypeLhs>::value && !traits::is_dimensionless_unit<UnitTypeRhs>::value, int> = 0>
-		inline constexpr auto operator/(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept -> unit_t<inverse<typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type>>
-	{
-		return unit_t<inverse<typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type>>
-			(static_cast<UNIT_LIB_DEFAULT_TYPE>(lhs) / rhs());
-	}
-
-	/// Division by a scalar for unit_t types with a linear scale
-	template<class UnitTypeLhs, typename T,
-		std::enable_if_t<std::is_arithmetic<T>::value && traits::has_linear_scale<UnitTypeLhs>::value, int> = 0>
-		inline constexpr UnitTypeLhs operator/(const UnitTypeLhs& lhs, T rhs) noexcept
-	{
-		return UnitTypeLhs(lhs() / rhs);
-	}
-
-	/// Division of a scalar  by a unit_t type with a linear scale
-	template<class UnitTypeRhs, typename T,
-		std::enable_if_t<std::is_arithmetic<T>::value && traits::has_linear_scale<UnitTypeRhs>::value, int> = 0>
-		inline constexpr auto operator/(T lhs, const UnitTypeRhs& rhs) noexcept -> unit_t<inverse<typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type>>
-	{
-		using UnitsRhs = typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
-		return unit_t<inverse<UnitsRhs>>
-			(lhs / rhs());
-	}
-
-	//----------------------------------
-	//	SCALAR COMPARISONS
-	//----------------------------------
-
-	template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
-	constexpr bool operator==(const UNIT_LIB_DEFAULT_TYPE lhs, const Units& rhs) noexcept
-	{
-		return detail::abs(lhs - static_cast<UNIT_LIB_DEFAULT_TYPE>(rhs)) < std::numeric_limits<UNIT_LIB_DEFAULT_TYPE>::epsilon() * detail::abs(lhs + static_cast<UNIT_LIB_DEFAULT_TYPE>(rhs)) ||
-			detail::abs(lhs - static_cast<UNIT_LIB_DEFAULT_TYPE>(rhs)) < std::numeric_limits<UNIT_LIB_DEFAULT_TYPE>::min();
-	}
-
-	template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
-	constexpr bool operator==(const Units& lhs, const UNIT_LIB_DEFAULT_TYPE rhs) noexcept
-	{
-		return detail::abs(static_cast<UNIT_LIB_DEFAULT_TYPE>(lhs) - rhs) < std::numeric_limits<UNIT_LIB_DEFAULT_TYPE>::epsilon() * detail::abs(static_cast<UNIT_LIB_DEFAULT_TYPE>(lhs) + rhs) ||
-			detail::abs(static_cast<UNIT_LIB_DEFAULT_TYPE>(lhs) - rhs) < std::numeric_limits<UNIT_LIB_DEFAULT_TYPE>::min();
-	}
-
-	template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
-	constexpr bool operator!=(const UNIT_LIB_DEFAULT_TYPE lhs, const Units& rhs) noexcept
-	{
-		return!(lhs == static_cast<UNIT_LIB_DEFAULT_TYPE>(rhs));
-	}
-
-	template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
-	constexpr bool operator!=(const Units& lhs, const UNIT_LIB_DEFAULT_TYPE rhs) noexcept
-	{
-		return !(static_cast<UNIT_LIB_DEFAULT_TYPE>(lhs) == rhs);
-	}
-
-	template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
-	constexpr bool operator>=(const UNIT_LIB_DEFAULT_TYPE lhs, const Units& rhs) noexcept
-	{
-		return std::isgreaterequal(lhs, static_cast<UNIT_LIB_DEFAULT_TYPE>(rhs));
-	}
-
-	template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
-	constexpr bool operator>=(const Units& lhs, const UNIT_LIB_DEFAULT_TYPE rhs) noexcept
-	{
-		return std::isgreaterequal(static_cast<UNIT_LIB_DEFAULT_TYPE>(lhs), rhs);
-	}
-
-	template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
-	constexpr bool operator>(const UNIT_LIB_DEFAULT_TYPE lhs, const Units& rhs) noexcept
-	{
-		return lhs > static_cast<UNIT_LIB_DEFAULT_TYPE>(rhs);
-	}
-
-	template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
-	constexpr bool operator>(const Units& lhs, const UNIT_LIB_DEFAULT_TYPE rhs) noexcept
-	{
-		return static_cast<UNIT_LIB_DEFAULT_TYPE>(lhs) > rhs;
-	}
-
-	template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
-	constexpr bool operator<=(const UNIT_LIB_DEFAULT_TYPE lhs, const Units& rhs) noexcept
-	{
-		return std::islessequal(lhs, static_cast<UNIT_LIB_DEFAULT_TYPE>(rhs));
-	}
-
-	template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
-	constexpr bool operator<=(const Units& lhs, const UNIT_LIB_DEFAULT_TYPE rhs) noexcept
-	{
-		return std::islessequal(static_cast<UNIT_LIB_DEFAULT_TYPE>(lhs), rhs);
-	}
-
-	template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
-	constexpr bool operator<(const UNIT_LIB_DEFAULT_TYPE lhs, const Units& rhs) noexcept
-	{
-		return lhs < static_cast<UNIT_LIB_DEFAULT_TYPE>(rhs);
-	}
-
-	template<typename Units, class = std::enable_if_t<units::traits::is_dimensionless_unit<Units>::value>>
-	constexpr bool operator<(const Units& lhs, const UNIT_LIB_DEFAULT_TYPE rhs) noexcept
-	{
-		return static_cast<UNIT_LIB_DEFAULT_TYPE>(lhs) < rhs;
-	}
-
-	//----------------------------------
-	//	POW
-	//----------------------------------
-
-	/** @cond */	// DOXYGEN IGNORE
-	namespace detail
-	{
-		/// recursive exponential implementation
-		template <int N, class U> struct power_of_unit
-		{
-			typedef typename units::detail::unit_multiply<U, typename power_of_unit<N - 1, U>::type> type;
-		};
-
-		/// End recursion
-		template <class U> struct power_of_unit<1, U>
-		{
-			typedef U type;
-		};
-	}
-	/** @endcond */	// END DOXYGEN IGNORE
-
-	namespace math
-	{
-		/**
-		 * @brief		computes the value of <i>value</i> raised to the <i>power</i>
-		 * @details		Only implemented for linear_scale units. <i>Power</i> must be known at compile time, so the resulting unit type can be deduced.
-		 * @tparam		power exponential power to raise <i>value</i> by.
-		 * @param[in]	value `unit_t` derived type to raise to the given <i>power</i>
-		 * @returns		new unit_t, raised to the given exponent
-		 */
-		template<int power, class UnitType, class = typename std::enable_if<traits::has_linear_scale<UnitType>::value, int>>
-		inline auto pow(const UnitType& value) noexcept -> unit_t<typename units::detail::power_of_unit<power, typename units::traits::unit_t_traits<UnitType>::unit_type>::type, typename units::traits::unit_t_traits<UnitType>::underlying_type, linear_scale>
-		{
-			return unit_t<typename units::detail::power_of_unit<power, typename units::traits::unit_t_traits<UnitType>::unit_type>::type, typename units::traits::unit_t_traits<UnitType>::underlying_type, linear_scale>
-				(std::pow(value(), power));
-		}
-
-		/**
-		 * @brief		computes the value of <i>value</i> raised to the <i>power</i> as a constexpr
-		 * @details		Only implemented for linear_scale units. <i>Power</i> must be known at compile time, so the resulting unit type can be deduced.
-		 *				Additionally, the power must be <i>a positive, integral, value</i>.
-		 * @tparam		power exponential power to raise <i>value</i> by.
-		 * @param[in]	value `unit_t` derived type to raise to the given <i>power</i>
-		 * @returns		new unit_t, raised to the given exponent
-		 */
-		template<int power, class UnitType, class = typename std::enable_if<traits::has_linear_scale<UnitType>::value, int>>
-		inline constexpr auto cpow(const UnitType& value) noexcept -> unit_t<typename units::detail::power_of_unit<power, typename units::traits::unit_t_traits<UnitType>::unit_type>::type, typename units::traits::unit_t_traits<UnitType>::underlying_type, linear_scale>
-		{
-			static_assert(power >= 0, "cpow cannot accept negative numbers. Try units::math::pow instead.");
-			return unit_t<typename units::detail::power_of_unit<power, typename units::traits::unit_t_traits<UnitType>::unit_type>::type, typename units::traits::unit_t_traits<UnitType>::underlying_type, linear_scale>
-				(detail::pow(value(), power));
-		}
-	}
-
-	//------------------------------
-	//	DECIBEL SCALE
-	//------------------------------
-
-	/**
-	* @brief		unit_t scale for representing decibel values.
-	* @details		internally stores linearized values. `operator()` returns the value in dB.
-	* @tparam		T	underlying storage type
-	* @sa			unit_t
-	*/
-	template<typename T>
-	struct decibel_scale
-	{
-		inline constexpr decibel_scale() = default;
-		inline constexpr decibel_scale(const decibel_scale&) = default;
-		inline ~decibel_scale() = default;
-		inline decibel_scale& operator=(const decibel_scale&) = default;
-#if defined(_MSC_VER) && (_MSC_VER > 1800)
-		inline constexpr decibel_scale(decibel_scale&&) = default;
-		inline decibel_scale& operator=(decibel_scale&&) = default;
-#endif
-		inline constexpr decibel_scale(const T value) noexcept : m_value(std::pow(10, value / 10)) {}
-		template<class... Args>
-		inline constexpr decibel_scale(const T value, std::true_type, Args&&...) noexcept : m_value(value) {}
-		inline constexpr T operator()() const noexcept { return 10 * std::log10(m_value); }
-
-		T m_value;	///< linearized value	
-	};
-
-	//------------------------------
-	//	SCALAR (DECIBEL) UNITS
-	//------------------------------
-
-	/**
-	 * @brief		namespace for unit types and containers for units that have no dimension (scalar units)
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-	namespace dimensionless
-	{
-		typedef unit_t<scalar, UNIT_LIB_DEFAULT_TYPE, decibel_scale> dB_t;
-#if !defined(UNIT_LIB_DISABLE_IOSTREAM)
-		inline std::ostream& operator<<(std::ostream& os, const dB_t& obj) { os << obj() << " dB"; return os; }
-#endif
-		typedef dB_t dBi_t;
-	}
-
-	//------------------------------
-	//	DECIBEL ARITHMETIC
-	//------------------------------
-
-	/// Addition for convertible unit_t types with a decibel_scale
-	template<class UnitTypeLhs, class UnitTypeRhs,
-		std::enable_if_t<traits::has_decibel_scale<UnitTypeLhs, UnitTypeRhs>::value, int> = 0>
-	constexpr inline auto operator+(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept -> unit_t<compound_unit<squared<typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type>>, typename units::traits::unit_t_traits<UnitTypeLhs>::underlying_type, decibel_scale>
-	{
-		using LhsUnits = typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type;
-		using RhsUnits = typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
-		using underlying_type = typename units::traits::unit_t_traits<UnitTypeLhs>::underlying_type;
-
-		return unit_t<compound_unit<squared<LhsUnits>>, underlying_type, decibel_scale>
-			(lhs.template toLinearized<underlying_type>() * convert<RhsUnits, LhsUnits>(rhs.template toLinearized<underlying_type>()), std::true_type());
-	}
-
-	/// Addition between unit_t types with a decibel_scale and dimensionless dB units
-	template<class UnitTypeLhs, std::enable_if_t<traits::has_decibel_scale<UnitTypeLhs>::value && !traits::is_dimensionless_unit<UnitTypeLhs>::value, int> = 0>
-	constexpr inline UnitTypeLhs operator+(const UnitTypeLhs& lhs, const dimensionless::dB_t& rhs) noexcept
-	{
-		using underlying_type = typename units::traits::unit_t_traits<UnitTypeLhs>::underlying_type;
-		return UnitTypeLhs(lhs.template toLinearized<underlying_type>() * rhs.template toLinearized<underlying_type>(), std::true_type());
-	}
-
-	/// Addition between unit_t types with a decibel_scale and dimensionless dB units
-	template<class UnitTypeRhs, std::enable_if_t<traits::has_decibel_scale<UnitTypeRhs>::value && !traits::is_dimensionless_unit<UnitTypeRhs>::value, int> = 0>
-	constexpr inline UnitTypeRhs operator+(const dimensionless::dB_t& lhs, const UnitTypeRhs& rhs) noexcept
-	{
-		using underlying_type = typename units::traits::unit_t_traits<UnitTypeRhs>::underlying_type;
-		return UnitTypeRhs(lhs.template toLinearized<underlying_type>() * rhs.template toLinearized<underlying_type>(), std::true_type());
-	}
-
-	/// Subtraction for convertible unit_t types with a decibel_scale
-	template<class UnitTypeLhs, class UnitTypeRhs, std::enable_if_t<traits::has_decibel_scale<UnitTypeLhs, UnitTypeRhs>::value, int> = 0>
-	constexpr inline auto operator-(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs) noexcept -> unit_t<compound_unit<typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type, inverse<typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type>>, typename units::traits::unit_t_traits<UnitTypeLhs>::underlying_type, decibel_scale>
-	{
-		using LhsUnits = typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type;
-		using RhsUnits = typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
-		using underlying_type = typename units::traits::unit_t_traits<UnitTypeLhs>::underlying_type;
-
-		return unit_t<compound_unit<LhsUnits, inverse<RhsUnits>>, underlying_type, decibel_scale>
-			(lhs.template toLinearized<underlying_type>() / convert<RhsUnits, LhsUnits>(rhs.template toLinearized<underlying_type>()), std::true_type());
-	}
-
-	/// Subtraction between unit_t types with a decibel_scale and dimensionless dB units
-	template<class UnitTypeLhs, std::enable_if_t<traits::has_decibel_scale<UnitTypeLhs>::value && !traits::is_dimensionless_unit<UnitTypeLhs>::value, int> = 0>
-	constexpr inline UnitTypeLhs operator-(const UnitTypeLhs& lhs, const dimensionless::dB_t& rhs) noexcept
-	{
-		using underlying_type = typename units::traits::unit_t_traits<UnitTypeLhs>::underlying_type;
-		return UnitTypeLhs(lhs.template toLinearized<underlying_type>() / rhs.template toLinearized<underlying_type>(), std::true_type());
-	}
-
-	/// Subtraction between unit_t types with a decibel_scale and dimensionless dB units
-	template<class UnitTypeRhs, std::enable_if_t<traits::has_decibel_scale<UnitTypeRhs>::value && !traits::is_dimensionless_unit<UnitTypeRhs>::value, int> = 0>
-	constexpr inline auto operator-(const dimensionless::dB_t& lhs, const UnitTypeRhs& rhs) noexcept -> unit_t<inverse<typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type>, typename units::traits::unit_t_traits<UnitTypeRhs>::underlying_type, decibel_scale>
-	{
-		using RhsUnits = typename units::traits::unit_t_traits<UnitTypeRhs>::unit_type;
-		using underlying_type = typename units::traits::unit_t_traits<RhsUnits>::underlying_type;
-
-		return unit_t<inverse<RhsUnits>, underlying_type, decibel_scale>
-			(lhs.template toLinearized<underlying_type>() / rhs.template toLinearized<underlying_type>(), std::true_type());
-	}
-
-	//----------------------------------
-	//	UNIT RATIO CLASS
-	//----------------------------------
-
-	/** @cond */	// DOXYGEN IGNORE
-	namespace detail
-	{
-		template<class Units>
-		struct _unit_value_t {};
-	}
-	/** @endcond */	// END DOXYGEN IGNORE
-
-	namespace traits
-	{
-#ifdef FOR_DOXYGEN_PURPOSES_ONLY
-		/**
-		* @ingroup		TypeTraits
-		* @brief		Trait for accessing the publically defined types of `units::unit_value_t_traits`
-		* @details		The units library determines certain properties of the `unit_value_t` types passed to 
-		*				them and what they represent by using the members of the corresponding `unit_value_t_traits`
-		*				instantiation.
-		*/
-		template<typename T>
-		struct unit_value_t_traits
-		{
-			typedef typename T::unit_type unit_type;	///< Dimension represented by the `unit_value_t`.
-			typedef typename T::ratio ratio;			///< Quantity represented by the `unit_value_t`, expressed as arational number.
-		};
-#endif
-
-		/** @cond */	// DOXYGEN IGNORE
-		/**
-		 * @brief		unit_value_t_traits specialization for things which are not unit_t
-		 * @details
-		 */
-		template<typename T, typename = void>
-		struct unit_value_t_traits
-		{
-			typedef void unit_type;
-			typedef void ratio;
-		};
-	
-		/**
-		 * @ingroup		TypeTraits
-		 * @brief		Trait for accessing the publically defined types of `units::unit_value_t_traits`
-		 * @details
-		 */
-		template<typename T>
-		struct unit_value_t_traits <T, typename void_t<
-			typename T::unit_type,
-			typename T::ratio>::type>
-		{
-			typedef typename T::unit_type unit_type;
-			typedef typename T::ratio ratio;
-		};
-		/** @endcond */	// END DOXYGEN IGNORE
-	}
-
-	//------------------------------------------------------------------------------
-	//	COMPILE-TIME UNIT VALUES AND ARITHMETIC
-	//------------------------------------------------------------------------------
-
-	/**
-	 * @ingroup		UnitContainers
-	 * @brief		Stores a rational unit value as a compile-time constant
-	 * @details		unit_value_t is useful for performing compile-time arithmetic on known 
-	 *				unit quantities.
-	 * @tparam		Units	units represented by the `unit_value_t`
-	 * @tparam		Num		numerator of the represented value.
-	 * @tparam		Denom	denominator of the represented value.
-	 * @sa			unit_value_t_traits to access information about the properties of the class,
-	 *				such as it's unit type and rational value.
-	 * @note		This is intentionally identical in concept to a `std::ratio`.
-	 *
-	 */
-	template<typename Units, std::uintmax_t Num, std::uintmax_t Denom = 1>
-	struct unit_value_t : units::detail::_unit_value_t<Units>
-	{
-		typedef Units unit_type;
-		typedef std::ratio<Num, Denom> ratio;
-
-		static_assert(traits::is_unit<Units>::value, "Template parameter `Units` must be a unit type.");
-		static constexpr const unit_t<Units> value() { return unit_t<Units>((UNIT_LIB_DEFAULT_TYPE)ratio::num / ratio::den); }
-	};
-
-	namespace traits
-	{
-		/**
-		 * @ingroup		TypeTraits
-		 * @brief		Trait which tests whether a type is a unit_value_t representing the given unit type.
-		 * @details		e.g. `is_unit_value_t<meters, myType>::value` would test that `myType` is a 
-		 *				`unit_value_t<meters>`.
-		 * @tparam		Units	units that the `unit_value_t` is supposed to have.
-		 * @tparam		T		type to test.
-		 */
-		template<typename T, typename Units = typename traits::unit_value_t_traits<T>::unit_type>
-		struct is_unit_value_t : std::integral_constant<bool, 
-			std::is_base_of<units::detail::_unit_value_t<Units>, T>::value>
-		{};
-	
-		/**
-		 * @ingroup		TypeTraits
-		 * @brief		Trait which tests whether type T is a unit_value_t with a unit type in the given category.
-		 * @details		e.g. `is_unit_value_t_category<units::category::length, unit_value_t<feet>>::value` would be true
-		 */
-		template<typename Category, typename T>
-		struct is_unit_value_t_category : std::integral_constant<bool,
-			std::is_same<units::traits::base_unit_of<typename traits::unit_value_t_traits<T>::unit_type>, Category>::value>
-		{
-			static_assert(is_base_unit<Category>::value, "Template parameter `Category` must be a `base_unit` type.");
-		};
-	}
-
-	/** @cond */	// DOXYGEN IGNORE
-	namespace detail
-	{
-		// base class for common arithmetic
-		template<class U1, class U2>
-		struct unit_value_arithmetic
-		{
-			static_assert(traits::is_unit_value_t<U1>::value, "Template parameter `U1` must be a `unit_value_t` type.");
-			static_assert(traits::is_unit_value_t<U2>::value, "Template parameter `U2` must be a `unit_value_t` type.");
-
-			using _UNIT1 = typename traits::unit_value_t_traits<U1>::unit_type;
-			using _UNIT2 = typename traits::unit_value_t_traits<U2>::unit_type;
-			using _CONV1 = typename units::traits::unit_traits<_UNIT1>::conversion_ratio;
-			using _CONV2 = typename units::traits::unit_traits<_UNIT2>::conversion_ratio;
-			using _RATIO1 = typename traits::unit_value_t_traits<U1>::ratio;
-			using _RATIO2 = typename traits::unit_value_t_traits<U2>::ratio;
-			using _RATIO2CONV = typename std::ratio_divide<std::ratio_multiply<_RATIO2, _CONV2>, _CONV1>;
-			using _PI_EXP = std::ratio_subtract<typename units::traits::unit_traits<_UNIT2>::pi_exponent_ratio, typename units::traits::unit_traits<_UNIT1>::pi_exponent_ratio>;
-		};
-	}
-	/** @endcond */	// END DOXYGEN IGNORE
-
-	/**
-	 * @ingroup		CompileTimeUnitManipulators
-	 * @brief		adds two unit_value_t types at compile-time
-	 * @details		The resulting unit will the the `unit_type` of `U1`
-	 * @tparam		U1	left-hand `unit_value_t`
-	 * @tparam		U2	right-hand `unit_value_t`
-	 * @sa			unit_value_t_traits to access information about the properties of the class,
-	 *				such as it's unit type and rational value.
-	 * @note		very similar in concept to `std::ratio_add`
-	 */
-	template<class U1, class U2>
-	struct unit_value_add : units::detail::unit_value_arithmetic<U1, U2>, units::detail::_unit_value_t<typename traits::unit_value_t_traits<U1>::unit_type>
-	{
-		/** @cond */	// DOXYGEN IGNORE
-		using Base = units::detail::unit_value_arithmetic<U1, U2>;
-		typedef typename Base::_UNIT1 unit_type;
-		using ratio = std::ratio_add<typename Base::_RATIO1, typename Base::_RATIO2CONV>;
-
-		static_assert(traits::is_convertible_unit<typename Base::_UNIT1, typename Base::_UNIT2>::value, "Unit types are not compatible.");
-		/** @endcond */	// END DOXYGEN IGNORE
-
-		/**
-		 * @brief		Value of sum
-		 * @details		Returns the calculated value of the sum of `U1` and `U2`, in the same
-		 *				units as `U1`.
-		 * @returns		Value of the sum in the appropriate units.
-		 */
-		static constexpr const unit_t<unit_type> value() noexcept
-		{
-			using UsePi = std::integral_constant<bool, Base::_PI_EXP::num != 0>;
-			return value(UsePi());
-		}
-
-		/** @cond */	// DOXYGEN IGNORE
-		// value if PI isn't involved
-		static constexpr const unit_t<unit_type> value(std::false_type) noexcept
-		{ 
-			return unit_t<unit_type>((UNIT_LIB_DEFAULT_TYPE)ratio::num / ratio::den);
-		}
-
-		// value if PI *is* involved
-		static constexpr const unit_t<unit_type> value(std::true_type) noexcept
-		{
-			return unit_t<unit_type>(((UNIT_LIB_DEFAULT_TYPE)Base::_RATIO1::num / Base::_RATIO1::den) +
-			((UNIT_LIB_DEFAULT_TYPE)Base::_RATIO2CONV::num / Base::_RATIO2CONV::den) * std::pow(units::constants::detail::PI_VAL, ((UNIT_LIB_DEFAULT_TYPE)Base::_PI_EXP::num / Base::_PI_EXP::den)));
-		}
-		/** @endcond */	// END DOXYGEN IGNORE
-	};
-
-	/**
-	 * @ingroup		CompileTimeUnitManipulators
-	 * @brief		subtracts two unit_value_t types at compile-time
-	 * @details		The resulting unit will the the `unit_type` of `U1`
-	 * @tparam		U1	left-hand `unit_value_t`
-	 * @tparam		U2	right-hand `unit_value_t`
-	 * @sa			unit_value_t_traits to access information about the properties of the class,
-	 *				such as it's unit type and rational value.
-	 * @note		very similar in concept to `std::ratio_subtract`
-	 */
-	template<class U1, class U2>
-	struct unit_value_subtract : units::detail::unit_value_arithmetic<U1, U2>, units::detail::_unit_value_t<typename traits::unit_value_t_traits<U1>::unit_type>
-	{
-		/** @cond */	// DOXYGEN IGNORE
-		using Base = units::detail::unit_value_arithmetic<U1, U2>;
-
-		typedef typename Base::_UNIT1 unit_type;
-		using ratio = std::ratio_subtract<typename Base::_RATIO1, typename Base::_RATIO2CONV>;
-
-		static_assert(traits::is_convertible_unit<typename Base::_UNIT1, typename Base::_UNIT2>::value, "Unit types are not compatible.");
-		/** @endcond */	// END DOXYGEN IGNORE
-
-		/**
-		 * @brief		Value of difference
-		 * @details		Returns the calculated value of the difference of `U1` and `U2`, in the same
-		 *				units as `U1`.
-		 * @returns		Value of the difference in the appropriate units.
-		 */
-		static constexpr const unit_t<unit_type> value() noexcept
-		{
-			using UsePi = std::integral_constant<bool, Base::_PI_EXP::num != 0>;
-			return value(UsePi());
-		}
-
-		/** @cond */	// DOXYGEN IGNORE
-		// value if PI isn't involved
-		static constexpr const unit_t<unit_type> value(std::false_type) noexcept
-		{
-			return unit_t<unit_type>((UNIT_LIB_DEFAULT_TYPE)ratio::num / ratio::den);
-		}
-
-		// value if PI *is* involved
-		static constexpr const unit_t<unit_type> value(std::true_type) noexcept
-		{
-			return unit_t<unit_type>(((UNIT_LIB_DEFAULT_TYPE)Base::_RATIO1::num / Base::_RATIO1::den) - ((UNIT_LIB_DEFAULT_TYPE)Base::_RATIO2CONV::num / Base::_RATIO2CONV::den)
-				* std::pow(units::constants::detail::PI_VAL, ((UNIT_LIB_DEFAULT_TYPE)Base::_PI_EXP::num / Base::_PI_EXP::den)));
-		}
-		/** @endcond */	// END DOXYGEN IGNORE	};
-	};
-
-	/**
-	 * @ingroup		CompileTimeUnitManipulators
-	 * @brief		multiplies two unit_value_t types at compile-time
-	 * @details		The resulting unit will the the `unit_type` of `U1 * U2`
-	 * @tparam		U1	left-hand `unit_value_t`
-	 * @tparam		U2	right-hand `unit_value_t`
-	 * @sa			unit_value_t_traits to access information about the properties of the class,
-	 *				such as it's unit type and rational value.
-	 * @note		very similar in concept to `std::ratio_multiply`
-	 */
-	template<class U1, class U2>
-	struct unit_value_multiply : units::detail::unit_value_arithmetic<U1, U2>,
-		units::detail::_unit_value_t<typename std::conditional<traits::is_convertible_unit<typename traits::unit_value_t_traits<U1>::unit_type,
-			typename traits::unit_value_t_traits<U2>::unit_type>::value, compound_unit<squared<typename traits::unit_value_t_traits<U1>::unit_type>>, 
-			compound_unit<typename traits::unit_value_t_traits<U1>::unit_type, typename traits::unit_value_t_traits<U2>::unit_type>>::type>
-	{
-		/** @cond */	// DOXYGEN IGNORE
-		using Base = units::detail::unit_value_arithmetic<U1, U2>;
-		
-		using unit_type = std::conditional_t<traits::is_convertible_unit<typename Base::_UNIT1, typename Base::_UNIT2>::value, compound_unit<squared<typename Base::_UNIT1>>, compound_unit<typename Base::_UNIT1, typename Base::_UNIT2>>;
-		using ratio = std::conditional_t<traits::is_convertible_unit<typename Base::_UNIT1, typename Base::_UNIT2>::value, std::ratio_multiply<typename Base::_RATIO1, typename Base::_RATIO2CONV>, std::ratio_multiply<typename Base::_RATIO1, typename Base::_RATIO2>>;
-		/** @endcond */	// END DOXYGEN IGNORE
-
-		/**
-		 * @brief		Value of product
-		 * @details		Returns the calculated value of the product of `U1` and `U2`, in units
-		 *				of `U1 x U2`.
-		 * @returns		Value of the product in the appropriate units.
-		 */
-		static constexpr const unit_t<unit_type> value() noexcept
-		{
-			using UsePi = std::integral_constant<bool, Base::_PI_EXP::num != 0>;
-			return value(UsePi());
-		}
-
-		/** @cond */	// DOXYGEN IGNORE
-		// value if PI isn't involved
-		static constexpr const unit_t<unit_type> value(std::false_type) noexcept
-		{
-			return unit_t<unit_type>((UNIT_LIB_DEFAULT_TYPE)ratio::num / ratio::den);
-		}
-
-		// value if PI *is* involved
-		static constexpr const unit_t<unit_type> value(std::true_type) noexcept
-		{
-			return unit_t<unit_type>(((UNIT_LIB_DEFAULT_TYPE)ratio::num / ratio::den) * std::pow(units::constants::detail::PI_VAL, ((UNIT_LIB_DEFAULT_TYPE)Base::_PI_EXP::num / Base::_PI_EXP::den)));
-		}
-		/** @endcond */	// END DOXYGEN IGNORE
-	};
-
-	/**
-	 * @ingroup		CompileTimeUnitManipulators
-	 * @brief		divides two unit_value_t types at compile-time
-	 * @details		The resulting unit will the the `unit_type` of `U1`
-	 * @tparam		U1	left-hand `unit_value_t`
-	 * @tparam		U2	right-hand `unit_value_t`
-	 * @sa			unit_value_t_traits to access information about the properties of the class,
-	 *				such as it's unit type and rational value.
-	 * @note		very similar in concept to `std::ratio_divide`
-	 */
-	template<class U1, class U2>
-	struct unit_value_divide : units::detail::unit_value_arithmetic<U1, U2>,
-		units::detail::_unit_value_t<typename std::conditional<traits::is_convertible_unit<typename traits::unit_value_t_traits<U1>::unit_type,
-		typename traits::unit_value_t_traits<U2>::unit_type>::value, dimensionless::scalar, compound_unit<typename traits::unit_value_t_traits<U1>::unit_type, 
-		inverse<typename traits::unit_value_t_traits<U2>::unit_type>>>::type>
-	{
-		/** @cond */	// DOXYGEN IGNORE
-		using Base = units::detail::unit_value_arithmetic<U1, U2>;
-		
-		using unit_type = std::conditional_t<traits::is_convertible_unit<typename Base::_UNIT1, typename Base::_UNIT2>::value, dimensionless::scalar, compound_unit<typename Base::_UNIT1, inverse<typename Base::_UNIT2>>>;
-		using ratio = std::conditional_t<traits::is_convertible_unit<typename Base::_UNIT1, typename Base::_UNIT2>::value, std::ratio_divide<typename Base::_RATIO1, typename Base::_RATIO2CONV>, std::ratio_divide<typename Base::_RATIO1, typename Base::_RATIO2>>;
-		/** @endcond */	// END DOXYGEN IGNORE
-
-		/**
-		 * @brief		Value of quotient
-		 * @details		Returns the calculated value of the quotient of `U1` and `U2`, in units
-		 *				of `U1 x U2`.
-		 * @returns		Value of the quotient in the appropriate units.
-		 */
-		static constexpr const unit_t<unit_type> value() noexcept
-		{
-			using UsePi = std::integral_constant<bool, Base::_PI_EXP::num != 0>;
-			return value(UsePi());
-		}
-
-		/** @cond */	// DOXYGEN IGNORE
-		// value if PI isn't involved
-		static constexpr const unit_t<unit_type> value(std::false_type) noexcept
-		{
-			return unit_t<unit_type>((UNIT_LIB_DEFAULT_TYPE)ratio::num / ratio::den);
-		}
-
-		// value if PI *is* involved
-		static constexpr const unit_t<unit_type> value(std::true_type) noexcept
-		{
-			return unit_t<unit_type>(((UNIT_LIB_DEFAULT_TYPE)ratio::num / ratio::den) * std::pow(units::constants::detail::PI_VAL, ((UNIT_LIB_DEFAULT_TYPE)Base::_PI_EXP::num / Base::_PI_EXP::den)));
-		}
-		/** @endcond */	// END DOXYGEN IGNORE
-	};
-
-	/**
-	 * @ingroup		CompileTimeUnitManipulators
-	 * @brief		raises unit_value_to a power at compile-time
-	 * @details		The resulting unit will the `unit_type` of `U1` squared
-	 * @tparam		U1	`unit_value_t` to take the exponentiation of.
-	 * @sa			unit_value_t_traits to access information about the properties of the class,
-	 *				such as it's unit type and rational value.
-	 * @note		very similar in concept to `units::math::pow`
-	 */
-	template<class U1, int power>
-	struct unit_value_power : units::detail::unit_value_arithmetic<U1, U1>, units::detail::_unit_value_t<typename units::detail::power_of_unit<power, typename traits::unit_value_t_traits<U1>::unit_type>::type>
-	{
-		/** @cond */	// DOXYGEN IGNORE
-		using Base = units::detail::unit_value_arithmetic<U1, U1>;
-
-		using unit_type = typename units::detail::power_of_unit<power, typename Base::_UNIT1>::type;
-		using ratio = typename units::detail::power_of_ratio<power, typename Base::_RATIO1>::type;
-		using pi_exponent = std::ratio_multiply<std::ratio<power>, typename Base::_UNIT1::pi_exponent_ratio>;
-		/** @endcond */	// END DOXYGEN IGNORE
-
-		/**
-		 * @brief		Value of exponentiation
-		 * @details		Returns the calculated value of the exponentiation of `U1`, in units
-		 *				of `U1^power`.
-		 * @returns		Value of the exponentiation in the appropriate units.
-		 */
-		static constexpr const unit_t<unit_type> value() noexcept
-		{
-			using UsePi = std::integral_constant<bool, Base::_PI_EXP::num != 0>;
-			return value(UsePi());
-		}
-
-		/** @cond */	// DOXYGEN IGNORE
-		// value if PI isn't involved
-		static constexpr const unit_t<unit_type> value(std::false_type) noexcept
-		{
-			return unit_t<unit_type>((UNIT_LIB_DEFAULT_TYPE)ratio::num / ratio::den);
-		}
-
-		// value if PI *is* involved
-		static constexpr const unit_t<unit_type> value(std::true_type) noexcept
-		{
-			return unit_t<unit_type>(((UNIT_LIB_DEFAULT_TYPE)ratio::num / ratio::den) * std::pow(units::constants::detail::PI_VAL, ((UNIT_LIB_DEFAULT_TYPE)pi_exponent::num / pi_exponent::den)));
-		}
-		/** @endcond */	// END DOXYGEN IGNORE	};
-	};
-
-	/**
-	 * @ingroup		CompileTimeUnitManipulators
-	 * @brief		calculates square root of unit_value_t at compile-time
-	 * @details		The resulting unit will the square root `unit_type` of `U1`	 
-	 * @tparam		U1	`unit_value_t` to take the square root of.
-	 * @sa			unit_value_t_traits to access information about the properties of the class,
-	 *				such as it's unit type and rational value.
-	 * @note		very similar in concept to `units::ratio_sqrt`
-	 */
-	template<class U1, std::intmax_t Eps = 10000000000>
-	struct unit_value_sqrt : units::detail::unit_value_arithmetic<U1, U1>, units::detail::_unit_value_t<square_root<typename traits::unit_value_t_traits<U1>::unit_type, Eps>>
-	{
-		/** @cond */	// DOXYGEN IGNORE
-		using Base = units::detail::unit_value_arithmetic<U1, U1>;
-
-		using unit_type = square_root<typename Base::_UNIT1, Eps>;
-		using ratio = ratio_sqrt<typename Base::_RATIO1, Eps>;
-		using pi_exponent = ratio_sqrt<typename Base::_UNIT1::pi_exponent_ratio, Eps>;
-		/** @endcond */	// END DOXYGEN IGNORE
-
-		/**
-		 * @brief		Value of square root
-		 * @details		Returns the calculated value of the square root of `U1`, in units
-		 *				of `U1^1/2`.
-		 * @returns		Value of the square root in the appropriate units.
-		 */
-		static constexpr const unit_t<unit_type> value() noexcept
-		{
-			using UsePi = std::integral_constant<bool, Base::_PI_EXP::num != 0>;
-			return value(UsePi());
-		}
-
-		/** @cond */	// DOXYGEN IGNORE
-		// value if PI isn't involved
-		static constexpr const unit_t<unit_type> value(std::false_type) noexcept
-		{
-			return unit_t<unit_type>((UNIT_LIB_DEFAULT_TYPE)ratio::num / ratio::den);
-		}
-
-		// value if PI *is* involved
-		static constexpr const unit_t<unit_type> value(std::true_type) noexcept
-		{
-			return unit_t<unit_type>(((UNIT_LIB_DEFAULT_TYPE)ratio::num / ratio::den) * std::pow(units::constants::detail::PI_VAL, ((UNIT_LIB_DEFAULT_TYPE)pi_exponent::num / pi_exponent::den)));
-		}
-		/** @endcond */	// END DOXYGEN IGNORE
-	};
-
-	//------------------------------
-	//	LITERALS
-	//------------------------------
-
-	/**
-	 * @namespace	units::literals
-	 * @brief		namespace for unit literal definitions of all categories.
-	 * @details		Literals allow for declaring unit types using suffix values. For example, a type
-	 *				of `meter_t(6.2)` could be declared as `6.2_m`. All literals use an underscore
-	 *				followed by the abbreviation for the unit. To enable literal syntax in your code,
-	 *				include the statement `using namespace units::literals`.
-	 * @anchor		unitLiterals
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-
-	//------------------------------
-	//	LENGTH UNITS
-	//------------------------------
-
-	/**
-	 * @namespace	units::length
-	 * @brief		namespace for unit types and containers representing length values
-	 * @details		The SI unit for length is `meters`, and the corresponding `base_unit` category is
-	 *				`length_unit`.
-	 * @anchor		lengthContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_LENGTH_UNITS)
-	UNIT_ADD_WITH_METRIC_PREFIXES(length, meter, meters, m, unit<std::ratio<1>, units::category::length_unit>)
-	UNIT_ADD(length, foot, feet, ft, unit<std::ratio<381, 1250>, meters>)
-	UNIT_ADD(length, mil, mils, mil, unit<std::ratio<1000>, feet>)
-	UNIT_ADD(length, inch, inches, in, unit<std::ratio<1, 12>, feet>)
-	UNIT_ADD(length, mile,   miles,    mi,    unit<std::ratio<5280>, feet>)
-	UNIT_ADD(length, nauticalMile, nauticalMiles, nmi, unit<std::ratio<1852>, meters>)
-	UNIT_ADD(length, astronicalUnit, astronicalUnits, au, unit<std::ratio<149597870700>, meters>)
-	UNIT_ADD(length, lightyear, lightyears, ly, unit<std::ratio<9460730472580800>, meters>)
-	UNIT_ADD(length, parsec, parsecs, pc, unit<std::ratio<648000>, astronicalUnits, std::ratio<-1>>)
-	UNIT_ADD(length, angstrom, angstroms, angstrom, unit<std::ratio<1, 10>, nanometers>)
-	UNIT_ADD(length, cubit, cubits, cbt, unit<std::ratio<18>, inches>)
-	UNIT_ADD(length, fathom, fathoms, ftm, unit<std::ratio<6>, feet>)
-	UNIT_ADD(length, chain, chains, ch, unit<std::ratio<66>, feet>)
-	UNIT_ADD(length, furlong, furlongs, fur, unit<std::ratio<10>, chains>)
-	UNIT_ADD(length, hand, hands, hand, unit<std::ratio<4>, inches>)
-	UNIT_ADD(length, league, leagues, lea, unit<std::ratio<3>, miles>)
-	UNIT_ADD(length, nauticalLeague, nauticalLeagues, nl, unit<std::ratio<3>, nauticalMiles>)
-	UNIT_ADD(length, yard, yards, yd, unit<std::ratio<3>, feet>)
-
-	UNIT_ADD_CATEGORY_TRAIT(length)
-#endif
-
-	//------------------------------
-	//	MASS UNITS
-	//------------------------------
-
-	/**
-	 * @namespace	units::mass
-	 * @brief		namespace for unit types and containers representing mass values
-	 * @details		The SI unit for mass is `kilograms`, and the corresponding `base_unit` category is
-	 *				`mass_unit`.
-	 * @anchor		massContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_MASS_UNITS)
-	UNIT_ADD_WITH_METRIC_PREFIXES(mass, gram, grams, g, unit<std::ratio<1, 1000>, units::category::mass_unit>)
-	UNIT_ADD(mass, metric_ton, metric_tons, t, unit<std::ratio<1000>, kilograms>)
-	UNIT_ADD(mass, pound, pounds, lb, unit<std::ratio<45359237, 100000000>, kilograms>)
-	UNIT_ADD(mass, long_ton, long_tons, ln_t, unit<std::ratio<2240>, pounds>)
-	UNIT_ADD(mass, short_ton, short_tons, sh_t, unit<std::ratio<2000>, pounds>)
-	UNIT_ADD(mass, stone, stone, st, unit<std::ratio<14>, pounds>)
-	UNIT_ADD(mass, ounce, ounces, oz, unit<std::ratio<1, 16>, pounds>)
-	UNIT_ADD(mass, carat, carats, ct, unit<std::ratio<200>, milligrams>)
-	UNIT_ADD(mass, slug, slugs, slug, unit<std::ratio<145939029, 10000000>, kilograms>)
-
-	UNIT_ADD_CATEGORY_TRAIT(mass)
-#endif
-
-	//------------------------------
-	//	TIME UNITS
-	//------------------------------
-
-	/**
-	 * @namespace	units::time
-	 * @brief		namespace for unit types and containers representing time values
-	 * @details		The SI unit for time is `seconds`, and the corresponding `base_unit` category is
-	 *				`time_unit`.
-	 * @anchor		timeContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_TIME_UNITS)
-	UNIT_ADD_WITH_METRIC_PREFIXES(time, second, seconds, s, unit<std::ratio<1>, units::category::time_unit>)
-	UNIT_ADD(time, minute, minutes, min, unit<std::ratio<60>, seconds>)
-	UNIT_ADD(time, hour, hours, hr, unit<std::ratio<60>, minutes>)
-	UNIT_ADD(time, day, days, d, unit<std::ratio<24>, hours>)
-	UNIT_ADD(time, week, weeks, wk, unit<std::ratio<7>, days>)
-	UNIT_ADD(time, year, years, yr, unit<std::ratio<365>, days>)
-	UNIT_ADD(time, julian_year, julian_years, a_j,	unit<std::ratio<31557600>, seconds>)
-	UNIT_ADD(time, gregorian_year, gregorian_years, a_g, unit<std::ratio<31556952>, seconds>)
-
-	UNIT_ADD_CATEGORY_TRAIT(time)
-#endif
-
-	//------------------------------
-	//	ANGLE UNITS
-	//------------------------------
-
-	/**
-	 * @namespace	units::angle
-	 * @brief		namespace for unit types and containers representing angle values
-	 * @details		The SI unit for angle is `radians`, and the corresponding `base_unit` category is
-	 *				`angle_unit`.
-	 * @anchor		angleContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
-	UNIT_ADD_WITH_METRIC_PREFIXES(angle, radian, radians, rad, unit<std::ratio<1>, units::category::angle_unit>)
-	UNIT_ADD(angle, degree, degrees, deg, unit<std::ratio<1, 180>, radians, std::ratio<1>>)
-	UNIT_ADD(angle, arcminute, arcminutes, arcmin, unit<std::ratio<1, 60>, degrees>)
-	UNIT_ADD(angle, arcsecond, arcseconds, arcsec, unit<std::ratio<1, 60>, arcminutes>)
-	UNIT_ADD(angle, milliarcsecond, milliarcseconds, mas, milli<arcseconds>)
-	UNIT_ADD(angle, turn, turns, tr, unit<std::ratio<2>, radians, std::ratio<1>>)
-	UNIT_ADD(angle, gradian, gradians, gon, unit<std::ratio<1, 400>, turns>)
-
-	UNIT_ADD_CATEGORY_TRAIT(angle)
-#endif
-
-	//------------------------------
-	//	UNITS OF CURRENT
-	//------------------------------
-	/**
-	 * @namespace	units::current
-	 * @brief		namespace for unit types and containers representing current values
-	 * @details		The SI unit for current is `amperes`, and the corresponding `base_unit` category is
-	 *				`current_unit`.
-	 * @anchor		currentContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_CURRENT_UNITS)
-	UNIT_ADD_WITH_METRIC_PREFIXES(current, ampere, amperes, A, unit<std::ratio<1>, units::category::current_unit>)
-	
-	UNIT_ADD_CATEGORY_TRAIT(current)
-#endif
-
-	//------------------------------
-	//	UNITS OF TEMPERATURE
-	//------------------------------
-
-	// NOTE: temperature units have special conversion overloads, since they
-	// require translations and aren't a reversible transform.
-
-	/**
-	 * @namespace	units::temperature
-	 * @brief		namespace for unit types and containers representing temperature values
-	 * @details		The SI unit for temperature is `kelvin`, and the corresponding `base_unit` category is
-	 *				`temperature_unit`.
-	 * @anchor		temperatureContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_TEMPERATURE_UNITS)
-	UNIT_ADD(temperature, kelvin, kelvin, K, unit<std::ratio<1>, units::category::temperature_unit>)
-	UNIT_ADD(temperature, celsius, celsius, degC, unit<std::ratio<1>, kelvin, std::ratio<0>, std::ratio<27315, 100>>)
-	UNIT_ADD(temperature, fahrenheit, fahrenheit, degF, unit<std::ratio<5, 9>, celsius, std::ratio<0>, std::ratio<-160, 9>>)
-	UNIT_ADD(temperature, reaumur, reaumur, Re, unit<std::ratio<10, 8>, celsius>)
-	UNIT_ADD(temperature, rankine, rankine, Ra, unit<std::ratio<5, 9>, kelvin>)
-
-	UNIT_ADD_CATEGORY_TRAIT(temperature)
-#endif
-
-	//------------------------------
-	//	UNITS OF AMOUNT OF SUBSTANCE
-	//------------------------------
-
-	/**
-	 * @namespace	units::substance
-	 * @brief		namespace for unit types and containers representing substance values
-	 * @details		The SI unit for substance is `moles`, and the corresponding `base_unit` category is
-	 *				`substance_unit`.
-	 * @anchor		substanceContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_SUBSTANCE_UNITS)
-	UNIT_ADD(substance, mole, moles, mol, unit<std::ratio<1>, units::category::substance_unit>)
-	
-	UNIT_ADD_CATEGORY_TRAIT(substance)
-#endif
-
-	//------------------------------
-	//	UNITS OF LUMINOUS INTENSITY
-	//------------------------------
-
-	/**
-	 * @namespace	units::luminous_intensity
-	 * @brief		namespace for unit types and containers representing luminous_intensity values
-	 * @details		The SI unit for luminous_intensity is `candelas`, and the corresponding `base_unit` category is
-	 *				`luminous_intensity_unit`.
-	 * @anchor		luminousIntensityContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_LUMINOUS_INTENSITY_UNITS)
-	UNIT_ADD_WITH_METRIC_PREFIXES(luminous_intensity, candela, candelas, cd, unit<std::ratio<1>, units::category::luminous_intensity_unit>)
-	
-	UNIT_ADD_CATEGORY_TRAIT(luminous_intensity)
-#endif
-
-	//------------------------------
-	//	UNITS OF SOLID ANGLE
-	//------------------------------
-
-	/**
-	 * @namespace	units::solid_angle
-	 * @brief		namespace for unit types and containers representing solid_angle values
-	 * @details		The SI unit for solid_angle is `steradians`, and the corresponding `base_unit` category is
-	 *				`solid_angle_unit`.
-	 * @anchor		solidAngleContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_SOLID_ANGLE_UNITS)
-	UNIT_ADD_WITH_METRIC_PREFIXES(solid_angle, steradian, steradians, sr, unit<std::ratio<1>, units::category::solid_angle_unit>)
-	UNIT_ADD(solid_angle, degree_squared, degrees_squared, sq_deg, squared<angle::degrees>)
-	UNIT_ADD(solid_angle, spat, spats, sp, unit<std::ratio<4>, steradians, std::ratio<1>>)
-
-	UNIT_ADD_CATEGORY_TRAIT(solid_angle)
-#endif
-
-	//------------------------------
-	//	FREQUENCY UNITS
-	//------------------------------
-
-	/**
-	 * @namespace	units::frequency
-	 * @brief		namespace for unit types and containers representing frequency values
-	 * @details		The SI unit for frequency is `hertz`, and the corresponding `base_unit` category is
-	 *				`frequency_unit`.
-	 * @anchor		frequencyContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_FREQUENCY_UNITS)
-	UNIT_ADD_WITH_METRIC_PREFIXES(frequency, hertz, hertz, Hz, unit<std::ratio<1>, units::category::frequency_unit>)
-
-	UNIT_ADD_CATEGORY_TRAIT(frequency)
-#endif
-
-	//------------------------------
-	//	VELOCITY UNITS
-	//------------------------------
-
-	/**
-	 * @namespace	units::velocity
-	 * @brief		namespace for unit types and containers representing velocity values
-	 * @details		The SI unit for velocity is `meters_per_second`, and the corresponding `base_unit` category is
-	 *				`velocity_unit`.
-	 * @anchor		velocityContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_VELOCITY_UNITS)
-	UNIT_ADD(velocity, meters_per_second, meters_per_second, mps, unit<std::ratio<1>, units::category::velocity_unit>)
-	UNIT_ADD(velocity, feet_per_second, feet_per_second, fps, compound_unit<length::feet, inverse<time::seconds>>)
-	UNIT_ADD(velocity, miles_per_hour, miles_per_hour, mph, compound_unit<length::miles, inverse<time::hour>>)
-	UNIT_ADD(velocity, kilometers_per_hour, kilometers_per_hour, kph, compound_unit<length::kilometers, inverse<time::hour>>)
-	UNIT_ADD(velocity, knot, knots, kts, compound_unit<length::nauticalMiles, inverse<time::hour>>)
-	
-	UNIT_ADD_CATEGORY_TRAIT(velocity)
-#endif
-
-	//------------------------------
-	//	ANGULAR VELOCITY UNITS
-	//------------------------------
-
-	/**
-	 * @namespace	units::angular_velocity
-	 * @brief		namespace for unit types and containers representing angular velocity values
-	 * @details		The SI unit for angular velocity is `radians_per_second`, and the corresponding `base_unit` category is
-	 *				`angular_velocity_unit`.
-	 * @anchor		angularVelocityContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGULAR_VELOCITY_UNITS)
-	UNIT_ADD(angular_velocity, radians_per_second, radians_per_second, rad_per_s, unit<std::ratio<1>, units::category::angular_velocity_unit>)
-	UNIT_ADD(angular_velocity, degrees_per_second, degrees_per_second, deg_per_s, compound_unit<angle::degrees, inverse<time::seconds>>)
-	UNIT_ADD(angular_velocity, revolutions_per_minute, revolutions_per_minute, rpm, unit<std::ratio<2, 60>, radians_per_second, std::ratio<1>>)
-	UNIT_ADD(angular_velocity, milliarcseconds_per_year, milliarcseconds_per_year, mas_per_yr, compound_unit<angle::milliarcseconds, inverse<time::year>>)
-
-	UNIT_ADD_CATEGORY_TRAIT(angular_velocity)
-#endif
-
-	//------------------------------
-	//	UNITS OF ACCELERATION
-	//------------------------------
-
-	/**
-	 * @namespace	units::acceleration
-	 * @brief		namespace for unit types and containers representing acceleration values
-	 * @details		The SI unit for acceleration is `meters_per_second_squared`, and the corresponding `base_unit` category is
-	 *				`acceleration_unit`.
-	 * @anchor		accelerationContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ACCELERATION_UNITS)
-	UNIT_ADD(acceleration, meters_per_second_squared, meters_per_second_squared, mps_sq, unit<std::ratio<1>, units::category::acceleration_unit>)
-	UNIT_ADD(acceleration, feet_per_second_squared, feet_per_second_squared, fps_sq, compound_unit<length::feet, inverse<squared<time::seconds>>>)
-	UNIT_ADD(acceleration, standard_gravity, standard_gravity, SG, unit<std::ratio<980665, 100000>, meters_per_second_squared>)
-
-	UNIT_ADD_CATEGORY_TRAIT(acceleration)
-#endif
-
-	//------------------------------
-	//	UNITS OF FORCE
-	//------------------------------
-
-	/**
-	 * @namespace	units::force
-	 * @brief		namespace for unit types and containers representing force values
-	 * @details		The SI unit for force is `newtons`, and the corresponding `base_unit` category is
-	 *				`force_unit`.
-	 * @anchor		forceContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_FORCE_UNITS)
-	UNIT_ADD_WITH_METRIC_PREFIXES(force, newton, newtons, N, unit<std::ratio<1>, units::category::force_unit>)
-	UNIT_ADD(force, pound, pounds, lbf, compound_unit<mass::slug, length::foot, inverse<squared<time::seconds>>>)
-	UNIT_ADD(force, dyne, dynes, dyn, unit<std::ratio<1, 100000>, newtons>)
-	UNIT_ADD(force, kilopond, kiloponds, kp, compound_unit<acceleration::standard_gravity, mass::kilograms>)
-	UNIT_ADD(force, poundal, poundals, pdl, compound_unit<mass::pound, length::foot, inverse<squared<time::seconds>>>)
-
-	UNIT_ADD_CATEGORY_TRAIT(force)
-#endif
-
-	//------------------------------
-	//	UNITS OF PRESSURE
-	//------------------------------
-
-	/**
-	 * @namespace	units::pressure
-	 * @brief		namespace for unit types and containers representing pressure values
-	 * @details		The SI unit for pressure is `pascals`, and the corresponding `base_unit` category is
-	 *				`pressure_unit`.
-	 * @anchor		pressureContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_PRESSURE_UNITS)
-	UNIT_ADD_WITH_METRIC_PREFIXES(pressure, pascal, pascals, Pa, unit<std::ratio<1>, units::category::pressure_unit>)
-	UNIT_ADD(pressure, bar, bars, bar, unit<std::ratio<100>, kilo<pascals>>)
-	UNIT_ADD(pressure, mbar, mbars, mbar, unit<std::ratio<1>, milli<bar>>)
-	UNIT_ADD(pressure, atmosphere, atmospheres, atm, unit<std::ratio<101325>, pascals>)
-	UNIT_ADD(pressure, pounds_per_square_inch, pounds_per_square_inch, psi, compound_unit<force::pounds, inverse<squared<length::inch>>>)
-	UNIT_ADD(pressure, torr, torrs, torr, unit<std::ratio<1, 760>, atmospheres>)
-	
-	UNIT_ADD_CATEGORY_TRAIT(pressure)
-#endif
-
-	//------------------------------
-	//	UNITS OF CHARGE
-	//------------------------------
-
-	/**
-	 * @namespace	units::charge
-	 * @brief		namespace for unit types and containers representing charge values
-	 * @details		The SI unit for charge is `coulombs`, and the corresponding `base_unit` category is
-	 *				`charge_unit`.
-	 * @anchor		chargeContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_CHARGE_UNITS)
-	UNIT_ADD_WITH_METRIC_PREFIXES(charge, coulomb, coulombs, C, unit<std::ratio<1>, units::category::charge_unit>)
-	UNIT_ADD_WITH_METRIC_PREFIXES(charge, ampere_hour, ampere_hours, Ah, compound_unit<current::ampere, time::hours>)
-
-	UNIT_ADD_CATEGORY_TRAIT(charge)
-#endif
-
-	//------------------------------
-	//	UNITS OF ENERGY
-	//------------------------------
-
-	/**
-	 * @namespace	units::energy
-	 * @brief		namespace for unit types and containers representing energy values
-	 * @details		The SI unit for energy is `joules`, and the corresponding `base_unit` category is
-	 *				`energy_unit`.
-	 * @anchor		energyContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ENERGY_UNITS)
-	UNIT_ADD_WITH_METRIC_PREFIXES(energy, joule, joules, J, unit<std::ratio<1>, units::category::energy_unit>)
-	UNIT_ADD_WITH_METRIC_PREFIXES(energy, calorie, calories, cal, unit<std::ratio<4184, 1000>, joules>)
-	UNIT_ADD(energy, kilowatt_hour, kilowatt_hours, kWh, unit<std::ratio<36, 10>, megajoules>)
-	UNIT_ADD(energy, watt_hour, watt_hours, Wh, unit<std::ratio<1, 1000>, kilowatt_hours>)
-	UNIT_ADD(energy, british_thermal_unit, british_thermal_units, BTU, unit<std::ratio<105505585262, 100000000>, joules>)
-	UNIT_ADD(energy, british_thermal_unit_iso, british_thermal_units_iso, BTU_iso, unit<std::ratio<1055056, 1000>, joules>)
-	UNIT_ADD(energy, british_thermal_unit_59, british_thermal_units_59, BTU59, unit<std::ratio<1054804, 1000>, joules>)
-	UNIT_ADD(energy, therm, therms, thm, unit<std::ratio<100000>, british_thermal_units_59>)
-	UNIT_ADD(energy, foot_pound, foot_pounds, ftlbf, unit<std::ratio<13558179483314004, 10000000000000000>, joules>)
-
-	UNIT_ADD_CATEGORY_TRAIT(energy)
-#endif
-
-	//------------------------------
-	//	UNITS OF POWER
-	//------------------------------
-
-	/**
-	 * @namespace	units::power
-	 * @brief		namespace for unit types and containers representing power values
-	 * @details		The SI unit for power is `watts`, and the corresponding `base_unit` category is
-	 *				`power_unit`.
-	 * @anchor		powerContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_POWER_UNITS)
-	UNIT_ADD_WITH_METRIC_PREFIXES(power, watt, watts, W, unit<std::ratio<1>, units::category::power_unit>)
-	UNIT_ADD(power, horsepower, horsepower, hp, unit<std::ratio<7457, 10>, watts>)
-	UNIT_ADD_DECIBEL(power, watt, dBW)
-	UNIT_ADD_DECIBEL(power, milliwatt, dBm)
-	
-	UNIT_ADD_CATEGORY_TRAIT(power)
-#endif
-
-	//------------------------------
-	//	UNITS OF VOLTAGE
-	//------------------------------
-
-	/**
-	 * @namespace	units::voltage
-	 * @brief		namespace for unit types and containers representing voltage values
-	 * @details		The SI unit for voltage is `volts`, and the corresponding `base_unit` category is
-	 *				`voltage_unit`.
-	 * @anchor		voltageContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_VOLTAGE_UNITS)
-	UNIT_ADD_WITH_METRIC_PREFIXES(voltage, volt, volts, V, unit<std::ratio<1>, units::category::voltage_unit>)
-	UNIT_ADD(voltage, statvolt, statvolts, statV, unit<std::ratio<1000000, 299792458>, volts>)
-	UNIT_ADD(voltage, abvolt, abvolts, abV, unit<std::ratio<1, 100000000>, volts>)
-	
-	UNIT_ADD_CATEGORY_TRAIT(voltage)
-#endif
-
-	//------------------------------
-	//	UNITS OF CAPACITANCE
-	//------------------------------
-
-	/**
-	 * @namespace	units::capacitance
-	 * @brief		namespace for unit types and containers representing capacitance values
-	 * @details		The SI unit for capacitance is `farads`, and the corresponding `base_unit` category is
-	 *				`capacitance_unit`.
-	 * @anchor		capacitanceContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_CAPACITANCE_UNITS)
-	UNIT_ADD_WITH_METRIC_PREFIXES(capacitance, farad, farads, F, unit<std::ratio<1>, units::category::capacitance_unit>)
-	
-	UNIT_ADD_CATEGORY_TRAIT(capacitance)
-#endif
-
-	//------------------------------
-	//	UNITS OF IMPEDANCE
-	//------------------------------
-
-	/**
-	 * @namespace	units::impedance
-	 * @brief		namespace for unit types and containers representing impedance values
-	 * @details		The SI unit for impedance is `ohms`, and the corresponding `base_unit` category is
-	 *				`impedance_unit`.
-	 * @anchor		impedanceContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_IMPEDANCE_UNITS)
-	UNIT_ADD_WITH_METRIC_PREFIXES(impedance, ohm, ohms, Ohm, unit<std::ratio<1>, units::category::impedance_unit>)
-	
-	UNIT_ADD_CATEGORY_TRAIT(impedance)
-#endif
-
-	//------------------------------
-	//	UNITS OF CONDUCTANCE
-	//------------------------------
-
-	/**
-	 * @namespace	units::conductance
-	 * @brief		namespace for unit types and containers representing conductance values
-	 * @details		The SI unit for conductance is `siemens`, and the corresponding `base_unit` category is
-	 *				`conductance_unit`.
-	 * @anchor		conductanceContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_CONDUCTANCE_UNITS)
-	UNIT_ADD_WITH_METRIC_PREFIXES(conductance, siemens, siemens, S, unit<std::ratio<1>, units::category::conductance_unit>)
-	
-	UNIT_ADD_CATEGORY_TRAIT(conductance)
-#endif
-
-	//------------------------------
-	//	UNITS OF MAGNETIC FLUX
-	//------------------------------
-
-	/**
-	 * @namespace	units::magnetic_flux
-	 * @brief		namespace for unit types and containers representing magnetic_flux values
-	 * @details		The SI unit for magnetic_flux is `webers`, and the corresponding `base_unit` category is
-	 *				`magnetic_flux_unit`.
-	 * @anchor		magneticFluxContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_MAGNETIC_FLUX_UNITS)
-	UNIT_ADD_WITH_METRIC_PREFIXES(magnetic_flux, weber, webers, Wb, unit<std::ratio<1>, units::category::magnetic_flux_unit>)
-	UNIT_ADD(magnetic_flux, maxwell, maxwells, Mx, unit<std::ratio<1, 100000000>, webers>)
-
-	UNIT_ADD_CATEGORY_TRAIT(magnetic_flux)
-#endif
-
-	//----------------------------------------
-	//	UNITS OF MAGNETIC FIELD STRENGTH
-	//----------------------------------------
-
-	/**
-	 * @namespace	units::magnetic_field_strength
-	 * @brief		namespace for unit types and containers representing magnetic_field_strength values
-	 * @details		The SI unit for magnetic_field_strength is `teslas`, and the corresponding `base_unit` category is
-	 *				`magnetic_field_strength_unit`.
-	 * @anchor		magneticFieldStrengthContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-	// Unfortunately `_T` is a WINAPI macro, so we have to use `_Te` as the tesla abbreviation.
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_MAGNETIC_FIELD_STRENGTH_UNITS)
-	UNIT_ADD_WITH_METRIC_PREFIXES(magnetic_field_strength, tesla, teslas, Te, unit<std::ratio<1>, units::category::magnetic_field_strength_unit>)
-	UNIT_ADD(magnetic_field_strength, gauss, gauss, G, compound_unit<magnetic_flux::maxwell, inverse<squared<length::centimeter>>>)
-		
-	UNIT_ADD_CATEGORY_TRAIT(magnetic_field_strength)
-#endif
-
-	//------------------------------
-	//	UNITS OF INDUCTANCE
-	//------------------------------
-
-	/**
-	 * @namespace	units::inductance
-	 * @brief		namespace for unit types and containers representing inductance values
-	 * @details		The SI unit for inductance is `henrys`, and the corresponding `base_unit` category is
-	 *				`inductance_unit`.
-	 * @anchor		inductanceContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_INDUCTANCE_UNITS)
-	UNIT_ADD_WITH_METRIC_PREFIXES(inductance, henry, henries, H, unit<std::ratio<1>, units::category::inductance_unit>)
-
-	UNIT_ADD_CATEGORY_TRAIT(inductance)
-#endif
-
-	//------------------------------
-	//	UNITS OF LUMINOUS FLUX
-	//------------------------------
-
-	/**
-	 * @namespace	units::luminous_flux
-	 * @brief		namespace for unit types and containers representing luminous_flux values
-	 * @details		The SI unit for luminous_flux is `lumens`, and the corresponding `base_unit` category is
-	 *				`luminous_flux_unit`.
-	 * @anchor		luminousFluxContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_LUMINOUS_FLUX_UNITS)
-	UNIT_ADD_WITH_METRIC_PREFIXES(luminous_flux, lumen, lumens, lm, unit<std::ratio<1>, units::category::luminous_flux_unit>)
-	
-	UNIT_ADD_CATEGORY_TRAIT(luminous_flux)
-#endif
-
-	//------------------------------
-	//	UNITS OF ILLUMINANCE
-	//------------------------------
-
-	/**
-	 * @namespace	units::illuminance
-	 * @brief		namespace for unit types and containers representing illuminance values
-	 * @details		The SI unit for illuminance is `luxes`, and the corresponding `base_unit` category is
-	 *				`illuminance_unit`.
-	 * @anchor		illuminanceContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ILLUMINANCE_UNITS)
-	UNIT_ADD_WITH_METRIC_PREFIXES(illuminance, lux, luxes, lx, unit<std::ratio<1>, units::category::illuminance_unit>)
-	UNIT_ADD(illuminance, footcandle, footcandles, fc, compound_unit<luminous_flux::lumen, inverse<squared<length::foot>>>)
-	UNIT_ADD(illuminance, lumens_per_square_inch, lumens_per_square_inch, lm_per_in_sq, compound_unit<luminous_flux::lumen, inverse<squared<length::inch>>>)
-	UNIT_ADD(illuminance, phot, phots, ph, compound_unit<luminous_flux::lumens, inverse<squared<length::centimeter>>>)
-	
-	UNIT_ADD_CATEGORY_TRAIT(illuminance)
-#endif
-
-	//------------------------------
-	//	UNITS OF RADIATION
-	//------------------------------
-
-	/**
-	 * @namespace	units::radiation
-	 * @brief		namespace for unit types and containers representing radiation values
-	 * @details		The SI units for radiation are:
-	 *				- source activity:	becquerel
-	 *				- absorbed dose:	gray
-	 *				- equivalent dose:	sievert
-	 * @anchor		radiationContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_RADIATION_UNITS)
-	UNIT_ADD_WITH_METRIC_PREFIXES(radiation, becquerel, becquerels, Bq, unit<std::ratio<1>, units::frequency::hertz>)
-	UNIT_ADD_WITH_METRIC_PREFIXES(radiation, gray, grays, Gy, compound_unit<energy::joules, inverse<mass::kilogram>>)
-	UNIT_ADD_WITH_METRIC_PREFIXES(radiation, sievert, sieverts, Sv, unit<std::ratio<1>, grays>)
-	UNIT_ADD(radiation, curie, curies, Ci, unit<std::ratio<37>, gigabecquerels>)
-	UNIT_ADD(radiation, rutherford, rutherfords, rd, unit<std::ratio<1>, megabecquerels>)
-	UNIT_ADD(radiation, rad, rads, rads, unit<std::ratio<1>, centigrays>)
-
-	UNIT_ADD_CATEGORY_TRAIT(radioactivity)
-#endif
-
-	//------------------------------
-	//	UNITS OF TORQUE
-	//------------------------------
-
-	/**
-	 * @namespace	units::torque
-	 * @brief		namespace for unit types and containers representing torque values
-	 * @details		The SI unit for torque is `newton_meters`, and the corresponding `base_unit` category is
-	 *				`torque_units`.
-	 * @anchor		torqueContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_TORQUE_UNITS)
-	UNIT_ADD(torque, newton_meter, newton_meters, Nm, unit<std::ratio<1>, units::energy::joule>)
-	UNIT_ADD(torque, foot_pound, foot_pounds, ftlb, compound_unit<length::foot, force::pounds>)
-	UNIT_ADD(torque, foot_poundal, foot_poundals, ftpdl, compound_unit<length::foot, force::poundal>)
-	UNIT_ADD(torque, inch_pound, inch_pounds, inlb, compound_unit<length::inch, force::pounds>)
-	UNIT_ADD(torque, meter_kilogram, meter_kilograms, mkgf, compound_unit<length::meter, force::kiloponds>)
-	
-	UNIT_ADD_CATEGORY_TRAIT(torque)
-#endif
-
-	//------------------------------
-	//	AREA UNITS
-	//------------------------------
-
-	/**
-	 * @namespace	units::area
-	 * @brief		namespace for unit types and containers representing area values
-	 * @details		The SI unit for area is `square_meters`, and the corresponding `base_unit` category is
-	 *				`area_unit`.
-	 * @anchor		areaContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_AREA_UNITS)
-	UNIT_ADD(area, square_meter, square_meters, sq_m, unit<std::ratio<1>, units::category::area_unit>)
-	UNIT_ADD(area, square_foot, square_feet, sq_ft, squared<length::feet>)
-	UNIT_ADD(area, square_inch, square_inches, sq_in, squared<length::inch>)
-	UNIT_ADD(area, square_mile, square_miles, sq_mi, squared<length::miles>)
-	UNIT_ADD(area, square_kilometer, square_kilometers, sq_km, squared<length::kilometers>)
-	UNIT_ADD(area, hectare, hectares, ha, unit<std::ratio<10000>, square_meters>)
-	UNIT_ADD(area, acre, acres, acre, unit<std::ratio<43560>, square_feet>)
-	
-	UNIT_ADD_CATEGORY_TRAIT(area)
-#endif
-
-	//------------------------------
-	//	UNITS OF VOLUME
-	//------------------------------
-
-	/**
-	 * @namespace	units::volume
-	 * @brief		namespace for unit types and containers representing volume values
-	 * @details		The SI unit for volume is `cubic_meters`, and the corresponding `base_unit` category is
-	 *				`volume_unit`.
-	 * @anchor		volumeContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_VOLUME_UNITS)
-	UNIT_ADD(volume, cubic_meter, cubic_meters, cu_m, unit<std::ratio<1>, units::category::volume_unit>)
-	UNIT_ADD(volume, cubic_millimeter, cubic_millimeters, cu_mm, cubed<length::millimeter>)
-	UNIT_ADD(volume, cubic_kilometer, cubic_kilometers, cu_km, cubed<length::kilometer>)
-	UNIT_ADD_WITH_METRIC_PREFIXES(volume, liter, liters, L, cubed<deci<length::meter>>)
-	UNIT_ADD(volume, cubic_inch, cubic_inches, cu_in, cubed<length::inches>)
-	UNIT_ADD(volume, cubic_foot, cubic_feet, cu_ft, cubed<length::feet>)
-	UNIT_ADD(volume, cubic_yard, cubic_yards, cu_yd, cubed<length::yards>)
-	UNIT_ADD(volume, cubic_mile, cubic_miles, cu_mi, cubed<length::miles>)
-	UNIT_ADD(volume, gallon, gallons, gal, unit<std::ratio<231>, cubic_inches>)
-	UNIT_ADD(volume, quart, quarts, qt, unit<std::ratio<1, 4>, gallons>)
-	UNIT_ADD(volume, pint, pints, pt, unit<std::ratio<1, 2>, quarts>)
-	UNIT_ADD(volume, cup, cups, c, unit<std::ratio<1, 2>, pints>)
-	UNIT_ADD(volume, fluid_ounce, fluid_ounces, fl_oz, unit<std::ratio<1, 8>, cups>)
-	UNIT_ADD(volume, barrel, barrels, bl, unit<std::ratio<42>, gallons>)
-	UNIT_ADD(volume, bushel, bushels, bu, unit<std::ratio<215042, 100>, cubic_inches>)
-	UNIT_ADD(volume, cord, cords, cord, unit<std::ratio<128>, cubic_feet>)
-	UNIT_ADD(volume, cubic_fathom, cubic_fathoms, cu_fm, cubed<length::fathom>)
-	UNIT_ADD(volume, tablespoon, tablespoons, tbsp, unit<std::ratio<1, 2>, fluid_ounces>)
-	UNIT_ADD(volume, teaspoon, teaspoons, tsp, unit<std::ratio<1, 6>, fluid_ounces>)
-	UNIT_ADD(volume, pinch, pinches, pinch, unit<std::ratio<1, 8>, teaspoons>)
-	UNIT_ADD(volume, dash, dashes, dash, unit<std::ratio<1, 2>, pinches>)
-	UNIT_ADD(volume, drop, drops, drop, unit<std::ratio<1, 360>, fluid_ounces>)
-	UNIT_ADD(volume, fifth, fifths, fifth, unit<std::ratio<1, 5>, gallons>)
-	UNIT_ADD(volume, dram, drams, dr, unit<std::ratio<1, 8>, fluid_ounces>)
-	UNIT_ADD(volume, gill, gills, gi, unit<std::ratio<4>, fluid_ounces>)
-	UNIT_ADD(volume, peck, pecks, pk, unit<std::ratio<1, 4>, bushels>)
-	UNIT_ADD(volume, sack, sacks, sacks, unit<std::ratio<3>, bushels>)
-	UNIT_ADD(volume, shot, shots, shots, unit<std::ratio<3, 2>, fluid_ounces>)
-	UNIT_ADD(volume, strike, strikes, strikes, unit<std::ratio<2>, bushels>)
-
-	UNIT_ADD_CATEGORY_TRAIT(volume)
-#endif
-
-	//------------------------------
-	//	UNITS OF DENSITY
-	//------------------------------
-
-	/**
-	 * @namespace	units::density
-	 * @brief		namespace for unit types and containers representing density values
-	 * @details		The SI unit for density is `kilograms_per_cubic_meter`, and the corresponding `base_unit` category is
-	 *				`density_unit`.
-	 * @anchor		densityContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_DENSITY_UNITS)
-	UNIT_ADD(density, kilograms_per_cubic_meter, kilograms_per_cubic_meter, kg_per_cu_m, unit<std::ratio<1>, units::category::density_unit>)
-	UNIT_ADD(density, grams_per_milliliter, grams_per_milliliter, g_per_mL, compound_unit<mass::grams, inverse<volume::milliliter>>)
-	UNIT_ADD(density, kilograms_per_liter, kilograms_per_liter, kg_per_L, unit<std::ratio<1>, compound_unit<mass::grams, inverse<volume::milliliter>>>)
-	UNIT_ADD(density, ounces_per_cubic_foot, ounces_per_cubic_foot, oz_per_cu_ft, compound_unit<mass::ounces, inverse<volume::cubic_foot>>)
-	UNIT_ADD(density, ounces_per_cubic_inch, ounces_per_cubic_inch, oz_per_cu_in, compound_unit<mass::ounces, inverse<volume::cubic_inch>>)
-	UNIT_ADD(density, ounces_per_gallon, ounces_per_gallon, oz_per_gal, compound_unit<mass::ounces, inverse<volume::gallon>>)
-	UNIT_ADD(density, pounds_per_cubic_foot, pounds_per_cubic_foot, lb_per_cu_ft, compound_unit<mass::pounds, inverse<volume::cubic_foot>>)
-	UNIT_ADD(density, pounds_per_cubic_inch, pounds_per_cubic_inch, lb_per_cu_in, compound_unit<mass::pounds, inverse<volume::cubic_inch>>)
-	UNIT_ADD(density, pounds_per_gallon, pounds_per_gallon, lb_per_gal, compound_unit<mass::pounds, inverse<volume::gallon>>)
-	UNIT_ADD(density, slugs_per_cubic_foot, slugs_per_cubic_foot, slug_per_cu_ft, compound_unit<mass::slugs, inverse<volume::cubic_foot>>)
-
-	UNIT_ADD_CATEGORY_TRAIT(density)
-#endif
-
-	//------------------------------
-	//	UNITS OF CONCENTRATION
-	//------------------------------
-
-	/**
-	 * @namespace	units::concentration
-	 * @brief		namespace for unit types and containers representing concentration values
-	 * @details		The SI unit for concentration is `parts_per_million`, and the corresponding `base_unit` category is
-	 *				`scalar_unit`.
-	 * @anchor		concentrationContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_CONCENTRATION_UNITS)
-	UNIT_ADD(concentration, ppm, parts_per_million, ppm, unit<std::ratio<1, 1000000>, units::category::scalar_unit>)
-	UNIT_ADD(concentration, ppb, parts_per_billion, ppb, unit<std::ratio<1, 1000>, parts_per_million>)
-	UNIT_ADD(concentration, ppt, parts_per_trillion, ppt, unit<std::ratio<1, 1000>, parts_per_billion>)
-	UNIT_ADD(concentration, percent, percent, pct, unit<std::ratio<1, 100>, units::category::scalar_unit>)
-
-	UNIT_ADD_CATEGORY_TRAIT(concentration)
-#endif
-
-	//------------------------------
-	//	UNITS OF DATA
-	//------------------------------
-
-	/**
-	 * @namespace	units::data
-	 * @brief		namespace for unit types and containers representing data values
-	 * @details		The base unit for data is `bytes`, and the corresponding `base_unit` category is
-	 *				`data_unit`.
-	 * @anchor		dataContainers
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_DATA_UNITS)
-	UNIT_ADD_WITH_METRIC_AND_BINARY_PREFIXES(data, byte, bytes, B, unit<std::ratio<1>, units::category::data_unit>)
-	UNIT_ADD(data, exabyte, exabytes, EB, unit<std::ratio<1000>, petabytes>)
-	UNIT_ADD_WITH_METRIC_AND_BINARY_PREFIXES(data, bit, bits, b, unit<std::ratio<1, 8>, byte>)
-	UNIT_ADD(data, exabit, exabits, Eb, unit<std::ratio<1000>, petabits>)
-
-	UNIT_ADD_CATEGORY_TRAIT(data)
-#endif
-
-	//------------------------------
-	//	UNITS OF DATA TRANSFER
-	//------------------------------
-
-	/**
-	* @namespace	units::data_transfer_rate
-	* @brief		namespace for unit types and containers representing data values
-	* @details		The base unit for data is `bytes`, and the corresponding `base_unit` category is
-	*				`data_unit`.
-	* @anchor		dataContainers
-	* @sa			See unit_t for more information on unit type containers.
-	*/
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_DATA_TRANSFER_RATE_UNITS)
-	UNIT_ADD_WITH_METRIC_AND_BINARY_PREFIXES(data_transfer_rate, bytes_per_second, bytes_per_second, Bps, unit<std::ratio<1>, units::category::data_transfer_rate_unit>)
-	UNIT_ADD(data_transfer_rate, exabytes_per_second, exabytes_per_second, EBps, unit<std::ratio<1000>, petabytes_per_second>)
-	UNIT_ADD_WITH_METRIC_AND_BINARY_PREFIXES(data_transfer_rate, bits_per_second, bits_per_second, bps, unit<std::ratio<1, 8>, bytes_per_second>)
-	UNIT_ADD(data_transfer_rate, exabits_per_second, exabits_per_second, Ebps, unit<std::ratio<1000>, petabits_per_second>)
-
-	UNIT_ADD_CATEGORY_TRAIT(data_transfer_rate)
-#endif
-
-	//------------------------------
-	//	CONSTANTS
-	//------------------------------
-
-	/**
-	 * @brief		namespace for physical constants like PI and Avogadro's Number.
-	 * @sa			See unit_t for more information on unit type containers.
-	 */
-#if !defined(DISABLE_PREDEFINED_UNITS)
-	namespace constants
-	{
-		/**
-		 * @name Unit Containers
-		 * @anchor constantContainers
-		 * @{
-		 */
-		using PI = unit<std::ratio<1>, dimensionless::scalar, std::ratio<1>>;
-
-		static constexpr const unit_t<PI>																											pi(1);											///< Ratio of a circle's circumference to its diameter.
-		static constexpr const velocity::meters_per_second_t																						c(299792458.0);									///< Speed of light in vacuum.
-		static constexpr const unit_t<compound_unit<cubed<length::meters>, inverse<mass::kilogram>, inverse<squared<time::seconds>>>>				G(6.67408e-11);									///< Newtonian constant of gravitation.
-		static constexpr const unit_t<compound_unit<energy::joule, time::seconds>>																	h(6.626070040e-34);								///< Planck constant.
-		static constexpr const unit_t<compound_unit<force::newtons, inverse<squared<current::ampere>>>>												mu0(pi * 4.0e-7 * force::newton_t(1) / units::math::cpow<2>(current::ampere_t(1)));										///< vacuum permeability.
-		static constexpr const unit_t<compound_unit<capacitance::farad, inverse<length::meter>>>													epsilon0(1.0 / (mu0 * math::cpow<2>(c)));		///< vacuum permitivity.
-		static constexpr const impedance::ohm_t																										Z0(mu0 * c);									///< characteristic impedance of vacuum.
-		static constexpr const unit_t<compound_unit<force::newtons, area::square_meter, inverse<squared<charge::coulomb>>>>							k_e(1.0 / (4 * pi * epsilon0));					///< Coulomb's constant.
-		static constexpr const charge::coulomb_t																									e(1.6021766208e-19);							///< elementary charge.
-		static constexpr const mass::kilogram_t																										m_e(9.10938356e-31);							///< electron mass.
-		static constexpr const mass::kilogram_t																										m_p(1.672621898e-27);							///< proton mass.
-		static constexpr const unit_t<compound_unit<energy::joules, inverse<magnetic_field_strength::tesla>>>										mu_B(e * h / (4 * pi *m_e));					///< Bohr magneton.
-		static constexpr const unit_t<inverse<substance::mol>>																						N_A(6.022140857e23);							///< Avagadro's Number.
-		static constexpr const unit_t<compound_unit<energy::joules, inverse<temperature::kelvin>, inverse<substance::moles>>>						R(8.3144598);									///< Gas constant.
-		static constexpr const unit_t<compound_unit<energy::joules, inverse<temperature::kelvin>>>													k_B(R / N_A);									///< Boltzmann constant.
-		static constexpr const unit_t<compound_unit<charge::coulomb, inverse<substance::mol>>>														F(N_A * e);										///< Faraday constant.
-		static constexpr const unit_t<compound_unit<power::watts, inverse<area::square_meters>, inverse<squared<squared<temperature::kelvin>>>>>	sigma((2 * math::cpow<5>(pi) * math::cpow<4>(R)) / (15 * math::cpow<3>(h) * math::cpow<2>(c) * math::cpow<4>(N_A)));	///< Stefan-Boltzmann constant.
-		/** @} */
-	}
-#endif
-
-	//----------------------------------
-	//	UNIT-ENABLED CMATH FUNCTIONS
-	//----------------------------------
-
-	/**
-	 * @brief		namespace for unit-enabled versions of the `<cmath>` library
-	 * @details		Includes trigonometric functions, exponential/log functions, rounding functions, etc.
-	 * @sa			See `unit_t` for more information on unit type containers.
-	 */
-	namespace math
-	{
-
-		//----------------------------------
-		//	MIN/MAX FUNCTIONS
-		//----------------------------------
-
-		template<class UnitTypeLhs, class UnitTypeRhs>
-		UnitTypeLhs min(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs)
-		{
-			static_assert(traits::is_convertible_unit_t<UnitTypeLhs, UnitTypeRhs>::value, "Unit types are not compatible.");
-			UnitTypeLhs r(rhs);
-			return (lhs < r ? lhs : r);
-		}
-
-		template<class UnitTypeLhs, class UnitTypeRhs>
-		UnitTypeLhs max(const UnitTypeLhs& lhs, const UnitTypeRhs& rhs)
-		{
-			static_assert(traits::is_convertible_unit_t<UnitTypeLhs, UnitTypeRhs>::value, "Unit types are not compatible.");
-			UnitTypeLhs r(rhs);
-			return (lhs > r ? lhs : r);
-		}
-
-		//----------------------------------
-		//	TRIGONOMETRIC FUNCTIONS
-		//----------------------------------
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Compute cosine
-		 * @details		The input value can be in any unit of angle, including radians or degrees.
-		 * @tparam		AngleUnit	any `unit_t` type of `category::angle_unit`. 
-		 * @param[in]	angle		angle to compute the cosine of
-		 * @returns		Returns the cosine of <i>angle</i>
-		 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
-		template<class AngleUnit>
-		dimensionless::scalar_t cos(const AngleUnit angle) noexcept
-		{
-			static_assert(traits::is_angle_unit<AngleUnit>::value, "Type `AngleUnit` must be a unit of angle derived from `unit_t`.");
-			return dimensionless::scalar_t(std::cos(angle.template convert<angle::radian>()()));
-		}
-#endif
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Compute sine
-		 * @details		The input value can be in any unit of angle, including radians or degrees.
-		 * @tparam		AngleUnit	any `unit_t` type of `category::angle_unit`.
-		 * @param[in]	angle		angle to compute the since of
-		 * @returns		Returns the sine of <i>angle</i>
-		 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
-		template<class AngleUnit>
-		dimensionless::scalar_t sin(const AngleUnit angle) noexcept
-		{
-			static_assert(traits::is_angle_unit<AngleUnit>::value, "Type `AngleUnit` must be a unit of angle derived from `unit_t`.");
-			return dimensionless::scalar_t(std::sin(angle.template convert<angle::radian>()()));
-		}
-#endif
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Compute tangent
-		 * @details		The input value can be in any unit of angle, including radians or degrees.
-		 * @tparam		AngleUnit	any `unit_t` type of `category::angle_unit`.
-		 * @param[in]	angle		angle to compute the tangent of
-		 * @returns		Returns the tangent of <i>angle</i>
-		 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
-		template<class AngleUnit>
-		dimensionless::scalar_t tan(const AngleUnit angle) noexcept
-		{
-			static_assert(traits::is_angle_unit<AngleUnit>::value, "Type `AngleUnit` must be a unit of angle derived from `unit_t`.");
-			return dimensionless::scalar_t(std::tan(angle.template convert<angle::radian>()()));
-		}
-#endif
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Compute arc cosine
-		 * @details		Returns the principal value of the arc cosine of x, expressed in radians.
-		 * @param[in]	x		Value whose arc cosine is computed, in the interval [-1,+1].
-		 * @returns		Principal arc cosine of x, in the interval [0,pi] radians.
-		 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
-		template<class ScalarUnit>
-		angle::radian_t acos(const ScalarUnit x) noexcept
-		{
-			static_assert(traits::is_dimensionless_unit<ScalarUnit>::value, "Type `ScalarUnit` must be a dimensionless unit derived from `unit_t`.");
-			return angle::radian_t(std::acos(x()));
-		}
-#endif
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Compute arc sine
-		 * @details		Returns the principal value of the arc sine of x, expressed in radians.
-		 * @param[in]	x		Value whose arc sine is computed, in the interval [-1,+1].
-		 * @returns		Principal arc sine of x, in the interval [-pi/2,+pi/2] radians.
-		 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
-		template<class ScalarUnit>
-		angle::radian_t asin(const ScalarUnit x) noexcept
-		{
-			static_assert(traits::is_dimensionless_unit<ScalarUnit>::value, "Type `ScalarUnit` must be a dimensionless unit derived from `unit_t`.");
-			return angle::radian_t(std::asin(x()));
-		}
-#endif
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Compute arc tangent
-		 * @details		Returns the principal value of the arc tangent of x, expressed in radians. 
-		 *				Notice that because of the sign ambiguity, the function cannot determine with 
-		 *				certainty in which quadrant the angle falls only by its tangent value. See 
-		 *				atan2 for an alternative that takes a fractional argument instead.
-		 * @tparam		AngleUnit	any `unit_t` type of `category::angle_unit`.
-		 * @param[in]	x		Value whose arc tangent is computed, in the interval [-1,+1].
-		 * @returns		Principal arc tangent of x, in the interval [-pi/2,+pi/2] radians.
-		 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
-		template<class ScalarUnit>
-		angle::radian_t atan(const ScalarUnit x) noexcept
-		{
-			static_assert(traits::is_dimensionless_unit<ScalarUnit>::value, "Type `ScalarUnit` must be a dimensionless unit derived from `unit_t`.");
-			return angle::radian_t(std::atan(x()));
-		}
-#endif
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Compute arc tangent with two parameters
-		 * @details		To compute the value, the function takes into account the sign of both arguments in order to determine the quadrant.
-		 * @param[in]	y		y-component of the triangle expressed.
-		 * @param[in]	x		x-component of the triangle expressed.
-		 * @returns		Returns the principal value of the arc tangent of <i>y/x</i>, expressed in radians.
-		 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
-		template<class Y, class X>
-		angle::radian_t atan2(const Y y, const X x) noexcept
-		{
-			static_assert(traits::is_dimensionless_unit<decltype(y/x)>::value, "The quantity y/x must yield a dimensionless ratio.");
-
-			// X and Y could be different length units, so normalize them
-			return angle::radian_t(std::atan2(y.template convert<typename units::traits::unit_t_traits<X>::unit_type>()(), x()));
-		}
-#endif
-
-		//----------------------------------
-		//	HYPERBOLIC TRIG FUNCTIONS
-		//----------------------------------
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Compute hyperbolic cosine
-		 * @details		The input value can be in any unit of angle, including radians or degrees.
-		 * @tparam		AngleUnit	any `unit_t` type of `category::angle_unit`.
-		 * @param[in]	angle		angle to compute the hyperbolic cosine of
-		 * @returns		Returns the hyperbolic cosine of <i>angle</i>
-		 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
-		template<class AngleUnit>
-		dimensionless::scalar_t cosh(const AngleUnit angle) noexcept
-		{
-			static_assert(traits::is_angle_unit<AngleUnit>::value, "Type `AngleUnit` must be a unit of angle derived from `unit_t`.");
-			return dimensionless::scalar_t(std::cosh(angle.template convert<angle::radian>()()));
-		}
-#endif
-
-		/**
-		* @ingroup		UnitMath
-		* @brief		Compute hyperbolic sine
-		* @details		The input value can be in any unit of angle, including radians or degrees.
-		* @tparam		AngleUnit	any `unit_t` type of `category::angle_unit`.
-		* @param[in]	angle		angle to compute the hyperbolic sine of
-		* @returns		Returns the hyperbolic sine of <i>angle</i>
-		*/
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
-		template<class AngleUnit>
-		dimensionless::scalar_t sinh(const AngleUnit angle) noexcept
-		{
-			static_assert(traits::is_angle_unit<AngleUnit>::value, "Type `AngleUnit` must be a unit of angle derived from `unit_t`.");
-			return dimensionless::scalar_t(std::sinh(angle.template convert<angle::radian>()()));
-		}
-#endif
-
-		/**
-		* @ingroup		UnitMath
-		* @brief		Compute hyperbolic tangent
-		* @details		The input value can be in any unit of angle, including radians or degrees.
-		* @tparam		AngleUnit	any `unit_t` type of `category::angle_unit`.
-		* @param[in]	angle		angle to compute the hyperbolic tangent of
-		* @returns		Returns the hyperbolic tangent of <i>angle</i>
-		*/
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
-		template<class AngleUnit>
-		dimensionless::scalar_t tanh(const AngleUnit angle) noexcept
-		{
-			static_assert(traits::is_angle_unit<AngleUnit>::value, "Type `AngleUnit` must be a unit of angle derived from `unit_t`.");
-			return dimensionless::scalar_t(std::tanh(angle.template convert<angle::radian>()()));
-		}
-#endif
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Compute arc hyperbolic cosine
-		 * @details		Returns the nonnegative arc hyperbolic cosine of x, expressed in radians.
-		 * @param[in]	x	Value whose arc hyperbolic cosine is computed. If the argument is less
-		 *					than 1, a domain error occurs.
-		 * @returns		Nonnegative arc hyperbolic cosine of x, in the interval [0,+INFINITY] radians.
-		 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
-		template<class ScalarUnit>
-		angle::radian_t acosh(const ScalarUnit x) noexcept
-		{
-			static_assert(traits::is_dimensionless_unit<ScalarUnit>::value, "Type `ScalarUnit` must be a dimensionless unit derived from `unit_t`.");
-			return angle::radian_t(std::acosh(x()));
-		}
-#endif
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Compute arc hyperbolic sine
-		 * @details		Returns the arc hyperbolic sine of x, expressed in radians.
-		 * @param[in]	x	Value whose arc hyperbolic sine is computed.
-		 * @returns		Arc hyperbolic sine of x, in radians.
-		 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
-		template<class ScalarUnit>
-		angle::radian_t asinh(const ScalarUnit x) noexcept
-		{
-			static_assert(traits::is_dimensionless_unit<ScalarUnit>::value, "Type `ScalarUnit` must be a dimensionless unit derived from `unit_t`.");
-			return angle::radian_t(std::asinh(x()));
-		}
-#endif
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Compute arc hyperbolic tangent
-		 * @details		Returns the arc hyperbolic tangent of x, expressed in radians.
-		 * @param[in]	x	Value whose arc hyperbolic tangent is computed, in the interval [-1,+1]. 
-		 *					If the argument is out of this interval, a domain error occurs. For 
-		 *					values of -1 and +1, a pole error may occur.
-		 * @returns		units::angle::radian_t
-		 */
-#if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS)
-		template<class ScalarUnit>
-		angle::radian_t atanh(const ScalarUnit x) noexcept
-		{
-			static_assert(traits::is_dimensionless_unit<ScalarUnit>::value, "Type `ScalarUnit` must be a dimensionless unit derived from `unit_t`.");
-			return angle::radian_t(std::atanh(x()));
-		}
-#endif
-
-		//----------------------------------
-		//	TRANSCENDENTAL FUNCTIONS
-		//----------------------------------
-
-		// it makes NO SENSE to put dimensioned units into a transcendental function, and if you think it does you are
-		// demonstrably wrong. https://en.wikipedia.org/wiki/Transcendental_function#Dimensional_analysis
-		
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Compute exponential function
-		 * @details		Returns the base-e exponential function of x, which is e raised to the power x: ex.
-		 * @param[in]	x	scalar value of the exponent.
-		 * @returns		Exponential value of x.
-		 *				If the magnitude of the result is too large to be represented by a value of the return type, the
-		 *				function returns HUGE_VAL (or HUGE_VALF or HUGE_VALL) with the proper sign, and an overflow range error occurs
-		 */
-		template<class ScalarUnit>
-		dimensionless::scalar_t exp(const ScalarUnit x) noexcept
-		{
-			static_assert(traits::is_dimensionless_unit<ScalarUnit>::value, "Type `ScalarUnit` must be a dimensionless unit derived from `unit_t`.");
-			return dimensionless::scalar_t(std::exp(x()));
-		}
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Compute natural logarithm
-		 * @details		Returns the natural logarithm of x.
-		 * @param[in]	x	scalar value whose logarithm is calculated. If the argument is negative, a 
-		 *					domain error occurs.
-		 * @sa			log10 for more common base-10 logarithms
-		 * @returns		Natural logarithm of x.
-		 */
-		template<class ScalarUnit>
-		dimensionless::scalar_t log(const ScalarUnit x) noexcept
-		{
-			static_assert(traits::is_dimensionless_unit<ScalarUnit>::value, "Type `ScalarUnit` must be a dimensionless unit derived from `unit_t`.");
-			return dimensionless::scalar_t(std::log(x()));
-		}
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Compute common logarithm
-		 * @details		Returns the common (base-10) logarithm of x.
-		 * @param[in]	x	Value whose logarithm is calculated. If the argument is negative, a 
-		 *					domain error occurs.
-		 * @returns		Common logarithm of x.
-		 */
-		template<class ScalarUnit>
-		dimensionless::scalar_t log10(const ScalarUnit x) noexcept
-		{
-			static_assert(traits::is_dimensionless_unit<ScalarUnit>::value, "Type `ScalarUnit` must be a dimensionless unit derived from `unit_t`.");
-			return dimensionless::scalar_t(std::log10(x()));
-		}
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Break into fractional and integral parts.
-		 * @details		The integer part is stored in the object pointed by intpart, and the 
-		 *				fractional part is returned by the function. Both parts have the same sign 
-		 *				as x.
-		 * @param[in]	x		scalar value to break into parts.
-		 * @param[in]	intpart Pointer to an object (of the same type as x) where the integral part
-		 *				is stored with the same sign as x.
-		 * @returns		The fractional part of x, with the same sign.
-		 */
-		template<class ScalarUnit>
-		dimensionless::scalar_t modf(const ScalarUnit x, ScalarUnit* intpart) noexcept
-		{
-			static_assert(traits::is_dimensionless_unit<ScalarUnit>::value, "Type `ScalarUnit` must be a dimensionless unit derived from `unit_t`.");
-
-			UNIT_LIB_DEFAULT_TYPE intp;
-			dimensionless::scalar_t fracpart = dimensionless::scalar_t(std::modf(x(), &intp));
-			*intpart = intp;
-			return fracpart;
-		}
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Compute binary exponential function
-		 * @details		Returns the base-2 exponential function of x, which is 2 raised to the power x: 2^x.
-		 * 2param[in]	x	Value of the exponent.
-		 * @returns		2 raised to the power of x.
-		 */
-		template<class ScalarUnit>
-		dimensionless::scalar_t exp2(const ScalarUnit x) noexcept
-		{
-			static_assert(traits::is_dimensionless_unit<ScalarUnit>::value, "Type `ScalarUnit` must be a dimensionless unit derived from `unit_t`.");
-			return dimensionless::scalar_t(std::exp2(x()));
-		}
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Compute exponential minus one
-		 * @details		Returns e raised to the power x minus one: e^x-1. For small magnitude values 
-		 *				of x, expm1 may be more accurate than exp(x)-1.
-		 * @param[in]	x	Value of the exponent.
-		 * @returns		e raised to the power of x, minus one.
-		 */
-		template<class ScalarUnit>
-		dimensionless::scalar_t expm1(const ScalarUnit x) noexcept
-		{
-			static_assert(traits::is_dimensionless_unit<ScalarUnit>::value, "Type `ScalarUnit` must be a dimensionless unit derived from `unit_t`.");
-			return dimensionless::scalar_t(std::expm1(x()));
-		}
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Compute logarithm plus one
-		 * @details		Returns the natural logarithm of one plus x. For small magnitude values of 
-		 *				x, logp1 may be more accurate than log(1+x).
-		 * @param[in]	x	Value whose logarithm is calculated. If the argument is less than -1, a 
-		 *					domain error occurs.
-		 * @returns		The natural logarithm of (1+x).
-		 */
-		template<class ScalarUnit>
-		dimensionless::scalar_t log1p(const ScalarUnit x) noexcept
-		{
-			static_assert(traits::is_dimensionless_unit<ScalarUnit>::value, "Type `ScalarUnit` must be a dimensionless unit derived from `unit_t`.");
-			return dimensionless::scalar_t(std::log1p(x()));
-		}
-		
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Compute binary logarithm
-		 * @details		Returns the binary (base-2) logarithm of x.
-		 * @param[in]	x	Value whose logarithm is calculated. If the argument is negative, a 
-		 *					domain error occurs.
-		 * @returns		The binary logarithm of x: log2x.
-		 */
-		template<class ScalarUnit>
-		dimensionless::scalar_t log2(const ScalarUnit x) noexcept
-		{
-			static_assert(traits::is_dimensionless_unit<ScalarUnit>::value, "Type `ScalarUnit` must be a dimensionless unit derived from `unit_t`.");
-			return dimensionless::scalar_t(std::log2(x()));
-		}
-
-		//----------------------------------
-		//	POWER FUNCTIONS
-		//----------------------------------
-		
-		/* pow is implemented earlier in the library since a lot of the unit definitions depend on it */
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		computes the square root of <i>value</i>
-		 * @details		Only implemented for linear_scale units.
-		 * @param[in]	value `unit_t` derived type to compute the square root of.
-		 * @returns		new unit_t, whose units are the square root of value's. E.g. if values
-		 *				had units of `square_meter`, then the return type will have units of
-		 *				`meter`.
-		 * @note		`sqrt` provides a _rational approximation_ of the square root of <i>value</i>.
-		 *				In some cases, _both_ the returned value _and_ conversion factor of the returned
-		 *				unit type may have errors no larger than `1e-10`.
-		 */
-		template<class UnitType, std::enable_if_t<units::traits::has_linear_scale<UnitType>::value, int> = 0>
-		inline auto sqrt(const UnitType& value) noexcept -> unit_t<square_root<typename units::traits::unit_t_traits<UnitType>::unit_type>, typename units::traits::unit_t_traits<UnitType>::underlying_type, linear_scale>
-		{
-			return unit_t<square_root<typename units::traits::unit_t_traits<UnitType>::unit_type>, typename units::traits::unit_t_traits<UnitType>::underlying_type, linear_scale>
-				(std::sqrt(value()));
-		}
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Computes the square root of the sum-of-squares of x and y.
-		 * @details		Only implemented for linear_scale units.
-		 * @param[in]	x	unit_t type value
-		 * @param[in]	y	unit_t type value
-		 * @returns		square root of the sum-of-squares of x and y in the same units
-		 *				as x.
-		 */
-		template<class UnitTypeLhs, class UnitTypeRhs, std::enable_if_t<units::traits::has_linear_scale<UnitTypeLhs, UnitTypeRhs>::value, int> = 0>
-		inline UnitTypeLhs hypot(const UnitTypeLhs& x, const UnitTypeRhs& y)
-		{
-			static_assert(traits::is_convertible_unit_t<UnitTypeLhs, UnitTypeRhs>::value, "Parameters of hypot() function are not compatible units.");
-			return UnitTypeLhs(std::hypot(x(), y.template convert<typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type>()()));
-		}
-
-		//----------------------------------
-		//	ROUNDING FUNCTIONS
-		//----------------------------------
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Round up value
-		 * @details		Rounds x upward, returning the smallest integral value that is not less than x.
-		 * @param[in]	x	Unit value to round up.
-		 * @returns		The smallest integral value that is not less than x.
-		 */
-		template<class UnitType, class = std::enable_if_t<traits::is_unit_t<UnitType>::value>>
-		UnitType ceil(const UnitType x) noexcept
-		{
-			return UnitType(std::ceil(x()));
-		}
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Round down value
-		 * @details		Rounds x downward, returning the largest integral value that is not greater than x.
-		 * @param[in]	x	Unit value to round down.
-		 * @returns		The value of x rounded downward.
-		 */
-		template<class UnitType, class = std::enable_if_t<traits::is_unit_t<UnitType>::value>>
-		UnitType floor(const UnitType x) noexcept
-		{
-			return UnitType(std::floor(x()));
-		}
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Compute remainder of division
-		 * @details		Returns the floating-point remainder of numer/denom (rounded towards zero).
-		 * @param[in]	numer	Value of the quotient numerator.
-		 * @param[in]	denom	Value of the quotient denominator.
-		 * @returns		The remainder of dividing the arguments.
-		 */
-		template<class UnitTypeLhs, class UnitTypeRhs, class = std::enable_if_t<traits::is_unit_t<UnitTypeLhs>::value && traits::is_unit_t<UnitTypeRhs>::value>>
-		UnitTypeLhs fmod(const UnitTypeLhs numer, const UnitTypeRhs denom) noexcept
-		{
-			static_assert(traits::is_convertible_unit_t<UnitTypeLhs, UnitTypeRhs>::value, "Parameters of fmod() function are not compatible units.");
-			return UnitTypeLhs(std::fmod(numer(), denom.template convert<typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type>()()));
-		}
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Truncate value
-		 * @details		Rounds x toward zero, returning the nearest integral value that is not 
-		 *				larger in magnitude than x. Effectively rounds towards 0.
-		 * @param[in]	x	Value to truncate
-		 * @returns		The nearest integral value that is not larger in magnitude than x.
-		 */
-		template<class UnitType, class = std::enable_if_t<traits::is_unit_t<UnitType>::value>>
-		UnitType trunc(const UnitType x) noexcept
-		{
-			return UnitType(std::trunc(x()));
-		}
-
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Round to nearest
-		 * @details		Returns the integral value that is nearest to x, with halfway cases rounded
-		 *				away from zero.
-		 * @param[in]	x	value to round.
-		 * @returns		The value of x rounded to the nearest integral.
-		 */
-		template<class UnitType, class = std::enable_if_t<traits::is_unit_t<UnitType>::value>>
-		UnitType round(const UnitType x) noexcept
-		{
-			return UnitType(std::round(x()));
-		}
-
-		//----------------------------------
-		//	FLOATING POINT MANIPULATION 
-		//----------------------------------
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Copy sign
-		 * @details		Returns a value with the magnitude and dimension of x, and the sign of y. 
-		 *				Values x and y do not have to be compatible units.
-		 * @param[in]	x	Value with the magnitude of the resulting value.
-		 * @param[in]	y	Value with the sign of the resulting value.
-		 * @returns		value with the magnitude and dimension of x, and the sign of y.
-		 */
-		template<class UnitTypeLhs, class UnitTypeRhs, class = std::enable_if_t<traits::is_unit_t<UnitTypeLhs>::value && traits::is_unit_t<UnitTypeRhs>::value>>
-		UnitTypeLhs copysign(const UnitTypeLhs x, const UnitTypeRhs y) noexcept
-		{
-			return UnitTypeLhs(std::copysign(x(), y()));	// no need for conversion to get the correct sign.
-		}
-
-		/// Overload to copy the sign from a raw double
-		template<class UnitTypeLhs, class = std::enable_if_t<traits::is_unit_t<UnitTypeLhs>::value>>
-		UnitTypeLhs copysign(const UnitTypeLhs x, const UNIT_LIB_DEFAULT_TYPE y) noexcept
-		{
-			return UnitTypeLhs(std::copysign(x(), y));
-		}
-
-		//----------------------------------
-		//	MIN / MAX / DIFFERENCE 
-		//----------------------------------
-		
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Positive difference
-		 * @details		The function returns x-y if x>y, and zero otherwise, in the same units as x.
-		 *				Values x and y do not have to be the same type of units, but they do have to
-		 *				be compatible.
-		 * @param[in]	x	Values whose difference is calculated.
-		 * @param[in]	y	Values whose difference is calculated.
-		 * @returns		The positive difference between x and y.
-		 */
-		template<class UnitTypeLhs, class UnitTypeRhs, class = std::enable_if_t<traits::is_unit_t<UnitTypeLhs>::value && traits::is_unit_t<UnitTypeRhs>::value>>
-		UnitTypeLhs fdim(const UnitTypeLhs x, const UnitTypeRhs y) noexcept
-		{
-			static_assert(traits::is_convertible_unit_t<UnitTypeLhs, UnitTypeRhs>::value, "Parameters of fdim() function are not compatible units.");
-			return UnitTypeLhs(std::fdim(x(), y.template convert<typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type>()()));
-		}
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Maximum value
-		 * @details		Returns the larger of its arguments: either x or y, in the same units as x.
-		 *				Values x and y do not have to be the same type of units, but they do have to
-		 *				be compatible.
-		 * @param[in]	x	Values among which the function selects a maximum.
-		 * @param[in]	y	Values among which the function selects a maximum.
-		 * @returns		The maximum numeric value of its arguments.
-		 */
-		template<class UnitTypeLhs, class UnitTypeRhs, class = std::enable_if_t<traits::is_unit_t<UnitTypeLhs>::value && traits::is_unit_t<UnitTypeRhs>::value>>
-		UnitTypeLhs fmax(const UnitTypeLhs x, const UnitTypeRhs y) noexcept
-		{
-			static_assert(traits::is_convertible_unit_t<UnitTypeLhs, UnitTypeRhs>::value, "Parameters of fmax() function are not compatible units.");
-			return UnitTypeLhs(std::fmax(x(), y.template convert<typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type>()()));
-		}
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Minimum value
-		 * @details		Returns the smaller of its arguments: either x or y, in the same units as x.
-		 *				If one of the arguments in a NaN, the other is returned.
-		 *				Values x and y do not have to be the same type of units, but they do have to
-		 *				be compatible.
-		 * @param[in]	x	Values among which the function selects a minimum.
-		 * @param[in]	y	Values among which the function selects a minimum.
-		 * @returns		The minimum numeric value of its arguments.
-		 */
-		template<class UnitTypeLhs, class UnitTypeRhs, class = std::enable_if_t<traits::is_unit_t<UnitTypeLhs>::value && traits::is_unit_t<UnitTypeRhs>::value>>
-		UnitTypeLhs fmin(const UnitTypeLhs x, const UnitTypeRhs y) noexcept
-		{
-			static_assert(traits::is_convertible_unit_t<UnitTypeLhs, UnitTypeRhs>::value, "Parameters of fmin() function are not compatible units.");
-			return UnitTypeLhs(std::fmin(x(), y.template convert<typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type>()()));
-		}
-
-		//----------------------------------
-		//	OTHER FUNCTIONS
-		//----------------------------------
-		
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Compute absolute value
-		 * @details		Returns the absolute value of x, i.e. |x|.
-		 * @param[in]	x	Value whose absolute value is returned.
-		 * @returns		The absolute value of x.
-		 */
-		template<class UnitType, class = std::enable_if_t<traits::is_unit_t<UnitType>::value>>
-		UnitType fabs(const UnitType x) noexcept
-		{
-			return UnitType(std::fabs(x()));
-		}
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Compute absolute value
-		 * @details		Returns the absolute value of x, i.e. |x|.
-		 * @param[in]	x	Value whose absolute value is returned.
-		 * @returns		The absolute value of x.
-		 */
-		template<class UnitType, class = std::enable_if_t<traits::is_unit_t<UnitType>::value>>
-		UnitType abs(const UnitType x) noexcept
-		{
-			return UnitType(std::fabs(x()));
-		}
-
-		/**
-		 * @ingroup		UnitMath
-		 * @brief		Multiply-add
-		 * @details		Returns x*y+z. The function computes the result without losing precision in 
-		 *				any intermediate result. The resulting unit type is a compound unit of x* y.
-		 * @param[in]	x	Values to be multiplied.
-		 * @param[in]	y	Values to be multiplied.
-		 * @param[in]	z	Value to be added.
-		 * @returns		The result of x*y+z
-		 */
-		template<class UnitTypeLhs, class UnitMultiply, class UnitAdd, class = std::enable_if_t<traits::is_unit_t<UnitTypeLhs>::value && traits::is_unit_t<UnitMultiply>::value && traits::is_unit_t<UnitAdd>::value>>
-		auto fma(const UnitTypeLhs x, const UnitMultiply y, const UnitAdd z) noexcept -> decltype(x * y)
-		{
-			using resultType = decltype(x * y);
-			static_assert(traits::is_convertible_unit_t<compound_unit<typename units::traits::unit_t_traits<UnitTypeLhs>::unit_type, typename units::traits::unit_t_traits<UnitMultiply>::unit_type>, typename units::traits::unit_t_traits<UnitAdd>::unit_type>::value, "Unit types are not compatible.");
-			return resultType(std::fma(x(), y(), resultType(z)()));
-		}
-
-	}	// end namespace math
-}	// end namespace units
-
-//------------------------------
-//	std::numeric_limits
-//------------------------------
-
-namespace std
-{
-	template<class Units, typename T, template<typename> class NonLinearScale>
-	class numeric_limits<units::unit_t<Units, T, NonLinearScale>>
-	{
-	public:
-		static constexpr units::unit_t<Units, T, NonLinearScale> min()
-		{
-			return units::unit_t<Units, T, NonLinearScale>(std::numeric_limits<T>::min());
-		}
-		static constexpr units::unit_t<Units, T, NonLinearScale> max()
-		{
-			return units::unit_t<Units, T, NonLinearScale>(std::numeric_limits<T>::max());
-		}
-		static constexpr units::unit_t<Units, T, NonLinearScale> lowest()
-		{
-			return units::unit_t<Units, T, NonLinearScale>(std::numeric_limits<T>::lowest());
-		}
-	};
-}
-
-#ifdef _MSC_VER
-#	if _MSC_VER <= 1800
-#		pragma warning(pop)
-#		undef constexpr
-#		pragma pop_macro("constexpr")
-#		undef noexcept
-#		pragma pop_macro("noexcept")
-#		undef _ALLOW_KEYWORD_MACROS
-#	endif // _MSC_VER < 1800
-#	pragma pop_macro("pascal")
-#endif // _MSC_VER
-
-#endif // units_h__
-
-// For Emacs
-// Local Variables:
-// Mode: C++
-// c-basic-offset: 2
-// fill-column: 116
-// tab-width: 4
-// End:
-
-using namespace units::literals;
-
-namespace units {
-using namespace acceleration;
-using namespace angular_velocity;
-using namespace length;
-using namespace time;
-using namespace velocity;
-using namespace acceleration;
-using namespace angle;
-using namespace voltage;
-}  // namespace units
diff --git a/wpiutil/src/main/native/include/wpi/Chrono.h b/wpiutil/src/main/native/include/wpi/Chrono.h
index 4593e85..33341c6 100644
--- a/wpiutil/src/main/native/include/wpi/Chrono.h
+++ b/wpiutil/src/main/native/include/wpi/Chrono.h
@@ -22,7 +22,7 @@
 namespace sys {
 
 /// A time point on the system clock. This is provided for two reasons:
-/// - to insulate us agains subtle differences in behavoir to differences in
+/// - to insulate us against subtle differences in behavior to differences in
 ///   system clock precision (which is implementation-defined and differs between
 ///   platforms).
 /// - to shorten the type name
diff --git a/wpiutil/src/main/native/include/wpi/Demangle.h b/wpiutil/src/main/native/include/wpi/Demangle.h
index b0e1134..5989ccc 100644
--- a/wpiutil/src/main/native/include/wpi/Demangle.h
+++ b/wpiutil/src/main/native/include/wpi/Demangle.h
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2008-2019 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2008-2020 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -10,6 +10,8 @@
 
 #include <string>
 
+#include "wpi/Twine.h"
+
 namespace wpi {
 
 /**
@@ -18,7 +20,7 @@
  * @param mangledSymbol the mangled symbol.
  * @return The demangled symbol, or mangledSymbol if demangling fails.
  */
-std::string Demangle(char const* mangledSymbol);
+std::string Demangle(const Twine& mangledSymbol);
 
 }  // namespace wpi
 
diff --git a/wpiutil/src/main/native/include/wpi/Endian.h b/wpiutil/src/main/native/include/wpi/Endian.h
index 365209c..ee4a51d 100644
--- a/wpiutil/src/main/native/include/wpi/Endian.h
+++ b/wpiutil/src/main/native/include/wpi/Endian.h
@@ -68,7 +68,9 @@
 /// Swap the bytes of value to match the given endianness.
 template<typename value_type, endianness endian>
 inline value_type byte_swap(value_type value) {
-  return byte_swap(value, endian);
+  if constexpr ((endian != native) && (endian != system_endianness()))
+    sys::swapByteOrder(value);
+  return value;
 }
 
 /// Read a value of a particular endianness from memory.
@@ -87,7 +89,13 @@
          endianness endian,
          std::size_t alignment>
 inline value_type read(const void *memory) {
-  return read<value_type, alignment>(memory, endian);
+  value_type ret;
+
+  memcpy(&ret,
+         LLVM_ASSUME_ALIGNED(
+             memory, (detail::PickAlignment<value_type, alignment>::value)),
+         sizeof(value_type));
+  return byte_swap<value_type, endian>(ret);
 }
 
 /// Read a value of a particular endianness from a buffer, and increment the
@@ -102,7 +110,9 @@
 template<typename value_type, endianness endian, std::size_t alignment,
          typename CharT>
 inline value_type readNext(const CharT *&memory) {
-  return readNext<value_type, alignment, CharT>(memory, endian);
+  value_type ret = read<value_type, endian, alignment>(memory);
+  memory += sizeof(value_type);
+  return ret;
 }
 
 /// Write a value to memory with a particular endianness.
@@ -118,12 +128,12 @@
          endianness endian,
          std::size_t alignment>
 inline void write(void *memory, value_type value) {
-  write<value_type, alignment>(memory, value, endian);
+  value = byte_swap<value_type, endian>(value);
+  memcpy(LLVM_ASSUME_ALIGNED(
+             memory, (detail::PickAlignment<value_type, alignment>::value)),
+         &value, sizeof(value_type));
 }
 
-template <typename value_type>
-using make_unsigned_t = typename std::make_unsigned<value_type>::type;
-
 /// Read a value of a particular endianness from memory, for a location
 /// that starts at the given bit offset within the first byte.
 template <typename value_type, endianness endian, std::size_t alignment>
@@ -142,15 +152,15 @@
     val[1] = byte_swap<value_type, endian>(val[1]);
 
     // Shift bits from the lower value into place.
-    make_unsigned_t<value_type> lowerVal = val[0] >> startBit;
+    std::make_unsigned_t<value_type> lowerVal = val[0] >> startBit;
     // Mask off upper bits after right shift in case of signed type.
-    make_unsigned_t<value_type> numBitsFirstVal =
+    std::make_unsigned_t<value_type> numBitsFirstVal =
         (sizeof(value_type) * 8) - startBit;
-    lowerVal &= ((make_unsigned_t<value_type>)1 << numBitsFirstVal) - 1;
+    lowerVal &= ((std::make_unsigned_t<value_type>)1 << numBitsFirstVal) - 1;
 
     // Get the bits from the upper value.
-    make_unsigned_t<value_type> upperVal =
-        val[1] & (((make_unsigned_t<value_type>)1 << startBit) - 1);
+    std::make_unsigned_t<value_type> upperVal =
+        val[1] & (((std::make_unsigned_t<value_type>)1 << startBit) - 1);
     // Shift them in to place.
     upperVal <<= numBitsFirstVal;
 
@@ -178,15 +188,15 @@
 
     // Mask off any existing bits in the upper part of the lower value that
     // we want to replace.
-    val[0] &= ((make_unsigned_t<value_type>)1 << startBit) - 1;
-    make_unsigned_t<value_type> numBitsFirstVal =
+    val[0] &= ((std::make_unsigned_t<value_type>)1 << startBit) - 1;
+    std::make_unsigned_t<value_type> numBitsFirstVal =
         (sizeof(value_type) * 8) - startBit;
-    make_unsigned_t<value_type> lowerVal = value;
+    std::make_unsigned_t<value_type> lowerVal = value;
     if (startBit > 0) {
       // Mask off the upper bits in the new value that are not going to go into
       // the lower value. This avoids a left shift of a negative value, which
       // is undefined behavior.
-      lowerVal &= (((make_unsigned_t<value_type>)1 << numBitsFirstVal) - 1);
+      lowerVal &= (((std::make_unsigned_t<value_type>)1 << numBitsFirstVal) - 1);
       // Now shift the new bits into place
       lowerVal <<= startBit;
     }
@@ -194,11 +204,11 @@
 
     // Mask off any existing bits in the lower part of the upper value that
     // we want to replace.
-    val[1] &= ~(((make_unsigned_t<value_type>)1 << startBit) - 1);
+    val[1] &= ~(((std::make_unsigned_t<value_type>)1 << startBit) - 1);
     // Next shift the bits that go into the upper value into position.
-    make_unsigned_t<value_type> upperVal = value >> numBitsFirstVal;
+    std::make_unsigned_t<value_type> upperVal = value >> numBitsFirstVal;
     // Mask off upper bits after right shift in case of signed type.
-    upperVal &= ((make_unsigned_t<value_type>)1 << startBit) - 1;
+    upperVal &= ((std::make_unsigned_t<value_type>)1 << startBit) - 1;
     val[1] |= upperVal;
 
     // Finally, rewrite values.
diff --git a/wpiutil/src/main/native/include/wpi/ErrorHandling.h b/wpiutil/src/main/native/include/wpi/ErrorHandling.h
index ef5843b..5c89c5e 100644
--- a/wpiutil/src/main/native/include/wpi/ErrorHandling.h
+++ b/wpiutil/src/main/native/include/wpi/ErrorHandling.h
@@ -46,7 +46,7 @@
   void install_fatal_error_handler(fatal_error_handler_t handler,
                                    void *user_data = nullptr);
 
-  /// Restores default error handling behaviour.
+  /// Restores default error handling behavior.
   void remove_fatal_error_handler();
 
   /// ScopedFatalErrorHandler - This is a simple helper class which just
diff --git a/wpiutil/src/main/native/include/wpi/HttpServerConnection.h b/wpiutil/src/main/native/include/wpi/HttpServerConnection.h
index c49c2a2..17c9ca2 100644
--- a/wpiutil/src/main/native/include/wpi/HttpServerConnection.h
+++ b/wpiutil/src/main/native/include/wpi/HttpServerConnection.h
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2018 FIRST. All Rights Reserved.                             */
+/* Copyright (c) 2018-2020 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -67,9 +67,9 @@
    *                      be set to false.
    * @param extra Extra HTTP headers to send, including final "\r\n"
    */
-  void BuildHeader(raw_ostream& os, int code, const Twine& codeText,
-                   const Twine& contentType, uint64_t contentLength,
-                   const Twine& extra = Twine{});
+  virtual void BuildHeader(raw_ostream& os, int code, const Twine& codeText,
+                           const Twine& contentType, uint64_t contentLength,
+                           const Twine& extra = Twine{});
 
   /**
    * Send data to client.
@@ -94,8 +94,9 @@
    * @param content Response message content
    * @param extraHeader Extra HTTP headers to send, including final "\r\n"
    */
-  void SendResponse(int code, const Twine& codeText, const Twine& contentType,
-                    StringRef content, const Twine& extraHeader = Twine{});
+  virtual void SendResponse(int code, const Twine& codeText,
+                            const Twine& contentType, StringRef content,
+                            const Twine& extraHeader = Twine{});
 
   /**
    * Send HTTP response from static data, along with other header information
@@ -111,9 +112,10 @@
    * @param gzipped True if content is gzip compressed
    * @param extraHeader Extra HTTP headers to send, including final "\r\n"
    */
-  void SendStaticResponse(int code, const Twine& codeText,
-                          const Twine& contentType, StringRef content,
-                          bool gzipped, const Twine& extraHeader = Twine{});
+  virtual void SendStaticResponse(int code, const Twine& codeText,
+                                  const Twine& contentType, StringRef content,
+                                  bool gzipped,
+                                  const Twine& extraHeader = Twine{});
 
   /**
    * Send error header and message.
@@ -124,7 +126,7 @@
    * @param code HTTP error code (e.g. 404)
    * @param message Additional message text
    */
-  void SendError(int code, const Twine& message = Twine{});
+  virtual void SendError(int code, const Twine& message = Twine{});
 
   /** The HTTP request. */
   HttpParser m_request{HttpParser::kRequest};
diff --git a/wpiutil/src/main/native/include/wpi/HttpUtil.h b/wpiutil/src/main/native/include/wpi/HttpUtil.h
index b0668eb..75b6e58 100644
--- a/wpiutil/src/main/native/include/wpi/HttpUtil.h
+++ b/wpiutil/src/main/native/include/wpi/HttpUtil.h
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2016-2018 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2016-2020 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -8,7 +8,9 @@
 #ifndef WPIUTIL_WPI_HTTPUTIL_H_
 #define WPIUTIL_WPI_HTTPUTIL_H_
 
+#include <initializer_list>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -59,6 +61,230 @@
 bool FindMultipartBoundary(wpi::raw_istream& is, StringRef boundary,
                            std::string* saveBuf);
 
+/**
+ * Map for looking up elements of the query portion of a URI.  Does not
+ * handle multiple elements with the same name.  This is a reference type;
+ * it does not make a copy of the query string, so it is important that the
+ * query string has a lifetime at least as long as this object.
+ */
+class HttpQueryMap {
+ public:
+  /**
+   * Constructs an empty map (with no entries).
+   */
+  HttpQueryMap() = default;
+
+  /**
+   * Constructs from an escaped query string.  Note: does not make a copy of
+   * the query string, so it must not be a temporary.
+   *
+   * @param query query string
+   */
+  explicit HttpQueryMap(StringRef query);
+
+  /**
+   * Gets an element of the query string.  Both the name and the returned
+   * value are unescaped strings.
+   *
+   * @param name name (unescaped)
+   * @param buf result buffer for value
+   * @return Optional unescaped value.  Returns an empty optional if the
+   *         name is not present in the query map.
+   */
+  std::optional<StringRef> Get(StringRef name,
+                               SmallVectorImpl<char>& buf) const;
+
+ private:
+  StringMap<StringRef> m_elems;
+};
+
+class HttpPathRef;
+
+/**
+ * Class for HTTP path matching.  A root path is represented as a single
+ * empty element, otherwise the path consists of each non-empty element
+ * between the '/' characters:
+ *  - "" -> []
+ *  - "/" -> [""]
+ *  - "/foo" -> ["foo"]
+ *  - "/foo/bar" -> ["foo", "bar"]
+ *  - "/foo//bar/" -> ["foo", "bar"]
+ *
+ * All path elements are unescaped.
+ */
+class HttpPath {
+ public:
+  /**
+   * Constructs an empty HTTP path.
+   */
+  HttpPath() = default;
+
+  /**
+   * Constructs a HTTP path from an escaped path string.  Makes a copy of the
+   * path, so it's safe to be a temporary.
+   */
+  explicit HttpPath(StringRef path);
+
+  /**
+   * Evaluates to true if the path is not empty.
+   */
+  explicit operator bool() const { return !empty(); }
+
+  /**
+   * Returns true if the path has no elements.
+   */
+  bool empty() const { return m_pathEnds.empty(); }
+
+  /**
+   * Returns number of elements in the path.
+   */
+  size_t size() const { return m_pathEnds.size(); }
+
+  /**
+   * Returns true if the path exactly matches the provided match list.
+   *
+   * @param match match list
+   * @return True if path equals match list
+   */
+  bool equals(std::initializer_list<StringRef> match) const {
+    return equals(0, makeArrayRef(match.begin(), match.end()));
+  }
+  bool equals(ArrayRef<StringRef> match) const { return equals(0, match); }
+  bool equals(StringRef match) const { return equals(0, makeArrayRef(match)); }
+
+  /**
+   * Returns true if the elements of the path starting at the "start" element
+   * match the provided match list, and there are no additional elements.
+   *
+   * @param start element to start matching at
+   * @param match match list
+   * @return True if match
+   */
+  bool equals(size_t start, std::initializer_list<StringRef> match) const {
+    return equals(start, makeArrayRef(match.begin(), match.end()));
+  }
+  bool equals(size_t start, ArrayRef<StringRef> match) const {
+    if (m_pathEnds.size() != (start + match.size())) return false;
+    return startswith(start, match);
+  }
+  bool equals(size_t start, StringRef match) const {
+    return equals(start, makeArrayRef(match));
+  }
+
+  /**
+   * Returns true if the first elements of the path match the provided match
+   * list.  The path may have additional elements.
+   *
+   * @param match match list
+   * @return True if path starts with match list
+   */
+  bool startswith(std::initializer_list<StringRef> match) const {
+    return startswith(0, makeArrayRef(match.begin(), match.end()));
+  }
+  bool startswith(ArrayRef<StringRef> match) const {
+    return startswith(0, match);
+  }
+  bool startswith(StringRef match) const {
+    return startswith(0, makeArrayRef(match));
+  }
+
+  /**
+   * Returns true if the elements of the path starting at the "start" element
+   * match the provided match list.  The path may have additional elements.
+   *
+   * @param start element to start matching at
+   * @param match match list
+   * @return True if path starting at the start element matches the match list
+   */
+  bool startswith(size_t start, std::initializer_list<StringRef> match) const {
+    return startswith(start, makeArrayRef(match.begin(), match.end()));
+  }
+
+  bool startswith(size_t start, ArrayRef<StringRef> match) const;
+
+  bool startswith(size_t start, StringRef match) const {
+    return startswith(start, makeArrayRef(match));
+  }
+
+  /**
+   * Gets a single element of the path.
+   */
+  StringRef operator[](size_t n) const {
+    return m_pathBuf.slice(n == 0 ? 0 : m_pathEnds[n - 1], m_pathEnds[n]);
+  }
+
+  /**
+   * Returns a path reference with the first N elements of the path removed.
+   */
+  HttpPathRef drop_front(size_t n) const;
+
+ private:
+  SmallString<128> m_pathBuf;
+  SmallVector<size_t, 16> m_pathEnds;
+};
+
+/**
+ * Proxy reference object for a portion of a HttpPath.
+ */
+class HttpPathRef {
+ public:
+  HttpPathRef() = default;
+  /*implicit*/ HttpPathRef(const HttpPath& path,  // NOLINT(runtime/explicit)
+                           size_t start = 0)
+      : m_path(&path), m_start(start) {}
+
+  explicit operator bool() const { return !empty(); }
+  bool empty() const { return m_path && m_path->size() == m_start; }
+  size_t size() const { return m_path ? m_path->size() - m_start : 0; }
+
+  bool equals(std::initializer_list<StringRef> match) const {
+    return equals(0, makeArrayRef(match.begin(), match.end()));
+  }
+  bool equals(ArrayRef<StringRef> match) const { return equals(0, match); }
+  bool equals(StringRef match) const { return equals(0, makeArrayRef(match)); }
+
+  bool equals(size_t start, std::initializer_list<StringRef> match) const {
+    return equals(start, makeArrayRef(match.begin(), match.end()));
+  }
+  bool equals(size_t start, ArrayRef<StringRef> match) const {
+    return m_path ? m_path->equals(m_start + start, match) : false;
+  }
+  bool equals(size_t start, StringRef match) const {
+    return equals(start, makeArrayRef(match));
+  }
+
+  bool startswith(std::initializer_list<StringRef> match) const {
+    return startswith(0, makeArrayRef(match.begin(), match.end()));
+  }
+  bool startswith(ArrayRef<StringRef> match) const {
+    return startswith(0, match);
+  }
+  bool startswith(StringRef match) const {
+    return startswith(0, makeArrayRef(match));
+  }
+
+  bool startswith(size_t start, std::initializer_list<StringRef> match) const {
+    return startswith(start, makeArrayRef(match.begin(), match.end()));
+  }
+  bool startswith(size_t start, ArrayRef<StringRef> match) const {
+    return m_path ? m_path->startswith(m_start + start, match) : false;
+  }
+  bool startswith(size_t start, StringRef match) const {
+    return startswith(start, makeArrayRef(match));
+  }
+
+  StringRef operator[](size_t n) const {
+    return m_path ? m_path->operator[](m_start + n) : StringRef{};
+  }
+  HttpPathRef drop_front(size_t n) const {
+    return m_path ? m_path->drop_front(m_start + n) : HttpPathRef{};
+  }
+
+ private:
+  const HttpPath* m_path = nullptr;
+  size_t m_start = 0;
+};
+
 class HttpLocation {
  public:
   HttpLocation() = default;
diff --git a/wpiutil/src/main/native/include/wpi/HttpUtil.inl b/wpiutil/src/main/native/include/wpi/HttpUtil.inl
index ce118b0..f66c746 100644
--- a/wpiutil/src/main/native/include/wpi/HttpUtil.inl
+++ b/wpiutil/src/main/native/include/wpi/HttpUtil.inl
@@ -1,15 +1,21 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) FIRST 2015. All Rights Reserved.                             */
+/* Copyright (c) 2015-2020 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
 /*----------------------------------------------------------------------------*/
 
-#ifndef WPIUTIL_SUPPORT_HTTPUTIL_INL_
-#define WPIUTIL_SUPPORT_HTTPUTIL_INL_
+#ifndef WPIUTIL_WPI_HTTPUTIL_INL_
+#define WPIUTIL_WPI_HTTPUTIL_INL_
+
+#include <utility>
 
 namespace wpi {
 
+inline HttpPathRef HttpPath::drop_front(size_t n) const {
+  return HttpPathRef(*this, n);
+}
+
 template <typename T>
 HttpRequest::HttpRequest(const HttpLocation& loc, const T& extraParams)
     : host{loc.host}, port{loc.port} {
@@ -45,4 +51,4 @@
 
 }  // namespace wpi
 
-#endif  // WPIUTIL_SUPPORT_HTTPUTIL_INL_
+#endif  // WPIUTIL_WPI_HTTPUTIL_INL_
diff --git a/wpiutil/src/main/native/include/wpi/HttpWebSocketServerConnection.h b/wpiutil/src/main/native/include/wpi/HttpWebSocketServerConnection.h
new file mode 100644
index 0000000..d662471
--- /dev/null
+++ b/wpiutil/src/main/native/include/wpi/HttpWebSocketServerConnection.h
@@ -0,0 +1,94 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2020 FIRST. All Rights Reserved.                             */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef WPIUTIL_WPI_HTTPWEBSOCKETSERVERCONNECTION_H_
+#define WPIUTIL_WPI_HTTPWEBSOCKETSERVERCONNECTION_H_
+
+#include <initializer_list>
+#include <memory>
+#include <string>
+
+#include "wpi/ArrayRef.h"
+#include "wpi/HttpServerConnection.h"
+#include "wpi/SmallVector.h"
+#include "wpi/StringRef.h"
+#include "wpi/WebSocket.h"
+#include "wpi/WebSocketServer.h"
+#include "wpi/uv/Stream.h"
+
+namespace wpi {
+
+/**
+ * A server-side HTTP connection that also accepts WebSocket upgrades.
+ *
+ * @tparam Derived derived class for std::enable_shared_from_this.
+ */
+template <typename Derived>
+class HttpWebSocketServerConnection
+    : public HttpServerConnection,
+      public std::enable_shared_from_this<Derived> {
+ public:
+  /**
+   * Constructor.
+   *
+   * @param stream network stream
+   * @param protocols Acceptable subprotocols
+   */
+  HttpWebSocketServerConnection(std::shared_ptr<uv::Stream> stream,
+                                ArrayRef<StringRef> protocols);
+
+  /**
+   * Constructor.
+   *
+   * @param stream network stream
+   * @param protocols Acceptable subprotocols
+   */
+  HttpWebSocketServerConnection(std::shared_ptr<uv::Stream> stream,
+                                std::initializer_list<StringRef> protocols)
+      : HttpWebSocketServerConnection(
+            stream, makeArrayRef(protocols.begin(), protocols.end())) {}
+
+ protected:
+  /**
+   * Check that an incoming WebSocket upgrade is okay.  This is called prior
+   * to accepting the upgrade (so prior to ProcessWsUpgrade()).
+   *
+   * The implementation should check other headers and return true if the
+   * WebSocket connection should be accepted.
+   *
+   * @param protocol negotiated subprotocol
+   */
+  virtual bool IsValidWsUpgrade(StringRef protocol) { return true; }
+
+  /**
+   * Process an incoming WebSocket upgrade.  This is called after the header
+   * reader has been disconnected and the websocket has been accepted.
+   *
+   * The implementation should set up appropriate callbacks on the websocket
+   * object to continue communication.
+   *
+   * @note When a WebSocket upgrade occurs, the stream user data is replaced
+   *       with the websocket, and the websocket user data points to "this".
+   *       Replace the websocket user data with caution!
+   */
+  virtual void ProcessWsUpgrade() = 0;
+
+  /**
+   * WebSocket connection; not valid until ProcessWsUpgrade is called.
+   */
+  WebSocket* m_websocket = nullptr;
+
+ private:
+  WebSocketServerHelper m_helper;
+  SmallVector<std::string, 2> m_protocols;
+};
+
+}  // namespace wpi
+
+#include "HttpWebSocketServerConnection.inl"
+
+#endif  // WPIUTIL_WPI_HTTPWEBSOCKETSERVERCONNECTION_H_
diff --git a/wpiutil/src/main/native/include/wpi/HttpWebSocketServerConnection.inl b/wpiutil/src/main/native/include/wpi/HttpWebSocketServerConnection.inl
new file mode 100644
index 0000000..586f189
--- /dev/null
+++ b/wpiutil/src/main/native/include/wpi/HttpWebSocketServerConnection.inl
@@ -0,0 +1,54 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2020 FIRST. All Rights Reserved.                             */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef WPIUTIL_WPI_HTTPWEBSOCKETSERVERCONNECTION_INL_
+#define WPIUTIL_WPI_HTTPWEBSOCKETSERVERCONNECTION_INL_
+
+#include <memory>
+
+namespace wpi {
+
+template <typename Derived>
+HttpWebSocketServerConnection<Derived>::HttpWebSocketServerConnection(
+    std::shared_ptr<uv::Stream> stream, ArrayRef<StringRef> protocols)
+    : HttpServerConnection{stream},
+      m_helper{m_request},
+      m_protocols{protocols.begin(), protocols.end()} {
+  // Handle upgrade event
+  m_helper.upgrade.connect([this] {
+    // Negotiate sub-protocol
+    SmallVector<StringRef, 2> protocols{m_protocols.begin(), m_protocols.end()};
+    StringRef protocol = m_helper.MatchProtocol(protocols).second;
+
+    // Check that the upgrade is valid
+    if (!IsValidWsUpgrade(protocol)) return;
+
+    // Disconnect HttpServerConnection header reader
+    m_dataConn.disconnect();
+    m_messageCompleteConn.disconnect();
+
+    // Accepting the stream may destroy this (as it replaces the stream user
+    // data), so grab a shared pointer first.
+    auto self = this->shared_from_this();
+
+    // Accept the upgrade
+    auto ws = m_helper.Accept(m_stream, protocol);
+
+    // Set this as the websocket user data to keep it around
+    ws->SetData(self);
+
+    // Store in member
+    m_websocket = ws.get();
+
+    // Call derived class function
+    ProcessWsUpgrade();
+  });
+}
+
+}  // namespace wpi
+
+#endif  // WPIUTIL_WPI_HTTPWEBSOCKETSERVERCONNECTION_INL_
diff --git a/wpiutil/src/main/native/include/wpi/MimeTypes.h b/wpiutil/src/main/native/include/wpi/MimeTypes.h
new file mode 100644
index 0000000..b3dc17b
--- /dev/null
+++ b/wpiutil/src/main/native/include/wpi/MimeTypes.h
@@ -0,0 +1,19 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2020 FIRST. All Rights Reserved.                             */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef WPIUTIL_WPI_MIMETYPES_H_
+#define WPIUTIL_WPI_MIMETYPES_H_
+
+#include "wpi/StringRef.h"
+
+namespace wpi {
+
+StringRef MimeTypeFromPath(StringRef path);
+
+}  // namespace wpi
+
+#endif  // WPIUTIL_WPI_MIMETYPES_H_
diff --git a/wpiutil/src/main/native/include/wpi/PriorityQueue.h b/wpiutil/src/main/native/include/wpi/PriorityQueue.h
deleted file mode 100644
index 37585a3..0000000
--- a/wpiutil/src/main/native/include/wpi/PriorityQueue.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*----------------------------------------------------------------------------*/
-/* Copyright (c) 2018 FIRST. All Rights Reserved.                             */
-/* Open Source Software - may be modified and shared by FRC teams. The code   */
-/* must be accompanied by the FIRST BSD license file in the root directory of */
-/* the project.                                                               */
-/*----------------------------------------------------------------------------*/
-
-#ifndef WPIUTIL_WPI_PRIORITYQUEUE_H_
-#define WPIUTIL_WPI_PRIORITYQUEUE_H_
-
-#include <algorithm>
-#include <functional>
-#include <queue>
-#include <vector>
-
-namespace wpi {
-
-/**
- * This class adds a method for removing all elements from the priority queue
- * matching the given value.
- */
-template <class T, class Container = std::vector<T>,
-          class Compare = std::less<typename Container::value_type>>
-class PriorityQueue : public std::priority_queue<T, Container, Compare> {
- public:
-  bool remove(const T& value) {
-    auto it = std::find(this->c.begin(), this->c.end(), value);
-    if (it != this->c.end()) {
-      this->c.erase(it);
-      std::make_heap(this->c.begin(), this->c.end(), this->comp);
-      return true;
-    } else {
-      return false;
-    }
-  }
-};
-
-}  // namespace wpi
-
-#endif  // WPIUTIL_WPI_PRIORITYQUEUE_H_
diff --git a/wpiutil/src/main/native/include/wpi/Signal.h b/wpiutil/src/main/native/include/wpi/Signal.h
index d8109ff..64b774c 100644
--- a/wpiutil/src/main/native/include/wpi/Signal.h
+++ b/wpiutil/src/main/native/include/wpi/Signal.h
@@ -815,7 +815,7 @@
  *
  * Beware of accidentally using recursive signal emission or cycles between
  * two or more signals in your code. Locking std::mutex more than once is
- * undefined behaviour, even if it "seems to work somehow". Use signal_r
+ * undefined behavior, even if it "seems to work somehow". Use signal_r
  * instead for that use case.
  */
 template <typename... T>
diff --git a/wpiutil/src/main/native/include/wpi/TCPStream.h b/wpiutil/src/main/native/include/wpi/TCPStream.h
index 6a38ffb..0c6e8a9 100644
--- a/wpiutil/src/main/native/include/wpi/TCPStream.h
+++ b/wpiutil/src/main/native/include/wpi/TCPStream.h
@@ -1,7 +1,7 @@
 /*
    TCPStream.h
 
-   TCPStream class interface. TCPStream provides methods to trasnfer
+   TCPStream class interface. TCPStream provides methods to transfer
    data between peers over a TCP/IP connection.
 
    ------------------------------------------
diff --git a/wpiutil/src/main/native/include/wpi/circular_buffer.h b/wpiutil/src/main/native/include/wpi/circular_buffer.h
index 097d5f6..5dc12f8 100644
--- a/wpiutil/src/main/native/include/wpi/circular_buffer.h
+++ b/wpiutil/src/main/native/include/wpi/circular_buffer.h
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2015-2019 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2015-2020 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -47,6 +47,8 @@
  private:
   std::vector<T> m_data;
 
+  T zero_val{0};
+
   // Index of element at front of buffer
   size_t m_front = 0;
 
diff --git a/wpiutil/src/main/native/include/wpi/circular_buffer.inc b/wpiutil/src/main/native/include/wpi/circular_buffer.inc
index 7f029e4..20690b7 100644
--- a/wpiutil/src/main/native/include/wpi/circular_buffer.inc
+++ b/wpiutil/src/main/native/include/wpi/circular_buffer.inc
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2015-2019 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2015-2020 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -12,7 +12,7 @@
 namespace wpi {
 
 template <class T>
-circular_buffer<T>::circular_buffer(size_t size) : m_data(size, 0) {}
+circular_buffer<T>::circular_buffer(size_t size) : m_data(size, T{0}) {}
 
 /**
  * Returns number of elements in buffer
@@ -45,7 +45,7 @@
 T& circular_buffer<T>::back() {
   // If there are no elements in the buffer, do nothing
   if (m_length == 0) {
-    return 0;
+    return zero_val;
   }
 
   return m_data[(m_front + m_length - 1) % m_data.size()];
@@ -58,7 +58,7 @@
 const T& circular_buffer<T>::back() const {
   // If there are no elements in the buffer, do nothing
   if (m_length == 0) {
-    return 0;
+    return zero_val;
   }
 
   return m_data[(m_front + m_length - 1) % m_data.size()];
@@ -110,7 +110,7 @@
 T circular_buffer<T>::pop_front() {
   // If there are no elements in the buffer, do nothing
   if (m_length == 0) {
-    return 0;
+    return T{0};
   }
 
   T& temp = m_data[m_front];
@@ -126,7 +126,7 @@
 T circular_buffer<T>::pop_back() {
   // If there are no elements in the buffer, do nothing
   if (m_length == 0) {
-    return 0;
+    return T{0};
   }
 
   m_length--;
@@ -191,7 +191,7 @@
  */
 template <class T>
 void circular_buffer<T>::reset() {
-  std::fill(m_data.begin(), m_data.end(), 0);
+  std::fill(m_data.begin(), m_data.end(), T{0});
   m_front = 0;
   m_length = 0;
 }
diff --git a/wpiutil/src/main/native/include/wpi/http_parser.h b/wpiutil/src/main/native/include/wpi/http_parser.h
index f4bf9fd..2189b8f 100644
--- a/wpiutil/src/main/native/include/wpi/http_parser.h
+++ b/wpiutil/src/main/native/include/wpi/http_parser.h
@@ -63,7 +63,7 @@
  * chunked' headers that indicate the presence of a body.
  *
  * Returning `2` from on_headers_complete will tell parser that it should not
- * expect neither a body nor any futher responses on this connection. This is
+ * expect neither a body nor any further responses on this connection. This is
  * useful for handling responses to a CONNECT request which may not contain
  * `Upgrade` or `Connection: upgrade` headers.
  *
diff --git a/wpiutil/src/main/native/include/wpi/priority_queue.h b/wpiutil/src/main/native/include/wpi/priority_queue.h
new file mode 100644
index 0000000..b194090
--- /dev/null
+++ b/wpiutil/src/main/native/include/wpi/priority_queue.h
@@ -0,0 +1,118 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2018-2020 FIRST. All Rights Reserved.                        */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#ifndef WPIUTIL_WPI_PRIORITY_QUEUE_H_
+#define WPIUTIL_WPI_PRIORITY_QUEUE_H_
+
+#include <algorithm>
+#include <functional>
+#include <utility>
+#include <vector>
+
+namespace wpi {
+
+/**
+ * This class is the same as std::priority_queue with two changes:
+ *
+ * 1. Adds a remove() function for removing all elements from the priority queue
+ *    that match the given value.
+ * 2. Replaces "void pop()" with "T pop()" so the element can be moved from the
+ *    queue directly instead of copied from top().
+ */
+template <typename T, typename Sequence = std::vector<T>,
+          typename Compare = std::less<typename Sequence::value_type>>
+class priority_queue {
+ public:
+  static_assert(std::is_same_v<T, typename Sequence::value_type>,
+                "value_type must be the same as the underlying container");
+
+  using value_type = typename Sequence::value_type;
+  using reference = typename Sequence::reference;
+  using const_reference = typename Sequence::const_reference;
+  using size_type = typename Sequence::size_type;
+  using container_type = Sequence;
+  using value_compare = Compare;
+
+  template <typename Seq = Sequence,
+            typename Requires = typename std::enable_if_t<
+                std::is_default_constructible<Compare>{} &&
+                std::is_default_constructible<Seq>{}>>
+  priority_queue() {}
+
+  priority_queue(const Compare& comp, const Sequence& c) : c(c), comp(comp) {
+    std::make_heap(c.begin(), c.end(), comp);
+  }
+
+  explicit priority_queue(const Compare& comp, Sequence&& c = Sequence{})
+      : c(std::move(c)), comp(comp) {
+    std::make_heap(c.begin(), c.end(), comp);
+  }
+
+  template <typename InputIterator>
+  priority_queue(InputIterator first, InputIterator last, const Compare& comp,
+                 const Sequence& c)
+      : c(c), comp(comp) {
+    c.insert(c.end(), first, last);
+    std::make_heap(c.begin(), c.end(), comp);
+  }
+
+  template <typename InputIterator>
+  priority_queue(InputIterator first, InputIterator last,
+                 const Compare& comp = Compare{}, Sequence&& c = Sequence{})
+      : c(std::move(c)), comp(comp) {
+    c.insert(c.end(), first, last);
+    std::make_heap(c.begin(), c.end(), comp);
+  }
+
+  [[nodiscard]] bool empty() const { return c.empty(); }
+
+  size_type size() const { return c.size(); }
+
+  const_reference top() const { return c.front(); }
+
+  void push(const value_type& value) {
+    c.push_back(value);
+    std::push_heap(c.begin(), c.end(), comp);
+  }
+
+  void push(value_type&& value) {
+    c.push_back(std::move(value));
+    std::push_heap(c.begin(), c.end(), comp);
+  }
+
+  template <typename... Args>
+  void emplace(Args&&... args) {
+    c.emplace_back(std::forward<Args>(args)...);
+    std::push_heap(c.begin(), c.end(), comp);
+  }
+
+  T pop() {
+    std::pop_heap(c.begin(), c.end(), comp);
+    auto ret = std::move(c.back());
+    c.pop_back();
+    return ret;
+  }
+
+  bool remove(const T& value) {
+    auto it = std::find(c.begin(), c.end(), value);
+    if (it != this->c.end()) {
+      c.erase(it);
+      std::make_heap(c.begin(), c.end(), comp);
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+ protected:
+  Sequence c;
+  Compare comp;
+};
+
+}  // namespace wpi
+
+#endif  // WPIUTIL_WPI_PRIORITY_QUEUE_H_
diff --git a/wpiutil/src/main/native/include/wpi/static_circular_buffer.h b/wpiutil/src/main/native/include/wpi/static_circular_buffer.h
new file mode 100644
index 0000000..8329917
--- /dev/null
+++ b/wpiutil/src/main/native/include/wpi/static_circular_buffer.h
@@ -0,0 +1,276 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2020 FIRST. All Rights Reserved.                             */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include <array>
+#include <cstddef>
+
+namespace wpi {
+
+/**
+ * This is a simple circular buffer so we don't need to "bucket brigade" copy
+ * old values.
+ */
+template <class T, size_t N>
+class static_circular_buffer {
+ public:
+  static_assert(N > 0, "The circular buffer size shouldn't be zero.");
+
+  constexpr static_circular_buffer() = default;
+
+  class iterator {
+   public:
+    using iterator_category = std::forward_iterator_tag;
+    using value_type = T;
+    using difference_type = std::ptrdiff_t;
+    using pointer = T*;
+    using reference = T&;
+
+    iterator(static_circular_buffer* buffer, size_t index)
+        : m_buffer(buffer), m_index(index) {}
+
+    iterator& operator++() {
+      ++m_index;
+      return *this;
+    }
+    iterator operator++(int) {
+      iterator retval = *this;
+      ++(*this);
+      return retval;
+    }
+    bool operator==(const iterator& other) const {
+      return m_buffer == other.m_buffer && m_index == other.m_index;
+    }
+    bool operator!=(const iterator& other) const { return !(*this == other); }
+    reference operator*() { return (*m_buffer)[m_index]; }
+
+   private:
+    static_circular_buffer* m_buffer;
+    size_t m_index;
+  };
+
+  class const_iterator {
+   public:
+    using iterator_category = std::forward_iterator_tag;
+    using value_type = T;
+    using difference_type = std::ptrdiff_t;
+    using pointer = T*;
+    using const_reference = const T&;
+
+    const_iterator(const static_circular_buffer* buffer, size_t index)
+        : m_buffer(buffer), m_index(index) {}
+
+    const_iterator& operator++() {
+      ++m_index;
+      return *this;
+    }
+    const_iterator operator++(int) {
+      const_iterator retval = *this;
+      ++(*this);
+      return retval;
+    }
+    bool operator==(const const_iterator& other) const {
+      return m_buffer == other.m_buffer && m_index == other.m_index;
+    }
+    bool operator!=(const const_iterator& other) const {
+      return !(*this == other);
+    }
+    const_reference operator*() const { return (*m_buffer)[m_index]; }
+
+   private:
+    const static_circular_buffer* m_buffer;
+    size_t m_index;
+  };
+
+  iterator begin() { return iterator(this, 0); }
+  iterator end() {
+    return iterator(this, ::wpi::static_circular_buffer<T, N>::size());
+  }
+
+  const_iterator begin() const { return const_iterator(this, 0); }
+  const_iterator end() const {
+    return const_iterator(this, ::wpi::static_circular_buffer<T, N>::size());
+  }
+
+  const_iterator cbegin() const { return const_iterator(this, 0); }
+  const_iterator cend() const {
+    return const_iterator(this, ::wpi::static_circular_buffer<T, N>::size());
+  }
+
+  /**
+   * Returns number of elements in buffer
+   */
+  size_t size() const { return m_length; }
+
+  /**
+   * Returns value at front of buffer
+   */
+  T& front() { return (*this)[0]; }
+
+  /**
+   * Returns value at front of buffer
+   */
+  const T& front() const { return (*this)[0]; }
+
+  /**
+   * Returns value at back of buffer
+   *
+   * If there are no elements in the buffer, calling this function results in
+   * undefined behavior.
+   */
+  T& back() { return m_data[(m_front + m_length - 1) % N]; }
+
+  /**
+   * Returns value at back of buffer
+   *
+   * If there are no elements in the buffer, calling this function results in
+   * undefined behavior.
+   */
+  const T& back() const { return m_data[(m_front + m_length - 1) % N]; }
+
+  /**
+   * Push a new value onto the front of the buffer.
+   *
+   * The value at the back is overwritten if the buffer is full.
+   */
+  void push_front(T value) {
+    m_front = ModuloDec(m_front);
+
+    m_data[m_front] = value;
+
+    if (m_length < N) {
+      m_length++;
+    }
+  }
+
+  /**
+   * Push a new value onto the back of the buffer.
+   *
+   * The value at the front is overwritten if the buffer is full.
+   */
+  void push_back(T value) {
+    m_data[(m_front + m_length) % N] = value;
+
+    if (m_length < N) {
+      m_length++;
+    } else {
+      // Increment front if buffer is full to maintain size
+      m_front = ModuloInc(m_front);
+    }
+  }
+
+  /**
+   * Push a new value onto the front of the buffer that is constructed with the
+   * provided constructor arguments.
+   *
+   * The value at the back is overwritten if the buffer is full.
+   */
+  template <class... Args>
+  void emplace_front(Args&&... args) {
+    m_front = ModuloDec(m_front);
+
+    m_data[m_front] = T{args...};
+
+    if (m_length < N) {
+      m_length++;
+    }
+  }
+
+  /**
+   * Push a new value onto the back of the buffer that is constructed with the
+   * provided constructor arguments.
+   *
+   * The value at the front is overwritten if the buffer is full.
+   */
+  template <class... Args>
+  void emplace_back(Args&&... args) {
+    m_data[(m_front + m_length) % N] = T{args...};
+
+    if (m_length < N) {
+      m_length++;
+    } else {
+      // Increment front if buffer is full to maintain size
+      m_front = ModuloInc(m_front);
+    }
+  }
+
+  /**
+   * Pop value at front of buffer.
+   *
+   * If there are no elements in the buffer, calling this function results in
+   * undefined behavior.
+   */
+  T pop_front() {
+    T& temp = m_data[m_front];
+    m_front = ModuloInc(m_front);
+    m_length--;
+    return temp;
+  }
+
+  /**
+   * Pop value at back of buffer.
+   *
+   * If there are no elements in the buffer, calling this function results in
+   * undefined behavior.
+   */
+  T pop_back() {
+    m_length--;
+    return m_data[(m_front + m_length) % N];
+  }
+
+  /**
+   * Empties internal buffer.
+   */
+  void reset() {
+    m_front = 0;
+    m_length = 0;
+  }
+
+  /**
+   * @return Element at index starting from front of buffer.
+   */
+  T& operator[](size_t index) { return m_data[(m_front + index) % N]; }
+
+  /**
+   * @return Element at index starting from front of buffer.
+   */
+  const T& operator[](size_t index) const {
+    return m_data[(m_front + index) % N];
+  }
+
+ private:
+  std::array<T, N> m_data;
+
+  // Index of element at front of buffer
+  size_t m_front = 0;
+
+  // Number of elements used in buffer
+  size_t m_length = 0;
+
+  /**
+   * Increment an index modulo the length of the buffer.
+   *
+   * @return The result of the modulo operation.
+   */
+  size_t ModuloInc(size_t index) { return (index + 1) % N; }
+
+  /**
+   * Decrement an index modulo the length of the buffer.
+   *
+   * @return The result of the modulo operation.
+   */
+  size_t ModuloDec(size_t index) {
+    if (index == 0) {
+      return N - 1;
+    } else {
+      return index - 1;
+    }
+  }
+};
+
+}  // namespace wpi
diff --git a/wpiutil/src/main/native/include/wpi/uv/Buffer.h b/wpiutil/src/main/native/include/wpi/uv/Buffer.h
index 51acd76..04e96b9 100644
--- a/wpiutil/src/main/native/include/wpi/uv/Buffer.h
+++ b/wpiutil/src/main/native/include/wpi/uv/Buffer.h
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2018-2019 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2018-2020 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -107,6 +107,7 @@
    * @param size Size of each buffer to allocate.
    */
   explicit SimpleBufferPool(size_t size = 4096) : m_size{size} {}
+  ~SimpleBufferPool() { Clear(); }
 
   SimpleBufferPool(const SimpleBufferPool& other) = delete;
   SimpleBufferPool& operator=(const SimpleBufferPool& other) = delete;
diff --git a/wpiutil/src/main/native/include/wpi/uv/util.h b/wpiutil/src/main/native/include/wpi/uv/util.h
index 3795aa8..14a021d 100644
--- a/wpiutil/src/main/native/include/wpi/uv/util.h
+++ b/wpiutil/src/main/native/include/wpi/uv/util.h
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2018 FIRST. All Rights Reserved.                             */
+/* Copyright (c) 2018-2020 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -58,6 +58,24 @@
 }
 
 /**
+ * Convert a binary structure containing an IPv4 or IPv6 address to a string.
+ * @param addr Binary structure
+ * @param ip Output string (any type that has `assign(char*, char*)`)
+ * @param port Output port number
+ * @return Error (same as `uv_ip6_name()`).
+ */
+template <typename T>
+int AddrToName(const sockaddr_storage& addr, T* ip, unsigned int* port) {
+  if (addr.ss_family == AF_INET)
+    return AddrToName(reinterpret_cast<const sockaddr_in&>(addr), ip, port);
+  if (addr.ss_family == AF_INET6)
+    return AddrToName(reinterpret_cast<const sockaddr_in6&>(addr), ip, port);
+  char name[1];
+  ip->assign(name, name);
+  return -1;
+}
+
+/**
  * Convert a binary IPv4 address to a string.
  * @param addr Binary address
  * @param ip Output string (any type that has `assign(char*, char*)`)
diff --git a/wpiutil/src/main/native/libuv/src/unix/tty.cpp b/wpiutil/src/main/native/libuv/src/unix/tty.cpp
index 74d3d75..5f68140 100644
--- a/wpiutil/src/main/native/libuv/src/unix/tty.cpp
+++ b/wpiutil/src/main/native/libuv/src/unix/tty.cpp
@@ -38,7 +38,7 @@
 static struct termios orig_termios;
 static uv_spinlock_t termios_spinlock = UV_SPINLOCK_INITIALIZER;
 
-static int uv__tty_is_slave(const int fd) {
+static int uv__tty_is_peripheral(const int fd) {
   int result;
 #if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
   int dummy;
@@ -50,15 +50,16 @@
   result = ioctl(fd, TIOCPTYGNAME, &dummy) != 0;
 #elif defined(__NetBSD__)
   /*
-   * NetBSD as an extension returns with ptsname(3) and ptsname_r(3) the slave
-   * device name for both descriptors, the master one and slave one.
+   * NetBSD as an extension returns with ptsname(3) and ptsname_r(3) the
+   * peripheral device name for both descriptors, the controller one and
+   * peripheral one.
    *
    * Implement function to compare major device number with pts devices.
    *
    * The major numbers are machine-dependent, on NetBSD/amd64 they are
    * respectively:
-   *  - master tty: ptc - major 6
-   *  - slave tty:  pts - major 5
+   *  - controller tty: ptc - major 6
+   *  - peripheral tty:  pts - major 5
    */
 
   struct stat sb;
@@ -133,12 +134,12 @@
    * other processes.
    */
   if (type == UV_TTY) {
-    /* Reopening a pty in master mode won't work either because the reopened
-     * pty will be in slave mode (*BSD) or reopening will allocate a new
-     * master/slave pair (Linux). Therefore check if the fd points to a
-     * slave device.
+    /* Reopening a pty in controller mode won't work either because the reopened
+     * pty will be in peripheral mode (*BSD) or reopening will allocate a new
+     * controller/peripheral pair (Linux). Therefore check if the fd points to a
+     * peripheral device.
      */
-    if (uv__tty_is_slave(fd) && ttyname_r(fd, path, sizeof(path)) == 0)
+    if (uv__tty_is_peripheral(fd) && ttyname_r(fd, path, sizeof(path)) == 0)
       r = uv__open_cloexec(path, mode);
     else
       r = -1;
diff --git a/wpiutil/src/main/native/unix/Demangle.cpp b/wpiutil/src/main/native/unix/Demangle.cpp
index 1ce4f31..3453084 100644
--- a/wpiutil/src/main/native/unix/Demangle.cpp
+++ b/wpiutil/src/main/native/unix/Demangle.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2008-2019 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2008-2020 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -11,26 +11,26 @@
 
 #include <cstdio>
 
+#include "wpi/SmallString.h"
+
 namespace wpi {
 
-std::string Demangle(char const* mangledSymbol) {
-  char buffer[256];
+std::string Demangle(const Twine& mangledSymbol) {
+  SmallString<128> buf;
   size_t length;
   int32_t status;
 
-  if (std::sscanf(mangledSymbol, "%*[^(]%*[(]%255[^)+]", buffer)) {
-    char* symbol = abi::__cxa_demangle(buffer, nullptr, &length, &status);
-    if (status == 0) {
-      return symbol;
-    } else {
-      // If the symbol couldn't be demangled, it's probably a C function,
-      // so just return it as-is.
-      return buffer;
-    }
+  char* symbol =
+      abi::__cxa_demangle(mangledSymbol.toNullTerminatedStringRef(buf).data(),
+                          nullptr, &length, &status);
+  if (status == 0) {
+    std::string rv{symbol};
+    std::free(symbol);
+    return rv;
   }
 
   // If everything else failed, just return the mangled symbol
-  return mangledSymbol;
+  return mangledSymbol.str();
 }
 
 }  // namespace wpi
diff --git a/wpiutil/src/main/native/unix/StackTrace.cpp b/wpiutil/src/main/native/unix/StackTrace.cpp
index be28080..004eb39 100644
--- a/wpiutil/src/main/native/unix/StackTrace.cpp
+++ b/wpiutil/src/main/native/unix/StackTrace.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2008-2019 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2008-2020 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -11,6 +11,7 @@
 
 #include "wpi/Demangle.h"
 #include "wpi/SmallString.h"
+#include "wpi/StringRef.h"
 #include "wpi/raw_ostream.h"
 
 namespace wpi {
@@ -25,7 +26,11 @@
   for (int i = offset; i < stackSize; i++) {
     // Only print recursive functions once in a row.
     if (i == 0 || stackTrace[i] != stackTrace[i - 1]) {
-      trace << "\tat " << Demangle(mangledSymbols[i]) << "\n";
+      // extract just function name from "pathToExe(functionName+offset)"
+      StringRef sym{mangledSymbols[i]};
+      sym = sym.split('(').second;
+      sym = sym.split('+').first;
+      trace << "\tat " << Demangle(sym) << "\n";
     }
   }
 
diff --git a/wpiutil/src/main/native/windows/Demangle.cpp b/wpiutil/src/main/native/windows/Demangle.cpp
index 34d1cab..a1560d6 100644
--- a/wpiutil/src/main/native/windows/Demangle.cpp
+++ b/wpiutil/src/main/native/windows/Demangle.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2008-2019 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2008-2020 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -11,19 +11,22 @@
 
 #include <dbghelp.h>
 
+#include "wpi/SmallString.h"
 #include "wpi/mutex.h"
 
 #pragma comment(lib, "Dbghelp.lib")
 
 namespace wpi {
 
-std::string Demangle(char const* mangledSymbol) {
+std::string Demangle(const Twine& mangledSymbol) {
   static wpi::mutex m;
   std::scoped_lock lock(m);
+  SmallString<128> buf;
   char buffer[256];
-  DWORD sz = UnDecorateSymbolName(mangledSymbol, buffer, sizeof(buffer),
-                                  UNDNAME_COMPLETE);
-  if (sz == 0) return mangledSymbol;
+  DWORD sz =
+      UnDecorateSymbolName(mangledSymbol.toNullTerminatedStringRef(buf).data(),
+                           buffer, sizeof(buffer), UNDNAME_COMPLETE);
+  if (sz == 0) return mangledSymbol.str();
   return std::string(buffer, sz);
 }
 
diff --git a/wpiutil/src/netconsoleTee/native/cpp/main.cpp b/wpiutil/src/netconsoleTee/native/cpp/main.cpp
index 6c2a4fe..82cc82a 100644
--- a/wpiutil/src/netconsoleTee/native/cpp/main.cpp
+++ b/wpiutil/src/netconsoleTee/native/cpp/main.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2018-2019 FIRST. All Rights Reserved.                        */
+/* Copyright (c) 2018-2020 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -57,14 +57,14 @@
   return true;
 }
 
-static void CopyUdp(uv::Stream& in, std::shared_ptr<uv::Udp> out,
+static void CopyUdp(uv::Stream& in, std::shared_ptr<uv::Udp> out, int port,
                     bool broadcast) {
   sockaddr_in addr;
   if (broadcast) {
     out->SetBroadcast(true);
-    uv::NameToAddr("0.0.0.0", 6666, &addr);
+    uv::NameToAddr("0.0.0.0", port, &addr);
   } else {
-    uv::NameToAddr("127.0.0.1", 6666, &addr);
+    uv::NameToAddr("127.0.0.1", port, &addr);
   }
 
   in.data.connect(
@@ -119,6 +119,7 @@
   bool useUdp = false;
   bool broadcastUdp = false;
   bool err = false;
+  int port = -1;
 
   while (arg < argc && argv[arg][0] == '-') {
     if (wpi::StringRef(argv[arg]) == "-u") {
@@ -126,6 +127,13 @@
     } else if (wpi::StringRef(argv[arg]) == "-b") {
       useUdp = true;
       broadcastUdp = true;
+    } else if (wpi::StringRef(argv[arg]) == "-p") {
+      ++arg;
+      if (arg >= argc || argv[arg][0] == '-' ||
+          wpi::StringRef(argv[arg]).getAsInteger(10, port)) {
+        wpi::errs() << "-p must be followed by port number\n";
+        err = true;
+      }
     } else {
       wpi::errs() << "unrecognized command line option " << argv[arg] << '\n';
       err = true;
@@ -135,9 +143,10 @@
 
   if (err) {
     wpi::errs()
-        << argv[0] << " [-ub]\n"
-        << "  -u  send udp to localhost port 6666 instead of using tcp\n"
-        << "  -b  broadcast udp to port 6666 instead of using tcp\n";
+        << argv[0] << " [-ub] [-p PORT]\n"
+        << "  -u       send udp to localhost port 6666 instead of using tcp\n"
+        << "  -b       broadcast udp to port 6666 instead of using tcp\n"
+        << "  -p PORT  use port PORT instead of 6666 (udp) or 1740 (tcp)\n";
     return EXIT_FAILURE;
   }
 
@@ -161,12 +170,12 @@
   if (useUdp) {
     auto udp = uv::Udp::Create(loop);
     // tee
-    CopyUdp(*stdinTty, udp, broadcastUdp);
+    CopyUdp(*stdinTty, udp, port < 0 ? 6666 : port, broadcastUdp);
   } else {
     auto tcp = uv::Tcp::Create(loop);
 
     // bind to listen address and port
-    tcp->Bind("", 1740);
+    tcp->Bind("", port < 0 ? 1740 : port);
 
     // when we get a connection, accept it
     tcp->connection.connect([srv = tcp.get(), stdinTty] {
diff --git a/wpiutil/src/test/java/edu/wpi/first/wpiutil/WPIUtilJNITest.java b/wpiutil/src/test/java/edu/wpi/first/wpiutil/WPIUtilJNITest.java
new file mode 100644
index 0000000..e92efe4
--- /dev/null
+++ b/wpiutil/src/test/java/edu/wpi/first/wpiutil/WPIUtilJNITest.java
@@ -0,0 +1,19 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2020 FIRST. All Rights Reserved.                             */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+package edu.wpi.first.wpiutil;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+public class WPIUtilJNITest {
+  @Test
+  public void testNow() {
+    assertDoesNotThrow(WPIUtilJNI::now);
+  }
+}
diff --git a/wpiutil/src/test/java/edu/wpi/first/wpiutil/math/MatrixTest.java b/wpiutil/src/test/java/edu/wpi/first/wpiutil/math/MatrixTest.java
deleted file mode 100644
index 4d6697d..0000000
--- a/wpiutil/src/test/java/edu/wpi/first/wpiutil/math/MatrixTest.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*----------------------------------------------------------------------------*/
-/* Copyright (c) 2019 FIRST. All Rights Reserved.                             */
-/* Open Source Software - may be modified and shared by FRC teams. The code   */
-/* must be accompanied by the FIRST BSD license file in the root directory of */
-/* the project.                                                               */
-/*----------------------------------------------------------------------------*/
-
-package edu.wpi.first.wpiutil.math;
-
-import org.ejml.data.SingularMatrixException;
-import org.ejml.dense.row.MatrixFeatures_DDRM;
-import org.ejml.simple.SimpleMatrix;
-import org.junit.jupiter.api.Test;
-
-import edu.wpi.first.wpiutil.math.numbers.N1;
-import edu.wpi.first.wpiutil.math.numbers.N2;
-import edu.wpi.first.wpiutil.math.numbers.N3;
-import edu.wpi.first.wpiutil.math.numbers.N4;
-
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-public class MatrixTest {
-  @Test
-  void testMatrixMultiplication() {
-    var mat1 = MatrixUtils.mat(Nat.N2(), Nat.N2())
-        .fill(2.0, 1.0,
-            0.0, 1.0);
-    var mat2 = MatrixUtils.mat(Nat.N2(), Nat.N2())
-        .fill(3.0, 0.0,
-            0.0, 2.5);
-
-    Matrix<N2, N2> result = mat1.times(mat2);
-
-    assertTrue(MatrixFeatures_DDRM.isEquals(
-        MatrixUtils.mat(Nat.N2(), Nat.N2())
-        .fill(6.0, 2.5,
-            0.0, 2.5).getStorage().getDDRM(),
-        result.getStorage().getDDRM()
-    ));
-
-    var mat3 = MatrixUtils.mat(Nat.N2(), Nat.N3())
-        .fill(1.0, 3.0, 0.5,
-            2.0, 4.3, 1.2);
-    var mat4 = MatrixUtils.mat(Nat.N3(), Nat.N4())
-        .fill(3.0, 1.5, 2.0, 4.5,
-            2.3, 1.0, 1.6, 3.1,
-            5.2, 2.1, 2.0, 1.0);
-
-    Matrix<N2, N4> result2 = mat3.times(mat4);
-
-    assertTrue(MatrixFeatures_DDRM.isIdentical(
-        MatrixUtils.mat(Nat.N2(), Nat.N4())
-        .fill(12.5, 5.55, 7.8, 14.3,
-            22.13, 9.82, 13.28, 23.53).getStorage().getDDRM(),
-        result2.getStorage().getDDRM(),
-        1E-9
-    ));
-  }
-
-  @Test
-  void testMatrixVectorMultiplication() {
-    var mat = MatrixUtils.mat(Nat.N2(), Nat.N2())
-        .fill(1.0, 1.0,
-            0.0, 1.0);
-
-    var vec = MatrixUtils.vec(Nat.N2())
-        .fill(3.0,
-            2.0);
-
-    Matrix<N2, N1> result = mat.times(vec);
-    assertTrue(MatrixFeatures_DDRM.isEquals(
-        MatrixUtils.vec(Nat.N2())
-        .fill(5.0,
-            2.0).getStorage().getDDRM(),
-        result.getStorage().getDDRM()
-    ));
-  }
-
-  @Test
-  void testTranspose() {
-    Matrix<N3, N1> vec = MatrixUtils.vec(Nat.N3())
-        .fill(1.0,
-            2.0,
-            3.0);
-
-    Matrix<N1, N3> transpose = vec.transpose();
-
-    assertTrue(MatrixFeatures_DDRM.isEquals(
-        MatrixUtils.mat(Nat.N1(), Nat.N3()).fill(1.0, 2.0, 3.0).getStorage()
-        .getDDRM(),
-        transpose.getStorage().getDDRM()
-    ));
-  }
-
-  @Test
-  void testInverse() {
-    var mat = MatrixUtils.mat(Nat.N3(), Nat.N3())
-        .fill(1.0, 3.0, 2.0,
-            5.0, 2.0, 1.5,
-            0.0, 1.3, 2.5);
-
-    var inv = mat.inv();
-
-    assertTrue(MatrixFeatures_DDRM.isIdentical(
-        MatrixUtils.eye(Nat.N3()).getStorage().getDDRM(),
-        mat.times(inv).getStorage().getDDRM(),
-        1E-9
-    ));
-
-    assertTrue(MatrixFeatures_DDRM.isIdentical(
-        MatrixUtils.eye(Nat.N3()).getStorage().getDDRM(),
-        inv.times(mat).getStorage().getDDRM(),
-        1E-9
-    ));
-  }
-
-  @Test
-  void testUninvertableMatrix() {
-    var singularMatrix = MatrixUtils.mat(Nat.N2(), Nat.N2())
-        .fill(2.0, 1.0,
-            2.0, 1.0);
-
-    assertThrows(SingularMatrixException.class, singularMatrix::inv);
-  }
-
-  @Test
-  void testMatrixScalarArithmetic() {
-    var mat = MatrixUtils.mat(Nat.N2(), Nat.N2())
-        .fill(1.0, 2.0,
-            3.0, 4.0);
-
-
-    assertTrue(MatrixFeatures_DDRM.isEquals(
-        MatrixUtils.mat(Nat.N2(), Nat.N2())
-        .fill(3.0, 4.0,
-            5.0, 6.0).getStorage().getDDRM(),
-        mat.plus(2.0).getStorage().getDDRM()
-    ));
-
-    assertTrue(MatrixFeatures_DDRM.isEquals(
-        MatrixUtils.mat(Nat.N2(), Nat.N2())
-        .fill(0.0, 1.0,
-            2.0, 3.0).getStorage().getDDRM(),
-        mat.minus(1.0).getStorage().getDDRM()
-    ));
-
-    assertTrue(MatrixFeatures_DDRM.isEquals(
-        MatrixUtils.mat(Nat.N2(), Nat.N2())
-        .fill(2.0, 4.0,
-            6.0, 8.0).getStorage().getDDRM(),
-        mat.times(2.0).getStorage().getDDRM()
-    ));
-
-    assertTrue(MatrixFeatures_DDRM.isIdentical(
-        MatrixUtils.mat(Nat.N2(), Nat.N2())
-        .fill(0.5, 1.0,
-            1.5, 2.0).getStorage().getDDRM(),
-        mat.div(2.0).getStorage().getDDRM(),
-        1E-3
-    ));
-  }
-
-  @Test
-  void testMatrixMatrixArithmetic() {
-    var mat1 = MatrixUtils.mat(Nat.N2(), Nat.N2())
-        .fill(1.0, 2.0,
-            3.0, 4.0);
-
-    var mat2 = MatrixUtils.mat(Nat.N2(), Nat.N2())
-        .fill(5.0, 6.0,
-            7.0, 8.0);
-
-    assertTrue(MatrixFeatures_DDRM.isEquals(
-        MatrixUtils.mat(Nat.N2(), Nat.N2())
-        .fill(-4.0, -4.0,
-            -4.0, -4.0).getStorage().getDDRM(),
-        mat1.minus(mat2).getStorage().getDDRM()
-    ));
-
-    assertTrue(MatrixFeatures_DDRM.isEquals(
-        MatrixUtils.mat(Nat.N2(), Nat.N2())
-        .fill(6.0, 8.0,
-            10.0, 12.0).getStorage().getDDRM(),
-        mat1.plus(mat2).getStorage().getDDRM()
-    ));
-  }
-
-  @Test
-  void testMatrixExponential() {
-    SimpleMatrix matrix = MatrixUtils.eye(Nat.N2()).getStorage();
-    var result = SimpleMatrixUtils.expm(matrix);
-
-    assertTrue(MatrixFeatures_DDRM.isIdentical(
-        result.getDDRM(),
-        new SimpleMatrix(2, 2, true, new double[]{Math.E, 0, 0, Math.E}).getDDRM(),
-        1E-9
-    ));
-
-    matrix = new SimpleMatrix(2, 2, true, new double[]{1, 2, 3, 4});
-    result = SimpleMatrixUtils.expm(matrix.scale(0.01));
-
-    assertTrue(MatrixFeatures_DDRM.isIdentical(
-        result.getDDRM(),
-        new SimpleMatrix(2, 2, true, new double[]{1.01035625, 0.02050912,
-            0.03076368, 1.04111993}).getDDRM(),
-        1E-8
-    ));
-  }
-}
diff --git a/wpiutil/src/test/native/cpp/EigenTest.cpp b/wpiutil/src/test/native/cpp/EigenTest.cpp
deleted file mode 100644
index 04a0bc2..0000000
--- a/wpiutil/src/test/native/cpp/EigenTest.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*----------------------------------------------------------------------------*/
-/* Copyright (c) 2019 FIRST. All Rights Reserved.                             */
-/* Open Source Software - may be modified and shared by FRC teams. The code   */
-/* must be accompanied by the FIRST BSD license file in the root directory of */
-/* the project.                                                               */
-/*----------------------------------------------------------------------------*/
-
-#include <Eigen/Core>
-#include <Eigen/LU>
-
-#include "gtest/gtest.h"
-
-TEST(EigenTest, MultiplicationTest) {
-  Eigen::Matrix<double, 2, 2> m1;
-  m1 << 2, 1, 0, 1;
-
-  Eigen::Matrix<double, 2, 2> m2;
-  m2 << 3, 0, 0, 2.5;
-
-  const auto result = m1 * m2;
-
-  Eigen::Matrix<double, 2, 2> expectedResult;
-  expectedResult << 6.0, 2.5, 0.0, 2.5;
-
-  EXPECT_TRUE(expectedResult.isApprox(result));
-
-  Eigen::Matrix<double, 2, 3> m3;
-  m3 << 1.0, 3.0, 0.5, 2.0, 4.3, 1.2;
-
-  Eigen::Matrix<double, 3, 4> m4;
-  m4 << 3.0, 1.5, 2.0, 4.5, 2.3, 1.0, 1.6, 3.1, 5.2, 2.1, 2.0, 1.0;
-
-  const auto result2 = m3 * m4;
-
-  Eigen::Matrix<double, 2, 4> expectedResult2;
-  expectedResult2 << 12.5, 5.55, 7.8, 14.3, 22.13, 9.82, 13.28, 23.53;
-
-  EXPECT_TRUE(expectedResult2.isApprox(result2));
-}
-
-TEST(EigenTest, TransposeTest) {
-  Eigen::Matrix<double, 3, 1> vec;
-  vec << 1, 2, 3;
-
-  const auto transpose = vec.transpose();
-
-  Eigen::Matrix<double, 1, 3> expectedTranspose;
-  expectedTranspose << 1, 2, 3;
-
-  EXPECT_TRUE(expectedTranspose.isApprox(transpose));
-}
-
-TEST(EigenTest, InverseTest) {
-  Eigen::Matrix<double, 3, 3> mat;
-  mat << 1.0, 3.0, 2.0, 5.0, 2.0, 1.5, 0.0, 1.3, 2.5;
-
-  const auto inverse = mat.inverse();
-  const auto identity = Eigen::MatrixXd::Identity(3, 3);
-
-  EXPECT_TRUE(identity.isApprox(mat * inverse));
-}
diff --git a/wpiutil/src/test/native/cpp/HttpWebSocketServerConnectionTest.cpp b/wpiutil/src/test/native/cpp/HttpWebSocketServerConnectionTest.cpp
new file mode 100644
index 0000000..8022cae
--- /dev/null
+++ b/wpiutil/src/test/native/cpp/HttpWebSocketServerConnectionTest.cpp
@@ -0,0 +1,28 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2020 FIRST. All Rights Reserved.                             */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "wpi/HttpWebSocketServerConnection.h"  // NOLINT(build/include_order)
+
+#include <gtest/gtest.h>
+
+namespace wpi {
+
+class HttpWebSocketServerConnectionTest
+    : public HttpWebSocketServerConnection<HttpWebSocketServerConnectionTest> {
+ public:
+  HttpWebSocketServerConnectionTest(std::shared_ptr<uv::Stream> stream,
+                                    ArrayRef<StringRef> protocols)
+      : HttpWebSocketServerConnection{stream, protocols} {}
+
+  void ProcessRequest() override { ++gotRequest; }
+  void ProcessWsUpgrade() override { ++gotUpgrade; }
+
+  int gotRequest = 0;
+  int gotUpgrade = 0;
+};
+
+}  // namespace wpi
diff --git a/wpiutil/src/test/native/cpp/StaticCircularBufferTest.cpp b/wpiutil/src/test/native/cpp/StaticCircularBufferTest.cpp
new file mode 100644
index 0000000..72da38b
--- /dev/null
+++ b/wpiutil/src/test/native/cpp/StaticCircularBufferTest.cpp
@@ -0,0 +1,151 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2020 FIRST. All Rights Reserved.                             */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#include "wpi/static_circular_buffer.h"  // NOLINT(build/include_order)
+
+#include <array>
+
+#include "gtest/gtest.h"
+
+static const std::array<double, 10> values = {
+    {751.848, 766.366, 342.657, 234.252, 716.126, 132.344, 445.697, 22.727,
+     421.125, 799.913}};
+
+static const std::array<double, 8> pushFrontOut = {
+    {799.913, 421.125, 22.727, 445.697, 132.344, 716.126, 234.252, 342.657}};
+
+static const std::array<double, 8> pushBackOut = {
+    {342.657, 234.252, 716.126, 132.344, 445.697, 22.727, 421.125, 799.913}};
+
+TEST(StaticCircularBufferTest, PushFrontTest) {
+  wpi::static_circular_buffer<double, 8> queue;
+
+  for (auto& value : values) {
+    queue.push_front(value);
+  }
+
+  for (size_t i = 0; i < pushFrontOut.size(); ++i) {
+    EXPECT_EQ(pushFrontOut[i], queue[i]);
+  }
+}
+
+TEST(StaticCircularBufferTest, PushBackTest) {
+  wpi::static_circular_buffer<double, 8> queue;
+
+  for (auto& value : values) {
+    queue.push_back(value);
+  }
+
+  for (size_t i = 0; i < pushBackOut.size(); ++i) {
+    EXPECT_EQ(pushBackOut[i], queue[i]);
+  }
+}
+
+TEST(StaticCircularBufferTest, EmplaceFrontTest) {
+  wpi::static_circular_buffer<double, 8> queue;
+
+  for (auto& value : values) {
+    queue.emplace_front(value);
+  }
+
+  for (size_t i = 0; i < pushFrontOut.size(); ++i) {
+    EXPECT_EQ(pushFrontOut[i], queue[i]);
+  }
+}
+
+TEST(StaticCircularBufferTest, EmplaceBackTest) {
+  wpi::static_circular_buffer<double, 8> queue;
+
+  for (auto& value : values) {
+    queue.emplace_back(value);
+  }
+
+  for (size_t i = 0; i < pushBackOut.size(); ++i) {
+    EXPECT_EQ(pushBackOut[i], queue[i]);
+  }
+}
+
+TEST(StaticCircularBufferTest, PushPopTest) {
+  wpi::static_circular_buffer<double, 3> queue;
+
+  // Insert three elements into the buffer
+  queue.push_back(1.0);
+  queue.push_back(2.0);
+  queue.push_back(3.0);
+
+  EXPECT_EQ(1.0, queue[0]);
+  EXPECT_EQ(2.0, queue[1]);
+  EXPECT_EQ(3.0, queue[2]);
+
+  /*
+   * The buffer is full now, so pushing subsequent elements will overwrite the
+   * front-most elements.
+   */
+
+  queue.push_back(4.0);  // Overwrite 1 with 4
+
+  // The buffer now contains 2, 3 and 4
+  EXPECT_EQ(2.0, queue[0]);
+  EXPECT_EQ(3.0, queue[1]);
+  EXPECT_EQ(4.0, queue[2]);
+
+  queue.push_back(5.0);  // Overwrite 2 with 5
+
+  // The buffer now contains 3, 4 and 5
+  EXPECT_EQ(3.0, queue[0]);
+  EXPECT_EQ(4.0, queue[1]);
+  EXPECT_EQ(5.0, queue[2]);
+
+  EXPECT_EQ(5.0, queue.pop_back());  // 5 is removed
+
+  // The buffer now contains 3 and 4
+  EXPECT_EQ(3.0, queue[0]);
+  EXPECT_EQ(4.0, queue[1]);
+
+  EXPECT_EQ(3.0, queue.pop_front());  // 3 is removed
+
+  // Leaving only one element with value == 4
+  EXPECT_EQ(4.0, queue[0]);
+}
+
+TEST(StaticCircularBufferTest, ResetTest) {
+  wpi::static_circular_buffer<double, 5> queue;
+
+  for (size_t i = 1; i < 6; ++i) {
+    queue.push_back(i);
+  }
+
+  queue.reset();
+
+  EXPECT_EQ(queue.size(), size_t{0});
+}
+
+TEST(StaticCircularBufferTest, IteratorTest) {
+  wpi::static_circular_buffer<double, 3> queue;
+
+  queue.push_back(1.0);
+  queue.push_back(2.0);
+  queue.push_back(3.0);
+  queue.push_back(4.0);  // Overwrite 1 with 4
+
+  // The buffer now contains 2, 3 and 4
+  const std::array<double, 3> values = {2.0, 3.0, 4.0};
+
+  // iterator
+  int i = 0;
+  for (auto& elem : queue) {
+    EXPECT_EQ(values[i], elem);
+    ++i;
+  }
+
+  // const_iterator
+  i = 0;
+  for (const auto& elem : queue) {
+    EXPECT_EQ(values[i], elem);
+    ++i;
+  }
+}
diff --git a/wpiutil/src/test/native/cpp/UnitsTest.cpp b/wpiutil/src/test/native/cpp/UnitsTest.cpp
deleted file mode 100644
index 8e0823a..0000000
--- a/wpiutil/src/test/native/cpp/UnitsTest.cpp
+++ /dev/null
@@ -1,3379 +0,0 @@
-/*----------------------------------------------------------------------------*/
-/* Copyright (c) 2019 FIRST. All Rights Reserved.                             */
-/* Open Source Software - may be modified and shared by FRC teams. The code   */
-/* must be accompanied by the FIRST BSD license file in the root directory of */
-/* the project.                                                               */
-/*----------------------------------------------------------------------------*/
-
-#include <array>
-#include <chrono>
-#include <string>
-#include <type_traits>
-
-#include "gtest/gtest.h"
-#include "units/units.h"
-
-using namespace units;
-using namespace units::dimensionless;
-using namespace units::length;
-using namespace units::mass;
-using namespace units::angle;
-using namespace units::time;
-using namespace units::frequency;
-using namespace units::area;
-using namespace units::velocity;
-using namespace units::angular_velocity;
-using namespace units::temperature;
-using namespace units::luminous_intensity;
-using namespace units::solid_angle;
-using namespace units::frequency;
-using namespace units::acceleration;
-using namespace units::pressure;
-using namespace units::charge;
-using namespace units::energy;
-using namespace units::power;
-using namespace units::voltage;
-using namespace units::capacitance;
-using namespace units::impedance;
-using namespace units::conductance;
-using namespace units::magnetic_flux;
-using namespace units::magnetic_field_strength;
-using namespace units::inductance;
-using namespace units::luminous_flux;
-using namespace units::illuminance;
-using namespace units::radiation;
-using namespace units::torque;
-using namespace units::volume;
-using namespace units::density;
-using namespace units::concentration;
-using namespace units::data;
-using namespace units::data_transfer_rate;
-using namespace units::math;
-
-#if !defined(_MSC_VER) || _MSC_VER > 1800
-using namespace units::literals;
-#endif
-
-namespace {
-
-class TypeTraits : public ::testing::Test {
- protected:
-  TypeTraits() {}
-  virtual ~TypeTraits() {}
-  virtual void SetUp() {}
-  virtual void TearDown() {}
-};
-
-class UnitManipulators : public ::testing::Test {
- protected:
-  UnitManipulators() {}
-  virtual ~UnitManipulators() {}
-  virtual void SetUp() {}
-  virtual void TearDown() {}
-};
-
-class UnitContainer : public ::testing::Test {
- protected:
-  UnitContainer() {}
-  virtual ~UnitContainer() {}
-  virtual void SetUp() {}
-  virtual void TearDown() {}
-};
-
-class UnitConversion : public ::testing::Test {
- protected:
-  UnitConversion() {}
-  virtual ~UnitConversion() {}
-  virtual void SetUp() {}
-  virtual void TearDown() {}
-};
-
-class UnitMath : public ::testing::Test {
- protected:
-  UnitMath() {}
-  virtual ~UnitMath() {}
-  virtual void SetUp() {}
-  virtual void TearDown() {}
-};
-
-class CompileTimeArithmetic : public ::testing::Test {
- protected:
-  CompileTimeArithmetic() {}
-  virtual ~CompileTimeArithmetic() {}
-  virtual void SetUp() {}
-  virtual void TearDown() {}
-};
-
-class Constexpr : public ::testing::Test {
- protected:
-  Constexpr() {}
-  virtual ~Constexpr() {}
-  virtual void SetUp() {}
-  virtual void TearDown() {}
-};
-
-class CaseStudies : public ::testing::Test {
- protected:
-  CaseStudies() {}
-  virtual ~CaseStudies() {}
-  virtual void SetUp() {}
-  virtual void TearDown() {}
-
-  struct RightTriangle {
-    using a = unit_value_t<meters, 3>;
-    using b = unit_value_t<meters, 4>;
-    using c = unit_value_sqrt<
-        unit_value_add<unit_value_power<a, 2>, unit_value_power<b, 2>>>;
-  };
-};
-}  // namespace
-
-TEST_F(TypeTraits, isRatio) {
-  EXPECT_TRUE(traits::is_ratio<std::ratio<1>>::value);
-  EXPECT_FALSE(traits::is_ratio<double>::value);
-}
-
-TEST_F(TypeTraits, ratio_sqrt) {
-  using rt2 = ratio_sqrt<std::ratio<2>>;
-  EXPECT_LT(std::abs(std::sqrt(2 / static_cast<double>(1)) -
-                     rt2::num / static_cast<double>(rt2::den)),
-            5e-9);
-
-  using rt4 = ratio_sqrt<std::ratio<4>>;
-  EXPECT_LT(std::abs(std::sqrt(4 / static_cast<double>(1)) -
-                     rt4::num / static_cast<double>(rt4::den)),
-            5e-9);
-
-  using rt10 = ratio_sqrt<std::ratio<10>>;
-  EXPECT_LT(std::abs(std::sqrt(10 / static_cast<double>(1)) -
-                     rt10::num / static_cast<double>(rt10::den)),
-            5e-9);
-
-  using rt30 = ratio_sqrt<std::ratio<30>>;
-  EXPECT_LT(std::abs(std::sqrt(30 / static_cast<double>(1)) -
-                     rt30::num / static_cast<double>(rt30::den)),
-            5e-9);
-
-  using rt61 = ratio_sqrt<std::ratio<61>>;
-  EXPECT_LT(std::abs(std::sqrt(61 / static_cast<double>(1)) -
-                     rt61::num / static_cast<double>(rt61::den)),
-            5e-9);
-
-  using rt100 = ratio_sqrt<std::ratio<100>>;
-  EXPECT_LT(std::abs(std::sqrt(100 / static_cast<double>(1)) -
-                     rt100::num / static_cast<double>(rt100::den)),
-            5e-9);
-
-  using rt1000 = ratio_sqrt<std::ratio<1000>>;
-  EXPECT_LT(std::abs(std::sqrt(1000 / static_cast<double>(1)) -
-                     rt1000::num / static_cast<double>(rt1000::den)),
-            5e-9);
-
-  using rt10000 = ratio_sqrt<std::ratio<10000>>;
-  EXPECT_LT(std::abs(std::sqrt(10000 / static_cast<double>(1)) -
-                     rt10000::num / static_cast<double>(rt10000::den)),
-            5e-9);
-}
-
-TEST_F(TypeTraits, is_unit) {
-  EXPECT_FALSE(traits::is_unit<std::ratio<1>>::value);
-  EXPECT_FALSE(traits::is_unit<double>::value);
-  EXPECT_TRUE(traits::is_unit<meters>::value);
-  EXPECT_TRUE(traits::is_unit<feet>::value);
-  EXPECT_TRUE(traits::is_unit<degrees_squared>::value);
-  EXPECT_FALSE(traits::is_unit<meter_t>::value);
-}
-
-TEST_F(TypeTraits, is_unit_t) {
-  EXPECT_FALSE(traits::is_unit_t<std::ratio<1>>::value);
-  EXPECT_FALSE(traits::is_unit_t<double>::value);
-  EXPECT_FALSE(traits::is_unit_t<meters>::value);
-  EXPECT_FALSE(traits::is_unit_t<feet>::value);
-  EXPECT_FALSE(traits::is_unit_t<degrees_squared>::value);
-  EXPECT_TRUE(traits::is_unit_t<meter_t>::value);
-}
-
-TEST_F(TypeTraits, unit_traits) {
-  EXPECT_TRUE(
-      (std::is_same<void,
-                    traits::unit_traits<double>::conversion_ratio>::value));
-  EXPECT_FALSE(
-      (std::is_same<void,
-                    traits::unit_traits<meters>::conversion_ratio>::value));
-}
-
-TEST_F(TypeTraits, unit_t_traits) {
-  EXPECT_TRUE(
-      (std::is_same<void,
-                    traits::unit_t_traits<double>::underlying_type>::value));
-  EXPECT_TRUE(
-      (std::is_same<UNIT_LIB_DEFAULT_TYPE,
-                    traits::unit_t_traits<meter_t>::underlying_type>::value));
-  EXPECT_TRUE(
-      (std::is_same<void, traits::unit_t_traits<double>::value_type>::value));
-  EXPECT_TRUE(
-      (std::is_same<UNIT_LIB_DEFAULT_TYPE,
-                    traits::unit_t_traits<meter_t>::value_type>::value));
-}
-
-TEST_F(TypeTraits, all_true) {
-  EXPECT_TRUE(all_true<true>::type::value);
-  EXPECT_TRUE((all_true<true, true>::type::value));
-  EXPECT_TRUE((all_true<true, true, true>::type::value));
-  EXPECT_FALSE(all_true<false>::type::value);
-  EXPECT_FALSE((all_true<true, false>::type::value));
-  EXPECT_FALSE((all_true<true, true, false>::type::value));
-  EXPECT_FALSE((all_true<false, false, false>::type::value));
-}
-
-TEST_F(TypeTraits, is_convertible_unit) {
-  EXPECT_TRUE((traits::is_convertible_unit<meters, meters>::value));
-  EXPECT_TRUE((traits::is_convertible_unit<meters, astronicalUnits>::value));
-  EXPECT_TRUE((traits::is_convertible_unit<meters, parsecs>::value));
-
-  EXPECT_TRUE((traits::is_convertible_unit<meters, meters>::value));
-  EXPECT_TRUE((traits::is_convertible_unit<astronicalUnits, meters>::value));
-  EXPECT_TRUE((traits::is_convertible_unit<parsecs, meters>::value));
-  EXPECT_TRUE((traits::is_convertible_unit<years, weeks>::value));
-
-  EXPECT_FALSE((traits::is_convertible_unit<meters, seconds>::value));
-  EXPECT_FALSE((traits::is_convertible_unit<seconds, meters>::value));
-  EXPECT_FALSE((traits::is_convertible_unit<years, meters>::value));
-}
-
-TEST_F(TypeTraits, inverse) {
-  double test;
-
-  using htz = inverse<seconds>;
-  bool shouldBeTrue = std::is_same<htz, hertz>::value;
-  EXPECT_TRUE(shouldBeTrue);
-
-  test = convert<inverse<celsius>, inverse<fahrenheit>>(1.0);
-  EXPECT_NEAR(5.0 / 9.0, test, 5.0e-5);
-
-  test = convert<inverse<kelvin>, inverse<fahrenheit>>(6.0);
-  EXPECT_NEAR(10.0 / 3.0, test, 5.0e-5);
-}
-
-TEST_F(TypeTraits, base_unit_of) {
-  using base = traits::base_unit_of<years>;
-  bool shouldBeTrue = std::is_same<base, category::time_unit>::value;
-
-  EXPECT_TRUE(shouldBeTrue);
-}
-
-TEST_F(TypeTraits, has_linear_scale) {
-  EXPECT_TRUE((traits::has_linear_scale<scalar_t>::value));
-  EXPECT_TRUE((traits::has_linear_scale<meter_t>::value));
-  EXPECT_TRUE((traits::has_linear_scale<foot_t>::value));
-  EXPECT_TRUE((traits::has_linear_scale<watt_t, scalar_t>::value));
-  EXPECT_TRUE((traits::has_linear_scale<scalar_t, meter_t>::value));
-  EXPECT_TRUE((traits::has_linear_scale<meters_per_second_t>::value));
-  EXPECT_FALSE((traits::has_linear_scale<dB_t>::value));
-  EXPECT_FALSE((traits::has_linear_scale<dB_t, meters_per_second_t>::value));
-}
-
-TEST_F(TypeTraits, has_decibel_scale) {
-  EXPECT_FALSE((traits::has_decibel_scale<scalar_t>::value));
-  EXPECT_FALSE((traits::has_decibel_scale<meter_t>::value));
-  EXPECT_FALSE((traits::has_decibel_scale<foot_t>::value));
-  EXPECT_TRUE((traits::has_decibel_scale<dB_t>::value));
-  EXPECT_TRUE((traits::has_decibel_scale<dBW_t>::value));
-
-  EXPECT_TRUE((traits::has_decibel_scale<dBW_t, dB_t>::value));
-  EXPECT_TRUE((traits::has_decibel_scale<dBW_t, dBm_t>::value));
-  EXPECT_TRUE((traits::has_decibel_scale<dB_t, dB_t>::value));
-  EXPECT_TRUE((traits::has_decibel_scale<dB_t, dB_t, dB_t>::value));
-  EXPECT_FALSE((traits::has_decibel_scale<dB_t, dB_t, meter_t>::value));
-  EXPECT_FALSE((traits::has_decibel_scale<meter_t, dB_t>::value));
-}
-
-TEST_F(TypeTraits, is_same_scale) {
-  EXPECT_TRUE((traits::is_same_scale<scalar_t, dimensionless_t>::value));
-  EXPECT_TRUE((traits::is_same_scale<dB_t, dBW_t>::value));
-  EXPECT_FALSE((traits::is_same_scale<dB_t, scalar_t>::value));
-}
-
-TEST_F(TypeTraits, is_dimensionless_unit) {
-  EXPECT_TRUE((traits::is_dimensionless_unit<scalar_t>::value));
-  EXPECT_TRUE((traits::is_dimensionless_unit<const scalar_t>::value));
-  EXPECT_TRUE((traits::is_dimensionless_unit<const scalar_t&>::value));
-  EXPECT_TRUE((traits::is_dimensionless_unit<dimensionless_t>::value));
-  EXPECT_TRUE((traits::is_dimensionless_unit<dB_t>::value));
-  EXPECT_TRUE((traits::is_dimensionless_unit<dB_t, scalar_t>::value));
-  EXPECT_TRUE((traits::is_dimensionless_unit<ppm_t>::value));
-  EXPECT_FALSE((traits::is_dimensionless_unit<meter_t>::value));
-  EXPECT_FALSE((traits::is_dimensionless_unit<dBW_t>::value));
-  EXPECT_FALSE((traits::is_dimensionless_unit<dBW_t, scalar_t>::value));
-}
-
-TEST_F(TypeTraits, is_length_unit) {
-  EXPECT_TRUE((traits::is_length_unit<meter>::value));
-  EXPECT_TRUE((traits::is_length_unit<cubit>::value));
-  EXPECT_FALSE((traits::is_length_unit<year>::value));
-  EXPECT_FALSE((traits::is_length_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_length_unit<meter_t>::value));
-  EXPECT_TRUE((traits::is_length_unit<const meter_t>::value));
-  EXPECT_TRUE((traits::is_length_unit<const meter_t&>::value));
-  EXPECT_TRUE((traits::is_length_unit<cubit_t>::value));
-  EXPECT_FALSE((traits::is_length_unit<year_t>::value));
-  EXPECT_TRUE((traits::is_length_unit<meter_t, cubit_t>::value));
-  EXPECT_FALSE((traits::is_length_unit<meter_t, year_t>::value));
-}
-
-TEST_F(TypeTraits, is_mass_unit) {
-  EXPECT_TRUE((traits::is_mass_unit<kilogram>::value));
-  EXPECT_TRUE((traits::is_mass_unit<stone>::value));
-  EXPECT_FALSE((traits::is_mass_unit<meter>::value));
-  EXPECT_FALSE((traits::is_mass_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_mass_unit<kilogram_t>::value));
-  EXPECT_TRUE((traits::is_mass_unit<const kilogram_t>::value));
-  EXPECT_TRUE((traits::is_mass_unit<const kilogram_t&>::value));
-  EXPECT_TRUE((traits::is_mass_unit<stone_t>::value));
-  EXPECT_FALSE((traits::is_mass_unit<meter_t>::value));
-  EXPECT_TRUE((traits::is_mass_unit<kilogram_t, stone_t>::value));
-  EXPECT_FALSE((traits::is_mass_unit<kilogram_t, meter_t>::value));
-}
-
-TEST_F(TypeTraits, is_time_unit) {
-  EXPECT_TRUE((traits::is_time_unit<second>::value));
-  EXPECT_TRUE((traits::is_time_unit<year>::value));
-  EXPECT_FALSE((traits::is_time_unit<meter>::value));
-  EXPECT_FALSE((traits::is_time_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_time_unit<second_t>::value));
-  EXPECT_TRUE((traits::is_time_unit<const second_t>::value));
-  EXPECT_TRUE((traits::is_time_unit<const second_t&>::value));
-  EXPECT_TRUE((traits::is_time_unit<year_t>::value));
-  EXPECT_FALSE((traits::is_time_unit<meter_t>::value));
-  EXPECT_TRUE((traits::is_time_unit<second_t, year_t>::value));
-  EXPECT_FALSE((traits::is_time_unit<second_t, meter_t>::value));
-}
-
-TEST_F(TypeTraits, is_angle_unit) {
-  EXPECT_TRUE((traits::is_angle_unit<angle::radian>::value));
-  EXPECT_TRUE((traits::is_angle_unit<angle::degree>::value));
-  EXPECT_FALSE((traits::is_angle_unit<watt>::value));
-  EXPECT_FALSE((traits::is_angle_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_angle_unit<angle::radian_t>::value));
-  EXPECT_TRUE((traits::is_angle_unit<const angle::radian_t>::value));
-  EXPECT_TRUE((traits::is_angle_unit<const angle::radian_t&>::value));
-  EXPECT_TRUE((traits::is_angle_unit<angle::degree_t>::value));
-  EXPECT_FALSE((traits::is_angle_unit<watt_t>::value));
-  EXPECT_TRUE((traits::is_angle_unit<angle::radian_t, angle::degree_t>::value));
-  EXPECT_FALSE((traits::is_angle_unit<angle::radian_t, watt_t>::value));
-}
-
-TEST_F(TypeTraits, is_current_unit) {
-  EXPECT_TRUE((traits::is_current_unit<current::ampere>::value));
-  EXPECT_FALSE((traits::is_current_unit<volt>::value));
-  EXPECT_FALSE((traits::is_current_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_current_unit<current::ampere_t>::value));
-  EXPECT_TRUE((traits::is_current_unit<const current::ampere_t>::value));
-  EXPECT_TRUE((traits::is_current_unit<const current::ampere_t&>::value));
-  EXPECT_FALSE((traits::is_current_unit<volt_t>::value));
-  EXPECT_TRUE((traits::is_current_unit<current::ampere_t,
-                                       current::milliampere_t>::value));
-  EXPECT_FALSE((traits::is_current_unit<current::ampere_t, volt_t>::value));
-}
-
-TEST_F(TypeTraits, is_temperature_unit) {
-  EXPECT_TRUE((traits::is_temperature_unit<fahrenheit>::value));
-  EXPECT_TRUE((traits::is_temperature_unit<kelvin>::value));
-  EXPECT_FALSE((traits::is_temperature_unit<cubit>::value));
-  EXPECT_FALSE((traits::is_temperature_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_temperature_unit<fahrenheit_t>::value));
-  EXPECT_TRUE((traits::is_temperature_unit<const fahrenheit_t>::value));
-  EXPECT_TRUE((traits::is_temperature_unit<const fahrenheit_t&>::value));
-  EXPECT_TRUE((traits::is_temperature_unit<kelvin_t>::value));
-  EXPECT_FALSE((traits::is_temperature_unit<cubit_t>::value));
-  EXPECT_TRUE((traits::is_temperature_unit<fahrenheit_t, kelvin_t>::value));
-  EXPECT_FALSE((traits::is_temperature_unit<cubit_t, fahrenheit_t>::value));
-}
-
-TEST_F(TypeTraits, is_substance_unit) {
-  EXPECT_TRUE((traits::is_substance_unit<substance::mol>::value));
-  EXPECT_FALSE((traits::is_substance_unit<year>::value));
-  EXPECT_FALSE((traits::is_substance_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_substance_unit<substance::mole_t>::value));
-  EXPECT_TRUE((traits::is_substance_unit<const substance::mole_t>::value));
-  EXPECT_TRUE((traits::is_substance_unit<const substance::mole_t&>::value));
-  EXPECT_FALSE((traits::is_substance_unit<year_t>::value));
-  EXPECT_TRUE(
-      (traits::is_substance_unit<substance::mole_t, substance::mole_t>::value));
-  EXPECT_FALSE((traits::is_substance_unit<year_t, substance::mole_t>::value));
-}
-
-TEST_F(TypeTraits, is_luminous_intensity_unit) {
-  EXPECT_TRUE((traits::is_luminous_intensity_unit<candela>::value));
-  EXPECT_FALSE(
-      (traits::is_luminous_intensity_unit<units::radiation::rad>::value));
-  EXPECT_FALSE((traits::is_luminous_intensity_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_luminous_intensity_unit<candela_t>::value));
-  EXPECT_TRUE((traits::is_luminous_intensity_unit<const candela_t>::value));
-  EXPECT_TRUE((traits::is_luminous_intensity_unit<const candela_t&>::value));
-  EXPECT_FALSE((traits::is_luminous_intensity_unit<rad_t>::value));
-  EXPECT_TRUE(
-      (traits::is_luminous_intensity_unit<candela_t, candela_t>::value));
-  EXPECT_FALSE((traits::is_luminous_intensity_unit<rad_t, candela_t>::value));
-}
-
-TEST_F(TypeTraits, is_solid_angle_unit) {
-  EXPECT_TRUE((traits::is_solid_angle_unit<steradian>::value));
-  EXPECT_TRUE((traits::is_solid_angle_unit<degree_squared>::value));
-  EXPECT_FALSE((traits::is_solid_angle_unit<angle::degree>::value));
-  EXPECT_FALSE((traits::is_solid_angle_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_solid_angle_unit<steradian_t>::value));
-  EXPECT_TRUE((traits::is_solid_angle_unit<const steradian_t>::value));
-  EXPECT_TRUE((traits::is_solid_angle_unit<const degree_squared_t&>::value));
-  EXPECT_FALSE((traits::is_solid_angle_unit<angle::degree_t>::value));
-  EXPECT_TRUE(
-      (traits::is_solid_angle_unit<degree_squared_t, steradian_t>::value));
-  EXPECT_FALSE(
-      (traits::is_solid_angle_unit<angle::degree_t, steradian_t>::value));
-}
-
-TEST_F(TypeTraits, is_frequency_unit) {
-  EXPECT_TRUE((traits::is_frequency_unit<hertz>::value));
-  EXPECT_FALSE((traits::is_frequency_unit<second>::value));
-  EXPECT_FALSE((traits::is_frequency_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_frequency_unit<hertz_t>::value));
-  EXPECT_TRUE((traits::is_frequency_unit<const hertz_t>::value));
-  EXPECT_TRUE((traits::is_frequency_unit<const hertz_t&>::value));
-  EXPECT_FALSE((traits::is_frequency_unit<second_t>::value));
-  EXPECT_TRUE((traits::is_frequency_unit<const hertz_t&, gigahertz_t>::value));
-  EXPECT_FALSE((traits::is_frequency_unit<second_t, hertz_t>::value));
-}
-
-TEST_F(TypeTraits, is_velocity_unit) {
-  EXPECT_TRUE((traits::is_velocity_unit<meters_per_second>::value));
-  EXPECT_TRUE((traits::is_velocity_unit<miles_per_hour>::value));
-  EXPECT_FALSE((traits::is_velocity_unit<meters_per_second_squared>::value));
-  EXPECT_FALSE((traits::is_velocity_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_velocity_unit<meters_per_second_t>::value));
-  EXPECT_TRUE((traits::is_velocity_unit<const meters_per_second_t>::value));
-  EXPECT_TRUE((traits::is_velocity_unit<const meters_per_second_t&>::value));
-  EXPECT_TRUE((traits::is_velocity_unit<miles_per_hour_t>::value));
-  EXPECT_FALSE((traits::is_velocity_unit<meters_per_second_squared_t>::value));
-  EXPECT_TRUE(
-      (traits::is_velocity_unit<miles_per_hour_t, meters_per_second_t>::value));
-  EXPECT_FALSE((traits::is_velocity_unit<meters_per_second_squared_t,
-                                         meters_per_second_t>::value));
-}
-
-TEST_F(TypeTraits, is_acceleration_unit) {
-  EXPECT_TRUE((traits::is_acceleration_unit<meters_per_second_squared>::value));
-  EXPECT_TRUE(
-      (traits::is_acceleration_unit<acceleration::standard_gravity>::value));
-  EXPECT_FALSE((traits::is_acceleration_unit<inch>::value));
-  EXPECT_FALSE((traits::is_acceleration_unit<double>::value));
-
-  EXPECT_TRUE(
-      (traits::is_acceleration_unit<meters_per_second_squared_t>::value));
-  EXPECT_TRUE(
-      (traits::is_acceleration_unit<const meters_per_second_squared_t>::value));
-  EXPECT_TRUE((
-      traits::is_acceleration_unit<const meters_per_second_squared_t&>::value));
-  EXPECT_TRUE((traits::is_acceleration_unit<standard_gravity_t>::value));
-  EXPECT_FALSE((traits::is_acceleration_unit<inch_t>::value));
-  EXPECT_TRUE(
-      (traits::is_acceleration_unit<standard_gravity_t,
-                                    meters_per_second_squared_t>::value));
-  EXPECT_FALSE(
-      (traits::is_acceleration_unit<inch_t,
-                                    meters_per_second_squared_t>::value));
-}
-
-TEST_F(TypeTraits, is_force_unit) {
-  EXPECT_TRUE((traits::is_force_unit<units::force::newton>::value));
-  EXPECT_TRUE((traits::is_force_unit<units::force::dynes>::value));
-  EXPECT_FALSE((traits::is_force_unit<meter>::value));
-  EXPECT_FALSE((traits::is_force_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_force_unit<units::force::newton_t>::value));
-  EXPECT_TRUE((traits::is_force_unit<const units::force::newton_t>::value));
-  EXPECT_TRUE((traits::is_force_unit<const units::force::newton_t&>::value));
-  EXPECT_TRUE((traits::is_force_unit<units::force::dyne_t>::value));
-  EXPECT_FALSE((traits::is_force_unit<watt_t>::value));
-  EXPECT_TRUE((traits::is_force_unit<units::force::dyne_t,
-                                     units::force::newton_t>::value));
-  EXPECT_FALSE((traits::is_force_unit<watt_t, units::force::newton_t>::value));
-}
-
-TEST_F(TypeTraits, is_pressure_unit) {
-  EXPECT_TRUE((traits::is_pressure_unit<pressure::pascals>::value));
-  EXPECT_TRUE((traits::is_pressure_unit<atmosphere>::value));
-  EXPECT_FALSE((traits::is_pressure_unit<year>::value));
-  EXPECT_FALSE((traits::is_pressure_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_pressure_unit<pascal_t>::value));
-  EXPECT_TRUE((traits::is_pressure_unit<const pascal_t>::value));
-  EXPECT_TRUE((traits::is_pressure_unit<const pascal_t&>::value));
-  EXPECT_TRUE((traits::is_pressure_unit<atmosphere_t>::value));
-  EXPECT_FALSE((traits::is_pressure_unit<year_t>::value));
-  EXPECT_TRUE(
-      (traits::is_pressure_unit<atmosphere_t, pressure::pascal_t>::value));
-  EXPECT_FALSE((traits::is_pressure_unit<year_t, pressure::pascal_t>::value));
-}
-
-TEST_F(TypeTraits, is_charge_unit) {
-  EXPECT_TRUE((traits::is_charge_unit<coulomb>::value));
-  EXPECT_FALSE((traits::is_charge_unit<watt>::value));
-  EXPECT_FALSE((traits::is_charge_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_charge_unit<coulomb_t>::value));
-  EXPECT_TRUE((traits::is_charge_unit<const coulomb_t>::value));
-  EXPECT_TRUE((traits::is_charge_unit<const coulomb_t&>::value));
-  EXPECT_FALSE((traits::is_charge_unit<watt_t>::value));
-  EXPECT_TRUE((traits::is_charge_unit<const coulomb_t&, coulomb_t>::value));
-  EXPECT_FALSE((traits::is_charge_unit<watt_t, coulomb_t>::value));
-}
-
-TEST_F(TypeTraits, is_energy_unit) {
-  EXPECT_TRUE((traits::is_energy_unit<joule>::value));
-  EXPECT_TRUE((traits::is_energy_unit<calorie>::value));
-  EXPECT_FALSE((traits::is_energy_unit<watt>::value));
-  EXPECT_FALSE((traits::is_energy_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_energy_unit<joule_t>::value));
-  EXPECT_TRUE((traits::is_energy_unit<const joule_t>::value));
-  EXPECT_TRUE((traits::is_energy_unit<const joule_t&>::value));
-  EXPECT_TRUE((traits::is_energy_unit<calorie_t>::value));
-  EXPECT_FALSE((traits::is_energy_unit<watt_t>::value));
-  EXPECT_TRUE((traits::is_energy_unit<calorie_t, joule_t>::value));
-  EXPECT_FALSE((traits::is_energy_unit<watt_t, joule_t>::value));
-}
-
-TEST_F(TypeTraits, is_power_unit) {
-  EXPECT_TRUE((traits::is_power_unit<watt>::value));
-  EXPECT_FALSE((traits::is_power_unit<henry>::value));
-  EXPECT_FALSE((traits::is_power_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_power_unit<watt_t>::value));
-  EXPECT_TRUE((traits::is_power_unit<const watt_t>::value));
-  EXPECT_TRUE((traits::is_power_unit<const watt_t&>::value));
-  EXPECT_FALSE((traits::is_power_unit<henry_t>::value));
-  EXPECT_TRUE((traits::is_power_unit<const watt_t&, watt_t>::value));
-  EXPECT_FALSE((traits::is_power_unit<henry_t, watt_t>::value));
-}
-
-TEST_F(TypeTraits, is_voltage_unit) {
-  EXPECT_TRUE((traits::is_voltage_unit<volt>::value));
-  EXPECT_FALSE((traits::is_voltage_unit<henry>::value));
-  EXPECT_FALSE((traits::is_voltage_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_voltage_unit<volt_t>::value));
-  EXPECT_TRUE((traits::is_voltage_unit<const volt_t>::value));
-  EXPECT_TRUE((traits::is_voltage_unit<const volt_t&>::value));
-  EXPECT_FALSE((traits::is_voltage_unit<henry_t>::value));
-  EXPECT_TRUE((traits::is_voltage_unit<const volt_t&, volt_t>::value));
-  EXPECT_FALSE((traits::is_voltage_unit<henry_t, volt_t>::value));
-}
-
-TEST_F(TypeTraits, is_capacitance_unit) {
-  EXPECT_TRUE((traits::is_capacitance_unit<farad>::value));
-  EXPECT_FALSE((traits::is_capacitance_unit<ohm>::value));
-  EXPECT_FALSE((traits::is_capacitance_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_capacitance_unit<farad_t>::value));
-  EXPECT_TRUE((traits::is_capacitance_unit<const farad_t>::value));
-  EXPECT_TRUE((traits::is_capacitance_unit<const farad_t&>::value));
-  EXPECT_FALSE((traits::is_capacitance_unit<ohm_t>::value));
-  EXPECT_TRUE(
-      (traits::is_capacitance_unit<const farad_t&, millifarad_t>::value));
-  EXPECT_FALSE((traits::is_capacitance_unit<ohm_t, farad_t>::value));
-}
-
-TEST_F(TypeTraits, is_impedance_unit) {
-  EXPECT_TRUE((traits::is_impedance_unit<ohm>::value));
-  EXPECT_FALSE((traits::is_impedance_unit<farad>::value));
-  EXPECT_FALSE((traits::is_impedance_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_impedance_unit<ohm_t>::value));
-  EXPECT_TRUE((traits::is_impedance_unit<const ohm_t>::value));
-  EXPECT_TRUE((traits::is_impedance_unit<const ohm_t&>::value));
-  EXPECT_FALSE((traits::is_impedance_unit<farad_t>::value));
-  EXPECT_TRUE((traits::is_impedance_unit<const ohm_t&, milliohm_t>::value));
-  EXPECT_FALSE((traits::is_impedance_unit<farad_t, ohm_t>::value));
-}
-
-TEST_F(TypeTraits, is_conductance_unit) {
-  EXPECT_TRUE((traits::is_conductance_unit<siemens>::value));
-  EXPECT_FALSE((traits::is_conductance_unit<volt>::value));
-  EXPECT_FALSE((traits::is_conductance_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_conductance_unit<siemens_t>::value));
-  EXPECT_TRUE((traits::is_conductance_unit<const siemens_t>::value));
-  EXPECT_TRUE((traits::is_conductance_unit<const siemens_t&>::value));
-  EXPECT_FALSE((traits::is_conductance_unit<volt_t>::value));
-  EXPECT_TRUE(
-      (traits::is_conductance_unit<const siemens_t&, millisiemens_t>::value));
-  EXPECT_FALSE((traits::is_conductance_unit<volt_t, siemens_t>::value));
-}
-
-TEST_F(TypeTraits, is_magnetic_flux_unit) {
-  EXPECT_TRUE((traits::is_magnetic_flux_unit<weber>::value));
-  EXPECT_TRUE((traits::is_magnetic_flux_unit<maxwell>::value));
-  EXPECT_FALSE((traits::is_magnetic_flux_unit<inch>::value));
-  EXPECT_FALSE((traits::is_magnetic_flux_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_magnetic_flux_unit<weber_t>::value));
-  EXPECT_TRUE((traits::is_magnetic_flux_unit<const weber_t>::value));
-  EXPECT_TRUE((traits::is_magnetic_flux_unit<const weber_t&>::value));
-  EXPECT_TRUE((traits::is_magnetic_flux_unit<maxwell_t>::value));
-  EXPECT_FALSE((traits::is_magnetic_flux_unit<inch_t>::value));
-  EXPECT_TRUE((traits::is_magnetic_flux_unit<maxwell_t, weber_t>::value));
-  EXPECT_FALSE((traits::is_magnetic_flux_unit<inch_t, weber_t>::value));
-}
-
-TEST_F(TypeTraits, is_magnetic_field_strength_unit) {
-  EXPECT_TRUE((traits::is_magnetic_field_strength_unit<
-               units::magnetic_field_strength::tesla>::value));
-  EXPECT_TRUE((traits::is_magnetic_field_strength_unit<gauss>::value));
-  EXPECT_FALSE((traits::is_magnetic_field_strength_unit<volt>::value));
-  EXPECT_FALSE((traits::is_magnetic_field_strength_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_magnetic_field_strength_unit<tesla_t>::value));
-  EXPECT_TRUE((traits::is_magnetic_field_strength_unit<const tesla_t>::value));
-  EXPECT_TRUE((traits::is_magnetic_field_strength_unit<const tesla_t&>::value));
-  EXPECT_TRUE((traits::is_magnetic_field_strength_unit<gauss_t>::value));
-  EXPECT_FALSE((traits::is_magnetic_field_strength_unit<volt_t>::value));
-  EXPECT_TRUE(
-      (traits::is_magnetic_field_strength_unit<gauss_t, tesla_t>::value));
-  EXPECT_FALSE(
-      (traits::is_magnetic_field_strength_unit<volt_t, tesla_t>::value));
-}
-
-TEST_F(TypeTraits, is_inductance_unit) {
-  EXPECT_TRUE((traits::is_inductance_unit<henry>::value));
-  EXPECT_FALSE((traits::is_inductance_unit<farad>::value));
-  EXPECT_FALSE((traits::is_inductance_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_inductance_unit<henry_t>::value));
-  EXPECT_TRUE((traits::is_inductance_unit<const henry_t>::value));
-  EXPECT_TRUE((traits::is_inductance_unit<const henry_t&>::value));
-  EXPECT_FALSE((traits::is_inductance_unit<farad_t>::value));
-  EXPECT_TRUE(
-      (traits::is_inductance_unit<const henry_t&, millihenry_t>::value));
-  EXPECT_FALSE((traits::is_inductance_unit<farad_t, henry_t>::value));
-}
-
-TEST_F(TypeTraits, is_luminous_flux_unit) {
-  EXPECT_TRUE((traits::is_luminous_flux_unit<lumen>::value));
-  EXPECT_FALSE((traits::is_luminous_flux_unit<pound>::value));
-  EXPECT_FALSE((traits::is_luminous_flux_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_luminous_flux_unit<lumen_t>::value));
-  EXPECT_TRUE((traits::is_luminous_flux_unit<const lumen_t>::value));
-  EXPECT_TRUE((traits::is_luminous_flux_unit<const lumen_t&>::value));
-  EXPECT_FALSE((traits::is_luminous_flux_unit<pound_t>::value));
-  EXPECT_TRUE(
-      (traits::is_luminous_flux_unit<const lumen_t&, millilumen_t>::value));
-  EXPECT_FALSE((traits::is_luminous_flux_unit<pound_t, lumen_t>::value));
-}
-
-TEST_F(TypeTraits, is_illuminance_unit) {
-  EXPECT_TRUE((traits::is_illuminance_unit<illuminance::footcandle>::value));
-  EXPECT_TRUE((traits::is_illuminance_unit<illuminance::lux>::value));
-  EXPECT_FALSE((traits::is_illuminance_unit<meter>::value));
-  EXPECT_FALSE((traits::is_illuminance_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_illuminance_unit<footcandle_t>::value));
-  EXPECT_TRUE((traits::is_illuminance_unit<const footcandle_t>::value));
-  EXPECT_TRUE((traits::is_illuminance_unit<const footcandle_t&>::value));
-  EXPECT_TRUE((traits::is_illuminance_unit<lux_t>::value));
-  EXPECT_FALSE((traits::is_illuminance_unit<meter_t>::value));
-  EXPECT_TRUE((traits::is_illuminance_unit<lux_t, footcandle_t>::value));
-  EXPECT_FALSE((traits::is_illuminance_unit<meter_t, footcandle_t>::value));
-}
-
-TEST_F(TypeTraits, is_radioactivity_unit) {
-  EXPECT_TRUE((traits::is_radioactivity_unit<becquerel>::value));
-  EXPECT_FALSE((traits::is_radioactivity_unit<year>::value));
-  EXPECT_FALSE((traits::is_radioactivity_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_radioactivity_unit<becquerel_t>::value));
-  EXPECT_TRUE((traits::is_radioactivity_unit<const becquerel_t>::value));
-  EXPECT_TRUE((traits::is_radioactivity_unit<const becquerel_t&>::value));
-  EXPECT_FALSE((traits::is_radioactivity_unit<year_t>::value));
-  EXPECT_TRUE((traits::is_radioactivity_unit<const becquerel_t&,
-                                             millibecquerel_t>::value));
-  EXPECT_FALSE((traits::is_radioactivity_unit<year_t, becquerel_t>::value));
-}
-
-TEST_F(TypeTraits, is_torque_unit) {
-  EXPECT_TRUE((traits::is_torque_unit<torque::newton_meter>::value));
-  EXPECT_TRUE((traits::is_torque_unit<torque::foot_pound>::value));
-  EXPECT_FALSE((traits::is_torque_unit<volume::cubic_meter>::value));
-  EXPECT_FALSE((traits::is_torque_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_torque_unit<torque::newton_meter_t>::value));
-  EXPECT_TRUE((traits::is_torque_unit<const torque::newton_meter_t>::value));
-  EXPECT_TRUE((traits::is_torque_unit<const torque::newton_meter_t&>::value));
-  EXPECT_TRUE((traits::is_torque_unit<torque::foot_pound_t>::value));
-  EXPECT_FALSE((traits::is_torque_unit<volume::cubic_meter_t>::value));
-  EXPECT_TRUE((traits::is_torque_unit<torque::foot_pound_t,
-                                      torque::newton_meter_t>::value));
-  EXPECT_FALSE((traits::is_torque_unit<volume::cubic_meter_t,
-                                       torque::newton_meter_t>::value));
-}
-
-TEST_F(TypeTraits, is_area_unit) {
-  EXPECT_TRUE((traits::is_area_unit<square_meter>::value));
-  EXPECT_TRUE((traits::is_area_unit<hectare>::value));
-  EXPECT_FALSE((traits::is_area_unit<astronicalUnit>::value));
-  EXPECT_FALSE((traits::is_area_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_area_unit<square_meter_t>::value));
-  EXPECT_TRUE((traits::is_area_unit<const square_meter_t>::value));
-  EXPECT_TRUE((traits::is_area_unit<const square_meter_t&>::value));
-  EXPECT_TRUE((traits::is_area_unit<hectare_t>::value));
-  EXPECT_FALSE((traits::is_area_unit<astronicalUnit_t>::value));
-  EXPECT_TRUE((traits::is_area_unit<hectare_t, square_meter_t>::value));
-  EXPECT_FALSE((traits::is_area_unit<astronicalUnit_t, square_meter_t>::value));
-}
-
-TEST_F(TypeTraits, is_volume_unit) {
-  EXPECT_TRUE((traits::is_volume_unit<cubic_meter>::value));
-  EXPECT_TRUE((traits::is_volume_unit<cubic_foot>::value));
-  EXPECT_FALSE((traits::is_volume_unit<square_feet>::value));
-  EXPECT_FALSE((traits::is_volume_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_volume_unit<cubic_meter_t>::value));
-  EXPECT_TRUE((traits::is_volume_unit<const cubic_meter_t>::value));
-  EXPECT_TRUE((traits::is_volume_unit<const cubic_meter_t&>::value));
-  EXPECT_TRUE((traits::is_volume_unit<cubic_inch_t>::value));
-  EXPECT_FALSE((traits::is_volume_unit<foot_t>::value));
-  EXPECT_TRUE((traits::is_volume_unit<cubic_inch_t, cubic_meter_t>::value));
-  EXPECT_FALSE((traits::is_volume_unit<foot_t, cubic_meter_t>::value));
-}
-
-TEST_F(TypeTraits, is_density_unit) {
-  EXPECT_TRUE((traits::is_density_unit<kilograms_per_cubic_meter>::value));
-  EXPECT_TRUE((traits::is_density_unit<ounces_per_cubic_foot>::value));
-  EXPECT_FALSE((traits::is_density_unit<year>::value));
-  EXPECT_FALSE((traits::is_density_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_density_unit<kilograms_per_cubic_meter_t>::value));
-  EXPECT_TRUE(
-      (traits::is_density_unit<const kilograms_per_cubic_meter_t>::value));
-  EXPECT_TRUE(
-      (traits::is_density_unit<const kilograms_per_cubic_meter_t&>::value));
-  EXPECT_TRUE((traits::is_density_unit<ounces_per_cubic_foot_t>::value));
-  EXPECT_FALSE((traits::is_density_unit<year_t>::value));
-  EXPECT_TRUE((traits::is_density_unit<ounces_per_cubic_foot_t,
-                                       kilograms_per_cubic_meter_t>::value));
-  EXPECT_FALSE(
-      (traits::is_density_unit<year_t, kilograms_per_cubic_meter_t>::value));
-}
-
-TEST_F(TypeTraits, is_data_unit) {
-  EXPECT_TRUE((traits::is_data_unit<bit>::value));
-  EXPECT_TRUE((traits::is_data_unit<byte>::value));
-  EXPECT_TRUE((traits::is_data_unit<exabit>::value));
-  EXPECT_TRUE((traits::is_data_unit<exabyte>::value));
-  EXPECT_FALSE((traits::is_data_unit<year>::value));
-  EXPECT_FALSE((traits::is_data_unit<double>::value));
-
-  EXPECT_TRUE((traits::is_data_unit<bit_t>::value));
-  EXPECT_TRUE((traits::is_data_unit<const bit_t>::value));
-  EXPECT_TRUE((traits::is_data_unit<const bit_t&>::value));
-  EXPECT_TRUE((traits::is_data_unit<byte_t>::value));
-  EXPECT_FALSE((traits::is_data_unit<year_t>::value));
-  EXPECT_TRUE((traits::is_data_unit<bit_t, byte_t>::value));
-  EXPECT_FALSE((traits::is_data_unit<year_t, byte_t>::value));
-}
-
-TEST_F(TypeTraits, is_data_transfer_rate_unit) {
-  EXPECT_TRUE((traits::is_data_transfer_rate_unit<Gbps>::value));
-  EXPECT_TRUE((traits::is_data_transfer_rate_unit<GBps>::value));
-  EXPECT_FALSE((traits::is_data_transfer_rate_unit<year>::value));
-  EXPECT_FALSE((traits::is_data_transfer_rate_unit<double>::value));
-
-  EXPECT_TRUE(
-      (traits::is_data_transfer_rate_unit<gigabits_per_second_t>::value));
-  EXPECT_TRUE((
-      traits::is_data_transfer_rate_unit<const gigabytes_per_second_t>::value));
-  EXPECT_TRUE((traits::is_data_transfer_rate_unit<
-               const gigabytes_per_second_t&>::value));
-  EXPECT_TRUE(
-      (traits::is_data_transfer_rate_unit<gigabytes_per_second_t>::value));
-  EXPECT_FALSE((traits::is_data_transfer_rate_unit<year_t>::value));
-  EXPECT_TRUE(
-      (traits::is_data_transfer_rate_unit<gigabits_per_second_t,
-                                          gigabytes_per_second_t>::value));
-  EXPECT_FALSE(
-      (traits::is_data_transfer_rate_unit<year_t,
-                                          gigabytes_per_second_t>::value));
-}
-
-TEST_F(UnitManipulators, squared) {
-  double test;
-
-  test = convert<squared<meters>, square_feet>(0.092903);
-  EXPECT_NEAR(0.99999956944, test, 5.0e-12);
-
-  using scalar_2 = squared<scalar>;  // this is actually nonsensical, and should
-                                     // also result in a scalar.
-  bool isSame =
-      std::is_same<typename std::decay<scalar_t>::type,
-                   typename std::decay<unit_t<scalar_2>>::type>::value;
-  EXPECT_TRUE(isSame);
-}
-
-TEST_F(UnitManipulators, cubed) {
-  double test;
-
-  test = convert<cubed<meters>, cubic_feet>(0.0283168);
-  EXPECT_NEAR(0.999998354619, test, 5.0e-13);
-}
-
-TEST_F(UnitManipulators, square_root) {
-  double test;
-
-  test = convert<square_root<square_kilometer>, meter>(1.0);
-  EXPECT_TRUE((traits::is_convertible_unit<
-               typename std::decay<square_root<square_kilometer>>::type,
-               kilometer>::value));
-  EXPECT_NEAR(1000.0, test, 5.0e-13);
-}
-
-TEST_F(UnitManipulators, compound_unit) {
-  using acceleration1 = unit<std::ratio<1>, category::acceleration_unit>;
-  using acceleration2 =
-      compound_unit<meters, inverse<seconds>, inverse<seconds>>;
-  using acceleration3 =
-      unit<std::ratio<1>,
-           base_unit<std::ratio<1>, std::ratio<0>, std::ratio<-2>>>;
-  using acceleration4 = compound_unit<meters, inverse<squared<seconds>>>;
-  using acceleration5 = compound_unit<meters, squared<inverse<seconds>>>;
-
-  bool areSame12 = std::is_same<acceleration1, acceleration2>::value;
-  bool areSame23 = std::is_same<acceleration2, acceleration3>::value;
-  bool areSame34 = std::is_same<acceleration3, acceleration4>::value;
-  bool areSame45 = std::is_same<acceleration4, acceleration5>::value;
-
-  EXPECT_TRUE(areSame12);
-  EXPECT_TRUE(areSame23);
-  EXPECT_TRUE(areSame34);
-  EXPECT_TRUE(areSame45);
-
-  // test that thing with translations still compile
-  using arbitrary1 = compound_unit<meters, inverse<celsius>>;
-  using arbitrary2 = compound_unit<meters, celsius>;
-  using arbitrary3 = compound_unit<arbitrary1, arbitrary2>;
-  EXPECT_TRUE((std::is_same<square_meters, arbitrary3>::value));
-}
-
-TEST_F(UnitManipulators, dimensionalAnalysis) {
-  // these look like 'compound units', but the dimensional analysis can be
-  // REALLY handy if the unit types aren't know (i.e. they themselves are
-  // template parameters), as you can get the resulting unit of the operation.
-
-  using velocity = units::detail::unit_divide<meters, second>;
-  bool shouldBeTrue = std::is_same<meters_per_second, velocity>::value;
-  EXPECT_TRUE(shouldBeTrue);
-
-  using acceleration1 = unit<std::ratio<1>, category::acceleration_unit>;
-  using acceleration2 = units::detail::unit_divide<
-      meters, units::detail::unit_multiply<seconds, seconds>>;
-  shouldBeTrue = std::is_same<acceleration1, acceleration2>::value;
-  EXPECT_TRUE(shouldBeTrue);
-}
-
-#ifdef _MSC_VER
-#if (_MSC_VER >= 1900)
-TEST_F(UnitContainer, trivial) {
-  EXPECT_TRUE((std::is_trivial<meter_t>::value));
-  EXPECT_TRUE((std::is_trivially_assignable<meter_t, meter_t>::value));
-  EXPECT_TRUE((std::is_trivially_constructible<meter_t>::value));
-  EXPECT_TRUE((std::is_trivially_copy_assignable<meter_t>::value));
-  EXPECT_TRUE((std::is_trivially_copy_constructible<meter_t>::value));
-  EXPECT_TRUE((std::is_trivially_copyable<meter_t>::value));
-  EXPECT_TRUE((std::is_trivially_default_constructible<meter_t>::value));
-  EXPECT_TRUE((std::is_trivially_destructible<meter_t>::value));
-  EXPECT_TRUE((std::is_trivially_move_assignable<meter_t>::value));
-  EXPECT_TRUE((std::is_trivially_move_constructible<meter_t>::value));
-
-  EXPECT_TRUE((std::is_trivial<dB_t>::value));
-  EXPECT_TRUE((std::is_trivially_assignable<dB_t, dB_t>::value));
-  EXPECT_TRUE((std::is_trivially_constructible<dB_t>::value));
-  EXPECT_TRUE((std::is_trivially_copy_assignable<dB_t>::value));
-  EXPECT_TRUE((std::is_trivially_copy_constructible<dB_t>::value));
-  EXPECT_TRUE((std::is_trivially_copyable<dB_t>::value));
-  EXPECT_TRUE((std::is_trivially_default_constructible<dB_t>::value));
-  EXPECT_TRUE((std::is_trivially_destructible<dB_t>::value));
-  EXPECT_TRUE((std::is_trivially_move_assignable<dB_t>::value));
-  EXPECT_TRUE((std::is_trivially_move_constructible<dB_t>::value));
-}
-#endif
-#endif
-
-TEST_F(UnitContainer, has_value_member) {
-  EXPECT_TRUE((traits::has_value_member<linear_scale<double>, double>::value));
-  EXPECT_FALSE((traits::has_value_member<meter, double>::value));
-}
-
-TEST_F(UnitContainer, make_unit) {
-  auto dist = units::make_unit<meter_t>(5);
-  EXPECT_EQ(meter_t(5), dist);
-}
-
-TEST_F(UnitContainer, unitTypeAddition) {
-  // units
-  meter_t a_m(1.0), c_m;
-  foot_t b_ft(3.28084);
-
-  double d = convert<feet, meters>(b_ft());
-  EXPECT_NEAR(1.0, d, 5.0e-5);
-
-  c_m = a_m + b_ft;
-  EXPECT_NEAR(2.0, c_m(), 5.0e-5);
-
-  c_m = b_ft + meter_t(3);
-  EXPECT_NEAR(4.0, c_m(), 5.0e-5);
-
-  auto e_ft = b_ft + meter_t(3);
-  EXPECT_NEAR(13.12336, e_ft(), 5.0e-6);
-
-  // scalar
-  scalar_t sresult = scalar_t(1.0) + scalar_t(1.0);
-  EXPECT_NEAR(2.0, sresult, 5.0e-6);
-
-  sresult = scalar_t(1.0) + 1.0;
-  EXPECT_NEAR(2.0, sresult, 5.0e-6);
-
-  sresult = 1.0 + scalar_t(1.0);
-  EXPECT_NEAR(2.0, sresult, 5.0e-6);
-
-  d = scalar_t(1.0) + scalar_t(1.0);
-  EXPECT_NEAR(2.0, d, 5.0e-6);
-
-  d = scalar_t(1.0) + 1.0;
-  EXPECT_NEAR(2.0, d, 5.0e-6);
-
-  d = 1.0 + scalar_t(1.0);
-  EXPECT_NEAR(2.0, d, 5.0e-6);
-}
-
-TEST_F(UnitContainer, unitTypeUnaryAddition) {
-  meter_t a_m(1.0);
-
-  EXPECT_EQ(++a_m, meter_t(2));
-  EXPECT_EQ(a_m++, meter_t(2));
-  EXPECT_EQ(a_m, meter_t(3));
-  EXPECT_EQ(+a_m, meter_t(3));
-  EXPECT_EQ(a_m, meter_t(3));
-
-  dBW_t b_dBW(1.0);
-
-  EXPECT_EQ(++b_dBW, dBW_t(2));
-  EXPECT_EQ(b_dBW++, dBW_t(2));
-  EXPECT_EQ(b_dBW, dBW_t(3));
-  EXPECT_EQ(+b_dBW, dBW_t(3));
-  EXPECT_EQ(b_dBW, dBW_t(3));
-}
-
-TEST_F(UnitContainer, unitTypeSubtraction) {
-  meter_t a_m(1.0), c_m;
-  foot_t b_ft(3.28084);
-
-  c_m = a_m - b_ft;
-  EXPECT_NEAR(0.0, c_m(), 5.0e-5);
-
-  c_m = b_ft - meter_t(1);
-  EXPECT_NEAR(0.0, c_m(), 5.0e-5);
-
-  auto e_ft = b_ft - meter_t(1);
-  EXPECT_NEAR(0.0, e_ft(), 5.0e-6);
-
-  scalar_t sresult = scalar_t(1.0) - scalar_t(1.0);
-  EXPECT_NEAR(0.0, sresult, 5.0e-6);
-
-  sresult = scalar_t(1.0) - 1.0;
-  EXPECT_NEAR(0.0, sresult, 5.0e-6);
-
-  sresult = 1.0 - scalar_t(1.0);
-  EXPECT_NEAR(0.0, sresult, 5.0e-6);
-
-  double d = scalar_t(1.0) - scalar_t(1.0);
-  EXPECT_NEAR(0.0, d, 5.0e-6);
-
-  d = scalar_t(1.0) - 1.0;
-  EXPECT_NEAR(0.0, d, 5.0e-6);
-
-  d = 1.0 - scalar_t(1.0);
-  EXPECT_NEAR(0.0, d, 5.0e-6);
-}
-
-TEST_F(UnitContainer, unitTypeUnarySubtraction) {
-  meter_t a_m(4.0);
-
-  EXPECT_EQ(--a_m, meter_t(3));
-  EXPECT_EQ(a_m--, meter_t(3));
-  EXPECT_EQ(a_m, meter_t(2));
-  EXPECT_EQ(-a_m, meter_t(-2));
-  EXPECT_EQ(a_m, meter_t(2));
-
-  dBW_t b_dBW(4.0);
-
-  EXPECT_EQ(--b_dBW, dBW_t(3));
-  EXPECT_EQ(b_dBW--, dBW_t(3));
-  EXPECT_EQ(b_dBW, dBW_t(2));
-  EXPECT_EQ(-b_dBW, dBW_t(-2));
-  EXPECT_EQ(b_dBW, dBW_t(2));
-}
-
-TEST_F(UnitContainer, unitTypeMultiplication) {
-  meter_t a_m(1.0), b_m(2.0);
-  foot_t a_ft(3.28084);
-
-  auto c_m2 = a_m * b_m;
-  EXPECT_NEAR(2.0, c_m2(), 5.0e-5);
-
-  c_m2 = b_m * meter_t(2);
-  EXPECT_NEAR(4.0, c_m2(), 5.0e-5);
-
-  c_m2 = b_m * a_ft;
-  EXPECT_NEAR(2.0, c_m2(), 5.0e-5);
-
-  auto c_m = b_m * 2.0;
-  EXPECT_NEAR(4.0, c_m(), 5.0e-5);
-
-  c_m = 2.0 * b_m;
-  EXPECT_NEAR(4.0, c_m(), 5.0e-5);
-
-  double convert = scalar_t(3.14);
-  EXPECT_NEAR(3.14, convert, 5.0e-5);
-
-  scalar_t sresult = scalar_t(5.0) * scalar_t(4.0);
-  EXPECT_NEAR(20.0, sresult(), 5.0e-5);
-
-  sresult = scalar_t(5.0) * 4.0;
-  EXPECT_NEAR(20.0, sresult(), 5.0e-5);
-
-  sresult = 4.0 * scalar_t(5.0);
-  EXPECT_NEAR(20.0, sresult(), 5.0e-5);
-
-  double result = scalar_t(5.0) * scalar_t(4.0);
-  EXPECT_NEAR(20.0, result, 5.0e-5);
-
-  result = scalar_t(5.0) * 4.0;
-  EXPECT_NEAR(20.0, result, 5.0e-5);
-
-  result = 4.0 * scalar_t(5.0);
-  EXPECT_NEAR(20.0, result, 5.0e-5);
-}
-
-TEST_F(UnitContainer, unitTypeMixedUnitMultiplication) {
-  meter_t a_m(1.0);
-  foot_t b_ft(3.28084);
-  unit_t<inverse<meter>> i_m(2.0);
-
-  // resultant unit is square of leftmost unit
-  auto c_m2 = a_m * b_ft;
-  EXPECT_NEAR(1.0, c_m2(), 5.0e-5);
-
-  auto c_ft2 = b_ft * a_m;
-  EXPECT_NEAR(10.7639111056, c_ft2(), 5.0e-7);
-
-  // you can get whatever (compatible) type you want if you ask explicitly
-  square_meter_t d_m2 = b_ft * a_m;
-  EXPECT_NEAR(1.0, d_m2(), 5.0e-5);
-
-  // a unit times a sclar ends up with the same units.
-  meter_t e_m = a_m * scalar_t(3.0);
-  EXPECT_NEAR(3.0, e_m(), 5.0e-5);
-
-  e_m = scalar_t(4.0) * a_m;
-  EXPECT_NEAR(4.0, e_m(), 5.0e-5);
-
-  // unit times its inverse results in a scalar
-  scalar_t s = a_m * i_m;
-  EXPECT_NEAR(2.0, s, 5.0e-5);
-
-  c_m2 = b_ft * meter_t(2);
-  EXPECT_NEAR(2.0, c_m2(), 5.0e-5);
-
-  auto e_ft2 = b_ft * meter_t(3);
-  EXPECT_NEAR(32.2917333168, e_ft2(), 5.0e-6);
-
-  auto mps = meter_t(10.0) * unit_t<inverse<seconds>>(1.0);
-  EXPECT_EQ(mps, meters_per_second_t(10));
-}
-
-TEST_F(UnitContainer, unitTypeScalarMultiplication) {
-  meter_t a_m(1.0);
-
-  auto result_m = scalar_t(3.0) * a_m;
-  EXPECT_NEAR(3.0, result_m(), 5.0e-5);
-
-  result_m = a_m * scalar_t(4.0);
-  EXPECT_NEAR(4.0, result_m(), 5.0e-5);
-
-  result_m = 3.0 * a_m;
-  EXPECT_NEAR(3.0, result_m(), 5.0e-5);
-
-  result_m = a_m * 4.0;
-  EXPECT_NEAR(4.0, result_m(), 5.0e-5);
-
-  bool isSame = std::is_same<decltype(result_m), meter_t>::value;
-  EXPECT_TRUE(isSame);
-}
-
-TEST_F(UnitContainer, unitTypeDivision) {
-  meter_t a_m(1.0), b_m(2.0);
-  foot_t a_ft(3.28084);
-  second_t a_sec(10.0);
-  bool isSame;
-
-  auto c = a_m / a_ft;
-  EXPECT_NEAR(1.0, c, 5.0e-5);
-  isSame = std::is_same<decltype(c), scalar_t>::value;
-  EXPECT_TRUE(isSame);
-
-  c = a_m / b_m;
-  EXPECT_NEAR(0.5, c, 5.0e-5);
-  isSame = std::is_same<decltype(c), scalar_t>::value;
-  EXPECT_TRUE(isSame);
-
-  c = a_ft / a_m;
-  EXPECT_NEAR(1.0, c, 5.0e-5);
-  isSame = std::is_same<decltype(c), scalar_t>::value;
-  EXPECT_TRUE(isSame);
-
-  c = scalar_t(1.0) / 2.0;
-  EXPECT_NEAR(0.5, c, 5.0e-5);
-  isSame = std::is_same<decltype(c), scalar_t>::value;
-  EXPECT_TRUE(isSame);
-
-  c = 1.0 / scalar_t(2.0);
-  EXPECT_NEAR(0.5, c, 5.0e-5);
-  isSame = std::is_same<decltype(c), scalar_t>::value;
-  EXPECT_TRUE(isSame);
-
-  double d = scalar_t(1.0) / 2.0;
-  EXPECT_NEAR(0.5, d, 5.0e-5);
-
-  auto e = a_m / a_sec;
-  EXPECT_NEAR(0.1, e(), 5.0e-5);
-  isSame = std::is_same<decltype(e), meters_per_second_t>::value;
-  EXPECT_TRUE(isSame);
-
-  auto f = a_m / 8.0;
-  EXPECT_NEAR(0.125, f(), 5.0e-5);
-  isSame = std::is_same<decltype(f), meter_t>::value;
-  EXPECT_TRUE(isSame);
-
-  auto g = 4.0 / b_m;
-  EXPECT_NEAR(2.0, g(), 5.0e-5);
-  isSame = std::is_same<decltype(g), unit_t<inverse<meters>>>::value;
-  EXPECT_TRUE(isSame);
-
-  auto mph = mile_t(60.0) / hour_t(1.0);
-  meters_per_second_t mps = mph;
-  EXPECT_NEAR(26.8224, mps(), 5.0e-5);
-}
-
-TEST_F(UnitContainer, compoundAssignmentAddition) {
-  // units
-  meter_t a(0.0);
-  a += meter_t(1.0);
-
-  EXPECT_EQ(meter_t(1.0), a);
-
-  a += foot_t(meter_t(1));
-
-  EXPECT_EQ(meter_t(2.0), a);
-
-  // scalars
-  scalar_t b(0);
-  b += scalar_t(1.0);
-
-  EXPECT_EQ(scalar_t(1.0), b);
-
-  b += 1;
-
-  EXPECT_EQ(scalar_t(2.0), b);
-}
-
-TEST_F(UnitContainer, compoundAssignmentSubtraction) {
-  // units
-  meter_t a(2.0);
-  a -= meter_t(1.0);
-
-  EXPECT_EQ(meter_t(1.0), a);
-
-  a -= foot_t(meter_t(1));
-
-  EXPECT_EQ(meter_t(0.0), a);
-
-  // scalars
-  scalar_t b(2);
-  b -= scalar_t(1.0);
-
-  EXPECT_EQ(scalar_t(1.0), b);
-
-  b -= 1;
-
-  EXPECT_EQ(scalar_t(0), b);
-}
-
-TEST_F(UnitContainer, compoundAssignmentMultiplication) {
-  // units
-  meter_t a(2.0);
-  a *= scalar_t(2.0);
-
-  EXPECT_EQ(meter_t(4.0), a);
-
-  a *= 2.0;
-
-  EXPECT_EQ(meter_t(8.0), a);
-
-  // scalars
-  scalar_t b(2);
-  b *= scalar_t(2.0);
-
-  EXPECT_EQ(scalar_t(4.0), b);
-
-  b *= 2;
-
-  EXPECT_EQ(scalar_t(8.0), b);
-}
-
-TEST_F(UnitContainer, compoundAssignmentDivision) {
-  // units
-  meter_t a(8.0);
-  a /= scalar_t(2.0);
-
-  EXPECT_EQ(meter_t(4.0), a);
-
-  a /= 2.0;
-
-  EXPECT_EQ(meter_t(2.0), a);
-
-  // scalars
-  scalar_t b(8);
-  b /= scalar_t(2.0);
-
-  EXPECT_EQ(scalar_t(4.0), b);
-
-  b /= 2;
-
-  EXPECT_EQ(scalar_t(2.0), b);
-}
-
-TEST_F(UnitContainer, scalarTypeImplicitConversion) {
-  double test = scalar_t(3.0);
-  EXPECT_DOUBLE_EQ(3.0, test);
-
-  scalar_t testS = 3.0;
-  EXPECT_DOUBLE_EQ(3.0, testS);
-
-  scalar_t test3(ppm_t(10));
-  EXPECT_DOUBLE_EQ(0.00001, test3);
-
-  scalar_t test4;
-  test4 = ppm_t(1);
-  EXPECT_DOUBLE_EQ(0.000001, test4);
-}
-
-TEST_F(UnitContainer, valueMethod) {
-  double test = meter_t(3.0).to<double>();
-  EXPECT_DOUBLE_EQ(3.0, test);
-
-  auto test2 = meter_t(4.0).value();
-  EXPECT_DOUBLE_EQ(4.0, test2);
-  EXPECT_TRUE((std::is_same<decltype(test2), double>::value));
-}
-
-TEST_F(UnitContainer, convertMethod) {
-  double test = meter_t(3.0).convert<feet>().to<double>();
-  EXPECT_NEAR(9.84252, test, 5.0e-6);
-}
-
-#ifndef UNIT_LIB_DISABLE_IOSTREAM
-TEST_F(UnitContainer, cout) {
-  testing::internal::CaptureStdout();
-  std::cout << degree_t(349.87);
-  std::string output = testing::internal::GetCapturedStdout();
-  EXPECT_STREQ("349.87 deg", output.c_str());
-
-  testing::internal::CaptureStdout();
-  std::cout << meter_t(1.0);
-  output = testing::internal::GetCapturedStdout();
-  EXPECT_STREQ("1 m", output.c_str());
-
-  testing::internal::CaptureStdout();
-  std::cout << dB_t(31.0);
-  output = testing::internal::GetCapturedStdout();
-  EXPECT_STREQ("31 dB", output.c_str());
-
-  testing::internal::CaptureStdout();
-  std::cout << volt_t(21.79);
-  output = testing::internal::GetCapturedStdout();
-  EXPECT_STREQ("21.79 V", output.c_str());
-
-  testing::internal::CaptureStdout();
-  std::cout << dBW_t(12.0);
-  output = testing::internal::GetCapturedStdout();
-  EXPECT_STREQ("12 dBW", output.c_str());
-
-  testing::internal::CaptureStdout();
-  std::cout << dBm_t(120.0);
-  output = testing::internal::GetCapturedStdout();
-  EXPECT_STREQ("120 dBm", output.c_str());
-
-  testing::internal::CaptureStdout();
-  std::cout << miles_per_hour_t(72.1);
-  output = testing::internal::GetCapturedStdout();
-  EXPECT_STREQ("72.1 mph", output.c_str());
-
-  // undefined unit
-  testing::internal::CaptureStdout();
-  std::cout << units::math::cpow<4>(meter_t(2));
-  output = testing::internal::GetCapturedStdout();
-  EXPECT_STREQ("16 m^4", output.c_str());
-
-  testing::internal::CaptureStdout();
-  std::cout << units::math::cpow<3>(foot_t(2));
-  output = testing::internal::GetCapturedStdout();
-  EXPECT_STREQ("8 cu_ft", output.c_str());
-
-  testing::internal::CaptureStdout();
-  std::cout << std::setprecision(9) << units::math::cpow<4>(foot_t(2));
-  output = testing::internal::GetCapturedStdout();
-  EXPECT_STREQ("0.138095597 m^4", output.c_str());
-
-  // constants
-  testing::internal::CaptureStdout();
-  std::cout << std::setprecision(8) << constants::k_B;
-  output = testing::internal::GetCapturedStdout();
-#if defined(_MSC_VER) && (_MSC_VER <= 1800)
-  EXPECT_STREQ("1.3806485e-023 m^2 kg s^-2 K^-1", output.c_str());
-#else
-  EXPECT_STREQ("1.3806485e-23 m^2 kg s^-2 K^-1", output.c_str());
-#endif
-
-  testing::internal::CaptureStdout();
-  std::cout << std::setprecision(9) << constants::mu_B;
-  output = testing::internal::GetCapturedStdout();
-#if defined(_MSC_VER) && (_MSC_VER <= 1800)
-  EXPECT_STREQ("9.27400999e-024 m^2 A", output.c_str());
-#else
-  EXPECT_STREQ("9.27400999e-24 m^2 A", output.c_str());
-#endif
-
-  testing::internal::CaptureStdout();
-  std::cout << std::setprecision(7) << constants::sigma;
-  output = testing::internal::GetCapturedStdout();
-#if defined(_MSC_VER) && (_MSC_VER <= 1800)
-  EXPECT_STREQ("5.670367e-008 kg s^-3 K^-4", output.c_str());
-#else
-  EXPECT_STREQ("5.670367e-08 kg s^-3 K^-4", output.c_str());
-#endif
-}
-
-TEST_F(UnitContainer, to_string) {
-  foot_t a(3.5);
-  EXPECT_STREQ("3.5 ft", units::length::to_string(a).c_str());
-
-  meter_t b(8);
-  EXPECT_STREQ("8 m", units::length::to_string(b).c_str());
-}
-
-TEST_F(UnitContainer, DISABLED_to_string_locale) {
-  struct lconv* lc;
-
-  // German locale
-#if defined(_MSC_VER)
-  setlocale(LC_ALL, "de-DE");
-#else
-  EXPECT_STREQ("de_DE.utf8", setlocale(LC_ALL, "de_DE.utf8"));
-#endif
-
-  lc = localeconv();
-  char point_de = *lc->decimal_point;
-  EXPECT_EQ(point_de, ',');
-
-  kilometer_t de = 2_km;
-  EXPECT_STREQ("2 km", units::length::to_string(de).c_str());
-
-  de = 2.5_km;
-  EXPECT_STREQ("2,5 km", units::length::to_string(de).c_str());
-
-  // US locale
-#if defined(_MSC_VER)
-  setlocale(LC_ALL, "en-US");
-#else
-  EXPECT_STREQ("en_US.utf8", setlocale(LC_ALL, "en_US.utf8"));
-#endif
-
-  lc = localeconv();
-  char point_us = *lc->decimal_point;
-  EXPECT_EQ(point_us, '.');
-
-  mile_t us = 2_mi;
-  EXPECT_STREQ("2 mi", units::length::to_string(us).c_str());
-
-  us = 2.5_mi;
-  EXPECT_STREQ("2.5 mi", units::length::to_string(us).c_str());
-}
-
-TEST_F(UnitContainer, nameAndAbbreviation) {
-  foot_t a(3.5);
-  EXPECT_STREQ("ft", units::abbreviation(a));
-  EXPECT_STREQ("ft", a.abbreviation());
-  EXPECT_STREQ("foot", a.name());
-
-  meter_t b(8);
-  EXPECT_STREQ("m", units::abbreviation(b));
-  EXPECT_STREQ("m", b.abbreviation());
-  EXPECT_STREQ("meter", b.name());
-}
-#endif
-
-TEST_F(UnitContainer, negative) {
-  meter_t a(5.3);
-  meter_t b(-5.3);
-  EXPECT_NEAR(a.to<double>(), -b.to<double>(), 5.0e-320);
-  EXPECT_NEAR(b.to<double>(), -a.to<double>(), 5.0e-320);
-
-  dB_t c(2.87);
-  dB_t d(-2.87);
-  EXPECT_NEAR(c.to<double>(), -d.to<double>(), 5.0e-320);
-  EXPECT_NEAR(d.to<double>(), -c.to<double>(), 5.0e-320);
-
-  ppm_t e = -1 * ppm_t(10);
-  EXPECT_EQ(e, -ppm_t(10));
-  EXPECT_NEAR(-0.00001, e, 5.0e-10);
-}
-
-TEST_F(UnitContainer, concentration) {
-  ppb_t a(ppm_t(1));
-  EXPECT_EQ(ppb_t(1000), a);
-  EXPECT_EQ(0.000001, a);
-  EXPECT_EQ(0.000001, a.to<double>());
-
-  scalar_t b(ppm_t(1));
-  EXPECT_EQ(0.000001, b);
-
-  scalar_t c = ppb_t(1);
-  EXPECT_EQ(0.000000001, c);
-}
-
-TEST_F(UnitContainer, dBConversion) {
-  dBW_t a_dbw(23.1);
-  watt_t a_w = a_dbw;
-  dBm_t a_dbm = a_dbw;
-
-  EXPECT_NEAR(204.173794, a_w(), 5.0e-7);
-  EXPECT_NEAR(53.1, a_dbm(), 5.0e-7);
-
-  milliwatt_t b_mw(100000.0);
-  watt_t b_w = b_mw;
-  dBm_t b_dbm = b_mw;
-  dBW_t b_dbw = b_mw;
-
-  EXPECT_NEAR(100.0, b_w(), 5.0e-7);
-  EXPECT_NEAR(50.0, b_dbm(), 5.0e-7);
-  EXPECT_NEAR(20.0, b_dbw(), 5.0e-7);
-}
-
-TEST_F(UnitContainer, dBAddition) {
-  bool isSame;
-
-  auto result_dbw = dBW_t(10.0) + dB_t(30.0);
-  EXPECT_NEAR(40.0, result_dbw(), 5.0e-5);
-  result_dbw = dB_t(12.0) + dBW_t(30.0);
-  EXPECT_NEAR(42.0, result_dbw(), 5.0e-5);
-  isSame = std::is_same<decltype(result_dbw), dBW_t>::value;
-  EXPECT_TRUE(isSame);
-
-  auto result_dbm = dB_t(30.0) + dBm_t(20.0);
-  EXPECT_NEAR(50.0, result_dbm(), 5.0e-5);
-
-  // adding dBW to dBW is something you probably shouldn't do, but let's see if
-  // it works...
-  auto result_dBW2 = dBW_t(10.0) + dBm_t(40.0);
-  EXPECT_NEAR(20.0, result_dBW2(), 5.0e-5);
-  isSame = std::is_same<decltype(result_dBW2),
-                        unit_t<squared<watts>, double, decibel_scale>>::value;
-  EXPECT_TRUE(isSame);
-}
-
-TEST_F(UnitContainer, dBSubtraction) {
-  bool isSame;
-
-  auto result_dbw = dBW_t(10.0) - dB_t(30.0);
-  EXPECT_NEAR(-20.0, result_dbw(), 5.0e-5);
-  isSame = std::is_same<decltype(result_dbw), dBW_t>::value;
-  EXPECT_TRUE(isSame);
-
-  auto result_dbm = dBm_t(100.0) - dB_t(30.0);
-  EXPECT_NEAR(70.0, result_dbm(), 5.0e-5);
-  isSame = std::is_same<decltype(result_dbm), dBm_t>::value;
-  EXPECT_TRUE(isSame);
-
-  auto result_db = dBW_t(100.0) - dBW_t(80.0);
-  EXPECT_NEAR(20.0, result_db(), 5.0e-5);
-  isSame = std::is_same<decltype(result_db), dB_t>::value;
-  EXPECT_TRUE(isSame);
-
-  result_db = dB_t(100.0) - dB_t(80.0);
-  EXPECT_NEAR(20.0, result_db(), 5.0e-5);
-  isSame = std::is_same<decltype(result_db), dB_t>::value;
-  EXPECT_TRUE(isSame);
-}
-
-TEST_F(UnitContainer, unit_cast) {
-  meter_t test1(5.7);
-  hectare_t test2(16);
-
-  double dResult1 = 5.7;
-
-  double dResult2 = 16;
-  int iResult2 = 16;
-
-  EXPECT_EQ(dResult1, unit_cast<double>(test1));
-  EXPECT_EQ(dResult2, unit_cast<double>(test2));
-  EXPECT_EQ(iResult2, unit_cast<int>(test2));
-
-  EXPECT_TRUE(
-      (std::is_same<double, decltype(unit_cast<double>(test1))>::value));
-  EXPECT_TRUE((std::is_same<int, decltype(unit_cast<int>(test2))>::value));
-}
-
-// literal syntax is only supported in GCC 4.7+ and MSVC2015+
-#if !defined(_MSC_VER) || _MSC_VER > 1800
-TEST_F(UnitContainer, literals) {
-  // basic functionality testing
-  EXPECT_TRUE((std::is_same<decltype(16.2_m), meter_t>::value));
-  EXPECT_TRUE(meter_t(16.2) == 16.2_m);
-  EXPECT_TRUE(meter_t(16) == 16_m);
-
-  EXPECT_TRUE((std::is_same<decltype(11.2_ft), foot_t>::value));
-  EXPECT_TRUE(foot_t(11.2) == 11.2_ft);
-  EXPECT_TRUE(foot_t(11) == 11_ft);
-
-  // auto using literal syntax
-  auto x = 10.0_m;
-  EXPECT_TRUE((std::is_same<decltype(x), meter_t>::value));
-  EXPECT_TRUE(meter_t(10) == x);
-
-  // conversion using literal syntax
-  foot_t y = 0.3048_m;
-  EXPECT_TRUE(1_ft == y);
-
-  // Pythagorean theorem
-  meter_t a = 3_m;
-  meter_t b = 4_m;
-  meter_t c = sqrt(pow<2>(a) + pow<2>(b));
-  EXPECT_TRUE(c == 5_m);
-}
-#endif
-
-TEST_F(UnitConversion, length) {
-  double test;
-  test = convert<meters, nanometers>(0.000000001);
-  EXPECT_NEAR(1.0, test, 5.0e-20);
-  test = convert<meters, micrometers>(0.000001);
-  EXPECT_NEAR(1.0, test, 5.0e-20);
-  test = convert<meters, millimeters>(0.001);
-  EXPECT_NEAR(1.0, test, 5.0e-20);
-  test = convert<meters, centimeters>(0.01);
-  EXPECT_NEAR(1.0, test, 5.0e-20);
-  test = convert<meters, kilometers>(1000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-20);
-  test = convert<meters, meters>(1.0);
-  EXPECT_NEAR(1.0, test, 5.0e-20);
-  test = convert<meters, feet>(0.3048);
-  EXPECT_NEAR(1.0, test, 5.0e-20);
-  test = convert<meters, miles>(1609.344);
-  EXPECT_NEAR(1.0, test, 5.0e-20);
-  test = convert<meters, inches>(0.0254);
-  EXPECT_NEAR(1.0, test, 5.0e-20);
-  test = convert<meters, nauticalMiles>(1852.0);
-  EXPECT_NEAR(1.0, test, 5.0e-20);
-  test = convert<meters, astronicalUnits>(149597870700.0);
-  EXPECT_NEAR(1.0, test, 5.0e-20);
-  test = convert<meters, lightyears>(9460730472580800.0);
-  EXPECT_NEAR(1.0, test, 5.0e-20);
-  test = convert<meters, parsec>(3.08567758e16);
-  EXPECT_NEAR(1.0, test, 5.0e7);
-
-  test = convert<feet, feet>(6.3);
-  EXPECT_NEAR(6.3, test, 5.0e-5);
-  test = convert<feet, inches>(6.0);
-  EXPECT_NEAR(72.0, test, 5.0e-5);
-  test = convert<inches, feet>(6.0);
-  EXPECT_NEAR(0.5, test, 5.0e-5);
-  test = convert<meter, feet>(1.0);
-  EXPECT_NEAR(3.28084, test, 5.0e-5);
-  test = convert<miles, nauticalMiles>(6.3);
-  EXPECT_NEAR(5.47455, test, 5.0e-6);
-  test = convert<miles, meters>(11.0);
-  EXPECT_NEAR(17702.8, test, 5.0e-2);
-  test = convert<meters, chains>(1.0);
-  EXPECT_NEAR(0.0497097, test, 5.0e-7);
-}
-
-TEST_F(UnitConversion, mass) {
-  double test;
-
-  test = convert<kilograms, grams>(1.0e-3);
-  EXPECT_NEAR(1.0, test, 5.0e-6);
-  test = convert<kilograms, micrograms>(1.0e-9);
-  EXPECT_NEAR(1.0, test, 5.0e-6);
-  test = convert<kilograms, milligrams>(1.0e-6);
-  EXPECT_NEAR(1.0, test, 5.0e-6);
-  test = convert<kilograms, kilograms>(1.0);
-  EXPECT_NEAR(1.0, test, 5.0e-6);
-  test = convert<kilograms, metric_tons>(1000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-6);
-  test = convert<kilograms, pounds>(0.453592);
-  EXPECT_NEAR(1.0, test, 5.0e-6);
-  test = convert<kilograms, long_tons>(1016.05);
-  EXPECT_NEAR(1.0, test, 5.0e-6);
-  test = convert<kilograms, short_tons>(907.185);
-  EXPECT_NEAR(1.0, test, 5.0e-6);
-  test = convert<kilograms, mass::ounces>(0.0283495);
-  EXPECT_NEAR(1.0, test, 5.0e-6);
-  test = convert<kilograms, carats>(0.0002);
-  EXPECT_NEAR(1.0, test, 5.0e-6);
-  test = convert<slugs, kilograms>(1.0);
-  EXPECT_NEAR(14.593903, test, 5.0e-7);
-
-  test = convert<pounds, carats>(6.3);
-  EXPECT_NEAR(14288.2, test, 5.0e-2);
-}
-
-TEST_F(UnitConversion, time) {
-  double result = 0;
-  double daysPerYear = 365;
-  double hoursPerDay = 24;
-  double minsPerHour = 60;
-  double secsPerMin = 60;
-  double daysPerWeek = 7;
-
-  result = 2 * daysPerYear * hoursPerDay * minsPerHour * secsPerMin *
-           (1 / minsPerHour) * (1 / secsPerMin) * (1 / hoursPerDay) *
-           (1 / daysPerWeek);
-  EXPECT_NEAR(104.286, result, 5.0e-4);
-
-  year_t twoYears(2.0);
-  week_t twoYearsInWeeks = twoYears;
-  EXPECT_NEAR(week_t(104.286).to<double>(), twoYearsInWeeks.to<double>(),
-              5.0e-4);
-
-  double test;
-
-  test = convert<seconds, seconds>(1.0);
-  EXPECT_NEAR(1.0, test, 5.0e-20);
-  test = convert<seconds, nanoseconds>(1.0e-9);
-  EXPECT_NEAR(1.0, test, 5.0e-20);
-  test = convert<seconds, microseconds>(1.0e-6);
-  EXPECT_NEAR(1.0, test, 5.0e-20);
-  test = convert<seconds, milliseconds>(1.0e-3);
-  EXPECT_NEAR(1.0, test, 5.0e-20);
-  test = convert<seconds, minutes>(60.0);
-  EXPECT_NEAR(1.0, test, 5.0e-20);
-  test = convert<seconds, hours>(3600.0);
-  EXPECT_NEAR(1.0, test, 5.0e-20);
-  test = convert<seconds, days>(86400.0);
-  EXPECT_NEAR(1.0, test, 5.0e-20);
-  test = convert<seconds, weeks>(604800.0);
-  EXPECT_NEAR(1.0, test, 5.0e-20);
-  test = convert<seconds, years>(3.154e7);
-  EXPECT_NEAR(1.0, test, 5.0e3);
-
-  test = convert<years, weeks>(2.0);
-  EXPECT_NEAR(104.2857142857143, test, 5.0e-14);
-  test = convert<hours, minutes>(4.0);
-  EXPECT_NEAR(240.0, test, 5.0e-14);
-  test = convert<julian_years, days>(1.0);
-  EXPECT_NEAR(365.25, test, 5.0e-14);
-  test = convert<gregorian_years, days>(1.0);
-  EXPECT_NEAR(365.2425, test, 5.0e-14);
-}
-
-TEST_F(UnitConversion, angle) {
-  angle::degree_t quarterCircleDeg(90.0);
-  angle::radian_t quarterCircleRad = quarterCircleDeg;
-  EXPECT_NEAR(angle::radian_t(constants::detail::PI_VAL / 2.0).to<double>(),
-              quarterCircleRad.to<double>(), 5.0e-12);
-
-  double test;
-
-  test = convert<angle::radians, angle::radians>(1.0);
-  EXPECT_NEAR(1.0, test, 5.0e-20);
-  test = convert<angle::radians, angle::milliradians>(0.001);
-  EXPECT_NEAR(1.0, test, 5.0e-4);
-  test = convert<angle::radians, angle::degrees>(0.0174533);
-  EXPECT_NEAR(1.0, test, 5.0e-7);
-  test = convert<angle::radians, angle::arcminutes>(0.000290888);
-  EXPECT_NEAR(0.99999928265913, test, 5.0e-8);
-  test = convert<angle::radians, angle::arcseconds>(4.8481e-6);
-  EXPECT_NEAR(0.999992407, test, 5.0e-10);
-  test = convert<angle::radians, angle::turns>(6.28319);
-  EXPECT_NEAR(1.0, test, 5.0e-6);
-  test = convert<angle::radians, angle::gradians>(0.015708);
-  EXPECT_NEAR(1.0, test, 5.0e-6);
-
-  test = convert<angle::radians, angle::radians>(2.1);
-  EXPECT_NEAR(2.1, test, 5.0e-6);
-  test = convert<angle::arcseconds, angle::gradians>(2.1);
-  EXPECT_NEAR(0.000648148, test, 5.0e-6);
-  test = convert<angle::radians, angle::degrees>(constants::detail::PI_VAL);
-  EXPECT_NEAR(180.0, test, 5.0e-6);
-  test = convert<angle::degrees, angle::radians>(90.0);
-  EXPECT_NEAR(constants::detail::PI_VAL / 2, test, 5.0e-6);
-}
-
-TEST_F(UnitConversion, current) {
-  double test;
-
-  test = convert<current::A, current::mA>(2.1);
-  EXPECT_NEAR(2100.0, test, 5.0e-6);
-}
-
-TEST_F(UnitConversion, temperature) {
-  // temp conversion are weird/hard since they involve translations AND scaling.
-  double test;
-
-  test = convert<kelvin, kelvin>(72.0);
-  EXPECT_NEAR(72.0, test, 5.0e-5);
-  test = convert<fahrenheit, fahrenheit>(72.0);
-  EXPECT_NEAR(72.0, test, 5.0e-5);
-  test = convert<kelvin, fahrenheit>(300.0);
-  EXPECT_NEAR(80.33, test, 5.0e-5);
-  test = convert<fahrenheit, kelvin>(451.0);
-  EXPECT_NEAR(505.928, test, 5.0e-4);
-  test = convert<kelvin, celsius>(300.0);
-  EXPECT_NEAR(26.85, test, 5.0e-3);
-  test = convert<celsius, kelvin>(451.0);
-  EXPECT_NEAR(724.15, test, 5.0e-3);
-  test = convert<fahrenheit, celsius>(72.0);
-  EXPECT_NEAR(22.2222, test, 5.0e-5);
-  test = convert<celsius, fahrenheit>(100.0);
-  EXPECT_NEAR(212.0, test, 5.0e-5);
-  test = convert<fahrenheit, celsius>(32.0);
-  EXPECT_NEAR(0.0, test, 5.0e-5);
-  test = convert<celsius, fahrenheit>(0.0);
-  EXPECT_NEAR(32.0, test, 5.0e-5);
-  test = convert<rankine, kelvin>(100.0);
-  EXPECT_NEAR(55.5556, test, 5.0e-5);
-  test = convert<kelvin, rankine>(100.0);
-  EXPECT_NEAR(180.0, test, 5.0e-5);
-  test = convert<fahrenheit, rankine>(100.0);
-  EXPECT_NEAR(559.67, test, 5.0e-5);
-  test = convert<rankine, fahrenheit>(72.0);
-  EXPECT_NEAR(-387.67, test, 5.0e-5);
-  test = convert<reaumur, kelvin>(100.0);
-  EXPECT_NEAR(398.0, test, 5.0e-1);
-  test = convert<reaumur, celsius>(80.0);
-  EXPECT_NEAR(100.0, test, 5.0e-5);
-  test = convert<celsius, reaumur>(212.0);
-  EXPECT_NEAR(169.6, test, 5.0e-2);
-  test = convert<reaumur, fahrenheit>(80.0);
-  EXPECT_NEAR(212.0, test, 5.0e-5);
-  test = convert<fahrenheit, reaumur>(37.0);
-  EXPECT_NEAR(2.222, test, 5.0e-3);
-}
-
-TEST_F(UnitConversion, luminous_intensity) {
-  double test;
-
-  test = convert<candela, millicandela>(72.0);
-  EXPECT_NEAR(72000.0, test, 5.0e-5);
-  test = convert<millicandela, candela>(376.0);
-  EXPECT_NEAR(0.376, test, 5.0e-5);
-}
-
-TEST_F(UnitConversion, solid_angle) {
-  double test;
-  bool same;
-
-  same = std::is_same<traits::base_unit_of<steradians>,
-                      traits::base_unit_of<degrees_squared>>::value;
-  EXPECT_TRUE(same);
-
-  test = convert<steradians, steradians>(72.0);
-  EXPECT_NEAR(72.0, test, 5.0e-5);
-  test = convert<steradians, degrees_squared>(1.0);
-  EXPECT_NEAR(3282.8, test, 5.0e-2);
-  test = convert<steradians, spats>(8.0);
-  EXPECT_NEAR(0.636619772367582, test, 5.0e-14);
-  test = convert<degrees_squared, steradians>(3282.8);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<degrees_squared, degrees_squared>(72.0);
-  EXPECT_NEAR(72.0, test, 5.0e-5);
-  test = convert<degrees_squared, spats>(3282.8);
-  EXPECT_NEAR(1.0 / (4 * constants::detail::PI_VAL), test, 5.0e-5);
-  test = convert<spats, steradians>(1.0 / (4 * constants::detail::PI_VAL));
-  EXPECT_NEAR(1.0, test, 5.0e-14);
-  test = convert<spats, degrees_squared>(1.0 / (4 * constants::detail::PI_VAL));
-  EXPECT_NEAR(3282.8, test, 5.0e-2);
-  test = convert<spats, spats>(72.0);
-  EXPECT_NEAR(72.0, test, 5.0e-5);
-}
-
-TEST_F(UnitConversion, frequency) {
-  double test;
-
-  test = convert<hertz, kilohertz>(63000.0);
-  EXPECT_NEAR(63.0, test, 5.0e-5);
-  test = convert<hertz, hertz>(6.3);
-  EXPECT_NEAR(6.3, test, 5.0e-5);
-  test = convert<kilohertz, hertz>(5.0);
-  EXPECT_NEAR(5000.0, test, 5.0e-5);
-  test = convert<megahertz, hertz>(1.0);
-  EXPECT_NEAR(1.0e6, test, 5.0e-5);
-}
-
-TEST_F(UnitConversion, velocity) {
-  double test;
-  bool same;
-
-  same = std::is_same<meters_per_second,
-                      unit<std::ratio<1>, category::velocity_unit>>::value;
-  EXPECT_TRUE(same);
-  same = traits::is_convertible_unit<miles_per_hour, meters_per_second>::value;
-  EXPECT_TRUE(same);
-
-  test = convert<meters_per_second, miles_per_hour>(1250.0);
-  EXPECT_NEAR(2796.17, test, 5.0e-3);
-  test = convert<feet_per_second, kilometers_per_hour>(2796.17);
-  EXPECT_NEAR(3068.181418, test, 5.0e-7);
-  test = convert<knots, miles_per_hour>(600.0);
-  EXPECT_NEAR(690.468, test, 5.0e-4);
-  test = convert<miles_per_hour, feet_per_second>(120.0);
-  EXPECT_NEAR(176.0, test, 5.0e-5);
-  test = convert<feet_per_second, meters_per_second>(10.0);
-  EXPECT_NEAR(3.048, test, 5.0e-5);
-}
-
-TEST_F(UnitConversion, angular_velocity) {
-  double test;
-  bool same;
-
-  same =
-      std::is_same<radians_per_second,
-                   unit<std::ratio<1>, category::angular_velocity_unit>>::value;
-  EXPECT_TRUE(same);
-  same = traits::is_convertible_unit<rpm, radians_per_second>::value;
-  EXPECT_TRUE(same);
-
-  test = convert<radians_per_second, milliarcseconds_per_year>(1.0);
-  EXPECT_NEAR(6.504e15, test, 1.0e12);
-  test = convert<degrees_per_second, radians_per_second>(1.0);
-  EXPECT_NEAR(0.0174533, test, 5.0e-8);
-  test = convert<rpm, radians_per_second>(1.0);
-  EXPECT_NEAR(0.10471975512, test, 5.0e-13);
-  test = convert<milliarcseconds_per_year, radians_per_second>(1.0);
-  EXPECT_NEAR(1.537e-16, test, 5.0e-20);
-}
-
-TEST_F(UnitConversion, acceleration) {
-  double test;
-
-  test = convert<standard_gravity, meters_per_second_squared>(1.0);
-  EXPECT_NEAR(9.80665, test, 5.0e-10);
-}
-TEST_F(UnitConversion, force) {
-  double test;
-
-  test = convert<units::force::newton, units::force::newton>(1.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<units::force::newton, units::force::pounds>(6.3);
-  EXPECT_NEAR(1.4163, test, 5.0e-5);
-  test = convert<units::force::newton, units::force::dynes>(5.0);
-  EXPECT_NEAR(500000.0, test, 5.0e-5);
-  test = convert<units::force::newtons, units::force::poundals>(2.1);
-  EXPECT_NEAR(15.1893, test, 5.0e-5);
-  test = convert<units::force::newtons, units::force::kiloponds>(173.0);
-  EXPECT_NEAR(17.6411, test, 5.0e-5);
-  test = convert<units::force::poundals, units::force::kiloponds>(21.879);
-  EXPECT_NEAR(0.308451933, test, 5.0e-10);
-}
-
-TEST_F(UnitConversion, area) {
-  double test;
-
-  test = convert<hectares, acres>(6.3);
-  EXPECT_NEAR(15.5676, test, 5.0e-5);
-  test = convert<square_miles, square_kilometers>(10.0);
-  EXPECT_NEAR(25.8999, test, 5.0e-5);
-  test = convert<square_inch, square_meter>(4.0);
-  EXPECT_NEAR(0.00258064, test, 5.0e-9);
-  test = convert<acre, square_foot>(5.0);
-  EXPECT_NEAR(217800.0, test, 5.0e-5);
-  test = convert<square_meter, square_foot>(1.0);
-  EXPECT_NEAR(10.7639, test, 5.0e-5);
-}
-
-TEST_F(UnitConversion, pressure) {
-  double test;
-
-  test = convert<pascals, torr>(1.0);
-  EXPECT_NEAR(0.00750062, test, 5.0e-5);
-  test = convert<bar, psi>(2.2);
-  EXPECT_NEAR(31.9083, test, 5.0e-5);
-  test = convert<atmospheres, bar>(4.0);
-  EXPECT_NEAR(4.053, test, 5.0e-5);
-  test = convert<torr, pascals>(800.0);
-  EXPECT_NEAR(106657.89474, test, 5.0e-5);
-  test = convert<psi, atmospheres>(38.0);
-  EXPECT_NEAR(2.58575, test, 5.0e-5);
-  test = convert<psi, pascals>(1.0);
-  EXPECT_NEAR(6894.76, test, 5.0e-3);
-  test = convert<pascals, bar>(0.25);
-  EXPECT_NEAR(2.5e-6, test, 5.0e-5);
-  test = convert<torr, atmospheres>(9.0);
-  EXPECT_NEAR(0.0118421, test, 5.0e-8);
-  test = convert<bar, torr>(12.0);
-  EXPECT_NEAR(9000.74, test, 5.0e-3);
-  test = convert<atmospheres, psi>(1.0);
-  EXPECT_NEAR(14.6959, test, 5.0e-5);
-}
-
-TEST_F(UnitConversion, charge) {
-  double test;
-
-  test = convert<coulombs, ampere_hours>(4.0);
-  EXPECT_NEAR(0.00111111, test, 5.0e-9);
-  test = convert<ampere_hours, coulombs>(1.0);
-  EXPECT_NEAR(3600.0, test, 5.0e-6);
-}
-
-TEST_F(UnitConversion, energy) {
-  double test;
-
-  test = convert<joules, calories>(8000.000464);
-  EXPECT_NEAR(1912.046, test, 5.0e-4);
-  test = convert<therms, joules>(12.0);
-  EXPECT_NEAR(1.266e+9, test, 5.0e5);
-  test = convert<megajoules, watt_hours>(100.0);
-  EXPECT_NEAR(27777.778, test, 5.0e-4);
-  test = convert<kilocalories, megajoules>(56.0);
-  EXPECT_NEAR(0.234304, test, 5.0e-7);
-  test = convert<kilojoules, therms>(56.0);
-  EXPECT_NEAR(0.000530904, test, 5.0e-5);
-  test = convert<british_thermal_units, kilojoules>(18.56399995447);
-  EXPECT_NEAR(19.5860568, test, 5.0e-5);
-  test = convert<calories, energy::foot_pounds>(18.56399995447);
-  EXPECT_NEAR(57.28776190423856, test, 5.0e-5);
-  test = convert<megajoules, calories>(1.0);
-  EXPECT_NEAR(239006.0, test, 5.0e-1);
-  test = convert<kilocalories, kilowatt_hours>(2.0);
-  EXPECT_NEAR(0.00232444, test, 5.0e-9);
-  test = convert<therms, kilocalories>(0.1);
-  EXPECT_NEAR(2521.04, test, 5.0e-3);
-  test = convert<watt_hours, megajoules>(67.0);
-  EXPECT_NEAR(0.2412, test, 5.0e-5);
-  test = convert<british_thermal_units, watt_hours>(100.0);
-  EXPECT_NEAR(29.3071, test, 5.0e-5);
-  test = convert<calories, BTU>(100.0);
-  EXPECT_NEAR(0.396567, test, 5.0e-5);
-}
-
-TEST_F(UnitConversion, power) {
-  double test;
-
-  test = convert<compound_unit<energy::foot_pounds, inverse<seconds>>, watts>(
-      550.0);
-  EXPECT_NEAR(745.7, test, 5.0e-2);
-  test = convert<watts, gigawatts>(1000000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-4);
-  test = convert<microwatts, watts>(200000.0);
-  EXPECT_NEAR(0.2, test, 5.0e-4);
-  test = convert<horsepower, watts>(100.0);
-  EXPECT_NEAR(74570.0, test, 5.0e-1);
-  test = convert<horsepower, megawatts>(5.0);
-  EXPECT_NEAR(0.0037284994, test, 5.0e-7);
-  test = convert<kilowatts, horsepower>(232.0);
-  EXPECT_NEAR(311.117, test, 5.0e-4);
-  test = convert<milliwatts, horsepower>(1001.0);
-  EXPECT_NEAR(0.001342363, test, 5.0e-9);
-}
-
-TEST_F(UnitConversion, voltage) {
-  double test;
-
-  test = convert<volts, millivolts>(10.0);
-  EXPECT_NEAR(10000.0, test, 5.0e-5);
-  test = convert<picovolts, volts>(1000000000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<nanovolts, volts>(1000000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<microvolts, volts>(1000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<millivolts, volts>(1000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<kilovolts, volts>(0.001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<megavolts, volts>(0.000001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<gigavolts, volts>(0.000000001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<statvolts, volts>(299.792458);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<millivolts, statvolts>(1000.0);
-  EXPECT_NEAR(299.792458, test, 5.0e-5);
-  test = convert<abvolts, nanovolts>(0.1);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<microvolts, abvolts>(0.01);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-}
-
-TEST_F(UnitConversion, capacitance) {
-  double test;
-
-  test = convert<farads, millifarads>(10.0);
-  EXPECT_NEAR(10000.0, test, 5.0e-5);
-  test = convert<picofarads, farads>(1000000000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<nanofarads, farads>(1000000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<microfarads, farads>(1000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<millifarads, farads>(1000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<kilofarads, farads>(0.001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<megafarads, farads>(0.000001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<gigafarads, farads>(0.000000001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-}
-
-TEST_F(UnitConversion, impedance) {
-  double test;
-
-  test = convert<ohms, milliohms>(10.0);
-  EXPECT_NEAR(10000.0, test, 5.0e-5);
-  test = convert<picoohms, ohms>(1000000000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<nanoohms, ohms>(1000000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<microohms, ohms>(1000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<milliohms, ohms>(1000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<kiloohms, ohms>(0.001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<megaohms, ohms>(0.000001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<gigaohms, ohms>(0.000000001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-}
-
-TEST_F(UnitConversion, conductance) {
-  double test;
-
-  test = convert<siemens, millisiemens>(10.0);
-  EXPECT_NEAR(10000.0, test, 5.0e-5);
-  test = convert<picosiemens, siemens>(1000000000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<nanosiemens, siemens>(1000000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<microsiemens, siemens>(1000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<millisiemens, siemens>(1000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<kilosiemens, siemens>(0.001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<megasiemens, siemens>(0.000001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<gigasiemens, siemens>(0.000000001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-}
-
-TEST_F(UnitConversion, magnetic_flux) {
-  double test;
-
-  test = convert<webers, milliwebers>(10.0);
-  EXPECT_NEAR(10000.0, test, 5.0e-5);
-  test = convert<picowebers, webers>(1000000000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<nanowebers, webers>(1000000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<microwebers, webers>(1000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<milliwebers, webers>(1000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<kilowebers, webers>(0.001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<megawebers, webers>(0.000001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<gigawebers, webers>(0.000000001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<maxwells, webers>(100000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<nanowebers, maxwells>(10.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-}
-
-TEST_F(UnitConversion, magnetic_field_strength) {
-  double test;
-
-  test = convert<teslas, milliteslas>(10.0);
-  EXPECT_NEAR(10000.0, test, 5.0e-5);
-  test = convert<picoteslas, teslas>(1000000000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<nanoteslas, teslas>(1000000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<microteslas, teslas>(1000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<milliteslas, teslas>(1000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<kiloteslas, teslas>(0.001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<megateslas, teslas>(0.000001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<gigateslas, teslas>(0.000000001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<gauss, teslas>(10000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<nanoteslas, gauss>(100000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-}
-
-TEST_F(UnitConversion, inductance) {
-  double test;
-
-  test = convert<henries, millihenries>(10.0);
-  EXPECT_NEAR(10000.0, test, 5.0e-5);
-  test = convert<picohenries, henries>(1000000000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<nanohenries, henries>(1000000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<microhenries, henries>(1000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<millihenries, henries>(1000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<kilohenries, henries>(0.001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<megahenries, henries>(0.000001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<gigahenries, henries>(0.000000001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-}
-
-TEST_F(UnitConversion, luminous_flux) {
-  double test;
-
-  test = convert<lumens, millilumens>(10.0);
-  EXPECT_NEAR(10000.0, test, 5.0e-5);
-  test = convert<picolumens, lumens>(1000000000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<nanolumens, lumens>(1000000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<microlumens, lumens>(1000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<millilumens, lumens>(1000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<kilolumens, lumens>(0.001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<megalumens, lumens>(0.000001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<gigalumens, lumens>(0.000000001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-}
-
-TEST_F(UnitConversion, illuminance) {
-  double test;
-
-  test = convert<luxes, milliluxes>(10.0);
-  EXPECT_NEAR(10000.0, test, 5.0e-5);
-  test = convert<picoluxes, luxes>(1000000000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<nanoluxes, luxes>(1000000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<microluxes, luxes>(1000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<milliluxes, luxes>(1000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<kiloluxes, luxes>(0.001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<megaluxes, luxes>(0.000001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<gigaluxes, luxes>(0.000000001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-
-  test = convert<footcandles, luxes>(0.092903);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<lux, lumens_per_square_inch>(1550.0031000062);
-  EXPECT_NEAR(1.0, test, 5.0e-13);
-  test = convert<phots, luxes>(0.0001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-}
-
-TEST_F(UnitConversion, radiation) {
-  double test;
-
-  test = convert<becquerels, millibecquerels>(10.0);
-  EXPECT_NEAR(10000.0, test, 5.0e-5);
-  test = convert<picobecquerels, becquerels>(1000000000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<nanobecquerels, becquerels>(1000000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<microbecquerels, becquerels>(1000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<millibecquerels, becquerels>(1000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<kilobecquerels, becquerels>(0.001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<megabecquerels, becquerels>(0.000001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<gigabecquerels, becquerels>(0.000000001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-
-  test = convert<grays, milligrays>(10.0);
-  EXPECT_NEAR(10000.0, test, 5.0e-5);
-  test = convert<picograys, grays>(1000000000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<nanograys, grays>(1000000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<micrograys, grays>(1000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<milligrays, grays>(1000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<kilograys, grays>(0.001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<megagrays, grays>(0.000001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<gigagrays, grays>(0.000000001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-
-  test = convert<sieverts, millisieverts>(10.0);
-  EXPECT_NEAR(10000.0, test, 5.0e-5);
-  test = convert<picosieverts, sieverts>(1000000000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<nanosieverts, sieverts>(1000000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<microsieverts, sieverts>(1000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<millisieverts, sieverts>(1000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<kilosieverts, sieverts>(0.001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<megasieverts, sieverts>(0.000001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<gigasieverts, sieverts>(0.000000001);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-
-  test = convert<becquerels, curies>(37.0e9);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<becquerels, rutherfords>(1000000.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<rads, grays>(100.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-}
-
-TEST_F(UnitConversion, torque) {
-  double test;
-
-  test = convert<torque::foot_pounds, newton_meter>(1.0);
-  EXPECT_NEAR(1.355817948, test, 5.0e-5);
-  test = convert<inch_pounds, newton_meter>(1.0);
-  EXPECT_NEAR(0.112984829, test, 5.0e-5);
-  test = convert<foot_poundals, newton_meter>(1.0);
-  EXPECT_NEAR(4.214011009e-2, test, 5.0e-5);
-  test = convert<meter_kilograms, newton_meter>(1.0);
-  EXPECT_NEAR(9.80665, test, 5.0e-5);
-  test = convert<inch_pound, meter_kilogram>(86.79616930855788);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<foot_poundals, inch_pound>(2.681170713);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-}
-
-TEST_F(UnitConversion, volume) {
-  double test;
-
-  test = convert<cubic_meters, cubic_meter>(1.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<cubic_millimeters, cubic_meter>(1.0);
-  EXPECT_NEAR(1.0e-9, test, 5.0e-5);
-  test = convert<cubic_kilometers, cubic_meter>(1.0);
-  EXPECT_NEAR(1.0e9, test, 5.0e-5);
-  test = convert<liters, cubic_meter>(1.0);
-  EXPECT_NEAR(0.001, test, 5.0e-5);
-  test = convert<milliliters, cubic_meter>(1.0);
-  EXPECT_NEAR(1.0e-6, test, 5.0e-5);
-  test = convert<cubic_inches, cubic_meter>(1.0);
-  EXPECT_NEAR(1.6387e-5, test, 5.0e-10);
-  test = convert<cubic_feet, cubic_meter>(1.0);
-  EXPECT_NEAR(0.0283168, test, 5.0e-8);
-  test = convert<cubic_yards, cubic_meter>(1.0);
-  EXPECT_NEAR(0.764555, test, 5.0e-7);
-  test = convert<cubic_miles, cubic_meter>(1.0);
-  EXPECT_NEAR(4.168e+9, test, 5.0e5);
-  test = convert<gallons, cubic_meter>(1.0);
-  EXPECT_NEAR(0.00378541, test, 5.0e-8);
-  test = convert<quarts, cubic_meter>(1.0);
-  EXPECT_NEAR(0.000946353, test, 5.0e-10);
-  test = convert<pints, cubic_meter>(1.0);
-  EXPECT_NEAR(0.000473176, test, 5.0e-10);
-  test = convert<cups, cubic_meter>(1.0);
-  EXPECT_NEAR(0.00024, test, 5.0e-6);
-  test = convert<volume::fluid_ounces, cubic_meter>(1.0);
-  EXPECT_NEAR(2.9574e-5, test, 5.0e-5);
-  test = convert<barrels, cubic_meter>(1.0);
-  EXPECT_NEAR(0.158987294928, test, 5.0e-13);
-  test = convert<bushels, cubic_meter>(1.0);
-  EXPECT_NEAR(0.0352391, test, 5.0e-8);
-  test = convert<cords, cubic_meter>(1.0);
-  EXPECT_NEAR(3.62456, test, 5.0e-6);
-  test = convert<cubic_fathoms, cubic_meter>(1.0);
-  EXPECT_NEAR(6.11644, test, 5.0e-6);
-  test = convert<tablespoons, cubic_meter>(1.0);
-  EXPECT_NEAR(1.4787e-5, test, 5.0e-10);
-  test = convert<teaspoons, cubic_meter>(1.0);
-  EXPECT_NEAR(4.9289e-6, test, 5.0e-11);
-  test = convert<pinches, cubic_meter>(1.0);
-  EXPECT_NEAR(616.11519921875e-9, test, 5.0e-20);
-  test = convert<dashes, cubic_meter>(1.0);
-  EXPECT_NEAR(308.057599609375e-9, test, 5.0e-20);
-  test = convert<drops, cubic_meter>(1.0);
-  EXPECT_NEAR(82.14869322916e-9, test, 5.0e-9);
-  test = convert<fifths, cubic_meter>(1.0);
-  EXPECT_NEAR(0.00075708236, test, 5.0e-12);
-  test = convert<drams, cubic_meter>(1.0);
-  EXPECT_NEAR(3.69669e-6, test, 5.0e-12);
-  test = convert<gills, cubic_meter>(1.0);
-  EXPECT_NEAR(0.000118294, test, 5.0e-10);
-  test = convert<pecks, cubic_meter>(1.0);
-  EXPECT_NEAR(0.00880977, test, 5.0e-9);
-  test = convert<sacks, cubic_meter>(9.4591978);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<shots, cubic_meter>(1.0);
-  EXPECT_NEAR(4.43603e-5, test, 5.0e-11);
-  test = convert<strikes, cubic_meter>(1.0);
-  EXPECT_NEAR(0.07047814033376, test, 5.0e-5);
-  test = convert<volume::fluid_ounces, milliliters>(1.0);
-  EXPECT_NEAR(29.5735, test, 5.0e-5);
-}
-
-TEST_F(UnitConversion, density) {
-  double test;
-
-  test = convert<kilograms_per_cubic_meter, kilograms_per_cubic_meter>(1.0);
-  EXPECT_NEAR(1.0, test, 5.0e-5);
-  test = convert<grams_per_milliliter, kilograms_per_cubic_meter>(1.0);
-  EXPECT_NEAR(1000.0, test, 5.0e-5);
-  test = convert<kilograms_per_liter, kilograms_per_cubic_meter>(1.0);
-  EXPECT_NEAR(1000.0, test, 5.0e-5);
-  test = convert<ounces_per_cubic_foot, kilograms_per_cubic_meter>(1.0);
-  EXPECT_NEAR(1.001153961, test, 5.0e-10);
-  test = convert<ounces_per_cubic_inch, kilograms_per_cubic_meter>(1.0);
-  EXPECT_NEAR(1.729994044e3, test, 5.0e-7);
-  test = convert<ounces_per_gallon, kilograms_per_cubic_meter>(1.0);
-  EXPECT_NEAR(7.489151707, test, 5.0e-10);
-  test = convert<pounds_per_cubic_foot, kilograms_per_cubic_meter>(1.0);
-  EXPECT_NEAR(16.01846337, test, 5.0e-9);
-  test = convert<pounds_per_cubic_inch, kilograms_per_cubic_meter>(1.0);
-  EXPECT_NEAR(2.767990471e4, test, 5.0e-6);
-  test = convert<pounds_per_gallon, kilograms_per_cubic_meter>(1.0);
-  EXPECT_NEAR(119.8264273, test, 5.0e-8);
-  test = convert<slugs_per_cubic_foot, kilograms_per_cubic_meter>(1.0);
-  EXPECT_NEAR(515.3788184, test, 5.0e-6);
-}
-
-TEST_F(UnitConversion, concentration) {
-  double test;
-
-  test = ppm_t(1.0);
-  EXPECT_NEAR(1.0e-6, test, 5.0e-12);
-  test = ppb_t(1.0);
-  EXPECT_NEAR(1.0e-9, test, 5.0e-12);
-  test = ppt_t(1.0);
-  EXPECT_NEAR(1.0e-12, test, 5.0e-12);
-  test = percent_t(18.0);
-  EXPECT_NEAR(0.18, test, 5.0e-12);
-}
-
-TEST_F(UnitConversion, data) {
-  EXPECT_EQ(8, (convert<byte, bit>(1)));
-
-  EXPECT_EQ(1000, (convert<kilobytes, bytes>(1)));
-  EXPECT_EQ(1000, (convert<megabytes, kilobytes>(1)));
-  EXPECT_EQ(1000, (convert<gigabytes, megabytes>(1)));
-  EXPECT_EQ(1000, (convert<terabytes, gigabytes>(1)));
-  EXPECT_EQ(1000, (convert<petabytes, terabytes>(1)));
-  EXPECT_EQ(1000, (convert<exabytes, petabytes>(1)));
-
-  EXPECT_EQ(1024, (convert<kibibytes, bytes>(1)));
-  EXPECT_EQ(1024, (convert<mebibytes, kibibytes>(1)));
-  EXPECT_EQ(1024, (convert<gibibytes, mebibytes>(1)));
-  EXPECT_EQ(1024, (convert<tebibytes, gibibytes>(1)));
-  EXPECT_EQ(1024, (convert<pebibytes, tebibytes>(1)));
-  EXPECT_EQ(1024, (convert<exbibytes, pebibytes>(1)));
-
-  EXPECT_EQ(93750000, (convert<gigabytes, kibibits>(12)));
-
-  EXPECT_EQ(1000, (convert<kilobits, bits>(1)));
-  EXPECT_EQ(1000, (convert<megabits, kilobits>(1)));
-  EXPECT_EQ(1000, (convert<gigabits, megabits>(1)));
-  EXPECT_EQ(1000, (convert<terabits, gigabits>(1)));
-  EXPECT_EQ(1000, (convert<petabits, terabits>(1)));
-  EXPECT_EQ(1000, (convert<exabits, petabits>(1)));
-
-  EXPECT_EQ(1024, (convert<kibibits, bits>(1)));
-  EXPECT_EQ(1024, (convert<mebibits, kibibits>(1)));
-  EXPECT_EQ(1024, (convert<gibibits, mebibits>(1)));
-  EXPECT_EQ(1024, (convert<tebibits, gibibits>(1)));
-  EXPECT_EQ(1024, (convert<pebibits, tebibits>(1)));
-  EXPECT_EQ(1024, (convert<exbibits, pebibits>(1)));
-
-  // Source: https://en.wikipedia.org/wiki/Binary_prefix
-  EXPECT_NEAR(percent_t(2.4), kibibyte_t(1) / kilobyte_t(1) - 1, 0.005);
-  EXPECT_NEAR(percent_t(4.9), mebibyte_t(1) / megabyte_t(1) - 1, 0.005);
-  EXPECT_NEAR(percent_t(7.4), gibibyte_t(1) / gigabyte_t(1) - 1, 0.005);
-  EXPECT_NEAR(percent_t(10.0), tebibyte_t(1) / terabyte_t(1) - 1, 0.005);
-  EXPECT_NEAR(percent_t(12.6), pebibyte_t(1) / petabyte_t(1) - 1, 0.005);
-  EXPECT_NEAR(percent_t(15.3), exbibyte_t(1) / exabyte_t(1) - 1, 0.005);
-}
-
-TEST_F(UnitConversion, data_transfer_rate) {
-  EXPECT_EQ(8, (convert<bytes_per_second, bits_per_second>(1)));
-
-  EXPECT_EQ(1000, (convert<kilobytes_per_second, bytes_per_second>(1)));
-  EXPECT_EQ(1000, (convert<megabytes_per_second, kilobytes_per_second>(1)));
-  EXPECT_EQ(1000, (convert<gigabytes_per_second, megabytes_per_second>(1)));
-  EXPECT_EQ(1000, (convert<terabytes_per_second, gigabytes_per_second>(1)));
-  EXPECT_EQ(1000, (convert<petabytes_per_second, terabytes_per_second>(1)));
-  EXPECT_EQ(1000, (convert<exabytes_per_second, petabytes_per_second>(1)));
-
-  EXPECT_EQ(1024, (convert<kibibytes_per_second, bytes_per_second>(1)));
-  EXPECT_EQ(1024, (convert<mebibytes_per_second, kibibytes_per_second>(1)));
-  EXPECT_EQ(1024, (convert<gibibytes_per_second, mebibytes_per_second>(1)));
-  EXPECT_EQ(1024, (convert<tebibytes_per_second, gibibytes_per_second>(1)));
-  EXPECT_EQ(1024, (convert<pebibytes_per_second, tebibytes_per_second>(1)));
-  EXPECT_EQ(1024, (convert<exbibytes_per_second, pebibytes_per_second>(1)));
-
-  EXPECT_EQ(93750000, (convert<gigabytes_per_second, kibibits_per_second>(12)));
-
-  EXPECT_EQ(1000, (convert<kilobits_per_second, bits_per_second>(1)));
-  EXPECT_EQ(1000, (convert<megabits_per_second, kilobits_per_second>(1)));
-  EXPECT_EQ(1000, (convert<gigabits_per_second, megabits_per_second>(1)));
-  EXPECT_EQ(1000, (convert<terabits_per_second, gigabits_per_second>(1)));
-  EXPECT_EQ(1000, (convert<petabits_per_second, terabits_per_second>(1)));
-  EXPECT_EQ(1000, (convert<exabits_per_second, petabits_per_second>(1)));
-
-  EXPECT_EQ(1024, (convert<kibibits_per_second, bits_per_second>(1)));
-  EXPECT_EQ(1024, (convert<mebibits_per_second, kibibits_per_second>(1)));
-  EXPECT_EQ(1024, (convert<gibibits_per_second, mebibits_per_second>(1)));
-  EXPECT_EQ(1024, (convert<tebibits_per_second, gibibits_per_second>(1)));
-  EXPECT_EQ(1024, (convert<pebibits_per_second, tebibits_per_second>(1)));
-  EXPECT_EQ(1024, (convert<exbibits_per_second, pebibits_per_second>(1)));
-
-  // Source: https://en.wikipedia.org/wiki/Binary_prefix
-  EXPECT_NEAR(percent_t(2.4),
-              kibibytes_per_second_t(1) / kilobytes_per_second_t(1) - 1, 0.005);
-  EXPECT_NEAR(percent_t(4.9),
-              mebibytes_per_second_t(1) / megabytes_per_second_t(1) - 1, 0.005);
-  EXPECT_NEAR(percent_t(7.4),
-              gibibytes_per_second_t(1) / gigabytes_per_second_t(1) - 1, 0.005);
-  EXPECT_NEAR(percent_t(10.0),
-              tebibytes_per_second_t(1) / terabytes_per_second_t(1) - 1, 0.005);
-  EXPECT_NEAR(percent_t(12.6),
-              pebibytes_per_second_t(1) / petabytes_per_second_t(1) - 1, 0.005);
-  EXPECT_NEAR(percent_t(15.3),
-              exbibytes_per_second_t(1) / exabytes_per_second_t(1) - 1, 0.005);
-}
-
-TEST_F(UnitConversion, pi) {
-  EXPECT_TRUE(
-      units::traits::is_dimensionless_unit<decltype(constants::pi)>::value);
-  EXPECT_TRUE(units::traits::is_dimensionless_unit<constants::PI>::value);
-
-  // implicit conversion/arithmetic
-  EXPECT_NEAR(3.14159, constants::pi, 5.0e-6);
-  EXPECT_NEAR(6.28318531, (2 * constants::pi), 5.0e-9);
-  EXPECT_NEAR(6.28318531, (constants::pi + constants::pi), 5.0e-9);
-  EXPECT_NEAR(0.0, (constants::pi - constants::pi), 5.0e-9);
-  EXPECT_NEAR(31.00627668, units::math::cpow<3>(constants::pi), 5.0e-10);
-  EXPECT_NEAR(0.0322515344, (1.0 / units::math::cpow<3>(constants::pi)),
-              5.0e-11);
-  EXPECT_TRUE(constants::detail::PI_VAL == constants::pi);
-  EXPECT_TRUE(1.0 != constants::pi);
-  EXPECT_TRUE(4.0 > constants::pi);
-  EXPECT_TRUE(3.0 < constants::pi);
-  EXPECT_TRUE(constants::pi > 3.0);
-  EXPECT_TRUE(constants::pi < 4.0);
-
-  // explicit conversion
-  EXPECT_NEAR(3.14159, constants::pi.to<double>(), 5.0e-6);
-
-  // auto multiplication
-  EXPECT_TRUE(
-      (std::is_same<meter_t, decltype(constants::pi * meter_t(1))>::value));
-  EXPECT_TRUE(
-      (std::is_same<meter_t, decltype(meter_t(1) * constants::pi)>::value));
-
-  EXPECT_NEAR(constants::detail::PI_VAL,
-              (constants::pi * meter_t(1)).to<double>(), 5.0e-10);
-  EXPECT_NEAR(constants::detail::PI_VAL,
-              (meter_t(1) * constants::pi).to<double>(), 5.0e-10);
-
-  // explicit multiplication
-  meter_t a = constants::pi * meter_t(1);
-  meter_t b = meter_t(1) * constants::pi;
-
-  EXPECT_NEAR(constants::detail::PI_VAL, a.to<double>(), 5.0e-10);
-  EXPECT_NEAR(constants::detail::PI_VAL, b.to<double>(), 5.0e-10);
-
-  // auto division
-  EXPECT_TRUE(
-      (std::is_same<hertz_t, decltype(constants::pi / second_t(1))>::value));
-  EXPECT_TRUE(
-      (std::is_same<second_t, decltype(second_t(1) / constants::pi)>::value));
-
-  EXPECT_NEAR(constants::detail::PI_VAL,
-              (constants::pi / second_t(1)).to<double>(), 5.0e-10);
-  EXPECT_NEAR(1.0 / constants::detail::PI_VAL,
-              (second_t(1) / constants::pi).to<double>(), 5.0e-10);
-
-  // explicit
-  hertz_t c = constants::pi / second_t(1);
-  second_t d = second_t(1) / constants::pi;
-
-  EXPECT_NEAR(constants::detail::PI_VAL, c.to<double>(), 5.0e-10);
-  EXPECT_NEAR(1.0 / constants::detail::PI_VAL, d.to<double>(), 5.0e-10);
-}
-
-TEST_F(UnitConversion, constants) {
-  // Source: NIST "2014 CODATA recommended values"
-  EXPECT_NEAR(299792458, constants::c(), 5.0e-9);
-  EXPECT_NEAR(6.67408e-11, constants::G(), 5.0e-17);
-  EXPECT_NEAR(6.626070040e-34, constants::h(), 5.0e-44);
-  EXPECT_NEAR(1.2566370614e-6, constants::mu0(), 5.0e-17);
-  EXPECT_NEAR(8.854187817e-12, constants::epsilon0(), 5.0e-21);
-  EXPECT_NEAR(376.73031346177, constants::Z0(), 5.0e-12);
-  EXPECT_NEAR(8987551787.3681764, constants::k_e(), 5.0e-6);
-  EXPECT_NEAR(1.6021766208e-19, constants::e(), 5.0e-29);
-  EXPECT_NEAR(9.10938356e-31, constants::m_e(), 5.0e-40);
-  EXPECT_NEAR(1.672621898e-27, constants::m_p(), 5.0e-37);
-  EXPECT_NEAR(9.274009994e-24, constants::mu_B(), 5.0e-32);
-  EXPECT_NEAR(6.022140857e23, constants::N_A(), 5.0e14);
-  EXPECT_NEAR(8.3144598, constants::R(), 5.0e-8);
-  EXPECT_NEAR(1.38064852e-23, constants::k_B(), 5.0e-31);
-  EXPECT_NEAR(96485.33289, constants::F(), 5.0e-5);
-  EXPECT_NEAR(5.670367e-8, constants::sigma(), 5.0e-14);
-}
-
-TEST_F(UnitConversion, std_chrono) {
-  nanosecond_t a = std::chrono::nanoseconds(10);
-  EXPECT_EQ(nanosecond_t(10), a);
-  microsecond_t b = std::chrono::microseconds(10);
-  EXPECT_EQ(microsecond_t(10), b);
-  millisecond_t c = std::chrono::milliseconds(10);
-  EXPECT_EQ(millisecond_t(10), c);
-  second_t d = std::chrono::seconds(1);
-  EXPECT_EQ(second_t(1), d);
-  minute_t e = std::chrono::minutes(120);
-  EXPECT_EQ(minute_t(120), e);
-  hour_t f = std::chrono::hours(2);
-  EXPECT_EQ(hour_t(2), f);
-
-  std::chrono::nanoseconds g = nanosecond_t(100);
-  EXPECT_EQ(std::chrono::duration_cast<std::chrono::nanoseconds>(g).count(),
-            100);
-  std::chrono::nanoseconds h = microsecond_t(2);
-  EXPECT_EQ(std::chrono::duration_cast<std::chrono::nanoseconds>(h).count(),
-            2000);
-  std::chrono::nanoseconds i = millisecond_t(1);
-  EXPECT_EQ(std::chrono::duration_cast<std::chrono::nanoseconds>(i).count(),
-            1000000);
-  std::chrono::nanoseconds j = second_t(1);
-  EXPECT_EQ(std::chrono::duration_cast<std::chrono::nanoseconds>(j).count(),
-            1000000000);
-  std::chrono::nanoseconds k = minute_t(1);
-  EXPECT_EQ(std::chrono::duration_cast<std::chrono::nanoseconds>(k).count(),
-            60000000000);
-  std::chrono::nanoseconds l = hour_t(1);
-  EXPECT_EQ(std::chrono::duration_cast<std::chrono::nanoseconds>(l).count(),
-            3600000000000);
-}
-
-TEST_F(UnitConversion, squaredTemperature) {
-  using squared_celsius = units::compound_unit<squared<celsius>>;
-  using squared_celsius_t = units::unit_t<squared_celsius>;
-  const squared_celsius_t right(100);
-  const celsius_t rootRight = units::math::sqrt(right);
-  EXPECT_EQ(celsius_t(10), rootRight);
-}
-
-TEST_F(UnitMath, min) {
-  meter_t a(1);
-  foot_t c(1);
-  EXPECT_EQ(c, math::min(a, c));
-}
-
-TEST_F(UnitMath, max) {
-  meter_t a(1);
-  foot_t c(1);
-  EXPECT_EQ(a, math::max(a, c));
-}
-
-TEST_F(UnitMath, cos) {
-  EXPECT_TRUE((std::is_same<typename std::decay<scalar_t>::type,
-                            typename std::decay<decltype(
-                                cos(angle::radian_t(0)))>::type>::value));
-  EXPECT_NEAR(scalar_t(-0.41614683654), cos(angle::radian_t(2)), 5.0e-11);
-  EXPECT_NEAR(scalar_t(-0.70710678118), cos(angle::degree_t(135)),
-              5.0e-11);
-}
-
-TEST_F(UnitMath, sin) {
-  EXPECT_TRUE((std::is_same<typename std::decay<scalar_t>::type,
-                            typename std::decay<decltype(
-                                sin(angle::radian_t(0)))>::type>::value));
-  EXPECT_NEAR(scalar_t(0.90929742682), sin(angle::radian_t(2)), 5.0e-11);
-  EXPECT_NEAR(scalar_t(0.70710678118), sin(angle::degree_t(135)), 5.0e-11);
-}
-
-TEST_F(UnitMath, tan) {
-  EXPECT_TRUE((std::is_same<typename std::decay<scalar_t>::type,
-                            typename std::decay<decltype(
-                                tan(angle::radian_t(0)))>::type>::value));
-  EXPECT_NEAR(scalar_t(-2.18503986326), tan(angle::radian_t(2)), 5.0e-11);
-  EXPECT_NEAR(scalar_t(-1.0), tan(angle::degree_t(135)), 5.0e-11);
-}
-
-TEST_F(UnitMath, acos) {
-  EXPECT_TRUE(
-      (std::is_same<
-          typename std::decay<angle::radian_t>::type,
-          typename std::decay<decltype(acos(scalar_t(0)))>::type>::value));
-  EXPECT_NEAR(angle::radian_t(2).to<double>(),
-              acos(scalar_t(-0.41614683654)).to<double>(), 5.0e-11);
-  EXPECT_NEAR(
-      angle::degree_t(135).to<double>(),
-      angle::degree_t(acos(scalar_t(-0.70710678118654752440084436210485)))
-          .to<double>(),
-      5.0e-12);
-}
-
-TEST_F(UnitMath, asin) {
-  EXPECT_TRUE(
-      (std::is_same<
-          typename std::decay<angle::radian_t>::type,
-          typename std::decay<decltype(asin(scalar_t(0)))>::type>::value));
-  EXPECT_NEAR(angle::radian_t(1.14159265).to<double>(),
-              asin(scalar_t(0.90929742682)).to<double>(), 5.0e-9);
-  EXPECT_NEAR(
-      angle::degree_t(45).to<double>(),
-      angle::degree_t(asin(scalar_t(0.70710678118654752440084436210485)))
-          .to<double>(),
-      5.0e-12);
-}
-
-TEST_F(UnitMath, atan) {
-  EXPECT_TRUE(
-      (std::is_same<
-          typename std::decay<angle::radian_t>::type,
-          typename std::decay<decltype(atan(scalar_t(0)))>::type>::value));
-  EXPECT_NEAR(angle::radian_t(-1.14159265).to<double>(),
-              atan(scalar_t(-2.18503986326)).to<double>(), 5.0e-9);
-  EXPECT_NEAR(angle::degree_t(-45).to<double>(),
-              angle::degree_t(atan(scalar_t(-1.0))).to<double>(), 5.0e-12);
-}
-
-TEST_F(UnitMath, atan2) {
-  EXPECT_TRUE((std::is_same<typename std::decay<angle::radian_t>::type,
-                            typename std::decay<decltype(atan2(
-                                scalar_t(1), scalar_t(1)))>::type>::value));
-  EXPECT_NEAR(angle::radian_t(constants::detail::PI_VAL / 4).to<double>(),
-              atan2(scalar_t(2), scalar_t(2)).to<double>(), 5.0e-12);
-  EXPECT_NEAR(
-      angle::degree_t(45).to<double>(),
-      angle::degree_t(atan2(scalar_t(2), scalar_t(2))).to<double>(),
-      5.0e-12);
-
-  EXPECT_TRUE((std::is_same<typename std::decay<angle::radian_t>::type,
-                            typename std::decay<decltype(atan2(
-                                scalar_t(1), scalar_t(1)))>::type>::value));
-  EXPECT_NEAR(angle::radian_t(constants::detail::PI_VAL / 6).to<double>(),
-              atan2(scalar_t(1), scalar_t(std::sqrt(3))).to<double>(),
-              5.0e-12);
-  EXPECT_NEAR(angle::degree_t(30).to<double>(),
-              angle::degree_t(atan2(scalar_t(1), scalar_t(std::sqrt(3))))
-                  .to<double>(),
-              5.0e-12);
-}
-
-TEST_F(UnitMath, cosh) {
-  EXPECT_TRUE((std::is_same<typename std::decay<scalar_t>::type,
-                            typename std::decay<decltype(
-                                cosh(angle::radian_t(0)))>::type>::value));
-  EXPECT_NEAR(scalar_t(3.76219569108), cosh(angle::radian_t(2)), 5.0e-11);
-  EXPECT_NEAR(scalar_t(5.32275215), cosh(angle::degree_t(135)), 5.0e-9);
-}
-
-TEST_F(UnitMath, sinh) {
-  EXPECT_TRUE((std::is_same<typename std::decay<scalar_t>::type,
-                            typename std::decay<decltype(
-                                sinh(angle::radian_t(0)))>::type>::value));
-  EXPECT_NEAR(scalar_t(3.62686040785), sinh(angle::radian_t(2)), 5.0e-11);
-  EXPECT_NEAR(scalar_t(5.22797192), sinh(angle::degree_t(135)), 5.0e-9);
-}
-
-TEST_F(UnitMath, tanh) {
-  EXPECT_TRUE((std::is_same<typename std::decay<scalar_t>::type,
-                            typename std::decay<decltype(
-                                tanh(angle::radian_t(0)))>::type>::value));
-  EXPECT_NEAR(scalar_t(0.96402758007), tanh(angle::radian_t(2)), 5.0e-11);
-  EXPECT_NEAR(scalar_t(0.98219338), tanh(angle::degree_t(135)), 5.0e-11);
-}
-
-TEST_F(UnitMath, acosh) {
-  EXPECT_TRUE((std::is_same<typename std::decay<angle::radian_t>::type,
-                            typename std::decay<decltype(
-                                acosh(scalar_t(0)))>::type>::value));
-  EXPECT_NEAR(angle::radian_t(1.316957896924817).to<double>(),
-              acosh(scalar_t(2.0)).to<double>(), 5.0e-11);
-  EXPECT_NEAR(angle::degree_t(75.456129290216893).to<double>(),
-              angle::degree_t(acosh(scalar_t(2.0))).to<double>(), 5.0e-12);
-}
-
-TEST_F(UnitMath, asinh) {
-  EXPECT_TRUE((std::is_same<typename std::decay<angle::radian_t>::type,
-                            typename std::decay<decltype(
-                                asinh(scalar_t(0)))>::type>::value));
-  EXPECT_NEAR(angle::radian_t(1.443635475178810).to<double>(),
-              asinh(scalar_t(2)).to<double>(), 5.0e-9);
-  EXPECT_NEAR(angle::degree_t(82.714219883108939).to<double>(),
-              angle::degree_t(asinh(scalar_t(2))).to<double>(), 5.0e-12);
-}
-
-TEST_F(UnitMath, atanh) {
-  EXPECT_TRUE((std::is_same<typename std::decay<angle::radian_t>::type,
-                            typename std::decay<decltype(
-                                atanh(scalar_t(0)))>::type>::value));
-  EXPECT_NEAR(angle::radian_t(0.549306144334055).to<double>(),
-              atanh(scalar_t(0.5)).to<double>(), 5.0e-9);
-  EXPECT_NEAR(angle::degree_t(31.472923730945389).to<double>(),
-              angle::degree_t(atanh(scalar_t(0.5))).to<double>(), 5.0e-12);
-}
-
-TEST_F(UnitMath, exp) {
-  double val = 10.0;
-  EXPECT_EQ(std::exp(val), exp(scalar_t(val)));
-}
-
-TEST_F(UnitMath, log) {
-  double val = 100.0;
-  EXPECT_EQ(std::log(val), log(scalar_t(val)));
-}
-
-TEST_F(UnitMath, log10) {
-  double val = 100.0;
-  EXPECT_EQ(std::log10(val), log10(scalar_t(val)));
-}
-
-TEST_F(UnitMath, modf) {
-  double val = 100.0;
-  double modfr1;
-  scalar_t modfr2;
-  EXPECT_EQ(std::modf(val, &modfr1), modf(scalar_t(val), &modfr2));
-  EXPECT_EQ(modfr1, modfr2);
-}
-
-TEST_F(UnitMath, exp2) {
-  double val = 10.0;
-  EXPECT_EQ(std::exp2(val), exp2(scalar_t(val)));
-}
-
-TEST_F(UnitMath, expm1) {
-  double val = 10.0;
-  EXPECT_EQ(std::expm1(val), expm1(scalar_t(val)));
-}
-
-TEST_F(UnitMath, log1p) {
-  double val = 10.0;
-  EXPECT_EQ(std::log1p(val), log1p(scalar_t(val)));
-}
-
-TEST_F(UnitMath, log2) {
-  double val = 10.0;
-  EXPECT_EQ(std::log2(val), log2(scalar_t(val)));
-}
-
-TEST_F(UnitMath, pow) {
-  bool isSame;
-  meter_t value(10.0);
-
-  auto sq = pow<2>(value);
-  EXPECT_NEAR(100.0, sq(), 5.0e-2);
-  isSame = std::is_same<decltype(sq), square_meter_t>::value;
-  EXPECT_TRUE(isSame);
-
-  auto cube = pow<3>(value);
-  EXPECT_NEAR(1000.0, cube(), 5.0e-2);
-  isSame = std::is_same<decltype(cube), unit_t<cubed<meter>>>::value;
-  EXPECT_TRUE(isSame);
-
-  auto fourth = pow<4>(value);
-  EXPECT_NEAR(10000.0, fourth(), 5.0e-2);
-  isSame = std::is_same<
-      decltype(fourth),
-      unit_t<compound_unit<squared<meter>, squared<meter>>>>::value;
-  EXPECT_TRUE(isSame);
-}
-
-TEST_F(UnitMath, sqrt) {
-  EXPECT_TRUE((std::is_same<typename std::decay<meter_t>::type,
-                            typename std::decay<decltype(sqrt(
-                                square_meter_t(4.0)))>::type>::value));
-  EXPECT_NEAR(meter_t(2.0).to<double>(),
-              sqrt(square_meter_t(4.0)).to<double>(), 5.0e-9);
-
-  EXPECT_TRUE((std::is_same<typename std::decay<angle::radian_t>::type,
-                            typename std::decay<decltype(
-                                sqrt(steradian_t(16.0)))>::type>::value));
-  EXPECT_NEAR(angle::radian_t(4.0).to<double>(),
-              sqrt(steradian_t(16.0)).to<double>(), 5.0e-9);
-
-  EXPECT_TRUE((std::is_convertible<typename std::decay<foot_t>::type,
-                                   typename std::decay<decltype(sqrt(
-                                       square_foot_t(10.0)))>::type>::value));
-
-  // for rational conversion (i.e. no integral root) let's check a bunch of
-  // different ways this could go wrong
-  foot_t resultFt = sqrt(square_foot_t(10.0));
-  EXPECT_NEAR(foot_t(3.16227766017).to<double>(),
-              sqrt(square_foot_t(10.0)).to<double>(), 5.0e-9);
-  EXPECT_NEAR(foot_t(3.16227766017).to<double>(), resultFt.to<double>(),
-              5.0e-9);
-  EXPECT_EQ(resultFt, sqrt(square_foot_t(10.0)));
-}
-
-TEST_F(UnitMath, hypot) {
-  EXPECT_TRUE((std::is_same<typename std::decay<meter_t>::type,
-                            typename std::decay<decltype(hypot(
-                                meter_t(3.0), meter_t(4.0)))>::type>::value));
-  EXPECT_NEAR(meter_t(5.0).to<double>(),
-              (hypot(meter_t(3.0), meter_t(4.0))).to<double>(), 5.0e-9);
-
-  EXPECT_TRUE((std::is_same<typename std::decay<foot_t>::type,
-                            typename std::decay<decltype(hypot(
-                                foot_t(3.0), meter_t(1.2192)))>::type>::value));
-  EXPECT_NEAR(foot_t(5.0).to<double>(),
-              (hypot(foot_t(3.0), meter_t(1.2192))).to<double>(), 5.0e-9);
-}
-
-TEST_F(UnitMath, ceil) {
-  double val = 101.1;
-  EXPECT_EQ(std::ceil(val), ceil(meter_t(val)).to<double>());
-  EXPECT_TRUE((std::is_same<typename std::decay<meter_t>::type,
-                            typename std::decay<decltype(
-                                ceil(meter_t(val)))>::type>::value));
-}
-
-TEST_F(UnitMath, floor) {
-  double val = 101.1;
-  EXPECT_EQ(std::floor(val), floor(scalar_t(val)));
-}
-
-TEST_F(UnitMath, fmod) {
-  EXPECT_EQ(std::fmod(100.0, 101.2),
-            fmod(meter_t(100.0), meter_t(101.2)).to<double>());
-}
-
-TEST_F(UnitMath, trunc) {
-  double val = 101.1;
-  EXPECT_EQ(std::trunc(val), trunc(scalar_t(val)));
-}
-
-TEST_F(UnitMath, round) {
-  double val = 101.1;
-  EXPECT_EQ(std::round(val), round(scalar_t(val)));
-}
-
-TEST_F(UnitMath, copysign) {
-  double sign = -1;
-  meter_t val(5.0);
-  EXPECT_EQ(meter_t(-5.0), copysign(val, sign));
-  EXPECT_EQ(meter_t(-5.0), copysign(val, angle::radian_t(sign)));
-}
-
-TEST_F(UnitMath, fdim) {
-  EXPECT_EQ(meter_t(0.0), fdim(meter_t(8.0), meter_t(10.0)));
-  EXPECT_EQ(meter_t(2.0), fdim(meter_t(10.0), meter_t(8.0)));
-  EXPECT_NEAR(meter_t(9.3904).to<double>(),
-              fdim(meter_t(10.0), foot_t(2.0)).to<double>(),
-              5.0e-320);  // not sure why they aren't comparing exactly equal,
-                          // but clearly they are.
-}
-
-TEST_F(UnitMath, fmin) {
-  EXPECT_EQ(meter_t(8.0), fmin(meter_t(8.0), meter_t(10.0)));
-  EXPECT_EQ(meter_t(8.0), fmin(meter_t(10.0), meter_t(8.0)));
-  EXPECT_EQ(foot_t(2.0), fmin(meter_t(10.0), foot_t(2.0)));
-}
-
-TEST_F(UnitMath, fmax) {
-  EXPECT_EQ(meter_t(10.0), fmax(meter_t(8.0), meter_t(10.0)));
-  EXPECT_EQ(meter_t(10.0), fmax(meter_t(10.0), meter_t(8.0)));
-  EXPECT_EQ(meter_t(10.0), fmax(meter_t(10.0), foot_t(2.0)));
-}
-
-TEST_F(UnitMath, fabs) {
-  EXPECT_EQ(meter_t(10.0), fabs(meter_t(-10.0)));
-  EXPECT_EQ(meter_t(10.0), fabs(meter_t(10.0)));
-}
-
-TEST_F(UnitMath, abs) {
-  EXPECT_EQ(meter_t(10.0), abs(meter_t(-10.0)));
-  EXPECT_EQ(meter_t(10.0), abs(meter_t(10.0)));
-}
-
-TEST_F(UnitMath, fma) {
-  meter_t x(2.0);
-  meter_t y(3.0);
-  square_meter_t z(1.0);
-  EXPECT_EQ(square_meter_t(7.0), fma(x, y, z));
-}
-
-// Constexpr
-#if !defined(_MSC_VER) || _MSC_VER > 1800
-TEST_F(Constexpr, construction) {
-  constexpr meter_t result0(0);
-  constexpr auto result1 = make_unit<meter_t>(1);
-  constexpr auto result2 = meter_t(2);
-
-  EXPECT_EQ(meter_t(0), result0);
-  EXPECT_EQ(meter_t(1), result1);
-  EXPECT_EQ(meter_t(2), result2);
-
-  EXPECT_TRUE(noexcept(result0));
-  EXPECT_TRUE(noexcept(result1));
-  EXPECT_TRUE(noexcept(result2));
-}
-
-TEST_F(Constexpr, constants) {
-  EXPECT_TRUE(noexcept(constants::c()));
-  EXPECT_TRUE(noexcept(constants::G()));
-  EXPECT_TRUE(noexcept(constants::h()));
-  EXPECT_TRUE(noexcept(constants::mu0()));
-  EXPECT_TRUE(noexcept(constants::epsilon0()));
-  EXPECT_TRUE(noexcept(constants::Z0()));
-  EXPECT_TRUE(noexcept(constants::k_e()));
-  EXPECT_TRUE(noexcept(constants::e()));
-  EXPECT_TRUE(noexcept(constants::m_e()));
-  EXPECT_TRUE(noexcept(constants::m_p()));
-  EXPECT_TRUE(noexcept(constants::mu_B()));
-  EXPECT_TRUE(noexcept(constants::N_A()));
-  EXPECT_TRUE(noexcept(constants::R()));
-  EXPECT_TRUE(noexcept(constants::k_B()));
-  EXPECT_TRUE(noexcept(constants::F()));
-  EXPECT_TRUE(noexcept(constants::sigma()));
-}
-
-TEST_F(Constexpr, arithmetic) {
-  constexpr auto result0(1_m + 1_m);
-  constexpr auto result1(1_m - 1_m);
-  constexpr auto result2(1_m * 1_m);
-  constexpr auto result3(1_m / 1_m);
-  constexpr auto result4(meter_t(1) + meter_t(1));
-  constexpr auto result5(meter_t(1) - meter_t(1));
-  constexpr auto result6(meter_t(1) * meter_t(1));
-  constexpr auto result7(meter_t(1) / meter_t(1));
-  constexpr auto result8(units::math::cpow<2>(meter_t(2)));
-  constexpr auto result9 = units::math::cpow<3>(2_m);
-  constexpr auto result10 = 2_m * 2_m;
-
-  EXPECT_TRUE(noexcept(result0));
-  EXPECT_TRUE(noexcept(result1));
-  EXPECT_TRUE(noexcept(result2));
-  EXPECT_TRUE(noexcept(result3));
-  EXPECT_TRUE(noexcept(result4));
-  EXPECT_TRUE(noexcept(result5));
-  EXPECT_TRUE(noexcept(result6));
-  EXPECT_TRUE(noexcept(result7));
-  EXPECT_TRUE(noexcept(result8));
-  EXPECT_TRUE(noexcept(result9));
-  EXPECT_TRUE(noexcept(result10));
-
-  EXPECT_EQ(8_cu_m, result9);
-  EXPECT_EQ(4_sq_m, result10);
-}
-
-TEST_F(Constexpr, realtional) {
-  constexpr bool equalityTrue = (1_m == 1_m);
-  constexpr bool equalityFalse = (1_m == 2_m);
-  constexpr bool lessThanTrue = (1_m < 2_m);
-  constexpr bool lessThanFalse = (1_m < 1_m);
-  constexpr bool lessThanEqualTrue1 = (1_m <= 1_m);
-  constexpr bool lessThanEqualTrue2 = (1_m <= 2_m);
-  constexpr bool lessThanEqualFalse = (1_m < 0_m);
-  constexpr bool greaterThanTrue = (2_m > 1_m);
-  constexpr bool greaterThanFalse = (2_m > 2_m);
-  constexpr bool greaterThanEqualTrue1 = (2_m >= 1_m);
-  constexpr bool greaterThanEqualTrue2 = (2_m >= 2_m);
-  constexpr bool greaterThanEqualFalse = (2_m > 3_m);
-
-  EXPECT_TRUE(equalityTrue);
-  EXPECT_TRUE(lessThanTrue);
-  EXPECT_TRUE(lessThanEqualTrue1);
-  EXPECT_TRUE(lessThanEqualTrue2);
-  EXPECT_TRUE(greaterThanTrue);
-  EXPECT_TRUE(greaterThanEqualTrue1);
-  EXPECT_TRUE(greaterThanEqualTrue2);
-  EXPECT_FALSE(equalityFalse);
-  EXPECT_FALSE(lessThanFalse);
-  EXPECT_FALSE(lessThanEqualFalse);
-  EXPECT_FALSE(greaterThanFalse);
-  EXPECT_FALSE(greaterThanEqualFalse);
-}
-
-TEST_F(Constexpr, stdArray) {
-  constexpr std::array<meter_t, 5> arr = {0_m, 1_m, 2_m, 3_m, 4_m};
-  constexpr bool equal = (arr[3] == 3_m);
-  EXPECT_TRUE(equal);
-}
-
-#endif
-
-TEST_F(CompileTimeArithmetic, unit_value_t) {
-  typedef unit_value_t<meters, 3, 2> mRatio;
-  EXPECT_EQ(meter_t(1.5), mRatio::value());
-}
-
-TEST_F(CompileTimeArithmetic, is_unit_value_t) {
-  typedef unit_value_t<meters, 3, 2> mRatio;
-
-  EXPECT_TRUE((traits::is_unit_value_t<mRatio>::value));
-  EXPECT_FALSE((traits::is_unit_value_t<meter_t>::value));
-  EXPECT_FALSE((traits::is_unit_value_t<double>::value));
-
-  EXPECT_TRUE((traits::is_unit_value_t<mRatio, meters>::value));
-  EXPECT_FALSE((traits::is_unit_value_t<meter_t, meters>::value));
-  EXPECT_FALSE((traits::is_unit_value_t<double, meters>::value));
-}
-
-TEST_F(CompileTimeArithmetic, is_unit_value_t_category) {
-  typedef unit_value_t<feet, 3, 2> mRatio;
-  EXPECT_TRUE(
-      (traits::is_unit_value_t_category<category::length_unit, mRatio>::value));
-  EXPECT_FALSE(
-      (traits::is_unit_value_t_category<category::angle_unit, mRatio>::value));
-  EXPECT_FALSE((
-      traits::is_unit_value_t_category<category::length_unit, meter_t>::value));
-  EXPECT_FALSE(
-      (traits::is_unit_value_t_category<category::length_unit, double>::value));
-}
-
-TEST_F(CompileTimeArithmetic, unit_value_add) {
-  typedef unit_value_t<meters, 3, 2> mRatio;
-
-  using sum = unit_value_add<mRatio, mRatio>;
-  EXPECT_EQ(meter_t(3.0), sum::value());
-  EXPECT_TRUE(
-      (traits::is_unit_value_t_category<category::length_unit, sum>::value));
-
-  typedef unit_value_t<feet, 1> ftRatio;
-
-  using sumf = unit_value_add<ftRatio, mRatio>;
-  EXPECT_TRUE((
-      std::is_same<typename std::decay<foot_t>::type,
-                   typename std::decay<decltype(sumf::value())>::type>::value));
-  EXPECT_NEAR(5.92125984, sumf::value().to<double>(), 5.0e-8);
-  EXPECT_TRUE(
-      (traits::is_unit_value_t_category<category::length_unit, sumf>::value));
-
-  typedef unit_value_t<celsius, 1> cRatio;
-  typedef unit_value_t<fahrenheit, 2> fRatio;
-
-  using sumc = unit_value_add<cRatio, fRatio>;
-  EXPECT_TRUE((
-      std::is_same<typename std::decay<celsius_t>::type,
-                   typename std::decay<decltype(sumc::value())>::type>::value));
-  EXPECT_NEAR(2.11111111111, sumc::value().to<double>(), 5.0e-8);
-  EXPECT_TRUE((traits::is_unit_value_t_category<category::temperature_unit,
-                                                sumc>::value));
-
-  typedef unit_value_t<angle::radian, 1> rRatio;
-  typedef unit_value_t<angle::degree, 3> dRatio;
-
-  using sumr = unit_value_add<rRatio, dRatio>;
-  EXPECT_TRUE((
-      std::is_same<typename std::decay<angle::radian_t>::type,
-                   typename std::decay<decltype(sumr::value())>::type>::value));
-  EXPECT_NEAR(1.05235988, sumr::value().to<double>(), 5.0e-8);
-  EXPECT_TRUE(
-      (traits::is_unit_value_t_category<category::angle_unit, sumr>::value));
-}
-
-TEST_F(CompileTimeArithmetic, unit_value_subtract) {
-  typedef unit_value_t<meters, 3, 2> mRatio;
-
-  using diff = unit_value_subtract<mRatio, mRatio>;
-  EXPECT_EQ(meter_t(0), diff::value());
-  EXPECT_TRUE(
-      (traits::is_unit_value_t_category<category::length_unit, diff>::value));
-
-  typedef unit_value_t<feet, 1> ftRatio;
-
-  using difff = unit_value_subtract<ftRatio, mRatio>;
-  EXPECT_TRUE((std::is_same<
-               typename std::decay<foot_t>::type,
-               typename std::decay<decltype(difff::value())>::type>::value));
-  EXPECT_NEAR(-3.92125984, difff::value().to<double>(), 5.0e-8);
-  EXPECT_TRUE(
-      (traits::is_unit_value_t_category<category::length_unit, difff>::value));
-
-  typedef unit_value_t<celsius, 1> cRatio;
-  typedef unit_value_t<fahrenheit, 2> fRatio;
-
-  using diffc = unit_value_subtract<cRatio, fRatio>;
-  EXPECT_TRUE((std::is_same<
-               typename std::decay<celsius_t>::type,
-               typename std::decay<decltype(diffc::value())>::type>::value));
-  EXPECT_NEAR(-0.11111111111, diffc::value().to<double>(), 5.0e-8);
-  EXPECT_TRUE((traits::is_unit_value_t_category<category::temperature_unit,
-                                                diffc>::value));
-
-  typedef unit_value_t<angle::radian, 1> rRatio;
-  typedef unit_value_t<angle::degree, 3> dRatio;
-
-  using diffr = unit_value_subtract<rRatio, dRatio>;
-  EXPECT_TRUE((std::is_same<
-               typename std::decay<angle::radian_t>::type,
-               typename std::decay<decltype(diffr::value())>::type>::value));
-  EXPECT_NEAR(0.947640122, diffr::value().to<double>(), 5.0e-8);
-  EXPECT_TRUE(
-      (traits::is_unit_value_t_category<category::angle_unit, diffr>::value));
-}
-
-TEST_F(CompileTimeArithmetic, unit_value_multiply) {
-  typedef unit_value_t<meters, 2> mRatio;
-  typedef unit_value_t<feet, 656168, 100000> ftRatio;  // 2 meter
-
-  using product = unit_value_multiply<mRatio, mRatio>;
-  EXPECT_EQ(square_meter_t(4), product::value());
-  EXPECT_TRUE(
-      (traits::is_unit_value_t_category<category::area_unit, product>::value));
-
-  using productM = unit_value_multiply<mRatio, ftRatio>;
-
-  EXPECT_TRUE((std::is_same<
-               typename std::decay<square_meter_t>::type,
-               typename std::decay<decltype(productM::value())>::type>::value));
-  EXPECT_NEAR(4.0, productM::value().to<double>(), 5.0e-7);
-  EXPECT_TRUE(
-      (traits::is_unit_value_t_category<category::area_unit, productM>::value));
-
-  using productF = unit_value_multiply<ftRatio, mRatio>;
-  EXPECT_TRUE((std::is_same<
-               typename std::decay<square_foot_t>::type,
-               typename std::decay<decltype(productF::value())>::type>::value));
-  EXPECT_NEAR(43.0556444224, productF::value().to<double>(), 5.0e-6);
-  EXPECT_TRUE(
-      (traits::is_unit_value_t_category<category::area_unit, productF>::value));
-
-  using productF2 = unit_value_multiply<ftRatio, ftRatio>;
-  EXPECT_TRUE(
-      (std::is_same<
-          typename std::decay<square_foot_t>::type,
-          typename std::decay<decltype(productF2::value())>::type>::value));
-  EXPECT_NEAR(43.0556444224, productF2::value().to<double>(), 5.0e-8);
-  EXPECT_TRUE((
-      traits::is_unit_value_t_category<category::area_unit, productF2>::value));
-
-  typedef unit_value_t<units::force::newton, 5> nRatio;
-
-  using productN = unit_value_multiply<nRatio, ftRatio>;
-  EXPECT_FALSE(
-      (std::is_same<
-          typename std::decay<torque::newton_meter_t>::type,
-          typename std::decay<decltype(productN::value())>::type>::value));
-  EXPECT_TRUE((std::is_convertible<
-               typename std::decay<torque::newton_meter_t>::type,
-               typename std::decay<decltype(productN::value())>::type>::value));
-  EXPECT_NEAR(32.8084, productN::value().to<double>(), 5.0e-8);
-  EXPECT_NEAR(10.0, (productN::value().convert<newton_meter>().to<double>()),
-              5.0e-7);
-  EXPECT_TRUE((traits::is_unit_value_t_category<category::torque_unit,
-                                                productN>::value));
-
-  typedef unit_value_t<angle::radian, 11, 10> r1Ratio;
-  typedef unit_value_t<angle::radian, 22, 10> r2Ratio;
-
-  using productR = unit_value_multiply<r1Ratio, r2Ratio>;
-  EXPECT_TRUE((std::is_same<
-               typename std::decay<steradian_t>::type,
-               typename std::decay<decltype(productR::value())>::type>::value));
-  EXPECT_NEAR(2.42, productR::value().to<double>(), 5.0e-8);
-  EXPECT_NEAR(7944.39137,
-              (productR::value().convert<degrees_squared>().to<double>()),
-              5.0e-6);
-  EXPECT_TRUE((traits::is_unit_value_t_category<category::solid_angle_unit,
-                                                productR>::value));
-}
-
-TEST_F(CompileTimeArithmetic, unit_value_divide) {
-  typedef unit_value_t<meters, 2> mRatio;
-  typedef unit_value_t<feet, 656168, 100000> ftRatio;  // 2 meter
-
-  using product = unit_value_divide<mRatio, mRatio>;
-  EXPECT_EQ(scalar_t(1), product::value());
-  EXPECT_TRUE((
-      traits::is_unit_value_t_category<category::scalar_unit, product>::value));
-
-  using productM = unit_value_divide<mRatio, ftRatio>;
-
-  EXPECT_TRUE((std::is_same<
-               typename std::decay<scalar_t>::type,
-               typename std::decay<decltype(productM::value())>::type>::value));
-  EXPECT_NEAR(1, productM::value().to<double>(), 5.0e-7);
-  EXPECT_TRUE((traits::is_unit_value_t_category<category::scalar_unit,
-                                                productM>::value));
-
-  using productF = unit_value_divide<ftRatio, mRatio>;
-  EXPECT_TRUE((std::is_same<
-               typename std::decay<scalar_t>::type,
-               typename std::decay<decltype(productF::value())>::type>::value));
-  EXPECT_NEAR(1.0, productF::value().to<double>(), 5.0e-6);
-  EXPECT_TRUE((traits::is_unit_value_t_category<category::scalar_unit,
-                                                productF>::value));
-
-  using productF2 = unit_value_divide<ftRatio, ftRatio>;
-  EXPECT_TRUE(
-      (std::is_same<
-          typename std::decay<scalar_t>::type,
-          typename std::decay<decltype(productF2::value())>::type>::value));
-  EXPECT_NEAR(1.0, productF2::value().to<double>(), 5.0e-8);
-  EXPECT_TRUE((traits::is_unit_value_t_category<category::scalar_unit,
-                                                productF2>::value));
-
-  typedef unit_value_t<seconds, 10> sRatio;
-
-  using productMS = unit_value_divide<mRatio, sRatio>;
-  EXPECT_TRUE(
-      (std::is_same<
-          typename std::decay<meters_per_second_t>::type,
-          typename std::decay<decltype(productMS::value())>::type>::value));
-  EXPECT_NEAR(0.2, productMS::value().to<double>(), 5.0e-8);
-  EXPECT_TRUE((traits::is_unit_value_t_category<category::velocity_unit,
-                                                productMS>::value));
-
-  typedef unit_value_t<angle::radian, 20> rRatio;
-
-  using productRS = unit_value_divide<rRatio, sRatio>;
-  EXPECT_TRUE(
-      (std::is_same<
-          typename std::decay<radians_per_second_t>::type,
-          typename std::decay<decltype(productRS::value())>::type>::value));
-  EXPECT_NEAR(2, productRS::value().to<double>(), 5.0e-8);
-  EXPECT_NEAR(114.592,
-              (productRS::value().convert<degrees_per_second>().to<double>()),
-              5.0e-4);
-  EXPECT_TRUE((traits::is_unit_value_t_category<category::angular_velocity_unit,
-                                                productRS>::value));
-}
-
-TEST_F(CompileTimeArithmetic, unit_value_power) {
-  typedef unit_value_t<meters, 2> mRatio;
-
-  using sq = unit_value_power<mRatio, 2>;
-  EXPECT_TRUE((std::is_convertible<
-               typename std::decay<square_meter_t>::type,
-               typename std::decay<decltype(sq::value())>::type>::value));
-  EXPECT_NEAR(4, sq::value().to<double>(), 5.0e-8);
-  EXPECT_TRUE(
-      (traits::is_unit_value_t_category<category::area_unit, sq>::value));
-
-  typedef unit_value_t<angle::radian, 18, 10> rRatio;
-
-  using sqr = unit_value_power<rRatio, 2>;
-  EXPECT_TRUE((std::is_convertible<
-               typename std::decay<steradian_t>::type,
-               typename std::decay<decltype(sqr::value())>::type>::value));
-  EXPECT_NEAR(3.24, sqr::value().to<double>(), 5.0e-8);
-  EXPECT_NEAR(10636.292574038049895092690529904,
-              (sqr::value().convert<degrees_squared>().to<double>()), 5.0e-10);
-  EXPECT_TRUE((traits::is_unit_value_t_category<category::solid_angle_unit,
-                                                sqr>::value));
-}
-
-TEST_F(CompileTimeArithmetic, unit_value_sqrt) {
-  typedef unit_value_t<square_meters, 10> mRatio;
-
-  using root = unit_value_sqrt<mRatio>;
-  EXPECT_TRUE((std::is_convertible<
-               typename std::decay<meter_t>::type,
-               typename std::decay<decltype(root::value())>::type>::value));
-  EXPECT_NEAR(3.16227766017, root::value().to<double>(), 5.0e-9);
-  EXPECT_TRUE(
-      (traits::is_unit_value_t_category<category::length_unit, root>::value));
-
-  typedef unit_value_t<hectare, 51, 7> hRatio;
-
-  using rooth = unit_value_sqrt<hRatio, 100000000>;
-  EXPECT_TRUE((std::is_convertible<
-               typename std::decay<mile_t>::type,
-               typename std::decay<decltype(rooth::value())>::type>::value));
-  EXPECT_NEAR(2.69920623253, rooth::value().to<double>(), 5.0e-8);
-  EXPECT_NEAR(269.920623, rooth::value().convert<meters>().to<double>(),
-              5.0e-6);
-  EXPECT_TRUE(
-      (traits::is_unit_value_t_category<category::length_unit, rooth>::value));
-
-  typedef unit_value_t<steradian, 18, 10> rRatio;
-
-  using rootr = unit_value_sqrt<rRatio>;
-  EXPECT_TRUE((traits::is_angle_unit<decltype(rootr::value())>::value));
-  EXPECT_NEAR(1.3416407865, rootr::value().to<double>(), 5.0e-8);
-  EXPECT_NEAR(76.870352574,
-              rootr::value().convert<angle::degrees>().to<double>(), 5.0e-6);
-  EXPECT_TRUE(
-      (traits::is_unit_value_t_category<category::angle_unit, rootr>::value));
-}
-
-TEST_F(CaseStudies, radarRangeEquation) {
-  watt_t P_t;            // transmit power
-  scalar_t G;            // gain
-  meter_t lambda;        // wavelength
-  square_meter_t sigma;  // radar cross section
-  meter_t R;             // range
-  kelvin_t T_s;          // system noise temp
-  hertz_t B_n;           // bandwidth
-  scalar_t L;            // loss
-
-  P_t = megawatt_t(1.4);
-  G = dB_t(33.0);
-  lambda = constants::c / megahertz_t(2800);
-  sigma = square_meter_t(1.0);
-  R = meter_t(111000.0);
-  T_s = kelvin_t(950.0);
-  B_n = megahertz_t(1.67);
-  L = dB_t(8.0);
-
-  scalar_t SNR = (P_t * math::pow<2>(G) * math::pow<2>(lambda) * sigma) /
-                 (math::pow<3>(4 * constants::pi) * math::pow<4>(R) *
-                  constants::k_B * T_s * B_n * L);
-
-  EXPECT_NEAR(1.535, SNR(), 5.0e-4);
-}
-
-TEST_F(CaseStudies, pythagoreanTheorum) {
-  EXPECT_EQ(meter_t(3), RightTriangle::a::value());
-  EXPECT_EQ(meter_t(4), RightTriangle::b::value());
-  EXPECT_EQ(meter_t(5), RightTriangle::c::value());
-  EXPECT_TRUE(pow<2>(RightTriangle::a::value()) +
-                  pow<2>(RightTriangle::b::value()) ==
-              pow<2>(RightTriangle::c::value()));
-}
diff --git a/wpiutil/src/test/native/cpp/uv/UvGetAddrInfoTest.cpp b/wpiutil/src/test/native/cpp/uv/UvGetAddrInfoTest.cpp
index 11ac426..20d27f1 100644
--- a/wpiutil/src/test/native/cpp/uv/UvGetAddrInfoTest.cpp
+++ b/wpiutil/src/test/native/cpp/uv/UvGetAddrInfoTest.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2018 FIRST. All Rights Reserved.                             */
+/* Copyright (c) 2018-2020 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -46,7 +46,8 @@
     fail_cb_called++;
   });
 
-  GetAddrInfo(loop, [](const addrinfo&) { FAIL(); }, Twine::createNull());
+  GetAddrInfo(
+      loop, [](const addrinfo&) { FAIL(); }, Twine::createNull());
   loop->Run();
   ASSERT_EQ(fail_cb_called, 1);
 }
@@ -62,7 +63,8 @@
   });
 
   // Use a FQDN by ending in a period
-  GetAddrInfo(loop, [](const addrinfo&) { FAIL(); }, "xyzzy.xyzzy.xyzzy.");
+  GetAddrInfo(
+      loop, [](const addrinfo&) { FAIL(); }, "xyzzy.xyzzy.xyzzy.");
   loop->Run();
   ASSERT_EQ(fail_cb_called, 1);
 }
@@ -73,7 +75,8 @@
   auto loop = Loop::Create();
   loop->error.connect([](Error) { FAIL(); });
 
-  GetAddrInfo(loop, [&](const addrinfo&) { getaddrinfo_cbs++; }, "localhost");
+  GetAddrInfo(
+      loop, [&](const addrinfo&) { getaddrinfo_cbs++; }, "localhost");
 
   loop->Run();
 
@@ -90,12 +93,13 @@
 
   for (int i = 0; i < CONCURRENT_COUNT; i++) {
     callback_counts[i] = 0;
-    GetAddrInfo(loop,
-                [i, &callback_counts, &getaddrinfo_cbs](const addrinfo&) {
-                  callback_counts[i]++;
-                  getaddrinfo_cbs++;
-                },
-                "localhost");
+    GetAddrInfo(
+        loop,
+        [i, &callback_counts, &getaddrinfo_cbs](const addrinfo&) {
+          callback_counts[i]++;
+          getaddrinfo_cbs++;
+        },
+        "localhost");
   }
 
   loop->Run();
diff --git a/wpiutil/src/test/native/cpp/uv/UvGetNameInfoTest.cpp b/wpiutil/src/test/native/cpp/uv/UvGetNameInfoTest.cpp
index 16de329..76d22d9 100644
--- a/wpiutil/src/test/native/cpp/uv/UvGetNameInfoTest.cpp
+++ b/wpiutil/src/test/native/cpp/uv/UvGetNameInfoTest.cpp
@@ -1,5 +1,5 @@
 /*----------------------------------------------------------------------------*/
-/* Copyright (c) 2018 FIRST. All Rights Reserved.                             */
+/* Copyright (c) 2018-2020 FIRST. All Rights Reserved.                        */
 /* Open Source Software - may be modified and shared by FRC teams. The code   */
 /* must be accompanied by the FIRST BSD license file in the root directory of */
 /* the project.                                                               */
@@ -41,13 +41,14 @@
   auto loop = Loop::Create();
   loop->error.connect([](Error) { FAIL(); });
 
-  GetNameInfo4(loop,
-               [&](const char* hostname, const char* service) {
-                 ASSERT_NE(hostname, nullptr);
-                 ASSERT_NE(service, nullptr);
-                 getnameinfo_cbs++;
-               },
-               "127.0.0.1", 80);
+  GetNameInfo4(
+      loop,
+      [&](const char* hostname, const char* service) {
+        ASSERT_NE(hostname, nullptr);
+        ASSERT_NE(service, nullptr);
+        getnameinfo_cbs++;
+      },
+      "127.0.0.1", 80);
 
   loop->Run();
 
@@ -60,13 +61,14 @@
   auto loop = Loop::Create();
   loop->error.connect([](Error) { FAIL(); });
 
-  GetNameInfo6(loop,
-               [&](const char* hostname, const char* service) {
-                 ASSERT_NE(hostname, nullptr);
-                 ASSERT_NE(service, nullptr);
-                 getnameinfo_cbs++;
-               },
-               "::1", 80);
+  GetNameInfo6(
+      loop,
+      [&](const char* hostname, const char* service) {
+        ASSERT_NE(hostname, nullptr);
+        ASSERT_NE(service, nullptr);
+        getnameinfo_cbs++;
+      },
+      "::1", 80);
 
   loop->Run();
 
