/* -*- mode:C++ ; compile-command: "g++-3.4 -I.. -g -c permu.cc -DHAVE_CONFIG_H -DIN_GIAC" -*- */
#include "giacPCH.h"
/*
* Copyright (C) 2005, 2007 R. De Graeve & B. Parisse,
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
using namespace std;
#include
#include "permu.h"
#include "usual.h"
#include "sym2poly.h"
#include "rpn.h"
#include "prog.h"
#include "derive.h"
#include "subst.h"
#include "misc.h"
#include "plot.h"
#include "intg.h"
#include "ifactor.h"
#include "lin.h"
#include "modpoly.h"
#include "giacintl.h"
#ifndef NO_NAMESPACE_GIAC
namespace giac {
#endif // ndef NO_NAMESPACE_GIAC
vecteur vector_int_2_vecteur(const vector & v,GIAC_CONTEXT){
//transforme un vector en vecteur
vector::const_iterator it=v.begin(),itend=v.end();
vecteur res;
res.reserve(itend-it);
if (xcas_mode(contextptr) || abs_calc_mode(contextptr)==38){
for (;it!=itend;++it)
res.push_back(*it+1);
}
else {
for (;it!=itend;++it)
res.push_back(*it);
}
return res;
}
vecteur vector_int_2_vecteur(const vector & v){
//transforme un vector en vecteur
vector::const_iterator it=v.begin(),itend=v.end();
vecteur res;
res.reserve(itend-it);
for (;it!=itend;++it)
res.push_back(*it);
return res;
}
static vector vecteur_2_vector_int(const vecteur & v,GIAC_CONTEXT){
//transforme un vecteur en vector -> empty vector on error
vecteur::const_iterator it=v.begin(),itend=v.end();
vector res;
res.reserve(itend-it);
if (xcas_mode(contextptr) || abs_calc_mode(contextptr)==38){
for (;it!=itend;++it)
if ((*it).type==_INT_)
res.push_back((*it).val-1);
else
return vector(0);
}
else {
for (;it!=itend;++it)
if ((*it).type==_INT_)
res.push_back((*it).val);
else
return vector(0);
}
return res;
}
vector vecteur_2_vector_int(const vecteur & v){
//transforme un vecteur en vector -> empty vector on error
vecteur::const_iterator it=v.begin(),itend=v.end();
vector res;
res.reserve(itend-it);
for (;it!=itend;++it){
if ((*it).type==_INT_)
res.push_back((*it).val);
else
return vector(0);
}
return res;
}
static vector< vector > vecteur_2_vectvector_int(const vecteur & v,GIAC_CONTEXT){
//transforme un vecteur en vector< vector > -> empty vector on error
vecteur::const_iterator it=v.begin(),itend=v.end();
vector< vector > res;
res.reserve(itend-it);
for (;it!=itend;++it){
if (it->type!=_VECT)
return vector< vector >(0);
res.push_back(vecteur_2_vector_int(*it->_VECTptr,contextptr));
}
return res;
}
vector< vector > vecteur_2_vectvector_int(const vecteur & v){
//transforme un vecteur en vector< vector > -> empty vector on error
vecteur::const_iterator it=v.begin(),itend=v.end();
vector< vector > res;
res.reserve(itend-it);
for (;it!=itend;++it){
if (it->type!=_VECT)
return vector< vector >(0);
res.push_back(vecteur_2_vector_int(*it->_VECTptr));
}
return res;
}
static vecteur vectvector_int_2_vecteur(const vector< vector > & v,GIAC_CONTEXT){
//transforme un vector< vector > en vecteur
int s=int(v.size());
vecteur res;
res.reserve(s);
for (int i=0;i > & v){
//transforme un vector< vector > en vecteur
int s=int(v.size());
vecteur res;
res.reserve(s);
for (int i=0;i sizes(const vector< vector > & v){
//donne la liste des tailles des vecteurs qui forment v
int s=int(v.size());
vector res(s);
for (int i=0;i vi;
vi=v[i];
res[i]=int(vi.size());
//res.push_back(vi.size());pourqoi?
}
return res;
}
gen _sizes(const gen & args,GIAC_CONTEXT){
if ( args.type==_STRNG && args.subtype==-1) return args;
if (args.type!=_VECT)
return gentypeerr(contextptr);
vecteur v(*args._VECTptr);
vecteur res;
vecteur::const_iterator it=v.begin(),itend=v.end();
res.reserve(itend-it);
for (;it!=itend;++it){
if (it->type!=_VECT)
return gensizeerr(contextptr);
res.push_back(int(it->_VECTptr->size()));
}
return res;
}
static const char _sizes_s[]="sizes";
static define_unary_function_eval (__sizes,&_sizes,_sizes_s);
define_unary_function_ptr5( at_sizes ,alias_at_sizes,&__sizes,0,true);
static int cyclesorder(const vector< vector > & v,GIAC_CONTEXT){
vector ss;
ss=sizes(v);
return(_lcm(vector_int_2_vecteur(ss,contextptr),contextptr).val);
}
static int permuorder(const vector & p,GIAC_CONTEXT){
vector< vector > c;
c=permu2cycles(p);
return(_lcm(vector_int_2_vecteur(sizes(c),contextptr),contextptr).val);
}
gen _permuorder(const gen & args,GIAC_CONTEXT){
if ( args.type==_STRNG && args.subtype==-1) return args;
if (args.type!=_VECT)
return gensizeerr(contextptr);
vecteur v(*args._VECTptr);
vector p;
if (!is_permu(v,p,contextptr))
return gensizeerr(contextptr);
return (permuorder(p,contextptr));
}
static const char _permuorder_s[]="permuorder";
static define_unary_function_eval (__permuorder,&_permuorder,_permuorder_s);
define_unary_function_ptr5( at_permuorder ,alias_at_permuorder,&__permuorder,0,true);
void shuffle(vector & temp){
int n=int(temp.size());
// source wikipedia Fisher-Yates shuffle article
for (int i=0;i rand_k_n(int k,int n,bool sorted){
if (k<=0 || n<=0)
return vector(0);
if (//n>=65536 &&
k*double(k)<=n/4){
vector t(k),ts(k);
for (int essai=20;essai>=0;--essai){
int i;
for (i=0;i=n/3 || (sorted && k*std::log(double(k))>n) ){
vector t; t.reserve(k);
// (algorithm suggested by O. Garet)
while (n>0){
int r=int(std_rand()/(rand_max2+1.0)*n);
if (r tab(n,true);
vector v(k);
for (int j=0;j randperm(const int & n){
//renvoie une permutation au hasard de long n
vector temp(n);
for (int k=0;k p(n);
//on chosit au hasard h et alors p[k]=temp[h]
int m;
m=n;
for (int k=0;k p=randperm(int(v.size()));
vecteur w(v);
for (unsigned i=0;i & p1,GIAC_CONTEXT) {
//renvoie true si p est une perm et transforme p en le vector p1
int n;
n=int(p.size());
vector p2(n);
p1=p2;
vector temp(n);
for (int j=0;j0 || abs_calc_mode(contextptr)==38)
p1[j]=p[j].val-1;
else
p1[j]=p[j].val;
if ((n<=p1[j])|| (p1[j])<0) {
return(false);
}
}
int k;
k=0;
while (k=n) {return(false);}
if (temp[p1k]) {
return(false);}
else {temp[p1k]=1;}
k=k+1;
}
return(true);
}
gen _is_permu(const gen & args,GIAC_CONTEXT){
if ( args.type==_STRNG && args.subtype==-1) return args;
if (args.type!=_VECT)
return gensizeerr(contextptr);
vecteur v(*args._VECTptr);
vector p1;
return is_permu(v,p1,contextptr);
}
static const char _is_permu_s[]="is_permu";
static define_unary_function_eval (__is_permu,&_is_permu,_is_permu_s);
define_unary_function_ptr5( at_is_permu ,alias_at_is_permu,&__is_permu,0,true);
bool is_cycle(const vecteur & c,vector & c1,GIAC_CONTEXT) {
//renvoie true si c est un cycle et transf c vecteur en le cycle c1 vector
int n1;
n1=int(c.size());
//vector p;
vector c2(n1);
c1=c2;
for (int j=0;j0 || abs_calc_mode(contextptr)==38)
c1[j]=c[j].val-1;
else
c1[j]=c[j].val;
}
for (int k=0;k c1;
return is_cycle(v,c1,contextptr);
}
static const char _is_cycle_s[]="is_cycle";
static define_unary_function_eval (__is_cycle,&_is_cycle,_is_cycle_s);
define_unary_function_ptr5( at_is_cycle ,alias_at_is_cycle,&__is_cycle,0,true);
vector cycle2perm(const vector & c) {
//transforme c en la permu p et renvoie p
int n1;
n1=int(c.size());
//vector c1(n1);
int n;
n=c[0];
for (int k=1;k p(n);
for (int k=0;k c;
if (!is_cycle(v,c,contextptr))
return gensizeerr(contextptr);
return vector_int_2_vecteur(cycle2perm(c),contextptr);
}
static const char _cycle2perm_s[]="cycle2perm";
static define_unary_function_eval (__cycle2perm,&_cycle2perm,_cycle2perm_s);
define_unary_function_ptr5( at_cycle2perm ,alias_at_cycle2perm,&__cycle2perm,0,true);
vector p1op2(const vector & p1,const vector & p2) {
//composition de 2 perm p1 et p2 de long n1 et n2 : a pour long max(n1,n2)
int n1;
n1=int(p1.size());
int n2;
n2=int(p2.size());
vector p3;
vector p4;
p3=p1;
p4=p2;
if (n1>n2) {
for (int k=n2;k p(n1);
for (int k=0;ksize()!=2) )
return gentypeerr(contextptr);
vecteur v(*args._VECTptr);
gen v1=v.front(),v2=v.back();
if ( (v1.type!=_VECT) || (v2.type!=_VECT))
return gentypeerr(contextptr);
vector p1,p2;
if (!is_permu(*v1._VECTptr,p1,contextptr) || !is_permu(*v2._VECTptr,p2,contextptr))
return gensizeerr(contextptr);
return vector_int_2_vecteur(p1op2(p1,p2),contextptr);
}
static const char _p1op2_s[]="p1op2";
static define_unary_function_eval (__p1op2,&_p1op2,_p1op2_s);
define_unary_function_ptr5( at_p1op2 ,alias_at_p1op2,&__p1op2,0,true);
vector c1oc2(const vector & c1,const vector & c2) {
//composition de 2 cycles en une perm de long min
vector p1;
p1=cycle2perm(c1);
vector p2;
p2=cycle2perm(c2);
int n1;
n1=int(p1.size());
int n2;
n2=int(p2.size());
int n;
if (n1>n2) {
n=n1;
for (int k=n2;k p(n);
for (int k=0;ksize()!=2) )
return gentypeerr(contextptr);
vecteur v(*args._VECTptr);
gen v1=v.front(),v2=v.back();
if ( (v1.type!=_VECT) || (v2.type!=_VECT))
return gentypeerr(contextptr);
vector c1,c2;
//c1=vecteur_2_vector_int(*v1._VECTptr);
//c2=vecteur_2_vector_int(*v2._VECTptr);
if (!is_cycle(*v1._VECTptr,c1,contextptr) || !is_cycle(*v2._VECTptr,c2,contextptr))
return gensizeerr(contextptr);
return vector_int_2_vecteur(c1oc2(c1,c2),contextptr);
}
static const char _c1oc2_s[]="c1oc2";
static define_unary_function_eval (__c1oc2,&_c1oc2,_c1oc2_s);
define_unary_function_ptr5( at_c1oc2 ,alias_at_c1oc2,&__c1oc2,0,true);
vector c1op2(const vector & c1, const vector & p2) {
//composition d'un cycle et d'une perm en une perm de long min
vector p1,p3;
p1=cycle2perm(c1);
int n1;
n1=int(p1.size());
int n2;
n2=int(p2.size());
p3=p2;
int n;
if (n1>n2) {
n=n1;
for (int k=n2;k p(n);
for (int k=0;ksize()!=2) )
return gentypeerr(contextptr);
vecteur v(*args._VECTptr);
gen v1=v.front(),v2=v.back();
if ( (v1.type!=_VECT) || (v2.type!=_VECT))
return gentypeerr(contextptr);
vector c1,p2;
if (!is_cycle(*v1._VECTptr,c1,contextptr) || !is_permu(*v2._VECTptr,p2,contextptr))
return gensizeerr(contextptr);
return vector_int_2_vecteur(c1op2(c1,p2),contextptr);
}
static const char _c1op2_s[]="c1op2";
static define_unary_function_eval (__c1op2,&_c1op2,_c1op2_s);
define_unary_function_ptr5( at_c1op2 ,alias_at_c1op2,&__c1op2,0,true);
vector p1oc2(const vector & p1, const vector & c2) {
//composition d'une perm et d'un cycle en une perm de long min
vector p2,p3;
p2=cycle2perm(c2);
int n2;
n2=int(p2.size());
int n1;
n1=int(p1.size());
p3=p1;
int n;
if (n1>n2) {n=n1;
for (int k=n2;k p(n);
for (int k=0;ksize()!=2) )
return gentypeerr(contextptr);
vecteur v(*args._VECTptr);
gen v1=v.front(),v2=v.back();
if ( (v1.type!=_VECT) || (v2.type!=_VECT))
return gentypeerr(contextptr);
vector p1,c2;
if (!is_cycle(*v2._VECTptr,c2,contextptr) || !is_permu(*v1._VECTptr,p1,contextptr))
return gensizeerr(contextptr);
return vector_int_2_vecteur(p1oc2(p1,c2),contextptr);
}
static const char _p1oc2_s[]="p1oc2";
static define_unary_function_eval (__p1oc2,&_p1oc2,_p1oc2_s);
define_unary_function_ptr5( at_p1oc2 ,alias_at_p1oc2,&__p1oc2,0,true);
vector cycles2permu(const vector< vector > & c) {
//transforme une liste de cycles en la permutation produit
int n;
n=int(c.size());
vector pk;
vector p;
vector ck;
vector c1;
ck=c[n-1];
vector c0(1);
c0[0]=0;
p=c1oc2(ck,c0);
for (int k=n-2;k>=0;k--){
ck=c[k];
p=c1op2(ck,p);
}
return(p);
}
gen _cycles2permu(const gen & args,GIAC_CONTEXT){
if ( args.type==_STRNG && args.subtype==-1) return args;
if (args.type!=_VECT)
return gentypeerr(contextptr);
vecteur v(*args._VECTptr);
vecteur::const_iterator it=v.begin(),itend=v.end();
for (;it!=itend;++it){
vector c;
if (it->type!=_VECT || !is_cycle(*it->_VECTptr,c,contextptr))
return gensizeerr(contextptr);
}
return vector_int_2_vecteur(cycles2permu(vecteur_2_vectvector_int(v,contextptr)),contextptr);
}
static const char _cycles2permu_s[]="cycles2permu";
static define_unary_function_eval (__cycles2permu,&_cycles2permu,_cycles2permu_s);
define_unary_function_ptr5( at_cycles2permu ,alias_at_cycles2permu,&__cycles2permu,0,true);
vector< vector > permu2cycles(const vector & p) {
//transforme la permutation p en une liste de cycles (p= produit de ces cycles)
int l=int(p.size());
int n=0;
int deb;
vector p1(l);
p1=p;
vector temp(l+1);
vector< vector > c;
if (p1[l-1]==l-1) {
vector c1;
c1.push_back(l-1);
c.push_back(c1); l=l-1;
}
temp[l]=0;
for (int k=0;k v;
v.push_back(n);deb=n;
while (p1[n]!=deb){
v.push_back(p1[n]);
temp[n]=0;
n=p1[n];
}
if (n!=deb) {c.push_back(v);}
temp[n]=0;
n=deb+1;
while ((n p;
if (!is_permu(v,p,contextptr))
return gensizeerr(contextptr);
return vectvector_int_2_vecteur(permu2cycles(p),contextptr);
}
static const char _permu2cycles_s[]="permu2cycles";
static define_unary_function_eval (__permu2cycles,&_permu2cycles,_permu2cycles_s);
define_unary_function_ptr5( at_permu2cycles ,alias_at_permu2cycles,&__permu2cycles,0,true);
vector perminv(const vector & p){
int n;
n=int(p.size());
vector p1(n);
for (int j=0;j p;
if (!is_permu(v,p,contextptr))
return gensizeerr(contextptr);
return vector_int_2_vecteur(perminv(p),contextptr);
}
static const char _perminv_s[]="perminv";
static define_unary_function_eval (__perminv,&_perminv,_perminv_s);
define_unary_function_ptr5( at_perminv ,alias_at_perminv,&__perminv,0,true);
vector cycleinv(const vector & c){
int n;
n=int(c.size());
vector c1(n);
for (int j=0;j c;
if (!is_cycle(v,c,contextptr))
return gensizeerr(contextptr);
return vector_int_2_vecteur(cycleinv(c),contextptr);
}
static const char _cycleinv_s[]="cycleinv";
static define_unary_function_eval (__cycleinv,&_cycleinv,_cycleinv_s);
define_unary_function_ptr5( at_cycleinv ,alias_at_cycleinv,&__cycleinv,0,true);
int signature(const vector & p) {
//renvoie la signature de la permutation p
int s;
s=1;
vector< vector > c;
c=permu2cycles(p);
int l=int(c.size());
for (int k=0;k p;
if (!is_permu(v,p,contextptr))
return gensizeerr(contextptr);
return signature(p);
}
static const char _signature_s[]="signature";
static define_unary_function_eval (__signature,&_signature,_signature_s);
define_unary_function_ptr5( at_signature ,alias_at_signature,&__signature,0,true);
vecteur vector_giac_double_2_vecteur(const vector & v){
//transforme un vector en vecteur
vector::const_iterator it=v.begin(),itend=v.end();
vecteur res;
res.reserve(itend-it);
for (;it!=itend;++it)
res.push_back(double(*it));
return res;
}
vecteur vectvector_giac_double_2_vecteur(const vector< vector > & v){
//transforme un vector< vector > en vecteur
int s=int(v.size());
vecteur res;
res.reserve(s);
for (int i=0;isize()!=2) )
return gentypeerr(contextptr);
vecteur v(*args._VECTptr);
gen v1=v.front(),v2=v.back();
n=v1.val;
p=v2.val;
}
vecteur c;
for (int k=0;kbegin(),itend=g._VECTptr->end();
gen res(0);
mpz_t tmpz;
mpz_init(tmpz);
for (;it!=itend;++it){
if (res.type==_ZINT && is_integer(*it)){
#if defined(INT128) && !defined(USE_GMP_REPLACEMENTS)
if (it->type==_INT_)
mpz_add_ui(*res._ZINTptr,*res._ZINTptr,longlong(it->val)*(it->val));
else {
mpz_mul(tmpz,*it->_ZINTptr,*it->_ZINTptr);
mpz_add(*res._ZINTptr,*res._ZINTptr,tmpz);
}
#else
if (it->type==_INT_){
mpz_set_si(tmpz,it->val);
mpz_mul(tmpz,tmpz,tmpz);
}
else
mpz_mul(tmpz,*it->_ZINTptr,*it->_ZINTptr);
mpz_add(*res._ZINTptr,*res._ZINTptr,tmpz);
#endif
}
else
res += (*it)*(*it);
}
mpz_clear(tmpz);
return res;
}
gen square_hadamard_bound(const matrice & m){
const_iterateur it=m.begin(),itend=m.end();
gen prod(1);
for (;it!=itend;++it){
type_operator_times(prod,l2norm2(*it),prod);
// prod=prod*l2norm2(*it);
}
return prod;
}
gen _hadamard(const gen & args,GIAC_CONTEXT){
if ( args.type==_STRNG && args.subtype==-1) return args;
if (ckmatrix(args) || args[0][0].type!=_VECT){
// Hadamard bound on det(args)
matrice & m=*args._VECTptr;
if (has_num_coeff(m)){
gen r=1.0;
for (unsigned i=0;isize()!=2) )
return gentypeerr(contextptr);
vecteur v(*args._VECTptr);
gen g1=v.front(),g2=v.back();
if ((g1.type!=_VECT) ||(g2.type!=_VECT))
return gentypeerr(contextptr);
vecteur v1(*g1._VECTptr);
vecteur v2(*g2._VECTptr);
if (v1.size()!=v2.size()) return gensizeerr(contextptr);
int n=int(v1.size());
vecteur c;
for (int k=0;ksize()!=2) )
return gentypeerr(contextptr);
vecteur v(*args._VECTptr);
gen g1=_equal2diff(v.front(),contextptr),g2=v.back();
if ((g1.type!=_VECT) ||(g2.type!=_VECT))
return gentypeerr(contextptr);
vecteur v1(*g1._VECTptr);
vecteur v2(*g2._VECTptr);
int n=int(v2.size()),m=int(v1.size());
vecteur c;
for (int k=0;k0 && args.valsize()==3){
gen opt=args._VECTptr->back();
if (opt.is_symb_of_sommet(at_equal) && (opt._SYMBptr->feuille[0]==at_coordonnees || (opt._SYMBptr->feuille[0].type==_INT_ && opt._SYMBptr->feuille[0].val==_COORDS))){
gen f=eval(args._VECTptr->front(),1,contextptr);
gen coord=(*args._VECTptr)[1];
if (coord.type==_VECT && coord._VECTptr->size()==3){
if (opt._SYMBptr->feuille[1]==at_sphere){
gen r=coord[0],r2=pow(r,2,contextptr),t=coord[1],s=sin(t,contextptr),p=coord[2];
gen res=derive(r2*derive(f,r,contextptr),r,contextptr);
res += derive(derive(s*f,t,contextptr),t,contextptr)/s;
res += derive(derive(f,p,contextptr),p,contextptr)/(s*s);
return res/r2;
}
if (opt._SYMBptr->feuille[1]==at_cylindre){
gen r=coord[0],t=coord[1],z=coord[2];
gen res=derive(r*derive(f,r,contextptr),r,contextptr);
res += derive(derive(f,t,contextptr),t,contextptr)/(r*r);
res += derive(derive(f,z,contextptr),z,contextptr);
return res;
}
}
}
}
if ( (args.type!=_VECT) || (args._VECTptr->size()!=2) )
return gentypeerr(contextptr);
vecteur v(plotpreprocess(args,contextptr));
if (is_undef(v))
return v;
gen g1=v.front(),g2=v.back();
if (g2.type!=_VECT)
return gentypeerr(contextptr);
vecteur v2(*g2._VECTptr);
int n=int(v2.size());
gen la;
la=0;
for (int k=0;ksize()!=2) )
return gentypeerr(contextptr);
vecteur v(plotpreprocess(args,contextptr));
if (is_undef(v))
return v;
gen g1=v.front(),g2=v.back();
if (g2.type!=_VECT)
return gentypeerr(contextptr);
vecteur v2(*g2._VECTptr);
int n=int(v2.size());
vecteur he;
for (int k=0;ksize()==3){
gen opt=args._VECTptr->back();
if (opt.is_symb_of_sommet(at_equal) && (opt._SYMBptr->feuille[0]==at_coordonnees || (opt._SYMBptr->feuille[0].type==_INT_ && opt._SYMBptr->feuille[0].val==_COORDS))){
gen g=eval(args._VECTptr->front(),1,contextptr);
gen coord=(*args._VECTptr)[1];
if (g.type==_VECT && coord.type==_VECT && g._VECTptr->size()==3 && coord._VECTptr->size()==3){
if (opt._SYMBptr->feuille[1]==at_sphere){
// spheric: 1/r^2*d_r(r^2*A_r)+1/r/sin(theta)*d_theta(sin(theta)*A_theta)+1/r*sin(theta)*d_phi(A_phi)
gen Ar=g[0],At=g[1],Ap=g[2],r=coord[0],r2=pow(r,2,contextptr),t=coord[1],s=sin(t,contextptr),p=coord[2];
return derive(r2*Ar,r,contextptr)/r2+(derive(s*At,t,contextptr)+derive(Ap,p,contextptr))/(r*s);
}
if (opt._SYMBptr->feuille[1]==at_cylindre){
// cylindric: 1/r*d_r(r*A_r)+1/r*d_theta(A_theta)+d_z(A_z)
gen Ar=g[0],At=g[1],Az=g[2],r=coord[0],t=coord[1],z=coord[2];
return (derive(r*Ar,r,contextptr)+derive(At,t,contextptr))/r+derive(Az,z,contextptr);
}
}
}
}
if ( (args.type!=_VECT) || (args._VECTptr->size()!=2) )
return gentypeerr(contextptr);
vecteur v(plotpreprocess(args,contextptr));
if (is_undef(v))
return v;
gen g1=v.front(),g2=v.back();
if ((g1.type!=_VECT) ||(g2.type!=_VECT))
return gentypeerr(contextptr);
vecteur v1(*g1._VECTptr);
vecteur v2(*g2._VECTptr);
int n=int(v2.size());
gen di;
di=0;
for (int k=0;ksize()==3){
gen opt=args._VECTptr->back();
if (opt.is_symb_of_sommet(at_equal) && (opt._SYMBptr->feuille[0]==at_coordonnees || (opt._SYMBptr->feuille[0].type==_INT_ && opt._SYMBptr->feuille[0].val==_COORDS))){
gen g=eval(args._VECTptr->front(),1,contextptr);
gen coord=(*args._VECTptr)[1];
if (g.type==_VECT && coord.type==_VECT && g._VECTptr->size()==3 && coord._VECTptr->size()==3){
if (opt._SYMBptr->feuille[1]==at_sphere){
// spheric: 1/r/sin(theta)*(d_theta(sin(theta)*A_phi)-d_phi(A_theta)),
// 1/r/sin(theta)*d_phi(A_r)-1/r*d_r(r*A_phi), 1/r*(d_r(r*A_theta)-d_theta(A_r))
gen Ar=g[0],At=g[1],Ap=g[2],r=coord[0],r2=pow(r,2,contextptr),t=coord[1],s=sin(t,contextptr),p=coord[2];
return makevecteur((derive(s*Ap,t,contextptr)-derive(At,p,contextptr))/(r*s),derive(Ar,p,contextptr)/(r*s)-derive(r*Ap,r,contextptr)/r,(derive(r*At,r,contextptr)-derive(Ar,t,contextptr))/r);
}
if (opt._SYMBptr->feuille[1]==at_cylindre){
// cylindric (1/r*d_theta(A_z)-d_z(A_theta)),d_z(A_r)-d_r(A_z),1/r*d_r(r*A_theta)-d_theta(A_r))
gen Ar=g[0],At=g[1],Az=g[2],r=coord[0],t=coord[1],z=coord[2];
return makevecteur(derive(Az,t,contextptr)/r-derive(At,z,contextptr),derive(Ar,z,contextptr)-derive(Az,r,contextptr),(derive(r*At,r,contextptr)-derive(Ar,t,contextptr))/r);
}
}
}
}
if ( (args.type!=_VECT) || (args._VECTptr->size()!=2) )
return gentypeerr(contextptr);
vecteur v(plotpreprocess(args,contextptr));
if (is_undef(v))
return v;
gen g1=v.front(),g2=v.back();
if ((g1.type!=_VECT) ||(g2.type!=_VECT))
return gentypeerr(contextptr);
vecteur v1(*g1._VECTptr);
vecteur v2(*g2._VECTptr);
int n=int(v2.size());
if (n!=3) return gensizeerr(contextptr);
vecteur rot(3);
rot[0]=derive(v1[2],v2[1],contextptr)-derive(v1[1],v2[2],contextptr);
rot[1]=derive(v1[0],v2[2],contextptr)-derive(v1[2],v2[0],contextptr);
rot[2]=derive(v1[1],v2[0],contextptr)-derive(v1[0],v2[1],contextptr);
return rot;
}
static const char _curl_s[]="curl";
static define_unary_function_eval_quoted (__curl,&_curl,_curl_s);
define_unary_function_ptr5( at_curl ,alias_at_curl,&__curl,_QUOTE_ARGUMENTS,true);
bool find_n_x(const gen & args,int & n,gen & x,gen & a){
if (args.type==_INT_){
n=args.val;
x=vx_var;
a=a__IDNT_e;
return true;
}
if (args.type==_DOUBLE_){
n=int(args._DOUBLE_val);
if (n!=args._DOUBLE_val)
return false;
x=vx_var;
a=a__IDNT_e;
return true;
}
if (args.type!=_VECT || args._VECTptr->size()<2)
return false;
vecteur v=*args._VECTptr;
if (v[0].type==_DOUBLE_ && v[0]._DOUBLE_val==int(v[0]._DOUBLE_val))
v[0]=int(v[0]._DOUBLE_val);
if (v[0].type==_INT_){
n=v[0].val;
x=v[1];
}
else
return false;
if (v.size()>2)
a=v[2];
else
a=a__IDNT_e;
return true;
}
vecteur hermite(int n){
vecteur v(n+1);
v[0]=pow(plus_two,n);
for (int k=2;k<=n;k+=2){
v[k]=-((n+2-k)*(n+1-k)*v[k-2])/(2*k);
if (is_undef(v[k]))
return v;
}
return v;
}
bool poly2symbmat(matrice & A,const gen & var,GIAC_CONTEXT){
iterateur it=A.begin(),itend=A.end();
for (;it!=itend;++it){
if (it->type!=_VECT) return false;
iterateur jt=it->_VECTptr->begin(),jtend=it->_VECTptr->end();
for (;jt!=jtend;++jt){
*jt=_poly2symb(makesequence(*jt,var),contextptr);
}
}
return true;
}
bool unmod(std_matrix & a,const gen & p){
for (size_t i=0;i & v=a[i];
for (size_t j=0;jbegin(),itend=g._VECTptr->end();
for (;it!=itend;++it){
gen & h =*it;
if (h.type==_MOD){
if (*(h._MODptr+1)!=p)
return false;
h=unmod(h);
}
}
}
}
}
return true;
}
bool hnf(const matrice & Aorig,const gen & var,matrice & U,matrice & A,matrice & V,bool do_smith,GIAC_CONTEXT){
std_matrix aorig,u,a,v;
if (var.type==_VECT){
if (var._VECTptr->empty())
matrice2std_matrix_gen(Aorig,aorig);
else
return false; // multivariate polynomial are not yet allowed
}
else {
gen tmp=_symb2poly(makesequence(Aorig,var),contextptr);
if (!ckmatrix(tmp))
return false;
matrice2std_matrix_gen(*tmp._VECTptr,aorig);
}
// fixme, detect modular computation
environment env;
gen g=aorig[0][0];
if (g.type==_VECT && g._VECTptr->back().type==_MOD){
env.modulo=*(g._VECTptr->back()._MODptr+1);
env.moduloon=true;
if (!unmod(aorig,env.modulo))
return false;
}
else
env.moduloon=false;
if (do_smith){
if (!smith(aorig,u,a,v,&env,contextptr))
return false;
}
else {
if (!hermite(aorig,u,a,&env,contextptr))
return false;
}
std_matrix_gen2matrice_destroy(u,U);
std_matrix_gen2matrice_destroy(a,A);
if (do_smith)
std_matrix_gen2matrice_destroy(v,V);
if (var.type!=_VECT || !var._VECTptr->empty()) {
poly2symbmat(U,var,contextptr);
poly2symbmat(A,var,contextptr);
if (do_smith)
poly2symbmat(V,var,contextptr);
}
if (env.moduloon){
U=*makemod(U,env.modulo)._VECTptr;
A=*makemod(A,env.modulo)._VECTptr;
if (do_smith)
V=*makemod(V,env.modulo)._VECTptr;
}
return true;
}
gen _hermite(const gen & args,GIAC_CONTEXT){
if ( args.type==_STRNG && args.subtype==-1) return args;
int n;
gen a,x;
if (!find_n_x(args,n,x,a)){
matrice U,A,V; // U invertible and A such that U*args==A
if (ckmatrix(args) && hnf(*args._VECTptr,ggb_var(args),U,A,V,false,contextptr))
return makesequence(U,A);
if (args.type==_VECT && args._VECTptr->size()==2 && ckmatrix(args._VECTptr->front()) && hnf(*args._VECTptr->front()._VECTptr,args._VECTptr->back(),U,A,V,false,contextptr))
return makesequence(U,A);
return gensizeerr(contextptr);
}
return r2e(hermite(n),x,contextptr);
}
static const char _hermite_s[]="hermite";
static define_unary_function_eval (__hermite,&_hermite,_hermite_s);
define_unary_function_ptr5( at_hermite ,alias_at_hermite,&__hermite,0,true);
gen _smith(const gen & args,GIAC_CONTEXT){
if ( args.type==_STRNG && args.subtype==-1) return args;
matrice U,A,V; // U invertible and A such that U*args==A
if (ckmatrix(args) && hnf(*args._VECTptr,ggb_var(args),U,A,V,true,contextptr))
return makesequence(U,A,V);
if (args.type==_VECT && args._VECTptr->size()==2 && ckmatrix(args._VECTptr->front()) && hnf(*args._VECTptr->front()._VECTptr,args._VECTptr->back(),U,A,V,true,contextptr))
return makesequence(U,A,V);
return gensizeerr(contextptr);
}
static const char _smith_s[]="smith";
static define_unary_function_eval (__smith,&_smith,_smith_s);
define_unary_function_ptr5( at_smith ,alias_at_smith,&__smith,0,true);
vecteur laguerre(int n){
// L_k(x)=v_k(x)/k!
// L_{n+1}=1/(n+1)*((2n+1-x)*L_n(x)-nL_{n-1}(x))
// hence v_{n+1}=(2n+1-x)v_n-n*(n-1)*v_{n-1}
vecteur v0,v1,tmp1,tmp2,tmpx;
v0.reserve(n+1);
v1.reserve(n+1);
tmp1.reserve(n+1);
tmp2.reserve(n+1);
tmpx=makevecteur(-1,0);
v0.push_back(1); // v0=1
v1.push_back(-1);
v1.push_back(1); // v1=1-x
for (int k=1;k v1, v0, tmp1 -> v1, tmp1, v0
v0.swap(v1);
v1.swap(tmp1);
if (is_undef(v1))
return v1;
// cerr << v0 << " " << v1 << endl;
}
return v1;
}
gen _laguerre(const gen & args,GIAC_CONTEXT){
if ( args.type==_STRNG && args.subtype==-1) return args;
int n;
gen a,x;
if (!find_n_x(args,n,x,a))
return gensizeerr(contextptr);
if (is_zero(a))
return inv(factorial(n),contextptr)*symb_horner(laguerre(n),x);
gen p0,p1,p2;
p0=1;
p1=1+a-x;
if (n==0) return p0;
if (n==1) return p1;
for (int k=2;k<=n;k++){
//p2=rdiv(2*k+a-1-x,k)*p1-rdiv(k+a-1,k)*p0;
p2=(2*k+a-1-x)*p1-(k-1)*(k+a-1)*p0;
p0=p1;
p1=p2;
}
//return normal(p2,contextptr);
return normal(rdiv(p2,factorial(n),contextptr),contextptr);
}
static const char _laguerre_s[]="laguerre";
static define_unary_function_eval (__laguerre,&_laguerre,_laguerre_s);
define_unary_function_ptr5( at_laguerre ,alias_at_laguerre,&__laguerre,0,true);
// Improved one
vecteur tchebyshev1(int n){
if (n==0) return vecteur(1,1);
vecteur v(n+1);
v[0]=pow(gen(2),n-1);
if (n==1) return v;
for (int k=2;k<=n;k+=2){
v[k]=-((n-k+2)*(n-k+1)*v[k-2])/(2*k*(n-k/2));
if (is_undef(v[k]))
return v;
}
return v;
}
gen _tchebyshev1(const gen & args,GIAC_CONTEXT){
if ( args.type==_STRNG && args.subtype==-1) return args;
int n;
gen a,x;
if (!find_n_x(args,n,x,a))
return gensizeerr(contextptr);
return r2e(tchebyshev1(n),x,contextptr);
}
static const char _tchebyshev1_s[]="tchebyshev1";
static define_unary_function_eval (__tchebyshev1,&_tchebyshev1,_tchebyshev1_s);
define_unary_function_ptr5( at_tchebyshev1 ,alias_at_tchebyshev1,&__tchebyshev1,0,true);
// Improved one
vecteur tchebyshev2(int n){
vecteur v(n+1);
v[0]=pow(gen(2),n);
for (int k=1;k<=n/2;++k){
v[2*k]=-(n+2-2*k)*(n+1-2*k)*v[2*k-2]/(4*k*(n+1-k));
if (is_undef(v[2*k]))
return v;
}
return v;
}
gen _tchebyshev2(const gen & args,GIAC_CONTEXT){
if ( args.type==_STRNG && args.subtype==-1) return args;
gen p0,p1,p2;
int n;
gen a,x;
if (!find_n_x(args,n,x,a))
return gensizeerr(contextptr);
return r2e(tchebyshev2(n),x,contextptr);
}
static const char _tchebyshev2_s[]="tchebyshev2";
static define_unary_function_eval (__tchebyshev2,&_tchebyshev2,_tchebyshev2_s);
define_unary_function_ptr5( at_tchebyshev2 ,alias_at_tchebyshev2,&__tchebyshev2,0,true);
// Legendre is the vecteur returned divided by n!
vecteur legendre(int n){
vecteur v0,v1,vtmp1,vtmp2;
v0.push_back(1);
v1.push_back(1);
v1.push_back(0);
if (!n) return v0;
if (n==1) return v1;
for (int k=2;k<=n;k++){
multvecteur(2*k-1,v1,vtmp1);
vtmp1.push_back(0); // (2k-1)*x*p1
multvecteur((k-1)*(k-1),v0,vtmp2); // (k-1)^2*p0
vtmp1=vtmp1-vtmp2; // p2=(2*k-1)*x*p1-(k-1)*(k-1)*p0;
v0=v1;
v1=vtmp1;
}
return v1;
}
gen _legendre(const gen & args,GIAC_CONTEXT){
if ( args.type==_STRNG && args.subtype==-1) return args;
int n;
gen a,x;
if (!find_n_x(args,n,x,a))
return gensizeerr(contextptr);
vecteur v=multvecteur(inv(factorial(n),contextptr),legendre(n));
return r2e(v,x,contextptr);
}
static const char _legendre_s[]="legendre";
static define_unary_function_eval (__legendre,&_legendre,_legendre_s);
define_unary_function_ptr5( at_legendre ,alias_at_legendre,&__legendre,0,true);
// arithmetic mean column by column
vecteur mean(const matrice & m,bool column){
matrice mt;
if (column)
mt=mtran(m);
else
mt=m;
vecteur res;
const_iterateur it=mt.begin(),itend=mt.end();
for (;it!=itend;++it){
const gen & g =*it;
if (g.type!=_VECT){
res.push_back(g);
continue;
}
vecteur & v=*g._VECTptr;
if (v.empty()){
res.push_back(undef);
continue;
}
const_iterateur jt=v.begin(),jtend=v.end();
int s=int(jtend-jt);
gen somme(0);
for (;jt!=jtend;++jt){
//somme = somme + evalf(*jt);
somme = somme + *jt;
}
res.push_back(rdiv(somme,s,context0));
}
return res;
}
vecteur stddev(const matrice & m,bool column,int variance){
matrice mt;
if (column)
mt=mtran(m);
else
mt=m;
vecteur moyenne(mean(mt,false));
vecteur res;
const_iterateur it=mt.begin(),itend=mt.end();
for (int i=0;it!=itend;++it,++i){
const gen & g =*it;
if (g.type!=_VECT){
res.push_back(0);
continue;
}
vecteur & v=*g._VECTptr;
if (v.empty()){
res.push_back(undef);
continue;
}
const_iterateur jt=v.begin(),jtend=v.end();
int s=int(jtend-jt);
gen somme(0);
for (;jt!=jtend;++jt){
// somme = somme + evalf((*jt)*(*jt));
somme = somme + (*jt)*(*jt);
}
if (variance!=3)
res.push_back(sqrt(rdiv(somme-s*moyenne[i]*moyenne[i],s-(variance==2),context0),context0));
else
res.push_back(rdiv(somme,s,context0)-moyenne[i]*moyenne[i]);
}
return res;
}
matrice ascsort(const matrice & m,bool column){
matrice mt;
if (column)
mt=mtran(m);
else
mt=m;
iterateur it=mt.begin(),itend=mt.end();
gen tmp;
for (;it!=itend;++it){
gen & g =*it;
if (g.type!=_VECT)
continue;
vecteur v=*g._VECTptr;
if (v.empty())
continue;
const_iterateur jt=v.begin(),jtend=v.end();
int n=int(jtend-jt);
vector vv(n);
for (int j=0;jt!=jtend;++jt,++j){
if ( (jt->type==_VECT) && (jt->_VECTptr->size()==3) )
tmp=(*jt->_VECTptr)[1];
else
tmp=*jt;
tmp=evalf(tmp,1,0);
if (tmp.type!=_DOUBLE_)
vv[j]=0;
else
vv[j]=tmp._DOUBLE_val;
}
sort(vv.begin(),vv.end());
for (int j=0;j p1;
vecteur p(*args._VECTptr);
if (!(is_permu(p,p1,contextptr)))
return gentypeerr(contextptr);
int n=int(p.size());
vecteur c;
vecteur l(n);
for (int k=0;k & a , const int n, vector< vector > s) {
//teste si a est egal a l'un des n premiers elements de s
bool cont=true;
int j=0;
while (j<=n && cont) {
if (a==s[j]) {
cont=false;
}
j=j+1;
}
return (! cont);
}
vector< vector > groupermu(const vector & p1,const vector & p2) {
//groupe engendre par de 2 perm p1 et p2 de long n1 et n2 : a pour long max(n1,n2)
int n1;
n1=int(p1.size());
int n2;
n2=int(p2.size());
vector a;
vector b;
a=p1;
b=p2;
if (n1>n2) {
for (int k=n2;k > s(2);
s[0]=a;
s[1]=b;
int p=0;
int q=1;
bool pfini=true;
while (pfini) {
int k=0;
for (int j=p;j<=q;j++){
vector na;
vector nb;
na=p1op2(a,s[j]);
if (!(est_dans(na,q+k,s))){
k=k+1;
s.push_back(na);
}
nb=p1op2(b,s[j]);
if (!(est_dans(nb,q+k,s))){
k=k+1;
s.push_back(nb);
}
}
if (k!=0) {
p=q+1;
q=q+k;
} else {
pfini=false;
}
}
//q est l'ordre du groupe = size(s)
return(s);
}
gen _groupermu(const gen & args,GIAC_CONTEXT){
if ( args.type==_STRNG && args.subtype==-1) return args;
if ( (args.type!=_VECT) || (args._VECTptr->size()!=2) )
return gentypeerr(contextptr);
vecteur v(*args._VECTptr);
gen v1=v.front(),v2=v.back();
if ( (v1.type!=_VECT) || (v2.type!=_VECT))
return gentypeerr(contextptr);
vector p1,p2;
if (!is_permu(*v1._VECTptr,p1,contextptr) || !is_permu(*v2._VECTptr,p2,contextptr))
return gensizeerr(contextptr);
return vectvector_int_2_vecteur(groupermu(p1,p2),contextptr);
}
static const char _groupermu_s[]="groupermu";
static define_unary_function_eval (__groupermu,&_groupermu,_groupermu_s);
define_unary_function_ptr5( at_groupermu ,alias_at_groupermu,&__groupermu,0,true);
gen _nextperm(const gen & args,GIAC_CONTEXT){
if ( args.type==_STRNG && args.subtype==-1) return args;
if (args.type!=_VECT)
return gentypeerr(contextptr);
const vecteur & v1=*args._VECTptr;
vector p1;
if (!is_permu(v1,p1,contextptr))
return gensizeerr(contextptr);
if (next_permutation(p1.begin(),p1.end()))
return vector_int_2_vecteur(p1,contextptr);
else
return undef;
}
static const char _nextperm_s[]="nextperm";
static define_unary_function_eval (__nextperm,&_nextperm,_nextperm_s);
define_unary_function_ptr5( at_nextperm ,alias_at_nextperm,&__nextperm,0,true);
gen _prevperm(const gen & args,GIAC_CONTEXT){
if ( args.type==_STRNG && args.subtype==-1) return args;
if (args.type!=_VECT)
return gentypeerr(contextptr);
const vecteur & v1=*args._VECTptr;
vector p1;
if (!is_permu(v1,p1,contextptr))
return gensizeerr(contextptr);
if (prev_permutation(p1.begin(),p1.end()))
return vector_int_2_vecteur(p1,contextptr);
else
return undef;
}
static const char _prevperm_s[]="prevperm";
static define_unary_function_eval (__prevperm,&_prevperm,_prevperm_s);
define_unary_function_ptr5( at_prevperm ,alias_at_prevperm,&__prevperm,0,true);
gen _split(const gen & args,GIAC_CONTEXT){
if ( args.type==_STRNG && args.subtype==-1) return args;
//renvoie [ax,ay] si les arg sont g1=ax*an (sans denominateur) et g2=[x,y]
//sinon renvoie [0]
if ( (args.type!=_VECT) || (args._VECTptr->size()!=2) )
return gentypeerr(contextptr);
vecteur v(*args._VECTptr);
gen g1=v.front(),g2=v.back();
if (g2.type!=_VECT)
return gentypeerr(contextptr);
vecteur v2(*g2._VECTptr);
int n=int(v2.size());
if (n!=2) return gensizeerr(contextptr);
vecteur fa;
fa=factors(g1,vx_var,contextptr);
int l=int(fa.size());
gen ax=1;
gen ay=1;
for (int k=0;ksize()!=2) )
return gentypeerr(contextptr);
gen g1=args[0],g2=args[1];
if (g2.type!=_VECT)
return gentypeerr(contextptr);
vecteur v2(*g2._VECTptr);
int sv2=int(v2.size());
if (sv2!=2) return gensizeerr(contextptr);
identificateur x("rieman_sum_x");
//on pose k=n*x
//mettre que v2[0]=n et v2[1]=k sont ds N
//_assume(makevecteur(is_plus(v2[0])));
//_assume(makevecteur(is_plus(v2[1])));
gen a=recursive_normal(v2[0]*subst(g1,v2[1],x*v2[0],false,contextptr),contextptr);
gen nda=_fxnd(a,contextptr);
vecteur nada(*nda._VECTptr);
//na numerateur de a et da denominateur de a ou k=n*x
gen na=nada[0];
gen da=nada[1];
vecteur var(2);
var[0]=na;
v2[1]=x;
var[1]=v2;
//var=[na,[n,x]]
gen b0=_split(var,contextptr);
if (is_undef(b0)) return b0;
//on separe les variables du numerateur
vecteur vb0(*b0._VECTptr);
if ((vb0.size()==1)&& (vb0[0]==0))
return string2gen(gettext("Probably not a Riemann sum"),false);
var[0]=da;
//var=[da,[n,x]]
gen b1=_split(var,contextptr);
if (is_undef(b1)) return b1;
//on separe les variables du denominateur
vecteur vb1(*b1._VECTptr);
if ((vb1.size()==1)&& (vb1[0]==0))
return string2gen(gettext("Probably not a Riemann sum"),false);
gen an=vb0[0]/vb1[0];
gen ax=vb0[1]/vb1[1];
gen tmp=_integrate(makesequence(ax,x,0,1),contextptr);
if (is_undef(tmp)) return tmp;
gen tmp2=_limit(makesequence(an,v2[0],plus_inf),contextptr);
//tmp n'a pas ete calcule sum_riemann(pi/(2*n)*log(sin(pi*k/(2*n))),[n,k])
//if ((tmp.type==_SYMB)&&(tmp._SYMBptr->sommet==at_integrate))
//return _limit(makevecteur(tmp*an,v2[0],plus_inf));
//tmp ne doit pas etre infini qd tmp2 est nul et reciproquement
if (is_inf(tmp)&& is_zero(tmp2))
return string2gen(gettext("Probably not a Riemann sum"),false);
if (is_zero(tmp)&& is_inf(tmp2))
return string2gen(gettext("Probably not a Riemann sum"),false);
gen res=recursive_normal(tmp*_series(makesequence(an,v2[0],plus_inf),contextptr),contextptr);
res=_limit(makesequence(res,v2[0],plus_inf),contextptr);
return res;
}
static const char _sum_riemann_s[]="sum_riemann";
static define_unary_function_eval (__sum_riemann,&_sum_riemann,_sum_riemann_s);
define_unary_function_ptr5( at_sum_riemann,alias_at_sum_rieman,&__sum_riemann,0,true);
#ifndef NO_NAMESPACE_GIAC
} // namespace giac
#endif // ndef NO_NAMESPACE_GIAC