Class: FastMatrix::Vector

Inherits:
Data
  • Object
show all
Defined in:
lib/scalar.rb,
lib/vector/vector.rb,
lib/vector/constructors.rb,
ext/fast_matrix/Vector/vector.c

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(size) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
# File 'ext/fast_matrix/Vector/vector.c', line 48

VALUE vector_initialize(VALUE self, VALUE size)
{
    int n = raise_rb_value_to_int(size);

    if(n <= 0)
        rb_raise(fm_eIndexError, "Size cannot be negative or zero");

    struct vector* data = get_vector_from_rb_value(self);
    c_vector_init(data, n);

	return self;
}

Class Method Details

.[](*elems) ⇒ Object

Creates a Vector from a list of elements.

Vector[7, 4, ...]


10
11
12
13
14
# File 'lib/vector/constructors.rb', line 10

def self.[](*elems)
  vector = new(elems.size)
  vector.each_with_index! { |_, idx| elems[idx] }
  vector
end

.basis(size:, index:) ⇒ Object

Returns a standard basis n-vector, where k is the index.

Vector.basis(size:, index:) # => Vector[0, 1, 0]

Raises:



31
32
33
34
35
36
37
# File 'lib/vector/constructors.rb', line 31

def Vector.basis(size:, index:)
  raise IndexError, "invalid size (#{size} for 1..)" if size < 1
  raise IndexError, "invalid index (#{index} for 0...#{size})" unless 0 <= index && index < size    
  result = zero(size)
  result[index] = 1
  result
end

.convert(vector) ⇒ Object

Create fast vector from standard vector



14
15
16
# File 'lib/vector/vector.rb', line 14

def self.convert(vector)
  elements(vector)
end

.cross_product(*args) ⇒ Object



427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
# File 'ext/fast_matrix/Vector/vector.c', line 427

VALUE vector_cross_product(int argc, VALUE* argv, VALUE obj)
{
    struct vector** vcts;
    convert_vector_array(argc, argv, &vcts);

    int n = argc + 1;

    if(!c_vector_equal_by_size(argc, vcts, n))
    {
        free(vcts);
        rb_raise(fm_eIndexError, "Rows of different size");
    }

    struct vector* R;
    VALUE result = TypedData_Make_Struct(cVector, struct vector, &vector_type, R);
    c_vector_init(R, n);

    c_vector_cross_product(argc, vcts, R->data);

    return result;
}

.elements(array, copy = true) ⇒ Object

Creates a vector from an Array. The optional argument copy exists only for compatibility with standard. The optional argument copy cannot be false, unlike standard.



21
22
23
24
# File 'lib/vector/constructors.rb', line 21

def self.elements(array, copy = true)
  check_flag_copy(copy)
  self[*array]
end

.independent?(*args) ⇒ Boolean

Returns:

  • (Boolean)


316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
# File 'ext/fast_matrix/Vector/vector.c', line 316

VALUE vector_independent(int argc, VALUE* argv, VALUE obj)
{
    if(argc == 0)
        return Qtrue;
    
    struct vector** vcts;
    convert_vector_array(argc, argv, &vcts);

    int n = vcts[0]->n;

    if(!c_vector_equal_by_size(argc, vcts, n))
    {
        free(vcts);
        rb_raise(fm_eIndexError, "Rows of different size");
    }

    double* C = malloc(sizeof(double) * argc * n);
    c_vector_hstack(n, argc, vcts, C);
    int result = c_matrix_rank(n, argc, C);

    free(vcts);
    free(C);
    if(result == argc)
        return Qtrue;
    return Qfalse;
}

.zero(size) ⇒ Object

Return a zero vector.

Vector.zero(3) => Vector[0, 0, 0]


44
45
46
47
# File 'lib/vector/constructors.rb', line 44

def self.zero(size)
  result = new(size)
  result.fill!(0)
end

Instance Method Details

#*(v) ⇒ Object



248
249
250
251
252
253
254
255
256
257
258
# File 'ext/fast_matrix/Vector/vector.c', line 248

