source: git/ntl/src/WordVector.c @ 45fefa

fieker-DuValspielwiese
Last change on this file since 45fefa was de6a29, checked in by Hans Schönemann <hannes@…>, 19 years ago
* hannes: NTL-5.4 git-svn-id: file:///usr/local/Singular/svn/trunk@8693 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 6.1 KB
Line 
1
2#include <NTL/WordVector.h>
3
4#include <NTL/new.h>
5
6NTL_START_IMPL
7
8
9
10void WordVector::DoSetLength(long n)   
11{   
12   long m; 
13 
14   if (n < 0) { 
15      Error("negative length in vector::SetLength"); 
16   } 
17
18   if (NTL_OVERFLOW(n, NTL_BITS_PER_LONG, 0)) 
19      Error("length too big in vector::SetLength");
20     
21   if (n == 0) { 
22      if (rep) rep[-1] = 0; 
23      return; 
24   } 
25 
26   if (!rep) { 
27      m = ((n+NTL_WordVectorMinAlloc-1)/NTL_WordVectorMinAlloc) * NTL_WordVectorMinAlloc; 
28
29      if (NTL_OVERFLOW(m, NTL_BITS_PER_LONG, 0))
30         Error("length too big in vector::SetLength");
31
32      _ntl_ulong *p = (_ntl_ulong *) 
33                      NTL_MALLOC(m, sizeof(_ntl_ulong), 2*sizeof(_ntl_ulong));
34
35      if (!p) { 
36         Error("out of memory in SetLength()"); 
37      } 
38      rep = p+2;
39
40      rep[-1] = n;
41      rep[-2] = m << 1;
42 
43      return;
44   } 
45
46   long max_length = (rep[-2] >> 1);
47
48   if (n <= max_length) { 
49      rep[-1] = n; 
50      return;
51   } 
52
53   long frozen = (rep[-2] & 1);
54
55   if (frozen) Error("Cannot grow this WordVector");
56     
57   m = max(n, long(NTL_WordVectorExpansionRatio*max_length));
58
59   m = ((m+NTL_WordVectorMinAlloc-1)/NTL_WordVectorMinAlloc)*NTL_WordVectorMinAlloc; 
60   _ntl_ulong *p = rep - 2;
61
62   if (NTL_OVERFLOW(m, NTL_BITS_PER_LONG, 0))
63      Error("length too big in vector::SetLength");
64
65   p = (_ntl_ulong *) 
66       NTL_REALLOC(p, m, sizeof(_ntl_ulong), 2*sizeof(_ntl_ulong)); 
67   if (!p) { 
68      Error("out of memory in SetLength()"); 
69   } 
70   rep = p+2;
71
72   rep[-1] = n;
73   rep[-2] = m << 1;
74} 
75 
76 
77void WordVector::SetMaxLength(long n) 
78{ 
79   long OldLength = length(); 
80   DoSetLength(n); 
81   if (rep) rep[-1] = OldLength;
82} 
83 
84 
85WordVector& WordVector::operator=(const WordVector& a) 
86{ 
87   long i, n; 
88   _ntl_ulong *p; 
89   const _ntl_ulong *ap; 
90 
91   if (this == &a) return *this; 
92 
93   n = a.length(); 
94   ap = a.elts(); 
95 
96   SetLength(n); 
97   p = elts(); 
98 
99 
100   for (i = 0; i < n; i++) 
101      p[i] = ap[i]; 
102
103   return *this;
104} 
105       
106 
107WordVector::~WordVector() 
108{ 
109   if (!rep) return; 
110   if (rep[-2] & 1) Error("Cannot free this WordVector");
111   free(rep-2);
112} 
113   
114void WordVector::kill() 
115{ 
116   if (!rep) return; 
117   if (rep[-2] & 1) 
118      Error("Cannot free this WordVector");
119   free(rep-2);
120   rep = 0; 
121} 
122 
123void WordVector::RangeError(long i) const 
124{ 
125   Error( "index out of range in vector "); 
126} 
127
128void CopySwap(WordVector& x, WordVector& y)
129{
130   static WordVector t;
131   t = x;
132   x = y;
133   y = t;
134}
135 
136void WordVector::swap_impl(WordVector& x, WordVector& y) 
137{ 
138   if ((x.rep && (x.rep[-2] & 1)) ||
139       (y.rep && (y.rep[-2] & 1))) {
140      CopySwap(x, y);
141      return;
142   }
143
144   _ntl_ulong* t; 
145   t = x.rep; 
146   x.rep = y.rep; 
147   y.rep = t; 
148} 
149 
150void WordVector::append_impl(WordVector& v, _ntl_ulong a) 
151{ 
152   long l = v.length();
153   v.SetLength(l+1); 
154   v[l] = a; 
155} 
156 
157void WordVector::append_impl(WordVector& v, const WordVector& w) 
158{ 
159   long l = v.length(); 
160   long m = w.length(); 
161   long i; 
162   v.SetLength(l+m); 
163   for (i = 0; i < m; i++) 
164      v[l+i] = w[i]; 
165}
166
167
168long operator==(const WordVector& a, const WordVector& b) 
169{ 
170   long n = a.length(); 
171   if (b.length() != n) return 0; 
172   const _ntl_ulong* ap = a.elts(); 
173   const _ntl_ulong* bp = b.elts(); 
174   long i; 
175   for (i = 0; i < n; i++) if (ap[i] != bp[i]) return 0; 
176   return 1; 
177} 
178
179long operator!=(const WordVector& a, const WordVector& b) 
180{  return !(a == b); }
181
182   
183
184
185
186long InnerProduct(const WordVector& a, const WordVector& b)
187{
188   long n = min(a.length(), b.length());
189   const _ntl_ulong *ap = a.elts();
190   const _ntl_ulong *bp = b.elts();
191
192   _ntl_ulong acc;
193   long i;
194
195   acc = 0;
196   for (i = 0; i < n; i++)
197      acc ^= ap[i] & bp[i];
198
199#if (NTL_BITS_PER_LONG == 32)
200   acc ^= acc >> 16;
201   acc ^= acc >> 8;
202   acc ^= acc >> 4;
203   acc ^= acc >> 2;
204   acc ^= acc >> 1;
205   acc &= 1;
206#elif (NTL_BITS_PER_LONG == 64)
207   acc ^= acc >> 32;
208   acc ^= acc >> 16;
209   acc ^= acc >> 8;
210   acc ^= acc >> 4;
211   acc ^= acc >> 2;
212   acc ^= acc >> 1;
213   acc &= 1;
214#else
215   _ntl_ulong t = acc;
216   while (t) {
217      t = t >> 8;
218      acc ^= t;
219   }
220
221   acc ^= acc >> 4;
222   acc ^= acc >> 2;
223   acc ^= acc >> 1;
224   acc &= 1;
225#endif
226
227   return long(acc);
228}
229
230
231void ShiftAdd(_ntl_ulong *cp, const _ntl_ulong* ap, long sa, long n)
232// c = c + (a << n)
233{
234   if (sa == 0) return;
235
236   long i;
237
238   long wn = n/NTL_BITS_PER_LONG;
239   long bn = n - wn*NTL_BITS_PER_LONG;
240
241   if (bn == 0) {
242      for (i = sa+wn-1; i >= wn; i--)
243         cp[i] ^= ap[i-wn];
244   }
245   else {
246      _ntl_ulong t = ap[sa-1] >> (NTL_BITS_PER_LONG-bn);
247      if (t) cp[sa+wn] ^= t;
248      for (i = sa+wn-1; i >= wn+1; i--)
249         cp[i] ^= (ap[i-wn] << bn) | (ap[i-wn-1] >> (NTL_BITS_PER_LONG-bn));
250      cp[wn] ^= ap[0] << bn;
251   }
252}
253
254long WV_BlockConstructAlloc(WordVector& x, long d, long n)
255{
256   long nwords, nbytes, AllocAmt, m, j; 
257   _ntl_ulong *p, *q;
258
259
260   /* check n value */
261
262   if (n <= 0)
263      Error("block construct: n must be positive");
264
265   /* check d value */
266
267   if (d <= 0) 
268      Error("block construct: d must be positive");
269
270   if (NTL_OVERFLOW(d, NTL_BITS_PER_LONG, 0) || 
271       NTL_OVERFLOW(d, sizeof(_ntl_ulong), 2*sizeof(_ntl_ulong)))
272      Error("block construct: d too large");
273
274   nwords = d + 2;
275   nbytes = nwords*sizeof(_ntl_ulong);
276   
277   AllocAmt = (NTL_MAX_ALLOC_BLOCK - sizeof(_ntl_ulong)) / nbytes;
278   if (AllocAmt == 0) AllocAmt = 1;
279
280   if (AllocAmt < n)
281      m = AllocAmt;
282   else
283      m = n;
284
285   p = (_ntl_ulong *) NTL_MALLOC(m, nbytes, sizeof(_ntl_ulong));
286   if (!p) Error("out of memory in block construct");
287
288   *p = m;
289
290   q = p+3;
291   x.rep = q;
292   
293   for (j = 0; j < m; j++) {
294      q[-2] = (d << 1) | 1;
295      q[-1] = 0;
296      q += nwords;
297   }
298
299   return m;
300}
301
302void WV_BlockConstructSet(WordVector& x, WordVector& y, long i)
303{
304   long d, size;
305 
306   d = x.rep[-2] >> 1;
307   size = d + 2;
308 
309   y.rep = x.rep + i*size;
310}
311
312long WV_BlockDestroy(WordVector& x)
313{
314   long m;
315   _ntl_ulong *p;
316 
317   p = x.rep - 3;
318   m = (long) *p;
319   free(p);
320   return m;
321}
322
323long WV_storage(long d)
324{
325   return (d + 2)*sizeof(_ntl_ulong) + sizeof(WordVector);
326}
327
328
329
330
331NTL_END_IMPL
Note: See TracBrowser for help on using the repository browser.