<commit_before>/* matrix - test matrix functionality

   Copyright © 2012-2016 <NAME> <<EMAIL>>.
         Institute of Electronic Music and Acoustics (IEM),
         University of Music and Dramatic Arts, Graz

   This file is part of libambix

   libambix is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as
   published by the Free Software Foundation; either version 2.1 of
   the License, or (at your option) any later version.

   libambix 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 Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this program; if not, see <http://www.gnu.org/licenses/>.

*/

#include "common.h"
#include <string.h>
#include <stdlib.h>

static float32_t leftdata_4_3[]= {
   0.19, 0.06, 0.14,
   0.05, 0.08, 0.44,
   0.25, 0.90, 0.77,
   0.83, 0.51, 0.58,
};
static float32_t leftdata_4_4[]= {
  0.7131185686247925, 0.1054799265939327, 0.1882023608287114, 0.1496964665104298,
  0.9035382689904633, 0.0958506183093942, 0.1490156537909140, 0.6730762573692578,
  0.7110257215280688, 0.4278857180785819, 0.5050723092090162, 0.2342525090113509,
  0.1917073427152419, 0.3837280931544647, 0.0397484032568303, 0.5895499716980565,
};
static float32_t rightdata_3_2[]= {
   0.22, 0.46,
   0.36, 0.53,
   0.77, 0.85,
};
static float32_t resultdata_4_2[]= {
  /* leftdata[4,3] * rightdata[3,2] */
   0.1712, 0.2382,
   0.3786, 0.4394,
   0.9719, 1.2465,
   0.8128, 1.1451,
};
static float32_t resultpinv_4_3[] = {
  /* (leftdata[4,3])^-1 */
 0.320059925923633, -0.616572833442599, -0.758203952544301,  1.397070173352668,
-0.475395139478048, -2.112396458091558,  1.443108803981482, -0.198593134445739,
 0.349719602203337,  2.683861685335670, -0.150602340058839, -0.196372558639406,
};
static float32_t resultpinv_4_4[] = {
  /* (leftdata[4,4])^-1 */
  3.260687761423661,-0.750604578051301,-1.027983295100203, 0.437466478433052,
  4.478583197847279,-3.527343133136301,-0.883177052786819, 3.240826676373624,
 -6.751824651655014, 2.959470009112655, 3.874801812795508,-3.203980734335171,
 -3.520111656963465, 2.340434097800232, 0.647874863173282,-0.339426118611342,
};
static void mtxinverse_test(const ambix_matrix_t *mtx, const ambix_matrix_t *result, float32_t eps) {
  ambix_matrix_t *pinv = 0;
  ambix_matrix_t *mul=0;
  ambix_matrix_t *eye=0;
  float32_t errf;
  int min_rowcol=(mtx->cols<mtx->rows)?mtx->cols:mtx->rows;

  fail_if((NULL==mtx), __LINE__, "cannot invert NULL-matrix");
  eye=ambix_matrix_init(min_rowcol, min_rowcol, eye);
  eye=ambix_matrix_fill(eye, AMBIX_MATRIX_IDENTITY);
  fail_if((NULL==eye), __LINE__, "cannot create eye-matrix for pinv-verification");

  pinv=ambix_matrix_pinv(mtx, pinv);
  if(NULL==pinv)matrix_print(mtx);
  fail_if((NULL==pinv), __LINE__, "could not invert matrix");

  if(mtx->cols < mtx->rows)
    mul=ambix_matrix_multiply(pinv, mtx, 0);
  else
    mul=ambix_matrix_multiply(mtx, pinv, 0);

#if 0
  matrix_print(mtx);
  matrix_print(pinv);
  matrix_print(mul);
  if(result)matrix_print(result);
  printf("------------\n");
#endif

  if(result) {
    errf=matrix_diff(__LINE__, pinv, result, eps);
    fail_if((errf>eps), __LINE__, "diffing (pseudo)inverse returned %g (>%g)", errf, eps);

    errf=matrix_diff(__LINE__, mul, eye, eps);
    fail_if((errf>eps), __LINE__, "diffing mtx*pinv(mtx) returned %g (>%g)", errf, eps);
  } else matrix_print(pinv);

  ambix_matrix_destroy(pinv);
  ambix_matrix_destroy(mul);
  ambix_matrix_destroy(eye);
}
void mtxinverse_tests(float32_t eps) {
  float32_t errf;
  ambix_matrix_t *mtx=0, *testresult=0;
  float32_t*transposedata = (float32_t*)calloc(3*4, sizeof(float32_t));

  STARTTEST("\n");

  /* fill in some test data 4x4 */
  STARTTEST("[4x4]\n");
  mtx=ambix_matrix_init(4, 4, mtx);
  ambix_matrix_fill_data(mtx, leftdata_4_4);
  testresult=ambix_matrix_init(4, 4, testresult);
  ambix_matrix_fill_data(testresult, resultpinv_4_4);
  mtxinverse_test(mtx, testresult, eps);

  /* fill in some test data 4x3 */
  STARTTEST("[4x3]\n");
  mtx=ambix_matrix_init(4, 3, mtx);
  ambix_matrix_fill_data(mtx, leftdata_4_3);
  testresult=ambix_matrix_init(3, 4, testresult);
  ambix_matrix_fill_data(testresult, resultpinv_4_3);
  mtxinverse_test(mtx, testresult, eps);

  /* fill in some test data 3x4 */
  STARTTEST("[3x4]\n");<commit_msg>fail if mtx-inversions succeeds and no reference result is present.<commit_after>/* matrix - test matrix functionality

   Copyright © 2012-2016 <NAME> <<EMAIL>>.
         Institute of Electronic Music and Acoustics (IEM),
         University of Music and Dramatic Arts, Graz

   This file is part of libambix

   libambix is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as
   published by the Free Software Foundation; either version 2.1 of
   the License, or (at your option) any later version.

   libambix 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 Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this program; if not, see <http://www.gnu.org/licenses/>.

*/

#include "common.h"
#include <string.h>
#include <stdlib.h>

static float32_t leftdata_4_3[]= {
   0.19, 0.06, 0.14,
   0.05, 0.08, 0.44,
   0.25, 0.90, 0.77,
   0.83, 0.51, 0.58,
};
static float32_t leftdata_4_4[]= {
  0.7131185686247925, 0.1054799265939327, 0.1882023608287114, 0.1496964665104298,
  0.9035382689904633, 0.0958506183093942, 0.1490156537909140, 0.6730762573692578,
  0.7110257215280688, 0.4278857180785819, 0.5050723092090162, 0.2342525090113509,
  0.1917073427152419, 0.3837280931544647, 0.0397484032568303, 0.5895499716980565,
};
static float32_t rightdata_3_2[]= {
   0.22, 0.46,
   0.36, 0.53,
   0.77, 0.85,
};
static float32_t resultdata_4_2[]= {
  /* leftdata[4,3] * rightdata[3,2] */
   0.1712, 0.2382,
   0.3786, 0.4394,
   0.9719, 1.2465,
   0.8128, 1.1451,
};
static float32_t resultpinv_4_3[] = {
  /* (leftdata[4,3])^-1 */
 0.320059925923633, -0.616572833442599, -0.758203952544301,  1.397070173352668,
-0.475395139478048, -2.112396458091558,  1.443108803981482, -0.198593134445739,
 0.349719602203337,  2.683861685335670, -0.150602340058839, -0.196372558639406,
};
static float32_t resultpinv_4_4[] = {
  /* (leftdata[4,4])^-1 */
  3.260687761423661,-0.750604578051301,-1.027983295100203, 0.437466478433052,
  4.478583197847279,-3.527343133136301,-0.883177052786819, 3.240826676373624,
 -6.751824651655014, 2.959470009112655, 3.874801812795508,-3.203980734335171,
 -3.520111656963465, 2.340434097800232, 0.647874863173282,-0.339426118611342,
};
static void mtxinverse_test(const ambix_matrix_t *mtx, const ambix_matrix_t *result, float32_t eps) {
  ambix_matrix_t *pinv = 0;
  ambix_matrix_t *mul=0;
  ambix_matrix_t *eye=0;
  float32_t errf;
  int min_rowcol=(mtx->cols<mtx->rows)?mtx->cols:mtx->rows;

  fail_if((NULL==mtx), __LINE__, "cannot invert NULL-matrix");
  eye=ambix_matrix_init(min_rowcol, min_rowcol, eye);
  eye=ambix_matrix_fill(eye, AMBIX_MATRIX_IDENTITY);
  fail_if((NULL==eye), __LINE__, "cannot create eye-matrix for pinv-verification");

  pinv=ambix_matrix_pinv(mtx, pinv);
  if(NULL==pinv)matrix_print(mtx);
  fail_if((NULL==pinv), __LINE__, "could not invert matrix");

  if(mtx->cols < mtx->rows)
    mul=ambix_matrix_multiply(pinv, mtx, 0);
  else
    mul=ambix_matrix_multiply(mtx, pinv, 0);

#if 0
  matrix_print(mtx);
  matrix_print(pinv);
  matrix_print(mul);
  if(result)matrix_print(result);
  printf("------------\n");
#endif

  if(result) {
    errf=matrix_diff(__LINE__, pinv, result, eps);
    fail_if((errf>eps), __LINE__, "diffing (pseudo)inverse returned %g (>%g)", errf, eps);

    errf=matrix_diff(__LINE__, mul, eye, eps);
    fail_if((errf>eps), __LINE__, "diffing mtx*pinv(mtx) returned %g (>%g)", errf, eps);
  } else {
    errf=matrix_diff(__LINE__, mul, eye, eps);
    fail_if((!(isnan(errf) || isinf(errf) || (errf>eps))), __LINE__, "diffing invalid mtx*pinv(mtx) returned %g (!>%g)", errf, eps);
  }

  ambix_matrix_destroy(pinv);
  ambix_matrix_destroy(mul);
  ambix_matrix_destroy(eye);
}
void mtxinverse_tests(float32_t eps) {
  float32_t errf;
  ambix_matrix_t *mtx=0, *testresult=0;
  float32_t*transposedata = (float32_t*)calloc(3*4, sizeof(float32_t));

  STARTTEST("\n");

  /* fill in some test data 4x4 */
  STARTTEST("[4x4]\n");
  mtx=ambix_matrix_init(4, 4, mtx);
  ambix_matrix_fill_data(mtx, leftdata_4_4);
  testresult=ambix_matrix_init(4, 4, testresult);
  ambix_matrix_fill_data(testresult, resultpinv_4_4);
  mtxinverse_test(mtx, testresult, eps);

  /* fill in some test data 4x3 */
  STARTTEST("[4x3]\n");
  mtx=ambix_matrix_init(4, 3, mtx);
  ambix_matrix_fill_data(mtx, leftdata_4_3);
  testresult=ambix_matrix_init(3, 4, testresult);
  ambix_matrix_fill_data(testresult, resultpinv_4_3);
  mtxinverse_test(mtx, testresult, eps);

  /* fill in some test data 3x4 */
  STARTTEST("[3x4]\n");
{'fraction_non_alphanumeric': 0.13539651837524178, 'fraction_numerical': 0.19557274876423814, 'mean_word_length': 4.65775075987842, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3599775', 'n_tokens_mistral': 4869, 'n_tokens_neox': 3828, 'n_words': 781}