1 // -*- mode:C++ ; compile-command: "g++ -I.. -g -c unary.cc -DIN_GIAC -DHAVE_CONFIG_H" -*-
2 #include "giacPCH.h"
3 
4 /*
5  *  Copyright (C) 2000,14 B. Parisse, Institut Fourier, 38402 St Martin d'Heres
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 3 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program. If not, see <http://www.gnu.org/licenses/>.
19  */
20 using namespace std;
21 #include "unary.h"
22 #include "gen.h"
23 #include "usual.h"
24 #include "rpn.h"
25 #include "tex.h"
26 #include "input_lexer.h"
27 #include "symbolic.h"
28 #include "input_lexer.h"
29 #include "rpn.h"
30 #include "sparse.h"
31 #include "giacintl.h"
32 
33 #ifndef NO_NAMESPACE_GIAC
34 namespace giac {
35 #endif // ndef NO_NAMESPACE_GIAC
36   // unary_function_ptr
37 
operator ()(const gen & arg,const context * context_ptr) const38   gen unary_function_ptr::operator () (const gen & arg,const context * context_ptr) const{
39     return (*ptr())(arg,context_ptr);
40     // return (*ptr)(arg,context_ptr);
41     this->dbgprint();
42   }
43 
dbgprint() const44   const char * unary_function_ptr::dbgprint() const {
45 #ifndef NSPIRE
46     CERR << ptr()->s << endl;
47 #endif
48     return ptr()->s;
49   }
50 
51 #if 0 // def x86_64
52   bool unary_function_ptr::quoted() const { return (ptr()->index_quoted_function & 0x1) || ( ((longlong) _ptr) & 0x1); }
53 #else
quoted() const54   bool unary_function_ptr::quoted() const { return (ptr()->index_quoted_function & 0x1) || ( ((size_t) _ptr) & 0x1); }
55 #endif
56 
57   /*
58   unary_function_ptr::unary_function_ptr(const unary_function_ptr & myptr):ptr(myptr.ptr),ref_count(myptr.ref_count),quoted(myptr.quoted){
59     if (ref_count)
60       ++(*ref_count);
61   }
62 
63   // dynamic unary_function_abstract
64   unary_function_ptr::unary_function_ptr(const unary_function_abstract & myptr): quoted(0) {
65     ref_count = new int(1);
66     ptr = myptr.recopie();
67   }
68 
69   unary_function_ptr::unary_function_ptr(const unary_function_abstract & myptr,int myquoted,int parser_token): quoted(myquoted) {
70     ptr = myptr.recopie();
71     if (parser_token)
72       if (!lexer_functions_register(*this,ptr->s,parser_token))
73 	setsizeerr(gettext("Unable to register ")+ptr->s);
74   }
75   */
76 
77   // global unary_function_abstract pointer, no reference count here
78 
79 #ifdef NO_UNARY_FUNCTION_COMPOSE
unary_function_ptr(const unary_function_eval * myptr,int myquoted,int parser_token)80   unary_function_ptr::unary_function_ptr(const unary_function_eval * myptr,int myquoted,int parser_token): _ptr((size_t)myptr){
81     if (myquoted)
82       *((size_t *) &_ptr) |= 0x1;
83     if (parser_token)
84       if (!lexer_functions_register(*this,myptr->s,parser_token))
85 	setsizeerr(gettext("Unable to register ")+string(myptr->s));
86   }
87 
unary_function_ptr(const alias_unary_function_eval * myptr,int myquoted,int parser_token)88   unary_function_ptr::unary_function_ptr(const alias_unary_function_eval * myptr,int myquoted,int parser_token):_ptr((size_t)myptr) {
89     if (myquoted)
90       *((size_t *) &_ptr) |= 0x1;
91     if (parser_token)
92       if (!lexer_functions_register(*this,myptr->s,parser_token))
93 	setsizeerr(gettext("Unable to register ")+string(myptr->s));
94   }
95 
96   /*
97   unary_function_ptr::unary_function_ptr(const unary_function_eval * myptr,int parser_token): _ptr(myptr){
98     if (parser_token)
99       if (!lexer_functions_register(*this,myptr->s,parser_token))
100 	setsizeerr(gettext("Unable to register ")+string(myptr->s));
101   }
102   unary_function_ptr::unary_function_ptr(const alias_unary_function_eval * myptr,int parser_token):_ptr((const unary_function_eval *)myptr) {
103     if (parser_token)
104       if (!lexer_functions_register(*this,myptr->s,parser_token))
105 	setsizeerr(gettext("Unable to register ")+string(myptr->s));
106   }
107 
108   */
print(GIAC_CONTEXT) const109   const char * unary_function_eval::print(GIAC_CONTEXT) const {
110     if (abs_calc_mode(contextptr)==38){
111       if (calc_mode(contextptr)==38){
112 	const char * maj = hp38_display_in_maj(s);
113 	return maj?maj:s;
114       }
115       else
116 	return s;
117     }
118     int lang=language(contextptr);
119     multimap<string,localized_string>::iterator it=back_lexer_localization_map().find(s),backend=back_lexer_localization_map().end(),itend=back_lexer_localization_map().upper_bound(s);
120     if (it!=backend){
121       for (;it!=itend;++it){
122 	if (it->second.language==lang)
123 	  return it->second.chaine.c_str();
124       }
125     }
126     return s;
127   }
128 
129 #else //  NO_UNARY_FUNCTION_COMPOSE
unary_function_ptr(const unary_function_abstract * myptr,int myquoted,int parser_token)130   unary_function_ptr::unary_function_ptr(const unary_function_abstract * myptr,int myquoted,int parser_token): _ptr(myptr){
131     if (myquoted)
132       *((size_t *) &_ptr) |= 0x1;
133     if (parser_token)
134       if (!lexer_functions_register(*this,myptr->s,parser_token))
135 	setsizeerr(gettext("Unable to register ")+string(myptr->s));
136   }
137 
unary_function_ptr(const alias_unary_function_eval * myptr,int myquoted,int parser_token)138   unary_function_ptr::unary_function_ptr(const alias_unary_function_eval * myptr,int myquoted,int parser_token):_ptr((const unary_function_abstract *)myptr) {
139     if (myquoted)
140       *((size_t *) &_ptr) |= 0x1;
141     if (parser_token)
142       if (!lexer_functions_register(*this,myptr->s,parser_token))
143 	setsizeerr(gettext("Unable to register ")+string(myptr->s));
144   }
145 
146   /*
147   unary_function_ptr::unary_function_ptr(const unary_function_abstract * myptr,int parser_token): _ptr(myptr){
148     if (parser_token)
149       if (!lexer_functions_register(*this,myptr->s,parser_token))
150 	setsizeerr(gettext("Unable to register ")+string(myptr->s));
151   }
152 
153   unary_function_ptr::unary_function_ptr(const alias_unary_function_eval * myptr,int parser_token):_ptr((const unary_function_abstract *)myptr) {
154     if (parser_token)
155       if (!lexer_functions_register(*this,myptr->s,parser_token))
156 	setsizeerr(gettext("Unable to register ")+string(myptr->s));
157   }
158   */
159 
print(GIAC_CONTEXT) const160   const char * unary_function_abstract::print(GIAC_CONTEXT) const {
161     if (abs_calc_mode(contextptr)==38){
162       if (calc_mode(contextptr)==38){
163 	const char * maj = hp38_display_in_maj(s);
164 	return maj?maj:s;
165       }
166       return s;
167     }
168     int lang=language(contextptr);
169     multimap<string,localized_string>::iterator it=back_lexer_localization_map().find(s),backend=back_lexer_localization_map().end(),itend=back_lexer_localization_map().upper_bound(s);
170     if (it!=backend){
171       for (;it!=itend;++it){
172 	if (it->second.language==lang)
173 	  return it->second.chaine.c_str();
174       }
175     }
176     return s;
177   }
178 #endif //  NO_UNARY_FUNCTION_COMPOSE
179 
180   /*
181   // copy constructor
182   unary_function_ptr & unary_function_ptr::operator = (const unary_function_ptr & acopier){
183     if (ref_count){
184       if (!((*ref_count)--)){
185 	delete ptr;
186 	delete ref_count;
187       }
188     }
189     ptr = acopier.ptr;
190     ref_count=acopier.ref_count;
191     quoted = acopier.quoted;
192     if (ref_count)
193       ++(*ref_count);
194     return *this;
195   }
196 
197   unary_function_ptr::~unary_function_ptr(){
198     if (ref_count){
199       if (!((*ref_count)--)){
200 	delete ptr;
201 	delete ref_count;
202       }
203     }
204   }
205   */
206 
apply(const gen & e,const unary_function_ptr & f,GIAC_CONTEXT)207   gen apply(const gen & e,const unary_function_ptr & f,GIAC_CONTEXT){
208     if (e.type==_MAP){
209       gen_map res;
210       gen g(res);
211       map_apply(*e._MAPptr,f,*g._MAPptr,contextptr);
212       return g;
213     }
214     if (e.type!=_VECT)
215       return f(e,contextptr);
216     const_iterateur it=e._VECTptr->begin(),itend=e._VECTptr->end();
217     //    if (itend==it && abs_calc_mode(contextptr)==38) return gensizeerr();
218     vecteur v;
219     v.reserve(itend-it);
220     for (;it!=itend;++it){
221       gen tmp=f(*it,contextptr);
222       if (is_undef(tmp))
223 	return gen2vecteur(tmp);
224       v.push_back(tmp);
225     }
226     return gen(v,e.subtype);
227   }
228 
apply(const gen & e,const unary_function_ptr * f,GIAC_CONTEXT)229   gen apply(const gen & e,const unary_function_ptr * f,GIAC_CONTEXT){
230     if (e.type!=_VECT)
231       return (*f)(e,contextptr);
232     const_iterateur it=e._VECTptr->begin(),itend=e._VECTptr->end();
233     // if (itend==it && abs_calc_mode(contextptr)==38) return gensizeerr();
234     vecteur v;
235     v.reserve(itend-it);
236     for (;it!=itend;++it){
237       gen tmp=(*f)(*it,contextptr);
238       if (is_undef(tmp))
239 	return gen2vecteur(tmp);
240       v.push_back(tmp);
241     }
242     return gen(v,e.subtype);
243   }
244 
apply(const gen & e,gen (* f)(const gen &))245   gen apply(const gen & e, gen (* f) (const gen &) ){
246     if (e.type!=_VECT)
247       return f(e);
248     const_iterateur it=e._VECTptr->begin(),itend=e._VECTptr->end();
249     vecteur v;
250     v.reserve(itend-it);
251     for (;it!=itend;++it){
252       gen tmp=f(*it);
253       if (is_undef(tmp))
254 	return gen2vecteur(tmp);
255       v.push_back(tmp);
256     }
257     return gen(v,e.subtype);
258   }
259 
apply(const gen & e,gen (* f)(const gen &,const context *),GIAC_CONTEXT)260   gen apply(const gen & e, gen (* f) (const gen &,const context *),GIAC_CONTEXT ){
261     if (e.type==_MAP){
262       gen_map res;
263       gen g(res);
264       map_apply(*e._MAPptr,*g._MAPptr,contextptr,f);
265       return g;
266     }
267     if (e.type!=_VECT)
268       return f(e,contextptr);
269     const_iterateur it=e._VECTptr->begin(),itend=e._VECTptr->end();
270     // if (itend==it && abs_calc_mode(contextptr)==38) return gensizeerr();
271     vecteur v;
272     v.reserve(itend-it);
273     for (;it!=itend;++it){
274       gen tmp=f(*it,contextptr);
275       if (is_undef(tmp))
276 	return gen2vecteur(tmp);
277       v.push_back(tmp);
278     }
279     return gen(v,e.subtype);
280   }
281 
apply(const gen & e1,const gen & e2,gen (* f)(const gen &,const gen &))282   gen apply(const gen & e1, const gen & e2,gen (* f) (const gen &, const gen &) ){
283     if ((e1.type!=_VECT) && (e2.type!=_VECT))
284       return f(e1,e2);
285     if (e1.type!=_VECT){
286       const_iterateur it=e2._VECTptr->begin(),itend=e2._VECTptr->end();
287       vecteur v;
288       v.reserve(itend-it);
289       for (;it!=itend;++it){
290 	gen tmp=f(e1,*it);
291 	if (is_undef(tmp))
292 	  return gen2vecteur(tmp);
293 	v.push_back(tmp);
294       }
295       return gen(v,e2.subtype);
296     }
297     if (e2.type!=_VECT){
298       const_iterateur it=e1._VECTptr->begin(),itend=e1._VECTptr->end();
299       vecteur v;
300       v.reserve(itend-it);
301       for (;it!=itend;++it){
302 	gen tmp=f(*it,e2);
303 	if (is_undef(tmp))
304 	  return gen2vecteur(tmp);
305 	v.push_back(tmp);
306       }
307       return gen(v,e1.subtype);
308     }
309     const_iterateur it1=e1._VECTptr->begin(),it1end=e1._VECTptr->end();
310     const_iterateur it2=e2._VECTptr->begin(),it2end=e2._VECTptr->end();
311     // if (it2end-it2!=it1end-it1) return gendimerr();
312     vecteur v;
313     v.reserve(it1end-it1);
314     for (;it1!=it1end && it2!=it2end;++it1,++it2){
315       gen tmp=f(*it1,*it2);
316       if (is_undef(tmp))
317 	return gen2vecteur(tmp);
318       v.push_back(tmp);
319     }
320     return gen(v,e1.subtype);
321   }
322 
apply(const gen & e,const context * contextptr,const gen_op_context & f)323   gen apply(const gen & e, const context * contextptr,const gen_op_context & f ){
324     if (e.type==_MAP){
325       gen_map res;
326       gen g(res);
327       map_apply(*e._MAPptr,*g._MAPptr,contextptr,f);
328       return g;
329     }
330     if (e.type!=_VECT)
331       return f(e,contextptr);
332     const_iterateur it=e._VECTptr->begin(),itend=e._VECTptr->end();
333     // if (itend==it && abs_calc_mode(contextptr)==38) return gensizeerr();
334     vecteur v;
335     v.reserve(itend-it);
336     for (;it!=itend;++it){
337       gen tmp=f(*it,contextptr);
338       if (is_undef(tmp))
339 	return gen2vecteur(tmp);
340       v.push_back(tmp);
341     }
342     return gen(v,e.subtype);
343   }
344 
apply(const gen & e1,const gen & e2,const context * contextptr,gen (* f)(const gen &,const gen &,const context *))345   gen apply(const gen & e1, const gen & e2,const context * contextptr,gen (* f) (const gen &, const gen &,const context *) ){
346     if ((e1.type!=_VECT) && (e2.type!=_VECT))
347       return f(e1,e2,contextptr);
348     if (e1.type!=_VECT){
349       const_iterateur it=e2._VECTptr->begin(),itend=e2._VECTptr->end();
350       vecteur v;
351       v.reserve(itend-it);
352       for (;it!=itend;++it){
353 	gen tmp=f(e1,*it,contextptr);
354 	if (is_undef(tmp))
355 	  return gen2vecteur(tmp);
356 	v.push_back(tmp);
357       }
358       return gen(v,e2.subtype);
359     }
360     if (e2.type!=_VECT){
361       const_iterateur it=e1._VECTptr->begin(),itend=e1._VECTptr->end();
362       vecteur v;
363       v.reserve(itend-it);
364       for (;it!=itend;++it){
365 	gen tmp=f(*it,e2,contextptr);
366 	if (is_undef(tmp))
367 	  return gen2vecteur(tmp);
368 	v.push_back(tmp);
369       }
370       return gen(v,e1.subtype);
371     }
372     const_iterateur it1=e1._VECTptr->begin(),it1end=e1._VECTptr->end();
373     const_iterateur it2=e2._VECTptr->begin(),it2end=e2._VECTptr->end();
374     // if (it2end-it2!=it1end-it1) return gendimerr();
375     vecteur v;
376     v.reserve(it1end-it1);
377     for (;it1!=it1end && it2!=it2end;++it1,++it2){
378       gen tmp=f(*it1,*it2,contextptr);
379       if (is_undef(tmp))
380 	return gen2vecteur(tmp);
381       v.push_back(tmp);
382     }
383     return gen(v,e1.subtype);
384   }
385 
apply1st(const gen & e1,const gen & e2,gen (* f)(const gen &,const gen &))386   gen apply1st(const gen & e1, const gen & e2,gen (* f) (const gen &, const gen &) ){
387     if (e1.type!=_VECT)
388       return f(e1,e2);
389     const_iterateur it=e1._VECTptr->begin(),itend=e1._VECTptr->end();
390     gen res=new ref_vecteur;
391     res.subtype=e1.subtype;
392     vecteur &v=*res._VECTptr;
393     v.reserve(itend-it);
394     for (;it!=itend;++it){
395       gen tmp=f(*it,e2);
396       if (is_undef(tmp))
397 	return gen2vecteur(tmp);
398       v.push_back(tmp);
399     }
400     return res;//gen(v,e1.subtype);
401   }
402 
apply1st(const gen & e1,const gen & e2,const context * contextptr,gen (* f)(const gen &,const gen &,const context *))403   gen apply1st(const gen & e1, const gen & e2,const context * contextptr, gen (* f) (const gen &, const gen &,const context *) ){
404     if (e1.type!=_VECT)
405       return f(e1,e2,contextptr);
406     const_iterateur it=e1._VECTptr->begin(),itend=e1._VECTptr->end();
407     gen res=new ref_vecteur;
408     res.subtype=e1.subtype;
409     vecteur &v=*res._VECTptr;
410     v.reserve(itend-it);
411     for (;it!=itend;++it){
412       gen tmp=f(*it,e2,contextptr);
413       if (is_undef(tmp))
414 	return gen2vecteur(tmp);
415       v.push_back(tmp);
416     }
417     return res;//gen(v,e1.subtype);
418   }
419 
apply2nd(const gen & e1,const gen & e2,gen (* f)(const gen &,const gen &))420   gen apply2nd(const gen & e1, const gen & e2,gen (* f) (const gen &, const gen &) ){
421     if (e2.type!=_VECT)
422       return f(e1,e2);
423     const_iterateur it=e2._VECTptr->begin(),itend=e2._VECTptr->end();
424     gen res=new ref_vecteur;
425     res.subtype=e2.subtype;
426     vecteur &v=*res._VECTptr;
427     v.reserve(itend-it);
428     for (;it!=itend;++it){
429       gen tmp=f(e1,*it);
430       if (is_undef(tmp))
431 	return gen2vecteur(tmp);
432       v.push_back(tmp);
433     }
434     return res; // gen(v,e2.subtype);
435   }
436 
apply2nd(const gen & e1,const gen & e2,const context * contextptr,gen (* f)(const gen &,const gen &,const context *))437   gen apply2nd(const gen & e1, const gen & e2,const context * contextptr, gen (* f) (const gen &, const gen &,const context *) ){
438     if (e2.type!=_VECT)
439       return f(e1,e2,contextptr);
440     const_iterateur it=e2._VECTptr->begin(),itend=e2._VECTptr->end();
441     gen res=new ref_vecteur;
442     res.subtype=e2.subtype;
443     vecteur &v=*res._VECTptr; //   vecteur v;
444     v.reserve(itend-it);
445     for (;it!=itend;++it){
446       gen tmp=f(e1,*it,contextptr);
447       if (is_undef(tmp))
448 	return gen2vecteur(tmp);
449       v.push_back(tmp);
450     }
451     return res;//gen(v,e2.subtype);
452   }
453 
454 #ifdef NO_UNARY_FUNCTION_COMPOSE
455 #ifdef NSPIRE
operator <<(nio::ios_base<T> & os,const unary_function_eval & o)456   template<class T> nio::ios_base<T> & operator << (nio::ios_base<T> & os,const unary_function_eval & o) { return os << o.s ; }
457 #else
operator <<(ostream & os,const unary_function_eval & o)458   ostream & operator << (ostream & os,const unary_function_eval & o) { return os << o.s ; }
459 #endif
460 #else
461   // unary_function_abstract
recopie() const462   unary_function_abstract * unary_function_abstract::recopie() const{
463     unary_function_abstract * ptr=new unary_function_abstract(index_quoted_function,s);
464     ptr->D = D;
465     return ptr;
466   }
467 
recopie() const468   unary_function_unary * unary_function_unary::recopie() const{
469     unary_function_unary * ptr=new unary_function_unary(index_quoted_function,op,s);
470     ptr->D = D;
471     return ptr;
472   }
473 
recopie() const474   unary_function_eval * unary_function_eval::recopie() const{
475     unary_function_eval * ptr=new unary_function_eval(index_quoted_function,op,s);
476     ptr->D = D;
477     return ptr;
478   }
479 
480   // I/O
operator <<(ostream & os,const unary_function_abstract & o)481   ostream & operator << (ostream & os,const unary_function_abstract & o){ return os << o.s; }
operator <<(ostream & os,const unary_function_unary & o)482   ostream & operator << (ostream & os,const unary_function_unary & o) { return os << o.s ; }
operator <<(ostream & os,const unary_function_eval & o)483   ostream & operator << (ostream & os,const unary_function_eval & o) { return os << o.s ; }
484 
recopie() const485   unary_function_compose * unary_function_compose::recopie() const{
486     unary_function_compose * ptr=new unary_function_compose(index_quoted_function,op_v);
487     ptr->D = D;
488     return ptr;
489   }
490 
recopie() const491   unary_function_list * unary_function_list::recopie() const{
492     unary_function_list * ptr=new unary_function_list(index_quoted_function,op_l);
493     ptr->D = D;
494     return ptr;
495   }
496 
recopie() const497   unary_function_constant * unary_function_constant::recopie() const{
498     unary_function_constant * ptr=new unary_function_constant(index_quoted_function,constant);
499     ptr->D = D;
500     return ptr;
501   }
502 
recopie() const503   unary_function_innerprod * unary_function_innerprod::recopie() const{
504     unary_function_innerprod * ptr=new unary_function_innerprod(index_quoted_function,i);
505     ptr->D = D;
506     return ptr;
507   }
508 
recopie() const509   unary_function_user * unary_function_user::recopie() const{
510     unary_function_user * ptr=new unary_function_user(index_quoted_function,f,s,printsommet,texprint,cprint);
511     ptr->D = D;
512     return ptr;
513   }
514 
515 
516   // unary_function_compose related
operator ()(const gen & arg,const context * context_ptr) const517   gen unary_function_compose::operator () (const gen & arg,const context * context_ptr) const{
518     vector<unary_function_ptr>::const_iterator it=op_v.begin(),itend=op_v.end();
519     gen res(arg);
520     for (;it!=itend;++it)
521       res=(*it)(res,context_ptr);
522     return res;
523   }
524 
unary_function_compose(unsigned u,const vector<unary_function_ptr> & myop_v)525   unary_function_compose::unary_function_compose(unsigned u,const vector<unary_function_ptr> & myop_v) : unary_function_abstract(u,0) {
526     string * sptr=new string(":: ");
527     vector<unary_function_ptr>::const_iterator it=myop_v.begin(),itend=myop_v.end();
528     for (;it!=itend;++it){
529       op_v.push_back( (*it) );
530       *sptr += it->ptr()->s;
531       *sptr +=" ";
532     }
533     *sptr += string(";");
534     s=sptr->c_str();
535   }
536 
operator ()(const gen & arg,const context * context_ptr) const537   gen unary_function_list::operator () (const gen & arg,const context * context_ptr) const{
538     vector<unary_function_ptr>::const_iterator it=op_l.begin(),itend=op_l.end();
539     vecteur res;
540     for (;it!=itend;++it)
541       res.push_back( (*it)(arg,context_ptr));
542     return res;
543   }
544 
unary_function_list(unsigned u,const vector<unary_function_ptr> & myop_v)545   unary_function_list::unary_function_list(unsigned u,const vector<unary_function_ptr> & myop_v) : unary_function_abstract(u,0) {
546     string * sptr=new string("{ ");
547     vector<unary_function_ptr>::const_iterator it=myop_v.begin(),itend=myop_v.end();
548     for (;it!=itend;++it){
549       op_l.push_back( (*it) );
550       *sptr += it->ptr()->s;
551       *sptr +=" ";
552     }
553     *sptr += string("}");
554     s=sptr->c_str();
555   }
556 
557 
operator ()(const gen & arg,const context * contextptr) const558   gen unary_function_innerprod::operator () (const gen & arg,const context * contextptr) const{
559     if (arg.type!=_VECT)
560       setsizeerr(arg.print(contextptr)+ gettext(" should be of type _VECT (unary.cc)"));
561     vecteur res;
562     // remove i indices from arg
563     vecteur::const_iterator jt=arg._VECTptr->begin(),jtend=arg._VECTptr->end();
564     vector<int>::const_iterator it=i.begin(), itend=i.end();
565     for (int j=0;jt!=jtend;++jt,++j){
566       if (it==itend)
567 	break;
568       else {
569 	if (j!=*it)
570 	  res.push_back(*jt);
571 	else
572 	  ++it;
573       }
574     }
575     for (;jt!=jtend;++jt)
576       res.push_back(*jt);
577     return res;
578   }
579 
operator <<(ostream & os,const unary_function_compose & p)580   ostream & operator << (ostream & os,const unary_function_compose & p){ return os << p.s;}
operator <<(ostream & os,const unary_function_list & p)581   ostream & operator << (ostream & os,const unary_function_list & p){ return os<< p.s; }
operator <<(ostream & os,const unary_function_constant & c)582   ostream & operator << (ostream & os,const unary_function_constant & c){ return os<< c.s; }
operator <<(ostream & os,const unary_function_innerprod & i)583   ostream & operator << (ostream & os,const unary_function_innerprod & i){ return os<< i.s; }
584 
585 #endif // NO_UNARY_FUNCTION_COMPOSE
586 
printsommetasoperator(const gen & feuille,const char * sommetstr_orig,GIAC_CONTEXT)587   string printsommetasoperator(const gen & feuille,const char * sommetstr_orig,GIAC_CONTEXT){
588     if (feuille.type!=_VECT)
589       return feuille.print(contextptr);
590     string sommetstr(sommetstr_orig);
591     if ( (sommetstr[0]>32 && isalpha(sommetstr[0])) || sommetstr[0]=='%' || sommetstr[0]=='.')
592       sommetstr=' '+sommetstr+' ';
593     vecteur::const_iterator itb=feuille._VECTptr->begin(),itend=feuille._VECTptr->end();
594     if (itb==itend)
595       return "";
596     string s;
597     if (itb->type==_FRAC && sommetstr!="=")
598       s='('+itb->print(contextptr)+')';
599     else {
600       if ( sommetstr=="=" || itb->type==_IDNT || (itb->type<=_CPLX && is_positive(*itb,contextptr)) )
601 	s=itb->print(contextptr);
602       else
603 	s='('+itb->print(contextptr)+')';
604     }
605     ++itb;
606     for (;;){
607       if (itb==itend)
608 	return s;
609       if ( (itb->type==_SYMB || itb->type==_FRAC || itb->type==_CPLX || (itb->type==_VECT && itb->subtype==_SEQ__VECT) ) && sommetstr!="." )
610 	s += sommetstr + '('+itb->print(contextptr)+")";
611       else
612 	s += sommetstr + itb->print(contextptr);
613       ++itb;
614     }
615   }
616 
texprintsommetasoperator(const gen & feuille,const char * sommetstr_orig,GIAC_CONTEXT)617   string texprintsommetasoperator(const gen & feuille,const char * sommetstr_orig,GIAC_CONTEXT){
618     if (feuille.type!=_VECT)
619       return feuille.print(contextptr);
620     string sommetstr(sommetstr_orig);
621     vecteur::const_iterator itb=feuille._VECTptr->begin(),itend=feuille._VECTptr->end();
622     if (itb==itend)
623       return "";
624     string s;
625     if (itb->type==_FRAC)
626       s="("+gen2tex(*itb,contextptr)+")";
627     else {
628       if ( sommetstr=="=" || itb->type==_IDNT || (itb->type<=_CPLX && is_positive(*itb,contextptr)) )
629 	s=gen2tex(*itb,contextptr);
630       else
631 	s="("+gen2tex(*itb,contextptr)+")";
632     }
633     ++itb;
634     for (;;){
635       if (itb==itend)
636 	return s;
637       if ( itb->type==_SYMB || itb->type==_FRAC || itb->type==_CPLX || (itb->type==_VECT && itb->subtype==_SEQ__VECT) )
638 	s += sommetstr + '('+gen2tex(*itb,contextptr)+")";
639       else
640 	s += sommetstr + gen2tex(*itb,contextptr);
641       ++itb;
642     }
643   }
644 
645 #ifdef NO_UNARY_FUNCTION_COMPOSE
646 
partial_derivative(gen (* mydf)(const gen & argss,const context * contextptr))647   partial_derivative::partial_derivative(gen (* mydf) (const gen & argss,const context * contextptr) ) :     df(unary_function_ptr(new unary_function_eval(0,mydf,""))) {}
648 
649 #else
partial_derivative_onearg(gen (* mydf)(const gen & args))650   partial_derivative_onearg::partial_derivative_onearg(gen (* mydf) (const gen & args) ) :     df(unary_function_ptr(new unary_function_unary(0,mydf,""))) {}
partial_derivative_onearg(gen (* mydf)(const gen & args,const context * contextptr))651   partial_derivative_onearg::partial_derivative_onearg(gen (* mydf) (const gen & args,const context * contextptr) ) :     df(unary_function_ptr(new unary_function_eval(0,mydf,""))) {}
652 #endif
653 
654 
655 #ifndef NO_NAMESPACE_GIAC
656 } // namespace giac
657 #endif // ndef NO_NAMESPACE_GIAC
658