#include <gsl/gsl_test.h>
#include <gsl/gsl_ieee_utils.h>
#include <gsl/gsl_math.h>
#include "gsl_cblas.h"

#include "tests.h"

void
test_tbmv (void) {
const double flteps = 1e-4, dbleps = 1e-6;
  {
   int order = 101;
   int trans = 111;
   int uplo = 121;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { 0.439f, -0.484f, -0.952f, -0.508f, 0.381f, -0.889f, -0.192f, -0.279f, -0.155f };
   float X[] = { -0.089f, -0.688f, -0.203f };
   int incX = -1;
   float x_expected[] = { 0.017088f, 0.315595f, 0.243875f };
   cblas_stbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stbmv(case 894)");
     }
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 121;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { 0.439f, -0.484f, -0.952f, -0.508f, 0.381f, -0.889f, -0.192f, -0.279f, -0.155f };
   float X[] = { -0.089f, -0.688f, -0.203f };
   int incX = -1;
   float x_expected[] = { -0.089f, -0.721909f, 0.129992f };
   cblas_stbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stbmv(case 895)");
     }
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 122;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { 0.439f, -0.484f, -0.952f, -0.508f, 0.381f, -0.889f, -0.192f, -0.279f, -0.155f };
   float X[] = { -0.089f, -0.688f, -0.203f };
   int incX = -1;
   float x_expected[] = { 0.156927f, -0.159004f, 0.098252f };
   cblas_stbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stbmv(case 896)");
     }
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 122;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { 0.439f, -0.484f, -0.952f, -0.508f, 0.381f, -0.889f, -0.192f, -0.279f, -0.155f };
   float X[] = { -0.089f, -0.688f, -0.203f };
   int incX = -1;
   float x_expected[] = { 0.043096f, -0.584876f, -0.203f };
   cblas_stbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stbmv(case 897)");
     }
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 121;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { 0.439f, -0.484f, -0.952f, -0.508f, 0.381f, -0.889f, -0.192f, -0.279f, -0.155f };
   float X[] = { -0.089f, -0.688f, -0.203f };
   int incX = -1;
   float x_expected[] = { 0.024831f, -0.24504f, 0.447756f };
   cblas_stbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stbmv(case 898)");
     }
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 121;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { 0.439f, -0.484f, -0.952f, -0.508f, 0.381f, -0.889f, -0.192f, -0.279f, -0.155f };
   float X[] = { -0.089f, -0.688f, -0.203f };
   int incX = -1;
   float x_expected[] = { -0.089f, -0.670912f, 0.146504f };
   cblas_stbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stbmv(case 899)");
     }
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 122;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { 0.439f, -0.484f, -0.952f, -0.508f, 0.381f, -0.889f, -0.192f, -0.279f, -0.155f };
   float X[] = { -0.089f, -0.688f, -0.203f };
   int incX = -1;
   float x_expected[] = { -0.24504f, 0.447756f, -0.089117f };
   cblas_stbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stbmv(case 900)");
     }
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 122;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { 0.439f, -0.484f, -0.952f, -0.508f, 0.381f, -0.889f, -0.192f, -0.279f, -0.155f };
   float X[] = { -0.089f, -0.688f, -0.203f };
   int incX = -1;
   float x_expected[] = { -0.351128f, -0.589748f, -0.203f };
   cblas_stbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stbmv(case 901)");
     }
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 121;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { 0.94f, -0.091f, 0.984f, -0.276f, -0.342f, -0.484f, -0.665f, -0.2f, 0.349f };
   float X[] = { 0.023f, -0.501f, -0.562f };
   int incX = -1;
   float x_expected[] = { 0.156047f, 0.189418f, -0.52828f };
   cblas_stbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stbmv(case 902)");
     }
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 121;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { 0.94f, -0.091f, 0.984f, -0.276f, -0.342f, -0.484f, -0.665f, -0.2f, 0.349f };
   float X[] = { 0.023f, -0.501f, -0.562f };
   int incX = -1;
   float x_expected[] = { 0.194342f, -0.449858f, -0.562f };
   cblas_stbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stbmv(case 903)");
     }
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 122;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { 0.94f, -0.091f, 0.984f, -0.276f, -0.342f, -0.484f, -0.665f, -0.2f, 0.349f };
   float X[] = { 0.023f, -0.501f, -0.562f };
   int incX = -1;
   float x_expected[] = { -0.0046f, 0.156047f, 0.189418f };
   cblas_stbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stbmv(case 904)");
     }
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 122;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { 0.94f, -0.091f, 0.984f, -0.276f, -0.342f, -0.484f, -0.665f, -0.2f, 0.349f };
   float X[] = { 0.023f, -0.501f, -0.562f };
   int incX = -1;
   float x_expected[] = { 0.023f, -0.516295f, -0.423724f };
   cblas_stbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stbmv(case 905)");
     }
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 121;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { 0.94f, -0.091f, 0.984f, -0.276f, -0.342f, -0.484f, -0.665f, -0.2f, 0.349f };
   float X[] = { 0.023f, -0.501f, -0.562f };
   int incX = -1;
   float x_expected[] = { 0.328565f, 0.326454f, 0.051142f };
   cblas_stbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stbmv(case 906)");
     }
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 121;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { 0.94f, -0.091f, 0.984f, -0.276f, -0.342f, -0.484f, -0.665f, -0.2f, 0.349f };
   float X[] = { 0.023f, -0.501f, -0.562f };
   int incX = -1;
   float x_expected[] = { 0.356165f, -0.345888f, -0.562f };
   cblas_stbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stbmv(case 907)");
     }
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 122;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { 0.94f, -0.091f, 0.984f, -0.276f, -0.342f, -0.484f, -0.665f, -0.2f, 0.349f };
   float X[] = { 0.023f, -0.501f, -0.562f };
   int incX = -1;
   float x_expected[] = { -0.015295f, 0.13041f, -0.482689f };
   cblas_stbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stbmv(case 908)");
     }
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 122;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { 0.94f, -0.091f, 0.984f, -0.276f, -0.342f, -0.484f, -0.665f, -0.2f, 0.349f };
   float X[] = { 0.023f, -0.501f, -0.562f };
   int incX = -1;
   float x_expected[] = { 0.023f, -0.508866f, -0.516409f };
   cblas_stbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stbmv(case 909)");
     }
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 121;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { 0.566, 0.955, -0.086, -0.856, 0.177, 0.974, -0.652, -0.884, 0.77 };
   double X[] = { -0.77, -0.818, 0.337 };
   int incX = -1;
   double x_expected[] = { 0.50204, 0.563918, -0.590448 };
   cblas_dtbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtbmv(case 910)");
     }
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 121;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { 0.566, 0.955, -0.086, -0.856, 0.177, 0.974, -0.652, -0.884, 0.77 };
   double X[] = { -0.77, -0.818, 0.337 };
   int incX = -1;
   double x_expected[] = { -0.77, -0.95429, -0.44419 };
   cblas_dtbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtbmv(case 911)");
     }
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 122;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { 0.566, 0.955, -0.086, -0.856, 0.177, 0.974, -0.652, -0.884, 0.77 };
   double X[] = { -0.77, -0.818, 0.337 };
   int incX = -1;
   double x_expected[] = { 1.214016, -0.433258, 0.321835 };
   cblas_dtbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtbmv(case 912)");
     }
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 122;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { 0.566, 0.955, -0.086, -0.856, 0.177, 0.974, -0.652, -0.884, 0.77 };
   double X[] = { -0.77, -0.818, 0.337 };
   int incX = -1;
   double x_expected[] = { -0.236664, -1.106472, 0.337 };
   cblas_dtbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtbmv(case 913)");
     }
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 121;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { 0.566, 0.955, -0.086, -0.856, 0.177, 0.974, -0.652, -0.884, 0.77 };
   double X[] = { -0.77, -0.818, 0.337 };
   int incX = -1;
   double x_expected[] = { 0.68068, 0.357254, 1.022043 };
   cblas_dtbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtbmv(case 914)");
     }
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 121;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { 0.566, 0.955, -0.086, -0.856, 0.177, 0.974, -0.652, -0.884, 0.77 };
   double X[] = { -0.77, -0.818, 0.337 };
   int incX = -1;
   double x_expected[] = { -0.77, -0.31596, 1.037208 };
   cblas_dtbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtbmv(case 915)");
     }
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 122;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { 0.566, 0.955, -0.086, -0.856, 0.177, 0.974, -0.652, -0.884, 0.77 };
   double X[] = { -0.77, -0.818, 0.337 };
   int incX = -1;
   double x_expected[] = { 0.357254, 1.022043, 0.190742 };
   cblas_dtbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtbmv(case 916)");
     }
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 122;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { 0.566, 0.955, -0.086, -0.856, 0.177, 0.974, -0.652, -0.884, 0.77 };
   double X[] = { -0.77, -0.818, 0.337 };
   int incX = -1;
   double x_expected[] = { -0.914786, -0.496165, 0.337 };
   cblas_dtbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtbmv(case 917)");
     }
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 121;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { 0.188, 0.6, -0.743, -0.803, 0.449, -0.681, -0.464, -0.029, 0.553 };
   double X[] = { -0.851, 0.481, 0.155 };
   int incX = -1;
   double x_expected[] = { 0.610833, -0.293243, 0.02914 };
   cblas_dtbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtbmv(case 918)");
     }
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 121;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { 0.188, 0.6, -0.743, -0.803, 0.449, -0.681, -0.464, -0.029, 0.553 };
   double X[] = { -0.851, 0.481, 0.155 };
   int incX = -1;
   double x_expected[] = { -0.635031, 0.574, 0.155 };
   cblas_dtbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtbmv(case 919)");
     }
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 122;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { 0.188, 0.6, -0.743, -0.803, 0.449, -0.681, -0.464, -0.029, 0.553 };
   double X[] = { -0.851, 0.481, 0.155 };
   int incX = -1;
   double x_expected[] = { 0.024679, 0.610833, -0.293243 };
   cblas_dtbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtbmv(case 920)");
     }
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 122;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { 0.188, 0.6, -0.743, -0.803, 0.449, -0.681, -0.464, -0.029, 0.553 };
   double X[] = { -0.851, 0.481, 0.155 };
   int incX = -1;
   double x_expected[] = { -0.851, 0.875864, -0.231243 };
   cblas_dtbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtbmv(case 921)");
     }
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 121;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { 0.188, 0.6, -0.743, -0.803, 0.449, -0.681, -0.464, -0.029, 0.553 };
   double X[] = { -0.851, 0.481, 0.155 };
   int incX = -1;
   double x_expected[] = { -0.198505, 0.091504, 0.093 };
   cblas_dtbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtbmv(case 922)");
     }
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 121;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { 0.188, 0.6, -0.743, -0.803, 0.449, -0.681, -0.464, -0.029, 0.553 };
   double X[] = { -0.851, 0.481, 0.155 };
   int incX = -1;
   double x_expected[] = { -1.074184, 0.356535, 0.155 };
   cblas_dtbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtbmv(case 923)");
     }
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 122;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { 0.188, 0.6, -0.743, -0.803, 0.449, -0.681, -0.464, -0.029, 0.553 };
   double X[] = { -0.851, 0.481, 0.155 };
   int incX = -1;
   double x_expected[] = { 0.394864, -0.768342, 0.31774 };
   cblas_dtbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtbmv(case 924)");
     }
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 122;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { 0.188, 0.6, -0.743, -0.803, 0.449, -0.681, -0.464, -0.029, 0.553 };
   double X[] = { -0.851, 0.481, 0.155 };
   int incX = -1;
   double x_expected[] = { -0.851, 0.098901, 0.4436 };
   cblas_dtbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtbmv(case 925)");
     }
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 121;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { 0.824f, -0.45f, -0.987f, 0.758f, 0.42f, -0.357f, 0.147f, -0.191f, 0.88f, 0.63f, 0.155f, -0.573f, 0.224f, 0.146f, 0.501f, -0.889f, 0.456f, 0.796f };
   float X[] = { -0.46f, 0.069f, 0.308f, -0.003f, -0.236f, 0.605f };
   int incX = -1;
   float x_expected[] = { -0.113114f, -0.051704f, -0.403567f, -0.288349f, -0.223936f, 0.841145f };
   cblas_ctbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctbmv(case 926) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctbmv(case 926) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 121;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { 0.824f, -0.45f, -0.987f, 0.758f, 0.42f, -0.357f, 0.147f, -0.191f, 0.88f, 0.63f, 0.155f, -0.573f, 0.224f, 0.146f, 0.501f, -0.889f, 0.456f, 0.796f };
   float X[] = { -0.46f, 0.069f, 0.308f, -0.003f, -0.236f, 0.605f };
   int incX = -1;
   float x_expected[] = { -0.46f, 0.069f, -0.14027f, -0.23208f, -0.537722f, 0.841425f };
   cblas_ctbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctbmv(case 927) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctbmv(case 927) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 122;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { 0.824f, -0.45f, -0.987f, 0.758f, 0.42f, -0.357f, 0.147f, -0.191f, 0.88f, 0.63f, 0.155f, -0.573f, 0.224f, 0.146f, 0.501f, -0.889f, 0.456f, 0.796f };
   float X[] = { -0.46f, 0.069f, 0.308f, -0.003f, -0.236f, 0.605f };
   int incX = -1;
   float x_expected[] = { -0.099689f, 0.487805f, 0.353793f, 0.325411f, -0.225658f, -0.776023f };
   cblas_ctbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctbmv(case 928) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctbmv(case 928) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 122;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { 0.824f, -0.45f, -0.987f, 0.758f, 0.42f, -0.357f, 0.147f, -0.191f, 0.88f, 0.63f, 0.155f, -0.573f, 0.224f, 0.146f, 0.501f, -0.889f, 0.456f, 0.796f };
   float X[] = { -0.46f, 0.069f, 0.308f, -0.003f, -0.236f, 0.605f };
   int incX = -1;
   float x_expected[] = { -0.39057f, 0.113296f, 0.388863f, 0.131011f, -0.236f, 0.605f };
   cblas_ctbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctbmv(case 929) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctbmv(case 929) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 121;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { 0.824f, -0.45f, -0.987f, 0.758f, 0.42f, -0.357f, 0.147f, -0.191f, 0.88f, 0.63f, 0.155f, -0.573f, 0.224f, 0.146f, 0.501f, -0.889f, 0.456f, 0.796f };
   float X[] = { -0.46f, 0.069f, 0.308f, -0.003f, -0.236f, 0.605f };
   int incX = -1;
   float x_expected[] = { -0.169119f, 0.443509f, 0.159816f, 0.139696f, -0.180955f, -0.835292f };
   cblas_ctbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctbmv(case 930) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctbmv(case 930) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 121;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { 0.824f, -0.45f, -0.987f, 0.758f, 0.42f, -0.357f, 0.147f, -0.191f, 0.88f, 0.63f, 0.155f, -0.573f, 0.224f, 0.146f, 0.501f, -0.889f, 0.456f, 0.796f };
   float X[] = { -0.46f, 0.069f, 0.308f, -0.003f, -0.236f, 0.605f };
   int incX = -1;
   float x_expected[] = { -0.46f, 0.069f, 0.194886f, -0.054704f, -0.191297f, 0.545731f };
   cblas_ctbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctbmv(case 931) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctbmv(case 931) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 122;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { 0.824f, -0.45f, -0.987f, 0.758f, 0.42f, -0.357f, 0.147f, -0.191f, 0.88f, 0.63f, 0.155f, -0.573f, 0.224f, 0.146f, 0.501f, -0.889f, 0.456f, 0.796f };
   float X[] = { -0.46f, 0.069f, 0.308f, -0.003f, -0.236f, 0.605f };
   int incX = -1;
   float x_expected[] = { 0.159816f, 0.139696f, -0.180955f, -0.835292f, 0.077786f, 0.60472f };
   cblas_ctbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctbmv(case 932) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctbmv(case 932) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 122;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { 0.824f, -0.45f, -0.987f, 0.758f, 0.42f, -0.357f, 0.147f, -0.191f, 0.88f, 0.63f, 0.155f, -0.573f, 0.224f, 0.146f, 0.501f, -0.889f, 0.456f, 0.796f };
   float X[] = { -0.46f, 0.069f, 0.308f, -0.003f, -0.236f, 0.605f };
   int incX = -1;
   float x_expected[] = { -0.18707f, 0.2604f, 0.082342f, -0.779023f, -0.236f, 0.605f };
   cblas_ctbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctbmv(case 933) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctbmv(case 933) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 121;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { -0.814f, 0.043f, -0.755f, -0.094f, 0.876f, 0.257f, 0.406f, 0.491f, -0.27f, -0.787f, 0.545f, 0.732f, -0.512f, -0.085f, 0.234f, 0.001f, -0.225f, -0.002f };
   float X[] = { 0.411f, -0.308f, -0.912f, 0.811f, -0.894f, -0.116f };
   int incX = -1;
   float x_expected[] = { 0.647885f, 0.621535f, -0.104407f, 0.05309f, 0.732704f, 0.055982f };
   cblas_ctbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctbmv(case 934) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctbmv(case 934) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 121;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { -0.814f, 0.043f, -0.755f, -0.094f, 0.876f, 0.257f, 0.406f, 0.491f, -0.27f, -0.787f, 0.545f, 0.732f, -0.512f, -0.085f, 0.234f, 0.001f, -0.225f, -0.002f };
   float X[] = { 0.411f, -0.308f, -0.912f, 0.811f, -0.894f, -0.116f };
   int incX = -1;
   float x_expected[] = { 1.2955f, 0.190774f, -0.247934f, 0.982616f, -0.894f, -0.116f };
   cblas_ctbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctbmv(case 935) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctbmv(case 935) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 122;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { -0.814f, 0.043f, -0.755f, -0.094f, 0.876f, 0.257f, 0.406f, 0.491f, -0.27f, -0.787f, 0.545f, 0.732f, -0.512f, -0.085f, 0.234f, 0.001f, -0.225f, -0.002f };
   float X[] = { 0.411f, -0.308f, -0.912f, 0.811f, -0.894f, -0.116f };
   int incX = -1;
   float x_expected[] = { 0.096482f, -0.071661f, 0.647885f, 0.621535f, -0.104407f, 0.05309f };
   cblas_ctbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctbmv(case 936) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctbmv(case 936) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 122;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { -0.814f, 0.043f, -0.755f, -0.094f, 0.876f, 0.257f, 0.406f, 0.491f, -0.27f, -0.787f, 0.545f, 0.732f, -0.512f, -0.085f, 0.234f, 0.001f, -0.225f, -0.002f };
   float X[] = { 0.411f, -0.308f, -0.912f, 0.811f, -0.894f, -0.116f };
   int incX = -1;
   float x_expected[] = { 0.411f, -0.308f, -1.14861f, 0.933761f, -1.66247f, -0.234526f };
   cblas_ctbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctbmv(case 937) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctbmv(case 937) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 121;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { -0.814f, 0.043f, -0.755f, -0.094f, 0.876f, 0.257f, 0.406f, 0.491f, -0.27f, -0.787f, 0.545f, 0.732f, -0.512f, -0.085f, 0.234f, 0.001f, -0.225f, -0.002f };
   float X[] = { 0.411f, -0.308f, -0.912f, 0.811f, -0.894f, -0.116f };
   int incX = -1;
   float x_expected[] = { 0.632361f, -0.409373f, 0.578489f, 0.012724f, 0.664066f, 0.171616f };
   cblas_ctbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctbmv(case 938) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctbmv(case 938) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 121;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { -0.814f, 0.043f, -0.755f, -0.094f, 0.876f, 0.257f, 0.406f, 0.491f, -0.27f, -0.787f, 0.545f, 0.732f, -0.512f, -0.085f, 0.234f, 0.001f, -0.225f, -0.002f };
   float X[] = { 0.411f, -0.308f, -0.912f, 0.811f, -0.894f, -0.116f };
   int incX = -1;
   float x_expected[] = { 0.946879f, -0.645712f, -1.21801f, 0.32495f, -0.894f, -0.116f };
   cblas_ctbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctbmv(case 939) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctbmv(case 939) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 122;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { -0.814f, 0.043f, -0.755f, -0.094f, 0.876f, 0.257f, 0.406f, 0.491f, -0.27f, -0.787f, 0.545f, 0.732f, -0.512f, -0.085f, 0.234f, 0.001f, -0.225f, -0.002f };
   float X[] = { 0.411f, -0.308f, -0.912f, 0.811f, -0.894f, -0.116f };
   int incX = -1;
   float x_expected[] = { -0.236612f, 0.122761f, -1.12184f, -0.358823f, 1.4975f, -0.470595f };
   cblas_ctbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctbmv(case 940) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctbmv(case 940) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 122;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { -0.814f, 0.043f, -0.755f, -0.094f, 0.876f, 0.257f, 0.406f, 0.491f, -0.27f, -0.787f, 0.545f, 0.732f, -0.512f, -0.085f, 0.234f, 0.001f, -0.225f, -0.002f };
   float X[] = { 0.411f, -0.308f, -0.912f, 0.811f, -0.894f, -0.116f };
   int incX = -1;
   float x_expected[] = { 0.411f, -0.308f, -1.26537f, 0.570703f, -0.129206f, -0.642577f };
   cblas_ctbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctbmv(case 941) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctbmv(case 941) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 113;
   int uplo = 121;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { -0.675f, 0.047f, 0.695f, 0.724f, -0.438f, 0.991f, -0.188f, -0.06f, -0.093f, 0.302f, 0.842f, -0.753f, 0.465f, -0.972f, -0.058f, 0.988f, 0.093f, 0.164f };
   float X[] = { 0.065f, -0.082f, -0.746f, 0.775f, 0.694f, -0.954f };
   int incX = -1;
   float x_expected[] = { 0.413357f, 0.178267f, -0.114618f, -1.35595f, -0.513288f, 0.611332f };
   cblas_ctbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctbmv(case 942) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctbmv(case 942) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 113;
   int uplo = 121;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { -0.675f, 0.047f, 0.695f, 0.724f, -0.438f, 0.991f, -0.188f, -0.06f, -0.093f, 0.302f, 0.842f, -0.753f, 0.465f, -0.972f, -0.058f, 0.988f, 0.093f, 0.164f };
   float X[] = { 0.065f, -0.082f, -0.746f, 0.775f, 0.694f, -0.954f };
   int incX = -1;
   float x_expected[] = { 0.368428f, 0.071217f, -0.954366f, -0.390486f, 0.694f, -0.954f };
   cblas_ctbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctbmv(case 943) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctbmv(case 943) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 113;
   int uplo = 122;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { -0.675f, 0.047f, 0.695f, 0.724f, -0.438f, 0.991f, -0.188f, -0.06f, -0.093f, 0.302f, 0.842f, -0.753f, 0.465f, -0.972f, -0.058f, 0.988f, 0.093f, 0.164f };
   float X[] = { 0.065f, -0.082f, -0.746f, 0.775f, 0.694f, -0.954f };
   int incX = -1;
   float x_expected[] = { -0.084786f, -0.059464f, 0.413357f, 0.178267f, -0.114618f, -1.35595f };
   cblas_ctbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctbmv(case 944) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctbmv(case 944) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 113;
   int uplo = 122;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { -0.675f, 0.047f, 0.695f, 0.724f, -0.438f, 0.991f, -0.188f, -0.06f, -0.093f, 0.302f, 0.842f, -0.753f, 0.465f, -0.972f, -0.058f, 0.988f, 0.093f, 0.164f };
   float X[] = { 0.065f, -0.082f, -0.746f, 0.775f, 0.694f, -0.954f };
   int incX = -1;
   float x_expected[] = { 0.065f, -0.082f, -0.636071f, 0.80005f, 0.787748f, -1.14446f };
   cblas_ctbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctbmv(case 945) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctbmv(case 945) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 113;
   int uplo = 121;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { -0.675f, 0.047f, 0.695f, 0.724f, -0.438f, 0.991f, -0.188f, -0.06f, -0.093f, 0.302f, 0.842f, -0.753f, 0.465f, -0.972f, -0.058f, 0.988f, 0.093f, 0.164f };
   float X[] = { 0.065f, -0.082f, -0.746f, 0.775f, 0.694f, -0.954f };
   int incX = -1;
   float x_expected[] = { -1.18498f, -0.424201f, 0.230196f, 0.374209f, -0.208366f, -1.16549f };
   cblas_ctbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctbmv(case 946) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctbmv(case 946) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 113;
   int uplo = 121;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { -0.675f, 0.047f, 0.695f, 0.724f, -0.438f, 0.991f, -0.188f, -0.06f, -0.093f, 0.302f, 0.842f, -0.753f, 0.465f, -0.972f, -0.058f, 0.988f, 0.093f, 0.164f };
   float X[] = { 0.065f, -0.082f, -0.746f, 0.775f, 0.694f, -0.954f };
   int incX = -1;
   float x_expected[] = { -1.03519f, -0.446737f, -0.819232f, 0.995992f, 0.694f, -0.954f };
   cblas_ctbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctbmv(case 947) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctbmv(case 947) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 113;
   int uplo = 122;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { -0.675f, 0.047f, 0.695f, 0.724f, -0.438f, 0.991f, -0.188f, -0.06f, -0.093f, 0.302f, 0.842f, -0.753f, 0.465f, -0.972f, -0.058f, 0.988f, 0.093f, 0.164f };
   float X[] = { 0.065f, -0.082f, -0.746f, 0.775f, 0.694f, -0.954f };
   int incX = -1;
   float x_expected[] = { 0.109929f, 0.02505f, 0.062939f, -0.202464f, -0.470658f, 1.69006f };
   cblas_ctbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctbmv(case 948) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctbmv(case 948) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 113;
   int uplo = 122;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   float A[] = { -0.675f, 0.047f, 0.695f, 0.724f, -0.438f, 0.991f, -0.188f, -0.06f, -0.093f, 0.302f, 0.842f, -0.753f, 0.465f, -0.972f, -0.058f, 0.988f, 0.093f, 0.164f };
   float X[] = { 0.065f, -0.082f, -0.746f, 0.775f, 0.694f, -0.954f };
   int incX = -1;
   float x_expected[] = { 0.065f, -0.082f, -0.776809f, 0.762996f, 0.73663f, 0.124729f };
   cblas_ctbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctbmv(case 949) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctbmv(case 949) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 121;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { -0.212, 0.612, 0.189, -0.046, -0.124, 0.82, 0.753, 0.727, 0.331, 0.116, 0.504, -0.673, -0.888, -0.277, -0.361, -0.909, 0.982, -0.124 };
   double X[] = { 0.064, 0.169, -0.81, -0.779, -0.641, -0.103 };
   int incX = -1;
   double x_expected[] = { -0.010019, -0.1678, -0.042017, -1.112094, 0.010004, -0.480427 };
   cblas_ztbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztbmv(case 950) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztbmv(case 950) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 121;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { -0.212, 0.612, 0.189, -0.046, -0.124, 0.82, 0.753, 0.727, 0.331, 0.116, 0.504, -0.673, -0.888, -0.277, -0.361, -0.909, 0.982, -0.124 };
   double X[] = { 0.064, 0.169, -0.81, -0.779, -0.641, -0.103 };
   int incX = -1;
   double x_expected[] = { 0.064, 0.169, -0.80842, -0.715637, -0.829924, -0.212971 };
   cblas_ztbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztbmv(case 951) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztbmv(case 951) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 122;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { -0.212, 0.612, 0.189, -0.046, -0.124, 0.82, 0.753, 0.727, 0.331, 0.116, 0.504, -0.673, -0.888, -0.277, -0.361, -0.909, 0.982, -0.124 };
   double X[] = { 0.064, 0.169, -0.81, -0.779, -0.641, -0.103 };
   int incX = -1;
   double x_expected[] = { 0.634014, 0.796937, -0.585538, -0.895375, -0.125887, 0.010019 };
   cblas_ztbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztbmv(case 952) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztbmv(case 952) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 122;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { -0.212, 0.612, 0.189, -0.046, -0.124, 0.82, 0.753, 0.727, 0.331, 0.116, 0.504, -0.673, -0.888, -0.277, -0.361, -0.909, 0.982, -0.124 };
   double X[] = { 0.064, 0.169, -0.81, -0.779, -0.641, -0.103 };
   int incX = -1;
   double x_expected[] = { 0.567497, 1.085122, -1.217792, -1.322566, -0.641, -0.103 };
   cblas_ztbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztbmv(case 953) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztbmv(case 953) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 121;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { -0.212, 0.612, 0.189, -0.046, -0.124, 0.82, 0.753, 0.727, 0.331, 0.116, 0.504, -0.673, -0.888, -0.277, -0.361, -0.909, 0.982, -0.124 };
   double X[] = { 0.064, 0.169, -0.81, -0.779, -0.641, -0.103 };
   int incX = -1;
   double x_expected[] = { 0.130517, -0.119185, -0.187765, -0.519609, -0.169484, -1.165438 };
   cblas_ztbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztbmv(case 954) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztbmv(case 954) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 121;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { -0.212, 0.612, 0.189, -0.046, -0.124, 0.82, 0.753, 0.727, 0.331, 0.116, 0.504, -0.673, -0.888, -0.277, -0.361, -0.909, 0.982, -0.124 };
   double X[] = { 0.064, 0.169, -0.81, -0.779, -0.641, -0.103 };
   int incX = -1;
   double x_expected[] = { 0.064, 0.169, -0.820019, -0.9468, -0.684597, -1.278457 };
   cblas_ztbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztbmv(case 955) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztbmv(case 955) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 122;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { -0.212, 0.612, 0.189, -0.046, -0.124, 0.82, 0.753, 0.727, 0.331, 0.116, 0.504, -0.673, -0.888, -0.277, -0.361, -0.909, 0.982, -0.124 };
   double X[] = { 0.064, 0.169, -0.81, -0.779, -0.641, -0.103 };
   int incX = -1;
   double x_expected[] = { -0.187765, -0.519609, -0.169484, -1.165438, 0.198928, -0.370456 };
   cblas_ztbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztbmv(case 956) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztbmv(case 956) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 122;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { -0.212, 0.612, 0.189, -0.046, -0.124, 0.82, 0.753, 0.727, 0.331, 0.116, 0.504, -0.673, -0.888, -0.277, -0.361, -0.909, 0.982, -0.124 };
   double X[] = { 0.064, 0.169, -0.81, -0.779, -0.641, -0.103 };
   int incX = -1;
   double x_expected[] = { -0.113746, -0.182809, -0.935887, -0.768981, -0.641, -0.103 };
   cblas_ztbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztbmv(case 957) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztbmv(case 957) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 121;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { -0.374, -0.308, 0.792, 0.884, -0.794, -0.055, -0.281, 0.527, 0.246, 0.762, 0.853, 0.891, -0.231, 0.384, 0.373, -0.717, -0.957, -0.338 };
   double X[] = { 0.884, 0.636, 0.921, 0.282, -0.649, 0.188 };
   int incX = -1;
   double x_expected[] = { -0.436746, 0.963714, -1.087615, -0.018695, 0.30063, 0.12958 };
   cblas_ztbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztbmv(case 958) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztbmv(case 958) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 121;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { -0.374, -0.308, 0.792, 0.884, -0.794, -0.055, -0.281, 0.527, 0.246, 0.762, 0.853, 0.891, -0.231, 0.384, 0.373, -0.717, -0.957, -0.338 };
   double X[] = { 0.884, 0.636, 0.921, 0.282, -0.649, 0.188 };
   int incX = -1;
   double x_expected[] = { 0.895682, 1.407174, 0.2408, -0.14282, -0.649, 0.188 };
   cblas_ztbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztbmv(case 959) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztbmv(case 959) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 122;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { -0.374, -0.308, 0.792, 0.884, -0.794, -0.055, -0.281, 0.527, 0.246, 0.762, 0.853, 0.891, -0.231, 0.384, 0.373, -0.717, -0.957, -0.338 };
   double X[] = { 0.884, 0.636, 0.921, 0.282, -0.649, 0.188 };
   int incX = -1;
   double x_expected[] = { 0.785744, -0.3966, -0.436746, 0.963714, -1.087615, -0.018695 };
   cblas_ztbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztbmv(case 960) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztbmv(case 960) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 122;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { -0.374, -0.308, 0.792, 0.884, -0.794, -0.055, -0.281, 0.527, 0.246, 0.762, 0.853, 0.891, -0.231, 0.384, 0.373, -0.717, -0.957, -0.338 };
   double X[] = { 0.884, 0.636, 0.921, 0.282, -0.649, 0.188 };
   int incX = -1;
   double x_expected[] = { 0.884, 0.636, 0.472572, 0.47454, -1.056415, 0.594125 };
   cblas_ztbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztbmv(case 961) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztbmv(case 961) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 121;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { -0.374, -0.308, 0.792, 0.884, -0.794, -0.055, -0.281, 0.527, 0.246, 0.762, 0.853, 0.891, -0.231, 0.384, 0.373, -0.717, -0.957, -0.338 };
   double X[] = { 0.884, 0.636, 0.921, 0.282, -0.649, 0.188 };
   int incX = -1;
   double x_expected[] = { 0.464705, -0.108078, 0.094975, 0.376323, -0.6802, -0.42482 };
   cblas_ztbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztbmv(case 962) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztbmv(case 962) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 121;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { -0.374, -0.308, 0.792, 0.884, -0.794, -0.055, -0.281, 0.527, 0.246, 0.762, 0.853, 0.891, -0.231, 0.384, 0.373, -0.717, -0.957, -0.338 };
   double X[] = { 0.884, 0.636, 0.921, 0.282, -0.649, 0.188 };
   int incX = -1;
   double x_expected[] = { 0.562961, 0.924522, 1.004293, -0.112851, -0.649, 0.188 };
   cblas_ztbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztbmv(case 963) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztbmv(case 963) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 122;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { -0.374, -0.308, 0.792, 0.884, -0.794, -0.055, -0.281, 0.527, 0.246, 0.762, 0.853, 0.891, -0.231, 0.384, 0.373, -0.717, -0.957, -0.338 };
   double X[] = { 0.884, 0.636, 0.921, 0.282, -0.649, 0.188 };
   int incX = -1;
   double x_expected[] = { -0.448428, 0.19254, -0.674583, 1.236189, 0.780774, 1.167088 };
   cblas_ztbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztbmv(case 964) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztbmv(case 964) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 122;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { -0.374, -0.308, 0.792, 0.884, -0.794, -0.055, -0.281, 0.527, 0.246, 0.762, 0.853, 0.891, -0.231, 0.384, 0.373, -0.717, -0.957, -0.338 };
   double X[] = { 0.884, 0.636, 0.921, 0.282, -0.649, 0.188 };
   int incX = -1;
   double x_expected[] = { 0.884, 0.636, 0.653832, 1.112064, -0.168856, 1.225508 };
   cblas_ztbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztbmv(case 965) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztbmv(case 965) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 113;
   int uplo = 121;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { 0.002, 0.95, -0.363, 0.084, -0.646, 0.816, -0.407, 0.099, -0.02, -0.906, -0.874, 0.191, -0.328, -0.968, 0.79, 0.826, -0.795, 0.277 };
   double X[] = { -0.591, -0.084, 0.707, 0.945, 0.326, 0.428 };
   int incX = -1;
   double x_expected[] = { -0.59515, 0.077106, -0.27658, -0.637356, 0.407252, -0.308844 };
   cblas_ztbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztbmv(case 966) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztbmv(case 966) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 113;
   int uplo = 121;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { 0.002, 0.95, -0.363, 0.084, -0.646, 0.816, -0.407, 0.099, -0.02, -0.906, -0.874, 0.191, -0.328, -0.968, 0.79, 0.826, -0.795, 0.277 };
   double X[] = { -0.591, -0.084, 0.707, 0.945, 0.326, 0.428 };
   int incX = -1;
   double x_expected[] = { -1.46131, 0.537642, 0.624614, 0.762252, 0.326, 0.428 };
   cblas_ztbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztbmv(case 967) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztbmv(case 967) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 113;
   int uplo = 122;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { 0.002, 0.95, -0.363, 0.084, -0.646, 0.816, -0.407, 0.099, -0.02, -0.906, -0.874, 0.191, -0.328, -0.968, 0.79, 0.826, -0.795, 0.277 };
   double X[] = { -0.591, -0.084, 0.707, 0.945, 0.326, 0.428 };
   int incX = -1;
   double x_expected[] = { -0.536274, 0.421806, -0.59515, 0.077106, -0.27658, -0.637356 };
   cblas_ztbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztbmv(case 968) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztbmv(case 968) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 113;
   int uplo = 122;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { 0.002, 0.95, -0.363, 0.084, -0.646, 0.816, -0.407, 0.099, -0.02, -0.906, -0.874, 0.191, -0.328, -0.968, 0.79, 0.826, -0.795, 0.277 };
   double X[] = { -0.591, -0.084, 0.707, 0.945, 0.326, 0.428 };
   int incX = -1;
   double x_expected[] = { -0.591, -0.084, 0.98216, 0.400464, 0.131806, -0.026608 };
   cblas_ztbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztbmv(case 969) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztbmv(case 969) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 113;
   int uplo = 121;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { 0.002, 0.95, -0.363, 0.084, -0.646, 0.816, -0.407, 0.099, -0.02, -0.906, -0.874, 0.191, -0.328, -0.968, 0.79, 0.826, -0.795, 0.277 };
   double X[] = { -0.591, -0.084, 0.707, 0.945, 0.326, 0.428 };
   int incX = -1;
   double x_expected[] = { -1.68293, 0.796222, -0.96062, 0.415172, -0.082386, -0.182748 };
   cblas_ztbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztbmv(case 970) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztbmv(case 970) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 113;
   int uplo = 121;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { 0.002, 0.95, -0.363, 0.084, -0.646, 0.816, -0.407, 0.099, -0.02, -0.906, -0.874, 0.191, -0.328, -0.968, 0.79, 0.826, -0.795, 0.277 };
   double X[] = { -0.591, -0.084, 0.707, 0.945, 0.326, 0.428 };
   int incX = -1;
   double x_expected[] = { -1.737656, 0.290416, 0.61669, 0.73853, 0.326, 0.428 };
   cblas_ztbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztbmv(case 971) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztbmv(case 971) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 113;
   int uplo = 122;
   int diag = 131;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { 0.002, 0.95, -0.363, 0.084, -0.646, 0.816, -0.407, 0.099, -0.02, -0.906, -0.874, 0.191, -0.328, -0.968, 0.79, 0.826, -0.795, 0.277 };
   double X[] = { -0.591, -0.084, 0.707, 0.945, 0.326, 0.428 };
   int incX = -1;
   double x_expected[] = { 0.27516, -0.544536, -0.10627, -0.988374, 0.229991, -0.711267 };
   cblas_ztbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztbmv(case 972) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztbmv(case 972) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 113;
   int uplo = 122;
   int diag = 132;
   int N = 3;
   int K = 1;
   int lda = 3;
   double A[] = { 0.002, 0.95, -0.363, 0.084, -0.646, 0.816, -0.407, 0.099, -0.02, -0.906, -0.874, 0.191, -0.328, -0.968, 0.79, 0.826, -0.795, 0.277 };
   double X[] = { -0.591, -0.084, 0.707, 0.945, 0.326, 0.428 };
   int incX = -1;
   double x_expected[] = { -0.591, -0.084, 0.794924, 0.411234, 0.148739, 0.025577 };
   cblas_ztbmv(order, uplo, trans, diag, N, K, A, lda, X, incX);
   {
     int i;
     for (i = 0; i < 3; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztbmv(case 973) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztbmv(case 973) imag");
     };
   };
  };

}


/* ieee-utils/fp-aix.c
 *
 * Copyright (C) 1996, 1997, 1998, 1999, 2000 Tim Mooney
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include <math.h>
#include <fptrap.h>
#include <float.h>
#include <gsl/gsl_ieee_utils.h>
#include <gsl/gsl_errno.h>

int
gsl_ieee_set_mode (int precision, int rounding, int exception_mask)
{
  fptrap_t   mode = 0 ;
  fprnd_t    rnd  = 0 ;

  switch (precision)
    {

    /* I'm not positive about AIX only supporting default precision rounding,
     * but this is the best assumption until it's proven otherwise. */

    case GSL_IEEE_SINGLE_PRECISION:
      GSL_ERROR ("AIX only supports default precision rounding",
                 GSL_EUNSUP) ;
      break ;
    case GSL_IEEE_DOUBLE_PRECISION:
      GSL_ERROR ("AIX only supports default precision rounding",
                 GSL_EUNSUP) ;
      break ;
    case GSL_IEEE_EXTENDED_PRECISION:
      GSL_ERROR ("AIX only supports default precision rounding",
                 GSL_EUNSUP) ;
      break ;
    }

  switch (rounding)
    {
    case GSL_IEEE_ROUND_TO_NEAREST:
      rnd = FP_RND_RN ;
      fp_swap_rnd (rnd) ;
      break ;
    case GSL_IEEE_ROUND_DOWN:
      rnd = FP_RND_RM ;
      fp_swap_rnd (rnd) ;
      break ;
    case GSL_IEEE_ROUND_UP:
      rnd = FP_RND_RP ;
      fp_swap_rnd (rnd) ;
      break ;
    case GSL_IEEE_ROUND_TO_ZERO:
      rnd = FP_RND_RZ ;
      fp_swap_rnd (rnd) ;
      break ;
    default:
      rnd = FP_RND_RN ;
      fp_swap_rnd (rnd) ;
    }

  /* Turn on all the exceptions apart from 'inexact' */

  mode = TRP_INVALID | TRP_DIV_BY_ZERO | TRP_OVERFLOW | TRP_UNDERFLOW ;

  if (exception_mask & GSL_IEEE_MASK_INVALID)
    mode &= ~ TRP_INVALID ;

  if (exception_mask & GSL_IEEE_MASK_DENORMALIZED)
    {
      /* do nothing */
    }
  else
    {
      GSL_ERROR ("AIX does not support the denormalized operand exception. "
                 "Use 'mask-denormalized' to work around this.",
                 GSL_EUNSUP) ;
    }

  if (exception_mask & GSL_IEEE_MASK_DIVISION_BY_ZERO)
    mode &= ~ TRP_DIV_BY_ZERO ;

  if (exception_mask & GSL_IEEE_MASK_OVERFLOW)
    mode &= ~ TRP_OVERFLOW ;

  if (exception_mask & GSL_IEEE_MASK_UNDERFLOW)
    mode &=  ~ TRP_UNDERFLOW ;

  if (exception_mask & GSL_IEEE_TRAP_INEXACT)
    {
      mode |= TRP_INEXACT ;
    }
  else
    {
      mode &= ~ TRP_INEXACT ;
    }

  /* AIX appears to require two steps -- first enable floating point traps
   * in general... */
  fp_trap(FP_TRAP_SYNC);

  /* next, enable the traps we're interested in */
  fp_enable(mode);

  return GSL_SUCCESS ;

}


/*
 *  rand.h
 *  Random number generation
 *
 *  Created by OKAMOTO Kenji, SAKO Yasushi and RIKEN
 *  Copyright 2011-2015
 *  Cellular Informatics Laboratory, Advance Science Institute, RIKEN, Japan.
 *  All rights reserved.
 *
 *  Ver. 1.0.0
 *  Last modified on 2015.09.17
 */

#ifndef DEF_RAND
#define DEF_RAND

#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>

void initRan();
void freeRan();
double ranInRange( double, double );
double enoise( double );
double interval( double );

#endif

//


#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION

#include <Python.h>
#include <numpy/arrayobject.h>

#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>

#include <math.h>

// Forward function declaration.
static PyObject *zsampler_sample_region(PyObject *self, PyObject *args);
static PyObject *zsampler_sample_categorical(PyObject *self, PyObject *args);

// Boilerplate: method list.
static PyMethodDef methods[] = {
  { "sample_region", zsampler_sample_region, METH_VARARGS, "Doc string."},
  { "sample_bulk_categorical", zsampler_sample_categorical, METH_VARARGS, "Doc string."},
  { NULL, NULL, 0, NULL } /* Sentinel */
};

static struct PyModuleDef sampler_module =
{
    PyModuleDef_HEAD_INIT,
    "zsampler", /* name of module */
    "",          /* module documentation, may be NULL */
    -1,          /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
    methods
};

