Actual source code: taovec.c
1: #include "tao_general.h" /*I "tao_solver.h" I*/
2: #include "taovec.h"
6: /*@C
7: TaoVecDestroy - Destroys the TaoVec object.
9: Input Parameter:
10: . vv - the vector
12: Level: beginner
13: @*/
14: int TaoVecDestroy( TaoVec* vv){
15: TaoFunctionBegin;
16: if (vv!=TAO_NULL && vv!=0){
17: delete vv;
18: }
19: vv=TAO_NULL;
20: TaoFunctionReturn(0);
21: }
25: /*@C
26: CloneVecs - Creates an array of pointers to new TaoVec objects. The new
27: objects have the same structure as this one.
29: Input Parameter:
30: . nn - number of new vectors
32: Output Parameter:
33: . tvs - pointer to array TaoVec pointers
35: .seealso TaoVec::Clone()
37: Level: intermediate
38: @*/
39: int TaoVec::CloneVecs(int nn, TaoVec***tvs){
40: int i,info;
41: TaoVec ** ntv;
42: TaoFunctionBegin;
43: ntv = new TaoVec*[nn];
44: for (i=0;i<nn;i++){
45: info = this->Clone(&ntv[i]);CHKERRQ(info);
46: }
47: *tvs=ntv;
48: TaoFunctionReturn(0);
49: }
53: /*@C
54: DestroyVecs - Destroys an array TaoVec objects.
56: Input Parameter:
57: + nn - number of new vectors
58: - tvs - pointer to array TaoVec pointers
60: Level: advanced
62: .seealso TaoVec::CloneVecs()
63: @*/
64: int TaoVec::DestroyVecs(int nn, TaoVec**ntv){
65: int i,info;
66: TaoFunctionBegin;
67: for (i=0;i<nn;i++){
68: info = TaoVecDestroy( ntv[i] );CHKERRQ(info);
69: }
70: delete[] ntv;
71: TaoFunctionReturn(0);
72: }
76: /*@C
77: Clone - Creates a new TaoVec object with the same structure as this one. It does not
78: copy the value to the new vector.
80: Input:
81: . vv - address of a pointer to a TaoVec
83: Output Parameter:
84: . vv - address of a pointer to new TaoVec object
86: .seealso TaoVec::CloneVecs(), TaoVec::CopyFrom()
88: Level: intermediate
89: @*/
90: int TaoVec::Clone( TaoVec* *vv ){
91: TaoFunctionBegin;
92: SETERRQ(56,"Operation not defined");
93: /* TaoFunctionReturn(1); */
94: }
98: /*@C
99: Compatible - Determines whether this vector belongs to the same space as another,
100: and operations such as inner product and sum are well defined.
102: Input Parameter:
103: . vv - TAO vector to which to the comparison is made
105: Output Value:
106: . flag - TAO_TRUE if the two vectors are Compatible and TAO_FALSE otherwise.
108: Level: advanced
110: .seealso TaoVec::GetDimension()
111: @*/
112: int TaoVec::Compatible(TaoVec* vv, TaoTruth *flag){
113: TaoFunctionBegin;
114: if (!flag){
115: TaoFunctionReturn(1);
116: }
117: *flag=TAO_FALSE;
118: TaoFunctionReturn(0);
119: }
123: /*@C
124: SetToConstant - Sets each element of this vector equal to the specified constant.
126: Input Parameter:
127: . c - a constant
129: Level: intermediate
131: .seealso TaoVec::Scale()
132: @*/
133: int TaoVec::SetToConstant( double c ){
134: int i,nn,info;
135: TaoScalar *tptr;
137: TaoFunctionBegin;
138: info = this->GetArray(&tptr,&nn);CHKERRQ(info);
139: for (i=0;i<nn;i++){ tptr[i]=c; }
140: info = this->RestoreArray(&tptr,&nn);CHKERRQ(info);
141: TaoFunctionReturn(0);
142: }
146: /*@C
147: SetToZero - Sets each element of this vector equal to zero.
149: Input Parameters: none
151: Level: intermediate
153: .seealso TaoVec::SetToConstant()
154: @*/
155: int TaoVec::SetToZero(){
156: int i,nn,info;
157: TaoScalar *tptr;
159: TaoFunctionBegin;
160: info = this->GetArray(&tptr,&nn);CHKERRQ(info);
161: for (i=0;i<nn;i++){ tptr[i]=0; }
162: info = this->RestoreArray(&tptr,&nn);CHKERRQ(info);
163: TaoFunctionReturn(0);
164: }
168: /*@C
169: CopyFrom - Copies the contents of one vector into this vector.
171: Input Parameter:
172: . vv - A TaoVec from which the contents will be copied.
174: Level: intermediate
176: .seealso TaoVec::Axpy(), TaoVec::ScaleCopyFrom()
177: @*/
178: int TaoVec::CopyFrom( TaoVec* vv ){
179: int i,nn1,nn2,info;
180: TaoScalar *tptr1,*tptr2;
182: TaoFunctionBegin;
183: info = this->GetArray(&tptr1,&nn1);CHKERRQ(info);
184: if (vv!=this){
185: info = vv->GetArray(&tptr2,&nn2);CHKERRQ(info);
186: if (nn1!=nn2) {TaoFunctionReturn(1);}
187: for (i=0;i<nn1;i++){ tptr1[i]=tptr2[i]; }
188: info = vv->RestoreArray(&tptr2,&nn2);CHKERRQ(info);
189: }
190: info = this->RestoreArray(&tptr1,&nn1);CHKERRQ(info);
191: TaoFunctionReturn(0);
192: }
196: /*@C
197: ScaleCopyFrom - Copies the contents of one vector into this vector and scales it.
199: Input Parameter:
200: + a - the scalar
201: - vv - A TaoVec from which the contents will be copied.
203: Level: intermediate
205: .seealso TaoVec::Axpy(), TaoVec::Aypx()
206: @*/
207: int TaoVec::ScaleCopyFrom( double a, TaoVec* vv ){
208: int i,nn1,nn2,info;
209: TaoScalar *tptr1,*tptr2;
211: TaoFunctionBegin;
212: info = this->GetArray(&tptr1,&nn1);CHKERRQ(info);
213: if (vv!=this){
214: info = vv->GetArray(&tptr2,&nn2);CHKERRQ(info);
215: if (nn1!=nn2) {TaoFunctionReturn(1);}
216: for (i=0;i<nn1;i++){ tptr1[i]=a*tptr2[i]; }
217: info = vv->RestoreArray(&tptr2,&nn2);CHKERRQ(info);
218: } else {
219: this->Scale(a);
220: }
221: info = this->RestoreArray(&tptr1,&nn1);CHKERRQ(info);
222: TaoFunctionReturn(0);
223: }
227: /*@C
228: NormInfinity - Computes the infinity norm of this vector.
230: Ouput Parameter:
231: . vnorm - the infinity norm of this vector
233: Level: intermediate
235: .seealso TaoVec::Norm1(), TaoVec::Norm2()
236: @*/
237: int TaoVec::NormInfinity(double *vnorm){
238: int i,nn,info;
239: TaoScalar dd=0, *v;
241: TaoFunctionBegin;
242: info = this->GetArray(&v,&nn);CHKERRQ(info);
243: for (i=0;i<nn;i++){
244: if (v[i]<0 && v[i]<-dd) dd=-v[i];
245: else if (v[i]>0 && v[i]>dd) dd=v[i];
246: }
247: info = this->RestoreArray(&v,&nn);CHKERRQ(info);
248: *vnorm=dd;
249: TaoFunctionReturn(0);
250: }
254: /*@C
255: Norm1 - Computes the one-norm of this vector.
257: Ouput Parameter:
258: . vnorm - the one-norm of this vector
260: Level: intermediate
262: .seealso TaoVec::NormInfinity(), TaoVec::Norm2()
263: @*/
264: int TaoVec::Norm1(double *vnorm){
265: int i,nn,info;
266: TaoScalar dd=0, *v;
268: TaoFunctionBegin;
269: info = this->GetArray(&v,&nn);CHKERRQ(info);
270: for (i=0;i<nn;i++){
271: if (v[i]<0) dd-=v[i];
272: else dd+=v[i];
273: }
274: info = this->RestoreArray(&v,&nn);CHKERRQ(info);
275: TaoFunctionReturn(0);
276: }
280: /*@C
281: Norm2 - Compute the two-norm of this vector.
283: Ouput Parameter:
284: . vnorm - the two-norm of this vector
286: Level: intermediate
288: .seealso TaoVec::Norm1(), TaoVec::NormInfinity(), TaoVec::Norm2squared()
289: @*/
290: int TaoVec::Norm2(double *vnorm){
291: int i,nn,info;
292: TaoScalar dd=0, *v;
294: TaoFunctionBegin;
295: info = this->GetArray(&v,&nn);CHKERRQ(info);
296: for (i=0;i<nn;i++) dd+=v[i]*v[i];
297: *vnorm=sqrt(dd);
298: info = this->RestoreArray(&v,&nn);CHKERRQ(info);
299: TaoFunctionReturn(0);
300: }
304: /*@C
305: Norm2squared - Computes the square of the two norm of this vector.
307: Ouput Parameter:
308: . vnorm2 - the square of the two norm of this vector
310: Level: intermediate
312: .seealso TaoVec::Norm2()
313: @*/
314: int TaoVec::Norm2squared(double *vnorm2){
315: int i,nn,info;
316: TaoScalar dd=0, *v;
318: TaoFunctionBegin;
319: info = this->GetArray(&v,&nn);CHKERRQ(info);
320: for (i=0;i<nn;i++) dd+=v[i]*v[i];
321: *vnorm2=dd;
322: info = this->RestoreArray(&v,&nn);CHKERRQ(info);
323: TaoFunctionReturn(0);
324: }
328: /*@C
329: Scale - Multiplies this vector by a scalar.
331: Input Parameter:
332: . alpha - the scalar
334: Level: intermediate
336: .seealso TaoVec::SetToConstant(), TaoVec::Aypx()
337: @*/
338: int TaoVec::Scale( double alpha ){
339: int i,nn,info;
340: TaoScalar *v;
342: TaoFunctionBegin;
343: info = this->GetArray(&v,&nn);CHKERRQ(info);
344: for (i=0;i<nn;i++) v[i]*=alpha;
345: info = this->RestoreArray(&v,&nn);CHKERRQ(info);
346: TaoFunctionReturn(0);
347: }
351: /*@C
352: Axpy - Adds a scalar multiple of a vector to this vector. (this += alpha * xx)
354: Input Parameter:
355: + alpha - the scalar
356: - xx - the vector
358: Level: intermediate
360: .seealso TaoVec::CopyFrom(), TaoVec::Aypx()
361: @*/
362: int TaoVec::Axpy( double alpha, TaoVec* xx ){
363: int i,nn1,nn2,info;
364: TaoScalar *tptr1,*tptr2;
366: TaoFunctionBegin;
367: info = this->GetArray(&tptr1,&nn1);CHKERRQ(info);
368: info = xx->GetArray(&tptr2,&nn2);CHKERRQ(info);
369: if (nn1!=nn2) {TaoFunctionReturn(1);}
370: for (i=0;i<nn1;i++){ tptr1[i]+= alpha * tptr2[i]; }
371: info = this->RestoreArray(&tptr1,&nn1);CHKERRQ(info);
372: info = xx->RestoreArray(&tptr2,&nn2);CHKERRQ(info);
373: TaoFunctionReturn(0);
374: }
378: /*@C
379: Axpby - Adds a scalar multiple of a vector to a multiple of this vector. (this=alpha*xx + beta*this)
381: Input Parameter:
382: + alpha - the scalar of tx
383: . xx - the vector
384: - beta - the scalar multiple of this vector
386: Level: intermediate
388: .seealso TaoVec::Axpy(), TaoVec::Aypx()
389: @*/
390: int TaoVec::Axpby( double alpha, TaoVec* xx, double beta ){
391: int i,nn1,nn2,info;
392: TaoScalar *tptr1,*tptr2;
394: TaoFunctionBegin;
395: info = this->GetArray(&tptr1,&nn1);CHKERRQ(info);
396: info = xx->GetArray(&tptr2,&nn2);CHKERRQ(info);
397: if (nn1!=nn2) {TaoFunctionReturn(1);}
398: for (i=0;i<nn1;i++){ tptr1[i] = beta * tptr1[i] + alpha * tptr2[i]; }
399: info = this->RestoreArray(&tptr1,&nn1);CHKERRQ(info);
400: info = xx->RestoreArray(&tptr2,&nn2);CHKERRQ(info);
401: TaoFunctionReturn(0);
402: }
406: /*@C
407: Aypx - Adds a vector to a scalar multiple of this vector. (this=alpha*this+xx)
409: Input Parameter:
410: + alpha - the scalar
411: - xx - the vector
413: Level: intermediate
415: .seealso TaoVec::Scale(), TaoVec::Axpy()
416: @*/
417: int TaoVec::Aypx( double alpha, TaoVec* xx ){
418: int i,nn1,nn2,info;
419: TaoScalar *tptr1,*tptr2;
421: TaoFunctionBegin;
422: info = this->GetArray(&tptr1,&nn1);CHKERRQ(info);
423: info = xx->GetArray(&tptr2,&nn2);CHKERRQ(info);
424: if (nn1!=nn2) {TaoFunctionReturn(1);}
425: for (i=0;i<nn1;i++){ tptr1[i] = alpha * tptr1[i] + tptr2[i]; }
426: info = this->RestoreArray(&tptr1,&nn1);CHKERRQ(info);
427: info = xx->RestoreArray(&tptr2,&nn2);CHKERRQ(info);
428: TaoFunctionReturn(0);
429: }
430:
433: /*@C
434: AddConstant - Adds a constant to each element of this vector.
436: Input Parameter:
437: . alpha - the scalar
439: Level: intermediate
441: .seealso TaoVec::SetToConstant(), TaoVec::Axpy()
442: @*/
443: int TaoVec::AddConstant( double alpha ){
444: int i,nn,info;
445: TaoScalar *v;
447: TaoFunctionBegin;
448: info = this->GetArray(&v,&nn);CHKERRQ(info);
449: for (i=0;i<nn;i++) v[i]+=alpha;
450: info = this->RestoreArray(&v,&nn);CHKERRQ(info);
451: TaoFunctionReturn(0);
452: }
456: /*@C
457: Dot - Computes the inner product of this vector with another vector.
459: Input Parameter:
460: . vv - another TaoVec object
462: Output Parameter:
463: . vDotv - the inner product of the two vectors
465: Level: intermediate
467: .seealso TaoVec::Norm()
468: @*/
469: int TaoVec::Dot( TaoVec* vv, double *vDotv ){
470: int i,nn1,nn2,info;
471: TaoScalar dd=0,*tptr1,*tptr2;
473: TaoFunctionBegin;
474: info = this->GetArray(&tptr1,&nn1);CHKERRQ(info);
475: info = vv->GetArray(&tptr2,&nn2);CHKERRQ(info);
476: if (nn1!=nn2) {TaoFunctionReturn(1);}
477: for (i=0;i<nn1;i++) dd+=tptr1[i]*tptr2[i];
478: info = this->RestoreArray(&tptr1,&nn1);CHKERRQ(info);
479: info = vv->RestoreArray(&tptr2,&nn2);CHKERRQ(info);
480: *vDotv=dd;
481: TaoFunctionReturn(0);
482: }
486: /*@C
487: Negate - Multiplies the elements of this vector by negative one.
489: Input Parameters: none
491: Level: intermediate
493: .seealso TaoVec::Scale()
494: @*/
495: int TaoVec::Negate(){
496: int i,nn,info;
497: TaoScalar *v;
499: TaoFunctionBegin;
500: info = this->GetArray(&v,&nn);CHKERRQ(info);
501: for (i=0;i<nn;i++) v[i]=-v[i];
502: info = this->RestoreArray(&v,&nn);CHKERRQ(info);
503: TaoFunctionReturn(0);
504: }
508: /*@C
509: Reciprocal - Sets each element of this vector to its Reciprocal.
511: Input Parameters: none
513: Level: intermediate
515: .seealso TaoVec::PointwiseDivide()
516: @*/
517: int TaoVec::Reciprocal(){
518: int i,nn,info;
519: TaoScalar *v;
521: TaoFunctionBegin;
522: info = this->GetArray(&v,&nn);CHKERRQ(info);
523: for (i=0;i<nn;i++){
524: if (v[i]!=0) v[i]= 1.0/v[i];
525: else v[i]=TAO_INFINITY;
526: }
527: info = this->RestoreArray(&v,&nn);CHKERRQ(info);
528: TaoFunctionReturn(0);
529: }
533: /*@C
534: Sqrt - Sets each element of this vector to its square root.
536: Input Parameters: none
538: Level: intermediate
540: @*/
541: int TaoVec::Sqrt(){
542: int i,nn,info;
543: TaoScalar *v;
545: TaoFunctionBegin;
546: info = this->GetArray(&v,&nn);CHKERRQ(info);
547: for (i=0;i<nn;i++){
548: if (v[i] >= 0) {
549: v[i] = sqrt(v[i]);
550: }
551: else {
552: v[i] = TAO_INFINITY;
553: }
554: }
555: info = this->RestoreArray(&v,&nn);CHKERRQ(info);
556: TaoFunctionReturn(0);
557: }
561: /*@C
562: Pow - Raises each element of this vector to a power.
564: Input Parameters: none
566: Level: intermediate
568: @*/
569: int TaoVec::Pow(double p){
570: int i,nn,info;
571: TaoScalar *v;
573: TaoFunctionBegin;
574: info = this->GetArray(&v,&nn);CHKERRQ(info);
575: for (i=0;i<nn;i++){
576: if (v[i] >= 0) {
577: v[i] = pow(v[i], p);
578: }
579: else {
580: v[i] = TAO_INFINITY;
581: }
582: }
583: info = this->RestoreArray(&v,&nn);CHKERRQ(info);
584: TaoFunctionReturn(0);
585: }
589: /*@C
590: GetDimension - Gets the dimension of the vector space where this vector belongs.
592: Output Parameter:
593: . n - the dimension of the vector space
595: Level: intermediate
597: .seealso TaoVec::Compatible()
598: @*/
599: int TaoVec::GetDimension(int *n){
600: TaoFunctionBegin;
601: SETERRQ(56,"Operation not defined");
602: /* TaoFunctionReturn(1); */
603: }
607: /*@C
608: PointwiseMultiply - Computes the componentwise multiplication of two vectors
609: and stores the result in this vector.
611: Input Parameters:
612: . vv, ww - the two vectors
614: Level: intermediate
616: .seealso TaoVec::PointwiseDivide()
617: @*/
618: int TaoVec::PointwiseMultiply( TaoVec* vv, TaoVec* ww ){
619: int i,nn1,nn2,nn3,info;
620: TaoScalar *tptr1,*tptr2,*tptr3;
622: TaoFunctionBegin;
623: info = this->GetArray(&tptr1,&nn1);CHKERRQ(info);
624: if (this!=vv){
625: info = vv->GetArray(&tptr2,&nn2);CHKERRQ(info);
626: } else {
627: tptr2=tptr1; nn2=nn1;
628: }
629: if (this!=ww && vv!=ww){
630: info = ww->GetArray(&tptr3,&nn3);CHKERRQ(info);
631: } else if (vv==ww){
632: tptr3=tptr2; nn3=nn2;
633: } else {
634: tptr3=tptr1; nn3=nn1;
635: }
636: if (nn1!=nn2 || nn2!=nn3) {TaoFunctionReturn(1);}
637: for (i=0;i<nn1;i++) tptr1[i]=tptr2[i] * tptr3[i];
638: info = this->RestoreArray(&tptr1,&nn1);CHKERRQ(info);
639: if (this!=vv){
640: info = vv->RestoreArray(&tptr2,&nn2);CHKERRQ(info);
641: }
642: if (this!=ww && vv!=ww){
643: info = ww->RestoreArray(&tptr3,&nn3);CHKERRQ(info);
644: }
646: TaoFunctionReturn(0);
647: }
651: /*@C
652: PointwiseDivide - Computes the componentwise division of two vectors
653: and stores the result in this vector.
655: Input Parameters:
656: + vv - the vector of numerators
657: - ww - the vector of denominators
659: Level: intermediate
661: .seealso TaoVec::PointwiseMultiply()
662: @*/
663: int TaoVec::PointwiseDivide( TaoVec* vv , TaoVec* ww){
664: int i,nn1,nn2,nn3,info;
665: TaoScalar *tptr1,*tptr2,*tptr3;
667: TaoFunctionBegin;
668: info = this->GetArray(&tptr1,&nn1);CHKERRQ(info);
669: if (this!=vv){
670: info = vv->GetArray(&tptr2,&nn2);CHKERRQ(info);
671: } else {
672: tptr2=tptr1; nn2=nn1;
673: }
674: if (this!=ww && vv!=ww){
675: info = ww->GetArray(&tptr3,&nn3);CHKERRQ(info);
676: } else if (vv==ww){
677: tptr3=tptr2; nn3=nn2;
678: } else {
679: tptr3=tptr1; nn3=nn1;
680: }
681: if (nn1!=nn2 || nn2!=nn3) {TaoFunctionReturn(1);}
682: for (i=0;i<nn1;i++) tptr1[i]=tptr2[i] / tptr3[i];
683: info = this->RestoreArray(&tptr1,&nn1);CHKERRQ(info);
684: if (this!=vv){
685: info = vv->RestoreArray(&tptr2,&nn2);CHKERRQ(info);
686: }
687: if (this!=ww && vv!=ww){
688: info = ww->RestoreArray(&tptr3,&nn3);CHKERRQ(info);
689: }
690: TaoFunctionReturn(0);
691: }
695: /*@C
696: Median - Computes the componentwise median of three vectors
697: and stores the result in this vector.
699: Input Parameters:
700: . vv, ww, xx - the three vectors
702: Level: intermediate
704: @*/
705: int TaoVec::Median( TaoVec* vv, TaoVec* ww, TaoVec* xx){
706: int i,nn1,nn2,nn3,nn4,info;
707: TaoScalar *tptr1,*tptr2,*tptr3,*tptr4;
709: TaoFunctionBegin;
710: info = this->GetArray(&tptr1,&nn1);CHKERRQ(info);
711: if (this!=vv){
712: info = vv->GetArray(&tptr2,&nn2);CHKERRQ(info);
713: } else {
714: tptr2=tptr1; nn2=nn1;
715: }
716: if (this!=ww){
717: info = ww->GetArray(&tptr3,&nn3);CHKERRQ(info);
718: } else {
719: tptr3=tptr1; nn3=nn1;
720: }
721: if (this!=xx){
722: info = xx->GetArray(&tptr4,&nn4);CHKERRQ(info);
723: } else {
724: tptr4=tptr1; nn4=nn1;
725: }
727: if (nn1!=nn2 || nn2!=nn3 || nn3!=nn4) {TaoFunctionReturn(1);}
728: for (i=0;i<nn1;i++){
729: if (tptr2[i]<=tptr3[i] && tptr3[i] <= tptr4[i]){
730: tptr1[i]=tptr3[i];
731: } else if (tptr4[i]<=tptr3[i] && tptr3[i] <= tptr2[i]){
732: tptr1[i]=tptr3[i];
733: } else if (tptr3[i]<=tptr2[i] && tptr2[i] <= tptr4[i]){
734: tptr1[i]=tptr2[i];
735: } else if (tptr4[i]<=tptr2[i] && tptr2[i] <= tptr3[i]){
736: tptr1[i]=tptr2[i];
737: } else {
738: tptr1[i]=tptr4[i];
739: }
740: }
741: info = this->RestoreArray(&tptr1,&nn1);CHKERRQ(info);
742: if (this!=vv){
743: info = vv->RestoreArray(&tptr2,&nn2);CHKERRQ(info);
744: }
745: if (this!=ww){
746: info = ww->RestoreArray(&tptr3,&nn3);CHKERRQ(info);
747: }
748: if (this!=xx){
749: info = xx->RestoreArray(&tptr4,&nn4);CHKERRQ(info);
750: }
751: TaoFunctionReturn(0);
752: }
756: /*@C
757: PointwiseMinimum - Computes the componentwise minimum of two vectors
758: and stores the result in this vector.
760: Input Parameters:
761: . vv, ww - the two vectors
763: Level: intermediate
765: .seealso TaoVec::PointwiseMaximum()
766: @*/
767: int TaoVec::PointwiseMinimum( TaoVec* vv, TaoVec* ww){
768: int i,nn1,nn2,nn3,info;
769: TaoScalar *tptr1,*tptr2,*tptr3;
771: TaoFunctionBegin;
772: info = this->GetArray(&tptr1,&nn1);CHKERRQ(info);
773: if (vv!=this){
774: info = vv->GetArray(&tptr2,&nn2);CHKERRQ(info);
775: } else {
776: tptr2=tptr1; nn2=nn1;
777: }
778: if (ww!=this){
779: info = ww->GetArray(&tptr3,&nn3);CHKERRQ(info);
780: } else {
781: tptr3=tptr1; nn3=nn1;
782: }
784: if (nn1!=nn2 || nn2!=nn3) {TaoFunctionReturn(1);}
785: for (i=0;i<nn1;i++) tptr1[i] = TaoMin( tptr2[i] , tptr3[i]);
786: info = this->RestoreArray(&tptr1,&nn1);CHKERRQ(info);
787: if (vv!=this){
788: info = vv->RestoreArray(&tptr2,&nn2);CHKERRQ(info);
789: }
790: if (ww!=this){
791: info = ww->RestoreArray(&tptr3,&nn3);CHKERRQ(info);
792: }
793: TaoFunctionReturn(0);
794: }
798: /*@C
799: PointwiseMaximum - Computes the componentwise minimum of two vectors
800: and stores the result in this vector.
802: Input Parameters:
803: . vv, ww - the two vectors
805: Level: intermediate
807: .seealso TaoVec::PointwiseMinimum()
808: @*/
809: int TaoVec::PointwiseMaximum( TaoVec* vv, TaoVec* ww){
810: int i,nn1,nn2,nn3,info;
811: TaoScalar *tptr1,*tptr2,*tptr3;
813: TaoFunctionBegin;
814: info = this->GetArray(&tptr1,&nn1);CHKERRQ(info);
815: if (vv!=this){
816: info = vv->GetArray(&tptr2,&nn2);CHKERRQ(info);
817: } else {
818: tptr2=tptr1; nn2=nn1;
819: }
820: if (ww!=this){
821: info = ww->GetArray(&tptr3,&nn3);CHKERRQ(info);
822: } else {
823: tptr3=tptr1; nn3=nn1;
824: }
825: if (nn1!=nn2 || nn2!=nn3) {TaoFunctionReturn(1);}
826: for (i=0;i<nn1;i++) tptr1[i] = TaoMax( tptr2[i] , tptr3[i]);
827: info = this->RestoreArray(&tptr1,&nn1);CHKERRQ(info);
828: if (vv!=this){
829: info = vv->RestoreArray(&tptr2,&nn2);CHKERRQ(info);
830: }
831: if (ww!=this){
832: info = ww->RestoreArray(&tptr3,&nn3);CHKERRQ(info);
833: }
834: TaoFunctionReturn(0);
835: }
839: /*@C
840: Waxpby - Sums two scaled vectors and stores the result in this vector. (this=alpha*xx+beta*yy)
842: Input Parameters:
843: + a - the multiple of the first vector
844: . xx - the first vector
845: . b - the multiple of the second vector
846: - yy - the second vector
848: Level: intermediate
850: .seealso TaoVec::Axpy(), TaoVec::Axpby(), TaoVec::Aypx();
851: @*/
852: int TaoVec::Waxpby ( double a, TaoVec* xx, double b, TaoVec* yy){
853: int i,nn1,nn2,nn3,info;
854: TaoScalar *tptr1,*tptr2,*tptr3;
856: TaoFunctionBegin;
857: info = this->GetArray(&tptr1,&nn1);CHKERRQ(info);
858: info = xx->GetArray(&tptr2,&nn2);CHKERRQ(info);
859: info = yy->GetArray(&tptr3,&nn3);CHKERRQ(info);
860: if (nn1!=nn2 || nn2!=nn3) {TaoFunctionReturn(1);}
861: for (i=0;i<nn1;i++){ tptr1[i] = a * tptr2[i] + b * tptr3[i]; }
862: info = this->RestoreArray(&tptr1,&nn1);CHKERRQ(info);
863: info = xx->RestoreArray(&tptr2,&nn2);CHKERRQ(info);
864: info = yy->RestoreArray(&tptr3,&nn3);CHKERRQ(info);
865: TaoFunctionReturn(0);
866: }
870: /*@C
871: AbsoluteValue - Sets each element of this vector equal to its magnitude.
873: Input Parameters: none
875: Level: intermediate
876: @*/
877: int TaoVec::AbsoluteValue(){
878: int i,nn,info;
879: TaoScalar *v;
881: TaoFunctionBegin;
882: info = this->GetArray(&v,&nn);CHKERRQ(info);
883: for (i=0;i<nn;i++){
884: v[i]= TaoAbsScalar(v[i]);
885: }
886: info = this->RestoreArray(&v,&nn);CHKERRQ(info);
887: TaoFunctionReturn(0);
888: }
892: /*@C
893: MinElement - Finds the smallest element of this vector.
895: Output Parameter:
896: . val - the smallest value in the vector
898: Level: intermediate
899: @*/
900: int TaoVec::MinElement(double *val){
901: int i,nn,info;
902: TaoScalar dd=TAO_INFINITY,*v;
904: TaoFunctionBegin;
905: info = this->GetArray(&v,&nn);CHKERRQ(info);
906: for (i=0;i<nn;i++){
907: if (v[i]<dd) dd=v[i];
908: }
909: info = this->RestoreArray(&v,&nn);CHKERRQ(info);
910: *val = dd;
911: TaoFunctionReturn(0);
912: }
916: /*@C
917: Sign - Replace each element of this vector with -1, 0, or 1, depending on its sign.
919: Level: intermediate
920: @*/
921: int TaoVec::Sign(){
922: int i,nn,info;
923: TaoScalar *v;
925: TaoFunctionBegin;
926: info = this->GetArray(&v,&nn);CHKERRQ(info);
927: for (i=0;i<nn;i++){
928: if (v[i]<0){
929: v[i]=-1;
930: } else if (v[i]>0){
931: v[i]=1.0;
932: } else {
933: v[i]=0.0;
934: }
935: }
936: info = this->RestoreArray(&v,&nn);CHKERRQ(info);
937: TaoFunctionReturn(0);
938: }
942: /*@C
943: SetReducedVec - Sets the reduced space of the vector that this
944: vector should represent. The index set describes which
945: elements of the vector should be used. This routine also
946: copies the appropriate elements from the full space vector
947: into the reduced space vector.
949: Input Parameters:
950: + vv - a vector
951: - ss - an index set
953: Level: advanced
955: .seealso TaoVec::CreateReducedVec(), TaoVec::ReducedCopyFromFull(), TaoVec::ReducedXPY(), TaoSelectSubset()
956: @*/
957: int TaoVec::SetReducedVec(TaoVec* vv,TaoIndexSet* ss){
958: TaoFunctionBegin;
959: SETERRQ(56,"Operation not defined");
960: /* TaoFunctionReturn(1); */
961: }
965: /*@C
966: ReducedCopyFromFull - Copies the appropriate elements of the vector into
967: this reduced vector.
968:
969: Input Parameters:
970: + ss - an index set
971: - vv - a full vector
973: Level: advanced
975: .seealso TaoVec::CreateReducedVec(), TaoVec::ReducedXPY()
976: @*/
977: int TaoVec::ReducedCopyFromFull(TaoVec* vv, TaoIndexSet* ss){
978: TaoFunctionBegin;
979: SETERRQ(56,"Operation not defined");
980: /* TaoFunctionReturn(1); */
981: }
985: /*@C
986: ReducedXPY - Adds a reduced vector to the appropriate elements of this vector.
987:
988: Input Parameters:
989: + vv - the reduced vector
990: - ss - the index set identifying which elements of this vector should be supplemented
992: Level: advanced
994: .seealso TaoVec::CreateReducedVec(), TaoVec::ReducedCopyFromFull()
995: @*/
996: int TaoVec::ReducedXPY(TaoVec* vv, TaoIndexSet* ss){
997: TaoFunctionBegin;
998: SETERRQ(56,"Operation not defined");
999: /* TaoFunctionReturn(1); */
1000: }
1004: /*@C
1005: StepMax - Calculates the largest multiple of a vector that can be added to
1006: this vector while keeping each element of this vector nonnegative.
1007:
1008: Input Parameters:
1009: . vv - the step direction
1011: Input Parameters:
1012: . step1 - the maximum stepsize
1014: Note:
1015: This vector should contain all positive elements.
1017: Note:
1018: If there is no maximum steplength, the output scalar may be set
1019: to TAO_INFINITY.
1021: Level: advanced
1022: @*/
1023: int TaoVec::StepMax(TaoVec* vv,double *step1){
1024: int i,nn1,nn2,info;
1025: TaoScalar *xx,*dx;
1026: double stepmax1=TAO_INFINITY;
1028: TaoFunctionBegin;
1029: info = this->GetArray(&xx,&nn1);CHKERRQ(info);
1030: if (this!=vv){
1031: info = vv->GetArray(&dx,&nn2);CHKERRQ(info);
1032: if (nn1!=nn2) {TaoFunctionReturn(1);}
1033: for (i=0;i<nn1;i++){
1034: if (xx[i] < 0){
1035: TaoFunctionReturn(1);
1036: } else if (dx[i]<0){
1037: stepmax1=TaoMin(stepmax1,-xx[i]/dx[i]);
1038: }
1039: }
1040: info = vv->RestoreArray(&dx,&nn2);CHKERRQ(info);
1041: *step1=stepmax1;
1042: } else {
1043: *step1=1.0;
1044: }
1045: info = this->RestoreArray(&xx,&nn1);CHKERRQ(info);
1046: TaoFunctionReturn(0);
1047: }
1049: /*@C
1050: StepBoundInfo - Calculates the largest multiple of a vector that can be added to
1051: this vector while keeping each element of this vector nonnegative.
1052:
1053: Input Parameters:
1054: + txl - the lower bounds on this vector
1055: . txu - the upper bounds on this vector
1056: - tdx - the step direction for this vector
1058: Output Parameters:
1059: + boundmin - the step to closest bound i.e min(a1, ..., an);
1060: . wolfemin - the step to closest bound not equal i.e min(b1, ..., bn);
1061: - boundmax - the step to farthest bound i.e. max(c1, ..., cn);
1063: Where:
1064: if tdx[i] > 0; ai = (txu[i] - this[i])/tdx[i] ; bi=ai, ci=ai;
1065: if tdx[i] < 0; ai = (txl[i] - this[i])/tdx[i] ; bi=ai, ci=ai
1066: if tdx[i] == 0 && txl[i] < x[i] < txu[i] ; ai=TAO_INFINITY, bi=ai, ci=ai;
1067: if tdx[i] == 0 && (txl[i] == x[i] || txu[i] == x[i]) ; ai= 0, bi=TAO_INFINITY, ci=0;
1068:
1069: Note:
1070: If there is no maximum steplength, the output scalar may be set
1071: to TAO_INFINITY.
1073: Level: advanced
1074: @*/
1075: int TaoVec::StepBoundInfo(TaoVec* XL ,TaoVec* XU, TaoVec*S, double *bmin1,double *bmin2, double *bmax){
1076: TaoFunctionBegin;
1077: SETERRQ(56,"Operation not defined");
1078: /* TaoFunctionReturn(1); */
1079: }
1083: /*@C
1084: View - Views the contents of the vector.
1085:
1086: Input Parameters: none
1087:
1088: Level: intermediate
1089: @*/
1090: int TaoVec::View(){
1091: TaoFunctionBegin;
1092: SETERRQ(56,"Operation not defined");
1093: /* TaoFunctionReturn(1); */
1094: }
1098: /*@C
1099: BoundGradientProjection - Projects this vector according to this definition.
1100: If XX[i]==XXL[i], then this[i] = min(G[i],0);
1101: If XX[i]==XXU[i], then this[i] = max(G[i],0);
1102: else this[i] = G[i];
1104: Input Parameters:
1105: . GG,XX,XXL,XXU - the vectors.
1107: Level: advanced
1108: @*/
1109: int TaoVec::BoundGradientProjection(TaoVec* gg,TaoVec* xxll,TaoVec* xx, TaoVec* xxuu){
1110: int i,nn1,nn2,nn3,nn4,nn5,info;
1111: TaoScalar *xptr,*xlptr,*xuptr,*gptr,*gpptr;
1113: TaoFunctionBegin;
1114: info = this->GetArray(&gpptr,&nn1);CHKERRQ(info);
1115: if (this != gg){
1116: info = gg->GetArray(&gptr,&nn2);CHKERRQ(info);
1117: } else {
1118: gptr=gpptr; nn2=nn1;
1119: }
1120: info = xxll->GetArray(&xlptr,&nn3);CHKERRQ(info);
1121: info = xx->GetArray(&xptr,&nn4);CHKERRQ(info);
1122: info = xxuu->GetArray(&xuptr,&nn5);CHKERRQ(info);
1123: if (nn1!=nn2 || nn2!=nn3 || nn3!=nn4 || nn4!=nn5) {TaoFunctionReturn(1);}
1125: for (i=0; i<nn1; i++){
1127: gpptr[i] = gptr[i];
1128: if (gpptr[i]>0 && xptr[i]<=xlptr[i]){
1129: gpptr[i] = 0;
1130: } else if (gpptr[i]<0 && xptr[i]>=xuptr[i]){
1131: gpptr[i] = 0;
1132: }
1133: }
1134: info = this->RestoreArray(&gpptr,&nn1);CHKERRQ(info);
1135: if (this!=gg){
1136: info = gg->RestoreArray(&gptr,&nn2);CHKERRQ(info);
1137: }
1138: info = xxll->RestoreArray(&xlptr,&nn3);CHKERRQ(info);
1139: info = xx->RestoreArray(&xptr,&nn4);CHKERRQ(info);
1140: info = xxuu->RestoreArray(&xuptr,&nn5);CHKERRQ(info);
1142: TaoFunctionReturn(0);
1143: }
1147: /*@C
1148: GetArray - Sets a pointer to the first element in the vector array.
1150: Output Parameters:
1151: + dptr - pointer an the array of numbers
1152: - n - the length of the array
1154: Note:
1155: This operation may not be defined the same for all vector types.
1157: Level: intermediate
1159: .seealso TaoVec::RestoreArray()
1160: @*/
1161: int TaoVec::GetArray(TaoScalar **dptr, int *n){
1162: TaoFunctionBegin;
1163: SETERRQ(56,"Operation not defined");
1164: /* TaoFunctionReturn(1); */
1165: }
1169: /*@C
1170: RestoreArray - Returns a pointer to the first element in the vector array.
1172: Input Parameters:
1173: + dptr - pointer an the array of numbers obtained from TaoVec::GetArray
1174: - n - the length of the array
1176: Note:
1177: This routine is not used within TAO solvers. Rather, it is used to
1178: implement other routines.
1180: Level: intermediate
1182: .seealso TaoVec::GetArray()
1183: @*/
1184: int TaoVec::RestoreArray(TaoScalar **dptr, int *n){
1185: TaoFunctionBegin;
1186: *dptr=NULL;
1187: *n=0;
1188: TaoFunctionReturn(0);
1189: }
1193: /*@C
1194: CreateIndexSet - Creates an index set that may be used to describe sets of
1195: elements of this vector.
1197: Output Parameters:
1198: . ss - a new index set
1200: Level: advanced
1201: @*/
1202: int TaoVec::CreateIndexSet(TaoIndexSet **ss){
1203: TaoFunctionBegin;
1204: SETERRQ(56,"Operation not defined");
1205: /* TaoFunctionReturn(1); */
1206: }
1208: inline static double fischer(double a, double b)
1209: {
1210: // Method suggested by Bob Vanderbei
1211: if (a + b <= 0) {
1212: return sqrt(a*a + b*b) - (a + b);
1213: }
1214: return -2.0*a*b / (sqrt(a*a + b*b) + (a + b));
1215: }
1219: /*@C
1220: Fischer - Evaluates the Fischer-Burmeister function for complementarity
1221: problems.
1222:
1223: Input Parameters:
1224: + xx - current point
1225: . ff - function evaluated at x
1226: . ll - lower bounds
1227: - uu - upper bounds
1229: Notes:
1230: The Fischer-Burmeister function is defined as
1231: $ phi(a,b) := sqrt(a*a + b*b) - a - b
1232: and is used reformulate a complementarity problem as a semismooth
1233: system of equations.
1235: The result of this function is done by cases:
1236: + l[i] == -infinity, u[i] == infinity -- fb[i] = -f[i]
1237: . l[i] == -infinity, u[i] finite -- fb[i] = phi(u[i]-x[i], -f[i])
1238: . l[i] finite, u[i] == infinity -- fb[i] = phi(x[i]-l[i], f[i])
1239: . l[i] finite < u[i] finite -- fb[i] = phi(x[i]-l[i], phi(u[i]-x[i], -f[u]))
1240: - otherwise l[i] == u[i] -- fb[i] = l[i] - x[i]
1242: Level: advanced
1244: .seealso TaoMat::D_Fischer()
1245: @*/
1246: int TaoVec::Fischer(TaoVec* xx, TaoVec* ff, TaoVec* ll, TaoVec* uu)
1247: {
1248: int i,nn1,nn2,nn3,nn4,nn5,info;
1249: TaoScalar *v,*x,*f,*l,*u;
1251: TaoFunctionBegin;
1252: info = this->GetArray(&v,&nn1); CHKERRQ(info);
1253: info = xx->GetArray(&x,&nn2); CHKERRQ(info);
1254: info = ff->GetArray(&f,&nn3); CHKERRQ(info);
1255: info = ll->GetArray(&l,&nn4); CHKERRQ(info);
1256: info = uu->GetArray(&u,&nn5); CHKERRQ(info);
1257: if (nn1!=nn2 || nn2!=nn3 || nn3!=nn4 || nn4!=nn5) {
1258: TaoFunctionReturn(1);
1259: }
1261: for (i=0;i<nn1;i++) {
1263: if ((l[i] <= -TAO_INFINITY) && (u[i] >= TAO_INFINITY)) {
1264: v[i] = -f[i];
1265: }
1266: else if (l[i] <= -TAO_INFINITY) {
1267: v[i] = -fischer(u[i] - x[i], -f[i]);
1268: }
1269: else if (u[i] >= TAO_INFINITY) {
1270: v[i] = fischer(x[i] - l[i], f[i]);
1271: }
1272: else if (l[i] == u[i]) {
1273: v[i] = l[i] - x[i];
1274: }
1275: else {
1276: v[i] = fischer(u[i] - x[i], -f[i]);
1277: v[i] = fischer(x[i] - l[i], v[i]);
1278: }
1280: }
1282: info = this->RestoreArray(&v,&nn1);CHKERRQ(info);
1283: info = xx->RestoreArray(&x,&nn2);CHKERRQ(info);
1284: info = ff->RestoreArray(&f,&nn3);CHKERRQ(info);
1285: info = ll->RestoreArray(&l,&nn4);CHKERRQ(info);
1286: info = uu->RestoreArray(&u,&nn5);CHKERRQ(info);
1288: TaoFunctionReturn(0);
1289: }
1291: inline static double sfischer(double a, double b, double c)
1292: {
1293: // Method suggested by Bob Vanderbei
1294: if (a + b <= 0) {
1295: return sqrt(a*a + b*b + 2.0*c*c) - (a + b);
1296: }
1297: return 2.0*(c*c - a*b) / (sqrt(a*a + b*b + 2.0*c*c) + (a + b));
1298: }
1302: /*@C
1303: SFischer - Evaluates the Smoothed Fischer-Burmeister function for
1304: complementarity problems.
1306: Input Parameters:
1307: + xx - current point
1308: . ff - function evaluated at x
1309: . ll - lower bounds
1310: . uu - upper bounds
1311: - mu - smoothing parameter
1313: Notes:
1314: The Smoothed Fischer-Burmeister function is defined as
1315: $ phi(a,b) := sqrt(a*a + b*b + 2*mu*mu) - a - b
1316: and is used reformulate a complementarity problem as a semismooth
1317: system of equations.
1319: The result of this function is done by cases:
1320: + l[i] == -infinity, u[i] == infinity -- fb[i] = -f[i] - 2*mu*x[i]
1321: . l[i] == -infinity, u[i] finite -- fb[i] = phi(u[i]-x[i], -f[i], mu)
1322: . l[i] finite, u[i] == infinity -- fb[i] = phi(x[i]-l[i], f[i], mu)
1323: . l[i] finite < u[i] finite -- fb[i] = phi(x[i]-l[i], phi(u[i]-x[i], -f[u], mu), mu)
1324: - otherwise l[i] == u[i] -- fb[i] = l[i] - x[i]
1326: Level: advanced
1328: .seealso TaoMat::SD_Fischer()
1329: @*/
1330: int TaoVec::SFischer(TaoVec* xx, TaoVec* ff, TaoVec* ll, TaoVec* uu, double mu)
1331: {
1333: int i, nn1, nn2, nn3, nn4, nn5, info;
1334: TaoScalar *v, *x, *f, *l, *u;
1336: TaoFunctionBegin;
1338: if ((mu >= -TAO_EPSILON) && (mu <= TAO_EPSILON)) {
1339: Fischer(xx, ff, ll, uu);
1340: }
1341: else {
1342: info = this->GetArray(&v, &nn1); CHKERRQ(info);
1343: info = xx->GetArray(&x, &nn2); CHKERRQ(info);
1344: info = ff->GetArray(&f, &nn3); CHKERRQ(info);
1345: info = ll->GetArray(&l, &nn4); CHKERRQ(info);
1346: info = uu->GetArray(&u, &nn5); CHKERRQ(info);
1348: if (nn1!=nn2 || nn2!=nn3 || nn3!=nn4 || nn4!=nn5) {
1349: TaoFunctionReturn(1);
1350: }
1352: for (i = 0; i < nn1; ++i) {
1353: if ((l[i] <= -TAO_INFINITY) && (u[i] >= TAO_INFINITY)) {
1354: v[i] = -f[i] - mu*x[i];
1355: }
1356: else if (l[i] <= -TAO_INFINITY) {
1357: v[i] = -sfischer(u[i] - x[i], -f[i], mu);
1358: }
1359: else if (u[i] >= TAO_INFINITY) {
1360: v[i] = sfischer(x[i] - l[i], f[i], mu);
1361: }
1362: else if (l[i] == u[i]) {
1363: v[i] = l[i] - x[i];
1364: }
1365: else {
1366: v[i] = sfischer(u[i] - x[i], -f[i], mu);
1367: v[i] = sfischer(x[i] - l[i], v[i], mu);
1368: }
1369: }
1371: info = this->RestoreArray(&v, &nn1); CHKERRQ(info);
1372: info = xx->RestoreArray(&x, &nn2); CHKERRQ(info);
1373: info = ff->RestoreArray(&f, &nn3); CHKERRQ(info);
1374: info = ll->RestoreArray(&l, &nn4); CHKERRQ(info);
1375: info = uu->RestoreArray(&u, &nn5); CHKERRQ(info);
1376: }
1377: TaoFunctionReturn(0);
1378: }