text:
/*
** ECM - eigenvector centrality mapping using full matrix
**
** G.Lohmann, MPI-KYB, Nov 2018
*/

#include <viaio/Vlib.h>
#include <viaio/VImage.h>
#include <viaio/mu.h>
#include <viaio/option.h>

#include <gsl/gsl_matrix.h>
#include <gsl/gsl_vector.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_cblas.h>
#include <gsl/gsl_blas.h>

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

#ifdef _OPENMP
#include <omp.h>
#endif /*_OPENMP*/

#define SQR(x) ((x) * (x))

/* check if matrix is irreducible.
** If it is not, then Perron-Frobenius theorem does not apply
*/
void CheckReducibility(float *A,size_t nvox)
{
  size_t i,j,k,n;
  float umin = 99999;

  n=0;
  for (i=0; i<nvox; i++) {
    for (j=0; j<i; j++) {
      k=j+i*(i+1)/2;
      if (A[k] > 0) n++;
      if (A[k] > 0 && A[k] < umin) umin = A[k];
    }
    for (j=i+1; j<nvox; j++) {
      k=i+j*(j+1)/2;
      if (A[k] > 0) n++;
    }
  }

  if (n < nvox) {
    VWarning(" matrix is not irreducible, correction term is applied.");
    for (i=0; i<nvox; i++) {
      for (j=0; j<i; j++) {
	k=j+i*(i+1)/2;
	if (A[k] < umin) A[k] = umin*0.5;
      }
    }
  }
}

/* re-implementation of cblas_sspmv,  cblas_sspmv causes problems */
void my_sspmv(float *A,float *x,float *y,size_t n)
{
  size_t i,j,k,kk;
  float tmp1=0,tmp2=0;

  kk = k = 0;
  for (j=0; j<n; j++) {
    y[j] = 0;
    tmp1 = x[j];
    tmp2 = 0;
    k = kk;
    for (i=0; i<j; i++) {
      y[i] += tmp1 * A[k];
      tmp2 += A[k] * x[i];
      k++;
    }
    y[j] += tmp1*A[kk+j] + tmp2;
    kk += (j+1);
  }
}

void MatrixPowerIteration(float *A,float *ev,size_t nvox,int maxiter)
{
  int i,iter;
  float sum,d,nx;

  fprintf(stderr," power iteration...\n");
  float *y = (float *) VCalloc(nvox,sizeof(float));
  nx = (double)nvox;
  for (i=0; i<nvox; i++) ev[i] = y[i] = 1.0/nx;

  for (iter=0; iter < maxiter; iter++) {

    /* y = Ax,  A symmetric and lower-triangular */
    /* cblas_sspmv(CblasRowMajor,CblasLower,(int)n,1.0f,A,ev,1,1.0f,y,1); */
    my_sspmv(A,ev,y,nvox);

    /* normalize */
    sum = 0;
    for (i=0; i<nvox; i++) sum += y[i]*y[i];
    sum = sqrt(sum);

    /* check convergence */
    d = 0;
    for (i=0; i<nvox; i++) {
      y[i] /= sum;
      d += SQR(ev[i] - y[i]);
      ev[i] = y[i];
    }
    fprintf(stderr," %5d   %f\n",(int)iter,d);

    if (iter > 2 && d < 1.0e-6) break;
  }
  VFree(y);
}

float CorrMetric(float z,int type)
{
  switch (type) {
  case 1:  /* add */
    z += 1.0;
    break;
  case 2:  /* pos  */
    if (z < 0) z = 0;
    break;
  case 3:  /* abs */
    z = fabs(z);
    break;
  case 4:  /* neg */
    if (z < 0) z = -z;
    else z = 0;
    break;
  default:
    VError("illegal type");
  }
  return z;
}

double ECMcorrelation(const float *arr1,const float *arr2,size_t nt,int type)
{
  size_t i;
  double sum=0,z=0,kx=(double)nt;

  if ((type > 0 && type < 5) || (type==6)) {
    sum=0;
    for (i=0; i<nt; i++) {
      const double u = (double)arr1[i];
      const double v = (double)arr2[i];
      sum += u*v;
    }
    z = sum/kx;
  }

  switch (type) {

  case 0:  /* RLC positive */
    sum=0;
    for (i=0; i<nt; i++) {
      const double u = (double)arr1[i];
      const double v = (double)arr2[i];
      sum += u*v + fabs(u*v);
    }
    z = sum/(2.0*kx);
    break;

  case 1:  /* add */
     z += 1.0;
     break;

  case 2:  /* pos  */
    if (z < 0) z = 0;
    break;

  case 3:  /* abs */
    z = fabs(z);
    break;

  case 4:  /* neg */
    if (z < 0) z = -z;
    else z = 0;
    break;

  case 5:   /* Gaussian of Euclidean distance */
    sum=0;
    for (i=0; i<nt; i++) {
      const double u = (double)arr1[i];
      const double v = (double)arr2[i];
      const double d = u-v;
      sum += d*d;
    }
    z = sum/kx;
    z = exp(-0.5*z*z);
    break;

  case 7:  /* RLC negative */
    sum=0;
    for (i=0; i<nt; i++) {
      const double u = (double)arr1[i];
      const double v = (double)arr2[i];
      sum += (fabs(u*v) - u*v);
    }
    z = sum/(2.0*kx);
    break;

  default:
    ;
  }
  return z;
}

void VMatrixECM(gsl_matrix_float *X,float *ev,int type,int maxiter,VImage map)
{
  size_t i,j;
  size_t nvox = X->size1;
  size_t nt = X->size2;

  /* compute similarity matrix */
  size_t m = (nvox*(nvox+1))/2;
  float *A = (float *) calloc(m,sizeof(float));
  if (!A) VError(" err allocating correlation matrix (too big)");
  memset(A,0,m*sizeof(float));
  size_t progress=0;

#pragma omp parallel for shared(progress) private(j) schedule(guided) firstprivate(X,A)
  for (i=0; i<nvox; i++) {
    if (i%1000 == 0) fprintf(stderr," %d000  of  %lu\r",(int)(++progress),nvox);

    const float *arr1 = gsl_matrix_float_const_ptr(X,i,0);
    for (j=0; j<=i; j++) {
      if (i == j) continue;
      const float *arr2 = gsl_matrix_float_const_ptr(X,j,0);

      const double v = ECMcorrelation(arr1,arr2,nt,type);
      const size_t k=j+i*(i+1)/2;
      A[k] = v;
    }
  }
  fprintf(stderr,"\n");

  /* CheckReducibility(A,nvox); */
  /* DMN(map,A,nvox); */

  /* power iteration */
  MatrixPowerIteration(A,ev,nvox,maxiter);
  VFree(A);
}

max_stars_repo_name: zrajna/lipsia

max_issues_repo_name: zrajna/lipsia

max_forks_repo_name: zrajna/lipsia


text:
#pragma once

#include <vector>

#include <gsl/gsl>
#include <atlcomcli.h>

using gsl::span;

namespace gfx {

	/*
		Defines the file formats supported by the imaging functions.
	*/
	enum class ImageFileFormat {
		BMP,
		JPEG,
		TGA,
		FNTART,
		IMG,
		Unknown
	};

	struct ImageFileInfo {
		ImageFileFormat format = ImageFileFormat::Unknown;
		int width = 0;
		int height = 0;
		bool hasAlpha = false;
	};

	/*
		Tries to detect the image format of the given data by
		inspecting the header only.
	*/
	ImageFileInfo DetectImageFormat(span<uint8_t> data);

	bool DetectTga(span<uint8_t> data, ImageFileInfo &info);

	std::unique_ptr<uint8_t[]> DecodeTga(span<uint8_t> data);

	/*
		Specifies the pixel format of the uncompressed data
		when encoding or decoding a JPEG image.
	*/
	enum class JpegPixelFormat {
		RGB,
		BGR,
		RGBX,
		BGRX,
		XBGR,
		XRGB
	};

	/*
		Encodes a JPEG image in memory and returns the compressed data.
		pitch is the size in pixels of a line of the uncompressed data.
		quality is an integer between 1 and 100.
	*/
	std::vector<uint8_t> EncodeJpeg(const uint8_t* imageData,
	                                JpegPixelFormat imageDataFormat,
	                                int width,
	                                int height,
	                                int quality,
	                                int pitch);

	struct DecodedImage {
		std::unique_ptr<uint8_t[]> data;
		ImageFileInfo info;
	};

	DecodedImage DecodeFontArt(const span<uint8_t> data);

	DecodedImage DecodeImage(const span<uint8_t> data);

	DecodedImage DecodeCombinedImage(const std::string &filename, span<uint8_t> data);

	HCURSOR LoadImageToCursor(const span<uint8_t> data, uint32_t hotspotX, uint32_t hotspotY);

}

ext: h

max_stars_repo_name: edoipi/TemplePlus

max_issues_repo_name: edoipi/TemplePlus

max_forks_repo_name: edoipi/TemplePlus


text:
//
// C++ Interface: %{MODULE}
//
// Description:
//
//
// Author: %{AUTHOR} <%{EMAIL}>, (C) %{YEAR}
//
// Copyright: See COPYING file that comes with this distribution
//
//

#ifndef STK_BasicVector_h
#define STK_BasicVector_h

#include "common.h"
#include "Error.h"

#include <cstddef>
#include <cstdlib>
#include <stdexcept>
#include <iostream>

#ifdef HAVE_ATLAS
extern "C"{
  #ifdef USE_MKL
    #include "mkl.h"
  #else
    #include <cblas.h>
    #include <atlas/clapack.h>
  #endif
}
#endif

namespace STK
{
  template<typename _ElemT> class BasicVector;
  template<typename _ElemT> class Matrix;

  // we need to declare the friend << operator here
  template<typename _ElemT>
    std::ostream & operator << (std::ostream & out, BasicVector<_ElemT> & m);

  /** **************************************************************************
   ** **************************************************************************
   *  @brief Provides a matrix abstraction class
   *
   *  This class provides a way to work with matrices in STK.
   *  It encapsulates basic operations and memory optimizations.
   *
   */
  template<typename _ElemT>
      class BasicVector
    {
    public:
      BasicVector(): mpData(NULL)
#ifdef STK_MEMALIGN_MANUAL
        ,mpFreeData(NULL)
#endif
        , mLength(0)
      {}

      /**
       * @brief Copy constructor
       * @param rV
       */
      BasicVector(const BasicVector<_ElemT>& rV);

      BasicVector(const size_t s);

      BasicVector(const _ElemT* pData, const size_t s);

      ~BasicVector();

      void
      Init(size_t length);

      /**
       * @brief Dealocates the window from memory and resets the dimensions to (0)
       */
      void
      Destroy();

      /**
       * @brief Returns @c true if vector is initialized
       */
      const bool
      IsInitialized() const
      { return mpData != NULL; }

      /**
       * @brief Sets all elements to 0
       */
      void
      Clear();

      const size_t
      Length() const
      { return mLength; }

      /**
       * @brief Returns size of matrix in memory (in bytes)
       */
      const size_t
      MSize() const
      {
        return (mLength + (((16 / sizeof(_ElemT)) - mLength%(16 / sizeof(_ElemT)))
                          % (16 / sizeof(_ElemT)))) * sizeof(_ElemT);
      }

      /**
       *  @brief Gives access to the vector memory area
       *  @return pointer to the first field
       */
      _ElemT*
      pData() const
      { return mpData; }

      /**
       *  @brief Gives access to the vector memory area
       *  @return pointer to the first field
       */
      const _ElemT* const
      cpData() const
      { return mpData; }

