blob: 978eb9abd0f40bd520f0151fc68606547046df36 [file] [log] [blame]
Austin Schuh9a24b372018-01-28 16:12:29 -08001/**************************************************************************************************
2* *
3* This file is part of BLASFEO. *
4* *
5* BLASFEO -- BLAS For Embedded Optimization. *
6* Copyright (C) 2016-2017 by Gianluca Frison. *
7* Developed at IMTEK (University of Freiburg) under the supervision of Moritz Diehl. *
8* All rights reserved. *
9* *
10* HPMPC is free software; you can redistribute it and/or *
11* modify it under the terms of the GNU Lesser General Public *
12* License as published by the Free Software Foundation; either *
13* version 2.1 of the License, or (at your option) any later version. *
14* *
15* HPMPC is distributed in the hope that it will be useful, *
16* but WITHOUT ANY WARRANTY; without even the implied warranty of *
17* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
18* See the GNU Lesser General Public License for more details. *
19* *
20* You should have received a copy of the GNU Lesser General Public *
21* License along with HPMPC; if not, write to the Free Software *
22* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
23* *
24* Author: Gianluca Frison, giaf (at) dtu.dk *
25* gianluca.frison (at) imtek.uni-freiburg.de *
26* *
27**************************************************************************************************/
28
29#include <stdlib.h>
30#include <stdio.h>
31#include <math.h>
32
33#include "../include/blasfeo_common.h"
34
35
36
37#if defined(LA_REFERENCE) | defined(LA_BLAS)
38
39
40
41// return memory size (in bytes) needed for a strmat
42int s_size_strmat(int m, int n)
43 {
44 int tmp = m<n ? m : n; // al(min(m,n)) // XXX max ???
45 int size = (m*n+tmp)*sizeof(float);
46 return size;
47 }
48
49
50
51// return memory size (in bytes) needed for the diagonal of a strmat
52int s_size_diag_strmat(int m, int n)
53 {
54 int size = 0;
55 int tmp = m<n ? m : n; // al(min(m,n)) // XXX max ???
56 size = tmp*sizeof(float);
57 return size;
58 }
59
60
61
62// create a matrix structure for a matrix of size m*n by using memory passed by a pointer
63void s_create_strmat(int m, int n, struct s_strmat *sA, void *memory)
64 {
65 sA->m = m;
66 sA->n = n;
67 float *ptr = (float *) memory;
68 sA->pA = ptr;
69 ptr += m*n;
70 int tmp = m<n ? m : n; // al(min(m,n)) // XXX max ???
71 sA->dA = ptr;
72 ptr += tmp;
73 sA->use_dA = 0;
74 sA->memory_size = (m*n+tmp)*sizeof(float);
75 return;
76 }
77
78
79
80// return memory size (in bytes) needed for a strvec
81int s_size_strvec(int m)
82 {
83 int size = m*sizeof(float);
84 return size;
85 }
86
87
88
89// create a matrix structure for a matrix of size m*n by using memory passed by a pointer
90void s_create_strvec(int m, struct s_strvec *sa, void *memory)
91 {
92 sa->m = m;
93 float *ptr = (float *) memory;
94 sa->pa = ptr;
95// ptr += m * n;
96 sa->memory_size = m*sizeof(float);
97 return;
98 }
99
100
101
102// convert a matrix into a matrix structure
103void s_cvt_mat2strmat(int m, int n, float *A, int lda, struct s_strmat *sA, int ai, int aj)
104 {
105 int ii, jj;
106 int lda2 = sA->m;
107 float *pA = sA->pA + ai + aj*lda2;
108 for(jj=0; jj<n; jj++)
109 {
110 ii = 0;
111 for(; ii<m-3; ii+=4)
112 {
113 pA[ii+0+jj*lda2] = A[ii+0+jj*lda];
114 pA[ii+1+jj*lda2] = A[ii+1+jj*lda];
115 pA[ii+2+jj*lda2] = A[ii+2+jj*lda];
116 pA[ii+3+jj*lda2] = A[ii+3+jj*lda];
117 }
118 for(; ii<m; ii++)
119 {
120 pA[ii+0+jj*lda2] = A[ii+0+jj*lda];
121 }
122 }
123 return;
124 }
125
126
127
128// convert and transpose a matrix into a matrix structure
129void s_cvt_tran_mat2strmat(int m, int n, float *A, int lda, struct s_strmat *sA, int ai, int aj)
130 {
131 int ii, jj;
132 int lda2 = sA->m;
133 float *pA = sA->pA + ai + aj*lda2;
134 for(jj=0; jj<n; jj++)
135 {
136 ii = 0;
137 for(; ii<m-3; ii+=4)
138 {
139 pA[jj+(ii+0)*lda2] = A[ii+0+jj*lda];
140 pA[jj+(ii+1)*lda2] = A[ii+1+jj*lda];
141 pA[jj+(ii+2)*lda2] = A[ii+2+jj*lda];
142 pA[jj+(ii+3)*lda2] = A[ii+3+jj*lda];
143 }
144 for(; ii<m; ii++)
145 {
146 pA[jj+(ii+0)*lda2] = A[ii+0+jj*lda];
147 }
148 }
149 return;
150 }
151
152
153
154// convert a vector into a vector structure
155void s_cvt_vec2strvec(int m, float *a, struct s_strvec *sa, int ai)
156 {
157 float *pa = sa->pa + ai;
158 int ii;
159 for(ii=0; ii<m; ii++)
160 pa[ii] = a[ii];
161 return;
162 }
163
164
165
166// convert a matrix structure into a matrix
167void s_cvt_strmat2mat(int m, int n, struct s_strmat *sA, int ai, int aj, float *A, int lda)
168 {
169 int ii, jj;
170 int lda2 = sA->m;
171 float *pA = sA->pA + ai + aj*lda2;
172 for(jj=0; jj<n; jj++)
173 {
174 ii = 0;
175 for(; ii<m-3; ii+=4)
176 {
177 A[ii+0+jj*lda] = pA[ii+0+jj*lda2];
178 A[ii+1+jj*lda] = pA[ii+1+jj*lda2];
179 A[ii+2+jj*lda] = pA[ii+2+jj*lda2];
180 A[ii+3+jj*lda] = pA[ii+3+jj*lda2];
181 }
182 for(; ii<m; ii++)
183 {
184 A[ii+0+jj*lda] = pA[ii+0+jj*lda2];
185 }
186 }
187 return;
188 }
189
190
191
192// convert and transpose a matrix structure into a matrix
193void s_cvt_tran_strmat2mat(int m, int n, struct s_strmat *sA, int ai, int aj, float *A, int lda)
194 {
195 int ii, jj;
196 int lda2 = sA->m;
197 float *pA = sA->pA + ai + aj*lda2;
198 for(jj=0; jj<n; jj++)
199 {
200 ii = 0;
201 for(; ii<m-3; ii+=4)
202 {
203 A[jj+(ii+0)*lda] = pA[ii+0+jj*lda2];
204 A[jj+(ii+1)*lda] = pA[ii+1+jj*lda2];
205 A[jj+(ii+2)*lda] = pA[ii+2+jj*lda2];
206 A[jj+(ii+3)*lda] = pA[ii+3+jj*lda2];
207 }
208 for(; ii<m; ii++)
209 {
210 A[jj+(ii+0)*lda] = pA[ii+0+jj*lda2];
211 }
212 }
213 return;
214 }
215
216
217
218// convert a vector structure into a vector
219void s_cvt_strvec2vec(int m, struct s_strvec *sa, int ai, float *a)
220 {
221 float *pa = sa->pa + ai;
222 int ii;
223 for(ii=0; ii<m; ii++)
224 a[ii] = pa[ii];
225 return;
226 }
227
228
229
230// cast a matrix into a matrix structure
231void s_cast_mat2strmat(float *A, struct s_strmat *sA)
232 {
233 sA->pA = A;
234 return;
235 }
236
237
238
239// cast a matrix into the diagonal of a matrix structure
240void s_cast_diag_mat2strmat(float *dA, struct s_strmat *sA)
241 {
242 sA->dA = dA;
243 return;
244 }
245
246
247
248// cast a vector into a vector structure
249void s_cast_vec2vecmat(float *a, struct s_strvec *sa)
250 {
251 sa->pa = a;
252 return;
253 }
254
255
256
257// insert element into strmat
258void sgein1_libstr(float a, struct s_strmat *sA, int ai, int aj)
259 {
260 int lda = sA->m;
261 float *pA = sA->pA + ai + aj*lda;
262 pA[0] = a;
263 return;
264 }
265
266
267
268// extract element from strmat
269float sgeex1_libstr(struct s_strmat *sA, int ai, int aj)
270 {
271 int lda = sA->m;
272 float *pA = sA->pA + ai + aj*lda;
273 return pA[0];
274 }
275
276
277
278// insert element into strvec
279void svecin1_libstr(float a, struct s_strvec *sx, int xi)
280 {
281 float *x = sx->pa + xi;
282 x[0] = a;
283 return;
284 }
285
286
287
288// extract element from strvec
289float svecex1_libstr(struct s_strvec *sx, int xi)
290 {
291 float *x = sx->pa + xi;
292 return x[0];
293 }
294
295
296
297// set all elements of a strmat to a value
298void sgese_libstr(int m, int n, float alpha, struct s_strmat *sA, int ai, int aj)
299 {
300 int lda = sA->m;
301 float *pA = sA->pA + ai + aj*lda;
302 int ii, jj;
303 for(jj=0; jj<n; jj++)
304 {
305 for(ii=0; ii<m; ii++)
306 {
307 pA[ii+lda*jj] = alpha;
308 }
309 }
310 return;
311 }
312
313
314
315// set all elements of a strvec to a value
316void svecse_libstr(int m, float alpha, struct s_strvec *sx, int xi)
317 {
318 float *x = sx->pa + xi;
319 int ii;
320 for(ii=0; ii<m; ii++)
321 x[ii] = alpha;
322 return;
323 }
324
325
326
327// extract diagonal to vector
328void sdiaex_libstr(int kmax, float alpha, struct s_strmat *sA, int ai, int aj, struct s_strvec *sx, int xi)
329 {
330 int lda = sA->m;
331 float *pA = sA->pA + ai + aj*lda;
332 float *x = sx->pa + xi;
333 int ii;
334 for(ii=0; ii<kmax; ii++)
335 x[ii] = alpha*pA[ii*(lda+1)];
336 return;
337 }
338
339
340
341// insert a vector into diagonal
342void sdiain_libstr(int kmax, float alpha, struct s_strvec *sx, int xi, struct s_strmat *sA, int ai, int aj)
343 {
344 int lda = sA->m;
345 float *pA = sA->pA + ai + aj*lda;
346 float *x = sx->pa + xi;
347 int ii;
348 for(ii=0; ii<kmax; ii++)
349 pA[ii*(lda+1)] = alpha*x[ii];
350 return;
351 }
352
353
354
355// extract a row into a vector
356void srowex_libstr(int kmax, float alpha, struct s_strmat *sA, int ai, int aj, struct s_strvec *sx, int xi)
357 {
358 int lda = sA->m;
359 float *pA = sA->pA + ai + aj*lda;
360 float *x = sx->pa + xi;
361 int ii;
362 for(ii=0; ii<kmax; ii++)
363 x[ii] = alpha*pA[ii*lda];
364 return;
365 }
366
367
368
369// insert a vector into a row
370void srowin_libstr(int kmax, float alpha, struct s_strvec *sx, int xi, struct s_strmat *sA, int ai, int aj)
371 {
372 int lda = sA->m;
373 float *pA = sA->pA + ai + aj*lda;
374 float *x = sx->pa + xi;
375 int ii;
376 for(ii=0; ii<kmax; ii++)
377 pA[ii*lda] = alpha*x[ii];
378 return;
379 }
380
381
382
383// add a vector to a row
384void srowad_libstr(int kmax, float alpha, struct s_strvec *sx, int xi, struct s_strmat *sA, int ai, int aj)
385 {
386 int lda = sA->m;
387 float *pA = sA->pA + ai + aj*lda;
388 float *x = sx->pa + xi;
389 int ii;
390 for(ii=0; ii<kmax; ii++)
391 pA[ii*lda] += alpha*x[ii];
392 return;
393 }
394
395
396
397// swap two rows of a matrix struct
398void srowsw_libstr(int kmax, struct s_strmat *sA, int ai, int aj, struct s_strmat *sC, int ci, int cj)
399 {
400 int lda = sA->m;
401 float *pA = sA->pA + ai + aj*lda;
402 int ldc = sC->m;
403 float *pC = sC->pA + ci + cj*lda;
404 int ii;
405 float tmp;
406 for(ii=0; ii<kmax; ii++)
407 {
408 tmp = pA[ii*lda];
409 pA[ii*lda] = pC[ii*ldc];
410 pC[ii*ldc] = tmp;
411 }
412 return;
413 }
414
415
416
417// permute the rows of a matrix struct
418void srowpe_libstr(int kmax, int *ipiv, struct s_strmat *sA)
419 {
420 int ii;
421 for(ii=0; ii<kmax; ii++)
422 {
423 if(ipiv[ii]!=ii)
424 srowsw_libstr(sA->n, sA, ii, 0, sA, ipiv[ii], 0);
425 }
426 return;
427 }
428
429
430
431// insert a vector into a rcol
432void scolin_libstr(int kmax, struct s_strvec *sx, int xi, struct s_strmat *sA, int ai, int aj)
433 {
434 int lda = sA->m;
435 float *pA = sA->pA + ai + aj*lda;
436 float *x = sx->pa + xi;
437 int ii;
438 for(ii=0; ii<kmax; ii++)
439 pA[ii] = x[ii];
440 return;
441 }
442
443
444
445// swap two cols of a matrix struct
446void scolsw_libstr(int kmax, struct s_strmat *sA, int ai, int aj, struct s_strmat *sC, int ci, int cj)
447 {
448 int lda = sA->m;
449 float *pA = sA->pA + ai + aj*lda;
450 int ldc = sC->m;
451 float *pC = sC->pA + ci + cj*lda;
452 int ii;
453 float tmp;
454 for(ii=0; ii<kmax; ii++)
455 {
456 tmp = pA[ii];
457 pA[ii] = pC[ii];
458 pC[ii] = tmp;
459 }
460 return;
461 }
462
463
464
465// permute the cols of a matrix struct
466void scolpe_libstr(int kmax, int *ipiv, struct s_strmat *sA)
467 {
468 int ii;
469 for(ii=0; ii<kmax; ii++)
470 {
471 if(ipiv[ii]!=ii)
472 scolsw_libstr(sA->m, sA, 0, ii, sA, 0, ipiv[ii]);
473 }
474 return;
475 }
476
477
478
479// copy a generic strmat into a generic strmat
480void sgecp_libstr(int m, int n, struct s_strmat *sA, int ai, int aj, struct s_strmat *sC, int ci, int cj)
481 {
482 int lda = sA->m;
483 float *pA = sA->pA + ai + aj*lda;
484 int ldc = sC->m;
485 float *pC = sC->pA + ci + cj*ldc;
486 int ii, jj;
487 for(jj=0; jj<n; jj++)
488 {
489 ii = 0;
490 for(; ii<m-3; ii+=4)
491 {
492 pC[ii+0+jj*ldc] = pA[ii+0+jj*lda];
493 pC[ii+1+jj*ldc] = pA[ii+1+jj*lda];
494 pC[ii+2+jj*ldc] = pA[ii+2+jj*lda];
495 pC[ii+3+jj*ldc] = pA[ii+3+jj*lda];
496 }
497 for(; ii<m; ii++)
498 {
499 pC[ii+0+jj*ldc] = pA[ii+0+jj*lda];
500 }
501 }
502 return;
503 }
504
505
506
507// scale a generic strmat
508void sgesc_libstr(int m, int n, float alpha, struct s_strmat *sA, int ai, int aj)
509 {
510 int lda = sA->m;
511 float *pA = sA->pA + ai + aj*lda;
512 int ii, jj;
513 for(jj=0; jj<n; jj++)
514 {
515 ii = 0;
516 for(; ii<m-3; ii+=4)
517 {
518 pA[ii+0+jj*lda] *= alpha;
519 pA[ii+1+jj*lda] *= alpha;
520 pA[ii+2+jj*lda] *= alpha;
521 pA[ii+3+jj*lda] *= alpha;
522 }
523 for(; ii<m; ii++)
524 {
525 pA[ii+0+jj*lda] *= alpha;
526 }
527 }
528 return;
529 }
530
531
532
533// copy a strvec into a strvec
534void sveccp_libstr(int m, struct s_strvec *sa, int ai, struct s_strvec *sc, int ci)
535 {
536 float *pa = sa->pa + ai;
537 float *pc = sc->pa + ci;
538 int ii;
539 ii = 0;
540 for(; ii<m-3; ii+=4)
541 {
542 pc[ii+0] = pa[ii+0];
543 pc[ii+1] = pa[ii+1];
544 pc[ii+2] = pa[ii+2];
545 pc[ii+3] = pa[ii+3];
546 }
547 for(; ii<m; ii++)
548 {
549 pc[ii+0] = pa[ii+0];
550 }
551 return;
552 }
553
554
555
556// scale a strvec
557void svecsc_libstr(int m, float alpha, struct s_strvec *sa, int ai)
558 {
559 float *pa = sa->pa + ai;
560 int ii;
561 ii = 0;
562 for(; ii<m-3; ii+=4)
563 {
564 pa[ii+0] *= alpha;
565 pa[ii+1] *= alpha;
566 pa[ii+2] *= alpha;
567 pa[ii+3] *= alpha;
568 }
569 for(; ii<m; ii++)
570 {
571 pa[ii+0] *= alpha;
572 }
573 return;
574 }
575
576
577
578// copy a lower triangular strmat into a lower triangular strmat
579void strcp_l_libstr(int m, struct s_strmat *sA, int ai, int aj, struct s_strmat *sC, int ci, int cj)
580 {
581 int lda = sA->m;
582 float *pA = sA->pA + ai + aj*lda;
583 int ldc = sC->m;
584 float *pC = sC->pA + ci + cj*ldc;
585 int ii, jj;
586 for(jj=0; jj<m; jj++)
587 {
588 ii = jj;
589 for(; ii<m; ii++)
590 {
591 pC[ii+0+jj*ldc] = pA[ii+0+jj*lda];
592 }
593 }
594 return;
595 }
596
597
598
599// scale and add a generic strmat into a generic strmat
600void sgead_libstr(int m, int n, float alpha, struct s_strmat *sA, int ai, int aj, struct s_strmat *sC, int ci, int cj)
601 {
602 int lda = sA->m;
603 float *pA = sA->pA + ai + aj*lda;
604 int ldc = sC->m;
605 float *pC = sC->pA + ci + cj*ldc;
606 int ii, jj;
607 for(jj=0; jj<n; jj++)
608 {
609 ii = 0;
610 for(; ii<m-3; ii+=4)
611 {
612 pC[ii+0+jj*ldc] += alpha*pA[ii+0+jj*lda];
613 pC[ii+1+jj*ldc] += alpha*pA[ii+1+jj*lda];
614 pC[ii+2+jj*ldc] += alpha*pA[ii+2+jj*lda];
615 pC[ii+3+jj*ldc] += alpha*pA[ii+3+jj*lda];
616 }
617 for(; ii<m; ii++)
618 {
619 pC[ii+0+jj*ldc] += alpha*pA[ii+0+jj*lda];
620 }
621 }
622 return;
623 }
624
625
626
627// scales and adds a strvec into a strvec
628void svecad_libstr(int m, float alpha, struct s_strvec *sa, int ai, struct s_strvec *sc, int ci)
629 {
630 float *pa = sa->pa + ai;
631 float *pc = sc->pa + ci;
632 int ii;
633 ii = 0;
634 for(; ii<m-3; ii+=4)
635 {
636 pc[ii+0] += alpha*pa[ii+0];
637 pc[ii+1] += alpha*pa[ii+1];
638 pc[ii+2] += alpha*pa[ii+2];
639 pc[ii+3] += alpha*pa[ii+3];
640 }
641 for(; ii<m; ii++)
642 {
643 pc[ii+0] += alpha*pa[ii+0];
644 }
645 return;
646 }
647
648
649
650// copy and transpose a generic strmat into a generic strmat
651void sgetr_libstr(int m, int n, struct s_strmat *sA, int ai, int aj, struct s_strmat *sC, int ci, int cj)
652 {
653 int lda = sA->m;
654 float *pA = sA->pA + ai + aj*lda;
655 int ldc = sC->m;
656 float *pC = sC->pA + ci + cj*ldc;
657 int ii, jj;
658 for(jj=0; jj<n; jj++)
659 {
660 ii = 0;
661 for(; ii<m-3; ii+=4)
662 {
663 pC[jj+(ii+0)*ldc] = pA[ii+0+jj*lda];
664 pC[jj+(ii+1)*ldc] = pA[ii+1+jj*lda];
665 pC[jj+(ii+2)*ldc] = pA[ii+2+jj*lda];
666 pC[jj+(ii+3)*ldc] = pA[ii+3+jj*lda];
667 }
668 for(; ii<m; ii++)
669 {
670 pC[jj+(ii+0)*ldc] = pA[ii+0+jj*lda];
671 }
672 }
673 return;
674 }
675
676
677
678// copy and transpose a lower triangular strmat into an upper triangular strmat
679void strtr_l_libstr(int m, struct s_strmat *sA, int ai, int aj, struct s_strmat *sC, int ci, int cj)
680 {
681 int lda = sA->m;
682 float *pA = sA->pA + ai + aj*lda;
683 int ldc = sC->m;
684 float *pC = sC->pA + ci + cj*ldc;
685 int ii, jj;
686 for(jj=0; jj<m; jj++)
687 {
688 ii = jj;
689 for(; ii<m; ii++)
690 {
691 pC[jj+(ii+0)*ldc] = pA[ii+0+jj*lda];
692 }
693 }
694 return;
695 }
696
697
698
699// copy and transpose an upper triangular strmat into a lower triangular strmat
700void strtr_u_libstr(int m, struct s_strmat *sA, int ai, int aj, struct s_strmat *sC, int ci, int cj)
701 {
702 int lda = sA->m;
703 float *pA = sA->pA + ai + aj*lda;
704 int ldc = sC->m;
705 float *pC = sC->pA + ci + cj*ldc;
706 int ii, jj;
707 for(jj=0; jj<m; jj++)
708 {
709 ii = 0;
710 for(; ii<=jj; ii++)
711 {
712 pC[jj+(ii+0)*ldc] = pA[ii+0+jj*lda];
713 }
714 }
715 return;
716 }
717
718
719
720// insert a strvec to the diagonal of a strmat, sparse formulation
721void sdiain_sp_libstr(int kmax, float alpha, struct s_strvec *sx, int xi, int *idx, struct s_strmat *sD, int di, int dj)
722 {
723 float *x = sx->pa + xi;
724 int ldd = sD->m;
725 float *pD = sD->pA + di + dj*ldd;
726 int ii, jj;
727 for(jj=0; jj<kmax; jj++)
728 {
729 ii = idx[jj];
730 pD[ii*(ldd+1)] = alpha * x[jj];
731 }
732 return;
733 }
734
735
736
737// extract the diagonal of a strmat from a strvec , sparse formulation
738void sdiaex_sp_libstr(int kmax, float alpha, int *idx, struct s_strmat *sD, int di, int dj, struct s_strvec *sx, int xi)
739 {
740 float *x = sx->pa + xi;
741 int ldd = sD->m;
742 float *pD = sD->pA + di + dj*ldd;
743 int ii, jj;
744 for(jj=0; jj<kmax; jj++)
745 {
746 ii = idx[jj];
747 x[jj] = alpha * pD[ii*(ldd+1)];
748 }
749 return;
750 }
751
752
753
754// add a vector to diagonal
755void sdiaad_libstr(int kmax, float alpha, struct s_strvec *sx, int xi, struct s_strmat *sA, int ai, int aj)
756 {
757 int lda = sA->m;
758 float *pA = sA->pA + ai + aj*lda;
759 float *x = sx->pa + xi;
760 int ii;
761 for(ii=0; ii<kmax; ii++)
762 pA[ii*(lda+1)] += alpha*x[ii];
763 return;
764 }
765
766
767
768// add scaled strvec to another strvec and insert to diagonal of strmat, sparse formulation
769void sdiaad_sp_libstr(int kmax, float alpha, struct s_strvec *sx, int xi, int *idx, struct s_strmat *sD, int di, int dj)
770 {
771 float *x = sx->pa + xi;
772 int ldd = sD->m;
773 float *pD = sD->pA + di + dj*ldd;
774 int ii, jj;
775 for(jj=0; jj<kmax; jj++)
776 {
777 ii = idx[jj];
778 pD[ii*(ldd+1)] += alpha * x[jj];
779 }
780 return;
781 }
782
783
784
785// add scaled strvec to another strvec and insert to diagonal of strmat, sparse formulation
786void 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)
787 {
788 float *x = sx->pa + xi;
789 float *y = sy->pa + yi;
790 int ldd = sD->m;
791 float *pD = sD->pA + di + dj*ldd;
792 int ii, jj;
793 for(jj=0; jj<kmax; jj++)
794 {
795 ii = idx[jj];
796 pD[ii*(ldd+1)] = y[jj] + alpha * x[jj];
797 }
798 return;
799 }
800
801
802
803// add scaled strvec to row of strmat, sparse formulation
804void srowad_sp_libstr(int kmax, float alpha, struct s_strvec *sx, int xi, int *idx, struct s_strmat *sD, int di, int dj)
805 {
806 float *x = sx->pa + xi;
807 int ldd = sD->m;
808 float *pD = sD->pA + di + dj*ldd;
809 int ii, jj;
810 for(jj=0; jj<kmax; jj++)
811 {
812 ii = idx[jj];
813 pD[ii*ldd] += alpha * x[jj];
814 }
815 return;
816 }
817
818
819
820
821void svecad_sp_libstr(int m, float alpha, struct s_strvec *sx, int xi, int *idx, struct s_strvec *sz, int zi)
822 {
823 float *x = sx->pa + xi;
824 float *z = sz->pa + zi;
825 int ii;
826 for(ii=0; ii<m; ii++)
827 z[idx[ii]] += alpha * x[ii];
828 return;
829 }
830
831
832
833void svecin_sp_libstr(int m, float alpha, struct s_strvec *sx, int xi, int *idx, struct s_strvec *sz, int zi)
834 {
835 float *x = sx->pa + xi;
836 float *z = sz->pa + zi;
837 int ii;
838 for(ii=0; ii<m; ii++)
839 z[idx[ii]] = alpha * x[ii];
840 return;
841 }
842
843
844
845void svecex_sp_libstr(int m, float alpha, int *idx, struct s_strvec *sx, int xi, struct s_strvec *sz, int zi)
846 {
847 float *x = sx->pa + xi;
848 float *z = sz->pa + zi;
849 int ii;
850 for(ii=0; ii<m; ii++)
851 z[ii] = alpha * x[idx[ii]];
852 return;
853 }
854
855
856// clip without mask return
857void 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)
858 {
859 float *xm = sxm->pa + xim;
860 float *x = sx->pa + xi;
861 float *xp = sxp->pa + xip;
862 float *z = sz->pa + zi;
863 int ii;
864 for(ii=0; ii<m; ii++)
865 {
866 if(x[ii]>=xp[ii])
867 {
868 z[ii] = xp[ii];
869 }
870 else if(x[ii]<=xm[ii])
871 {
872 z[ii] = xm[ii];
873 }
874 else
875 {
876 z[ii] = x[ii];
877 }
878 }
879 return;
880 }
881
882
883
884// clip with mask return
885void 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)
886 {
887 float *xm = sxm->pa + xim;
888 float *x = sx->pa + xi;
889 float *xp = sxp->pa + xip;
890 float *z = sz->pa + zi;
891 float *mask = sm->pa + mi;
892 int ii;
893 for(ii=0; ii<m; ii++)
894 {
895 if(x[ii]>=xp[ii])
896 {
897 z[ii] = xp[ii];
898 mask[ii] = 1.0;
899 }
900 else if(x[ii]<=xm[ii])
901 {
902 z[ii] = xm[ii];
903 mask[ii] = -1.0;
904 }
905 else
906 {
907 z[ii] = x[ii];
908 mask[ii] = 0.0;
909 }
910 }
911 return;
912 }
913
914
915// zero out components using mask
916void svecze_libstr(int m, struct s_strvec *sm, int mi, struct s_strvec *sv, int vi, struct s_strvec *se, int ei)
917 {
918 float *mask = sm->pa + mi;
919 float *v = sv->pa + vi;
920 float *e = se->pa + ei;
921 int ii;
922 for(ii=0; ii<m; ii++)
923 {
924 if(mask[ii]==0)
925 {
926 e[ii] = v[ii];
927 }
928 else
929 {
930 e[ii] = 0;
931 }
932 }
933 return;
934 }
935
936
937
938void svecnrm_inf_libstr(int m, struct s_strvec *sx, int xi, float *ptr_norm)
939 {
940 int ii;
941 float *x = sx->pa + xi;
942 float norm = 0.0;
943 for(ii=0; ii<m; ii++)
944 norm = fmax(norm, fabs(x[ii]));
945 *ptr_norm = norm;
946 return;
947 }
948
949
950
951#else
952
953#error : wrong LA choice
954
955#endif
956