PyMODINIT_FUNC PyInit_zsampler(void)
{
    import_array(); // crucial command if NumPy API is used
    return PyModule_Create(&sampler_module);
}

/*****************************************************************************
 * Helper methods                                                            *
 *****************************************************************************/
void print_int_array(npy_int64* array, int length) {
  for(int i = 0; i < length; i++) {
    printf("%ld ", array[i]);
  }
  printf("\n");
}

void print_f_array(npy_float64* array, int length) {
  for(int i = 0; i < length; i++) {
    printf("%lf ", array[i]);
  }
  printf("\n");
}

static PyObject* zsampler_sample_categorical(PyObject *self, PyObject *args) {

    PyArrayObject *py_Z, *py_prob;
    if (!PyArg_ParseTuple(args, "O!O!",
                            &PyArray_Type, &py_Z,
                            &PyArray_Type, &py_prob)) {
        return NULL;
    }

    npy_int64 C_N, C_K;
    C_N = PyArray_SHAPE(py_prob)[0];
    C_K = PyArray_SHAPE(py_prob)[1];

    const gsl_rng_type * C_T;
    gsl_rng * C_r;
    gsl_rng_env_setup();
    C_T = gsl_rng_taus;
    C_r = gsl_rng_alloc (C_T);

    double *_prob; // probabilities for sampling from multinomial
    _prob = (double*)malloc(C_K * sizeof(double));

    unsigned int *_new_sample;
    _new_sample = (unsigned int*)malloc(C_K * sizeof(unsigned int));

    PyArrayObject* out_Z = (PyArrayObject*)PyArray_NewCopy(py_Z, NPY_ANYORDER);
    for (int i=0; i < C_N; i++) {

        for (int k=0; k < C_K; k++) {
            _prob[k] = (*(npy_float64*)PyArray_GETPTR2(py_prob, i, k));
         }

        gsl_ran_multinomial(C_r, (size_t)C_K, 1, _prob, _new_sample);

        for (int k = 0; k < C_K; k++) {
            npy_int64* Zk = (npy_int64*)PyArray_GETPTR2(out_Z, i, k);
            Zk[0] = (npy_int64)_new_sample[k];
         }
    }

    free(_prob);
    free(_new_sample);
    gsl_rng_free(C_r);
    return (PyObject*)out_Z;  // no need to IncRef out_Z
}