      /**
       *  @brief Gives access to a specified vector element without range check
       *  @return pointer to the first field of the row
       */
      _ElemT&
      operator [] (size_t i) const
      { return *(mpData + i);}

      //########################################################################
      //########################################################################
      BasicVector<_ElemT>&
      AddCVMul(const _ElemT c, const BasicVector<_ElemT>& rV);

      BasicVector<_ElemT>&
      AddCVMul(const _ElemT c, const _ElemT* pV);

      BasicVector<_ElemT>&
      AddCVVDotMul(const _ElemT c, const _ElemT* pA, const size_t nA,
                                   const _ElemT* pB, const size_t nB);

      /// this = this + c * rM * rV
      BasicVector<_ElemT>&
      AddCMVMul(const _ElemT c, const Matrix<_ElemT>& rM,
                const BasicVector<_ElemT>& rV);

      /// this = this + c * rM * pV
      BasicVector<_ElemT>&
      AddCMVMul(const _ElemT c, const Matrix<_ElemT>& rM,
                const _ElemT* pV);

      /// this = this + c * rM * rV
      BasicVector<_ElemT>&
      AddCMtVMul(const _ElemT c, const Matrix<_ElemT>& rM,
                 const BasicVector<_ElemT>& rV);

      /// this = this + c * rM * rV
      BasicVector<_ElemT>&
      AddCMtVMul(const _ElemT c, const Matrix<_ElemT>& rM,
                 const _ElemT* pV);

      /// Adds a diagonal after Matrix-Matrix Multiplication
      BasicVector<_ElemT>&
      AddDiagCMMMul(const _ElemT c, const Matrix<_ElemT>& rMa,
                    const Matrix<_ElemT>& rMb);

      _ElemT
      Dot(const BasicVector<_ElemT>& rV);

      _ElemT
      Dot(const _ElemT* pV);

      /// Performs a row stack of the matrix rMa
      BasicVector<_ElemT>&
      MatrixRowStack(const Matrix<_ElemT>& rMa);

      /// Returns sum of the elements
      _ElemT
      Sum() const;

      /// Returns sum of the elements
      BasicVector<_ElemT>&
      AddRowSum(const Matrix<_ElemT>& rM);

      /// Returns sum of the elements
      BasicVector<_ElemT>&
      AddColSum(const Matrix<_ElemT>& rM);

      /// Returns log(sum(exp())) without exp overflow
      _ElemT
      LogSumExp() const;

      //########################################################################
      //########################################################################

      friend std::ostream &
      operator << <> (
        std::ostream& rOut,
        BasicVector<_ElemT>& rV);

      //operator _ElemT* ()
      //{
      //  return mpData;
      //}

    //##########################################################################
    //##########################################################################
    //protected:
    public:
      /// data memory area
      _ElemT*   mpData;
#ifdef STK_MEMALIGN_MANUAL
      /// data to be freed (in case of manual memalignment use, see common.h)
      _ElemT*   mpFreeData;
#endif
      size_t  mLength;      ///< Number of elements
    }; // class BasicVector

}; // namespace STK

//*****************************************************************************
//*****************************************************************************
// we need to include the implementation
#include "BasicVector.tcc"
//*****************************************************************************
//*****************************************************************************

/******************************************************************************
 ******************************************************************************
 * The following section contains specialized template definitions
 * whose implementation is in BasicVector.cc
 */

namespace STK
{
  template<>
    BasicVector<float>&
    BasicVector<float>::
    AddCVMul(const float c, const BasicVector<float>& rV);

  template<>
    BasicVector<double>&
    BasicVector<double>::
    AddCVMul(const double c, const BasicVector<double>& rV);

  template<>
    BasicVector<float>&
    BasicVector<float>::
    AddCVMul(const float c, const float* pV);

  template<>
    BasicVector<double>&
    BasicVector<double>::
    AddCVMul(const double c, const double* pV);

