/**
 * @file      MeshAdaptors.h
 *
 * @brief     This file contains mesh <-> Eigen matrix adaptors
 *
 * @author    Stefan Reinhold
 * @copyright Copyright (C) 2018 Stefan Reinhold  -- All Rights Reserved.
 *            You may use, distribute and modify this code under the terms of
 *            the AFL 3.0 license; see LICENSE for full license details.
 */

#pragma once

#include "Mesh.h"

#include <Eigen/Core>
#include <gsl/gsl>

namespace CortidQCT {
namespace Internal {
namespace Adaptor {

template <class T>
inline Eigen::Map<Eigen::Matrix<T, 3, Eigen::Dynamic> const>
vertexMap(Mesh<T> const &mesh) {
  return mesh.withUnsafeVertexPointer([&mesh](auto const *ptr) {
    return Eigen::Map<Eigen::Matrix<T, 3, Eigen::Dynamic> const>{
        ptr, 3, gsl::narrow_cast<Eigen::Index>(mesh.vertexCount())};
  });
}

template <class T>
inline Eigen::Map<Eigen::Matrix<T, 3, Eigen::Dynamic>>
vertexMap(Mesh<T> &mesh) {
  return mesh.withUnsafeVertexPointer([&mesh](auto *ptr) {
    return Eigen::Map<Eigen::Matrix<T, 3, Eigen::Dynamic>>{
        ptr, 3, gsl::narrow_cast<Eigen::Index>(mesh.vertexCount())};
  });
}

template <class T>
inline Eigen::Map<Eigen::Matrix<T, 3, Eigen::Dynamic> const>
vertexNormalMap(Mesh<T> const &mesh) {
  return mesh.withUnsafeVertexNormalPointer([&mesh](auto const *ptr) {
    return Eigen::Map<Eigen::Matrix<T, 3, Eigen::Dynamic> const>{
        ptr, 3, gsl::narrow_cast<Eigen::Index>(mesh.vertexCount())};
  });
}

template <class T>
inline Eigen::Map<Eigen::Matrix<T, 3, Eigen::Dynamic>>
vertexNormalMap(Mesh<T> &mesh) {
  return mesh.withUnsafeVertexNormalPointer([&mesh](auto *ptr) {
    return Eigen::Map<Eigen::Matrix<T, 3, Eigen::Dynamic>>{
        ptr, 3, gsl::narrow_cast<Eigen::Index>(mesh.vertexCount())};
  });
}

template <class T>
inline Eigen::Map<
    Eigen::Matrix<typename Mesh<T>::Index, 3, Eigen::Dynamic> const>
indexMap(Mesh<T> const &mesh) {
  using S = typename Mesh<T>::Index;
  return mesh.withUnsafeIndexPointer([&mesh](auto const *ptr) {
    return Eigen::Map<Eigen::Matrix<S, 3, Eigen::Dynamic> const>{
        ptr, 3, gsl::narrow_cast<Eigen::Index>(mesh.triangleCount())};
  });
}

template <class T>
inline Eigen::Map<Eigen::Matrix<typename Mesh<T>::Index, 3, Eigen::Dynamic>>
indexMap(Mesh<T> &mesh) {
  using S = typename Mesh<T>::Index;
  return mesh.withUnsafeIndexPointer([&mesh](auto *ptr) {
    return Eigen::Map<Eigen::Matrix<S, 3, Eigen::Dynamic>>{
        ptr, 3, gsl::narrow_cast<Eigen::Index>(mesh.triangleCount())};
  });
}

template <class T>
inline Eigen::Map<
    Eigen::Matrix<typename Mesh<T>::Label, Eigen::Dynamic, 1> const>
labelMap(Mesh<T> const &mesh) {
  using S = typename Mesh<T>::Label;
  return mesh.withUnsafeLabelPointer([&mesh](auto const *ptr) {
    return Eigen::Map<Eigen::Matrix<S, Eigen::Dynamic, 1> const>{
        ptr, gsl::narrow_cast<Eigen::Index>(mesh.vertexCount())};
  });
}

template <class T>
inline Eigen::Map<Eigen::Matrix<typename Mesh<T>::Label, Eigen::Dynamic, 1>>
labelMap(Mesh<T> &mesh) {
  using S = typename Mesh<T>::Label;
  return mesh.withUnsafeLabelPointer([&mesh](auto *ptr) {
    return Eigen::Map<Eigen::Matrix<S, Eigen::Dynamic, 1>>{
        ptr, gsl::narrow_cast<Eigen::Index>(mesh.vertexCount())};
  });
}

} // namespace Adaptor
} // namespace Internal
} // namespace CortidQCT


#ifndef __KILLDUPTRKS_H__
#define __KILLDUPTRKS_H__

#include <cstddef>
#include <vector>
#include <algorithm>
#include <functional>
#include <utility>
#include <iostream>

#include "L1Trigger/TrackFindingTMTT/interface/Settings.h"
#include "L1Trigger/TrackFindingTMTT/interface/Stub.h"
#include "L1Trigger/TrackFindingTMTT/interface/TP.h"
#include "FWCore/Utilities/interface/Exception.h"
#include <gsl/gsl_fit.h>

using namespace std;

/**
*  Kill duplicate reconstructed tracks.
*  e.g. Those sharing many hits in common.
*
*  Currently this is intended to run only on tracks found within a single (eta,phi) sector.
*  It includes a naive algorithms from Ian (dupTrkAlg = 1) & more sophisticated ones from Ivan (dupTrkAlg > 1).
*  The class is implemented inside L1Trigger/TrackFindingTMTT/interface/KillDupTrks.icc
*
*  The template class "T" can be any class inheriting from L1trackBase.
*
*  -------------------------------------------------------------------------------------------
*   GENERAL INFO ABOUT THE FILTER ALGORITHMS DEFINED IN THE CLASS.
*   Some of these algorithms are designed to work on r-phi L1track2D tracks, and some on r-z
*   L1track2D tracks. Others work on L1tracks3D.
*  -------------------------------------------------------------------------------------------
*/

namespace TMTT {

class L1trackBase;
class L1track2D;
class L1track3D;
class L1fittedTrack;

template <class T> class KillDupTrks {

public:

  KillDupTrks()
	{
    // Check that classed used as template "T" inherits from class L1trackBase.
    static_assert(std::is_base_of<L1trackBase, T>::value, "KillDupTrks ERROR: You instantiated this with a template class not inheriting from L1trackBase!");
  }

  ~KillDupTrks() {}

  /**
  *  Make available cfg parameters & specify which algorithm is to be used for duplicate track removal.
  */
  void init(const Settings* settings, unsigned int dupTrkAlg);

  /**
  *  Eliminate duplicate tracks from the input collection, and so return a reduced list of tracks.
  */
  vector<T> filter(const vector<T>& vecTracks) const;

private:

  /**
  *  Implementing "inverse" OSU algorithm, check for stubs in common,
  *  keep largest candidates if common stubs in N or more layers (default 5 at present), both if equal
  *  Implementing "inverse" OSU algorithm, check for stubs in common,
  *  keep largest candidates if common stubs in N or more layers (default 5 at present), both if equal
  */
  vector<T> filterAlg8(const vector<T>& vecTracks) const;

  /** Implementing "inverse" OSU algorithm, check for layers in common, reverse order as per Luis's suggestion
   * Comparison window of up to 6
   * Modified version of Algo23, looking for layers in common as in Algo8
   * Check if N or more common layers (default 5 at present)
   * Then keep candidate with most stubs, use |q/pT| as tie-break, finally drop "latest" if still equal
   */
vector<T> filterAlg25(const vector<T>& vecTracks) const;

  /**
  *  Prints out a consistently formatted formatted report of killed duplicate track
  */
  void printKill(unsigned alg, unsigned dup, unsigned cand, T dupTrack, T candTrack) const;

  /**
  * Counts candidate layers with stubs in common
  */
  unsigned int layerMatches(std::vector< std::pair<unsigned int, unsigned int> >* iStubs,
			    std::vector< std::pair<unsigned int, unsigned int> >* jStubs) const;
private:

  const Settings *settings_; // Configuration parameters.

  unsigned int dupTrkAlg_; // Specifies choice of algorithm for duplicate track removal.
  unsigned int dupTrkMinCommonHitsLayers_;  // Min no of matched stubs & layers to keep smaller cand
};

}
//=== Include file which implements all the functions in the above class.
#include "L1Trigger/TrackFindingTMTT/interface/KillDupTrks.icc"

#endif


/* ieee-utils/fp-sunos4.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 <sys/ieeefp.h>
#include <floatingpoint.h>
#include <signal.h>
#include <gsl/gsl_ieee_utils.h>
#include <gsl/gsl_errno.h>

int
gsl_ieee_set_mode (int precision, int rounding, int exception_mask)
{
  char * out ;

  switch (precision)
    {
    case GSL_IEEE_SINGLE_PRECISION:
      ieee_flags ("set", "precision", "single", out) ;
      break ;
    case GSL_IEEE_DOUBLE_PRECISION:
      ieee_flags ("set", "precision", "double", out) ;
      break ;
    case GSL_IEEE_EXTENDED_PRECISION:
      ieee_flags ("set", "precision", "extended", out) ;
      break ;
    default:
      ieee_flags ("set", "precision", "extended", out) ;
    }

  switch (rounding)
    {
    case GSL_IEEE_ROUND_TO_NEAREST:
      ieee_flags ("set", "direction", "nearest", out) ;
      break ;
    case GSL_IEEE_ROUND_DOWN:
      ieee_flags ("set", "direction", "negative", out) ;
      break ;
    case GSL_IEEE_ROUND_UP:
      ieee_flags ("set", "direction", "positive", out) ;
      break ;
    case GSL_IEEE_ROUND_TO_ZERO:
      ieee_flags ("set", "direction", "tozero", out) ;
      break ;
    default:
      ieee_flags ("set", "direction", "nearest", out) ;
    }

  if (exception_mask & GSL_IEEE_MASK_INVALID)
    {
      ieee_handler ("set", "invalid", SIGFPE_IGNORE) ;
    }
  else
    {
      ieee_handler ("set", "invalid", SIGFPE_ABORT) ;
    }

  if (exception_mask & GSL_IEEE_MASK_DENORMALIZED)
    {
      ieee_handler ("set", "denormalized", SIGFPE_IGNORE) ;
    }
  else
    {
      GSL_ERROR ("sunos4 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)
    {
      ieee_handler ("set", "division", SIGFPE_IGNORE) ;
    }
  else
    {
      ieee_handler ("set", "division", SIGFPE_ABORT) ;
    }

  if (exception_mask & GSL_IEEE_MASK_OVERFLOW)
    {
      ieee_handler ("set", "overflow", SIGFPE_IGNORE) ;
    }
  else
    {
      ieee_handler ("set", "overflow", SIGFPE_ABORT) ;
    }

  if (exception_mask & GSL_IEEE_MASK_UNDERFLOW)
    {
      ieee_handler ("set", "underflow", SIGFPE_IGNORE) ;
    }
  else
    {
      ieee_handler ("set", "underflow", SIGFPE_ABORT) ;
    }

  if (exception_mask & GSL_IEEE_TRAP_INEXACT)
    {
      ieee_handler ("set", "inexact", SIGFPE_ABORT) ;
    }
  else
    {
      ieee_handler ("set", "inexact", SIGFPE_IGNORE) ;
    }

  return GSL_SUCCESS ;
}


#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_tpmv (void) {
const double flteps = 1e-4, dbleps = 1e-6;
  {
   int order = 101;
   int trans = 111;
   int uplo = 121;
   int diag = 131;
   int N = 2;
   float A[] = { -0.587f, 0.14f, 0.841f };
   float X[] = { -0.213f, 0.885f };
   int incX = -1;
   float x_expected[] = { -0.179133f, -0.549315f };
   cblas_stpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stpmv(case 974)");
     }
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 121;
   int diag = 132;
   int N = 2;
   float A[] = { -0.587f, 0.14f, 0.841f };
   float X[] = { -0.213f, 0.885f };
   int incX = -1;
   float x_expected[] = { -0.213f, 0.85518f };
   cblas_stpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stpmv(case 975)");
     }
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 122;
   int diag = 131;
   int N = 2;
   float A[] = { -0.587f, 0.14f, 0.841f };
   float X[] = { -0.213f, 0.885f };
   int incX = -1;
   float x_expected[] = { -0.055233f, -0.519495f };
   cblas_stpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stpmv(case 976)");
     }
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 122;
   int diag = 132;
   int N = 2;
   float A[] = { -0.587f, 0.14f, 0.841f };
   float X[] = { -0.213f, 0.885f };
   int incX = -1;
   float x_expected[] = { -0.0891f, 0.885f };
   cblas_stpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stpmv(case 977)");
     }
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 121;
   int diag = 131;
   int N = 2;
   float A[] = { -0.587f, 0.14f, 0.841f };
   float X[] = { -0.213f, 0.885f };
   int incX = -1;
   float x_expected[] = { -0.179133f, -0.549315f };
   cblas_stpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stpmv(case 978)");
     }
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 121;
   int diag = 132;
   int N = 2;
   float A[] = { -0.587f, 0.14f, 0.841f };
   float X[] = { -0.213f, 0.885f };
   int incX = -1;
   float x_expected[] = { -0.213f, 0.85518f };
   cblas_stpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stpmv(case 979)");
     }
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 122;
   int diag = 131;
   int N = 2;
   float A[] = { -0.587f, 0.14f, 0.841f };
   float X[] = { -0.213f, 0.885f };
   int incX = -1;
   float x_expected[] = { -0.055233f, -0.519495f };
   cblas_stpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stpmv(case 980)");
     }
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 122;
   int diag = 132;
   int N = 2;
   float A[] = { -0.587f, 0.14f, 0.841f };
   float X[] = { -0.213f, 0.885f };
   int incX = -1;
   float x_expected[] = { -0.0891f, 0.885f };
   cblas_stpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stpmv(case 981)");
     }
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 121;
   int diag = 131;
   int N = 2;
   float A[] = { -0.765f, 0.968f, -0.956f };
   float X[] = { 0.243f, -0.274f };
   int incX = -1;
   float x_expected[] = { -0.49754f, 0.20961f };
   cblas_stpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stpmv(case 982)");
     }
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 121;
   int diag = 132;
   int N = 2;
   float A[] = { -0.765f, 0.968f, -0.956f };
   float X[] = { 0.243f, -0.274f };
   int incX = -1;
   float x_expected[] = { -0.022232f, -0.274f };
   cblas_stpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stpmv(case 983)");
     }
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 122;
   int diag = 131;
   int N = 2;
   float A[] = { -0.765f, 0.968f, -0.956f };
   float X[] = { 0.243f, -0.274f };
   int incX = -1;
   float x_expected[] = { -0.232308f, 0.444834f };
   cblas_stpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stpmv(case 984)");
     }
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 122;
   int diag = 132;
   int N = 2;
   float A[] = { -0.765f, 0.968f, -0.956f };
   float X[] = { 0.243f, -0.274f };
   int incX = -1;
   float x_expected[] = { 0.243f, -0.038776f };
   cblas_stpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stpmv(case 985)");
     }
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 121;
   int diag = 131;
   int N = 2;
   float A[] = { -0.765f, 0.968f, -0.956f };
   float X[] = { 0.243f, -0.274f };
   int incX = -1;
   float x_expected[] = { -0.49754f, 0.20961f };
   cblas_stpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stpmv(case 986)");
     }
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 121;
   int diag = 132;
   int N = 2;
   float A[] = { -0.765f, 0.968f, -0.956f };
   float X[] = { 0.243f, -0.274f };
   int incX = -1;
   float x_expected[] = { -0.022232f, -0.274f };
   cblas_stpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stpmv(case 987)");
     }
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 122;
   int diag = 131;
   int N = 2;
   float A[] = { -0.765f, 0.968f, -0.956f };
   float X[] = { 0.243f, -0.274f };
   int incX = -1;
   float x_expected[] = { -0.232308f, 0.444834f };
   cblas_stpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stpmv(case 988)");
     }
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 122;
   int diag = 132;
   int N = 2;
   float A[] = { -0.765f, 0.968f, -0.956f };
   float X[] = { 0.243f, -0.274f };
   int incX = -1;
   float x_expected[] = { 0.243f, -0.038776f };
   cblas_stpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], flteps, "stpmv(case 989)");
     }
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 121;
   int diag = 131;
   int N = 2;
   double A[] = { 0.393, -0.221, 0.356 };
   double X[] = { -0.062, -0.221 };
   int incX = -1;
   double x_expected[] = { -0.022072, -0.073151 };
   cblas_dtpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtpmv(case 990)");
     }
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 121;
   int diag = 132;
   int N = 2;
   double A[] = { 0.393, -0.221, 0.356 };
   double X[] = { -0.062, -0.221 };
   int incX = -1;
   double x_expected[] = { -0.062, -0.207298 };
   cblas_dtpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtpmv(case 991)");
     }
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 122;
   int diag = 131;
   int N = 2;
   double A[] = { 0.393, -0.221, 0.356 };
   double X[] = { -0.062, -0.221 };
   int incX = -1;
   double x_expected[] = { 0.026769, -0.086853 };
   cblas_dtpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtpmv(case 992)");
     }
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 122;
   int diag = 132;
   int N = 2;
   double A[] = { 0.393, -0.221, 0.356 };
   double X[] = { -0.062, -0.221 };
   int incX = -1;
   double x_expected[] = { -0.013159, -0.221 };
   cblas_dtpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtpmv(case 993)");
     }
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 121;
   int diag = 131;
   int N = 2;
   double A[] = { 0.393, -0.221, 0.356 };
   double X[] = { -0.062, -0.221 };
   int incX = -1;
   double x_expected[] = { -0.022072, -0.073151 };
   cblas_dtpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtpmv(case 994)");
     }
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 121;
   int diag = 132;
   int N = 2;
   double A[] = { 0.393, -0.221, 0.356 };
   double X[] = { -0.062, -0.221 };
   int incX = -1;
   double x_expected[] = { -0.062, -0.207298 };
   cblas_dtpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtpmv(case 995)");
     }
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 122;
   int diag = 131;
   int N = 2;
   double A[] = { 0.393, -0.221, 0.356 };
   double X[] = { -0.062, -0.221 };
   int incX = -1;
   double x_expected[] = { 0.026769, -0.086853 };
   cblas_dtpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtpmv(case 996)");
     }
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 122;
   int diag = 132;
   int N = 2;
   double A[] = { 0.393, -0.221, 0.356 };
   double X[] = { -0.062, -0.221 };
   int incX = -1;
   double x_expected[] = { -0.013159, -0.221 };
   cblas_dtpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtpmv(case 997)");
     }
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 121;
   int diag = 131;
   int N = 2;
   double A[] = { 0.694, 0.501, 0.019 };
   double X[] = { -0.928, 0.365 };
   int incX = -1;
   double x_expected[] = { 0.165233, 0.25331 };
   cblas_dtpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtpmv(case 998)");
     }
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 121;
   int diag = 132;
   int N = 2;
   double A[] = { 0.694, 0.501, 0.019 };
   double X[] = { -0.928, 0.365 };
   int incX = -1;
   double x_expected[] = { -0.745135, 0.365 };
   cblas_dtpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtpmv(case 999)");
     }
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 122;
   int diag = 131;
   int N = 2;
   double A[] = { 0.694, 0.501, 0.019 };
   double X[] = { -0.928, 0.365 };
   int incX = -1;
   double x_expected[] = { -0.017632, -0.211618 };
   cblas_dtpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtpmv(case 1000)");
     }
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 122;
   int diag = 132;
   int N = 2;
   double A[] = { 0.694, 0.501, 0.019 };
   double X[] = { -0.928, 0.365 };
   int incX = -1;
   double x_expected[] = { -0.928, -0.099928 };
   cblas_dtpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtpmv(case 1001)");
     }
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 121;
   int diag = 131;
   int N = 2;
   double A[] = { 0.694, 0.501, 0.019 };
   double X[] = { -0.928, 0.365 };
   int incX = -1;
   double x_expected[] = { 0.165233, 0.25331 };
   cblas_dtpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtpmv(case 1002)");
     }
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 121;
   int diag = 132;
   int N = 2;
   double A[] = { 0.694, 0.501, 0.019 };
   double X[] = { -0.928, 0.365 };
   int incX = -1;
   double x_expected[] = { -0.745135, 0.365 };
   cblas_dtpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtpmv(case 1003)");
     }
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 122;
   int diag = 131;
   int N = 2;
   double A[] = { 0.694, 0.501, 0.019 };
   double X[] = { -0.928, 0.365 };
   int incX = -1;
   double x_expected[] = { -0.017632, -0.211618 };
   cblas_dtpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtpmv(case 1004)");
     }
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 122;
   int diag = 132;
   int N = 2;
   double A[] = { 0.694, 0.501, 0.019 };
   double X[] = { -0.928, 0.365 };
   int incX = -1;
   double x_expected[] = { -0.928, -0.099928 };
   cblas_dtpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[i], x_expected[i], dbleps, "dtpmv(case 1005)");
     }
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 121;
   int diag = 131;
   int N = 2;
   float A[] = { 0.362f, -0.849f, -0.612f, -0.718f, 0.503f, -0.923f };
   float X[] = { 0.904f, 0.461f, -0.367f, 0.153f };
   int incX = -1;
   float x_expected[] = { 0.880215f, -0.602509f, -0.225207f, -0.564235f };
   cblas_ctpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctpmv(case 1006) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctpmv(case 1006) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 121;
   int diag = 132;
   int N = 2;
   float A[] = { 0.362f, -0.849f, -0.612f, -0.718f, 0.503f, -0.923f };
   float X[] = { 0.904f, 0.461f, -0.367f, 0.153f };
   int incX = -1;
   float x_expected[] = { 0.904f, 0.461f, -0.58925f, -0.778204f };
   cblas_ctpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctpmv(case 1007) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctpmv(case 1007) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 122;
   int diag = 131;
   int N = 2;
   float A[] = { 0.362f, -0.849f, -0.612f, -0.718f, 0.503f, -0.923f };
   float X[] = { 0.904f, 0.461f, -0.367f, 0.153f };
   int incX = -1;
   float x_expected[] = { 1.21467f, -0.432639f, -0.002957f, 0.366969f };
   cblas_ctpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctpmv(case 1008) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctpmv(case 1008) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 122;
   int diag = 132;
   int N = 2;
   float A[] = { 0.362f, -0.849f, -0.612f, -0.718f, 0.503f, -0.923f };
   float X[] = { 0.904f, 0.461f, -0.367f, 0.153f };
   int incX = -1;
   float x_expected[] = { 1.23846f, 0.63087f, -0.367f, 0.153f };
   cblas_ctpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctpmv(case 1009) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctpmv(case 1009) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 121;
   int diag = 131;
   int N = 2;
   float A[] = { 0.362f, -0.849f, -0.612f, -0.718f, 0.503f, -0.923f };
   float X[] = { 0.904f, 0.461f, -0.367f, 0.153f };
   int incX = -1;
   float x_expected[] = { 0.880215f, -0.602509f, -0.225207f, -0.564235f };
   cblas_ctpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctpmv(case 1010) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctpmv(case 1010) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 121;
   int diag = 132;
   int N = 2;
   float A[] = { 0.362f, -0.849f, -0.612f, -0.718f, 0.503f, -0.923f };
   float X[] = { 0.904f, 0.461f, -0.367f, 0.153f };
   int incX = -1;
   float x_expected[] = { 0.904f, 0.461f, -0.58925f, -0.778204f };
   cblas_ctpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctpmv(case 1011) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctpmv(case 1011) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 122;
   int diag = 131;
   int N = 2;
   float A[] = { 0.362f, -0.849f, -0.612f, -0.718f, 0.503f, -0.923f };
   float X[] = { 0.904f, 0.461f, -0.367f, 0.153f };
   int incX = -1;
   float x_expected[] = { 1.21467f, -0.432639f, -0.002957f, 0.366969f };
   cblas_ctpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctpmv(case 1012) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctpmv(case 1012) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 122;
   int diag = 132;
   int N = 2;
   float A[] = { 0.362f, -0.849f, -0.612f, -0.718f, 0.503f, -0.923f };
   float X[] = { 0.904f, 0.461f, -0.367f, 0.153f };
   int incX = -1;
   float x_expected[] = { 1.23846f, 0.63087f, -0.367f, 0.153f };
   cblas_ctpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctpmv(case 1013) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctpmv(case 1013) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 121;
   int diag = 131;
   int N = 2;
   float A[] = { -0.876f, -0.697f, -0.519f, -0.223f, 0.526f, -0.077f };
   float X[] = { 0.338f, -0.807f, 0.444f, -0.748f };
   int incX = -1;
   float x_expected[] = { -0.281591f, -0.161308f, -0.9103f, 0.34578f };
   cblas_ctpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctpmv(case 1014) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctpmv(case 1014) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 121;
   int diag = 132;
   int N = 2;
   float A[] = { -0.876f, -0.697f, -0.519f, -0.223f, 0.526f, -0.077f };
   float X[] = { 0.338f, -0.807f, 0.444f, -0.748f };
   int incX = -1;
   float x_expected[] = { -0.05924f, -0.5178f, 0.444f, -0.748f };
   cblas_ctpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctpmv(case 1015) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctpmv(case 1015) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 122;
   int diag = 131;
   int N = 2;
   float A[] = { -0.876f, -0.697f, -0.519f, -0.223f, 0.526f, -0.077f };
   float X[] = { 0.338f, -0.807f, 0.444f, -0.748f };
   int incX = -1;
   float x_expected[] = { 0.115649f, -0.450508f, -1.26568f, 0.689239f };
   cblas_ctpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctpmv(case 1016) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctpmv(case 1016) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 122;
   int diag = 132;
   int N = 2;
   float A[] = { -0.876f, -0.697f, -0.519f, -0.223f, 0.526f, -0.077f };
   float X[] = { 0.338f, -0.807f, 0.444f, -0.748f };
   int incX = -1;
   float x_expected[] = { 0.338f, -0.807f, 0.088617f, -0.404541f };
   cblas_ctpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctpmv(case 1017) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctpmv(case 1017) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 121;
   int diag = 131;
   int N = 2;
   float A[] = { -0.876f, -0.697f, -0.519f, -0.223f, 0.526f, -0.077f };
   float X[] = { 0.338f, -0.807f, 0.444f, -0.748f };
   int incX = -1;
   float x_expected[] = { -0.281591f, -0.161308f, -0.9103f, 0.34578f };
   cblas_ctpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctpmv(case 1018) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctpmv(case 1018) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 121;
   int diag = 132;
   int N = 2;
   float A[] = { -0.876f, -0.697f, -0.519f, -0.223f, 0.526f, -0.077f };
   float X[] = { 0.338f, -0.807f, 0.444f, -0.748f };
   int incX = -1;
   float x_expected[] = { -0.05924f, -0.5178f, 0.444f, -0.748f };
   cblas_ctpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctpmv(case 1019) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctpmv(case 1019) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 122;
   int diag = 131;
   int N = 2;
   float A[] = { -0.876f, -0.697f, -0.519f, -0.223f, 0.526f, -0.077f };
   float X[] = { 0.338f, -0.807f, 0.444f, -0.748f };
   int incX = -1;
   float x_expected[] = { 0.115649f, -0.450508f, -1.26568f, 0.689239f };
   cblas_ctpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctpmv(case 1020) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctpmv(case 1020) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 122;
   int diag = 132;
   int N = 2;
   float A[] = { -0.876f, -0.697f, -0.519f, -0.223f, 0.526f, -0.077f };
   float X[] = { 0.338f, -0.807f, 0.444f, -0.748f };
   int incX = -1;
   float x_expected[] = { 0.338f, -0.807f, 0.088617f, -0.404541f };
   cblas_ctpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctpmv(case 1021) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctpmv(case 1021) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 113;
   int uplo = 121;
   int diag = 131;
   int N = 2;
   float A[] = { 0.869f, -0.091f, -0.859f, 0.008f, -0.921f, -0.321f };
   float X[] = { -0.122f, -0.364f, 0.602f, -0.96f };
   int incX = -1;
   float x_expected[] = { -0.295592f, 1.11591f, 0.610498f, -0.779458f };
   cblas_ctpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctpmv(case 1022) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctpmv(case 1022) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 113;
   int uplo = 121;
   int diag = 132;
   int N = 2;
   float A[] = { 0.869f, -0.091f, -0.859f, 0.008f, -0.921f, -0.321f };
   float X[] = { -0.122f, -0.364f, 0.602f, -0.96f };
   int incX = -1;
   float x_expected[] = { -0.646798f, 0.455824f, 0.602f, -0.96f };
   cblas_ctpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctpmv(case 1023) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctpmv(case 1023) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 113;
   int uplo = 122;
   int diag = 131;
   int N = 2;
   float A[] = { 0.869f, -0.091f, -0.859f, 0.008f, -0.921f, -0.321f };
   float X[] = { -0.122f, -0.364f, 0.602f, -0.96f };
   int incX = -1;
   float x_expected[] = { 0.229206f, 0.296082f, 0.712384f, -0.465806f };
   cblas_ctpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctpmv(case 1024) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctpmv(case 1024) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 113;
   int uplo = 122;
   int diag = 132;
   int N = 2;
   float A[] = { 0.869f, -0.091f, -0.859f, 0.008f, -0.921f, -0.321f };
   float X[] = { -0.122f, -0.364f, 0.602f, -0.96f };
   int incX = -1;
   float x_expected[] = { -0.122f, -0.364f, 0.703886f, -0.646348f };
   cblas_ctpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctpmv(case 1025) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctpmv(case 1025) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 113;
   int uplo = 121;
   int diag = 131;
   int N = 2;
   float A[] = { 0.869f, -0.091f, -0.859f, 0.008f, -0.921f, -0.321f };
   float X[] = { -0.122f, -0.364f, 0.602f, -0.96f };
   int incX = -1;
   float x_expected[] = { -0.295592f, 1.11591f, 0.610498f, -0.779458f };
   cblas_ctpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctpmv(case 1026) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctpmv(case 1026) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 113;
   int uplo = 121;
   int diag = 132;
   int N = 2;
   float A[] = { 0.869f, -0.091f, -0.859f, 0.008f, -0.921f, -0.321f };
   float X[] = { -0.122f, -0.364f, 0.602f, -0.96f };
   int incX = -1;
   float x_expected[] = { -0.646798f, 0.455824f, 0.602f, -0.96f };
   cblas_ctpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctpmv(case 1027) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctpmv(case 1027) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 113;
   int uplo = 122;
   int diag = 131;
   int N = 2;
   float A[] = { 0.869f, -0.091f, -0.859f, 0.008f, -0.921f, -0.321f };
   float X[] = { -0.122f, -0.364f, 0.602f, -0.96f };
   int incX = -1;
   float x_expected[] = { 0.229206f, 0.296082f, 0.712384f, -0.465806f };
   cblas_ctpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctpmv(case 1028) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctpmv(case 1028) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 113;
   int uplo = 122;
   int diag = 132;
   int N = 2;
   float A[] = { 0.869f, -0.091f, -0.859f, 0.008f, -0.921f, -0.321f };
   float X[] = { -0.122f, -0.364f, 0.602f, -0.96f };
   int incX = -1;
   float x_expected[] = { -0.122f, -0.364f, 0.703886f, -0.646348f };
   cblas_ctpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], flteps, "ctpmv(case 1029) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], flteps, "ctpmv(case 1029) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 121;
   int diag = 131;
   int N = 2;
   double A[] = { 0.254, 0.263, -0.271, -0.595, -0.182, -0.672 };
   double X[] = { -0.042, -0.705, -0.255, -0.854 };
   int incX = -1;
   double x_expected[] = { -0.466116, 0.156534, -0.248261, -0.067936 };
   cblas_ztpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztpmv(case 1030) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztpmv(case 1030) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 121;
   int diag = 132;
   int N = 2;
   double A[] = { 0.254, 0.263, -0.271, -0.595, -0.182, -0.672 };
   double X[] = { -0.042, -0.705, -0.255, -0.854 };
   int incX = -1;
   double x_expected[] = { -0.042, -0.705, -0.663093, -0.637955 };
   cblas_ztpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztpmv(case 1031) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztpmv(case 1031) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 122;
   int diag = 131;
   int N = 2;
   double A[] = { 0.254, 0.263, -0.271, -0.595, -0.182, -0.672 };
   double X[] = { -0.042, -0.705, -0.255, -0.854 };
   int incX = -1;
   double x_expected[] = { -0.905141, 0.539693, 0.159832, -0.283981 };
   cblas_ztpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztpmv(case 1032) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztpmv(case 1032) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 111;
   int uplo = 122;
   int diag = 132;
   int N = 2;
   double A[] = { 0.254, 0.263, -0.271, -0.595, -0.182, -0.672 };
   double X[] = { -0.042, -0.705, -0.255, -0.854 };
   int incX = -1;
   double x_expected[] = { -0.481025, -0.321841, -0.255, -0.854 };
   cblas_ztpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztpmv(case 1033) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztpmv(case 1033) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 121;
   int diag = 131;
   int N = 2;
   double A[] = { 0.254, 0.263, -0.271, -0.595, -0.182, -0.672 };
   double X[] = { -0.042, -0.705, -0.255, -0.854 };
   int incX = -1;
   double x_expected[] = { -0.466116, 0.156534, -0.248261, -0.067936 };
   cblas_ztpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztpmv(case 1034) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztpmv(case 1034) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 121;
   int diag = 132;
   int N = 2;
   double A[] = { 0.254, 0.263, -0.271, -0.595, -0.182, -0.672 };
   double X[] = { -0.042, -0.705, -0.255, -0.854 };
   int incX = -1;
   double x_expected[] = { -0.042, -0.705, -0.663093, -0.637955 };
   cblas_ztpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztpmv(case 1035) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztpmv(case 1035) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 122;
   int diag = 131;
   int N = 2;
   double A[] = { 0.254, 0.263, -0.271, -0.595, -0.182, -0.672 };
   double X[] = { -0.042, -0.705, -0.255, -0.854 };
   int incX = -1;
   double x_expected[] = { -0.905141, 0.539693, 0.159832, -0.283981 };
   cblas_ztpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztpmv(case 1036) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztpmv(case 1036) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 111;
   int uplo = 122;
   int diag = 132;
   int N = 2;
   double A[] = { 0.254, 0.263, -0.271, -0.595, -0.182, -0.672 };
   double X[] = { -0.042, -0.705, -0.255, -0.854 };
   int incX = -1;
   double x_expected[] = { -0.481025, -0.321841, -0.255, -0.854 };
   cblas_ztpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztpmv(case 1037) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztpmv(case 1037) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 121;
   int diag = 131;
   int N = 2;
   double A[] = { 0.421, -0.407, -0.595, -0.387, 0.884, -0.498 };
   double X[] = { -0.008, 0.904, -0.689, -0.679 };
   int incX = -1;
   double x_expected[] = { 0.590302, 1.473768, -0.566422, -0.005436 };
   cblas_ztpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztpmv(case 1038) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztpmv(case 1038) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 121;
   int diag = 132;
   int N = 2;
   double A[] = { 0.421, -0.407, -0.595, -0.387, 0.884, -0.498 };
   double X[] = { -0.008, 0.904, -0.689, -0.679 };
   int incX = -1;
   double x_expected[] = { 0.139182, 1.574648, -0.689, -0.679 };
   cblas_ztpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztpmv(case 1039) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztpmv(case 1039) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 122;
   int diag = 131;
   int N = 2;
   double A[] = { 0.421, -0.407, -0.595, -0.387, 0.884, -0.498 };
   double X[] = { -0.008, 0.904, -0.689, -0.679 };
   int incX = -1;
   double x_expected[] = { 0.44312, 0.80312, -0.211814, -0.54022 };
   cblas_ztpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztpmv(case 1040) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztpmv(case 1040) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 112;
   int uplo = 122;
   int diag = 132;
   int N = 2;
   double A[] = { 0.421, -0.407, -0.595, -0.387, 0.884, -0.498 };
   double X[] = { -0.008, 0.904, -0.689, -0.679 };
   int incX = -1;
   double x_expected[] = { -0.008, 0.904, -0.334392, -1.213784 };
   cblas_ztpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztpmv(case 1041) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztpmv(case 1041) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 121;
   int diag = 131;
   int N = 2;
   double A[] = { 0.421, -0.407, -0.595, -0.387, 0.884, -0.498 };
   double X[] = { -0.008, 0.904, -0.689, -0.679 };
   int incX = -1;
   double x_expected[] = { 0.590302, 1.473768, -0.566422, -0.005436 };
   cblas_ztpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztpmv(case 1042) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztpmv(case 1042) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 121;
   int diag = 132;
   int N = 2;
   double A[] = { 0.421, -0.407, -0.595, -0.387, 0.884, -0.498 };
   double X[] = { -0.008, 0.904, -0.689, -0.679 };
   int incX = -1;
   double x_expected[] = { 0.139182, 1.574648, -0.689, -0.679 };
   cblas_ztpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztpmv(case 1043) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztpmv(case 1043) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 122;
   int diag = 131;
   int N = 2;
   double A[] = { 0.421, -0.407, -0.595, -0.387, 0.884, -0.498 };
   double X[] = { -0.008, 0.904, -0.689, -0.679 };
   int incX = -1;
   double x_expected[] = { 0.44312, 0.80312, -0.211814, -0.54022 };
   cblas_ztpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztpmv(case 1044) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztpmv(case 1044) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 112;
   int uplo = 122;
   int diag = 132;
   int N = 2;
   double A[] = { 0.421, -0.407, -0.595, -0.387, 0.884, -0.498 };
   double X[] = { -0.008, 0.904, -0.689, -0.679 };
   int incX = -1;
   double x_expected[] = { -0.008, 0.904, -0.334392, -1.213784 };
   cblas_ztpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztpmv(case 1045) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztpmv(case 1045) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 113;
   int uplo = 121;
   int diag = 131;
   int N = 2;
   double A[] = { -0.743, -0.078, 0.77, 0.505, 0.157, -0.986 };
   double X[] = { -0.641, 0.565, -0.406, -0.948 };
   int incX = -1;
   double x_expected[] = { -1.449087, -1.068251, 0.375602, 0.672696 };
   cblas_ztpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztpmv(case 1046) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztpmv(case 1046) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 113;
   int uplo = 121;
   int diag = 132;
   int N = 2;
   double A[] = { -0.743, -0.078, 0.77, 0.505, 0.157, -0.986 };
   double X[] = { -0.641, 0.565, -0.406, -0.948 };
   int incX = -1;
   double x_expected[] = { -1.43236, 0.04007, -0.406, -0.948 };
   cblas_ztpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztpmv(case 1047) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztpmv(case 1047) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 113;
   int uplo = 122;
   int diag = 131;
   int N = 2;
   double A[] = { -0.743, -0.078, 0.77, 0.505, 0.157, -0.986 };
   double X[] = { -0.641, 0.565, -0.406, -0.948 };
   int incX = -1;
   double x_expected[] = { -0.657727, -0.543321, 0.167357, 1.431451 };
   cblas_ztpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztpmv(case 1048) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztpmv(case 1048) imag");
     };
   };
  };

  {
   int order = 101;
   int trans = 113;
   int uplo = 122;
   int diag = 132;
   int N = 2;
   double A[] = { -0.743, -0.078, 0.77, 0.505, 0.157, -0.986 };
   double X[] = { -0.641, 0.565, -0.406, -0.948 };
   int incX = -1;
   double x_expected[] = { -0.641, 0.565, -0.614245, -0.189245 };
   cblas_ztpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztpmv(case 1049) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztpmv(case 1049) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 113;
   int uplo = 121;
   int diag = 131;
   int N = 2;
   double A[] = { -0.743, -0.078, 0.77, 0.505, 0.157, -0.986 };
   double X[] = { -0.641, 0.565, -0.406, -0.948 };
   int incX = -1;
   double x_expected[] = { -1.449087, -1.068251, 0.375602, 0.672696 };
   cblas_ztpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztpmv(case 1050) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztpmv(case 1050) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 113;
   int uplo = 121;
   int diag = 132;
   int N = 2;
   double A[] = { -0.743, -0.078, 0.77, 0.505, 0.157, -0.986 };
   double X[] = { -0.641, 0.565, -0.406, -0.948 };
   int incX = -1;
   double x_expected[] = { -1.43236, 0.04007, -0.406, -0.948 };
   cblas_ztpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztpmv(case 1051) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztpmv(case 1051) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 113;
   int uplo = 122;
   int diag = 131;
   int N = 2;
   double A[] = { -0.743, -0.078, 0.77, 0.505, 0.157, -0.986 };
   double X[] = { -0.641, 0.565, -0.406, -0.948 };
   int incX = -1;
   double x_expected[] = { -0.657727, -0.543321, 0.167357, 1.431451 };
   cblas_ztpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztpmv(case 1052) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztpmv(case 1052) imag");
     };
   };
  };

  {
   int order = 102;
   int trans = 113;
   int uplo = 122;
   int diag = 132;
   int N = 2;
   double A[] = { -0.743, -0.078, 0.77, 0.505, 0.157, -0.986 };
   double X[] = { -0.641, 0.565, -0.406, -0.948 };
   int incX = -1;
   double x_expected[] = { -0.641, 0.565, -0.614245, -0.189245 };
   cblas_ztpmv(order, uplo, trans, diag, N, A, X, incX);
   {
     int i;
     for (i = 0; i < 2; i++) {
       gsl_test_rel(X[2*i], x_expected[2*i], dbleps, "ztpmv(case 1053) real");
       gsl_test_rel(X[2*i+1], x_expected[2*i+1], dbleps, "ztpmv(case 1053) imag");
     };
   };
  };

}


/**
 *
 * @file qwrapper_dgemm.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
 * @author Mathieu Faverge
 * @author Jakub Kurzak
 * @date 2010-11-15
 * @generated d Tue Jan  7 11:44:56 2014
 *
 **/
#include <cblas.h>
#include "common.h"

/***************************************************************************//**
 *
 **/
void QUARK_CORE_dgemm(Quark *quark, Quark_Task_Flags *task_flags,
                      PLASMA_enum transA, int transB,
                      int m, int n, int k, int nb,
                      double alpha, const double *A, int lda,
                                                const double *B, int ldb,
                      double beta, double *C, int ldc)
{
    DAG_CORE_GEMM;
    QUARK_Insert_Task(quark, CORE_dgemm_quark, task_flags,
        sizeof(PLASMA_enum),                &transA,    VALUE,
        sizeof(PLASMA_enum),                &transB,    VALUE,
        sizeof(int),                        &m,         VALUE,
        sizeof(int),                        &n,         VALUE,
        sizeof(int),                        &k,         VALUE,
        sizeof(double),         &alpha,     VALUE,
        sizeof(double)*nb*nb,    A,                 INPUT,
        sizeof(int),                        &lda,       VALUE,
        sizeof(double)*nb*nb,    B,                 INPUT,
        sizeof(int),                        &ldb,       VALUE,
        sizeof(double),         &beta,      VALUE,
        sizeof(double)*nb*nb,    C,                 INOUT,
        sizeof(int),                        &ldc,       VALUE,
        0);
}

/***************************************************************************//**
 *
 **/
void QUARK_CORE_dgemm2( Quark *quark, Quark_Task_Flags *task_flags,
                        PLASMA_enum transA, int transB,
                        int m, int n, int k, int nb,
                        double alpha, const double *A, int lda,
                        const double *B, int ldb,
                        double beta, double *C, int ldc)
{
    DAG_CORE_GEMM;
    QUARK_Insert_Task(quark, CORE_dgemm_quark, task_flags,
        sizeof(PLASMA_enum),                &transA,    VALUE,
        sizeof(PLASMA_enum),                &transB,    VALUE,
        sizeof(int),                        &m,         VALUE,
        sizeof(int),                        &n,         VALUE,
        sizeof(int),                        &k,         VALUE,
        sizeof(double),         &alpha,     VALUE,
        sizeof(double)*nb*nb,    A,                 INPUT,
        sizeof(int),                        &lda,       VALUE,
        sizeof(double)*nb*nb,    B,                 INPUT,
        sizeof(int),                        &ldb,       VALUE,
        sizeof(double),         &beta,      VALUE,
        sizeof(double)*nb*nb,    C,                 INOUT | LOCALITY | GATHERV,
        sizeof(int),                        &ldc,       VALUE,
        0);
}

/***************************************************************************//**
 *
 **/
#if defined(PLASMA_HAVE_WEAK)
#pragma weak CORE_dgemm_quark = PCORE_dgemm_quark
#define CORE_dgemm_quark PCORE_dgemm_quark
#endif
void CORE_dgemm_quark(Quark *quark)
{
    PLASMA_enum transA;
    PLASMA_enum transB;
    int m;
    int n;
    int k;
    double alpha;
    double *A;
    int lda;
    double *B;
    int ldb;
    double beta;
    double *C;
    int ldc;

    quark_unpack_args_13(quark, transA, transB, m, n, k, alpha, A, lda, B, ldb, beta, C, ldc);
    cblas_dgemm(
        CblasColMajor,
        (CBLAS_TRANSPOSE)transA, (CBLAS_TRANSPOSE)transB,
        m, n, k,
        (alpha), A, lda,
        B, ldb,
        (beta), C, ldc);
}

/***************************************************************************//**
 *
 **/
void QUARK_CORE_dgemm_f2(Quark *quark, Quark_Task_Flags *task_flags,
                         PLASMA_enum transA, int transB,
                         int m, int n, int k, int nb,
                         double alpha, const double *A, int lda,
                                                   const double *B, int ldb,
                         double beta, double *C, int ldc,
                         double *fake1, int szefake1, int flag1,
                         double *fake2, int szefake2, int flag2)
{
    DAG_CORE_GEMM;
    QUARK_Insert_Task(quark, CORE_dgemm_f2_quark, task_flags,
        sizeof(PLASMA_enum),                &transA,    VALUE,
        sizeof(PLASMA_enum),                &transB,    VALUE,
        sizeof(int),                        &m,         VALUE,
        sizeof(int),                        &n,         VALUE,
        sizeof(int),                        &k,         VALUE,
        sizeof(double),         &alpha,     VALUE,
        sizeof(double)*nb*nb,    A,                 INPUT,
        sizeof(int),                        &lda,       VALUE,
        sizeof(double)*nb*nb,    B,                 INPUT,
        sizeof(int),                        &ldb,       VALUE,
        sizeof(double),         &beta,      VALUE,
        sizeof(double)*nb*nb,    C,                 INOUT | LOCALITY,
        sizeof(int),                        &ldc,       VALUE,
        sizeof(double)*szefake1, fake1,             flag1,
        sizeof(double)*szefake2, fake2,             flag2,
        0);
}

/***************************************************************************//**
 *
 **/
#if defined(PLASMA_HAVE_WEAK)
#pragma weak CORE_dgemm_f2_quark = PCORE_dgemm_f2_quark
#define CORE_dgemm_f2_quark PCORE_dgemm_f2_quark
#endif
void CORE_dgemm_f2_quark(Quark* quark)
{
    PLASMA_enum transA;
    PLASMA_enum transB;
    int M;
    int N;
    int K;
    double alpha;
    double *A;
    int LDA;
    double *B;
    int LDB;
    double beta;
    double *C;
    int LDC;
    void *fake1, *fake2;

    quark_unpack_args_15(quark, transA, transB, M, N, K, alpha,
                         A, LDA, B, LDB, beta, C, LDC, fake1, fake2);
    cblas_dgemm(
        CblasColMajor,
        (CBLAS_TRANSPOSE)transA, (CBLAS_TRANSPOSE)transB,
        M, N, K,
        (alpha), A, LDA,
        B, LDB,
        (beta), C, LDC);
}

/***************************************************************************//**
 *
 **/
void QUARK_CORE_dgemm_p2(Quark *quark, Quark_Task_Flags *task_flags,
                         PLASMA_enum transA, int transB,
                         int m, int n, int k, int nb,
                         double alpha, const double *A, int lda,
                         const double **B, int ldb,
                         double beta, double *C, int ldc)
{
    DAG_CORE_GEMM;
    QUARK_Insert_Task(quark, CORE_dgemm_p2_quark, task_flags,
        sizeof(PLASMA_enum),                &transA,    VALUE,
        sizeof(PLASMA_enum),                &transB,    VALUE,
        sizeof(int),                        &m,         VALUE,
        sizeof(int),                        &n,         VALUE,
        sizeof(int),                        &k,         VALUE,
        sizeof(double),         &alpha,     VALUE,
        sizeof(double)*lda*nb,   A,                 INPUT,
        sizeof(int),                        &lda,       VALUE,
        sizeof(double*),         B,                 INPUT,
        sizeof(int),                        &ldb,       VALUE,
        sizeof(double),         &beta,      VALUE,
        sizeof(double)*ldc*nb,    C,                 INOUT | LOCALITY,
        sizeof(int),                        &ldc,       VALUE,
        0);
}

/***************************************************************************//**
 *
 **/
#if defined(PLASMA_HAVE_WEAK)
#pragma weak CORE_dgemm_p2_quark = PCORE_dgemm_p2_quark
#define CORE_dgemm_p2_quark PCORE_dgemm_p2_quark
#endif
void CORE_dgemm_p2_quark(Quark* quark)
{
    PLASMA_enum transA;
    PLASMA_enum transB;
    int M;
    int N;
    int K;
    double alpha;
    double *A;
    int LDA;
    double **B;
    int LDB;
    double beta;
    double *C;
    int LDC;

    quark_unpack_args_13(quark, transA, transB, M, N, K, alpha,
                         A, LDA, B, LDB, beta, C, LDC);
    cblas_dgemm(
        CblasColMajor,
        (CBLAS_TRANSPOSE)transA, (CBLAS_TRANSPOSE)transB,
        M, N, K,
        (alpha), A, LDA,
        *B, LDB,
        (beta), C, LDC);
}

/***************************************************************************//**
 *
 **/
void QUARK_CORE_dgemm_p3(Quark *quark, Quark_Task_Flags *task_flags,
                           PLASMA_enum transA, int transB,
                           int m, int n, int k, int nb,
                           double alpha, const double *A, int lda,
                           const double *B, int ldb,
                           double beta, double **C, int ldc)
{
    DAG_CORE_GEMM;
    QUARK_Insert_Task(quark, CORE_dgemm_p3_quark, task_flags,
        sizeof(PLASMA_enum),                &transA,    VALUE,
        sizeof(PLASMA_enum),                &transB,    VALUE,
        sizeof(int),                        &m,         VALUE,
        sizeof(int),                        &n,         VALUE,
        sizeof(int),                        &k,         VALUE,
        sizeof(double),         &alpha,     VALUE,
        sizeof(double)*lda*nb,   A,                 INPUT,
        sizeof(int),                        &lda,       VALUE,
        sizeof(double)*ldb*nb,   B,                 INPUT,
        sizeof(int),                        &ldb,       VALUE,
        sizeof(double),         &beta,      VALUE,
        sizeof(double*),         C,                 INOUT | LOCALITY,
        sizeof(int),                        &ldc,       VALUE,
        0);
}

/***************************************************************************//**
 *
 **/
#if defined(PLASMA_HAVE_WEAK)
#pragma weak CORE_dgemm_p3_quark = PCORE_dgemm_p3_quark
#define CORE_dgemm_p3_quark PCORE_dgemm_p3_quark
#endif
void CORE_dgemm_p3_quark(Quark* quark)
{
    PLASMA_enum transA;
    PLASMA_enum transB;
    int M;
    int N;
    int K;
    double alpha;
    double *A;
    int LDA;
    double *B;
    int LDB;
    double beta;
    double **C;
    int LDC;

    quark_unpack_args_13(quark, transA, transB, M, N, K, alpha,
                         A, LDA, B, LDB, beta, C, LDC);
    cblas_dgemm(
        CblasColMajor,
        (CBLAS_TRANSPOSE)transA, (CBLAS_TRANSPOSE)transB,
        M, N, K,
        (alpha), A, LDA,
        B, LDB,
        (beta), *C, LDC);
}

/***************************************************************************//**
 *
 **/
void QUARK_CORE_dgemm_p2f1(Quark *quark, Quark_Task_Flags *task_flags,
                           PLASMA_enum transA, int transB,
                           int m, int n, int k, int nb,
                           double alpha, const double *A, int lda,
                           const double **B, int ldb,
                           double beta, double *C, int ldc,
                           double *fake1, int szefake1, int flag1)
{
    DAG_CORE_GEMM;
    QUARK_Insert_Task(quark, CORE_dgemm_p2f1_quark, task_flags,
        sizeof(PLASMA_enum),                &transA,    VALUE,
        sizeof(PLASMA_enum),                &transB,    VALUE,
        sizeof(int),                        &m,         VALUE,
        sizeof(int),                        &n,         VALUE,
        sizeof(int),                        &k,         VALUE,
        sizeof(double),         &alpha,     VALUE,
        sizeof(double)*lda*nb,   A,                 INPUT,
        sizeof(int),                        &lda,       VALUE,
        sizeof(double*),         B,                 INPUT,
        sizeof(int),                        &ldb,       VALUE,
        sizeof(double),         &beta,      VALUE,
        sizeof(double)*ldc*nb,    C,                 INOUT | LOCALITY,
        sizeof(int),                        &ldc,       VALUE,
        sizeof(double)*szefake1, fake1,             flag1,
        0);
}

/***************************************************************************//**
 *
 **/
#if defined(PLASMA_HAVE_WEAK)
#pragma weak CORE_dgemm_p2f1_quark = PCORE_dgemm_p2f1_quark
#define CORE_dgemm_p2f1_quark PCORE_dgemm_p2f1_quark
#endif
void CORE_dgemm_p2f1_quark(Quark* quark)
{
    PLASMA_enum transA;
    PLASMA_enum transB;
    int M;
    int N;
    int K;
    double alpha;
    double *A;
    int LDA;
    double **B;
    int LDB;
    double beta;
    double *C;
    int LDC;
    void *fake1;

    quark_unpack_args_14(quark, transA, transB, M, N, K, alpha,
                         A, LDA, B, LDB, beta, C, LDC, fake1);
    cblas_dgemm(
        CblasColMajor,
        (CBLAS_TRANSPOSE)transA, (CBLAS_TRANSPOSE)transB,
        M, N, K,
        (alpha), A, LDA,
        *B, LDB,
        (beta), C, LDC);
}


#ifndef DERIVATIVE_H
#define DERIVATIVE_H

#include <memory>

#include <gsl/gsl_math.h>
#include <gsl/gsl_vector.h>
#include <gsl/gsl_interp.h>
#include <gsl/gsl_deriv.h>

#include "constants.h"

void deriv_discrete(gsl_vector *df, gsl_vector *f, double step);

#endif // DERIVATIVE_H


#include <stdio.h>
#include <gsl/gsl_vector.h>

int
main (void)
{
  int i;
  gsl_vector * v = gsl_vector_alloc (10);

  {
     FILE * f = fopen ("test.dat", "r");
     gsl_vector_fscanf (f, v);
     fclose (f);
  }

  for (i = 0; i < 10; i++)
    {
      printf ("%g\n", gsl_vector_get(v, i));
    }

  gsl_vector_free (v);
  return 0;
}


#pragma once

#include <utility>
#include <iostream>
#include <initializer_list>
#include <exception>

#include <gsl/gsl_math.h>
#include <gsl/gsl_linalg.h>

#include "utils/fcmp.h"

namespace gsl_wrapper
{

  class Vector
  {
  public:
    // Constructors and destructor
    Vector(size_t vec_size);
    Vector(gsl_vector *gsl_vec_ptr);

    Vector(const Vector &copy_from);
    Vector(Vector &&move_from);

    Vector(std::initializer_list<double> args);

    ~Vector();

    // Member functions
    auto get_gsl_vector() const -> gsl_vector *;
    auto size() const -> size_t;
    auto begin() const -> double *;
    auto end() const -> double *;

    // Operators
    auto operator=(const Vector &copy_from) -> Vector &;
    auto operator=(Vector &&move_from) -> Vector &;

    auto operator==(const Vector &comparasion_vector) -> bool;
    auto operator!=(const Vector &comparasion_vector) -> bool;

    auto operator[](const size_t index) -> double &;
    auto operator[](const size_t index) const -> const double &;

    auto operator+(const Vector &add_to) const -> Vector;
    auto operator-(const Vector &sub) const -> Vector;
    auto operator*(const double number) const -> Vector;

    // Friend declarations
    friend auto operator<<(std::ostream &stream, const Vector &to_print) -> std::ostream &;
    friend auto operator*(const double number, const Vector &vec) -> Vector;

  private:
    gsl_vector *m_vector_ptr;
    size_t m_vector_size;
  };

  inline Vector::Vector(size_t vec_size)
      : m_vector_ptr{gsl_vector_calloc(vec_size)},
        m_vector_size{vec_size}
  {
  }

  inline Vector::Vector(gsl_vector *gsl_vec_ptr)
      : m_vector_ptr{gsl_vec_ptr},
        m_vector_size{gsl_vec_ptr->size}
  {
  }

  inline Vector::Vector(const Vector &copy_from)
      : m_vector_ptr{gsl_vector_calloc(copy_from.m_vector_size)},
        m_vector_size{copy_from.m_vector_size}
  {
    gsl_vector_memcpy(m_vector_ptr, copy_from.m_vector_ptr);
  }

  inline Vector::Vector(Vector &&move_from)
      : m_vector_ptr{std::exchange(move_from.m_vector_ptr, nullptr)},
        m_vector_size{std::exchange(move_from.m_vector_size, 0)}
  {
  }

  inline Vector::Vector(std::initializer_list<double> args)
      : m_vector_ptr{gsl_vector_calloc(args.size())},
        m_vector_size{args.size()}
  {
    size_t i = 0;
    for (auto &&el : args)
    {
      gsl_vector_set(m_vector_ptr, i++, el);
    }
  }

  inline Vector::~Vector()
  {
    gsl_vector_free(m_vector_ptr);
  }

  inline auto Vector::get_gsl_vector() const -> gsl_vector *
  {
    return m_vector_ptr;
  }

  inline auto Vector::size() const -> size_t
  {
    return m_vector_size;
  }

  inline auto Vector::begin() const -> double *
  {
    return m_vector_ptr->data;
  }

  inline auto Vector::end() const -> double *
  {
    return m_vector_ptr->data + m_vector_size;
  }

  inline auto Vector::operator=(const Vector &copy_from) -> Vector &
  {
    // Prevent self copy
    if (m_vector_ptr == copy_from.m_vector_ptr)
      return *this;

    gsl_vector_free(m_vector_ptr);
    m_vector_ptr = gsl_vector_calloc(copy_from.m_vector_size);
    gsl_vector_memcpy(m_vector_ptr, copy_from.m_vector_ptr);
    m_vector_size = copy_from.m_vector_size;

    return *this;
  }

  inline auto Vector::operator=(Vector &&move_from) -> Vector &
  {
    // Prevent self move
    if (m_vector_ptr == move_from.m_vector_ptr)
      return *this;

    gsl_vector_free(m_vector_ptr);
    m_vector_ptr = std::exchange(move_from.m_vector_ptr, nullptr);
    m_vector_size = std::exchange(move_from.m_vector_size, 0);

    return *this;
  }

  inline auto Vector::operator==(const Vector &comparasion_vector) -> bool
  {
    if (m_vector_size != comparasion_vector.m_vector_size)
      return false;

    for (size_t i = 0; i < m_vector_size; i++)
    {
      bool test = ::gsl_wrapper::utils::equal((*this)[i], comparasion_vector[i]);
      if (!test)
        return false;
    }
    return true;
  }

  inline auto Vector::operator!=(const Vector &comparasion_vector) -> bool
  {
    return !(*this == comparasion_vector);
  }

  inline auto Vector::operator[](const size_t index) -> double &
  {
    if (index >= m_vector_size)
      throw std::range_error{"Accesing vector elements out of bounds"};
    return *gsl_vector_ptr(m_vector_ptr, index);
  }

  inline auto Vector::operator[](const size_t index) const -> const double &
  {
    return *gsl_vector_const_ptr(m_vector_ptr, index);
  }

  inline auto operator<<(std::ostream &stream, const Vector &to_print) -> std::ostream &
  {
    for (size_t i = 0; i < to_print.m_vector_size - 1; i++)
    {
      stream << to_print[i] << " ";
    }
    stream << to_print[to_print.m_vector_size - 1];

    return stream;
  }

  inline auto Vector::operator+(const Vector &add_to) const -> Vector
  {
    if (m_vector_size != add_to.m_vector_size)
      throw std::range_error{"Adding vector of diffrent sizes"};

    Vector result(m_vector_size);

    for (size_t i = 0; i < m_vector_size; i++)
    {
      result[i] = (*this)[i] + add_to[i];
    }

    return result;
  }

  inline auto Vector::operator-(const Vector &sub) const -> Vector
  {
    if (m_vector_size != sub.m_vector_size)
      throw std::range_error{"Subtracting vector of diffrent sizes"};

    Vector result(m_vector_size);

    for (size_t i = 0; i < m_vector_size; i++)
    {
      result[i] = (*this)[i] - sub[i];
    }

    return result;
  }

  inline auto Vector::operator*(const double number) const -> Vector
  {
    Vector result = *this;
    for (auto &&el : result)
    {
      el *= number;
    }

    return result;
  }

  inline auto operator*(const double number, const Vector &vec) -> Vector
  {
    Vector result = vec;
    for (auto &&el : result)
    {
      el *= number;
    }

    return result;
  }

}


// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

// clang-format off

#pragma once

#pragma warning(push)

// C
#include <climits>
#include <cwchar>
#include <cwctype>

// STL

// Block minwindef.h min/max macros to prevent <algorithm> conflict
#define NOMINMAX

#include <algorithm>
#include <atomic>
#include <deque>
#include <list>
#include <memory>
#include <map>
#include <mutex>
#include <shared_mutex>
#include <new>
#include <optional>
#include <queue>
#include <stdexcept>
#include <string>
#include <string_view>
#include <thread>
#include <tuple>
#include <utility>
#include <vector>
#include <unordered_map>
#include <iterator>
#include <math.h>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <filesystem>
#include <functional>
#include <set>
#include <unordered_set>

// WIL
#include <wil/Common.h>
#include <wil/Result.h>
#include <wil/resource.h>
#include <wil/wistd_memory.h>
#include <wil/stl.h>
#include <wil/com.h>
#include <wil/filesystem.h>
#include <wil/win32_helpers.h>

// GSL
// Block GSL Multi Span include because it both has C++17 deprecated iterators
// and uses the C-namespaced "max" which conflicts with Windows definitions.
#ifndef BLOCK_GSL
#define GSL_MULTI_SPAN_H
#include <gsl/gsl>
#endif

// CppCoreCheck
#include <CppCoreCheck/Warnings.h>

// IntSafe
#define ENABLE_INTSAFE_SIGNED_FUNCTIONS
#include <intsafe.h>

// SAL
#include <sal.h>

// WRL
#include <wrl.h>

// TIL - Terminal Implementation Library
#include "til.h"

#pragma warning(pop)

// clang-format on


/*
 * Copyright 2020 Makani Technologies LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SIM_MATH_ODE_SOLVER_H_
#define SIM_MATH_ODE_SOLVER_H_

#include <stdint.h>

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

#include <vector>

namespace sim {

// Enumeration for return codes.
enum class OdeSolverStatus { kSuccess, kError, kOutOfPhysics };

// Interface representing a system of ordinary differential equations.
class OdeSystem {
 public:
  virtual ~OdeSystem() {}

  // Get the number of states for the ODE.
  virtual int32_t num_states() const = 0;

  // Calculate the state derivative for a given time and state.
  virtual void CalcDerivatives(double t, const std::vector<double> &x,
                               std::vector<double> *dx) const = 0;
};

// Interface for ODE solvers.
class OdeSolver {
 public:
  virtual ~OdeSolver() {}

  // Integrate the ODE with initial condition x0 at time t0 until time tf.
  //
  // Args:
  //   t0: Initial time.
  //   tf: Final time (>= t0).
  //   x0: Initial state.
  //   t_int: Null pointer or output time at which the integrator terminated.
  //   x: Terminal state.  It should be safe to reuse x0 as x.
  //
  // Returns:
  //   kSuccess on success (indicating *t_int = tf) and kError otherwise.
  virtual OdeSolverStatus Integrate(double t0, double tf,
                                    const std::vector<double> &x0,
                                    double *t_int, std::vector<double> *x) = 0;
};

}  // namespace sim

#endif  // SIM_MATH_ODE_SOLVER_H_


#ifndef QDM_THETA_H
#define QDM_THETA_H 1

#include <gsl/gsl_matrix.h>
#include <gsl/gsl_vector.h>

int
qdm_theta_optimize(
    gsl_vector *result,
    gsl_vector *emperical_quantiles,
    gsl_matrix *ix
);

void
qdm_theta_matrix_constrain(
    gsl_matrix *theta,
    double min
);

#endif /* QDM_THETA_H */


/* spcompress.c
 *
 * Copyright (C) 2012-2014, 2016 Patrick Alken
 *
 * 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 3 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 <math.h>
#include <gsl/gsl_math.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_spmatrix.h>

/*
gsl_spmatrix_ccs()
  Create a sparse matrix in compressed column format

Inputs: T - sparse matrix in triplet format

Return: pointer to new matrix (should be freed when finished with it)
*/

gsl_spmatrix *
gsl_spmatrix_ccs(const gsl_spmatrix *T)
{
  if (!GSL_SPMATRIX_ISTRIPLET(T))
    {
      GSL_ERROR_NULL("matrix must be in triplet format", GSL_EINVAL);
    }
  else
    {
      const size_t *Tj; /* column indices of triplet matrix */
      size_t *Cp;       /* column pointers of compressed column matrix */
      size_t *w;        /* copy of column pointers */
      gsl_spmatrix *m;
      size_t n;

      m = gsl_spmatrix_alloc_nzmax(T->size1, T->size2, T->nz,
                                   GSL_SPMATRIX_CCS);
      if (!m)
        return NULL;

      Tj = T->p;
      Cp = m->p;

      /* initialize column pointers to 0 */
      for (n = 0; n < m->size2 + 1; ++n)
        Cp[n] = 0;

      /*
       * compute the number of elements in each column:
       * Cp[j] = # non-zero elements in column j
       */
      for (n = 0; n < T->nz; ++n)
        Cp[Tj[n]]++;

      /* compute column pointers: p[j] = p[j-1] + nnz[j-1] */
      gsl_spmatrix_cumsum(m->size2, Cp);

      /* make a copy of the column pointers */
      w = (size_t *) m->work;
      for (n = 0; n < m->size2; ++n)
        w[n] = Cp[n];

      /* transfer data from triplet format to CCS */
      for (n = 0; n < T->nz; ++n)
        {
          size_t k = w[Tj[n]]++;
          m->i[k] = T->i[n];
          m->data[k] = T->data[n];
        }

      m->nz = T->nz;

      return m;
    }
}

gsl_spmatrix *
gsl_spmatrix_compcol(const gsl_spmatrix *T)
{
  return gsl_spmatrix_ccs(T);
}

/*
gsl_spmatrix_crs()
  Create a sparse matrix in compressed row format

Inputs: T - sparse matrix in triplet format

Return: pointer to new matrix (should be freed when finished with it)
*/

gsl_spmatrix *
gsl_spmatrix_crs(const gsl_spmatrix *T)
{
  if (!GSL_SPMATRIX_ISTRIPLET(T))
    {
      GSL_ERROR_NULL("matrix must be in triplet format", GSL_EINVAL);
    }
  else
    {
      const size_t *Ti; /* row indices of triplet matrix */
      size_t *Cp;       /* row pointers of compressed row matrix */
      size_t *w;        /* copy of column pointers */
      gsl_spmatrix *m;
      size_t n;

      m = gsl_spmatrix_alloc_nzmax(T->size1, T->size2, T->nz,
                                   GSL_SPMATRIX_CRS);
      if (!m)
        return NULL;

      Ti = T->i;
      Cp = m->p;

      /* initialize row pointers to 0 */
      for (n = 0; n < m->size1 + 1; ++n)
        Cp[n] = 0;

      /*
       * compute the number of elements in each row:
       * Cp[i] = # non-zero elements in row i
       */
      for (n = 0; n < T->nz; ++n)
        Cp[Ti[n]]++;

      /* compute row pointers: p[i] = p[i-1] + nnz[i-1] */
      gsl_spmatrix_cumsum(m->size1, Cp);

      /* make a copy of the row pointers */
      w = (size_t *) m->work;
      for (n = 0; n < m->size1; ++n)
        w[n] = Cp[n];

      /* transfer data from triplet format to CRS */
      for (n = 0; n < T->nz; ++n)
        {
          size_t k = w[Ti[n]]++;
          m->i[k] = T->p[n];
          m->data[k] = T->data[n];
        }

      m->nz = T->nz;

      return m;
    }
}

/*
gsl_spmatrix_cumsum()

Compute the cumulative sum:

p[j] = Sum_{k=0...j-1} c[k]

0 <= j < n + 1

Alternatively,
p[0] = 0
p[j] = p[j - 1] + c[j - 1]

Inputs: n - length of input array
        c - (input/output) array of size n + 1
            on input, contains the n values c[k]
            on output, contains the n + 1 values p[j]

Return: success or error
*/

void
gsl_spmatrix_cumsum(const size_t n, size_t *c)
{
  size_t sum = 0;
  size_t k;

  for (k = 0; k < n; ++k)
    {
      size_t ck = c[k];
      c[k] = sum;
      sum += ck;
    }

  c[n] = sum;
} /* gsl_spmatrix_cumsum() */


/*
  10 Sept 08: Process_Error_Code is now static and thus private to
              this library.
*/

#include <cblas.h>
#include "lbl.h"
#include "ma57.h"

#ifdef __cplusplus
extern "C" {   /* To prevent C++ compilers from mangling symbols */
#endif

  /* ================================================================= */

#ifdef  __FUNCT__
#undef  __FUNCT__
#endif
#define __FUNCT__ "Process_Error_Code"
static int Process_Error_Code( Ma57_Data *ma57, int nerror ) {

    LOGMSG( " [%3d]", nerror );
    /* Take appropriate action according to error code */
    /* Inflation factors are from the MA57 spec sheet  */
    switch( nerror ) {

    case 0:
      break;

      /* Warnings */
    case 1:
      LOGMSG( " Found and ignored %d indices out of range.\n", ma57->info[2] );
      break;

    case 2:
      LOGMSG( " Found and summed %d duplicate entries.\n", ma57->info[3] );
      break;

    case 3:
      LOGMSG( " Found duplicate and out-of-range indices.\n" );
      break;

    case 4:
      LOGMSG( " Matrix has rank %d, deficient.\n", ma57->info[24] );
      break;

    case 5:
      LOGMSG( " Found %d pivot sign changes in definite matrix.\n",
              ma57->info[25] );
      break;

    case 8:
      LOGMSG( " Infinity norm of solution found to be zero.\n" );
      break;

    case 10:
      LOGMSG( " Insufficient real space. Increased LFACT to %d.\n",
              ma57->lfact );
      break;

    case 11:
      LOGMSG( " Insufficient integer space. Increased LIFACT to %d.\n",
              ma57->lifact );
      break;

      /* Errors */
    case -1:
      LOGMSG( " Value of n is out of range: %d.\n", ma57->info[1] );
      break;

    case -2:
      LOGMSG( " Value of nz is out of range: %d.\n", ma57->info[1] );
      break;

    case -3:
      LOGMSG( " Adjusted size of array FACT to %d.\n", ma57->lfact );
      break;

    case -4:
      LOGMSG( " Adjusting size of array IFACT to %d.\n", ma57->lifact );
      break;

    case -5:
      LOGMSG( " Small pivot encountered at pivot step %d. Threshold = %lf.\n",
              ma57->info[1], ma57->cntl[1] );

    case -6:
      LOGMSG( " Change in pivot sign detected at pivot step %d.\n",
              ma57->info[1] );
      break;

    case -7:
      LOGMSG( " Erroneous sizing of array FACT or IFACT.\n" );
      break;

    case -8:
      LOGMSG( " Iterative refinement failed to converge.\n" );
      break;

    case -9:
      LOGMSG( " Error in user-supplied permutation array in component %d.\n",
              ma57->info[1] );
      break;

    case -10:
      LOGMSG( " Unknown pivoting strategy: %d\n.", ma57->info[1] );
      break;

    case -11:
      LOGMSG( " Size of RHS must be %d. Received %d.\n",
              ma57->n, ma57->info[1] );
      break;

    case -12:
      LOGMSG( " Invalid value of JOB (%d).\n", ma57->info[1] );
      break;

    case -13:
      LOGMSG( " Invalid number of iterative refinement steps (%d).\n",
              ma57->info[1] );
      break;

    case -14:
      LOGMSG( " Failed to estimate condition number.\n" );
      break;

    case -15:
      LOGMSG( " LKEEP has value %d, less than minimum allowed.\n",
              ma57->info[1] );
      break;

    case -16:
      LOGMSG( " Invalid number of RHS (%d).\n", ma57->info[1] );
      break;

    case -17:
      LOGMSG( " Increasing size of LWORK to %d.\n", ma57->lwork );
      break;

    case -18:
      LOGMSG( " MeTiS library not available or not found.\n" );
      break;

    default:
      LOGMSG( " Unrecognized flag from Factorize()." );
      nerror = -30;
    }
    return nerror;
  }

  /* ================================================================= */

#ifdef  __FUNCT__
#undef  __FUNCT__
#endif
#define __FUNCT__ "MA57_Initialize"
  Ma57_Data *Ma57_Initialize( int nz, int n, FILE *logfile ) {

    /* Call initialize subroutine MA57ID and set defaults */
    Ma57_Data *ma57 = (Ma57_Data *)LBL_Calloc( 1, sizeof(Ma57_Data) );
    ma57->logfile   = logfile;

    LOGMSG( " MA57 :: Initializing..." );

    ma57->n         = n;
    ma57->nz        = nz;
    ma57->fetched   = 0;
    ma57->irn       = (int *)LBL_Calloc( nz, sizeof(int) );
    ma57->jcn       = (int *)LBL_Calloc( nz, sizeof(int) );
    ma57->lkeep     = 5*n + nz + imax(n,nz) + 42 + n; // Add n to suggested val.
    ma57->keep      = (int *)LBL_Calloc( ma57->lkeep, sizeof(int) );
    ma57->iwork     = (int *)LBL_Calloc( 5*n, sizeof(int) );
    ma57->work      = NULL; // Will be initialized in Ma57_Solve()

    LOGMSG( " Calling ma57id..." );
    MA57ID( ma57->cntl, ma57->icntl ); // Initialize all parameters

    // Ensure some default parameters are appropriate
    ma57->icntl[0] = -1;  // Stream for error messages.
    ma57->icntl[1] = -1;  // Stream for warning messages.
    ma57->icntl[2] = -1;  // Stream for monitoring printing.
    ma57->icntl[3] = -1;  // Stream for printing of statistics.
    ma57->icntl[4] =  0;  // Verbosity: 0=none, 1=errors, 2=1+warnings,
                          //            3=2+monitor, 4=3+input,output
    ma57->icntl[5] =  5;  // Pivot selection strategy:
                          //  0: AMD using MC47
                          //  1: User-supplied pivot sequence
                          //  2: AMD with dense row strategy
                          //  3: MD as in MA27
                          //  4: MeTiS
                          //  5: Automatic (4 with fallback on 2)
    ma57->icntl[6] =  1;  // Numerical pivoting strategy
                          //  1: Do pivoting using value in cntl(1)
                          //  2: No pivoting; exit on sign change or zero
                          //  3: No pivoting; exit if pivot modulus < cntl(2)
                          //  4: No pivoting; alter pivots to have same sign
    ma57->icntl[7] =  1;  // Memory will be re-allocated if necessary
    ma57->icntl[15] = 0;  // No need to scale system before factorizing
    ma57->fetched = 0;

    LOGMSG( " done\n");
    return ma57;
  }

  /* ================================================================= */

#ifdef  __FUNCT__
#undef  __FUNCT__
#endif
#define __FUNCT__ "Ma57_Analyze"
  int Ma57_Analyze( Ma57_Data *ma57 ) {

    int finished = 0, error;
    LOGMSG( " MA57 :: Analyzing..." );

    /* Unpack data structure and call MA57AD */
    while( !finished ) {
      LOGMSG( "\n         Calling ma57ad... " );

      MA57AD( &(ma57->n), &(ma57->nz), ma57->irn, ma57->jcn,
              &(ma57->lkeep), ma57->keep, ma57->iwork, ma57->icntl,
              ma57->info, ma57->rinfo );

      error = ma57->info[0];

      if( !error )
        finished = 1;
      else {
        error = Process_Error_Code( ma57, error );
        if( error != -3 && error != -4 && error != -8 && error != -14 )
          return error;
      }
    }

    // Allocate data for Factorize()
    ma57->lfact = ceil( LFACT_GROW * ma57->info[8] );
    ma57->fact = (double *)LBL_Calloc( ma57->lfact, sizeof(double) );
    ma57->lifact = ceil( LIFACT_GROW * ma57->info[9] );
    ma57->ifact = (int *)LBL_Calloc( ma57->lifact, sizeof(int) );
    LBL_Free( ma57->iwork );
    ma57->iwork = (int *)LBL_Calloc( ma57->n, sizeof(int) );
    ma57->work = NULL;

    LOGMSG( " done\n");
    return 0;
  }

  /* ================================================================= */

#ifdef  __FUNCT__
#undef  __FUNCT__
#endif
#define __FUNCT__ "Ma57_Factorize"
  int Ma57_Factorize( Ma57_Data *ma57, double A[] ) {

    // To ensure consistency with the MA27 interface, the user must pass
    // the array A, *including* its zero-th element. Internally, A+1 is
    // passed to MA57.

    double *newFact;
    int    *newIfact;
    int     newSize, one = 1, zero = 0;
    int     finished = 0, error;
    LOGMSG( " MA57 :: Factorizing...\n" );

    /* Unpack data structure and call MA57BD */
    while( !finished ) {
      LOGMSG( "         Calling ma57bd... " );

      MA57BD( &(ma57->n), &(ma57->nz), A, ma57->fact, &(ma57->lfact),
              ma57->ifact, &(ma57->lifact), &(ma57->lkeep), ma57->keep,
              ma57->iwork, ma57->icntl, ma57->cntl, ma57->info, ma57->rinfo );

      error = ma57->info[0];

      if( !error ) {

        finished = 1;

      } else {

        error = Process_Error_Code( ma57, error );

        if( error == -3 || error == 10 ) {

          /* Resize real workspace */
          newSize = (error == 10) ? ma57->lfact : ma57->info[16];
          newSize = ceil( LFACT_GROW * newSize );
          LOGMSG("         Resizing real workspace for factors to %d", newSize);
          newFact = (double *)LBL_Calloc( newSize, sizeof(double) );
          MA57ED( &(ma57->n), &zero, ma57->keep, ma57->fact, &(ma57->lfact),
                  newFact, &newSize, ma57->ifact, &(ma57->lifact), NULL,
                  &zero, ma57->info );
          LBL_Free( ma57->fact );
          ma57->fact = newFact; newFact = NULL;
          ma57->lfact = newSize;

        } else if( error == -4 || error == 11 ) {

          /* Resize integer workspace */
          newSize = (error == 11) ? ma57->lifact : ma57->info[17];
          newSize = ceil( LIFACT_GROW * newSize );
          LOGMSG("         Resizing int workspace for factors to %d", newSize);
          newIfact = (int *)LBL_Calloc( newSize, sizeof(int) );
          MA57ED( &(ma57->n), &one, ma57->keep, ma57->fact, &(ma57->lfact),
                  NULL, &zero, ma57->ifact, &(ma57->lifact), newIfact,
                  &newSize, ma57->info );
          LBL_Free( ma57->ifact );
          ma57->ifact = newIfact; newIfact = NULL;
          ma57->lifact = newSize;

        } else {
          finished = 1;
          if( error < 0 ) return error;
        }
      }
    }

    LOGMSG("\n");
    LOGMSG("         %-23s: %6i   %-28s: %6i\n",
           "No. of 2x2 pivots"            , ma57->info[21],
           "Pivot step for modification"  , ma57->info[26]);
    LOGMSG("         %-28s: %6i   %-28s: %6i\n",
           "No. of negative e-vals"       , ma57->info[23],
           "No. of entries in factor"     , ma57->info[13]);
    LOGMSG("         %-28s: %6i   %-28s: %6i\n",
           "Rank of factorization"        , ma57->info[24],
           "No. of pivot sign changes"    , ma57->info[25]);
    LOGMSG("         done\n");
    return 0;
  }

  /* ================================================================= */

#ifdef  __FUNCT__
#undef  __FUNCT__
#endif
#define __FUNCT__ "Ma57_Solve"
  int Ma57_Solve( Ma57_Data *ma57, double x[] ) {

    int one = 1, finished = 0, error;

    LOGMSG( " MA57 :: Solving..." );

    ma57->job = 1;
    ma57->lrhs = ma57->n;
    ma57->nrhs = 1;
    ma57->lwork = ma57->n * ma57->nrhs;
    if( !ma57->work ) {
      LOGMSG("\n         Sizing work array to size %d ", ma57->lwork);
      ma57->work = (double *)LBL_Calloc( ma57->lwork, sizeof(double) );
    }

    while( !finished ) {
      LOGMSG( "\n         Calling ma57cd... " );

      /* Unpack data structure and call MA57CD */
      MA57CD( &(ma57->job), &(ma57->n), ma57->fact, &(ma57->lfact),
              ma57->ifact, &(ma57->lifact), &ma57->nrhs, x, &(ma57->lrhs),
              ma57->work, &(ma57->lwork), ma57->iwork, ma57->icntl,
              ma57->info );

      error = ma57->info[0];
      if( error == -17 ) {
        LBL_Free( ma57->work );
        ma57->lwork = ceil( 1.2 * ma57->lwork );
        LOGMSG("\n         Resizing work array to size %d ", ma57->lwork);
        ma57->work = (double *)LBL_Calloc( ma57->lwork, sizeof(double) );
      } else
        finished = 1;
      if( error ) error = Process_Error_Code( ma57, error );
    }

    LOGMSG( " done\n" );
    return error;
  }

  /* ================================================================= */

#ifdef  __FUNCT__
#undef  __FUNCT__
#endif
#define __FUNCT__ "Ma57_Refine"
  int Ma57_Refine( Ma57_Data *ma57, double x[], double rhs[],
                   double A[], int maxitref, int job ) {

    int error;

    LOGMSG( " MA57 :: Performing iterative refinement..." );

    ma57->job = job;
    /* For values of 'job' that demand the presence of the residual,
     * it should be placed by the user in ma57->residual prior to calling
     * this function.
     */

    /* Allocate work space */
    ma57->icntl[8] = imax( 1, maxitref );  // Number of refinement iterations
    ma57->icntl[9] = 1; // Return estimates of condition number
    LBL_Free( ma57->iwork );
    ma57->iwork = (int *)LBL_Calloc( ma57->n, sizeof(int) );

    LBL_Free( ma57->work );
    ma57->lwork = ma57->n;
    if( ma57->icntl[8] > 1 ) {
      ma57->lwork += 2 * ma57->n;
      if( ma57->icntl[9] > 0 )
        ma57->lwork += 2 * ma57->n;
    }
    ma57->work = (double *)LBL_Calloc( ma57->lwork, sizeof(double) );
    ma57->residual = (double *)LBL_Calloc( ma57->n, sizeof(double) );

    /* Perform iterative refinement */
    MA57DD( &(ma57->job), &(ma57->n), &(ma57->nz), A, ma57->irn,
            ma57->jcn, ma57->fact, &(ma57->lfact), ma57->ifact,
            &(ma57->lifact), rhs, x, ma57->residual, ma57->work,
            ma57->iwork, ma57->icntl, ma57->cntl, ma57->info,
            ma57->rinfo );

    error = ma57->info[0];
    if( error ) error = Process_Error_Code(ma57, ma57->info[0]);
    LOGMSG( " done\n" );
    return error;
  }

  /* ================================================================= */

#ifdef  __FUNCT__
#undef  __FUNCT__
#endif
#define __FUNCT__ "Ma57_Finalize"
  void Ma57_Finalize( Ma57_Data *ma57 ) {

    /* Free allocated memory */
    LOGMSG( " MA57 :: Deallocating data arrays..." );
    LBL_Free( ma57->irn );
    LBL_Free( ma57->jcn );
    LBL_Free( ma57->keep );
    LBL_Free( ma57->iwork );
    LBL_Free( ma57->fact );
    LBL_Free( ma57->ifact );
    LBL_Free( ma57->work );
    if( ma57->residual ) LBL_Free(ma57->residual);
    LOGMSG( " done.\n" );
    free(ma57);
    return;
  }

  /* ================================================================= */
    /* Currently, this routine doesn't do error checking on the
       allowable parameter values. */

#ifdef  __FUNCT__
#undef  __FUNCT__
#endif
#define __FUNCT__ "Ma57_set_int_parm"
  void Ma57_set_int_parm( Ma57_Data *ma57, int parm, int val ) {

      switch (parm) {
      case MA57_I_PIV_SELECTION:
          ma57->icntl[MA57_I_PIV_SELECTION] = val;
          LOGMSG(" Set %-20s = %10d\n","I_PIV_SELECTION",val);
          break;
      case MA57_I_PIV_NUMERICAL:
          ma57->icntl[MA57_I_PIV_NUMERICAL] = val;
          LOGMSG(" Set %-20s = %10d\n","I_PIV_NUMERICAL",val);
          break;
      case MA57_I_SCALING:
          ma57->icntl[MA57_I_SCALING] = val;
          LOGMSG(" Set %-20s = %10d\n","I_SCALING",val);
          break;
      }
      return;
  }

  /* ================================================================= */
    /* Currently, this routine doesn't do error checking on the
       allowable parameter values. */

#ifdef  __FUNCT__
#undef  __FUNCT__
#endif
#define __FUNCT__ "Ma57_set_real_parm"
  void Ma57_set_real_parm( Ma57_Data *ma57, int parm, double val ) {

      switch (parm) {
      case MA57_D_PIV_THRESH:
          ma57->cntl[MA57_D_PIV_THRESH] = val;
          LOGMSG(" Set %-20s = %10.2e\n","D_PIV_THRESH",val);
          break;
      case MA57_D_PIV_NONZERO:
          ma57->cntl[MA57_D_PIV_NONZERO] = val;
          LOGMSG(" Set %-20s = %10.2e\n","D_PIV_NONZERO",val);
          break;
      }
      return;
  }

  /* ================================================================= */

#ifdef  __FUNCT__
#undef  __FUNCT__
#endif
#define __FUNCT__ "Ma57_get_int_parm"
  int Ma57_get_int_parm( Ma57_Data *ma57, int parm ) {

      switch (parm) {
      case MA57_I_PIV_SELECTION:
          return ma57->icntl[MA57_I_PIV_SELECTION];
      case MA57_I_PIV_NUMERICAL:
          return ma57->icntl[MA57_I_PIV_NUMERICAL];
      case MA57_I_SCALING:
          return ma57->icntl[MA57_I_SCALING];
      }
      return 0;
  }

  /* ================================================================= */

#ifdef  __FUNCT__
#undef  __FUNCT__
#endif
#define __FUNCT__ "Ma57_get_real_parm"
  double Ma57_get_real_parm( Ma57_Data *ma57, int parm ) {

      switch (parm) {
      case MA57_D_PIV_THRESH:
          return ma57->cntl[MA57_D_PIV_THRESH];
      case MA57_D_PIV_NONZERO:
          return ma57->cntl[MA57_D_PIV_NONZERO];
      }
      return 0.0;
  }

  /* ================================================================= */

#ifdef __cplusplus
}              /* Closing brace for  extern "C"  block */
#endif