//      Mixture weight priors is block-specific
static PyObject* zsampler_sample_region(PyObject *self, PyObject *args) {

  // Input variables
  PyArrayObject *py_Z, *py_counts, *py_covariates, *py_beta, *py_alpha;
  PyArrayObject *py_region_alloc, *py_region_label_counts;

  /*  parse single numpy array argument */
    if (!PyArg_ParseTuple(args, "O!O!O!O!O!O!O!",
                            &PyArray_Type, &py_Z,
                            &PyArray_Type, &py_counts,
                            &PyArray_Type, &py_covariates,
                            &PyArray_Type, &py_beta,
                            &PyArray_Type, &py_alpha,
                            &PyArray_Type, &py_region_alloc,
                            &PyArray_Type, &py_region_label_counts)) {
        return NULL;
    }

    Py_INCREF(py_region_alloc);
    Py_INCREF(py_region_label_counts);

    const gsl_rng_type * C_T;
    gsl_rng * C_r;
    gsl_rng_env_setup();
    C_T = gsl_rng_taus;
    C_r = gsl_rng_alloc (C_T);

    // Temporary variables
    npy_int64 C_N, C_K, C_J;
    C_N = PyArray_SHAPE(py_Z)[0];
    C_K = PyArray_SHAPE(py_Z)[1];
    C_J = PyArray_SHAPE(py_beta)[0];

    PyArrayObject* out_Z = (PyArrayObject*)PyArray_NewCopy(py_Z, NPY_ANYORDER);

    npy_int64 *C_counts = (npy_int64 *) PyArray_DATA(py_counts);
    npy_float64 *C_alpha = (npy_float64 *) PyArray_DATA(py_alpha);
    npy_int64 *C_region_alloc = (npy_int64 *) PyArray_DATA(py_region_alloc);

    npy_int64 C_labelsum;
    npy_int64 *C_label_counts;
    C_label_counts = (npy_int64*)malloc(C_K * sizeof(npy_int64));
    double *_mu;
    _mu = (double*)malloc(C_K * sizeof(double));
    double *_logpoi;
    _logpoi = (double*)malloc(C_K * sizeof(double));
    double *_logcat;
    _logcat =(double*)malloc(C_K * sizeof(double));
    double *_lik;
    _lik =(double*)malloc(C_K * sizeof(double));
    double *_prob; // probabilities for sampling from multinomial
    _prob = (double*)malloc(C_K * sizeof(double));
    unsigned int *_new_sample;
    _new_sample = (unsigned int*)malloc(C_K * sizeof(unsigned int));

    npy_float64 C_alpha_sum = 0.0;
    for(int k=0; k < C_K; k++) {
      C_alpha_sum = C_alpha_sum + C_alpha[k];
    }

    for (int i=0; i < C_N; i++) {

      C_labelsum = 0;
      for (int k = 0; k < C_K; k++) {
        // subtract current cell counts from the region counts
        npy_int64* accessor = (npy_int64*)PyArray_GETPTR2(py_region_label_counts, C_region_alloc[i], k);
        accessor[0] = accessor[0] - (*(npy_int64*)PyArray_GETPTR2(out_Z, i, k));  // TODO: make this simpler

        C_label_counts[k] = accessor[0];
        C_labelsum = C_labelsum + C_label_counts[k];
      }

      // computation of likelihood and interim calculations
      for (int k=0; k < C_K; k++) {
        _mu[k] = 0;
        for (int j=0; j < C_J; j++) {
            _mu[k] = _mu[k] + ((*(npy_float64*)PyArray_GETPTR2(py_covariates, i, j)) * (*(npy_float64*)PyArray_GETPTR2(py_beta, j, k)));
        }

        _logpoi[k] = ((double)C_counts[i])*_mu[k] - exp(_mu[k]);
        _logcat[k] = log(((double)C_label_counts[k] + C_alpha[k])  / ((double)C_labelsum + C_alpha_sum));

        _lik[k] = (_logpoi[k] + _logcat[k]);
      }

      double maxval = _lik[0];
      for (int k=0; k < C_K; k++) {
        if(_lik[k] > maxval) {
          maxval = _lik[k];
        }
      }

      double sumexp = 0;
      for (int k=0; k < C_K; k++) {
        sumexp = sumexp + exp((double)_lik[k] - maxval);
      }

      double logsumexp = maxval + log(sumexp);

      for (int k=0; k < C_K; k++) {
        _prob[k] = exp((double)_lik[k] - logsumexp);
      }

      gsl_ran_multinomial(C_r, (size_t)C_K, 1, _prob, _new_sample);
      for (int k = 0; k < C_K; k++) {
        npy_int64* Zk = (npy_int64*)PyArray_GETPTR2(out_Z, i, k);
        Zk[0] = (npy_int64)_new_sample[k];

        // update the region label counts
        npy_int64* accessor = (npy_int64*)PyArray_GETPTR2(py_region_label_counts, C_region_alloc[i], k);
        accessor[0] = accessor[0] + Zk[0];
      }
    }

    free(C_label_counts);
    free(_mu);
    free(_logpoi);
    free(_logcat);
    free(_lik);
    free(_prob);
    free(_new_sample);

    gsl_rng_free(C_r);
    Py_DECREF(py_region_alloc);
    Py_DECREF(py_region_label_counts);
    return (PyObject*)out_Z;  // no need to IncRef out_Z
}


/**
 *
 * @file qwrapper_dlaset.c
 *
 *  PLASMA core_blas quark wrapper
 *  PLASMA is a software package provided by Univ. of Tennessee,
 *  Univ. of California Berkeley and Univ. of Colorado Denver
 *
 * @version 2.6.0
 * @author Hatem Ltaief
 * @date 2010-11-15
 * @generated d Tue Jan  7 11:44:58 2014
 *
 **/
#include <lapacke.h>
#include "common.h"

/***************************************************************************//**
 *
 **/
