Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/modules/vector_double_dense.pyx
4036 views
1
r"""
2
Dense vectors using a NumPy backend. This serves as a base class for
3
dense vectors over Real Double Field and Complex Double Field
4
5
EXAMPLES:
6
sage: v = vector(CDF,[(1,-1), (2,pi), (3,5)])
7
sage: v
8
(1.0 - 1.0*I, 2.0 + 3.14159265359*I, 3.0 + 5.0*I)
9
sage: type(v)
10
<type 'sage.modules.vector_complex_double_dense.Vector_complex_double_dense'>
11
sage: parent(v)
12
Vector space of dimension 3 over Complex Double Field
13
sage: v[0] = 5
14
sage: v
15
(5.0, 2.0 + 3.14159265359*I, 3.0 + 5.0*I)
16
sage: loads(dumps(v)) == v
17
True
18
sage: v = vector(RDF, [1,2,3,4]); v
19
(1.0, 2.0, 3.0, 4.0)
20
sage: loads(dumps(v)) == v
21
True
22
23
AUTHORS:
24
-- Jason Grout, Oct 2008: switch to numpy backend, factored out
25
Vector_double_dense class
26
-- Josh Kantor
27
-- William Stein
28
"""
29
30
###############################################################################
31
# Sage: System for Algebra and Geometry Experimentation
32
# Copyright (C) 2006 William Stein <[email protected]>
33
# Distributed under the terms of the GNU General Public License (GPL)
34
# http://www.gnu.org/licenses/
35
###############################################################################
36
37
cimport free_module_element
38
import free_module_element
39
40
from sage.structure.element cimport Element, ModuleElement, RingElement, Vector
41
42
from sage.rings.real_double import RDF
43
44
from sage.rings.complex_double import CDF
45
from sage.rings.complex_double cimport ComplexDoubleElement, new_ComplexDoubleElement
46
47
cimport numpy as cnumpy
48
49
numpy = None
50
scipy = None
51
52
# This is for the NumPy C API to work
53
cnumpy.import_array()
54
55
cdef class Vector_double_dense(free_module_element.FreeModuleElement):
56
"""
57
Base class for vectors over the Real Double Field and the Complex
58
Double Field. These are supposed to be fast vector operations
59
using C doubles. Most operations are implemented using numpy which
60
will call the underlying BLAS, if needed, on the system.
61
62
This class cannot be instantiated on its own. The numpy vector
63
creation depends on several variables that are set in the
64
subclasses.
65
66
EXAMPLES:
67
sage: v = vector(RDF, [1,2,3,4]); v
68
(1.0, 2.0, 3.0, 4.0)
69
sage: v*v
70
30.0
71
"""
72
def __cinit__(self, parent, entries, coerce=True, copy=True):
73
"""
74
Set up a new vector
75
76
EXAMPLE:
77
sage: v = vector(RDF, range(3))
78
sage: v.__new__(v.__class__, v.parent(), [1,1,1]) # random output
79
(3.00713073107e-261, 3.06320700422e-322, 2.86558074588e-322)
80
sage: v = vector(CDF, range(3))
81
sage: v.__new__(v.__class__, v.parent(), [1,1,1]) # random output
82
(-2.26770549592e-39, 5.1698223615e-252*I, -5.9147262602e-62 + 4.63145528786e-258*I)
83
"""
84
self._is_mutable = 1
85
self._degree = parent.degree()
86
self._parent = parent
87
88
cdef Vector_double_dense _new(self, cnumpy.ndarray vector_numpy):
89
"""
90
Return a new vector with same parent as self.
91
"""
92
cdef Vector_double_dense v
93
v = self.__class__.__new__(self.__class__,self._parent,None,None,None)
94
v._is_mutable = 1
95
v._parent = self._parent
96
v._degree = self._parent.degree()
97
98
v._vector_numpy = vector_numpy
99
return v
100
101
def __create_vector__(self):
102
"""
103
Create a new uninitialized numpy array to hold the data for the class.
104
105
This function assumes that self._numpy_dtypeint and
106
self._nrows and self._ncols have already been initialized.
107
108
EXAMPLE:
109
In this example, we throw away the current array and make a
110
new uninitialized array representing the data for the class.
111
sage: a=vector(RDF, range(9))
112
sage: a.__create_vector__()
113
"""
114
cdef cnumpy.npy_intp dims[1]
115
dims[0] = self._degree
116
self._vector_numpy = cnumpy.PyArray_SimpleNew(1, dims, self._numpy_dtypeint)
117
return
118
119
cdef bint is_dense_c(self):
120
"""
121
Return True (i.e., 1) if self is dense.
122
"""
123
return 1
124
125
cdef bint is_sparse_c(self):
126
"""
127
Return True (i.e., 1) if self is sparse.
128
"""
129
return 0
130
131
132
def __copy__(self, copy=True):
133
"""
134
Return a copy of the vector
135
136
EXAMPLE:
137
sage: a = vector(RDF, range(9))
138
sage: a == copy(a)
139
True
140
"""
141
if self._degree == 0:
142
return self
143
from copy import copy
144
return self._new(copy(self._vector_numpy))
145
146
def __init__(self, parent, entries, coerce = True, copy = True):
147
"""
148
Fill the vector with entries.
149
150
The numpy array must have already been allocated.
151
152
EXAMPLES:
153
sage: vector(RDF, range(9))
154
(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0)
155
sage: vector(CDF, 5)
156
(0.0, 0.0, 0.0, 0.0, 0.0)
157
158
TESTS:
159
sage: vector(CDF, 0)
160
()
161
sage: vector(RDF, 0)
162
()
163
sage: vector(CDF, 4)
164
(0.0, 0.0, 0.0, 0.0)
165
sage: vector(RDF, 4)
166
(0.0, 0.0, 0.0, 0.0)
167
sage: vector(CDF, [CDF(1+I)*j for j in range(4)])
168
(0.0, 1.0 + 1.0*I, 2.0 + 2.0*I, 3.0 + 3.0*I)
169
sage: vector(RDF, 4, range(4))
170
(0.0, 1.0, 2.0, 3.0)
171
172
sage: V = RDF^2
173
sage: V._element_class(V, 5)
174
Traceback (most recent call last):
175
...
176
TypeError: entries must be a list or 0
177
sage: V._element_class(V, 0)
178
(0.0, 0.0)
179
"""
180
cdef Py_ssize_t i,j
181
if isinstance(entries,(tuple, list)):
182
if len(entries)!=self._degree:
183
raise TypeError("entries has wrong length")
184
185
if coerce:
186
for i from 0<=i<self._degree:
187
self.set_unsafe(i,self._python_dtype(entries[i]))
188
else:
189
for i from 0<=i<self._degree:
190
self.set_unsafe(i,entries[i])
191
192
elif isinstance(entries, cnumpy.ndarray):
193
self._replace_self_with_numpy(entries)
194
else:
195
cnumpy.PyArray_FILLWBYTE(self._vector_numpy, 0)
196
if entries is None:
197
print "entries is None"
198
return
199
else:
200
try:
201
z = self._python_dtype(entries)
202
except TypeError:
203
raise TypeError("cannot coerce entry to type %s"%self._python_dtype)
204
if z != 0:
205
raise TypeError("entries must be a list or 0")
206
else:
207
# Set all entries to z=0.
208
for i from 0<=i<self._degree:
209
self.set_unsafe(i,z)
210
211
def __len__(self):
212
"""
213
Return the length of the vector.
214
215
EXAMPLE:
216
sage: v = vector(RDF, 5); v
217
(0.0, 0.0, 0.0, 0.0, 0.0)
218
sage: len(v)
219
5
220
"""
221
return self._degree
222
223
def __setitem__(self, i, object value):
224
"""
225
Set the `i`-th entry of self.
226
227
EXAMPLES:
228
sage: v = vector(CDF, [1,CDF(3,2), -1]); v
229
(1.0, 3.0 + 2.0*I, -1.0)
230
sage: v[1] = 2
231
sage: v[-1] = I
232
sage: v[5] = 2
233
Traceback (most recent call last):
234
...
235
IndexError: index out of range
236
sage: v
237
(1.0, 2.0, 1.0*I)
238
sage: v[1:3] = [1, 1]; v
239
(1.0, 1.0, 1.0)
240
"""
241
if not self._is_mutable:
242
raise ValueError("vector is immutable; please change a copy instead (use copy())")
243
cdef Py_ssize_t k, d, n
244
if isinstance(i, slice):
245
start, stop = i.start, i.stop
246
d = self.degree()
247
R = self.base_ring()
248
n = 0
249
for k from start <= k < stop:
250
if k >= d:
251
return
252
if k >= 0:
253
self[k] = R(value[n])
254
n = n + 1
255
else:
256
if i < 0:
257
i += self._degree
258
if i < 0 or i >= self._degree:
259
raise IndexError('index out of range')
260
self.set_unsafe(i, value)
261
262
def __getitem__(self, i):
263
"""
264
Return the `i`-th entry of self.
265
266
EXAMPLES:
267
sage: v = vector(CDF, [1,CDF(3,2), -1]); v
268
(1.0, 3.0 + 2.0*I, -1.0)
269
sage: v[1]
270
3.0 + 2.0*I
271
sage: v[-1]
272
-1.0
273
sage: v[5]
274
Traceback (most recent call last):
275
...
276
IndexError: index out of range
277
sage: v[-5]
278
Traceback (most recent call last):
279
...
280
IndexError: index out of range
281
sage: v[1:3]
282
(3.0 + 2.0*I, -1.0)
283
"""
284
if isinstance(i, slice):
285
start, stop, step = i.indices(len(self))
286
return free_module_element.vector(self.base_ring(), self.list()[start:stop])
287
else:
288
if i < 0:
289
i += self._degree
290
if i < 0 or i >= self._degree:
291
raise IndexError('index out of range')
292
return self.get_unsafe(i)
293
294
cdef set_unsafe(self, Py_ssize_t i, object value):
295
"""
296
Set the ith entry to value without any bounds checking,
297
mutability checking, etc.
298
"""
299
# We assume that Py_ssize_t is the same as npy_intp
300
301
# We must patch the ndarrayobject.h file so that the SETITEM
302
# macro does not have a semicolon at the end for this to work.
303
# Cython wraps the macro in a function that converts the
304
# returned int to a python object, which leads to compilation
305
# errors because after preprocessing you get something that
306
# looks like "););". This is bug
307
# http://scipy.org/scipy/numpy/ticket/918
308
309
# We call the self._python_dtype function on the value since
310
# numpy does not know how to deal with complex numbers other
311
# than the built-in complex number type.
312
cdef int status
313
status = cnumpy.PyArray_SETITEM(self._vector_numpy,
314
cnumpy.PyArray_GETPTR1(self._vector_numpy, i),
315
self._python_dtype(value))
316
#TODO: Throw an error if status == -1
317
318
319
cdef get_unsafe(self, Py_ssize_t i):
320
"""
321
Get the (i,j) entry without any bounds checking, etc.
322
"""
323
# We assume that Py_ssize_t is the same as npy_intp
324
return self._sage_dtype(cnumpy.PyArray_GETITEM(self._vector_numpy,
325
cnumpy.PyArray_GETPTR1(self._vector_numpy, i)))
326
327
328
cpdef ModuleElement _add_(self, ModuleElement right):
329
"""
330
Add two vectors together.
331
332
EXAMPLES:
333
sage: A = vector(RDF, range(3))
334
sage: A+A
335
(0.0, 2.0, 4.0)
336
"""
337
if self._degree == 0:
338
from copy import copy
339
return copy(self)
340
341
cdef Vector_double_dense _right, _left
342
_right = right
343
_left = self
344
345
return self._new(_left._vector_numpy + _right._vector_numpy)
346
347
cpdef ModuleElement _sub_(self, ModuleElement right):
348
"""
349
Return self - right
350
351
EXAMPLES:
352
sage: A = vector(RDF, range(3))
353
sage: (A-A).is_zero()
354
True
355
"""
356
if self._degree == 0:
357
from copy import copy
358
return copy(self)
359
360
cdef Vector_double_dense _right, _left
361
_right = right
362
_left = self
363
364
return self._new(_left._vector_numpy - _right._vector_numpy)
365
366
cpdef Element _dot_product_(self, Vector right):
367
"""
368
Dot product of self and right.
369
370
EXAMPLES:
371
sage: v = vector(RDF, [1,2,3]); w = vector(RDF, [2, 4, -3])
372
sage: v*w
373
1.0
374
sage: w*v
375
1.0
376
"""
377
if not right.parent() == self.parent():
378
right = self.parent().ambient_module()(right)
379
if self._degree == 0:
380
from copy import copy
381
return copy(self)
382
383
cdef Vector_double_dense _right, _left
384
_right = right
385
_left = self
386
387
global scipy
388
if scipy is None:
389
import scipy
390
return self._sage_dtype(scipy.dot(_left._vector_numpy, _right._vector_numpy))
391
392
cpdef Vector _pairwise_product_(self, Vector right):
393
"""
394
Return the component-wise product of self and right.
395
396
EXAMPLES:
397
sage: v = vector(CDF, [1,2,3]); w = vector(CDF, [2, 4, -3])
398
sage: v.pairwise_product(w)
399
(2.0, 8.0, -9.0)
400
"""
401
if not right.parent() == self.parent():
402
right = self.parent().ambient_module()(right)
403
404
if self._degree == 0:
405
from copy import copy
406
return copy(self)
407
408
cdef Vector_double_dense _right, _left
409
_right = right
410
_left = self
411
412
return self._new(_left._vector_numpy * _right._vector_numpy)
413
414
cpdef ModuleElement _rmul_(self, RingElement left):
415
"""
416
Multiply a scalar and vector
417
418
EXAMPLE:
419
sage: v = vector(CDF, range(3))
420
sage: 3*v
421
(0.0, 3.0, 6.0)
422
"""
423
if self._degree == 0:
424
from copy import copy
425
return copy(self)
426
427
return self._new(self._python_dtype(left)*self._vector_numpy)
428
429
430
cpdef ModuleElement _lmul_(self, RingElement right):
431
"""
432
Multiply a scalar and vector
433
434
EXAMPLE:
435
sage: v = vector(CDF, range(3))
436
sage: v*3
437
(0.0, 3.0, 6.0)
438
"""
439
if self._degree == 0:
440
from copy import copy
441
return copy(self)
442
443
return self._new(self._vector_numpy*self._python_dtype(right))
444
445
446
def inv_fft(self,algorithm="radix2", inplace=False):
447
"""
448
This performs the inverse fast fourier transform on the vector.
449
450
The fourier transform can be done in place using the keyword
451
inplace=True
452
453
This will be fastest if the vector's length is a power of 2.
454
455
EXAMPLES:
456
sage: v = vector(CDF,[1,2,3,4])
457
sage: w = v.fft()
458
sage: max(v - w.inv_fft()) < 1e-12
459
True
460
"""
461
return self.fft(direction="backward",algorithm=algorithm,inplace=inplace)
462
463
def fft(self, direction = "forward", algorithm = "radix2", inplace=False):
464
"""
465
This performs a fast fourier transform on the vector.
466
467
INPUT:
468
direction -- 'forward' (default) or 'backward'
469
470
The algorithm and inplace arguments are ignored.
471
472
This function is fastest if the vector's length is a power of 2.
473
474
EXAMPLES:
475
sage: v = vector(CDF,[1+2*I,2,3*I,4])
476
sage: v.fft()
477
(7.0 + 5.0*I, 1.0 + 1.0*I, -5.0 + 5.0*I, 1.0 - 3.0*I)
478
sage: v.fft(direction='backward')
479
(1.75 + 1.25*I, 0.25 - 0.75*I, -1.25 + 1.25*I, 0.25 + 0.25*I)
480
sage: v.fft().fft(direction='backward')
481
(1.0 + 2.0*I, 2.0, 3.0*I, 4.0)
482
sage: v.fft().parent()
483
Vector space of dimension 4 over Complex Double Field
484
sage: v.fft(inplace=True)
485
sage: v
486
(7.0 + 5.0*I, 1.0 + 1.0*I, -5.0 + 5.0*I, 1.0 - 3.0*I)
487
488
sage: v = vector(RDF,4,range(4)); v
489
(0.0, 1.0, 2.0, 3.0)
490
sage: v.fft()
491
(6.0, -2.0 + 2.0*I, -2.0, -2.0 - 2.0*I)
492
sage: v.fft(direction='backward')
493
(1.5, -0.5 - 0.5*I, -0.5, -0.5 + 0.5*I)
494
sage: v.fft().fft(direction='backward')
495
(0.0, 1.0, 2.0, 3.0)
496
sage: v.fft().parent()
497
Vector space of dimension 4 over Complex Double Field
498
sage: v.fft(inplace=True)
499
Traceback (most recent call last):
500
...
501
ValueError: inplace can only be True for CDF vectors
502
"""
503
if direction not in ('forward', 'backward'):
504
raise ValueError("direction must be either 'forward' or 'backward'")
505
506
if self._degree == 0:
507
return self
508
global scipy
509
if scipy is None:
510
import scipy
511
import scipy.fftpack
512
513
if inplace:
514
if self._sage_dtype is not CDF:
515
raise ValueError("inplace can only be True for CDF vectors")
516
if direction == 'forward':
517
self._vector_numpy = scipy.fftpack.fft(self._vector_numpy, overwrite_x = True)
518
else:
519
self._vector_numpy = scipy.fftpack.ifft(self._vector_numpy, overwrite_x = True)
520
else:
521
V = CDF**self._degree
522
from vector_complex_double_dense import Vector_complex_double_dense
523
if direction == 'forward':
524
return Vector_complex_double_dense(V, scipy.fft(self._vector_numpy))
525
else:
526
return Vector_complex_double_dense(V, scipy.ifft(self._vector_numpy))
527
528
529
def numpy(self):
530
"""
531
Return numpy array corresponding to this vector.
532
533
EXAMPLES:
534
sage: v = vector(CDF,4,range(4))
535
sage: v.numpy()
536
array([ 0.+0.j, 1.+0.j, 2.+0.j, 3.+0.j])
537
sage: v = vector(CDF,0)
538
sage: v.numpy()
539
array([], dtype=complex128)
540
sage: v = vector(RDF,4,range(4))
541
sage: v.numpy()
542
array([ 0., 1., 2., 3.])
543
sage: v = vector(RDF,0)
544
sage: v.numpy()
545
array([], dtype=float64)
546
"""
547
from copy import copy
548
return copy(self._vector_numpy)
549
550
cdef _replace_self_with_numpy(self,cnumpy.ndarray numpy_array):
551
"""
552
Replace the underlying numpy array with numpy_array.
553
"""
554
if self._degree == 0:
555
return
556
if numpy_array.ndim != 1 or len(self._vector_numpy) != numpy_array.shape[0]:
557
raise ValueError("vector lengths are not the same")
558
559
self._vector_numpy = numpy_array.astype(self._numpy_dtype)
560
561
562
def complex_vector(self):
563
"""
564
Return the associated complex vector, i.e., this vector but with
565
coefficients viewed as complex numbers.
566
567
EXAMPLES:
568
sage: v = vector(RDF,4,range(4)); v
569
(0.0, 1.0, 2.0, 3.0)
570
sage: v.complex_vector()
571
(0.0, 1.0, 2.0, 3.0)
572
sage: v = vector(RDF,0)
573
sage: v.complex_vector()
574
()
575
"""
576
return self.change_ring(CDF)
577
578
579
def zero_at(self, eps):
580
r"""
581
Returns a copy with small entries replaced by zeros.
582
583
This is useful for modifying output from algorithms
584
which have large relative errors when producing zero
585
elements, e.g. to create reliable doctests.
586
587
INPUT:
588
589
- ``eps`` - cutoff value
590
591
OUTPUT:
592
593
A modified copy of the vector. Elements smaller than
594
or equal to ``eps`` are replaced with zeroes. For
595
complex vectors, the real and imaginary parts are
596
considered individually.
597
598
599
EXAMPLES::
600
601
sage: v = vector(RDF, [1.0, 2.0, 10^-10, 3.0])
602
sage: v.zero_at(1e-8)
603
(1.0, 2.0, 0.0, 3.0)
604
sage: v.zero_at(1e-12)
605
(1.0, 2.0, 1e-10, 3.0)
606
607
For complex numbers the real and imaginary parts are considered
608
separately. ::
609
610
sage: w = vector(CDF, [10^-6 + 5*I, 5 + 10^-6*I, 5 + 5*I, 10^-6 + 10^-6*I])
611
sage: w.zero_at(1.0e-4)
612
(5.0*I, 5.0, 5.0 + 5.0*I, 0.0)
613
sage: w.zero_at(1.0e-8)
614
(1e-06 + 5.0*I, 5.0 + 1e-06*I, 5.0 + 5.0*I, 1e-06 + 1e-06*I)
615
"""
616
import sage.rings.complex_double
617
global numpy
618
cdef Vector_double_dense v
619
if numpy is None:
620
import numpy
621
eps = float(eps)
622
out = self._vector_numpy.copy()
623
if self._sage_dtype is sage.rings.complex_double.CDF:
624
out.real[numpy.abs(out.real) <= eps] = 0
625
out.imag[numpy.abs(out.imag) <= eps] = 0
626
else:
627
out[numpy.abs(out) <= eps] = 0
628
v = self._new(out)
629
return v
630
631
632
def norm(self, p=2):
633
r"""
634
Returns the norm (or related computations) of the vector.
635
636
INPUT:
637
638
- ``p`` - default: 2 - controls which norm is computed,
639
allowable values are any real number and positive and
640
negative infinity. See output discussion for specifics.
641
642
OUTPUT:
643
644
Returned value is a double precision floating point value
645
in ``RDF`` (or an integer when ``p=0``). The default value
646
of ``p = 2`` is the "usual" Euclidean norm. For other values:
647
648
- ``p = Infinity`` or ``p = oo``: the maximum of the
649
absolute values of the entries, where the absolute value
650
of the complex number `a+bi` is `\sqrt{a^2+b^2}`.
651
- ``p = -Infinity`` or ``p = -oo``: the minimum of the
652
absolute values of the entries.
653
- ``p = 0`` : the number of nonzero entries in the vector.
654
- ``p`` is any other real number: for a vector `\vec{x}`
655
this method computes
656
657
.. math::
658
659
\left(\sum_i x_i^p\right)^{1/p}
660
661
For ``p < 0`` this function is not a norm, but the above
662
computation may be useful for other purposes.
663
664
ALGORITHM:
665
666
Computation is performed by the ``norm()`` function of
667
the SciPy/NumPy library.
668
669
EXAMPLES:
670
671
First over the reals. ::
672
673
sage: v = vector(RDF, range(9))
674
sage: v.norm()
675
14.28285685...
676
sage: v.norm(p=2)
677
14.28285685...
678
sage: v.norm(p=6)
679
8.744039097...
680
sage: v.norm(p=Infinity)
681
8.0
682
sage: v.norm(p=-oo)
683
0.0
684
sage: v.norm(p=0)
685
8.0
686
sage: v.norm(p=0.3)
687
4099.153615...
688
689
And over the complex numbers. ::
690
691
sage: w = vector(CDF, [3-4*I, 0, 5+12*I])
692
sage: w.norm()
693
13.9283882...
694
sage: w.norm(p=2)
695
13.9283882...
696
sage: w.norm(p=0)
697
2.0
698
sage: w.norm(p=4.2)
699
13.0555695...
700
sage: w.norm(p=oo)
701
13.0
702
703
Negative values of ``p`` are allowed and will
704
provide the same computation as for positive values.
705
A zero entry in the vector will raise a warning and return
706
zero. ::
707
708
sage: v = vector(CDF, range(1,10))
709
sage: v.norm(p=-3.2)
710
0.953760808...
711
sage: w = vector(CDF, [-1,0,1])
712
sage: w.norm(p=-1.6)
713
0.0
714
715
Return values are in ``RDF``, or an integer when ``p = 0``. ::
716
717
sage: v = vector(RDF, [1,2,4,8])
718
sage: v.norm() in RDF
719
True
720
sage: v.norm(p=0) in ZZ
721
True
722
723
Improper values of ``p`` are caught. ::
724
725
sage: w = vector(CDF, [-1,0,1])
726
sage: w.norm(p='junk')
727
Traceback (most recent call last):
728
...
729
ValueError: vector norm 'p' must be +/- infinity or a real number, not junk
730
"""
731
global numpy
732
if numpy is None:
733
import numpy
734
import sage.rings.infinity
735
import sage.rings.integer
736
if p == sage.rings.infinity.Infinity:
737
p = numpy.inf
738
elif p == -sage.rings.infinity.Infinity:
739
p = -numpy.inf
740
else:
741
try:
742
p = RDF(p)
743
except:
744
raise ValueError("vector norm 'p' must be +/- infinity or a real number, not %s" % p)
745
n = numpy.linalg.norm(self._vector_numpy, ord=p)
746
# p = 0 returns integer *count* of non-zero entries
747
return RDF(n)
748
749
750
#############################
751
# statistics
752
#############################
753
def mean(self):
754
"""
755
Calculate the arithmetic mean of the vector.
756
757
EXAMPLE:
758
sage: v = vector(RDF, range(9))
759
sage: w = vector(CDF, [k+(9-k)*I for k in range(9)])
760
sage: v.mean()
761
4.0
762
sage: w.mean()
763
4.0 + 5.0*I
764
"""
765
global numpy
766
if numpy is None:
767
import numpy
768
return self._sage_dtype(numpy.mean(self._vector_numpy))
769
770
def variance(self, population=True):
771
"""
772
Calculate the variance of entries of the vector.
773
774
INPUT:
775
population -- If False, calculate the sample variance.
776
777
EXAMPLE:
778
sage: v = vector(RDF, range(9))
779
sage: w = vector(CDF, [k+(9-k)*I for k in range(9)])
780
sage: v.variance()
781
7.5
782
sage: v.variance(population=False)
783
6.66666666667
784
sage: w.variance()
785
15.0
786
sage: w.variance(population=False)
787
13.3333333333
788
"""
789
global numpy
790
if numpy is None:
791
import numpy
792
793
if population is True:
794
return self._sage_dtype(numpy.var(self._vector_numpy, ddof=1))
795
else:
796
return self._sage_dtype(numpy.var(self._vector_numpy, ddof=0))
797
798
def standard_deviation(self, population=True):
799
"""
800
Calculate the standard deviation of entries of the vector.
801
802
INPUT:
803
population -- If False, calculate the sample standard deviation.
804
805
EXAMPLES:
806
sage: v = vector(RDF, range(9))
807
sage: w = vector(CDF, [k+(9-k)*I for k in range(9)])
808
sage: v.standard_deviation()
809
2.73861278753
810
sage: v.standard_deviation(population=False)
811
2.58198889747
812
sage: w.standard_deviation()
813
3.87298334621
814
sage: w.standard_deviation(population=False)
815
3.6514837167
816
"""
817
global numpy
818
if numpy is None:
819
import numpy
820
821
if population is True:
822
return self._sage_dtype(numpy.std(self._vector_numpy, ddof=1))
823
else:
824
return self._sage_dtype(numpy.std(self._vector_numpy, ddof=0))
825
826
827
def stats_kurtosis(self):
828
"""
829
Compute the kurtosis of a dataset.
830
831
Kurtosis is the fourth central moment divided by the square of
832
the variance. Since we use Fisher's definition, 3.0 is
833
subtracted from the result to give 0.0 for a normal
834
distribution. (Paragraph from the scipy.stats docstring.)
835
836
EXAMPLE:
837
sage: v = vector(RDF, range(9))
838
sage: w = vector(CDF, [k+(9-k)*I for k in range(9)])
839
sage: v.stats_kurtosis()
840
-1.23
841
sage: w.stats_kurtosis()
842
-1.23
843
"""
844
global scipy
845
if scipy is None:
846
import scipy
847
import scipy.stats
848
return self._sage_dtype(scipy.stats.kurtosis(self._vector_numpy))
849
850
def prod(self):
851
"""
852
Return the product of the entries of self.
853
854
EXAMPLES:
855
sage: v = vector(RDF, range(9))
856
sage: w = vector(CDF, [k+(9-k)*I for k in range(9)])
857
sage: v.prod()
858
0.0
859
sage: w.prod()
860
57204225.0*I
861
"""
862
return self._sage_dtype(self._vector_numpy.prod())
863
864
def sum(self):
865
"""
866
Return the sum of the entries of self.
867
868
EXAMPLES:
869
sage: v = vector(RDF, range(9))
870
sage: w = vector(CDF, [k+(9-k)*I for k in range(9)])
871
sage: v.sum()
872
36.0
873
sage: w.sum()
874
36.0 + 45.0*I
875
"""
876
return self._sage_dtype(self._vector_numpy.sum())
877
878
879