VALUE vector_multiply(VALUE self, VALUE v)
{
    if(RB_FLOAT_TYPE_P(v) || FIXNUM_P(v)
        || RB_TYPE_P(v, T_BIGNUM))
        return vector_multiply_vn(self, v);
    if(RBASIC_CLASS(v) == cMatrix)
        return vector_multiply_vm(self, v);
    if(RBASIC_CLASS(v) == cVector)
        return vector_multiply_vv(self, v);
    rb_raise(fm_eTypeError, "Invalid klass for multiply");
}

#+(other) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'ext/fast_matrix/Vector/vector.c', line 97

VALUE vector_add_with(VALUE self, VALUE other)
{
    raise_check_rbasic(other, cVector, "vector");
	struct vector* A = get_vector_from_rb_value(self);
	struct vector* B = get_vector_from_rb_value(other);
    raise_check_equal_size_vectors(A, B);

    int n = A->n;

    struct vector* C;
    VALUE result = TypedData_Make_Struct(cVector, struct vector, &vector_type, C);

    c_vector_init(C, n);
    add_d_arrays_to_result(n, A->data, B->data, C->data);

    return result;
}

#+@Object



299
300
301
302
# File 'ext/fast_matrix/Vector/vector.c', line 299

VALUE vector_plus(VALUE self)
{
    return self;
}

#-(other) ⇒ Object



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'ext/fast_matrix/Vector/vector.c', line 131

VALUE vector_sub_with(VALUE self, VALUE other)
{
    raise_check_rbasic(other, cVector, "vector");
	struct vector* A = get_vector_from_rb_value(self);
	struct vector* B = get_vector_from_rb_value(other);
    raise_check_equal_size_vectors(A, B);

    int n = A->n;

    struct vector* C;
    VALUE result = TypedData_Make_Struct(cVector, struct vector, &vector_type, C);

    c_vector_init(C, n);
    sub_d_arrays_to_result(n, A->data, B->data, C->data);

    return result;
}

#-@Object



286
287
288
289
290
291
292
293
294
295
296
297
# File 'ext/fast_matrix/Vector/vector.c', line 286

VALUE vector_minus(VALUE self)
{
	struct vector* A = get_vector_from_rb_value(self);

    struct vector* R;
    VALUE result = TypedData_Make_Struct(cVector, struct vector, &vector_type, R);
    c_vector_init(R, A->n);

    multiply_d_array_to_result(A->n, A->data, -1, R->data);

    return result;
}

#/(v) ⇒ Object



508
509
510
511
512
513
514
515
516
517
518
519
520
# File 'ext/fast_matrix/Vector/vector.c', line 508

VALUE vector_division(VALUE self, VALUE v)
{
    double d = raise_rb_value_to_double(v);
    struct vector* A = get_vector_from_rb_value(self);

    struct vector* R;
    VALUE result = TypedData_Make_Struct(cVector, struct vector, &vector_type, R);
    c_vector_init(R, A->n);

    multiply_d_array_to_result(A->n, A->data, 1/d, R->data);

    return result;
}

#<(other) ⇒ Object



488
489
490
491
492
493
494
495
496
497
498
499
# File 'ext/fast_matrix/Vector/vector.c', line 488

VALUE vector_less(VALUE self, VALUE other)
{
    raise_check_rbasic(other, cVector, "vector");
	struct vector* A = get_vector_from_rb_value(self);
	struct vector* B = get_vector_from_rb_value(other);

    raise_check_equal_size_vectors(A, B);

    if(less_d_array(A->n, A->data, B->data))
        return Qtrue;
    return Qfalse;
}

#<=(other) ⇒ Object



462
463
464
465
466
467
468
469
470
471
472
473
# File 'ext/fast_matrix/Vector/vector.c', line 462

VALUE vector_less_or_equal(VALUE self, VALUE other)
{
    raise_check_rbasic(other, cVector, "vector");
	struct vector* A = get_vector_from_rb_value(self);
	struct vector* B = get_vector_from_rb_value(other);

    raise_check_equal_size_vectors(A, B);

    if(less_or_equal_d_array(A->n, A->data, B->data))
        return Qtrue;
    return Qfalse;
}

#==(other) ⇒ Object

FIXME: for compare with standard vector



65
66
67
68
69
70
71
72
73
74
75
# File 'lib/vector/vector.rb', line 65

def ==(other)
  return eql?(other) if other.class == Vector
  return false unless %i[size \[\]].all? { |x| other.respond_to? x }
  return false unless self.size == other.size

  result = true
  each_with_index do |elem, i|
    result &&= elem == other[i].to_f
  end
  result
end

#>(other) ⇒ Object



475
476
477
478
479
480
481
482
483
484
485
486
# File 'ext/fast_matrix/Vector/vector.c', line 475

VALUE vector_greater(VALUE self, VALUE other)
{
    raise_check_rbasic(other, cVector, "vector");
	struct vector* A = get_vector_from_rb_value(self);
	struct vector* B = get_vector_from_rb_value(other);

    raise_check_equal_size_vectors(A, B);

    if(greater_d_array(A->n, A->data, B->data))
        return Qtrue;
    return Qfalse;
}

#>=(other) ⇒ Object



449
450
451
452
453
454
455
456
457
458
459
460
# File 'ext/fast_matrix/Vector/vector.c', line 449

VALUE vector_greater_or_equal(VALUE self, VALUE other)
{
    raise_check_rbasic(other, cVector, "vector");
	struct vector* A = get_vector_from_rb_value(self);
	struct vector* B = get_vector_from_rb_value(other);

    raise_check_equal_size_vectors(A, B);

    if(greater_or_equal_d_array(A->n, A->data, B->data))
        return Qtrue;
    return Qfalse;
}

#[](idx) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
# File 'ext/fast_matrix/Vector/vector.c', line 77

VALUE vector_get(VALUE self, VALUE idx)
{
    int i = raise_rb_value_to_int(idx);
	struct vector* data = get_vector_from_rb_value(self);

    i = (i < 0) ? data->n + i : i;
    
    if(i < 0 || i >= data->n)
        return Qnil;

    return DBL2NUM(data->data[i]);
}

#[]=(idx, v) ⇒ Object

[]=



62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'ext/fast_matrix/Vector/vector.c', line 62

VALUE vector_set(VALUE self, VALUE idx, VALUE v)
{
	struct vector* data = get_vector_from_rb_value(self);
    raise_check_frozen_vector(data);
    int i = raise_rb_value_to_int(idx);
    double x = raise_rb_value_to_double(v);

    i = (i < 0) ? data->n + i : i;
    raise_check_range(i, 0, data->n);

    data->data[i] = x;
    return v;
}

#add!(other) ⇒ Object



116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'ext/fast_matrix/Vector/vector.c', line 116

VALUE vector_add_from(VALUE self, VALUE other)
{
	struct vector* A = get_vector_from_rb_value(self);
    raise_check_frozen_vector(A);
    raise_check_rbasic(other, cVector, "vector");
	struct vector* B = get_vector_from_rb_value(other);
    raise_check_equal_size_vectors(A, B);

    int n = A->n;

    add_d_arrays_to_first(n, A->data, B->data);

    return self;
}

#angle_with(other) ⇒ Object



413
414
415
416
417
418
419
420
421
422
423
424
425
# File 'ext/fast_matrix/Vector/vector.c', line 413

VALUE vector_angle_with(VALUE self, VALUE other)
{
    raise_check_rbasic(other, cVector, "vector");
	struct vector* A = get_vector_from_rb_value(self);
	struct vector* B = get_vector_from_rb_value(other);
    raise_check_equal_size_vectors(A, B);

    double a = c_vector_magnitude(A->n, A->data);
    double b = c_vector_magnitude(B->n, B->data);
    double d = c_vector_inner_product(A->n, A->data, B->data);

    return DBL2NUM(acos(d / (a * b)));
}

#cloneObject



