4
Copyright (C) 2003, 2004, 2005 Gabor Csardi <csardi@rmki.kfki.hu>
5
MTA RMKI, Konkoly-Thege Miklos st. 29-33, Budapest 1121, Hungary
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or
10
(at your option) any later version.
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
29
#include <string.h> /* memcpy & co. */
31
#include <stdarg.h> /* va_start & co */
36
* \section about_igraph_vector_t_objects About \type igraph_vector_t objects
38
* <para>The \type igraph_vector_t data type is a simple and efficient
39
* interface to arrays containing numbers. It is something
40
* similar as (but much simpler than) the \type vector template
41
* in the C++ standard library.</para>
43
* <para>Vectors are used extensively in \a igraph, all
44
* functions which expect or return a list of numbers use
45
* igraph_vector_t to achieve this.</para>
47
* <para>The \type igraph_vector_t type usually uses
49
* to store n elements. Sometimes it
50
* uses more, this is because vectors can shrink, but even if they
51
* shrink, the current implementation does not free a single bit of
54
* <para>The elements in an \type igraph_vector_t
55
* object are indexed from zero, we follow the usual C convention
58
* <para>The elements of a vector always occupy a single block of
59
* memory, the starting address of this memory block can be queried
60
* with the \ref VECTOR macro. This way, vector objects can be used
61
* with standard mathematical libraries, like the GNU Scientific
67
* \section igraph_vector_constructors_and_destructors Constructors and
70
* <para>\type igraph_vector_t objects have to be initialized before using
71
* them, this is analogous to calling a constructor on them. There are a
72
* number of \type igraph_vector_t constructors, for your
73
* convenience. \ref igraph_vector_init() is the basic constructor, it
74
* creates a vector of the given length, filled with zeros.
75
* \ref igraph_vector_copy() creates a new identical copy
76
* of an already existing and initialized vector. \ref
77
* igraph_vector_init_copy() creates a vector by copying a regular C array.
78
* \ref igraph_vector_init_seq() creates a vector containing a regular
79
* sequence with increment one.</para>
81
* <para>\ref igraph_vector_view() is a special constructor, it allows you to
82
* handle a regular C array as a \type vector without copying
86
* <para>If a \type igraph_vector_t object is not needed any more, it
87
* should be destroyed to free its allocated memory by calling the
88
* \type igraph_vector_t destructor, \ref igraph_vector_destroy().</para>
90
* <para> Note that vectors created by \ref igraph_vector_view() are special,
91
* you mustn't call \ref igraph_vector_destroy() on these.</para>
96
* \function igraph_vector_init
97
* \brief Initializes a vector object (constructor).
100
* Every vector needs to be initialized before it can be used, and
101
* there are a number of initialization functions or otherwise called
105
* Every vector object initialized by this function should be
106
* destroyed (ie. the memory allocated for it should be freed) when it
107
* is not needed anymore, the \ref igraph_vector_destroy() function is
108
* responsible for this.
109
* \param v Pointer to a not yet initialized vector object.
110
* \param size The size of the vector.
111
* \return error code:
112
* \c IGRAPH_ENOMEM if there is not enough memory.
114
* Time complexity: operating system dependent, the amount of
115
* \quote time \endquote required to allocate
117
* n is the number of elements.
120
int FUNCTION(igraph_vector,init) (TYPE(igraph_vector)* v, int long size) {
121
long int alloc_size= size > 0 ? size : 1;
122
if (size < 0) { size=0; }
123
v->stor_begin=igraph_Calloc(alloc_size, BASE);
124
if (v->stor_begin==0) {
125
IGRAPH_ERROR("cannot init vector", IGRAPH_ENOMEM);
127
v->stor_end=v->stor_begin + alloc_size;
128
v->end=v->stor_begin+size;
135
* \function igraph_vector_view
136
* \brief Handle a regular C array as a \type igraph_vector_t.
139
* This is a special \type igraph_vector_t constructor. It allows to
140
* handle a regular C array as a \type igraph_vector_t temporarily.
141
* Be sure that you \em don't ever call the destructor (\ref
142
* igraph_vector_destroy()) on objects created by this constructor.
143
* \param v Pointer to an uninitialized \type igraph_vector_t object.
144
* \param data Pointer, the C array.
145
* \param length The length of the C array.
146
* \return Pointer to the vector object, the same as the
147
* \p v parameter, for convenience.
149
* Time complexity: O(1)
152
const TYPE(igraph_vector)*FUNCTION(igraph_vector,view) (const TYPE(igraph_vector) *v,
155
TYPE(igraph_vector) *v2=(TYPE(igraph_vector)*)v;
156
v2->stor_begin=(BASE*)data;
157
v2->stor_end=(BASE*)data+length;
164
* \function igraph_vector_init_real
165
* \brief Create an \type igraph_vector_t from the parameters.
168
* Because of how C and the C library handles variable length argument
169
* lists, it is required that you supply real constants to this
170
* function. This means that
171
* \verbatim igraph_vector_t v;
172
* igraph_vector_init_real(&v, 5, 1,2,3,4,5); \endverbatim
173
* is an error at runtime and the results are undefined. This is
175
* \verbatim igraph_vector_t v;
176
* igraph_vector_init_real(&v, 5, 1.0,2.0,3.0,4.0,5.0); \endverbatim
177
* \param v Pointer to an uninitialized \type igraph_vector_t object.
178
* \param no Positive integer, the number of \type igraph_real_t
179
* parameters to follow.
180
* \param ... The elements of the vector.
181
* \return Error code, this can be \c IGRAPH_ENOMEM
182
* if there isn't enough memory to allocate the vector.
184
* \sa \ref igraph_vector_init_real_end(), \ref igraph_vector_init_int() for similar
187
* Time complexity: depends on the time required to allocate memory,
188
* but at least O(n), the number of
189
* elements in the vector.
192
int FUNCTION(igraph_vector,init_real)(TYPE(igraph_vector) *v, int no, ...) {
195
IGRAPH_CHECK(FUNCTION(igraph_vector,init)(v, no));
198
for (i=0; i<no; i++) {
199
VECTOR(*v)[i]=(BASE) va_arg(ap, double);
208
* \function igraph_vector_init_real_end
209
* \brief Create an \type igraph_vector_t from the parameters.
212
* This constructor is similar to \ref igraph_vector_init_real(), the only
213
* difference is that instead of giving the number of elements in the
214
* vector, a special marker element follows the last real vector
216
* \param v Pointer to an uninitialized \type igraph_vector_t object.
217
* \param endmark This element will signal the end of the vector. It
218
* will \em not be part of the vector.
219
* \param ... The elements of the vector.
220
* \return Error code, \c IGRAPH_ENOMEM if there
221
* isn't enough memory.
223
* \sa \ref igraph_vector_init_real() and \ref igraph_vector_init_int_end() for
226
* Time complexity: at least O(n) for
227
* n elements plus the time
228
* complexity of the memory allocation.
231
int FUNCTION(igraph_vector,init_real_end)(TYPE(igraph_vector) *v,
236
va_start(ap, endmark);
238
BASE num = va_arg(ap, double);
239
if (num == endmark) {
246
IGRAPH_CHECK(FUNCTION(igraph_vector,init)(v,n));
247
IGRAPH_FINALLY(FUNCTION(igraph_vector,destroy), v);
249
va_start(ap, endmark);
250
for (i=0; i<n; i++) {
251
VECTOR(*v)[i]=(BASE) va_arg(ap, double);
255
IGRAPH_FINALLY_CLEAN(1);
261
* \function igraph_vector_init_int
262
* \brief Create an \type igraph_vector_t containing the parameters.
265
* This function is similar to \ref igraph_vector_init_real(), but it expects
266
* \type int parameters. It is important that all parameters
267
* should be of this type, otherwise the result of the function call
269
* \param v Pointer to an uninitialized \type igraph_vector_t object.
270
* \param no The number of \type int parameters to follow.
271
* \param ... The elements of the vector.
272
* \return Error code, \c IGRAPH_ENOMEM if there is
274
* \sa \ref igraph_vector_init_real() and igraph_vector_init_int_end(), these are
277
* Time complexity: at least O(n) for
278
* n elements plus the time
279
* complexity of the memory allocation.
282
int FUNCTION(igraph_vector,init_int)(TYPE(igraph_vector) *v, int no, ...) {
285
IGRAPH_CHECK(FUNCTION(igraph_vector,init)(v, no));
288
for (i=0; i<no; i++) {
289
VECTOR(*v)[i]=(BASE) va_arg(ap, int);
298
* \function igraph_vector_init_int_end
299
* \brief Create an \type igraph_vector_t from the parameters.
302
* This constructor is similar to \ref igraph_vector_init_int(), the only
303
* difference is that instead of giving the number of elements in the
304
* vector, a special marker element follows the last real vector
306
* \param v Pointer to an uninitialized \type igraph_vector_t object.
307
* \param endmark This element will signal the end of the vector. It
308
* will \em not be part of the vector.
309
* \param ... The elements of the vector.
310
* \return Error code, \c IGRAPH_ENOMEM if there
311
* isn't enough memory.
313
* \sa \ref igraph_vector_init_int() and \ref igraph_vector_init_real_end() for
316
* Time complexity: at least O(n) for
317
* n elements plus the time
318
* complexity of the memory allocation.
321
int FUNCTION(igraph_vector_init,int_end)(TYPE(igraph_vector) *v, int endmark, ...) {
325
va_start(ap, endmark);
327
int num = va_arg(ap, int);
328
if (num == endmark) {
335
IGRAPH_CHECK(FUNCTION(igraph_vector,init)(v, n));
336
IGRAPH_FINALLY(FUNCTION(igraph_vector,destroy), v);
338
va_start(ap, endmark);
339
for (i=0; i<n; i++) {
340
VECTOR(*v)[i]=(BASE) va_arg(ap, int);
344
IGRAPH_FINALLY_CLEAN(1);
350
* \function igraph_vector_destroy
351
* \brief Destroys a vector object.
354
* All vectors initialized by \ref igraph_vector_init() should be properly
355
* destroyed by this function. A destroyed vector needs to be
356
* reinitialized by \ref igraph_vector_init(), \ref igraph_vector_init_copy() or
357
* another constructor.
358
* \param v Pointer to the (previously initialized) vector object to
361
* Time complexity: operating system dependent.
364
void FUNCTION(igraph_vector,destroy) (TYPE(igraph_vector)* v) {
366
if (v->stor_begin != 0) {
367
igraph_Free(v->stor_begin);
368
v->stor_begin = NULL;
374
* \function igraph_vector_reserve
375
* \brief Reserves memory for a vector.
378
* \a igraph vectors are flexible, they can grow and
380
* however occasionally needs the data in the vector to be copyed.
381
* In order to avoid you can call this function to reserve space for
382
* future growth of the vector.
385
* Note that this function does \em not change the size of the
386
* vector. Let us see a small example to clarify things: if you
387
* reserve space for 100 elements and the size of your
388
* vector was (and still is) 60, then you can surely add additional 40
389
* elements to your vector before it will be copied.
390
* \param v The vector object.
391
* \param size The new \em allocated size of the vector.
392
* \return Error code:
393
* \c IGRPAH_ENOMEM if there is not enough memory.
395
* Time complexity: operating system dependent, should be around
397
* is the new allocated size of the vector.
400
int FUNCTION(igraph_vector,reserve) (TYPE(igraph_vector)* v, long int size) {
401
long int actual_size=FUNCTION(igraph_vector,size)(v);
404
assert(v->stor_begin != NULL);
405
if (size <= FUNCTION(igraph_vector,size)(v)) { return 0; }
407
tmp=igraph_Realloc(v->stor_begin, size, BASE);
409
IGRAPH_ERROR("cannot reserve space for vector", IGRAPH_ENOMEM);
412
v->stor_end=v->stor_begin + size;
413
v->end=v->stor_begin+actual_size;
420
* \function igraph_vector_empty
421
* \brief Decides whether the size of the vector is zero.
423
* \param v The vector object.
424
* \return Non-zero number if the size of the vector is not zero and
427
* Time complexity: O(1).
430
igraph_bool_t FUNCTION(igraph_vector,empty) (const TYPE(igraph_vector)* v) {
432
assert(v->stor_begin != NULL);
433
return v->stor_begin == v->end;
438
* \function igraph_vector_size
439
* \brief Gives the size (=length) of the vector.
441
* \param v The vector object
442
* \return The size of the vector.
444
* Time complexity: O(1).
447
long int FUNCTION(igraph_vector,size) (const TYPE(igraph_vector)* v) {
449
assert(v->stor_begin != NULL);
450
return v->end - v->stor_begin;
455
* \function igraph_vector_clear
456
* \brief Removes all elements from a vector.
459
* This function simply sets the size of the vector to zero, it does
460
* not free any allocated memory. For that you have to call
461
* \ref igraph_vector_destroy().
462
* \param v The vector object.
464
* Time complexity: O(1).
467
void FUNCTION(igraph_vector,clear) (TYPE(igraph_vector)* v) {
469
assert(v->stor_begin != NULL);
470
v->end = v->stor_begin;
475
* \function igraph_vector_push_back
476
* \brief Appends one element to a vector.
479
* This function resizes the vector to be one element longer and
480
* sets the very last element in the vector to \p e.
481
* \param v The vector object.
482
* \param e The element to append to the vector.
483
* \return Error code:
484
* \c IGRAPH_ENOMEM: not enough memory.
486
* Time complexity: operating system dependent. What is important that
488
* subsequent calls to this function has time complexity
489
* O(n), even if there
490
* hadn't been any space reserved for the new elements by
491
* \ref igraph_vector_reserve(). This is implemented by a trick similar to the C++
492
* \type vector class: each time more memory is allocated for a
493
* vector, the size of the additionally allocated memory is the same
494
* as the vector's current length. (We assume here that the time
495
* complexity of memory allocation is at most linear.)
498
int FUNCTION(igraph_vector,push_back) (TYPE(igraph_vector)* v, BASE e) {
500
assert(v->stor_begin != NULL);
502
/* full, allocate more storage */
503
if (v->stor_end == v->end) {
504
long int new_size = FUNCTION(igraph_vector,size)(v) * 2;
505
if (new_size == 0) { new_size = 1; }
506
IGRAPH_CHECK(FUNCTION(igraph_vector,reserve)(v, new_size));
517
* \function igraph_vector_insert
518
* \brief Inserts a single element into a vector.
520
* Note that this function does not do range checking. Insertion will shift the
521
* elements from the position given to the end of the vector one position to the
522
* right, and the new element will be inserted in the empty space created at
523
* the given position. The size of the vector will increase by one.
525
* \param v The vector object.
526
* \param pos The position where the new element is inserted.
528
int FUNCTION(igraph_vector,insert)(TYPE(igraph_vector) *v, long int pos,
530
long int size = FUNCTION(igraph_vector,size)(v);
531
IGRAPH_CHECK(FUNCTION(igraph_vector,resize)(v, size+1));
533
memmove(v->stor_begin+pos+1, v->stor_begin+pos,
534
sizeof(BASE)*(size-pos));
536
v->stor_begin[pos] = value;
542
* \section igraph_vector_accessing_elements Accessing elements
544
* <para>The simplest way to access an element of a vector is to use the
545
* \ref VECTOR macro. This macro can be used both for querying and setting
546
* \type igraph_vector_t elements. If you need a function, \ref
547
* igraph_vector_e() queries and \ref igraph_vector_set() sets an element of a
548
* vector. \ref igraph_vector_e_ptr() returns the address of an element.</para>
550
* <para>\ref igraph_vector_tail() returns the last element of a non-empty
551
* vector. There is no <function>igraph_vector_head()</function> function
552
* however, as it is easy to write <code>VECTOR(v)[0]</code>
558
* \function igraph_vector_e
559
* \brief Access an element of a vector.
560
* \param v The \type igraph_vector_t object.
561
* \param pos The position of the element, the index of the first
563
* \return The desired element.
564
* \sa \ref igraph_vector_e_ptr() and the \ref VECTOR macro.
566
* Time complexity: O(1).
569
BASE FUNCTION(igraph_vector,e) (const TYPE(igraph_vector)* v, long int pos) {
571
assert(v->stor_begin != NULL);
572
return * (v->stor_begin + pos);
577
* \function igraph_vector_e_ptr
578
* \brief Get the address of an element of a vector
579
* \param v The \type igraph_vector_t object.
580
* \param pos The position of the element, the position of the first
582
* \return Pointer to the desired element.
583
* \sa \ref igraph_vector_e() and the \ref VECTOR macro.
585
* Time complexity: O(1).
588
BASE* FUNCTION(igraph_vector,e_ptr) (const TYPE(igraph_vector)* v, long int pos) {
590
assert(v->stor_begin != NULL);
591
return v->stor_begin+pos;
596
* \function igraph_vector_set
597
* \brief Assignment to an element of a vector.
598
* \param v The \type igraph_vector_t element.
599
* \param pos Position of the element to set.
600
* \param value New value of the element.
601
* \sa \ref igraph_vector_e().
604
void FUNCTION(igraph_vector,set) (TYPE(igraph_vector)* v,
605
long int pos, BASE value) {
607
assert(v->stor_begin != NULL);
608
*(v->stor_begin + pos) = value;
613
* \function igraph_vector_null
614
* \brief Sets each element in the vector to zero.
617
* Note that \ref igraph_vector_init() sets the elements to zero as well, so
618
* it makes no sense to call this function on a just initialized
620
* \param v The vector object.
622
* Time complexity: O(n), the size of
626
void FUNCTION(igraph_vector,null) (TYPE(igraph_vector)* v) {
628
assert(v->stor_begin != NULL);
629
if (FUNCTION(igraph_vector,size)(v)>0) {
630
memset(v->stor_begin, 0,
631
sizeof(BASE)*FUNCTION(igraph_vector,size)(v));
636
* \function igraph_vector_fill
637
* \brief Fill a vector with a constant element
639
* Sets each element of the vector to the supplied constant.
640
* \param vector The vector to work on.
641
* \param e The element to fill with.
643
* Time complexity: O(n), the size of the vector.
646
void FUNCTION(igraph_vector,fill) (TYPE(igraph_vector)* v, BASE e) {
649
assert(v->stor_begin != NULL);
650
for (ptr = v->stor_begin; ptr < v->end; ptr++) {
657
* \function igraph_vector_tail
658
* \brief Returns the last element in a vector.
661
* It is an error to call this function on an empty vector, the result
663
* \param v The vector object.
664
* \return The last element.
666
* Time complexity: O(1).
669
BASE FUNCTION(igraph_vector,tail)(const TYPE(igraph_vector) *v) {
671
assert(v->stor_begin != NULL);
672
return *((v->end)-1);
677
* \function igraph_vector_pop_back
678
* \brief Removes and returns the last element of a vector.
681
* It is an error to call this function with an empty vector.
682
* \param v The vector object.
683
* \return The removed last element.
685
* Time complexity: O(1).
688
BASE FUNCTION(igraph_vector,pop_back)(TYPE(igraph_vector)* v) {
691
assert(v->stor_begin != NULL);
692
assert(v->end != v->stor_begin);
693
tmp=FUNCTION(igraph_vector,e)(v, FUNCTION(igraph_vector,size)(v)-1);
700
* \function igraph_vector_sort_cmp
701
* \brief Internal comparision function of vector elements, used by
702
* \ref igraph_vector_sort().
705
int FUNCTION(igraph_vector,sort_cmp)(const void *a, const void *b) {
706
const BASE *da = (const BASE *) a;
707
const BASE *db = (const BASE *) b;
709
return (*da > *db) - (*da < *db);
714
* \function igraph_vector_sort
715
* \brief Sorts the elements of the vector into ascending order.
718
* This function uses the built-in sort function of the C library.
719
* \param v Pointer to an initialized vector object.
721
* Time complexity: should be
727
void FUNCTION(igraph_vector,sort)(TYPE(igraph_vector) *v) {
729
assert(v->stor_begin != NULL);
730
qsort(v->stor_begin, FUNCTION(igraph_vector,size)(v),
731
sizeof(BASE), FUNCTION(igraph_vector,sort_cmp));
736
* \function igraph_vector_resize
737
* \brief Resize the vector.
740
* Note that this function does not free any memory, just sets the
741
* size of the vector to the given one. It can on the other hand
742
* allocate more memory if the new size is larger than the previous
743
* one. In this case the newly appeared elements in the vector are
744
* \em not set to zero, they are uninitialized.
745
* \param v The vector object
746
* \param newsize The new size of the vector.
747
* \return Error code,
748
* \c IGRAPH_ENOMEM if there is not enough
749
* memory. Note that this function \em never returns an error
750
* if the vector is made smaller.
751
* \sa \ref igraph_vector_reserve() for allocating memory for future
752
* extensions of a vector.
754
* Time complexity: O(1) if the new
755
* size is smaller, operating system dependent if it is larger. In the
756
* latter case it is usually around
758
* n is the new size of the vector.
761
int FUNCTION(igraph_vector,resize)(TYPE(igraph_vector)* v, long int newsize) {
763
assert(v->stor_begin != NULL);
764
IGRAPH_CHECK(FUNCTION(igraph_vector,reserve)(v, newsize));
765
v->end = v->stor_begin+newsize;
771
* \function igraph_vector_max
772
* \brief Gives the maximum element of the vector.
775
* If the size of the vector is zero, an arbitrary number is
777
* \param v The vector object.
778
* \return The maximum element.
780
* Time complexity: O(n),
781
* n is the size of the vector.
784
BASE FUNCTION(igraph_vector,max)(const TYPE(igraph_vector)* v) {
788
assert(v->stor_begin != NULL);
789
max=*(v->stor_begin);
791
while (ptr < v->end) {
802
* \function igraph_vector_which_max
803
* \brief Gives the position of the maximum element of the vector.
806
* If the size of the vector is zero, -1 is
808
* \param v The vector object.
809
* \return The position of the first maximum element.
811
* Time complexity: O(n),
812
* n is the size of the vector.
815
long int FUNCTION(igraph_vector,which_max)(const TYPE(igraph_vector)* v) {
817
if (!FUNCTION(igraph_vector,empty)(v)) {
822
assert(v->stor_begin != NULL);
823
max=*(v->stor_begin); which=0;
824
ptr=v->stor_begin+1; pos=1;
825
while (ptr < v->end) {
837
* \function igraph_vector_min
838
* \brief Smallest element of a vector.
840
* The vector must be non-empty.
841
* \param v The input vector.
842
* \return The smallest element of \p v.
844
* Time complexity: O(n), the number of elements.
847
BASE FUNCTION(igraph_vector,min)(const TYPE(igraph_vector)* v) {
851
assert(v->stor_begin != NULL);
852
min=*(v->stor_begin);
854
while (ptr < v->end) {
864
* \function igraph_vector_which_min
865
* \brief Index of the smallest element.
867
* The vector must be non-empty.
868
* If the smallest element is not unique, then the index of the first
870
* \param v The input vector.
871
* \return Index of the smallest element.
873
* Time complexity: O(n), the number of elements.
876
long int FUNCTION(igraph_vector,which_min)(const TYPE(igraph_vector)* v) {
878
if (!FUNCTION(igraph_vector,empty)(v)) {
883
assert(v->stor_begin != NULL);
884
min=*(v->stor_begin); which=0;
885
ptr=v->stor_begin+1; pos=1;
886
while (ptr < v->end) {
899
* \function igraph_vector_init_copy
900
* \brief Initializes a vector from an ordinary C array (constructor).
902
* \param v Pointer to an uninitialized vector object.
903
* \param data A regular C array.
904
* \param length The length of the C array.
905
* \return Error code:
906
* \c IGRAPH_ENOMEM if there is not enough memory.
908
* Time complexity: operating system specific, usually
912
int FUNCTION(igraph_vector,init_copy)(TYPE(igraph_vector) *v,
913
BASE *data, long int length) {
914
v->stor_begin=igraph_Calloc(length, BASE);
915
if (v->stor_begin==0) {
916
IGRAPH_ERROR("cannot init vector from array", IGRAPH_ENOMEM);
918
v->stor_end=v->stor_begin+length;
920
memcpy(v->stor_begin, data, length*sizeof(BASE));
927
* \function igraph_vector_copy_to
928
* \brief Copies the contents of a vector to a C array.
931
* The C array should have sufficient length.
932
* \param v The vector object.
933
* \param to The C array.
935
* Time complexity: O(n),
936
* n is the size of the vector.
939
void FUNCTION(igraph_vector,copy_to)(const TYPE(igraph_vector) *v, BASE *to) {
942
assert(v->stor_begin != NULL);
943
if (v->end != v->stor_begin) {
944
memcpy(to, v->stor_begin, sizeof(BASE) * (v->end - v->stor_begin));
950
* \function igraph_vector_copy
951
* \brief Initializes a vector from another vector object (constructor).
954
* The contents of the existing vector object will be copied to
956
* \param to Pointer to a not yet initialized vector object.
957
* \param from The original vector object to copy.
958
* \return Error code:
959
* \c IGRAPH_ENOMEM if there is not enough memory.
961
* Time complexity: operating system dependent, usually
963
* n is the size of the vector.
966
int FUNCTION(igraph_vector,copy)(TYPE(igraph_vector) *to,
967
const TYPE(igraph_vector) *from) {
968
assert(from != NULL);
969
assert(from->stor_begin != NULL);
970
to->stor_begin=igraph_Calloc(FUNCTION(igraph_vector,size)(from), BASE);
971
if (to->stor_begin==0) {
972
IGRAPH_ERROR("canot copy vector", IGRAPH_ENOMEM);
974
to->stor_end=to->stor_begin+FUNCTION(igraph_vector,size)(from);
975
to->end=to->stor_end;
976
memcpy(to->stor_begin, from->stor_begin,
977
FUNCTION(igraph_vector,size)(from)*sizeof(BASE));
984
* \function igraph_vector_sum
985
* \brief Calculates the sum of the elements in the vector.
988
* For the empty vector 0.0 is returned.
989
* \param v The vector object.
990
* \return The sum of the elements.
992
* Time complexity: O(n), the size of
996
BASE FUNCTION(igraph_vector,sum)(const TYPE(igraph_vector) *v) {
1000
assert(v->stor_begin != NULL);
1001
for (p=v->stor_begin; p<v->end; p++) {
1009
* \function igraph_vector_prod
1010
* \brief Calculates the product of the elements in the vector.
1013
* For the empty vector one (1) is returned.
1014
* \param v The vector object.
1015
* \return The product of the elements.
1017
* Time complexity: O(n), the size of
1021
BASE FUNCTION(igraph_vector,prod)(const TYPE(igraph_vector) *v) {
1025
assert(v->stor_begin != NULL);
1026
for (p=v->stor_begin; p<v->end; p++) {
1034
* \function igraph_vector_init_seq
1035
* \brief Initializes a vector with a sequence.
1038
* The vector will contain the numbers \p from,
1039
* \p from+1, ..., \p to.
1040
* \param v Pointer to an uninitialized vector object.
1041
* \param from The lower limit in the sequence (inclusive).
1042
* \param to The upper limit in the sequence (inclusive).
1043
* \return Error code:
1044
* \c IGRAPH_ENOMEM: out of memory.
1046
* Time complexity: O(n), the number
1047
* of elements in the vector.
1050
int FUNCTION(igraph_vector,init_seq)(TYPE(igraph_vector) *v,
1051
BASE from, BASE to) {
1053
IGRAPH_CHECK(FUNCTION(igraph_vector,init)(v, to-from+1));
1055
for (p=v->stor_begin; p<v->end; p++) {
1064
* \function igraph_vector_remove_section
1065
* \brief Deletes a section from a vector.
1068
* Note that this function does not do range checking. The result is
1069
* undefined if you supply invalid limits.
1070
* \param v The vector object.
1071
* \param from The position of the first element to remove.
1072
* \param to The position of the first element \em not to remove.
1074
* Time complexity: O(n-from),
1075
* n is the number of elements in the
1079
void FUNCTION(igraph_vector,remove_section)(TYPE(igraph_vector) *v,
1080
long int from, long int to) {
1082
assert(v->stor_begin != NULL);
1083
memmove(v->stor_begin+from, v->stor_begin+to,
1084
sizeof(BASE)*(v->end-v->stor_begin-to));
1085
v->end -= (to-from);
1090
* \function igraph_vector_remove
1091
* \brief Removes a single element from a vector.
1093
* Note that this function does not do range checking.
1094
* \param v The vector object.
1095
* \param elem The position of the element to remove.
1097
* Time complexity: O(n-elem),
1098
* n is the number of elements in the
1102
void FUNCTION(igraph_vector,remove)(TYPE(igraph_vector) *v, long int elem) {
1104
assert(v->stor_begin != NULL);
1105
FUNCTION(igraph_vector,remove_section)(v, elem, elem+1);
1110
* \function igraph_vector_move_interval
1111
* \brief Copies a section of a vector.
1114
* The result of this function is undefined if the source and target
1115
* intervals overlap.
1116
* \param v The vector object.
1117
* \param begin The position of the first element to move.
1118
* \param end The position of the first element \em not to move.
1119
* \param to The target position.
1120
* \return Error code, the current implementation always returns with
1123
* Time complexity: O(end-begin).
1126
int FUNCTION(igraph_vector,move_interval)(TYPE(igraph_vector) *v,
1127
long int begin, long int end,
1130
assert(v->stor_begin != NULL);
1131
memcpy(v->stor_begin+to, v->stor_begin+begin,
1132
sizeof(BASE)*(end-begin));
1137
int FUNCTION(igraph_vector,move_interval2)(TYPE(igraph_vector) *v,
1138
long int begin, long int end,
1141
assert(v->stor_begin != NULL);
1142
memmove(v->stor_begin+to, v->stor_begin+begin,
1143
sizeof(BASE)*(end-begin));
1150
* \function igraph_vector_permdelete
1151
* \brief Remove elements of a vector (for internal use).
1154
void FUNCTION(igraph_vector,permdelete)(TYPE(igraph_vector) *v,
1155
const igraph_vector_t *index, long int nremove) {
1158
assert(v->stor_begin != NULL);
1159
n = FUNCTION(igraph_vector,size)(v);
1160
for (i=0; i<n; i++) {
1161
if (VECTOR(*index)[i] != 0) {
1162
VECTOR(*v)[ (long int)VECTOR(*index)[i]-1 ] = VECTOR(*v)[i];
1170
* \function igraph_vector_remove_negidx
1171
* \brief Remove elements of a vector (for internal use).
1174
void FUNCTION(igraph_vector,remove_negidx)(TYPE(igraph_vector) *v,
1175
const igraph_vector_t *neg, long int nremove) {
1178
assert(v->stor_begin != NULL);
1179
for (i=0; i<FUNCTION(igraph_vector,size)(v); i++) {
1180
VECTOR(*v)[idx++] = VECTOR(*v)[i];
1187
* \function igraph_vector_isininterval
1188
* \brief Checks if all elements of a vector are in the given
1191
* \param v The vector object.
1192
* \param low The lower limit of the interval (inclusive).
1193
* \param high The higher limit of the interval (inclusive).
1194
* \return True (positive integer) if all vector elements are in the
1195
* interval, false (zero) otherwise.
1197
* Time complexity: O(n), the number
1198
* of elements in the vector.
1201
igraph_bool_t FUNCTION(igraph_vector,isininterval)(const TYPE(igraph_vector) *v,
1206
assert(v->stor_begin != NULL);
1207
for (ptr=v->stor_begin; ptr<v->end; ptr++) {
1208
if (*ptr < low || *ptr >high) {
1217
* \function igraph_vector_any_smaller
1218
* \brief Checks if any element of a vector is smaller than a limit.
1220
* \param v The \type igraph_vector_t object.
1221
* \param limit The limit.
1222
* \return True (positive integer) if the vector contains at least one
1223
* smaller element than \p limit, false (zero)
1226
* Time complexity: O(n), the number
1227
* of elements in the vector.
1230
igraph_bool_t FUNCTION(igraph_vector,any_smaller)(const TYPE(igraph_vector) *v,
1234
assert(v->stor_begin != NULL);
1235
for (ptr=v->stor_begin; ptr<v->end; ptr++) {
1245
* \function igraph_vector_is_equal
1246
* \brief Decides whether two vectors contain exactly the same elements
1247
* (in the same order).
1249
* \param lhs The first vector.
1250
* \param rhs The second vector.
1251
* \return Positive integer if the two vectors are equal element by
1252
* element or zero if they are not.
1254
* Time complexity: O(n), the length
1258
igraph_bool_t FUNCTION(igraph_vector,is_equal)(const TYPE(igraph_vector) *lhs,
1259
const TYPE(igraph_vector) *rhs) {
1263
assert(lhs->stor_begin != 0);
1264
assert(rhs->stor_begin != 0);
1266
s=FUNCTION(igraph_vector,size)(lhs);
1267
if (s != FUNCTION(igraph_vector,size)(rhs)) {
1270
for (i=0; i<s; i++) {
1271
if (VECTOR(*lhs)[i] != VECTOR(*rhs)[i]) {
1281
* \function igraph_vector_binsearch
1282
* \brief Finds an element by binary searching a sorted vector.
1285
* It is assumed that the vector is sorted. If the specified element
1286
* (\p what) is not in the vector, then the
1287
* position of where it should be inserted (to keep the vector sorted)
1289
* \param v The \type igraph_vector_t object.
1290
* \param what The element to search for.
1291
* \param pos Pointer to a \type long int. This is set to the
1292
* position of an instance of \p what in the
1293
* vector if it is present. If \p v does not
1294
* contain \p what then
1295
* \p pos is set to the position to which it
1296
* should be inserted (to keep the the vector sorted of course).
1297
* \return Positive integer (true) if \p what is
1298
* found in the vector, zero (false) otherwise.
1300
* Time complexity: O(log(n)),
1301
* n is the number of elements in
1305
igraph_bool_t FUNCTION(igraph_vector,binsearch)(const TYPE(igraph_vector) *v,
1306
BASE what, long int *pos) {
1308
long int right=FUNCTION(igraph_vector,size)(v)-1;
1311
if (pos != 0) *pos=0;
1315
while (left < right-1) {
1316
long int middle=(left+right)/2;
1317
if (VECTOR(*v)[middle] > what) {
1319
} else if (VECTOR(*v)[middle] < what) {
1327
if (VECTOR(*v)[left] < what) {
1328
if (VECTOR(*v)[right] < what) left=right+1;
1336
if (left < FUNCTION(igraph_vector,size)(v)) {
1337
return VECTOR(*v)[left]==what;
1345
* \function igraph_vector_binsearch2
1346
* \brief Binary search, without returning the index.
1349
* It is assumed that the vector is sorted. If the specified element
1350
* (\p what) is not in the vector, then the
1351
* position of where it should be inserted (to keep the vector sorted)
1353
* \param v The \type igraph_vector_t object.
1354
* \param what The element to search for.
1355
* \return Positive integer (true) if \p what is
1356
* found in the vector, zero (false) otherwise.
1358
* Time complexity: O(log(n)),
1359
* n is the number of elements in
1363
igraph_bool_t FUNCTION(igraph_vector,binsearch2)(const TYPE(igraph_vector) *v,
1366
long int right=v->end - v->stor_begin-1;
1372
while (left < right-1) {
1373
long int middle=(left+right)/2;
1374
if (VECTOR(*v)[middle] > what) {
1376
} else if (VECTOR(*v)[middle] < what) {
1384
return VECTOR(*v)[left]==what || VECTOR(*v)[right]==what;
1388
* \function igraph_vector_scale
1389
* \brief Multiply all elements of a vector by a constant
1391
* \param v The vector.
1392
* \param by The constant.
1393
* \return Error code. The current implementation always returns with success.
1395
* Added in version 0.2.</para><para>
1397
* Time complexity: O(n), the number of elements in a vector.
1400
void FUNCTION(igraph_vector,scale)(TYPE(igraph_vector) *v, BASE by) {
1402
for (i=0; i<FUNCTION(igraph_vector,size)(v); i++) {
1403
VECTOR(*v)[i] *= by;
1408
* \function igraph_vector_add_constant
1409
* \brief Add a constant to the vector.
1411
* \p plus is added to every element of \p v. Note that overflow
1413
* \param v The input vector.
1414
* \param plus The constant to add.
1416
* Time complexity: O(n), the number of elements.
1419
void FUNCTION(igraph_vector,add_constant)(TYPE(igraph_vector) *v, BASE plus) {
1420
long int i, n=FUNCTION(igraph_vector,size)(v);
1421
for (i=0; i<n; i++) {
1422
VECTOR(*v)[i] += plus;
1427
* \function igraph_vector_contains
1428
* \brief Linear search in a vector.
1430
* Check whether the supplied element is included in the vector, by
1432
* \param v The input vector.
1433
* \param e The element to look for.
1434
* \return \c TRUE if the element is found and \c FALSE otherwise.
1436
* Time complexity: O(n), the length of the vector.
1439
igraph_bool_t FUNCTION(igraph_vector,contains)(const TYPE(igraph_vector) *v,
1441
BASE *p=v->stor_begin;
1452
* \function igraph_vector_search
1453
* \brief Search from a given position
1455
* The supplied element \p what is searched in vector \p v, starting
1456
* from element index \p from. If found then the index of the first
1457
* instance (after \p from) is stored in \p pos.
1458
* \param v The input vector.
1459
* \param from The index to start searching from. No range checking is
1461
* \param what The element to find.
1462
* \param pos If not \c NULL then the index of the found element is
1464
* \return Boolean, \c TRUE if the element was found, \c FALSE
1467
* Time complexity: O(m), the number of elements to search, the length
1468
* of the vector minus the \p from argument.
1471
igraph_bool_t FUNCTION(igraph_vector,search)(const TYPE(igraph_vector) *v,
1472
long int from, BASE what,
1474
long int i, n=FUNCTION(igraph_vector,size)(v);
1475
for (i=from; i<n; i++) {
1476
if (VECTOR(*v)[i]==what) break;
1490
* \function igraph_vector_filter_smaller
1494
int FUNCTION(igraph_vector,filter_smaller)(TYPE(igraph_vector) *v,
1496
long int i=0, n=FUNCTION(igraph_vector,size)(v);
1498
while (i<n && VECTOR(*v)[i]<elem) {
1503
while (s<n && VECTOR(*v)[s]==elem) {
1507
FUNCTION(igraph_vector,remove_section)(v, 0, i+(s-i)/2);
1512
* \function igraph_vector_append
1513
* \brief Append a vector to another one.
1515
* The target vector will be resized (except \p from is empty).
1516
* \param to The vector to append to.
1517
* \param from The vector to append, it is kept unchanged.
1518
* \return Error code.
1520
* Time complexity: O(n), the number of elements in the new vector.
1523
int FUNCTION(igraph_vector,append)(TYPE(igraph_vector) *to,
1524
const TYPE(igraph_vector) *from) {
1525
long int tosize, fromsize;
1527
tosize=FUNCTION(igraph_vector,size)(to);
1528
fromsize=FUNCTION(igraph_vector,size)(from);
1529
IGRAPH_CHECK(FUNCTION(igraph_vector,resize)(to, tosize+fromsize));
1530
memcpy(to->stor_begin+tosize, from->stor_begin,
1531
sizeof(BASE)*fromsize);
1532
to->end=to->stor_begin+tosize+fromsize;
1538
* \function igraph_vector_get_interval
1541
int FUNCTION(igraph_vector,get_interval)(const TYPE(igraph_vector) *v,
1542
TYPE(igraph_vector) *res,
1543
long int from, long int to) {
1544
IGRAPH_CHECK(FUNCTION(igraph_vector,resize)(res, to-from));
1545
memcpy(res->stor_begin, v->stor_begin+from, (to-from)*sizeof(BASE));
1550
* \function igraph_vector_maxdifference
1551
* \brief The largest element of \p m1 - \p m2
1553
* The maximum the elementwise performed difference is returned.
1554
* Both vectors must be non-empty, but they not need to have the same
1555
* length, the extra elements in the longer vector are ignored.
1556
* \param m1 The first vector.
1557
* \param m2 The second vector.
1558
* \return The maximum of the difference of \p m1 and \p m2.
1560
* Time complexity: O(n), the number of elements in the shorter
1564
BASE FUNCTION(igraph_vector,maxdifference)(const TYPE(igraph_vector) *m1,
1565
const TYPE(igraph_vector) *m2) {
1566
long int n1=FUNCTION(igraph_vector,size)(m1);
1567
long int n2=FUNCTION(igraph_vector,size)(m2);
1568
long int n= n1 < n2 ? n1 : n2;
1572
for (i=0; i<n; i++) {
1573
BASE d=fabs(VECTOR(*m1)[i]-VECTOR(*m2)[i]);
1583
* \function igraph_vector_update
1584
* \brief Update a vector from another one.
1586
* After this operation the contents of \p to will be exactly the same
1587
* \p from. \p to will be resized if it was originally shorter or
1588
* longer than \p from.
1589
* \param to The vector to update.
1590
* \param from The vector to update from.
1591
* \return Error code.
1593
* Time complexity: O(n), the number of elements in \p from.
1596
int FUNCTION(igraph_vector,update)(TYPE(igraph_vector) *to,
1597
const TYPE(igraph_vector) *from) {
1598
long int n=FUNCTION(igraph_vector,size)(from);
1599
FUNCTION(igraph_vector,resize)(to, n);
1600
memcpy(to->stor_begin, from->stor_begin, sizeof(BASE)*n);
1605
* \function igraph_vector_swap
1606
* \brief Swap elements of two vectors.
1608
* The two vectors must have the same length, otherwise an error
1610
* \param v1 The first vector.
1611
* \param v2 The second vector.
1612
* \return Error code.
1614
* Time complexity: O(n), the length of the vectors.
1617
int FUNCTION(igraph_vector,swap)(TYPE(igraph_vector) *v1, TYPE(igraph_vector) *v2) {
1619
long int i, n1=FUNCTION(igraph_vector,size)(v1);
1620
long int n2=FUNCTION(igraph_vector,size)(v2);
1622
IGRAPH_ERROR("Vectors must have the same number of elements for swapping",
1626
for (i=0; i<n1; i++) {
1629
VECTOR(*v1)[i]=VECTOR(*v2)[i];
1636
* \function igraph_vector_swap_elements
1637
* \brief Swap two elements in a vector.
1639
* Note that currently no range checking if performed.
1640
* \param v The input vector.
1641
* \param i Index of the first element.
1642
* \param j index of the second element. (Might be the same the
1644
* \return Error code, currently always \c IGRAPH_SUCCESS.
1646
* Time complexity: O(1).
1649
int FUNCTION(igraph_vector,swap_elements)(TYPE(igraph_vector) *v,
1650
long int i, long int j) {
1651
BASE tmp=VECTOR(*v)[i];
1652
VECTOR(*v)[i]=VECTOR(*v)[j];
1659
* \function igraph_vector_reverse
1660
* \brief Reverse the elements of a vector.
1662
* The first element will be last, the last element will be
1664
* \param v The input vector.
1665
* \return Error code, currently always \c IGRAPH_SUCCESS.
1667
* Time complexity: O(n), the number of elements.
1670
int FUNCTION(igraph_vector,reverse)(TYPE(igraph_vector) *v) {
1672
long int n=FUNCTION(igraph_vector,size)(v), n2=n/2;
1674
for (i=0, j=n-1; i<n2; i++, j--) {
1677
VECTOR(*v)[i]=VECTOR(*v)[j];
1685
* \function igraph_vector_shuffle
1686
* \brief Shuffles a vector in-place using the Fisher-Yates method
1689
* The Fisher-Yates shuffle ensures that every implementation is
1690
* equally probable when using a proper randomness source. Of course
1691
* this does not apply to pseudo-random generators as the cycle of
1692
* these generators is less than the number of possible permutations
1693
* of the vector if the vector is long enough.
1694
* \param v The vector object.
1695
* \return Error code, currently always \c IGRAPH_SUCCESS.
1697
* Time complexity: O(n),
1698
* n is the number of elements in the
1702
int FUNCTION(igraph_vector,shuffle)(TYPE(igraph_vector) *v) {
1703
long int n = FUNCTION(igraph_vector,size)(v);
1709
k = RNG_INTEGER(0, n-1);
1711
dummy = VECTOR(*v)[n];
1712
VECTOR(*v)[n] = VECTOR(*v)[k];
1713
VECTOR(*v)[k] = dummy;
1717
return IGRAPH_SUCCESS;
1721
* \function igraph_vector_add
1722
* \brief Add two vectors.
1724
* Add the elements of \p v2 to \p v1, the result is stored in \p
1725
* v1. The two vectors must have the same length.
1726
* \param v1 The first vector, the result will be stored here.
1727
* \param v2 The second vector, its contents will be unchanged.
1728
* \return Error code.
1730
* Time complexity: O(n), the number of elements.
1733
int FUNCTION(igraph_vector,add)(TYPE(igraph_vector) *v1,
1734
const TYPE(igraph_vector) *v2) {
1736
long int n1=FUNCTION(igraph_vector,size)(v1);
1737
long int n2=FUNCTION(igraph_vector,size)(v2);
1740
IGRAPH_ERROR("Vectors must have the same number of elements for swapping",
1744
for (i=0; i<n1; i++) {
1745
VECTOR(*v1)[i] += VECTOR(*v2)[i];
1752
* \function igraph_vector_sub
1753
* \brief Subtract a vector from another one.
1755
* Substract the elements of \p v2 from \p v1, the result is stored in
1756
* \p v1. The two vectors must have the same length.
1757
* \param v1 The first vector, to subtract from. The result is stored
1759
* \param v2 The vector to subtract, it will be unchanged.
1760
* \return Error code.
1762
* Time complexity: O(n), the length of the vectors.
1765
int FUNCTION(igraph_vector,sub)(TYPE(igraph_vector) *v1,
1766
const TYPE(igraph_vector) *v2) {
1768
long int n1=FUNCTION(igraph_vector,size)(v1);
1769
long int n2=FUNCTION(igraph_vector,size)(v2);
1772
IGRAPH_ERROR("Vectors must have the same number of elements for swapping",
1776
for (i=0; i<n1; i++) {
1777
VECTOR(*v1)[i] -= VECTOR(*v2)[i];
1784
* \function igraph_vector_mul
1785
* \brief Multiply two vectors.
1787
* \p v1 will be multiplied by \p v2, elementwise. The two vectors
1788
* must have the same length.
1789
* \param v1 The first vector, the result will be stored here.
1790
* \param v2 The second vector, it is left unchanged.
1791
* \return Error code.
1793
* Time complexity: O(n), the number of elements.
1796
int FUNCTION(igraph_vector,mul)(TYPE(igraph_vector) *v1,
1797
const TYPE(igraph_vector) *v2) {
1799
long int n1=FUNCTION(igraph_vector,size)(v1);
1800
long int n2=FUNCTION(igraph_vector,size)(v2);
1803
IGRAPH_ERROR("Vectors must have the same number of elements for swapping",
1807
for (i=0; i<n1; i++) {
1808
VECTOR(*v1)[i] *= VECTOR(*v2)[i];
1815
* \function igraph_vector_div
1816
* \brief Divide a vector by another one.
1818
* \p v1 is divided by \p v2, elementwise. They must have the same length. If the
1819
* base type of the vector can generate divide by zero errors then
1820
* please make sure that \p v2 contains no zero if you want to avoid
1822
* \param v1 The dividend. The result is also stored here.
1823
* \param v2 The divisor, it is left unchanged.
1824
* \return Error code.
1826
* Time complexity: O(n), the length of the vectors.
1829
int FUNCTION(igraph_vector,div)(TYPE(igraph_vector) *v1,
1830
const TYPE(igraph_vector) *v2) {
1832
long int n1=FUNCTION(igraph_vector,size)(v1);
1833
long int n2=FUNCTION(igraph_vector,size)(v2);
1836
IGRAPH_ERROR("Vectors must have the same number of elements for swapping",
1840
for (i=0; i<n1; i++) {
1841
VECTOR(*v1)[i] /= VECTOR(*v2)[i];
1848
* \function igraph_vector_minmax
1849
* \brief Minimum and maximum elements of a vector.
1851
* Handy if you want to have both the smallest and largest element of
1852
* a vector. The vector is only traversed once. The vector must by non-empty.
1853
* \param v The input vector. It must contain at least one element.
1854
* \param min Pointer to a base type variable, the minimum is stored
1856
* \param max Pointer to a base type variable, the maximum is stored
1858
* \return Error code.
1860
* Time complexity: O(n), the number of elements.
1863
int FUNCTION(igraph_vector,minmax)(const TYPE(igraph_vector) *v,
1864
BASE *min, BASE *max) {
1865
long int n=FUNCTION(igraph_vector,size)(v);
1867
*min=*max=VECTOR(*v)[0];
1868
for (i=1; i<n; i++) {
1869
BASE tmp=VECTOR(*v)[i];
1872
} else if (tmp < *min) {
1880
* \function igraph_vector_which_minmax
1881
* \brief Index of the minimum and maximum elements
1883
* Handy if you need the indices of the smallest and largest
1884
* elements. The vector is traversed only once. The vector must to
1886
* \param v The input vector. It must contain at least one element.
1887
* \param which_min The index of the minimum element will be stored
1889
* \param which_max The index of the maximum element will be stored
1891
* \return Error code.
1893
* Time complexity: O(n), the number of elements.
1896
int FUNCTION(igraph_vector,which_minmax)(const TYPE(igraph_vector) *v,
1897
long int *which_min, long int *which_max) {
1899
long int n=FUNCTION(igraph_vector,size)(v);
1902
*which_min=*which_max=0;
1903
min=max=VECTOR(*v)[0];
1904
for (i=1; i<n; i++) {
1905
BASE tmp=VECTOR(*v)[i];
1909
} else if (tmp < min) {
1918
* \function igraph_vector_isnull
1919
* \brief Are all elements zero?
1921
* Checks whether all elements of a vector are zero.
1922
* \param v The input vector
1923
* \return Boolean, \c TRUE if the vector contains only zeros, \c
1926
* Time complexity: O(n), the number of elements.
1929
igraph_bool_t FUNCTION(igraph_vector,isnull)(const TYPE(igraph_vector) *v) {
1931
long int n=FUNCTION(igraph_vector,size)(v);
1934
while ( i<n && VECTOR(*v)[i]==0) {
1942
* \function igraph_vector_intersect_sorted
1943
* \brief Calculates the intersection of two sorted vectors
1945
* The elements that are contained in both vectors are stored in the result
1946
* vector. All three vectors must be initialized.
1948
* \param v1 the first vector
1949
* \param v2 the second vector
1950
* \param result the result vector
1951
* \param keep_multiplicity whether to preserve the multiplicity of the
1952
* elements. If \c FALSE, all elements in the resulting vector will be
1955
int FUNCTION(igraph_vector,intersect_sorted)(const TYPE(igraph_vector) *v1,
1956
const TYPE(igraph_vector) *v2, TYPE(igraph_vector) *result,
1957
igraph_bool_t keep_multiplicity) {
1958
long int i, j, k, i0, j0;
1959
i0 = FUNCTION(igraph_vector,size)(v1);
1960
j0 = FUNCTION(igraph_vector,size)(v2);
1962
FUNCTION(igraph_vector,clear)(result);
1963
while (i < i0 && j < j0) {
1965
if (VECTOR(*v1)[i] == VECTOR(*v2)[j]) {
1966
element = VECTOR(*v1)[i]; k=0;
1967
while (i < i0 && VECTOR(*v1)[i] == element) { i++; k++; }
1968
while (j < j0 && VECTOR(*v2)[j] == element) { j++; k++; }
1969
if (!keep_multiplicity) k=1;
1971
FUNCTION(igraph_vector,push_back)(result, element);
1974
} else if (VECTOR(*v1)[i] < VECTOR(*v2)[j]) i++;