  template<>
    BasicVector<float>&
    BasicVector<float>::
    AddCMVMul(const float c, const Matrix<float>& rV, const BasicVector<float>& rV2);

  template<>
    BasicVector<double>&
    BasicVector<double>::
    AddCMVMul(const double c, const Matrix<double>& rV, const BasicVector<double>& rV2);

  template<>
    BasicVector<float>&
    BasicVector<float>::
    AddCMtVMul(const float c, const Matrix<float>& rV, const BasicVector<float>& rV2);

  template<>
    BasicVector<double>&
    BasicVector<double>::
    AddCMtVMul(const double c, const Matrix<double>& rV, const BasicVector<double>& rV2);

  template<>
    BasicVector<float>&
    BasicVector<float>::
    AddCMtVMul(const float c, const Matrix<float>& rV, const float* pV);

  template<>
    BasicVector<double>&
    BasicVector<double>::
    AddCMtVMul(const double c, const Matrix<double>& rV, const double* pV);

  template<>
    float
    BasicVector<float>::
    Dot(const float* pV);

  template<>
    double
    BasicVector<double>::
    Dot(const double* pV);

} // namespace STK

#endif // #ifndef STK_BasicVector_h

max_stars_repo_name: troylee/nnet-asr

max_issues_repo_name: troylee/nnet-asr

max_forks_repo_name: troylee/nnet-asr


text:
/**
 *
 * @file core_stsmlq_sytra1.c
 *
 *  PLASMA core_blas kernel
 *  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 Azzam Haidar
 * @date 2010-11-15
 * @generated s Tue Jan  7 11:44:48 2014
 *
 **/
#include <lapacke.h>
#include "common.h"
#undef COMPLEX
#define REAL

/***************************************************************************//**
 *
 * @ingroup CORE_float
 *
 * CORE_stsmlq_sytra1: see CORE_stsmlq
 *
 * This kernel applies a Right transformation on | A1' A2 |
 * and does not handle the transpose of A1.
 * Needs therefore to make the explicit transpose of A1 before
 * and after the application of the block of reflectors
 * Can be further optimized by changing accordingly the underneath
 * kernel ztsrfb!
 *
 *******************************************************************************
 *
 * @param[in] side
 *         @arg PlasmaLeft  : apply Q or Q**T from the Left;
 *         @arg PlasmaRight : apply Q or Q**T from the Right.
 *
 * @param[in] trans
 *         @arg PlasmaNoTrans   :  No transpose, apply Q;
 *         @arg PlasmaTrans :  ConjTranspose, apply Q**T.
 *
 * @param[in] m1
 *         The number of rows of the tile A1. m1 >= 0.
 *
 * @param[in] n1
 *         The number of columns of the tile A1. n1 >= 0.
 *
 * @param[in] m2
 *         The number of rows of the tile A2. m2 >= 0.
 *         m2 = m1 if side == PlasmaRight.
 *
 * @param[in] n2
 *         The number of columns of the tile A2. n2 >= 0.
 *         n2 = n1 if side == PlasmaLeft.
 *
 * @param[in] k
 *         The number of elementary reflectors whose product defines
 *         the matrix Q.
 *
 * @param[in] ib
 *         The inner-blocking size.  ib >= 0.
 *
 * @param[in,out] A1
 *         On entry, the m1-by-n1 tile A1.
 *         On exit, A1 is overwritten by the application of Q.
 *
 * @param[in] lda1
 *         The leading dimension of the array A1. lda1 >= max(1,m1).
 *
 * @param[in,out] A2
 *         On entry, the m2-by-n2 tile A2.
 *         On exit, A2 is overwritten by the application of Q.
 *
 * @param[in] lda2
 *         The leading dimension of the tile A2. lda2 >= max(1,m2).
 *
 * @param[in] V
 *         The i-th row must contain the vector which defines the
 *         elementary reflector H(i), for i = 1,2,...,k, as returned by
 *         CORE_STSLQT in the first k rows of its array argument V.
 *!
 * @param[in] ldv
 *         The leading dimension of the array V. ldv >= max(1,K).
 *
 * @param[in] T
 *         The IB-by-n1 triangular factor T of the block reflector.
 *         T is upper triangular by block (economic storage);
 *         The rest of the array is not referenced.
 *
 * @param[in] ldt
 *         The leading dimension of the array T. ldt >= IB.
 *
 * @param[out] WORK
 *         Workspace array of size
 *             LDWORK-by-m1 if side == PlasmaLeft
 *             LDWORK-by-IB if side == PlasmaRight
 *
 * @param[in] ldwork
 *         The leading dimension of the array WORK.
 *             LDWORK >= max(1,IB) if side == PlasmaLeft
 *             LDWORK >= max(1,n1) if side == PlasmaRight
 *
 *******************************************************************************
 *
 * @return
 *          \retval PLASMA_SUCCESS successful exit
 *          \retval <0 if -i, the i-th argument had an illegal value
 *
 ******************************************************************************/
#if defined(PLASMA_HAVE_WEAK)
#pragma weak CORE_stsmlq_sytra1 = PCORE_stsmlq_sytra1
#define CORE_stsmlq_sytra1 PCORE_stsmlq_sytra1
#define CORE_stsmlq PCORE_stsmlq
int  CORE_stsmlq(PLASMA_enum side, PLASMA_enum trans,
                 int m1, int n1, int m2, int n2, int K, int IB,
                 float *A1, int lda1,
                 float *A2, int lda2,
                 const float *V, int ldv,
                 const float *T, int ldt,
                 float *WORK, int LDWORK);
#endif
int CORE_stsmlq_sytra1( PLASMA_enum side, PLASMA_enum trans,
                        int m1, int n1, int m2, int n2,
                        int k, int ib,
                        float *A1, int lda1,
                        float *A2, int lda2,
                        const float *V, int ldv,
                        const float *T, int ldt,
                        float *WORK, int ldwork)
{
    int i, j;

    if ( (m1 != n1) ) {
        coreblas_error(3, "Illegal value of M1, N1");
        return -3;
    }

    /* in-place transposition of A1 */
    for (j = 0; j < n1; j++){
        A1[j + j*lda1] = (A1[j + j*lda1]);

        for (i = j+1; i < m1; i++){
            *WORK = *(A1 + i + j*lda1);
            *(A1 + i + j*lda1) = (*(A1 + j + i*lda1));
            *(A1 + j + i*lda1) = (*WORK);
        }
    }

    CORE_stsmlq(side, trans, m1, n1, m2, n2, k, ib,
                A1, lda1, A2, lda2,
                V,  ldv,  T,  ldt,
                WORK, ldwork);

    /* in-place transposition of A1 */
    for (j = 0; j < n1; j++){
        A1[j + j*lda1] = (A1[j + j*lda1]);

        for (i = j+1; i < m1; i++){
            *WORK = *(A1 + i + j*lda1);
            *(A1 + i + j*lda1) = (*(A1 + j + i*lda1));
            *(A1 + j + i*lda1) = (*WORK);
        }
    }

    return PLASMA_SUCCESS;
}

ext: c


text:
/**
 * @file batch_zdotu_sub.c
 *
 * Part of API test for Batched BLAS routines.
 *
 * @author  Samuel  D. Relton
 * @author  Pedro   V. Lara
 * @author  Mawussi Zounon
 * @date
 *
 * @precisions normal z -> c d s
 *
 **/

#include <cblas.h>
#include "bblas.h"

#define COMPLEX

