Actual source code: dvec2.c
1: /*$Id: dvec2.c,v 1.84 2001/03/23 23:21:25 balay Exp $*/
3: /*
4: Defines some vector operation functions that are shared by
5: sequential and parallel vectors.
6: */
7: #include src/vec/impls/dvecimpl.h
8: #include src/inline/dot.h
9: #include src/inline/setval.h
10: #include src/inline/axpy.h
12: #if defined(PETSC_USE_FORTRAN_KERNEL_MDOT)
13: int VecMDot_Seq(int nv,Vec xin,const Vec yin[],Scalar *z)
14: {
15: Vec_Seq *xv = (Vec_Seq *)xin->data;
16: int i,nv_rem,n = xin->n;
17: Scalar sum0,sum1,sum2,sum3,*yy0,*yy1,*yy2,*yy3,x0,x1,x2,x3,*x;
18: Vec *yy;
21: sum0 = 0;
22: sum1 = 0;
23: sum2 = 0;
25: i = nv;
26: nv_rem = nv&0x3;
27: yy = (Vec*)yin;
28: x = xv->array;
30: switch (nv_rem) {
31: case 3:
32: yy0 = ((Vec_Seq *)(yy[0]->data))->array;
33: yy1 = ((Vec_Seq *)(yy[1]->data))->array;
34: yy2 = ((Vec_Seq *)(yy[2]->data))->array;
35: fortranmdot3_(x,yy0,yy1,yy2,&n,&sum0,&sum1,&sum2);
36: z[0] = sum0;
37: z[1] = sum1;
38: z[2] = sum2;
39: break;
40: case 2:
41: yy0 = ((Vec_Seq *)(yy[0]->data))->array;
42: yy1 = ((Vec_Seq *)(yy[1]->data))->array;
43: fortranmdot2_(x,yy0,yy1,&n,&sum0,&sum1);
44: z[0] = sum0;
45: z[1] = sum1;
46: break;
47: case 1:
48: yy0 = ((Vec_Seq *)(yy[0]->data))->array;
49: fortranmdot1_(x,yy0,&n,&sum0);
50: z[0] = sum0;
51: break;
52: case 0:
53: break;
54: }
55: z += nv_rem;
56: i -= nv_rem;
57: yy += nv_rem;
59: while (i >0) {
60: sum0 = 0;
61: sum1 = 0;
62: sum2 = 0;
63: sum3 = 0;
64: yy0 = ((Vec_Seq *)(yy[0]->data))->array;
65: yy1 = ((Vec_Seq *)(yy[1]->data))->array;
66: yy2 = ((Vec_Seq *)(yy[2]->data))->array;
67: yy3 = ((Vec_Seq *)(yy[3]->data))->array;
68: yy += 4;
69: fortranmdot4_(x,yy0,yy1,yy2,yy3,&n,&sum0,&sum1,&sum2,&sum3);
70: z[0] = sum0;
71: z[1] = sum1;
72: z[2] = sum2;
73: z[3] = sum3;
74: z += 4;
75: i -= 4;
76: }
77: PetscLogFlops(nv*(2*xin->n-1));
78: return(0);
79: }
81: #else
82: int VecMDot_Seq(int nv,Vec xin,const Vec yin[],Scalar * restrict z)
83: {
84: Vec_Seq *xv = (Vec_Seq *)xin->data;
85: int n = xin->n,i,j,nv_rem,j_rem;
86: Scalar sum0,sum1,sum2,sum3,x0,x1,x2,x3,* restrict x;
87: Scalar * restrict yy0,* restrict yy1,* restrict yy2,*restrict yy3;
88: Vec *yy;
91: sum0 = 0;
92: sum1 = 0;
93: sum2 = 0;
95: i = nv;
96: nv_rem = nv&0x3;
97: yy = (Vec *)yin;
98: j = n;
99: x = xv->array;
101: switch (nv_rem) {
102: case 3:
103: yy0 = ((Vec_Seq *)(yy[0]->data))->array;
104: yy1 = ((Vec_Seq *)(yy[1]->data))->array;
105: yy2 = ((Vec_Seq *)(yy[2]->data))->array;
106: switch (j_rem=j&0x3) {
107: case 3:
108: x2 = x[2];
109: sum0 += x2*PetscConj(yy0[2]); sum1 += x2*PetscConj(yy1[2]);
110: sum2 += x2*PetscConj(yy2[2]);
111: case 2:
112: x1 = x[1];
113: sum0 += x1*PetscConj(yy0[1]); sum1 += x1*PetscConj(yy1[1]);
114: sum2 += x1*PetscConj(yy2[1]);
115: case 1:
116: x0 = x[0];
117: sum0 += x0*PetscConj(yy0[0]); sum1 += x0*PetscConj(yy1[0]);
118: sum2 += x0*PetscConj(yy2[0]);
119: case 0:
120: x += j_rem;
121: yy0 += j_rem;
122: yy1 += j_rem;
123: yy2 += j_rem;
124: j -= j_rem;
125: break;
126: }
127: while (j>0) {
128: x0 = x[0];
129: x1 = x[1];
130: x2 = x[2];
131: x3 = x[3];
132: x += 4;
133:
134: sum0 += x0*PetscConj(yy0[0]) + x1*PetscConj(yy0[1]) + x2*PetscConj(yy0[2]) + x3*PetscConj(yy0[3]); yy0+=4;
135: sum1 += x0*PetscConj(yy1[0]) + x1*PetscConj(yy1[1]) + x2*PetscConj(yy1[2]) + x3*PetscConj(yy1[3]); yy1+=4;
136: sum2 += x0*PetscConj(yy2[0]) + x1*PetscConj(yy2[1]) + x2*PetscConj(yy2[2]) + x3*PetscConj(yy2[3]); yy2+=4;
137: j -= 4;
138: }
139: z[0] = sum0;
140: z[1] = sum1;
141: z[2] = sum2;
142: break;
143: case 2:
144: yy0 = ((Vec_Seq *)(yy[0]->data))->array;
145: yy1 = ((Vec_Seq *)(yy[1]->data))->array;
146: switch (j_rem=j&0x3) {
147: case 3:
148: x2 = x[2];
149: sum0 += x2*PetscConj(yy0[2]); sum1 += x2*PetscConj(yy1[2]);
150: case 2:
151: x1 = x[1];
152: sum0 += x1*PetscConj(yy0[1]); sum1 += x1*PetscConj(yy1[1]);
153: case 1:
154: x0 = x[0];
155: sum0 += x0*PetscConj(yy0[0]); sum1 += x0*PetscConj(yy1[0]);
156: case 0:
157: x += j_rem;
158: yy0 += j_rem;
159: yy1 += j_rem;
160: j -= j_rem;
161: break;
162: }
163: while (j>0) {
164: x0 = x[0];
165: x1 = x[1];
166: x2 = x[2];
167: x3 = x[3];
168: x += 4;
169:
170: sum0 += x0*PetscConj(yy0[0]) + x1*PetscConj(yy0[1]) + x2*PetscConj(yy0[2]) + x3*PetscConj(yy0[3]); yy0+=4;
171: sum1 += x0*PetscConj(yy1[0]) + x1*PetscConj(yy1[1]) + x2*PetscConj(yy1[2]) + x3*PetscConj(yy1[3]); yy1+=4;
172: j -= 4;
173: }
174: z[0] = sum0;
175: z[1] = sum1;
176:
177: break;
178: case 1:
179: yy0 = ((Vec_Seq *)(yy[0]->data))->array;
180: switch (j_rem=j&0x3) {
181: case 3:
182: x2 = x[2]; sum0 += x2*PetscConj(yy0[2]);
183: case 2:
184: x1 = x[1]; sum0 += x1*PetscConj(yy0[1]);
185: case 1:
186: x0 = x[0]; sum0 += x0*PetscConj(yy0[0]);
187: case 0:
188: x += j_rem;
189: yy0 += j_rem;
190: j -= j_rem;
191: break;
192: }
193: while (j>0) {
194: sum0 += x[0]*PetscConj(yy0[0]) + x[1]*PetscConj(yy0[1])
195: + x[2]*PetscConj(yy0[2]) + x[3]*PetscConj(yy0[3]);
196: yy0+=4;
197: j -= 4; x+=4;
198: }
199: z[0] = sum0;
201: break;
202: case 0:
203: break;
204: }
205: z += nv_rem;
206: i -= nv_rem;
207: yy += nv_rem;
209: while (i >0) {
210: sum0 = 0;
211: sum1 = 0;
212: sum2 = 0;
213: sum3 = 0;
214: yy0 = ((Vec_Seq *)(yy[0]->data))->array;
215: yy1 = ((Vec_Seq *)(yy[1]->data))->array;
216: yy2 = ((Vec_Seq *)(yy[2]->data))->array;
217: yy3 = ((Vec_Seq *)(yy[3]->data))->array;
218: yy += 4;
220: j = n;
221: x = xv->array;
222: switch (j_rem=j&0x3) {
223: case 3:
224: x2 = x[2];
225: sum0 += x2*PetscConj(yy0[2]); sum1 += x2*PetscConj(yy1[2]);
226: sum2 += x2*PetscConj(yy2[2]); sum3 += x2*PetscConj(yy3[2]);
227: case 2:
228: x1 = x[1];
229: sum0 += x1*PetscConj(yy0[1]); sum1 += x1*PetscConj(yy1[1]);
230: sum2 += x1*PetscConj(yy2[1]); sum3 += x1*PetscConj(yy3[1]);
231: case 1:
232: x0 = x[0];
233: sum0 += x0*PetscConj(yy0[0]); sum1 += x0*PetscConj(yy1[0]);
234: sum2 += x0*PetscConj(yy2[0]); sum3 += x0*PetscConj(yy3[0]);
235: case 0:
236: x += j_rem;
237: yy0 += j_rem;
238: yy1 += j_rem;
239: yy2 += j_rem;
240: yy3 += j_rem;
241: j -= j_rem;
242: break;
243: }
244: while (j>0) {
245: x0 = x[0];
246: x1 = x[1];
247: x2 = x[2];
248: x3 = x[3];
249: x += 4;
250:
251: sum0 += x0*PetscConj(yy0[0]) + x1*PetscConj(yy0[1]) + x2*PetscConj(yy0[2]) + x3*PetscConj(yy0[3]); yy0+=4;
252: sum1 += x0*PetscConj(yy1[0]) + x1*PetscConj(yy1[1]) + x2*PetscConj(yy1[2]) + x3*PetscConj(yy1[3]); yy1+=4;
253: sum2 += x0*PetscConj(yy2[0]) + x1*PetscConj(yy2[1]) + x2*PetscConj(yy2[2]) + x3*PetscConj(yy2[3]); yy2+=4;
254: sum3 += x0*PetscConj(yy3[0]) + x1*PetscConj(yy3[1]) + x2*PetscConj(yy3[2]) + x3*PetscConj(yy3[3]); yy3+=4;
255: j -= 4;
256: }
257: z[0] = sum0;
258: z[1] = sum1;
259: z[2] = sum2;
260: z[3] = sum3;
261: z += 4;
262: i -= 4;
263: }
264: PetscLogFlops(nv*(2*xin->n-1));
265: return(0);
266: }
267: #endif
269: /* ----------------------------------------------------------------------------*/
270: int VecMTDot_Seq(int nv,Vec xin,const Vec yin[],Scalar *z)
271: {
272: Vec_Seq *xv = (Vec_Seq *)xin->data;
273: int n = xin->n,i,j,nv_rem,j_rem;
274: Scalar sum0,sum1,sum2,sum3,*yy0,*yy1,*yy2,*yy3,x0,x1,x2,x3,*x;
275: Vec *yy;
276:
279: sum0 = 0;
280: sum1 = 0;
281: sum2 = 0;
283: i = nv;
284: nv_rem = nv&0x3;
285: yy = (Vec*)yin;
286: j = n;
287: x = xv->array;
289: switch (nv_rem) {
290: case 3:
291: yy0 = ((Vec_Seq *)(yy[0]->data))->array;
292: yy1 = ((Vec_Seq *)(yy[1]->data))->array;
293: yy2 = ((Vec_Seq *)(yy[2]->data))->array;
294: switch (j_rem=j&0x3) {
295: case 3:
296: x2 = x[2];
297: sum0 += x2*yy0[2]; sum1 += x2*yy1[2];
298: sum2 += x2*yy2[2];
299: case 2:
300: x1 = x[1];
301: sum0 += x1*yy0[1]; sum1 += x1*yy1[1];
302: sum2 += x1*yy2[1];
303: case 1:
304: x0 = x[0];
305: sum0 += x0*yy0[0]; sum1 += x0*yy1[0];
306: sum2 += x0*yy2[0];
307: case 0:
308: x += j_rem;
309: yy0 += j_rem;
310: yy1 += j_rem;
311: yy2 += j_rem;
312: j -= j_rem;
313: break;
314: }
315: while (j>0) {
316: x0 = x[0];
317: x1 = x[1];
318: x2 = x[2];
319: x3 = x[3];
320: x += 4;
321:
322: sum0 += x0*yy0[0] + x1*yy0[1] + x2*yy0[2] + x3*yy0[3]; yy0+=4;
323: sum1 += x0*yy1[0] + x1*yy1[1] + x2*yy1[2] + x3*yy1[3]; yy1+=4;
324: sum2 += x0*yy2[0] + x1*yy2[1] + x2*yy2[2] + x3*yy2[3]; yy2+=4;
325: j -= 4;
326: }
327: z[0] = sum0;
328: z[1] = sum1;
329: z[2] = sum2;
330: break;
331: case 2:
332: yy0 = ((Vec_Seq *)(yy[0]->data))->array;
333: yy1 = ((Vec_Seq *)(yy[1]->data))->array;
334: switch (j_rem=j&0x3) {
335: case 3:
336: x2 = x[2];
337: sum0 += x2*yy0[2]; sum1 += x2*yy1[2];
338: case 2:
339: x1 = x[1];
340: sum0 += x1*yy0[1]; sum1 += x1*yy1[1];
341: case 1:
342: x0 = x[0];
343: sum0 += x0*yy0[0]; sum1 += x0*yy1[0];
344: case 0:
345: x += j_rem;
346: yy0 += j_rem;
347: yy1 += j_rem;
348: j -= j_rem;
349: break;
350: }
351: while (j>0) {
352: x0 = x[0];
353: x1 = x[1];
354: x2 = x[2];
355: x3 = x[3];
356: x += 4;
357:
358: sum0 += x0*yy0[0] + x1*yy0[1] + x2*yy0[2] + x3*yy0[3]; yy0+=4;
359: sum1 += x0*yy1[0] + x1*yy1[1] + x2*yy1[2] + x3*yy1[3]; yy1+=4;
360: j -= 4;
361: }
362: z[0] = sum0;
363: z[1] = sum1;
364:
365: break;
366: case 1:
367: yy0 = ((Vec_Seq *)(yy[0]->data))->array;
368: switch (j_rem=j&0x3) {
369: case 3:
370: x2 = x[2]; sum0 += x2*yy0[2];
371: case 2:
372: x1 = x[1]; sum0 += x1*yy0[1];
373: case 1:
374: x0 = x[0]; sum0 += x0*yy0[0];
375: case 0:
376: x += j_rem;
377: yy0 += j_rem;
378: j -= j_rem;
379: break;
380: }
381: while (j>0) {
382: sum0 += x[0]*yy0[0] + x[1]*yy0[1] + x[2]*yy0[2] + x[3]*yy0[3]; yy0+=4;
383: j -= 4; x+=4;
384: }
385: z[0] = sum0;
387: break;
388: case 0:
389: break;
390: }
391: z += nv_rem;
392: i -= nv_rem;
393: yy += nv_rem;
395: while (i >0) {
396: sum0 = 0;
397: sum1 = 0;
398: sum2 = 0;
399: sum3 = 0;
400: yy0 = ((Vec_Seq *)(yy[0]->data))->array;
401: yy1 = ((Vec_Seq *)(yy[1]->data))->array;
402: yy2 = ((Vec_Seq *)(yy[2]->data))->array;
403: yy3 = ((Vec_Seq *)(yy[3]->data))->array;
404: yy += 4;
406: j = n;
407: x = xv->array;
408: switch (j_rem=j&0x3) {
409: case 3:
410: x2 = x[2];
411: sum0 += x2*yy0[2]; sum1 += x2*yy1[2];
412: sum2 += x2*yy2[2]; sum3 += x2*yy3[2];
413: case 2:
414: x1 = x[1];
415: sum0 += x1*yy0[1]; sum1 += x1*yy1[1];
416: sum2 += x1*yy2[1]; sum3 += x1*yy3[1];
417: case 1:
418: x0 = x[0];
419: sum0 += x0*yy0[0]; sum1 += x0*yy1[0];
420: sum2 += x0*yy2[0]; sum3 += x0*yy3[0];
421: case 0:
422: x += j_rem;
423: yy0 += j_rem;
424: yy1 += j_rem;
425: yy2 += j_rem;
426: yy3 += j_rem;
427: j -= j_rem;
428: break;
429: }
430: while (j>0) {
431: x0 = x[0];
432: x1 = x[1];
433: x2 = x[2];
434: x3 = x[3];
435: x += 4;
436:
437: sum0 += x0*yy0[0] + x1*yy0[1] + x2*yy0[2] + x3*yy0[3]; yy0+=4;
438: sum1 += x0*yy1[0] + x1*yy1[1] + x2*yy1[2] + x3*yy1[3]; yy1+=4;
439: sum2 += x0*yy2[0] + x1*yy2[1] + x2*yy2[2] + x3*yy2[3]; yy2+=4;
440: sum3 += x0*yy3[0] + x1*yy3[1] + x2*yy3[2] + x3*yy3[3]; yy3+=4;
441: j -= 4;
442: }
443: z[0] = sum0;
444: z[1] = sum1;
445: z[2] = sum2;
446: z[3] = sum3;
447: z += 4;
448: i -= 4;
449: }
450: PetscLogFlops(nv*(2*xin->n-1));
451: return(0);
452: }
453:
455: int VecMax_Seq(Vec xin,int* idx,PetscReal * z)
456: {
457: Vec_Seq *x = (Vec_Seq*)xin->data;
458: int i,j=0,n = xin->n;
459: PetscReal max,tmp;
460: Scalar *xx = x->array;
463: if (!n) {
464: max = PETSC_MIN;
465: j = -1;
466: } else {
467: #if defined(PETSC_USE_COMPLEX)
468: max = PetscRealPart(*xx++); j = 0;
469: #else
470: max = *xx++; j = 0;
471: #endif
472: for (i=1; i<n; i++) {
473: #if defined(PETSC_USE_COMPLEX)
474: if ((tmp = PetscRealPart(*xx++)) > max) { j = i; max = tmp;}
475: #else
476: if ((tmp = *xx++) > max) { j = i; max = tmp; }
477: #endif
478: }
479: }
480: *z = max;
481: if (idx) *idx = j;
482: return(0);
483: }
485: int VecMin_Seq(Vec xin,int* idx,PetscReal * z)
486: {
487: Vec_Seq *x = (Vec_Seq*)xin->data;
488: int i,j=0,n = xin->n;
489: PetscReal min,tmp;
490: Scalar *xx = x->array;
493: if (!n) {
494: min = PETSC_MAX;
495: j = -1;
496: } else {
497: #if defined(PETSC_USE_COMPLEX)
498: min = PetscRealPart(*xx++); j = 0;
499: #else
500: min = *xx++; j = 0;
501: #endif
502: for (i=1; i<n; i++) {
503: #if defined(PETSC_USE_COMPLEX)
504: if ((tmp = PetscRealPart(*xx++)) < min) { j = i; min = tmp;}
505: #else
506: if ((tmp = *xx++) < min) { j = i; min = tmp; }
507: #endif
508: }
509: }
510: *z = min;
511: if (idx) *idx = j;
512: return(0);
513: }
515: int VecSet_Seq(const Scalar* alpha,Vec xin)
516: {
517: Vec_Seq *x = (Vec_Seq *)xin->data;
518: int n = xin->n,ierr;
519: Scalar *xx = x->array,oalpha = *alpha;
522: if (oalpha == 0.0) {
523: PetscMemzero(xx,n*sizeof(Scalar));
524: }
525: else {
526: SET(xx,n,oalpha);
527: }
528: return(0);
529: }
531: int VecSetRandom_Seq(PetscRandom r,Vec xin)
532: {
533: Vec_Seq *x = (Vec_Seq *)xin->data;
534: int n = xin->n,i,ierr;
535: Scalar *xx = x->array;
538: for (i=0; i<n; i++) {PetscRandomGetValue(r,&xx[i]);}
539: return(0);
540: }
542: int VecMAXPY_Seq(int nv,const Scalar *alpha,Vec xin,Vec *y)
543: {
544: Vec_Seq *xdata = (Vec_Seq*)xin->data;
545: int n = xin->n;
546: int j,j_rem;
547: Scalar *xx,*yy0,*yy1,*yy2,*yy3,alpha0,alpha1,alpha2,alpha3;
549: #if defined(PETSC_HAVE_PRAGMA_DISJOINT)
550: #pragma disjoint(*xx,*yy0,*yy1,*yy2,*yy3,*alpha)
551: #endif
554: PetscLogFlops(nv*2*n);
556: xx = xdata->array;
557: switch (j_rem=nv&0x3) {
558: case 3:
559: yy0 = ((Vec_Seq *)(y[0]->data))->array;
560: yy1 = ((Vec_Seq *)(y[1]->data))->array;
561: yy2 = ((Vec_Seq *)(y[2]->data))->array;
562: alpha0 = alpha[0];
563: alpha1 = alpha[1];
564: alpha2 = alpha[2];
565: y += 3;
566: alpha += 3;
567: APXY3(xx,alpha0,alpha1,alpha2,yy0,yy1,yy2,n);
568: break;
569: case 2:
570: yy0 = ((Vec_Seq *)(y[0]->data))->array;
571: yy1 = ((Vec_Seq *)(y[1]->data))->array;
572: alpha0 = alpha[0];
573: alpha1 = alpha[1];
574: y +=2;
575: alpha +=2;
576: APXY2(xx,alpha0,alpha1,yy0,yy1,n);
577: break;
578: case 1:
579: yy0 = ((Vec_Seq *)(y[0]->data))->array; y++;
580: alpha0 = *alpha++; APXY(xx,alpha0,yy0,n);
581: break;
582: }
583: for (j=j_rem; j<nv; j+=4) {
584: yy0 = ((Vec_Seq *)(y[0]->data))->array;
585: yy1 = ((Vec_Seq *)(y[1]->data))->array;
586: yy2 = ((Vec_Seq *)(y[2]->data))->array;
587: yy3 = ((Vec_Seq *)(y[3]->data))->array;
588: alpha0 = alpha[0];
589: alpha1 = alpha[1];
590: alpha2 = alpha[2];
591: alpha3 = alpha[3];
592: y += 4;
593: alpha += 4;
595: APXY4(xx,alpha0,alpha1,alpha2,alpha3,yy0,yy1,yy2,yy3,n);
596: }
597: return(0);
598: }
600: int VecAYPX_Seq(const Scalar *alpha,Vec xin,Vec yin)
601: {
602: Vec_Seq *x = (Vec_Seq *)xin->data,*y = (Vec_Seq *)yin->data;
603: int i,n = xin->n;
604: Scalar *xx = x->array,*yy = y->array,oalpha = *alpha;
607: PetscLogFlops(2*n);
608: for (i=0; i<n; i++) {
609: yy[i] = xx[i] + oalpha*yy[i];
610: }
611: return(0);
612: }
614: /*
615: IBM ESSL contains a routine dzaxpy() that is our WAXPY() but it appears
616: to be slower than a regular C loop. Hence,we do not include it.
617: void ?zaxpy(int*,Scalar*,Scalar*,int*,Scalar*,int*,Scalar*,int*);
618: */
620: int VecWAXPY_Seq(const Scalar* alpha,Vec xin,Vec yin,Vec win)
621: {
622: Vec_Seq *w = (Vec_Seq *)win->data,*x = (Vec_Seq *)xin->data;
623: Vec_Seq *y = (Vec_Seq *)yin->data;
624: int i,n = xin->n,ierr;
625: Scalar *xx = x->array,*yy = y->array,*ww = w->array,oalpha = *alpha;
628: if (oalpha == 1.0) {
629: PetscLogFlops(n);
630: /* could call BLAS axpy after call to memcopy, but may be slower */
631: for (i=0; i<n; i++) ww[i] = yy[i] + xx[i];
632: } else if (oalpha == -1.0) {
633: PetscLogFlops(n);
634: for (i=0; i<n; i++) ww[i] = yy[i] - xx[i];
635: } else if (oalpha == 0.0) {
636: PetscMemcpy(ww,yy,n*sizeof(Scalar));
637: } else {
638: for (i=0; i<n; i++) ww[i] = yy[i] + oalpha * xx[i];
639: PetscLogFlops(2*n);
640: }
641: return(0);
642: }
644: int VecPointwiseMult_Seq(Vec xin,Vec yin,Vec win)
645: {
646: Vec_Seq *w = (Vec_Seq *)win->data,*x = (Vec_Seq *)xin->data;
647: Vec_Seq *y = (Vec_Seq *)yin->data;
648: int n = xin->n,i;
649: Scalar *xx = x->array,*yy = y->array,*ww = w->array;
652: if (ww == xx) {
653: for (i=0; i<n; i++) ww[i] *= yy[i];
654: } else if (ww == yy) {
655: for (i=0; i<n; i++) ww[i] *= xx[i];
656: } else {
657: /* This was suppose to help on SGI but didn't really seem to
658: PetscReal * __restrict www = ww;
659: PetscReal * __restrict yyy = yy;
660: PetscReal * __restrict xxx = xx;
661: for (i=0; i<n; i++) www[i] = xxx[i] * yyy[i];
662: */
663: #if defined(PETSC_USE_FORTRAN_KERNEL_XTIMESY)
664: fortranxtimesy_(xx,yy,ww,&n);
665: #else
666: for (i=0; i<n; i++) ww[i] = xx[i] * yy[i];
667: #endif
668: }
669: PetscLogFlops(n);
670: return(0);
671: }
673: int VecPointwiseDivide_Seq(Vec xin,Vec yin,Vec win)
674: {
675: Vec_Seq *w = (Vec_Seq *)win->data,*x = (Vec_Seq *)xin->data;
676: Vec_Seq *y = (Vec_Seq *)yin->data;
677: int n = xin->n,i;
678: Scalar *xx = x->array,*yy = y->array,*ww = w->array;
681: PetscLogFlops(n);
682: for (i=0; i<n; i++) ww[i] = xx[i] / yy[i];
683: return(0);
684: }
686: int VecGetArray_Seq(Vec vin,Scalar *a[])
687: {
688: Vec_Seq *v = (Vec_Seq *)vin->data;
689: int ierr;
692: if (vin->array_gotten) {
693: SETERRQ(1,"Array has already been gotten for this vector,you mayn
694: have forgotten a call to VecRestoreArray()");
695: }
696: vin->array_gotten = PETSC_TRUE;
698: *a = v->array;
699: PetscObjectTakeAccess(vin);
700: return(0);
701: }
703: int VecRestoreArray_Seq(Vec vin,Scalar *a[])
704: {
709: if (!vin->array_gotten) {
710: SETERRQ(1,"Array has not been gotten for this vector, you mayn
711: have forgotten a call to VecGetArray()");
712: }
713: vin->array_gotten = PETSC_FALSE;
714: if (a) *a = 0; /* now user cannot accidently use it again */
716: PetscObjectGrantAccess(vin);
717: return(0);
718: }
720: int VecResetArray_Seq(Vec vin)
721: {
722: Vec_Seq *v = (Vec_Seq *)vin->data;
725: v->array = v->array_allocated;
726: return(0);
727: }
729: int VecPlaceArray_Seq(Vec vin,const Scalar *a)
730: {
731: Vec_Seq *v = (Vec_Seq *)vin->data;
734: v->array = (Scalar *)a;
735: return(0);
736: }
738: int VecReplaceArray_Seq(Vec vin,const Scalar *a)
739: {
740: Vec_Seq *v = (Vec_Seq *)vin->data;
741: int ierr;
744: if (v->array_allocated) {PetscFree(v->array_allocated);}
745: v->array_allocated = v->array = (Scalar *)a;
746: return(0);
747: }
749: int VecGetSize_Seq(Vec vin,int *size)
750: {
752: *size = vin->n;
753: return(0);
754: }
756: int VecConjugate_Seq(Vec xin)
757: {
758: Scalar *x = ((Vec_Seq *)xin->data)->array;
759: int n = xin->n;
762: while (n-->0) {
763: *x = PetscConj(*x);
764: x++;
765: }
766: return(0);
767: }
768: