source: git/gfanlib/gfanlib_vector.h @ 3c0aa5

spielwiese
Last change on this file since 3c0aa5 was 3c0aa5, checked in by Yue Ren <ren@…>, 10 years ago
status update for natalia
  • Property mode set to 100644
File size: 11.5 KB
Line 
1/*
2 * lib_zvector.h
3 *
4 *  Created on: Sep 6, 2010
5 *      Author: anders
6 */
7
8#ifndef GFANLIB_ZVECTOR_H_INCLUDED
9#define GFANLIB_ZVECTOR_H_INCLUDED
10
11#include <vector>
12#include <list>
13#include <assert.h>
14#include <algorithm>
15#include <iostream>
16#include <sstream>
17
18#include "gfanlib_z.h"
19#include "gfanlib_q.h"
20
21namespace gfan{
22
23inline void outOfRange(int i, int n)
24{
25  std::cerr<<"Index out of range. i="<<i<<" n="<<n<<std::endl;
26  assert(0);
27}
28
29template <class typ> class Vector{
30private:
31  std::vector<typ> v;
32public:
33  //--------------
34  // Constructors
35  //--------------
36  Vector(const Vector &a):v(a.v){
37  }
38  Vector(int n):v(n){
39    assert(n>=0);
40  };
41/*  Vektor(const typ *p, int n):v(n){
42    assert(n>=0);
43    support=0;for(int i=0;i<n;i++)v[i]=p[i];
44  };*/
45  ~Vector(){
46  };
47  Vector(){
48  };
49  static Vector standardVector(int n, int i)
50    {
51      Vector v(n);
52      v[i]=typ(1);
53      return v;
54    }
55  static Vector allOnes(int n)
56    {
57      Vector v(n);
58      for(int i=0;i<n;i++)
59        v[i]=typ(1);
60      return v;
61    }
62  //-------------
63  // Conversions
64  //-------------
65/*  template<class T> Vektor(const Vektor<T>& c)
66          :v(c.size())
67        {
68          for(int i=0;i<size();i++)v[i]=typ(c[i]);
69        }
70*/
71  //--------
72  // Access
73  //--------
74  typ& operator[](int n)
75    {
76      if(!(n>=0 && n<(int)v.size()))outOfRange(n,v.size());
77      return (v[n]);
78    }
79  const typ& operator[](int n)const{assert(n>=0 && n<(int)v.size());return (v[n]);}
80  const typ& UNCHECKEDACCESS(int n)const{return (v[n]);}
81
82  //-------------
83  // STL related
84  //-------------
85  unsigned int size()const{return v.size();};
86  void resize(int n){v.resize(n,typ());};
87  void grow(int i){if(size()<i)resize(i);}
88  void push_back(typ a)
89  {
90    v.push_back(a);
91  }
92  void sort()
93    {
94      std::sort(v.begin(),v.end());
95    }
96  bool nextPermutation()
97    {
98      return std::next_permutation(v.begin(),v.end());
99    }
100  bool operator<(const Vector & b)const
101    {
102      if(size()<b.size())return true;
103      if(size()>b.size())return false;
104      for(unsigned i=0;i<size();i++)
105        {
106          if(v[i]<b[i])return true;
107          if(b[i]<v[i])return false;
108        }
109      return false;
110    }
111
112  //-----------------
113  // Arithmetic fast
114  //-----------------
115  typ sum()const{typ f;for(typename std::vector<typ>::const_iterator i=v.begin();i!=v.end();i++)f+=*i;return f;};
116  Vector& operator+=(const Vector& q){assert(size()==q.size());typename std::vector<typ>::const_iterator j=q.v.begin();for(typename std::vector<typ>::iterator i=v.begin();i!=v.end();++i,++j)(*i)+=(*j);return *this;}
117  Vector& operator-=(const Vector& q){assert(size()==q.size());typename std::vector<typ>::const_iterator j=q.v.begin();for(typename std::vector<typ>::iterator i=v.begin();i!=v.end();++i,++j)(*i)-=(*j);return *this;}
118  Vector& operator/=(const Vector& q){assert(size()==q.size());typename std::vector<typ>::const_iterator j=q.v.begin();for(typename std::vector<typ>::iterator i=v.begin();i!=v.end();++i,++j)(*i)/=(*j);return *this;}
119  inline friend typ dot(const Vector& p, const Vector& q){assert(p.size()==q.size());typ s;typename std::vector<typ>::const_iterator j=q.v.begin();for(typename std::vector<typ>::const_iterator i=p.v.begin();i!=p.v.end();++i,++j)s+=(*i)*(*j);return s;}
120//  inline friend int64 dotLong(const Vektor& p, const Vektor& q){assert(p.size()==q.size());int64 s=0;for(int i=0;i<p.size();i++)s+=(int64)p[i]*(int64)q[i];return s;}
121  bool operator==(const Vector & q)const{if(size()!=q.size())return false;typename std::vector<typ>::const_iterator j=q.v.begin();for(typename std::vector<typ>::const_iterator i=v.begin();i!=v.end();++i,++j)if((*i)!=(*j))return false;return true;}
122  bool operator!=(const Vector & q)const {return !(operator==(q));}
123  bool isZero() const
124    {
125      for(typename std::vector<typ>::const_iterator i=v.begin();i!=v.end();++i)if(!(*i).isZero())return false;
126      return true;
127    }
128  bool isPositive() const
129    {
130      for(typename std::vector<typ>::const_iterator i=v.begin();i!=v.end();++i)if((*i).sign()<=0)return false;
131      return true;
132    }
133  bool isNonNegative() const
134    {
135      for(typename std::vector<typ>::const_iterator i=v.begin();i!=v.end();++i)if(i->sign()<0)return false;
136      return true;
137    }
138/*  int max()const
139  {
140    int ret=-0x7fffffff; //not completely correct, but kind of works for 64bit
141    for(int i=0;i<v.size();i++)if(ret<v[i])ret=v[i];
142    return ret;
143  }
144  int min()const
145  {
146    int ret=0x7fffffff;
147    for(int i=0;i<v.size();i++)if(ret>v[i])ret=v[i];
148    return ret;
149  }
150*/
151  friend bool dependent(const Vector& p, const Vector& q)
152    {
153          /*
154      typ pp=dot(p,p);
155      typ qq=dot(q,q);
156      typ pq=dot(p,q);
157      return pq*pq==pp*qq;
158*/
159          unsigned n=p.size();
160          assert(n==q.size());
161          unsigned i;
162          for(i=0;i<n;i++)
163          {
164            if(!p.v[i].isZero())break;
165          }
166          if(i==n)return true;
167          if(q.v[i].isZero())return q.isZero();
168          typ a=p.v[i];
169          typ b=q.v[i];
170          for(unsigned j=0;j<n;j++)
171            if(a*q.v[j]!=b*p.v[j])return false;
172          return true;
173    }
174
175  //-----------------
176  // Arithmetic slow
177  //-----------------
178  inline friend Vector operator*(typ s, const Vector& q){Vector p=q;for(unsigned i=0;i<q.size();i++)p[i]*=s;return p;}
179//  inline friend Vektor operator/(const Vektor& q, typ s){Vektor p=q;for(int i=0;i<q.size();i++)p[i]/=s;return p;}
180/*  inline friend Vector operator*(const Vektor& p, const Vektor& q){assert(p.size()==q.size());Vektor p1=p;for(int i=0;i<p.size();i++)p1.v[i]*=q.v[i];return p1;}
181  inline friend Vektor operator+(const Vektor& p, const Vektor& q){assert(p.size()==q.size());Vektor p1=p;for(int i=0;i<p.size();i++)p1[i]+=q[i];return p1;}
182*/
183  inline friend Vector operator/(const Vector& p, typ const &s){Vector ret(p.size());for(unsigned i=0;i<p.size();i++)ret[i]=p[i]/s;return ret;}
184  inline friend Vector operator+(const Vector& p, const Vector& q){assert(p.size()==q.size());Vector p1=p;for(unsigned i=0;i<p.size();i++)p1[i]+=q[i];return p1;}
185  inline friend Vector operator-(const Vector& p, const Vector& q){assert(p.size()==q.size());Vector p1=p;for(unsigned i=0;i<p.size();i++)p1[i]-=q[i];return p1;}
186  inline friend Vector max(const Vector& p, const Vector& q){assert(p.size()==q.size());Vector p1=p;for(unsigned i=0;i<p.size();i++)if(p1[i]<q[i])p1[i]=q[i];return p1;}
187  inline friend Vector min(const Vector& p, const Vector& q){assert(p.size()==q.size());Vector p1=p;for(unsigned i=0;i<p.size();i++)if(p1[i]>q[i])p1[i]=q[i];return p1;}
188
189  friend Vector operator-(const Vector &b)
190  {
191    Vector ret(b.size());
192    for(unsigned i=0;i<b.size();i++)ret[i]=-b[i];
193    return ret;
194  }
195  //------------------
196  // Monomial related
197  //------------------
198/*  int divides(const Vektor& q) const
199    {
200      assert(size()==q.size());
201      int n=v.size();
202      for(int i=0;i<n;i++)
203        {
204          if(v[i]>0)if(q.v[i]<v[i])return 0;
205        }
206      return 1;
207    }
208  inline friend bool relativelyPrime(const Vektor& p, const Vektor& q)
209    {
210      assert(p.size()==q.size());
211      int n=p.size();
212      for(int t=0;t<n;t++)if((p[t]>0)&&(q[t]>0)) return false;
213      return true;
214    }
215  Vektor supportVector()const
216    {
217      Vektor r(v.size());
218      for(int i=0;i<size();i++)
219        r[i]=(v[i]!=0);
220      return r;
221    }
222*/
223  //------------------------------
224  // Subvectors and concatenation
225  //------------------------------
226  Vector subvector(int begin, int end)const
227    {
228      assert(begin>=0);
229      assert(end<=(int)size());
230      assert(end>=begin);
231      Vector ret(end-begin);
232      for(int i=0;i<end-begin;i++)
233        ret[i]=v[begin+i];
234      return ret;
235    }
236/*  Vektor subvector(list<int> const &chosenIndices)const
237  {
238    Vektor ret(chosenIndices.size());
239    int I=0;
240    for(list<int>::const_iterator i=chosenIndices.begin();i!=chosenIndices.end();i++,I++)ret[I]=v[*i];
241    return ret;
242  }
243*/
244  friend Vector concatenation(Vector const &a, Vector const &b)
245  {
246    Vector ret(a.size()+b.size());
247    for(int i=0;i<a.size();i++)ret[i]=a[i];
248    for(int i=0;i<b.size();i++)ret[i+a.size()]=b[i];
249    return ret;
250  }
251  //----------------------
252  // Zero/nonZero entries
253  //----------------------
254/*  int indexOfLargestNonzeroEntry()const
255  {
256    int ret=-1;
257    for(int i=0;i<v.size();i++)
258      {
259        if(v[i])ret=i;
260      }
261    return ret;
262  }
263  Vektor supportIndices()const
264  {
265    Vektor ret(0);
266    for(int i=0;i<v.size();i++)
267      if(v[i]!=0)ret.push_back(i);
268    return ret;
269  }
270  Vektor supportAsZeroOneVector()const
271  {
272    Vektor ret(v.size());
273    for(int i=0;i<v.size();i++)ret[i]=bool(v[i]);
274    return ret;
275  }
276  void calcsupport(void)
277    {
278      support=0;
279      for(int i=0;i<v.size();i++)support=(support<<1)|(((v[i]>0)==true)&1);
280    }
281*/
282  friend std::ostream &operator<<(std::ostream &f, Vector const &a)
283  {
284    f<<"(";
285    for(typename std::vector<typ>::const_iterator i=a.v.begin();i!=a.v.end();i++)
286    {
287      if(i!=a.v.begin()) f<<",";
288      f<<*i;
289    }
290    return f<<")";
291  }
292
293  std::string toString()const
294  {
295          std::stringstream f;
296          f<<*this;
297          return f.str();
298  }
299
300  typ gcd()const
301  {
302    typ temp1,temp2;
303    typ ret(1);
304    for(unsigned i=0;i<size();i++)
305      ret=typ::gcd(ret,v[i],temp1,temp2);
306    return ret;
307  }
308  Vector normalized()const
309  {
310    assert(!typ::isField());
311    return (*this)/gcd();
312  }
313
314  void debugPrint()const
315  {
316    std::stringstream s;
317    s<<"(";
318    for(typename std::vector<typ>::const_iterator i=this->v.begin();i!=this->v.end();i++)
319    {
320      if(i!=this->v.begin()) s<<",";
321      s<<*i;
322    }
323    s<<")"<<std::endl;
324    std::cout << s.str();
325    return;
326  }
327};
328
329typedef Vector<Integer> ZVector;
330typedef Vector<Rational> QVector;
331typedef Vector<int> IntVector;
332
333inline QVector ZToQVector(ZVector const &v)
334{
335  QVector ret(v.size());
336  for(unsigned i=0;i<v.size();i++)ret[i]=Rational(v[i]);
337  return ret;
338}
339
340
341inline IntVector ZToIntVector(ZVector const &v)
342{
343  IntVector ret(v.size());
344  for(unsigned i=0;i<v.size();i++)ret[i]=v[i].toInt();
345  return ret;
346}
347
348
349inline ZVector IntToZVector(IntVector const &v)
350{
351  ZVector ret(v.size());
352  for(unsigned i=0;i<v.size();i++)ret[i]=Integer(v[i]);
353  return ret;
354}
355
356inline ZVector QToZVectorPrimitive(QVector const &v)
357{
358    int n=v.size();
359    ZVector ret(n);
360
361    mpz_t lcm;
362    mpz_t gcd;
363    mpz_init_set_ui(lcm, 1);
364    mpz_init_set_ui(gcd, 0);
365
366    mpq_t a;
367    mpq_init(a);
368    for(int j=0;j<n;j++)
369      {
370        v[j].setGmp(a);
371        if(mpz_cmp_si(mpq_denref(a),1)!=0)
372          mpz_lcm(lcm,lcm,mpq_denref(a));
373        if(mpz_sgn(mpq_numref(a))!=0)
374          mpz_gcd(gcd,gcd,mpq_numref(a));
375      }
376    mpq_clear(a);
377    if(mpz_sgn(gcd)!=0)//v is non-zero
378      {
379        if((mpz_cmp_si(lcm,1)==0)&&(mpz_cmp_si(gcd,1)==0)) //gcd=lcm=1
380          {
381            mpq_t a;
382            mpq_init(a);
383
384            for(int i=0;i<n;i++)
385              {
386                v[i].setGmp(a);
387                ret[i]=Integer(mpq_numref(a));
388              }
389            mpq_clear(a);
390          }
391        else
392          {
393            mpq_t a;
394            mpq_init(a);
395            mpz_t tempA;
396            mpz_t tempB;
397            mpz_init(tempA);
398            mpz_init(tempB);
399            for(int i=0;i<n;i++)
400              {
401                v[i].setGmp(a);
402                mpz_set(tempA,mpq_denref(a));
403                mpz_set(tempB,mpq_numref(a));
404                mpz_mul(tempA,gcd,tempA);
405                mpz_mul(tempB,lcm,tempB);
406                mpz_divexact(tempA,tempB,tempA);
407                ret[i]=Integer(tempA);
408              }
409            mpz_clear(tempB);
410            mpz_clear(tempA);
411            mpq_clear(a);
412          }
413      }
414    mpz_clear(gcd);
415    mpz_clear(lcm);
416
417    return ret;
418};
419
420};
421
422#endif /* LIB_ZVECTOR_H_ */
Note: See TracBrowser for help on using the repository browser.