void batch_zdotu_sub(
		  const int *n,
		  BBLAS_Complex64_t const * const *x,
		  const int *incx,
		  BBLAS_Complex64_t const * const *y,
		  const int *incy,
		  BBLAS_Complex64_t *dotu,
		  const int batch_count, const enum BBLAS_OPTS batch_opts,
		  int* info)
{
	/* Local variables */
	int first_index = 0;
	char func_name[15] = "batch_zdotu";

	/*initialize the result */
	for (int batch_iter = 0; batch_iter < batch_count; batch_iter++)
	  {
	    dotu[batch_iter] = (BBLAS_Complex64_t)0.0;
	  }

	/* Check input arguments */
	if (batch_count < 0)
	{
		xerbla_batch(func_name, BBLAS_ERR_BATCH_COUNT, -1);
	}

	if (batch_opts == BBLAS_FIXED)
	  {
	    /* Call fixed size code */
	    batchf_zdotu_sub(
			     n[first_index],
			     x,
			     incx[first_index],
			     y,
			     incy[first_index],
			     dotu,
			     batch_count, info);
	  }
	else if (batch_opts == BBLAS_VARIABLE)
	  {
	    /* Call variable size code */
	    batchv_zdotu_sub(
			     n,
			     x,
			     incx,
			     y,
			     incy,
			     dotu,
			     batch_count, info);

	  }
	else
	  {
	    xerbla_batch(func_name, BBLAS_ERR_BATCH_OPTS, -1);
	  }
}
#undef COMPLEX

max_stars_repo_name: mawussi/BBLAS-group


text:
#pragma once

#include "random_utils.h"
#include "schedule.h"
#include "schedule_params.h"
#include "stochastic_tunneling.h"
#include "temperature.h"
#include "utils.h"
#include <gsl/gsl-lite.hpp>

namespace angonoka::stun {
/**
    How many stochastic tunneling iterations to go through
    during each update.
*/
enum class BatchSize : std::int_fast32_t;

/**
    A single optimization job, meant to be launched in a thread pool.

    Optimizer starts many OptimizerJobs in parallel,
    pruning unseccessful jobs as needed.
*/
class OptimizerJob {
public:
    /**
        OptimizerJob options.

        @var params Schedule parameters
        @var random Random utils.
    */
    struct Options {
        gsl::not_null<const ScheduleParams*> params;
        gsl::not_null<RandomUtils*> random;
    };

    /**
        Constructor.

        @param params           Scheduling parameters
        @param random_utils     Random number generator utilities
        @param batch_size       Number of iterations per update
    */
    OptimizerJob(
        const ScheduleParams& params,
        RandomUtils& random_utils,
        BatchSize batch_size);
    OptimizerJob(const Options& options, BatchSize batch_size);

    /**
        Run stochastic tunneling optimization batch.

        Does batch_size number of iterations.
    */
    void update() noexcept;

    /**
        The best schedule so far.

        @return A schedule.
    */
    [[nodiscard]] Schedule schedule() const;

    /**
        The best makespan so far.

        @return Makespan.
    */
    [[nodiscard]] float normalized_makespan() const;

    /**
        Reset the optimization to initial state.
    */
    void reset();

    /**
        Get current options.

        @return Options.
    */
    [[nodiscard]] Options options() const;

    /**
        Set options.

        @param options Options.
    */
    void options(const Options& options);

    OptimizerJob(const OptimizerJob& other);
    OptimizerJob(OptimizerJob&& other) noexcept;
    OptimizerJob& operator=(const OptimizerJob& other);
    OptimizerJob& operator=(OptimizerJob&& other) noexcept;
    ~OptimizerJob() noexcept;

private:
    static constexpr auto beta_scale = 1e-4F;
    static constexpr auto stun_window = 10000;
    static constexpr auto gamma = .5F;
    static constexpr auto restart_period = 1 << 20;
    static constexpr auto initial_beta = 1.0F;

    int16 batch_size;
    Mutator mutator;
    Makespan makespan;
    Temperature temperature;
    StochasticTunneling stun;
};
} // namespace angonoka::stun

max_stars_repo_name: coffee-lord/angonoka

max_issues_repo_name: coffee-lord/angonoka

max_forks_repo_name: coffee-lord/angonoka