182
183
184
185
186
187
188
189
190
191
192
193
# File 'ext/fast_matrix/Vector/vector.c', line 182

VALUE vector_copy(VALUE self)
{
	struct vector* V = get_vector_from_rb_value(self);

    struct vector* R;
    VALUE result = TypedData_Make_Struct(cVector, struct vector, &vector_type, R);

    c_vector_init(R, V->n);
    copy_d_array(R->n, V->data, R->data);

    return result;
}

#coerce(other) ⇒ Object

The coerce method provides support for Ruby type coercion. This coercion mechanism is used by Ruby to handle mixed-type numeric operations: it is intended to find a compatible common type between the two operands of the operator. See also Numeric#coerce.



32
33
34
35
36
37
38
39
# File 'lib/scalar.rb', line 32

def coerce(other)
  case other
  when Numeric
    [Scalar.new(other), self]
  else
    raise TypeError, "#{self.class} can't be coerced into #{other.class}"
  end
end

#convertObject

Convert to standard ruby vector.



21
22
23
# File 'lib/vector/vector.rb', line 21

def convert
  ::Vector.elements(self)
end

#covectorObject



353
354
355
356
357
358
359
360
361
362
# File 'ext/fast_matrix/Vector/vector.c', line 353

VALUE vector_covector(VALUE self)
{
	struct vector* A = get_vector_from_rb_value(self);

    struct matrix* C;
    VALUE result = TypedData_Make_Struct(cMatrix, struct matrix, &matrix_type, C);
    c_matrix_init(C, A->n, 1);
    copy_d_array(A->n, A->data, C->data);
    return result;
}

#crossObject



6
# File 'lib/vector/vector.rb', line 6

alias cross cross_product

#eachObject

Iterate over the elements of this vector



38
39
40
41
42
43
44
45
# File 'lib/vector/vector.rb', line 38

def each
  return to_enum :each unless block_given?

  (0...size).each do |i|
    yield self[i]
  end
  self
end

#each_with_indexObject



47
48
49
50
51
52
53
54
# File 'lib/vector/vector.rb', line 47

def each_with_index
  return to_enum :each_with_index unless block_given?

  (0...size).each do |i|
    yield self[i], i
  end
  self
end

#each_with_index!Object

