/*
   Copyright: Copyright (c) MOSEK ApS, Denmark. All rights reserved.

   File:      blas_lapack.c

   Purpose: To demonstrate how to call BLAS/LAPACK routines for
            which MOSEK provides simplified interfaces.

 */
#include "mosek.h"
void print_matrix(MSKrealt* x, MSKint32t r, MSKint32t c)
{
  MSKint32t i, j;
  for (i = 0; i < r; i++)
  {
    for (j = 0; j < c; j++)
      printf("%f ", x[j * r + i]);

    printf("\n");
  }

}

int main(int argc, char*  argv[])
{

  /*TAG:begin-setup-comm*/
  MSKrescodee r   = MSK_RES_OK;
  MSKenv_t    env = NULL;

  const MSKint32t n = 3, m = 2, k = 3;
  /*TAG:end-setup-comm*/

  MSKrealt alpha = 2.0, beta = 0.5;
  MSKrealt x[]    = {1.0, 1.0, 1.0};
  MSKrealt y[]    = {1.0, 2.0, 3.0};
  MSKrealt z[]    = {1.0, 1.0};
  MSKrealt A[]    = {1.0, 1.0, 2.0, 2.0, 3.0, 3.0};
  MSKrealt B[]    = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0};
  MSKrealt C[]    = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0};
  MSKrealt D[]    = {1.0, 1.0, 1.0, 1.0};
  MSKrealt Q[]    = {1.0, 0.0, 0.0, 2.0};
  MSKrealt v[]    = {0.0, 0.0, 0.0};

  MSKrealt xy;

  /* BLAS routines*/
  /*TAG:begin-make-env*/
  r = MSK_makeenv(&env, NULL);
  /*TAG:end-make-env*/
  printf("n=%d m=%d k=%d\n", m, n, k);
  printf("alpha=%f\n", alpha);
  printf("beta=%f\n", beta);

  /*TAG:begin-dot*/
  r = MSK_dot(env, n, x, y, &xy);
  /*TAG:end-dot*/
  printf("dot results= %f r=%d\n", xy, r);


  print_matrix(x, 1, n);
  print_matrix(y, 1, n);

  /*TAG:begin-axpy*/
  r = MSK_axpy(env, n, alpha, x, y);
  /*TAG:end-axpy*/
  puts("axpy results is");
  print_matrix(y, 1, n);


  /*TAG:begin-gemv*/
  r = MSK_gemv(env, MSK_TRANSPOSE_NO, m, n, alpha, A, x, beta, z);
  /*TAG:end-gemv*/
  printf("gemv results is (r=%d) \n", r);
  print_matrix(z, 1, m);

  /*TAG:begin-gemm*/
  r = MSK_gemm(env, MSK_TRANSPOSE_NO, MSK_TRANSPOSE_NO, m, n, k, alpha, A, B, beta, C);
  /*TAG:end-gemm*/
  printf("gemm results is (r=%d) \n", r);
  print_matrix(C, m, n);

  /*TAG:begin-syrk*/
  r = MSK_syrk(env, MSK_UPLO_LO, MSK_TRANSPOSE_NO, m, k, 1., A, beta, D);
  /*TAG:end-syrk*/
  printf("syrk results is (r=%d) \n", r);
  print_matrix(D, m, m);

  /* LAPACK routines*/

  /*TAG:begin-potrf*/
  r = MSK_potrf(env, MSK_UPLO_LO, m, Q);
  /*TAG:end-potrf*/
  printf("potrf results is (r=%d) \n", r);
  print_matrix(Q, m, m);

  /*TAG:begin-syeig*/
  r = MSK_syeig(env, MSK_UPLO_LO, m, Q, v);
  /*TAG:end-syeig*/
  printf("syeig results is (r=%d) \n", r);
  print_matrix(v, 1, m);

  /*TAG:begin-syevd*/
  r = MSK_syevd(env, MSK_UPLO_LO, m, Q, v);
  /*TAG:end-syevd*/
  printf("syevd results is (r=%d) \n", r);
  print_matrix(v, 1, m);
  print_matrix(Q, m, m);

  /* Delete the environment and the associated data. */
  MSK_deleteenv(&env);

  return r;
}