void QUARK_CORE_dlaset(Quark *quark, Quark_Task_Flags *task_flags,
                       PLASMA_enum uplo, int M, int N,
                       double alpha, double beta,
                       double *A, int LDA)
{
    DAG_CORE_LASET;
    QUARK_Insert_Task(quark, CORE_dlaset_quark, task_flags,
        sizeof(PLASMA_enum),                &uplo,  VALUE,
        sizeof(int),                        &M,     VALUE,
        sizeof(int),                        &N,     VALUE,
        sizeof(double),         &alpha, VALUE,
        sizeof(double),         &beta,  VALUE,
        sizeof(double)*LDA*N,    A,      OUTPUT,
        sizeof(int),                        &LDA,   VALUE,
        0);
}

/***************************************************************************//**
 *
 **/
#if defined(PLASMA_HAVE_WEAK)
#pragma weak CORE_dlaset_quark = PCORE_dlaset_quark
#define CORE_dlaset_quark PCORE_dlaset_quark
#endif
void CORE_dlaset_quark(Quark *quark)
{
    PLASMA_enum uplo;
    int M;
    int N;
    double alpha;
    double beta;
    double *A;
    int LDA;

    quark_unpack_args_7(quark, uplo, M, N, alpha, beta, A, LDA);
    LAPACKE_dlaset_work(
        LAPACK_COL_MAJOR,
        lapack_const(uplo),
        M, N, alpha, beta, A, LDA);
}


/*
 * author: Achim Gaedke
 * created: May 2001
 * file: pygsl/src/constmodule.c
 * $Id: constmodule.c,v 1.11 2007/11/26 20:25:09 schnizer Exp $
 *
 *
 * Changes:
 *    7. October 2003 Added support for gsl-1.4 constants.
 */

#include <Python.h>
#include <gsl/gsl_math.h>
#include <gsl/gsl_const_num.h>
#include <pygsl/pygsl_features.h>

#ifdef _PYGSL_GSL_HAS_CGS
#include <gsl/gsl_const_cgs.h>
#endif

#ifdef _PYGSL_GSL_HAS_CGSM
#include <gsl/gsl_const_cgsm.h>
#endif

#ifdef _PYGSL_GSL_HAS_MKS
#include <gsl/gsl_const_mks.h>
#endif

#ifdef _PYGSL_GSL_HAS_MKSA
#include <gsl/gsl_const_mksa.h>
#endif

static PyMethodDef constMethods[] = {
  {NULL,     NULL}        /* Sentinel */
};

typedef struct {
  char* name;
  double value;
  char* doc;
} constConstants;

constConstants m_array[]={
#include "const_m_array.c"
{NULL,0,NULL}
};

#ifdef _PYGSL_GSL_HAS_MKS
constConstants mks_array[]={
#include "const_mks_array.c"
  {NULL,0,NULL}
};
#endif

#ifdef _PYGSL_GSL_HAS_CGS
constConstants cgs_array[]={
#include "const_cgs_array.c"
  {NULL,0,NULL}
};
#endif

#ifdef _PYGSL_GSL_HAS_MKSA
constConstants mksa_array[]={
#include "const_mksa_array.c"
  {NULL,0,NULL}
};
#endif

#ifdef _PYGSL_GSL_HAS_CGSM
constConstants cgsm_array[]={
#include "const_cgsm_array.c"
  {NULL,0,NULL}
};
#endif

constConstants num_array[]={
#include "const_num_array.c"
  {NULL,0,NULL}
};

static void
add_constants(constConstants* constants, PyObject* m)
{
  int i=0;
  while (constants[i].name!=NULL) {
    PyObject* floatObject=PyFloat_FromDouble(constants[i].value);
    if (floatObject==NULL) break;
    PyModule_AddObject(m,constants[i].name,floatObject);
    /* Py_DECREF(floatObject); */
    i++;
  }
}

DL_EXPORT(void) initconst(void)
{
  PyObject* const_module = Py_InitModule("const", constMethods);

#ifdef _PYGSL_GSL_HAS_MKS
  PyObject* mks_module   = PyImport_AddModule("pygsl.const.mks");
#endif
#ifdef _PYGSL_GSL_HAS_CGS
  PyObject* cgs_module   = PyImport_AddModule("pygsl.const.cgs");
#endif

#ifdef _PYGSL_GSL_HAS_MKSA
  PyObject* mksa_module   = PyImport_AddModule("pygsl.const.mksa");
#endif
#ifdef _PYGSL_GSL_HAS_CGSM
  PyObject* cgsm_module   = PyImport_AddModule("pygsl.const.cgsm");
#endif

  PyObject* math_module  = PyImport_AddModule("pygsl.const.m");
  PyObject* num_module   = PyImport_AddModule("pygsl.const.num");

  /* distribute constants on modules */
  add_constants(m_array  , const_module);
  add_constants(num_array, const_module);

#ifdef _PYGSL_GSL_HAS_MKS
  add_constants(mks_array, const_module);
  add_constants(mks_array, mks_module);
#endif
#ifdef _PYGSL_GSL_HAS_CGS
  add_constants(cgs_array, cgs_module);
#endif

#ifdef _PYGSL_GSL_HAS_MKSA
  add_constants(mksa_array, const_module);
  add_constants(mksa_array, mksa_module);
#endif
#ifdef _PYGSL_GSL_HAS_CGSM
  add_constants(cgsm_array, cgsm_module);
#endif

  add_constants(num_array, num_module);
  add_constants(m_array  , math_module);

  PyModule_AddObject(const_module, "m",   math_module);
#ifdef _PYGSL_GSL_HAS_CGS
  PyModule_AddObject(const_module, "cgs", cgs_module);
#endif
#ifdef _PYGSL_GSL_HAS_MKS
  PyModule_AddObject(const_module, "mks", mks_module);
#endif

#ifdef _PYGSL_GSL_HAS_CGSM
  PyModule_AddObject(const_module, "cgsm", cgsm_module);
#endif
#ifdef _PYGSL_GSL_HAS_MKSA
  PyModule_AddObject(const_module, "mksa", mksa_module);
#endif

  PyModule_AddObject(const_module, "num", num_module);
  return;
}


///
/// @file
///
/// @brief This file contains code that is used to validate the output of the
/// example codes.
///
/// @author Mirko Myllykoski (mirkom@cs.umu.se), Umeå University
///
/// @section LICENSE
///
/// Copyright (c) 2019-2020, Umeå Universitet
///
/// Redistribution and use in source and binary forms, with or without
/// modification, are permitted provided that the following conditions are met:
///
/// 1. Redistributions of source code must retain the above copyright notice,
///    this list of conditions and the following disclaimer.
///
/// 2. 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.
///
/// 3. Neither the name of the copyright holder 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 HOLDER 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.
///

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <cblas.h>

static inline double squ(double x)
{
    return x*x;
}

void check_orthogonality(int n, size_t ldQ, double const *Q)
{
    size_t ldT = ((n/8)+1)*8;
    double *T = malloc(n*ldT*sizeof(double));

    cblas_dgemm(CblasColMajor, CblasNoTrans, CblasTrans, n, n, n, 1.0,
        Q, ldQ, Q, ldQ, 0.0, T, ldT);

    double dot = 0.0;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            dot += squ(T[i*ldT+j] - (i == j ? 1.0 : 0.0));

    double norm = ((long long)1<<52) * sqrt(dot)/sqrt(n);

    if (norm < 1000) {
        printf("The matrix is orthogonal.\n");
    }
    else {
        fprintf(stderr, "Matrix is not orthogonal.\n");
        exit(EXIT_FAILURE);
    }

    free(T);
}

void check_residual(
    int n, size_t ldQ, size_t ldA, size_t ldZ, size_t ldC,
    double const *Q, double const *A, double const *Z, double const *C)
{
    size_t ldT = ((n/8)+1)*8;
    double *T = malloc(n*ldT*sizeof(double));

    size_t ldY = ((n/8)+1)*8;
    double *Y = malloc(n*ldT*sizeof(double));

    cblas_dgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, n, n, n, 1.0,
        Q, ldQ, A, ldA, 0.0, T, ldT);
    cblas_dgemm(CblasColMajor, CblasNoTrans, CblasTrans, n, n, n, 1.0,
        T, ldT, Z, ldZ, 0.0, Y, ldY);

    double dot = 0.0, a_dot = 0.0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            dot += squ(Y[i*ldY+j] - C[i*ldC+j]);
            a_dot += squ(C[i*ldC+j]);
        }
    }

    double norm = ((long long)1<<52) * sqrt(dot)/sqrt(a_dot);

    if (norm < 1000) {
        printf("The residual is small enough.\n");
    }
    else {
        fprintf(stderr, "The residual is too large.\n");
        exit(EXIT_FAILURE);
    }

    free(T);
    free(Y);
}


#include <lapacke.h>


#ifndef __GEMM_DRIVER_H
#define __GEMM_DRIVER_H

#include "util.h"

#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <tuple>
#include <algorithm>
#include <assert.h>
#include <iostream>
#include <sstream>
#include <vector>
// openblas
#include <cblas.h>

#ifndef CEIL
#define CEIL(value, divider)  (   ((value)-1)/(divider)+1  )
#endif

#ifndef CEIL_WRAP
#define CEIL_WRAP(value, divider)  ( CEIL((value), (divider)) * (divider)  )
#endif

typedef enum {
    LAYOUT_ROW_MAJOR = 0,
    LAYOUT_COL_MAJOR
}layout_t;

typedef enum {
    TRANS_NO_TRANS = 0,
    TRANS_TRANS,
    TRANS_CONJ_TRANS,
    TRANS_CONJ_NO_TRANS,
}trans_t;

typedef enum {
    IDENT_A_MATRIX = 0,
    IDENT_B_MATRIX
}identifier_t;

// cblas helper function
static inline CBLAS_ORDER to_blas_layout(layout_t layout){
    if(layout == LAYOUT_ROW_MAJOR)
        return CblasRowMajor;
    //if(layout == LAYOUT_COL_MAJOR)
    //TODO: validation
    return CblasColMajor;
}
// cblas helper function
static inline CBLAS_TRANSPOSE to_blas_transpose(trans_t trans){
    switch(trans){
        case  TRANS_NO_TRANS:
            return CblasNoTrans;
        case  TRANS_TRANS:
            return CblasTrans;
        case TRANS_CONJ_TRANS:
            return CblasConjTrans;
        case TRANS_CONJ_NO_TRANS:
            return CblasConjNoTrans;
        default:
            return CblasConjNoTrans;
    }
}
static inline const char * to_layout_str(layout_t layout){
    if(layout == LAYOUT_ROW_MAJOR)
        return "CblasRowMajor";
    if(layout == LAYOUT_COL_MAJOR)
        return "CblasColMajor";
    return "n/a major";
}

