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: