source: git/gfanlib/gfanlib_vector.h

spielwiese
Last change on this file was 15813d, checked in by Hans Schoenemann <hannes@…>, 8 years ago
format
  • Property mode set to 100644
File size: 11.4 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)__attribute__((always_inline))
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 __attribute__((always_inline)){assert(n>=0 && n<(int)v.size());return (v[n]);}
80  typ& UNCHECKEDACCESS(int n)__attribute__((always_inline)){return (v[n]);}
81  const typ& UNCHECKEDACCESS(int n)const __attribute__((always_inline)){return (v[n]);}
82
83  //-------------
84  // STL related
85  //-------------
86  unsigned int size()const{return v.size();};
87  void resize(int n){v.resize(n,typ());};
88  void grow(int i){if(size()<i)resize(i);}
89  void push_back(typ a)
90  {
91    v.push_back(a);
92  }
93  void sort()
94    {
95      std::sort(v.begin(),v.end());
96    }
97  bool nextPermutation()
98    {
99      return std::next_permutation(v.begin(),v.end());
100    }
101  bool operator<(const Vector & b)const
102    {
103      if(size()<b.size())return true;
104      if(size()>b.size())return false;
105      for(unsigned i=0;i<size();i++)
106        {
107          if(v[i]<b[i])return true;
108          if(b[i]<v[i])return false;
109        }
110      return false;
111    }
112
113  //-----------------
114  // Arithmetic fast
115  //-----------------
116  typ sum()const{typ f;for(typename std::vector<typ>::const_iterator i=v.begin();i!=v.end();i++)f+=*i;return f;};
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  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;}
120  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;}
121//  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;}
122  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;}
123  bool operator!=(const Vector & q)const {return !(operator==(q));}
124  bool isZero() const
125    {
126      for(typename std::vector<typ>::const_iterator i=v.begin();i!=v.end();++i)if(!(*i).isZero())return false;
127      return true;
128    }
129  bool isPositive() const
130    {
131      for(typename std::vector<typ>::const_iterator i=v.begin();i!=v.end();++i)if((*i).sign()<=0)return false;
132      return true;
133    }
134  bool isNonNegative() const
135    {
136      for(typename std::vector<typ>::const_iterator i=v.begin();i!=v.end();++i)if(i->sign()<0)return false;
137      return true;
138    }
139/*  int max()const
140  {
141    int ret=-0x7fffffff; //not completely correct, but kind of works for 64bit
142    for(int i=0;i<v.size();i++)if(ret<v[i])ret=v[i];
143    return ret;
144  }
145  int min()const
146  {
147    int ret=0x7fffffff;
148    for(int i=0;i<v.size();i++)if(ret>v[i])ret=v[i];
149    return ret;
150  }
151*/
152  friend bool dependent(const Vector& p, const Vector& q)
153    {
154          /*
155      typ pp=dot(p,p);
156      typ qq=dot(q,q);
157      typ pq=dot(p,q);
158      return pq*pq==pp*qq;
159*/
160          unsigned n=p.size();
161          assert(n==q.size());
162          unsigned i;
163          for(i=0;i<n;i++)
164          {
165            if(!p.v[i].isZero())break;
166          }
167          if(i==n)return true;
168          if(q.v[i].isZero())return q.isZero();
169          typ a=p.v[i];
170          typ b=q.v[i];
171          for(unsigned j=0;j<n;j++)
172            if(a*q.v[j]!=b*p.v[j])return false;
173          return true;
174    }
175
176  //-----------------
177  // Arithmetic slow
178  //-----------------
179  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;}
180//  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;}
181/*  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;}
182  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;}
183*/
184  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;}
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 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;}
187  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;}
188  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;}
189
190  friend Vector operator-(const Vector &b)
191  {
192    Vector ret(b.size());
193    for(unsigned i=0;i<b.size();i++)ret[i]=-b[i];
194    return ret;
195  }
196  //------------------
197  // Monomial related
198  //------------------
199/*  int divides(const Vektor& q) const
200    {
201      assert(size()==q.size());
202      int n=v.size();
203      for(int i=0;i<n;i++)
204        {
205          if(v[i]>0)if(q.v[i]<v[i])return 0;
206        }
207      return 1;
208    }
209  inline friend bool relativelyPrime(const Vektor& p, const Vektor& q)
210    {
211      assert(p.size()==q.size());
212      int n=p.size();
213      for(int t=0;t<n;t++)if((p[t]>0)&&(q[t]>0)) return false;
214      return true;
215    }
216  Vektor supportVector()const
217    {
218      Vektor r(v.size());
219      for(int i=0;i<size();i++)
220        r[i]=(v[i]!=0);
221      return r;
222    }
223*/
224  //------------------------------
225  // Subvectors and concatenation
226  //------------------------------
227  Vector subvector(int begin, int end)const
228    {
229      assert(begin>=0);
230      assert(end<=(int)size());
231      assert(end>=begin);
232      Vector ret(end-begin);
233      for(int i=0;i<end-begin;i++)
234        ret[i]=v[begin+i];
235      return ret;
236    }
237/*  Vektor subvector(list<int> const &chosenIndices)const
238  {
239    Vektor ret(chosenIndices.size());
240    int I=0;
241    for(list<int>::const_iterator i=chosenIndices.begin();i!=chosenIndices.end();i++,I++)ret[I]=v[*i];
242    return ret;
243  }
244*/
245  friend Vector concatenation(Vector const &a, Vector const &b)
246  {
247    Vector ret(a.size()+b.size());
248    for(int i=0;i<a.size();i++)ret[i]=a[i];
249    for(int i=0;i<b.size();i++)ret[i+a.size()]=b[i];
250    return ret;
251  }
252  //----------------------
253  // Zero/nonZero entries
254  //----------------------
255/*  int indexOfLargestNonzeroEntry()const
256  {
257    int ret=-1;
258    for(int i=0;i<v.size();i++)
259      {
260        if(v[i])ret=i;
261      }
262    return ret;
263  }
264  Vektor supportIndices()const
265  {
266    Vektor ret(0);
267    for(int i=0;i<v.size();i++)
268      if(v[i]!=0)ret.push_back(i);
269    return ret;
270  }
271  Vektor supportAsZeroOneVector()const
272  {
273    Vektor ret(v.size());
274    for(int i=0;i<v.size();i++)ret[i]=bool(v[i]);
275    return ret;
276  }
277  void calcsupport(void)
278    {
279      support=0;
280      for(int i=0;i<v.size();i++)support=(support<<1)|(((v[i]>0)==true)&1);
281    }
282*/
283  friend std::ostream &operator<<(std::ostream &f, Vector const &a)
284  {
285    f<<"(";
286    for(typename std::vector<typ>::const_iterator i=a.v.begin();i!=a.v.end();i++)
287    {
288      if(i!=a.v.begin()) f<<",";
289      f<<*i;
290    }
291    return f<<")";
292  }
293
294  std::string toString()const
295  {
296          std::stringstream f;
297          f<<*this;
298          return f.str();
299  }
300
301  typ gcd()const
302  {
303    typ temp1,temp2;
304    typ ret(1);
305    for(unsigned i=0;i<size();i++)
306      ret=typ::gcd(ret,v[i],temp1,temp2);
307    return ret;
308  }
309  Vector normalized()const
310  {
311    assert(!typ::isField());
312    return (*this)/gcd();
313  }
314};
315
316typedef Vector<Integer> ZVector;
317typedef Vector<Rational> QVector;
318typedef Vector<int> IntVector;
319
320inline QVector ZToQVector(ZVector const &v)
321{
322  QVector ret(v.size());
323  for(unsigned i=0;i<v.size();i++)ret[i]=Rational(v[i]);
324  return ret;
325}
326
327
328inline IntVector ZToIntVector(ZVector const &v)
329{
330  IntVector ret(v.size());
331  for(unsigned i=0;i<v.size();i++)ret[i]=v[i].toInt();
332  return ret;
333}
334
335
336inline ZVector IntToZVector(IntVector const &v)
337{
338  ZVector ret(v.size());
339  for(unsigned i=0;i<v.size();i++)ret[i]=Integer(v[i]);
340  return ret;
341}
342
343inline ZVector QToZVectorPrimitive(QVector const &v)
344{
345    int n=v.size();
346    ZVector ret(n);
347
348    mpz_t lcm;
349    mpz_t gcd;
350    mpz_init_set_ui(lcm, 1);
351    mpz_init_set_ui(gcd, 0);
352
353    mpq_t a;
354    mpq_init(a);
355    for(int j=0;j<n;j++)
356      {
357        v[j].setGmp(a);
358        if(mpz_cmp_si(mpq_denref(a),1)!=0)
359          mpz_lcm(lcm,lcm,mpq_denref(a));
360        if(mpz_sgn(mpq_numref(a))!=0)
361          mpz_gcd(gcd,gcd,mpq_numref(a));
362      }
363    mpq_clear(a);
364    if(mpz_sgn(gcd)!=0)//v is non-zero
365      {
366        if((mpz_cmp_si(lcm,1)==0)&&(mpz_cmp_si(gcd,1)==0)) //gcd=lcm=1
367          {
368            mpq_t a;
369            mpq_init(a);
370
371            for(int i=0;i<n;i++)
372              {
373                v[i].setGmp(a);
374                ret[i]=Integer(mpq_numref(a));
375              }
376            mpq_clear(a);
377          }
378        else
379          {
380            mpq_t a;
381            mpq_init(a);
382            mpz_t tempA;
383            mpz_t tempB;
384            mpz_init(tempA);
385            mpz_init(tempB);
386            for(int i=0;i<n;i++)
387              {
388                v[i].setGmp(a);
389                mpz_set(tempA,mpq_denref(a));
390                mpz_set(tempB,mpq_numref(a));
391                mpz_mul(tempA,gcd,tempA);
392                mpz_mul(tempB,lcm,tempB);
393                mpz_divexact(tempA,tempB,tempA);
394                ret[i]=Integer(tempA);
395              }
396            mpz_clear(tempB);
397            mpz_clear(tempA);
398            mpq_clear(a);
399          }
400      }
401    mpz_clear(gcd);
402    mpz_clear(lcm);
403
404    return ret;
405}
406
407}
408
409#endif /* LIB_ZVECTOR_H_ */
Note: See TracBrowser for help on using the repository browser.