static inline const char * to_trans_str(trans_t trans){
    if(trans == TRANS_NO_TRANS)
        return "CblasNoTrans";
    if(trans == TRANS_TRANS)
        return "CblasTrans";
    if(trans == TRANS_CONJ_TRANS)
        return "CblasConjTrans";
    if(trans == TRANS_CONJ_NO_TRANS)
        return "CblasConjNoTrans";
    return "n/a trans";
}

class gemm_context_t {
public:
// matrix descriptors
    layout_t    layout;
    trans_t     trans_a;
    trans_t     trans_b;
    size_t      m;
    size_t      n;
    size_t      k;

    size_t      lda;
    size_t      ldb;
    size_t      ldc;
    double      alpha;
    double      beta;

//
    size_t      alignment;  // used for alloc A/B/C, indeed not so useful

// blocking parameters
    size_t      mc;
    size_t      nc;
    size_t      kc;
    size_t      mr;
    size_t      nr;

// hw parameters
    //size_t      cpu_id;
    size_t      l1_size;
    size_t      l2_size;
    size_t      l3_size;
    size_t      tlb_entry_l1d;
    size_t      cacheline_size;
    size_t      page_size;
    std::vector<int>    cpu_list;

    double      frequency;  // MHz

    bool        cur_use_tuned {false};  // use tuned param from db or default, only a flag

    void serialize_layout_trans(std::ostream & os){
        std::string al, bl, cl;
        if(layout == LAYOUT_ROW_MAJOR){
            cl = "cr";
            if(trans_a == TRANS_NO_TRANS || trans_a == TRANS_CONJ_NO_TRANS){
                al = "ar";
            }else{
                al = "ac";
            }
            if(trans_b == TRANS_NO_TRANS || trans_b == TRANS_CONJ_NO_TRANS){
                bl = "br";
            }else{
                bl = "bc";
            }
        }else{
            cl = "cc";
            if(trans_a == TRANS_NO_TRANS || trans_a == TRANS_CONJ_NO_TRANS){
                al = "ac";
            }else{
                al = "ar";
            }
            if(trans_b == TRANS_NO_TRANS || trans_b == TRANS_CONJ_NO_TRANS){
                bl = "bc";
            }else{
                bl = "br";
            }
        }
        os<<al<<"-"<<bl<<"-"<<cl;
    }

    void deserialize_layout_trans(const std::istream & is){
        std::string al, bl, cl;
        std::stringstream tmp;
        tmp << is.rdbuf();
        std::string s( tmp.str() );

        al = s.substr(0, 2);
        bl = s.substr(3, 2);
        cl = s.substr(6, 2);

        if(cl == "cr"){
            layout = LAYOUT_ROW_MAJOR;
            if(al == "ar"){
                trans_a = TRANS_NO_TRANS;
            }else{
                trans_a = TRANS_TRANS;
            }
            if(bl == "br"){
                trans_b = TRANS_NO_TRANS;
            }else{
                trans_b = TRANS_TRANS;
            }
        }else if(cl == "cc"){
            layout = LAYOUT_COL_MAJOR;
            if(al == "ar"){
                trans_a = TRANS_TRANS;
            }else{
                trans_a = TRANS_NO_TRANS;
            }
            if(bl == "br"){
                trans_b = TRANS_TRANS;
            }else{
                trans_b = TRANS_NO_TRANS;
            }
        }
    }

    // TODO: fix more param
    void serialize(std::ostream & os){
        serialize_layout_trans(os);
        os<<"-"<<m<<"-"<<n<<"-"<<k;
    }
    void serialize(std::string & str){
        std::ostringstream oss;
        serialize(oss);
        str = oss.str();
    }
    void deserialize(std::istream & is){
        char _d;

        deserialize_layout_trans(is);
        is>>_d>>m>>_d>>n>>_d>>k;
    }
    void deserialize(std::string & str){
        std::istringstream iss;
        iss.str(str);
        deserialize(iss);
    }
};

// https://software.intel.com/en-us/mkl-developer-reference-c-cblas-gemm

class matrix_elem_t {
public:
    size_t operator() (size_t row, size_t col, size_t ldim, layout_t layout, trans_t trans){
        if(layout == LAYOUT_ROW_MAJOR){
            if(trans == TRANS_NO_TRANS || trans == TRANS_CONJ_NO_TRANS){
                assert(ldim>=col);
                return row * ldim;
            }
            else{
                assert(ldim>=row);
                return col * ldim;
            }
        }else{
            if(trans == TRANS_NO_TRANS || trans == TRANS_CONJ_NO_TRANS){
                assert(ldim>=row);
                return col * ldim;
            }
            else{
                assert(ldim>=col);
                return row * ldim;
            }
        }
    }
};

template<typename T>
class matrix_t{
public:
    matrix_t(size_t row_, size_t col_, size_t ldim_,
        layout_t layout_, trans_t trans_, size_t alignment_)
    {
        this->row = row_;
        this->col = col_;
        this->ldim = ldim_;
        // TODO ldim should be multiple of alignment!
        this->layout = layout_;
        this->trans = trans_;
        this->alignment = alignment_;

        size_t elements = matrix_elem_t()(row_, col_, ldim_, layout_, trans_);
        this->data = (T *) __aligned_malloc(sizeof(T)*elements, alignment_);
        rand_vector(this->data, elements);
    }
    ~matrix_t(){
        if(data)
            __aligned_free(this->data);
    }

    size_t dtype_size() const {
        return sizeof(T);
    }
    void __copy(const matrix_t<T> & rhs){
        this->row = rhs.row;
        this->col = rhs.col;
        this->ldim = rhs.ldim;

        this->layout = rhs.layout;
        this->trans = rhs.trans;
        this->alignment = rhs.alignment;
        size_t elements = matrix_elem_t()(rhs.row, rhs.col, rhs.ldim, rhs.layout, rhs.trans);
        this->data = (T *) __aligned_malloc(sizeof(T)*elements, alignment);
        memcpy(this->data, rhs.data, sizeof(T)*elements);
    }

    matrix_t(const matrix_t<T> & rhs){
        __copy(rhs);
    }
    matrix_t& operator =(const matrix_t<T> & rhs){
        __copy(rhs);
        return *this;
    }

    T           *data {nullptr};
    size_t      row;
    size_t      col;
    size_t      ldim;   // leading dimension

    layout_t    layout;
    trans_t     trans;
    size_t      alignment;
};

//typedef matrix_t<float> matrix_fp32_t;
//typedef matrix_t<double> matrix_fp64_t;

#endif


/* permutation/init.c
 *
 * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include <config.h>
#include <stdlib.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_permutation.h>

gsl_permutation *
gsl_permutation_alloc (const size_t n)
{
  gsl_permutation * p;

  if (n == 0)
    {
      GSL_ERROR_VAL ("permutation length n must be positive integer",
                        GSL_EDOM, 0);
    }

  p = (gsl_permutation *) malloc (sizeof (gsl_permutation));

  if (p == 0)
    {
      GSL_ERROR_VAL ("failed to allocate space for permutation struct",
                        GSL_ENOMEM, 0);
    }

  p->data = (size_t *) malloc (n * sizeof (size_t));

  if (p->data == 0)
    {
      free (p);         /* exception in constructor, avoid memory leak */

      GSL_ERROR_VAL ("failed to allocate space for permutation data",
                        GSL_ENOMEM, 0);
    }

  p->size = n;

  return p;
}

gsl_permutation *
gsl_permutation_calloc (const size_t n)
{
  size_t i;

  gsl_permutation * p =  gsl_permutation_alloc (n);

  if (p == 0)
    return 0;

  /* initialize permutation to identity */

  for (i = 0; i < n; i++)
    {
      p->data[i] = i;
    }

  return p;
}

void
gsl_permutation_init (gsl_permutation * p)
{
  const size_t n = p->size ;
  size_t i;

  /* initialize permutation to identity */

  for (i = 0; i < n; i++)
    {
      p->data[i] = i;
    }
}

void
gsl_permutation_free (gsl_permutation * p)
{
  free (p->data);
  free (p);
}


// Copyright (c) 2005 - 2011 Marc de Kamps
// All rights reserved.
//
// 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 the copyright holder 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.
//
//      If you use this software in work leading to a scientific publication, you should cite
//      the 'currently valid reference', which can be found at http://miind.sourceforge.net
#ifndef _CODE_LIBS_NUMTOOLSLIB_RANDOMGENERATOR_INCLUDE_GUARD
#define _CODE_LIBS_NUMTOOLSLIB_RANDOMGENERATOR_INCLUDE_GUARD

#include <vector>
#include <iostream>
#include <gsl/gsl_rng.h>
#include "ChangeSeedException.h"

using std::vector;

namespace NumtoolsLib
{

	//! Global default seed for RandomGenerator

	const long GLOBAL_SEED = 9875987L;

	//! This class contains a specific uniform random generator that can be used to generate other distributions
	//! GaussianDistribution and UniformDistribution, for example, use this random generator, which gsl_rng_mt19937
	//! of the Gnu Scietific Library. This class can be used to modify the seed and to keep track of the number
	//! of draws made by the generator. Distributions use one copy of this class.

	class RandomGenerator
	{

	public:

		RandomGenerator(long lseed = GLOBAL_SEED);
		~RandomGenerator();

		double	NextSampleValue();

	private:

		RandomGenerator(const RandomGenerator&);
		RandomGenerator& operator=(const RandomGenerator&);

		double	Ran2(long*);

		// new, uniformly distributed value

		void    AddOne         (){ std::cout << "zopa" << std::endl; ++_number_of_draws; }

		long			_initial_seed;    // initial seed value
		unsigned long	_number_of_draws; // number of calls to NextSampleValue

		gsl_rng*		_p_generator;

	}; // end of RandomGenerator

	//! Global Random Generator
	extern RandomGenerator GLOBAL_RANDOM_GENERATOR;

	inline double RandomGenerator::NextSampleValue()
	{
		AddOne();
		return gsl_rng_uniform(_p_generator);
	}

} // end of Numtools

#endif // include guard


#ifndef libceed_petsc_examples_setup_h
#define libceed_petsc_examples_setup_h

#include <ceed.h>
#include <petsc.h>

#include "structs.h"

PetscErrorCode CeedDataDestroy(CeedInt i, CeedData data);
PetscErrorCode SetupLibceedByDegree(DM dm, Ceed ceed, CeedInt degree,
                                    CeedInt topo_dim, CeedInt q_extra,
                                    PetscInt num_comp_x, PetscInt num_comp_u,
                                    PetscInt g_size, PetscInt xl_size,
                                    BPData bp_data, CeedData data,
                                    PetscBool setup_rhs, CeedVector rhs_ceed,
                                    CeedVector *target);
PetscErrorCode CeedLevelTransferSetup(Ceed ceed, CeedInt num_levels,
                                      CeedInt num_comp_u, CeedData *data, CeedInt *leveldegrees,
                                      CeedQFunction qf_restrict, CeedQFunction qf_prolong);

