2 * -----------------------------------------------------------------
4 * $Date: 2006/07/05 15:32:37 $
5 * -----------------------------------------------------------------
6 * Programmer(s): Scott D. Cohen, Alan C. Hindmarsh, Radu Serban,
7 * and Aaron Collier @ LLNL
8 * -----------------------------------------------------------------
9 * Copyright (c) 2002, The Regents of the University of California.
10 * Produced at the Lawrence Livermore National Laboratory.
11 * All rights reserved.
12 * For details, see the LICENSE file.
13 * -----------------------------------------------------------------
14 * This is the implementation file for a serial implementation
15 * of the NVECTOR package.
16 * -----------------------------------------------------------------
22 #include <nvector/nvector_serial.h>
23 #include <sundials/sundials_math.h>
25 #define ZERO RCONST(0.0)
26 #define HALF RCONST(0.5)
27 #define ONE RCONST(1.0)
28 #define ONEPT5 RCONST(1.5)
30 /* Private function prototypes */
32 static void VCopy_Serial(N_Vector x, N_Vector z);
34 static void VSum_Serial(N_Vector x, N_Vector y, N_Vector z);
36 static void VDiff_Serial(N_Vector x, N_Vector y, N_Vector z);
38 static void VNeg_Serial(N_Vector x, N_Vector z);
40 static void VScaleSum_Serial(realtype c, N_Vector x, N_Vector y, N_Vector z);
42 static void VScaleDiff_Serial(realtype c, N_Vector x, N_Vector y, N_Vector z);
44 static void VLin1_Serial(realtype a, N_Vector x, N_Vector y, N_Vector z);
46 static void VLin2_Serial(realtype a, N_Vector x, N_Vector y, N_Vector z);
48 static void Vaxpy_Serial(realtype a, N_Vector x, N_Vector y);
50 static void VScaleBy_Serial(realtype a, N_Vector x);
53 * -----------------------------------------------------------------
55 * -----------------------------------------------------------------
58 /* ----------------------------------------------------------------------------
59 * Function to create a new empty serial vector
62 N_Vector N_VNewEmpty_Serial(long int length)
66 N_VectorContent_Serial content;
70 v = (N_Vector) malloc(sizeof *v);
71 if (v == NULL) return(NULL);
73 /* Create vector operation structure */
75 ops = (N_Vector_Ops) malloc(sizeof(struct _generic_N_Vector_Ops));
76 if (ops == NULL) { free(v); return(NULL); }
78 ops->nvclone = N_VClone_Serial;
79 ops->nvcloneempty = N_VCloneEmpty_Serial;
80 ops->nvdestroy = N_VDestroy_Serial;
81 ops->nvspace = N_VSpace_Serial;
82 ops->nvgetarraypointer = N_VGetArrayPointer_Serial;
83 ops->nvsetarraypointer = N_VSetArrayPointer_Serial;
84 ops->nvlinearsum = N_VLinearSum_Serial;
85 ops->nvconst = N_VConst_Serial;
86 ops->nvprod = N_VProd_Serial;
87 ops->nvdiv = N_VDiv_Serial;
88 ops->nvscale = N_VScale_Serial;
89 ops->nvabs = N_VAbs_Serial;
90 ops->nvinv = N_VInv_Serial;
91 ops->nvaddconst = N_VAddConst_Serial;
92 ops->nvdotprod = N_VDotProd_Serial;
93 ops->nvmaxnorm = N_VMaxNorm_Serial;
94 ops->nvwrmsnormmask = N_VWrmsNormMask_Serial;
95 ops->nvwrmsnorm = N_VWrmsNorm_Serial;
96 ops->nvmin = N_VMin_Serial;
97 ops->nvwl2norm = N_VWL2Norm_Serial;
98 ops->nvl1norm = N_VL1Norm_Serial;
99 ops->nvcompare = N_VCompare_Serial;
100 ops->nvinvtest = N_VInvTest_Serial;
101 ops->nvconstrmask = N_VConstrMask_Serial;
102 ops->nvminquotient = N_VMinQuotient_Serial;
106 content = (N_VectorContent_Serial) malloc(sizeof(struct _N_VectorContent_Serial));
107 if (content == NULL) { free(ops); free(v); return(NULL); }
109 content->length = length;
110 content->own_data = FALSE;
111 content->data = NULL;
113 /* Attach content and ops */
114 v->content = content;
120 /* ----------------------------------------------------------------------------
121 * Function to create a new serial vector
124 N_Vector N_VNew_Serial(long int length)
130 v = N_VNewEmpty_Serial(length);
131 if (v == NULL) return(NULL);
136 /* Allocate memory */
138 data = (realtype *) malloc(length * sizeof(realtype));
139 if(data == NULL) { N_VDestroy_Serial(v); return(NULL); }
142 NV_OWN_DATA_S(v) = TRUE;
150 /* ----------------------------------------------------------------------------
151 * Function to create a serial N_Vector with user data component
154 N_Vector N_VMake_Serial(long int length, realtype *v_data)
159 v = N_VNewEmpty_Serial(length);
160 if (v == NULL) return(NULL);
164 NV_OWN_DATA_S(v) = FALSE;
165 NV_DATA_S(v) = v_data;
171 /* ----------------------------------------------------------------------------
172 * Function to create an array of new serial vectors.
175 N_Vector *N_VCloneVectorArray_Serial(int count, N_Vector w)
180 if (count <= 0) return(NULL);
183 vs = (N_Vector *) malloc(count * sizeof(N_Vector));
184 if(vs == NULL) return(NULL);
186 for (j = 0; j < count; j++) {
188 vs[j] = N_VClone_Serial(w);
190 N_VDestroyVectorArray_Serial(vs, j-1);
198 /* ----------------------------------------------------------------------------
199 * Function to create an array of new serial vectors with NULL data array.
202 N_Vector *N_VCloneVectorArrayEmpty_Serial(int count, N_Vector w)
207 if (count <= 0) return(NULL);
210 vs = (N_Vector *) malloc(count * sizeof(N_Vector));
211 if(vs == NULL) return(NULL);
213 for (j = 0; j < count; j++) {
215 vs[j] = N_VCloneEmpty_Serial(w);
217 N_VDestroyVectorArray_Serial(vs, j-1);
225 /* ----------------------------------------------------------------------------
226 * Function to free an array created with N_VCloneVectorArray_Serial
229 void N_VDestroyVectorArray_Serial(N_Vector *vs, int count)
233 for (j = 0; j < count; j++) N_VDestroy_Serial(vs[j]);
240 /* ----------------------------------------------------------------------------
241 * Function to print the a serial vector
244 void N_VPrint_Serial(N_Vector x)
254 for (i = 0; i < N; i++) {
255 #if defined(SUNDIALS_EXTENDED_PRECISION)
256 printf("%11.8Lg\n", xd[i]);
257 #elif defined(SUNDIALS_DOUBLE_PRECISION)
258 printf("%11.8lg\n", xd[i]);
260 printf("%11.8g\n", xd[i]);
269 * -----------------------------------------------------------------
270 * implementation of vector operations
271 * -----------------------------------------------------------------
274 N_Vector N_VCloneEmpty_Serial(N_Vector w)
278 N_VectorContent_Serial content;
280 if (w == NULL) return(NULL);
284 v = (N_Vector) malloc(sizeof *v);
285 if (v == NULL) return(NULL);
287 /* Create vector operation structure */
289 ops = (N_Vector_Ops) malloc(sizeof(struct _generic_N_Vector_Ops));
290 if (ops == NULL) { free(v); return(NULL); }
292 ops->nvclone = w->ops->nvclone;
293 ops->nvcloneempty = w->ops->nvcloneempty;
294 ops->nvdestroy = w->ops->nvdestroy;
295 ops->nvspace = w->ops->nvspace;
296 ops->nvgetarraypointer = w->ops->nvgetarraypointer;
297 ops->nvsetarraypointer = w->ops->nvsetarraypointer;
298 ops->nvlinearsum = w->ops->nvlinearsum;
299 ops->nvconst = w->ops->nvconst;
300 ops->nvprod = w->ops->nvprod;
301 ops->nvdiv = w->ops->nvdiv;
302 ops->nvscale = w->ops->nvscale;
303 ops->nvabs = w->ops->nvabs;
304 ops->nvinv = w->ops->nvinv;
305 ops->nvaddconst = w->ops->nvaddconst;
306 ops->nvdotprod = w->ops->nvdotprod;
307 ops->nvmaxnorm = w->ops->nvmaxnorm;
308 ops->nvwrmsnormmask = w->ops->nvwrmsnormmask;
309 ops->nvwrmsnorm = w->ops->nvwrmsnorm;
310 ops->nvmin = w->ops->nvmin;
311 ops->nvwl2norm = w->ops->nvwl2norm;
312 ops->nvl1norm = w->ops->nvl1norm;
313 ops->nvcompare = w->ops->nvcompare;
314 ops->nvinvtest = w->ops->nvinvtest;
315 ops->nvconstrmask = w->ops->nvconstrmask;
316 ops->nvminquotient = w->ops->nvminquotient;
320 content = (N_VectorContent_Serial) malloc(sizeof(struct _N_VectorContent_Serial));
321 if (content == NULL) { free(ops); free(v); return(NULL); }
323 content->length = NV_LENGTH_S(w);
324 content->own_data = FALSE;
325 content->data = NULL;
327 /* Attach content and ops */
328 v->content = content;
334 N_Vector N_VClone_Serial(N_Vector w)
341 v = N_VCloneEmpty_Serial(w);
342 if (v == NULL) return(NULL);
344 length = NV_LENGTH_S(w);
349 /* Allocate memory */
351 data = (realtype *) malloc(length * sizeof(realtype));
352 if(data == NULL) { N_VDestroy_Serial(v); return(NULL); }
355 NV_OWN_DATA_S(v) = TRUE;
363 void N_VDestroy_Serial(N_Vector v)
365 if (NV_OWN_DATA_S(v) == TRUE) {
369 free(v->content); v->content = NULL;
370 free(v->ops); v->ops = NULL;
376 void N_VSpace_Serial(N_Vector v, long int *lrw, long int *liw)
378 *lrw = NV_LENGTH_S(v);
384 realtype *N_VGetArrayPointer_Serial(N_Vector v)
386 return((realtype *) NV_DATA_S(v));
389 void N_VSetArrayPointer_Serial(realtype *v_data, N_Vector v)
391 if (NV_LENGTH_S(v) > 0) NV_DATA_S(v) = v_data;
396 void N_VLinearSum_Serial(realtype a, N_Vector x, realtype b, N_Vector y, N_Vector z)
399 realtype c, *xd, *yd, *zd;
405 if ((b == ONE) && (z == y)) { /* BLAS usage: axpy y <- ax+y */
410 if ((a == ONE) && (z == x)) { /* BLAS usage: axpy x <- by+x */
415 /* Case: a == b == 1.0 */
417 if ((a == ONE) && (b == ONE)) {
418 VSum_Serial(x, y, z);
422 /* Cases: (1) a == 1.0, b = -1.0, (2) a == -1.0, b == 1.0 */
424 if ((test = ((a == ONE) && (b == -ONE))) || ((a == -ONE) && (b == ONE))) {
427 VDiff_Serial(v2, v1, z);
431 /* Cases: (1) a == 1.0, b == other or 0.0, (2) a == other or 0.0, b == 1.0 */
432 /* if a or b is 0.0, then user should have called N_VScale */
434 if ((test = (a == ONE)) || (b == ONE)) {
438 VLin1_Serial(c, v1, v2, z);
442 /* Cases: (1) a == -1.0, b != 1.0, (2) a != 1.0, b == -1.0 */
444 if ((test = (a == -ONE)) || (b == -ONE)) {
448 VLin2_Serial(c, v1, v2, z);
453 /* catches case both a and b are 0.0 - user should have called N_VConst */
456 VScaleSum_Serial(a, x, y, z);
463 VScaleDiff_Serial(a, x, y, z);
467 /* Do all cases not handled above:
468 (1) a == other, b == 0.0 - user should have called N_VScale
469 (2) a == 0.0, b == other - user should have called N_VScale
470 (3) a,b == other, a !=b, a != -b */
477 for (i = 0; i < N; i++)
478 zd[i] = (a*xd[i])+(b*yd[i]);
483 void N_VConst_Serial(realtype c, N_Vector z)
493 for (i = 0; i < N; i++) zd[i] = c;
498 void N_VProd_Serial(N_Vector x, N_Vector y, N_Vector z)
501 realtype *xd, *yd, *zd;
510 for (i = 0; i < N; i++)
516 void N_VDiv_Serial(N_Vector x, N_Vector y, N_Vector z)
519 realtype *xd, *yd, *zd;
528 for (i = 0; i < N; i++)
534 void N_VScale_Serial(realtype c, N_Vector x, N_Vector z)
541 if (z == x) { /* BLAS usage: scale x <- cx */
542 VScaleBy_Serial(c, x);
548 } else if (c == -ONE) {
554 for (i = 0; i < N; i++)
561 void N_VAbs_Serial(N_Vector x, N_Vector z)
572 for (i = 0; i < N; i++)
578 void N_VInv_Serial(N_Vector x, N_Vector z)
589 for (i = 0; i < N; i++)
595 void N_VAddConst_Serial(N_Vector x, realtype b, N_Vector z)
606 for (i = 0; i < N; i++)
612 realtype N_VDotProd_Serial(N_Vector x, N_Vector y)
615 realtype sum, *xd, *yd;
624 for (i = 0; i < N; i++)
630 realtype N_VMaxNorm_Serial(N_Vector x)
641 for (i = 0; i < N; i++) {
642 if (ABS(xd[i]) > max) max = ABS(xd[i]);
648 realtype N_VWrmsNorm_Serial(N_Vector x, N_Vector w)
651 realtype sum, prodi, *xd, *wd;
660 for (i = 0; i < N; i++) {
665 return(RSqrt(sum/N));
668 realtype N_VWrmsNormMask_Serial(N_Vector x, N_Vector w, N_Vector id)
671 realtype sum, prodi, *xd, *wd, *idd;
674 xd = wd = idd = NULL;
681 for (i = 0; i < N; i++) {
688 return(RSqrt(sum / N));
691 realtype N_VMin_Serial(N_Vector x)
703 for (i = 1; i < N; i++) {
704 if (xd[i] < min) min = xd[i];
710 realtype N_VWL2Norm_Serial(N_Vector x, N_Vector w)
713 realtype sum, prodi, *xd, *wd;
722 for (i = 0; i < N; i++) {
730 realtype N_VL1Norm_Serial(N_Vector x)
741 for (i = 0; i<N; i++)
747 void N_VCompare_Serial(realtype c, N_Vector x, N_Vector z)
758 for (i = 0; i < N; i++) {
759 zd[i] = (ABS(xd[i]) >= c) ? ONE : ZERO;
765 booleantype N_VInvTest_Serial(N_Vector x, N_Vector z)
776 for (i = 0; i < N; i++) {
777 if (xd[i] == ZERO) return(FALSE);
784 booleantype N_VConstrMask_Serial(N_Vector c, N_Vector x, N_Vector m)
788 realtype *cd, *xd, *md;
799 for (i = 0; i < N; i++) {
801 if (cd[i] == ZERO) continue;
802 if (cd[i] > ONEPT5 || cd[i] < -ONEPT5) {
803 if ( xd[i]*cd[i] <= ZERO) { test = FALSE; md[i] = ONE; }
806 if ( cd[i] > HALF || cd[i] < -HALF) {
807 if (xd[i]*cd[i] < ZERO ) { test = FALSE; md[i] = ONE; }
814 realtype N_VMinQuotient_Serial(N_Vector num, N_Vector denom)
816 booleantype notEvenOnce;
818 realtype *nd, *dd, min;
822 N = NV_LENGTH_S(num);
824 dd = NV_DATA_S(denom);
829 for (i = 0; i < N; i++) {
830 if (dd[i] == ZERO) continue;
832 if (!notEvenOnce) min = MIN(min, nd[i]/dd[i]);
844 * -----------------------------------------------------------------
846 * -----------------------------------------------------------------
849 static void VCopy_Serial(N_Vector x, N_Vector z)
860 for (i = 0; i < N; i++)
866 static void VSum_Serial(N_Vector x, N_Vector y, N_Vector z)
869 realtype *xd, *yd, *zd;
878 for (i = 0; i < N; i++)
884 static void VDiff_Serial(N_Vector x, N_Vector y, N_Vector z)
887 realtype *xd, *yd, *zd;
896 for (i = 0; i < N; i++)
902 static void VNeg_Serial(N_Vector x, N_Vector z)
913 for (i = 0; i < N; i++)
919 static void VScaleSum_Serial(realtype c, N_Vector x, N_Vector y, N_Vector z)
922 realtype *xd, *yd, *zd;
931 for (i = 0; i < N; i++)
932 zd[i] = c*(xd[i]+yd[i]);
937 static void VScaleDiff_Serial(realtype c, N_Vector x, N_Vector y, N_Vector z)
940 realtype *xd, *yd, *zd;
949 for (i = 0; i < N; i++)
950 zd[i] = c*(xd[i]-yd[i]);
955 static void VLin1_Serial(realtype a, N_Vector x, N_Vector y, N_Vector z)
958 realtype *xd, *yd, *zd;
967 for (i = 0; i < N; i++)
968 zd[i] = (a*xd[i])+yd[i];
973 static void VLin2_Serial(realtype a, N_Vector x, N_Vector y, N_Vector z)
976 realtype *xd, *yd, *zd;
985 for (i = 0; i < N; i++)
986 zd[i] = (a*xd[i])-yd[i];
991 static void Vaxpy_Serial(realtype a, N_Vector x, N_Vector y)
1003 for (i = 0; i < N; i++)
1009 for (i = 0; i < N; i++)
1014 for (i = 0; i < N; i++)
1020 static void VScaleBy_Serial(realtype a, N_Vector x)
1030 for (i = 0; i < N; i++)