blob: 978eb9abd0f40bd520f0151fc68606547046df36 [file] [log] [blame]
/**************************************************************************************************
* *
* This file is part of BLASFEO. *
* *
* BLASFEO -- BLAS For Embedded Optimization. *
* Copyright (C) 2016-2017 by Gianluca Frison. *
* Developed at IMTEK (University of Freiburg) under the supervision of Moritz Diehl. *
* All rights reserved. *
* *
* HPMPC 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. *
* *
* HPMPC 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 HPMPC; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
* *
* Author: Gianluca Frison, giaf (at) dtu.dk *
* gianluca.frison (at) imtek.uni-freiburg.de *
* *
**************************************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "../include/blasfeo_common.h"
#if defined(LA_REFERENCE) | defined(LA_BLAS)
// return memory size (in bytes) needed for a strmat
int s_size_strmat(int m, int n)
{
int tmp = m<n ? m : n; // al(min(m,n)) // XXX max ???
int size = (m*n+tmp)*sizeof(float);
return size;
}
// return memory size (in bytes) needed for the diagonal of a strmat
int s_size_diag_strmat(int m, int n)
{
int size = 0;
int tmp = m<n ? m : n; // al(min(m,n)) // XXX max ???
size = tmp*sizeof(float);
return size;
}
// create a matrix structure for a matrix of size m*n by using memory passed by a pointer
void s_create_strmat(int m, int n, struct s_strmat *sA, void *memory)
{
sA->m = m;
sA->n = n;
float *ptr = (float *) memory;
sA->pA = ptr;
ptr += m*n;
int tmp = m<n ? m : n; // al(min(m,n)) // XXX max ???
sA->dA = ptr;
ptr += tmp;
sA->use_dA = 0;
sA->memory_size = (m*n+tmp)*sizeof(float);
return;
}
// return memory size (in bytes) needed for a strvec
int s_size_strvec(int m)
{
int size = m*sizeof(float);
return size;
}
// create a matrix structure for a matrix of size m*n by using memory passed by a pointer
void s_create_strvec(int m, struct s_strvec *sa, void *memory)
{
sa->m = m;
float *ptr = (float *) memory;
sa->pa = ptr;
// ptr += m * n;
sa->memory_size = m*sizeof(float);
return;
}
// convert a matrix into a matrix structure
void s_cvt_mat2strmat(int m, int n, float *A, int lda, struct s_strmat *sA, int ai, int aj)
{
int ii, jj;
int lda2 = sA->m;
float *pA = sA->pA + ai + aj*lda2;
for(jj=0; jj<n; jj++)
{
ii = 0;
for(; ii<m-3; ii+=4)
{
pA[ii+0+jj*lda2] = A[ii+0+jj*lda];
pA[ii+1+jj*lda2] = A[ii+1+jj*lda];
pA[ii+2+jj*lda2] = A[ii+2+jj*lda];
pA[ii+3+jj*lda2] = A[ii+3+jj*lda];
}
for(; ii<m; ii++)
{
pA[ii+0+jj*lda2] = A[ii+0+jj*lda];
}
}
return;
}
// convert and transpose a matrix into a matrix structure
void s_cvt_tran_mat2strmat(int m, int n, float *A, int lda, struct s_strmat *sA, int ai, int aj)
{
int ii, jj;
int lda2 = sA->m;
float *pA = sA->pA + ai + aj*lda2;
for(jj=0; jj<n; jj++)
{
ii = 0;
for(; ii<m-3; ii+=4)
{
pA[jj+(ii+0)*lda2] = A[ii+0+jj*lda];
pA[jj+(ii+1)*lda2] = A[ii+1+jj*lda];
pA[jj+(ii+2)*lda2] = A[ii+2+jj*lda];
pA[jj+(ii+3)*lda2] = A[ii+3+jj*lda];
}
for(; ii<m; ii++)
{
pA[jj+(ii+0)*lda2] = A[ii+0+jj*lda];
}
}
return;
}
// convert a vector into a vector structure
void s_cvt_vec2strvec(int m, float *a, struct s_strvec *sa, int ai)
{
float *pa = sa->pa + ai;
int ii;
for(ii=0; ii<m; ii++)
pa[ii] = a[ii];
return;
}
// convert a matrix structure into a matrix
void s_cvt_strmat2mat(int m, int n, struct s_strmat *sA, int ai, int aj, float *A, int lda)
{
int ii, jj;
int lda2 = sA->m;
float *pA = sA->pA + ai + aj*lda2;
for(jj=0; jj<n; jj++)
{
ii = 0;
for(; ii<m-3; ii+=4)
{
A[ii+0+jj*lda] = pA[ii+0+jj*lda2];
A[ii+1+jj*lda] = pA[ii+1+jj*lda2];
A[ii+2+jj*lda] = pA[ii+2+jj*lda2];
A[ii+3+jj*lda] = pA[ii+3+jj*lda2];
}
for(; ii<m; ii++)
{
A[ii+0+jj*lda] = pA[ii+0+jj*lda2];
}
}
return;
}
// convert and transpose a matrix structure into a matrix
void s_cvt_tran_strmat2mat(int m, int n, struct s_strmat *sA, int ai, int aj, float *A, int lda)
{
int ii, jj;
int lda2 = sA->m;
float *pA = sA->pA + ai + aj*lda2;
for(jj=0; jj<n; jj++)
{
ii = 0;
for(; ii<m-3; ii+=4)
{
A[jj+(ii+0)*lda] = pA[ii+0+jj*lda2];
A[jj+(ii+1)*lda] = pA[ii+1+jj*lda2];
A[jj+(ii+2)*lda] = pA[ii+2+jj*lda2];
A[jj+(ii+3)*lda] = pA[ii+3+jj*lda2];
}
for(; ii<m; ii++)
{
A[jj+(ii+0)*lda] = pA[ii+0+jj*lda2];
}
}
return;
}
// convert a vector structure into a vector
void s_cvt_strvec2vec(int m, struct s_strvec *sa, int ai, float *a)
{
float *pa = sa->pa + ai;
int ii;
for(ii=0; ii<m; ii++)
a[ii] = pa[ii];
return;
}
// cast a matrix into a matrix structure
void s_cast_mat2strmat(float *A, struct s_strmat *sA)
{
sA->pA = A;
return;
}
// cast a matrix into the diagonal of a matrix structure
void s_cast_diag_mat2strmat(float *dA, struct s_strmat *sA)
{
sA->dA = dA;
return;
}
// cast a vector into a vector structure
void s_cast_vec2vecmat(float *a, struct s_strvec *sa)
{
sa->pa = a;
return;
}
// insert element into strmat
void sgein1_libstr(float a, struct s_strmat *sA, int ai, int aj)
{
int lda = sA->m;
float *pA = sA->pA + ai + aj*lda;
pA[0] = a;
return;
}
// extract element from strmat
float sgeex1_libstr(struct s_strmat *sA, int ai, int aj)
{
int lda = sA->m;
float *pA = sA->pA + ai + aj*lda;
return pA[0];
}
// insert element into strvec
void svecin1_libstr(float a, struct s_strvec *sx, int xi)
{
float *x = sx->pa + xi;
x[0] = a;
return;
}
// extract element from strvec
float svecex1_libstr(struct s_strvec *sx, int xi)
{
float *x = sx->pa + xi;
return x[0];
}
// set all elements of a strmat to a value
void sgese_libstr(int m, int n, float alpha, struct s_strmat *sA, int ai, int aj)
{
int lda = sA->m;
float *pA = sA->pA + ai + aj*lda;
int ii, jj;
for(jj=0; jj<n; jj++)
{
for(ii=0; ii<m; ii++)
{
pA[ii+lda*jj] = alpha;
}
}
return;
}
// set all elements of a strvec to a value
void svecse_libstr(int m, float alpha, struct s_strvec *sx, int xi)
{
float *x = sx->pa + xi;
int ii;
for(ii=0; ii<m; ii++)
x[ii] = alpha;
return;
}
// extract diagonal to vector
void sdiaex_libstr(int kmax, float alpha, struct s_strmat *sA, int ai, int aj, struct s_strvec *sx, int xi)
{
int lda = sA->m;
float *pA = sA->pA + ai + aj*lda;
float *x = sx->pa + xi;
int ii;
for(ii=0; ii<kmax; ii++)
x[ii] = alpha*pA[ii*(lda+1)];
return;
}
// insert a vector into diagonal
void sdiain_libstr(int kmax, float alpha, struct s_strvec *sx, int xi, struct s_strmat *sA, int ai, int aj)
{
int lda = sA->m;
float *pA = sA->pA + ai + aj*lda;
float *x = sx->pa + xi;
int ii;
for(ii=0; ii<kmax; ii++)
pA[ii*(lda+1)] = alpha*x[ii];
return;
}
// extract a row into a vector
void srowex_libstr(int kmax, float alpha, struct s_strmat *sA, int ai, int aj, struct s_strvec *sx, int xi)
{
int lda = sA->m;
float *pA = sA->pA + ai + aj*lda;
float *x = sx->pa + xi;
int ii;
for(ii=0; ii<kmax; ii++)
x[ii] = alpha*pA[ii*lda];
return;
}
// insert a vector into a row
void srowin_libstr(int kmax, float alpha, struct s_strvec *sx, int xi, struct s_strmat *sA, int ai, int aj)
{
int lda = sA->m;
float *pA = sA->pA + ai + aj*lda;
float *x = sx->pa + xi;
int ii;
for(ii=0; ii<kmax; ii++)
pA[ii*lda] = alpha*x[ii];
return;
}
// add a vector to a row
void srowad_libstr(int kmax, float alpha, struct s_strvec *sx, int xi, struct s_strmat *sA, int ai, int aj)
{
int lda = sA->m;
float *pA = sA->pA + ai + aj*lda;
float *x = sx->pa + xi;
int ii;
for(ii=0; ii<kmax; ii++)
pA[ii*lda] += alpha*x[ii];
return;
}
// swap two rows of a matrix struct
void srowsw_libstr(int kmax, struct s_strmat *sA, int ai, int aj, struct s_strmat *sC, int ci, int cj)
{
int lda = sA->m;
float *pA = sA->pA + ai + aj*lda;
int ldc = sC->m;
float *pC = sC->pA + ci + cj*lda;
int ii;
float tmp;
for(ii=0; ii<kmax; ii++)
{
tmp = pA[ii*lda];
pA[ii*lda] = pC[ii*ldc];
pC[ii*ldc] = tmp;
}
return;
}
// permute the rows of a matrix struct
void srowpe_libstr(int kmax, int *ipiv, struct s_strmat *sA)
{
int ii;
for(ii=0; ii<kmax; ii++)
{
if(ipiv[ii]!=ii)
srowsw_libstr(sA->n, sA, ii, 0, sA, ipiv[ii], 0);
}
return;
}
// insert a vector into a rcol
void scolin_libstr(int kmax, struct s_strvec *sx, int xi, struct s_strmat *sA, int ai, int aj)
{
int lda = sA->m;
float *pA = sA->pA + ai + aj*lda;
float *x = sx->pa + xi;
int ii;
for(ii=0; ii<kmax; ii++)
pA[ii] = x[ii];
return;
}
// swap two cols of a matrix struct
void scolsw_libstr(int kmax, struct s_strmat *sA, int ai, int aj, struct s_strmat *sC, int ci, int cj)
{
int lda = sA->m;
float *pA = sA->pA + ai + aj*lda;
int ldc = sC->m;
float *pC = sC->pA + ci + cj*lda;
int ii;
float tmp;
for(ii=0; ii<kmax; ii++)
{
tmp = pA[ii];
pA[ii] = pC[ii];
pC[ii] = tmp;
}
return;
}
// permute the cols of a matrix struct
void scolpe_libstr(int kmax, int *ipiv, struct s_strmat *sA)
{
int ii;
for(ii=0; ii<kmax; ii++)
{
if(ipiv[ii]!=ii)
scolsw_libstr(sA->m, sA, 0, ii, sA, 0, ipiv[ii]);
}
return;
}
// copy a generic strmat into a generic strmat
void sgecp_libstr(int m, int n, struct s_strmat *sA, int ai, int aj, struct s_strmat *sC, int ci, int cj)
{
int lda = sA->m;
float *pA = sA->pA + ai + aj*lda;
int ldc = sC->m;
float *pC = sC->pA + ci + cj*ldc;
int ii, jj;
for(jj=0; jj<n; jj++)
{
ii = 0;
for(; ii<m-3; ii+=4)
{
pC[ii+0+jj*ldc] = pA[ii+0+jj*lda];
pC[ii+1+jj*ldc] = pA[ii+1+jj*lda];
pC[ii+2+jj*ldc] = pA[ii+2+jj*lda];
pC[ii+3+jj*ldc] = pA[ii+3+jj*lda];
}
for(; ii<m; ii++)
{
pC[ii+0+jj*ldc] = pA[ii+0+jj*lda];
}
}
return;
}
// scale a generic strmat
void sgesc_libstr(int m, int n, float alpha, struct s_strmat *sA, int ai, int aj)
{
int lda = sA->m;
float *pA = sA->pA + ai + aj*lda;
int ii, jj;
for(jj=0; jj<n; jj++)
{
ii = 0;
for(; ii<m-3; ii+=4)
{
pA[ii+0+jj*lda] *= alpha;
pA[ii+1+jj*lda] *= alpha;
pA[ii+2+jj*lda] *= alpha;
pA[ii+3+jj*lda] *= alpha;
}
for(; ii<m; ii++)
{
pA[ii+0+jj*lda] *= alpha;
}
}
return;
}
// copy a strvec into a strvec
void sveccp_libstr(int m, struct s_strvec *sa, int ai, struct s_strvec *sc, int ci)
{
float *pa = sa->pa + ai;
float *pc = sc->pa + ci;
int ii;
ii = 0;
for(; ii<m-3; ii+=4)
{
pc[ii+0] = pa[ii+0];
pc[ii+1] = pa[ii+1];
pc[ii+2] = pa[ii+2];
pc[ii+3] = pa[ii+3];
}
for(; ii<m; ii++)
{
pc[ii+0] = pa[ii+0];
}
return;
}
// scale a strvec
void svecsc_libstr(int m, float alpha, struct s_strvec *sa, int ai)
{
float *pa = sa->pa + ai;
int ii;
ii = 0;
for(; ii<m-3; ii+=4)
{
pa[ii+0] *= alpha;
pa[ii+1] *= alpha;
pa[ii+2] *= alpha;
pa[ii+3] *= alpha;
}
for(; ii<m; ii++)
{
pa[ii+0] *= alpha;
}
return;
}
// copy a lower triangular strmat into a lower triangular strmat
void strcp_l_libstr(int m, struct s_strmat *sA, int ai, int aj, struct s_strmat *sC, int ci, int cj)
{
int lda = sA->m;
float *pA = sA->pA + ai + aj*lda;
int ldc = sC->m;
float *pC = sC->pA + ci + cj*ldc;
int ii, jj;
for(jj=0; jj<m; jj++)
{
ii = jj;
for(; ii<m; ii++)
{
pC[ii+0+jj*ldc] = pA[ii+0+jj*lda];
}
}
return;
}
// scale and add a generic strmat into a generic strmat
void sgead_libstr(int m, int n, float alpha, struct s_strmat *sA, int ai, int aj, struct s_strmat *sC, int ci, int cj)
{
int lda = sA->m;
float *pA = sA->pA + ai + aj*lda;
int ldc = sC->m;
float *pC = sC->pA + ci + cj*ldc;
int ii, jj;
for(jj=0; jj<n; jj++)
{
ii = 0;
for(; ii<m-3; ii+=4)
{
pC[ii+0+jj*ldc] += alpha*pA[ii+0+jj*lda];
pC[ii+1+jj*ldc] += alpha*pA[ii+1+jj*lda];
pC[ii+2+jj*ldc] += alpha*pA[ii+2+jj*lda];
pC[ii+3+jj*ldc] += alpha*pA[ii+3+jj*lda];
}
for(; ii<m; ii++)
{
pC[ii+0+jj*ldc] += alpha*pA[ii+0+jj*lda];
}
}
return;
}
// scales and adds a strvec into a strvec
void svecad_libstr(int m, float alpha, struct s_strvec *sa, int ai, struct s_strvec *sc, int ci)
{
float *pa = sa->pa + ai;
float *pc = sc->pa + ci;
int ii;
ii = 0;
for(; ii<m-3; ii+=4)
{
pc[ii+0] += alpha*pa[ii+0];
pc[ii+1] += alpha*pa[ii+1];
pc[ii+2] += alpha*pa[ii+2];
pc[ii+3] += alpha*pa[ii+3];
}
for(; ii<m; ii++)
{
pc[ii+0] += alpha*pa[ii+0];
}
return;
}
// copy and transpose a generic strmat into a generic strmat
void sgetr_libstr(int m, int n, struct s_strmat *sA, int ai, int aj, struct s_strmat *sC, int ci, int cj)
{
int lda = sA->m;
float *pA = sA->pA + ai + aj*lda;
int ldc = sC->m;
float *pC = sC->pA + ci + cj*ldc;
int ii, jj;
for(jj=0; jj<n; jj++)
{
ii = 0;
for(; ii<m-3; ii+=4)
{
pC[jj+(ii+0)*ldc] = pA[ii+0+jj*lda];
pC[jj+(ii+1)*ldc] = pA[ii+1+jj*lda];
pC[jj+(ii+2)*ldc] = pA[ii+2+jj*lda];
pC[jj+(ii+3)*ldc] = pA[ii+3+jj*lda];
}
for(; ii<m; ii++)
{
pC[jj+(ii+0)*ldc] = pA[ii+0+jj*lda];
}
}
return;
}
// copy and transpose a lower triangular strmat into an upper triangular strmat
void strtr_l_libstr(int m, struct s_strmat *sA, int ai, int aj, struct s_strmat *sC, int ci, int cj)
{
int lda = sA->m;
float *pA = sA->pA + ai + aj*lda;
int ldc = sC->m;
float *pC = sC->pA + ci + cj*ldc;
int ii, jj;
for(jj=0; jj<m; jj++)
{
ii = jj;
for(; ii<m; ii++)
{
pC[jj+(ii+0)*ldc] = pA[ii+0+jj*lda];
}
}
return;
}
// copy and transpose an upper triangular strmat into a lower triangular strmat
void strtr_u_libstr(int m, struct s_strmat *sA, int ai, int aj, struct s_strmat *sC, int ci, int cj)
{
int lda = sA->m;
float *pA = sA->pA + ai + aj*lda;
int ldc = sC->m;
float *pC = sC->pA + ci + cj*ldc;
int ii, jj;
for(jj=0; jj<m; jj++)
{
ii = 0;
for(; ii<=jj; ii++)
{
pC[jj+(ii+0)*ldc] = pA[ii+0+jj*lda];
}
}
return;
}
// insert a strvec to the diagonal of a strmat, sparse formulation
void sdiain_sp_libstr(int kmax, float alpha, struct s_strvec *sx, int xi, int *idx, struct s_strmat *sD, int di, int dj)
{
float *x = sx->pa + xi;
int ldd = sD->m;
float *pD = sD->pA + di + dj*ldd;
int ii, jj;
for(jj=0; jj<kmax; jj++)
{
ii = idx[jj];
pD[ii*(ldd+1)] = alpha * x[jj];
}
return;
}
// extract the diagonal of a strmat from a strvec , sparse formulation
void sdiaex_sp_libstr(int kmax, float alpha, int *idx, struct s_strmat *sD, int di, int dj, struct s_strvec *sx, int xi)
{
float *x = sx->pa + xi;
int ldd = sD->m;
float *pD = sD->pA + di + dj*ldd;
int ii, jj;
for(jj=0; jj<kmax; jj++)
{
ii = idx[jj];
x[jj] = alpha * pD[ii*(ldd+1)];
}
return;
}
// add a vector to diagonal
void sdiaad_libstr(int kmax, float alpha, struct s_strvec *sx, int xi, struct s_strmat *sA, int ai, int aj)
{
int lda = sA->m;
float *pA = sA->pA + ai + aj*lda;
float *x = sx->pa + xi;
int ii;
for(ii=0; ii<kmax; ii++)
pA[ii*(lda+1)] += alpha*x[ii];
return;
}
// add scaled strvec to another strvec and insert to diagonal of strmat, sparse formulation
void sdiaad_sp_libstr(int kmax, float alpha, struct s_strvec *sx, int xi, int *idx, struct s_strmat *sD, int di, int dj)
{
float *x = sx->pa + xi;
int ldd = sD->m;
float *pD = sD->pA + di + dj*ldd;
int ii, jj;
for(jj=0; jj<kmax; jj++)
{
ii = idx[jj];
pD[ii*(ldd+1)] += alpha * x[jj];
}
return;
}
// add scaled strvec to another strvec and insert to diagonal of strmat, sparse formulation
void sdiaadin_sp_libstr(int kmax, float alpha, struct s_strvec *sx, int xi, struct s_strvec *sy, int yi, int *idx, struct s_strmat *sD, int di, int dj)
{
float *x = sx->pa + xi;
float *y = sy->pa + yi;
int ldd = sD->m;
float *pD = sD->pA + di + dj*ldd;
int ii, jj;
for(jj=0; jj<kmax; jj++)
{
ii = idx[jj];
pD[ii*(ldd+1)] = y[jj] + alpha * x[jj];
}
return;
}
// add scaled strvec to row of strmat, sparse formulation
void srowad_sp_libstr(int kmax, float alpha, struct s_strvec *sx, int xi, int *idx, struct s_strmat *sD, int di, int dj)
{
float *x = sx->pa + xi;
int ldd = sD->m;
float *pD = sD->pA + di + dj*ldd;
int ii, jj;
for(jj=0; jj<kmax; jj++)
{
ii = idx[jj];
pD[ii*ldd] += alpha * x[jj];
}
return;
}
void svecad_sp_libstr(int m, float alpha, struct s_strvec *sx, int xi, int *idx, struct s_strvec *sz, int zi)
{
float *x = sx->pa + xi;
float *z = sz->pa + zi;
int ii;
for(ii=0; ii<m; ii++)
z[idx[ii]] += alpha * x[ii];
return;
}
void svecin_sp_libstr(int m, float alpha, struct s_strvec *sx, int xi, int *idx, struct s_strvec *sz, int zi)
{
float *x = sx->pa + xi;
float *z = sz->pa + zi;
int ii;
for(ii=0; ii<m; ii++)
z[idx[ii]] = alpha * x[ii];
return;
}
void svecex_sp_libstr(int m, float alpha, int *idx, struct s_strvec *sx, int xi, struct s_strvec *sz, int zi)
{
float *x = sx->pa + xi;
float *z = sz->pa + zi;
int ii;
for(ii=0; ii<m; ii++)
z[ii] = alpha * x[idx[ii]];
return;
}
// clip without mask return
void sveccl_libstr(int m, struct s_strvec *sxm, int xim, struct s_strvec *sx, int xi, struct s_strvec *sxp, int xip, struct s_strvec *sz, int zi)
{
float *xm = sxm->pa + xim;
float *x = sx->pa + xi;
float *xp = sxp->pa + xip;
float *z = sz->pa + zi;
int ii;
for(ii=0; ii<m; ii++)
{
if(x[ii]>=xp[ii])
{
z[ii] = xp[ii];
}
else if(x[ii]<=xm[ii])
{
z[ii] = xm[ii];
}
else
{
z[ii] = x[ii];
}
}
return;
}
// clip with mask return
void sveccl_mask_libstr(int m, struct s_strvec *sxm, int xim, struct s_strvec *sx, int xi, struct s_strvec *sxp, int xip, struct s_strvec *sz, int zi, struct s_strvec *sm, int mi)
{
float *xm = sxm->pa + xim;
float *x = sx->pa + xi;
float *xp = sxp->pa + xip;
float *z = sz->pa + zi;
float *mask = sm->pa + mi;
int ii;
for(ii=0; ii<m; ii++)
{
if(x[ii]>=xp[ii])
{
z[ii] = xp[ii];
mask[ii] = 1.0;
}
else if(x[ii]<=xm[ii])
{
z[ii] = xm[ii];
mask[ii] = -1.0;
}
else
{
z[ii] = x[ii];
mask[ii] = 0.0;
}
}
return;
}
// zero out components using mask
void svecze_libstr(int m, struct s_strvec *sm, int mi, struct s_strvec *sv, int vi, struct s_strvec *se, int ei)
{
float *mask = sm->pa + mi;
float *v = sv->pa + vi;
float *e = se->pa + ei;
int ii;
for(ii=0; ii<m; ii++)
{
if(mask[ii]==0)
{
e[ii] = v[ii];
}
else
{
e[ii] = 0;
}
}
return;
}
void svecnrm_inf_libstr(int m, struct s_strvec *sx, int xi, float *ptr_norm)
{
int ii;
float *x = sx->pa + xi;
float norm = 0.0;
for(ii=0; ii<m; ii++)
norm = fmax(norm, fabs(x[ii]));
*ptr_norm = norm;
return;
}
#else
#error : wrong LA choice
#endif