#endif // libceed_petsc_examples_setup_h


#ifndef GSL_INTERFACE_H
#define GSL_INTERFACE_H

#include <gsl/gsl_odeiv2.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_matrix.h>

#ifdef __cplusplus
extern "C" {
#endif

/*****************************
 * Structure definitions
 *****************************
 */

/**
 * Encapsulation of the integrator;
*/
typedef struct cgsl_integrator{

  const gsl_odeiv2_step_type * step_type; /* time step allocation */
  gsl_odeiv2_step      * step;		  /* time step control */
  gsl_odeiv2_control   * control;	  /* definition of the system */
  gsl_odeiv2_system      system;	  /* definition of the driver */
  gsl_odeiv2_evolve    * evolution;	  /* emove forward in time*/
  gsl_odeiv2_driver    * driver;	  /* high level interface */

} cgsl_integrator;

//see <gsl/gsl_odeiv2.h> for an explanation of these
typedef int (* ode_function_ptr ) (double t, const double y[], double dydt[], void * params);
typedef int (* ode_jacobian_ptr ) (double t, const double y[], double * dfdy, double dfdt[], void * params);

/** Pre/post step callbacks
 *      t: Start of the current time step (communicationPoint)
 *     dt: Length of the current time step (communicationStepSize)
 *      n: Size of system
 *      y: For pre, the values of the variables before stepping. For post, after.
 * params: Opaque pointer
 */
typedef int (* pre_post_step_ptr ) (double t, double dt, int n, const double y[], void * params);

enum cgsl_callback_actions{
  CGSL_RESTART = 1                     // multistep integrators need a reset when
                                // used with the epce filter.
};

/**
 *
 *  This is intended to contain everything needed to integrate only one
 *  little bit at a time *and* to be able to backtrack when needed, and to
 *  have multiple instances of the model.
 *
 *  Here we use this for inheritance by aggregation so that each model is
 *  declared as
 *  typedef struct my_model{
 *     cgs_model   m;
 *         .
 *         .
 *     extra stuff
 *         .
 *         .
 *  }  my_model ;
*/

typedef struct cgsl_model{
  int n_variables;
  double *x;  	        /** state variables */
  double *x_backup;     /** for get/set FMU state */
  void * parameters;

  /** Definition of the dynamical system: this assumes an *explicit* ODE */
  ode_function_ptr function;
  /** Jacobian */
  ode_jacobian_ptr jacobian;

  /** Pre/post step functions */
  pre_post_step_ptr pre_step;
  pre_post_step_ptr post_step;

  /** Get/set FMU state
   * Used to copy/retreive internal state to/from temporary storage inside the model
   * params: Opaque pointer
   */
  void (* get_state) (struct cgsl_model *model);
  void (* set_state) (struct cgsl_model *model);

  /** Destructor */
  void (* free) (struct cgsl_model * model);

  /** Needed by ModelExchange to store content from parameters */
  void* (*get_model_parameters)(const struct cgsl_model *model);
} cgsl_model;

/**
 * Useful function for allocating the most common type of model
 */
cgsl_model* cgsl_model_default_alloc(
        int n_variables,            /** Number of variables */
        const double *x0,           /** Initial values. If NULL, initialize model->x to all zeroes instead */
        void *parameters,           /** User pointer */
        ode_function_ptr function,  /** ODE function */
        ode_jacobian_ptr jacobian,  /** Jacobian */
        pre_post_step_ptr pre_step, /** Pre-step function */
        pre_post_step_ptr post_step,/** Post-step function */
        size_t sz                   /** If sz > sizeof(cgsl_model) then allocate sz bytes instead.
                                        Useful for the my_model case described earlier in this file */
);

/** Default destructor. Frees model->x and the model itself */
void cgsl_model_default_free(cgsl_model *model);

/**
 * Finally we can put everything in a bag.  The spefic model only has to
 * fill in these fields.
 */
typedef struct cgsl_simulation {

  cgsl_model * model;         /** this contains the state variables */
  cgsl_integrator i;
  double t;		      /** current time */
  double t1;		      /** stop time */
  double h;		      /** first stepsize and current value */

  int   fixed_step;	      /** whether or not we move at fixed step */
  FILE * file;
  int store_data;	      /** whether or not we save the data in an array */
  double * data;              /** store variables as integration proceeds */
  int buffer_size;            /** size of data storage */
  int n;		      /** number of time steps taken */
  int save;		      /** persistence to file */
  int print;		      /** verbose on stderr */

  int iterations;             /** Number of iterations done by last call to cgsl_step_to() */
} cgsl_simulation;

/*****************************
 * Enum  definitions
 *****************************
 */

/**
 * List of available time integration methods in the gsl_odeiv2 library
 */
enum cgsl_integrator_ids
{
  rk2,		/* 0 */
  rk4,		/* 1 */
  rkf45,	/* 2 */
  rkck,		/* 3 */
  rk8pd,	/* 4 */
  rk1imp,	/* 5 */
  rk2imp,	/* 6 */
  rk4imp,	/* 7 */
  bsimp,	/* 8 */
  msadams,	/* 9 */
  msbdf		/*10 */
};

/* this will flag integrators which need restart */
  extern int restart_integrator;

/**************
 * Function declarations.
 **************
 */

/**
 * Essentially the constructor for the cgsl_simulation object.
 * The dynamical model is defined by a function, its Jacobian, an
 * opaque parameter struct, and a set of initial values.
 * All variables are assumed to be continuous.
 *
 *  \TODO: fix semantics for saving.  Use a filename
 *   instead of descriptor?  Open and close file automatically?
 */
cgsl_simulation cgsl_init_simulation_tolerance(
  cgsl_model * model, /** the model we work on */
        enum cgsl_integrator_ids integrator, /** Integrator ID   */
        double h,                    /** Initial time-step: must be non-zero, even  with variable step*/
        int fixed_step,		     /** Boolean */
        int save,		     /** Boolean */
        int print,		     /** Boolean  */
  FILE *f,		             /** File descriptor if 'save' is enabled  */
  double reltol, double abstol
  );

cgsl_simulation cgsl_init_simulation(
  cgsl_model * model, /** the model we work on */
        enum cgsl_integrator_ids integrator, /** Integrator ID   */
        double h,                    /** Initial time-step: must be non-zero, even  with variable step*/
        int fixed_step,		     /** Boolean */
        int save,		     /** Boolean */
        int print,		     /** Boolean  */
        FILE *f		             /** File descriptor if 'save' is enabled  */
  );

/**
 *  Memory deallocation.
 */
void  cgsl_free_simulation( cgsl_simulation sim );

/**  Step from current time to next communication point. */
int cgsl_step_to(void * _s,  double comm_point, double comm_step ) ;

/** Accessor */
const gsl_odeiv2_step_type * cgsl_get_integrator( int  i ) ;

/**  Commit to file. */
void cgsl_save_data( struct cgsl_simulation * sim );

/** Mutators for fixed step*/
/** \TODO: make this a toggle */
void cgsl_simulation_set_fixed_step( cgsl_simulation * s, double h );
void cgsl_simulation_set_variable_step( cgsl_simulation * s );

/** Get/set FMU state */
void cgsl_simulation_get( cgsl_simulation *s );
void cgsl_simulation_set( cgsl_simulation *s );

#ifdef __cplusplus
}
#endif

#endif


/*
GENETIC - A simple genetic algorithm.

Copyright 2014, Javier Burguete Tolosa.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
	list of conditions and the following disclaimer.

2. 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.

THIS SOFTWARE IS PROVIDED BY Javier Burguete Tolosa ``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 Javier Burguete Tolosa 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.
*/

/**
 * \file reproduction.c
 * \brief Source file to define the reproduction functions.
 * \author Javier Burguete Tolosa.
 * \copyright Copyright 2014 Javier Burguete Tolosa. All rights reserved.
 */
#define _GNU_SOURCE
#include <string.h>
#include <glib.h>
#include <gsl/gsl_rng.h>
//#include "config.h"
#include "bits.h"
#include "entity.h"
#include "reproduction.h"

void (*reproduction) (Entity *, Entity *, Entity *, unsigned int, gsl_rng *);
  ///< Pointer to the function to apply the reproduction operation.

/**
 * Function to mate two genotypes by single-point reproduction of each genome.
 */
static void
reproduction_singlepoints (Entity * father,     ///< Father.
                           Entity * mother,     ///< Mother.
                           Entity * son,        ///< Son.
                           unsigned int nbits,  ///< Genome nbits.
                           gsl_rng * rng)
                           ///< GSL random numbers generator.
{
  int i;
  i = gsl_rng_uniform_int (rng, nbits);
  bit_copy (son->genome, mother->genome, 0, 0, i);
  bit_copy (son->genome, father->genome, i, i, nbits - i);
}

/**
 * Function to mate two genotypes by double-point reproduction of each genome.
 */
static void
reproduction_doublepoints (Entity * father,     ///< Father.
                           Entity * mother,     ///< Mother.
                           Entity * son,        ///< Son.
                           unsigned int nbits,  ///< Genome nbits.
                           gsl_rng * rng)
                           ///< GSL random numbers generator.
{
  unsigned int i, j, k;
  i = gsl_rng_uniform_int (rng, nbits);
  j = gsl_rng_uniform_int (rng, nbits);
  if (i > j)
    k = i, i = j, j = k;
  bit_copy (son->genome, mother->genome, 0, 0, i);
  bit_copy (son->genome, father->genome, i, i, j - i);
  bit_copy (son->genome, mother->genome, j, j, nbits - j);
}

/**
 * Function to mate two genotypes by random mixing both genomes.
 */
static void
reproduction_mixing (Entity * father,   ///< Father.
                     Entity * mother,   ///< Mother.
                     Entity * son,      ///< Son.
                     unsigned int nbits,        ///< Genome nbits.
                     gsl_rng * rng)     ///< GSL random numbers generator.
{
  unsigned int i;
  for (i = 0; i < nbits; i++)
    {
      if (gsl_rng_uniform_int (rng, 2))
        {
          bit_get (father->genome, i) ?
            bit_set (son->genome, i) : bit_clear (son->genome, i);
        }
      else
        {
          bit_get (mother->genome, i) ?
            bit_set (son->genome, i) : bit_clear (son->genome, i);
        }
    }
}

/**
 * Function to select the reproduction operations.
 */
void
reproduction_init (unsigned int type)   ///< Type of reproduction operations.
{
  switch (type)
    {
    case REPRODUCTION_TYPE_SINGLEPOINTS:
      reproduction = &reproduction_singlepoints;
      break;
    case REPRODUCTION_TYPE_DOUBLEPOINTS:
      reproduction = &reproduction_doublepoints;
      break;
    default:
      reproduction = &reproduction_mixing;
    }
}