don’t use (Issue#1)



57
58
59
60
61
62
# File 'lib/vector/vector.rb', line 57

def each_with_index!
  (0...size).each do |i|
    self[i] = yield self[i], i
  end
  self
end

#eql?(other) ⇒ Boolean

Returns:

  • (Boolean)


164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'ext/fast_matrix/Vector/vector.c', line 164

VALUE vector_equal(VALUE self, VALUE other)
{
    if(RBASIC_CLASS(other) != cVector)
        return Qfalse;

    struct vector* A = get_vector_from_rb_value(self);
    struct vector* B = get_vector_from_rb_value(other);

    if(A->n != B->n)
		return Qfalse;

    int n = A->n;

    if(equal_d_arrays(n, A->data, B->data))
		return Qtrue;
	return Qfalse;
}

#fill!(value) ⇒ Object



372
373
374
375
376
377
378
379
# File 'ext/fast_matrix/Vector/vector.c', line 372

VALUE vector_fill(VALUE self, VALUE value)
{
	struct vector* A = get_vector_from_rb_value(self);
    raise_check_frozen_vector(A);
    double d = raise_rb_value_to_double(value);
    fill_d_array(A->n, A->data, d);
    return self;
}

#freezeObject



501
502
503
504
505
506
# File 'ext/fast_matrix/Vector/vector.c', line 501

VALUE vector_freeze(VALUE self)
{
	struct vector* A = get_vector_from_rb_value(self);
    A->frozen = true;
    return self;
}

#inner_product(other) ⇒ Object Also known as: dot



402
403
404
405
406
407
408
409
410
411
# File 'ext/fast_matrix/Vector/vector.c', line 402

VALUE vector_inner_product(VALUE self, VALUE other)
{
    raise_check_rbasic(other, cVector, "vector");
	struct vector* A = get_vector_from_rb_value(self);
	struct vector* B = get_vector_from_rb_value(other);
    raise_check_equal_size_vectors(A, B);

    double result = c_vector_inner_product(A->n, A->data, B->data);
    return DBL2NUM(result);
}

#magnitudeObject Also known as: r, norm



260
261
262
263
264
# File 'ext/fast_matrix/Vector/vector.c', line 260

VALUE vector_magnitude(VALUE self)
{
	struct vector* A = get_vector_from_rb_value(self);
    return DBL2NUM(c_vector_magnitude(A->n, A->data));
}

#normalizeObject



267
268
269
270
271
272
273
274
275
276
277
# File 'ext/fast_matrix/Vector/vector.c', line 267

VALUE vector_normalize(VALUE self)
{
	struct vector* A = get_vector_from_rb_value(self);

    struct vector* R;
    VALUE result = TypedData_Make_Struct(cVector, struct vector, &vector_type, R);
    c_vector_init(R, A->n);
    c_vector_normalize(A->n, A->data, R->data);

    return result;
}

#normalize!Object



279
280
281
282
283
284
# File 'ext/fast_matrix/Vector/vector.c', line 279

VALUE vector_normalize_self(VALUE self)
{
	struct vector* A = get_vector_from_rb_value(self);
    c_vector_normalize_self(A->n, A->data);
    return self;
}

#round(*args) ⇒ Object



381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
# File 'ext/fast_matrix/Vector/vector.c', line 381

VALUE vector_round(int argc, VALUE *argv, VALUE self)
{
    if(argc > 1)
        rb_raise(fm_eTypeError, "Wrong number of arguments");
    int d;
    if(argc == 1)
        d = raise_rb_value_to_int(argv[0]);
    else
        d = 0;

    struct vector* A = get_vector_from_rb_value(self);

    struct vector* R;
    VALUE result = TypedData_Make_Struct(cVector, struct vector, &vector_type, R);
    c_vector_init(R, A->n);

    round_d_array(A->n, A->data, R->data, d);

    return result;
}

#sizeObject



90
91
92
93
94
# File 'ext/fast_matrix/Vector/vector.c', line 90

VALUE vector_length(VALUE self)
{
	struct vector* data = get_vector_from_rb_value(self);
    return INT2NUM(data->n);
}

#sub!(other) ⇒ Object



150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'ext/fast_matrix/Vector/vector.c', line 150

VALUE vector_sub_from(VALUE self, VALUE other)
{
    raise_check_rbasic(other, cVector, "vector");
	struct vector* A = get_vector_from_rb_value(self);
	struct vector* B = get_vector_from_rb_value(other);
    raise_check_equal_size_vectors(A, B);

    int n = A->n;

    sub_d_arrays_to_first(n, A->data, B->data);

    return self;
}

#to_aryObject



25
26
27
# File 'lib/vector/vector.rb', line 25

def to_ary
  Array.new(size) { |i| self[i] }
end

#to_matrixObject



343
344
345
346
347
348
349
350
351
352
# File 'ext/fast_matrix/Vector/vector.c', line 343

VALUE vector_to_matrix(VALUE self)
{
	struct vector* A = get_vector_from_rb_value(self);

    struct matrix* C;
    VALUE result = TypedData_Make_Struct(cMatrix, struct matrix, &matrix_type, C);
    c_matrix_init(C, 1, A->n);
    copy_d_array(A->n, A->data, C->data);
    return result;
}

#to_sObject Also known as: to_str



29
30
31
# File 'lib/vector/vector.rb', line 29

def to_s
  "#{self.class}[#{to_ary.join(', ')}]"
end

#zero?Boolean

Returns:

  • (Boolean)


364
365
366
367
368
369
370
# File 'ext/fast_matrix/Vector/vector.c', line 364

VALUE vector_zero(VALUE self)
{
	struct vector* A = get_vector_from_rb_value(self);
    if(zero_d_array(A->n, A->data))
            return Qtrue;
    return Qfalse;
}