@@ -103,17 +103,17 @@ Examples:
103
103
104
104
=head3 Access values
105
105
106
- row(i) : MathObjectMatrix
107
- For a 1D tensor , produces a 1D tensor
108
- For nD tensor with n > 1, produces a (n-1)D tensor
106
+ row(i) : MathObject Matrix
107
+ For a degree 1 Matrix , produces a degree 1 Matrix
108
+ For a degree n Matrix with n > 1, produces a degree (n-1) Matrix
109
109
110
- column(j) : MathObjectMatrix or Real or Complex
111
- For a 1D tensor , produces a Real or Complex
112
- For nD tensor with n > 1, produces an nD tensor where 2nd dimension is 1
110
+ column(j) : MathObject Matrix or Real or Complex
111
+ For a degree 1 Matrix , produces a Real or Complex
112
+ For a degree n Matrix with n > 1, produces a degree n Matrix where the 2nd dimesion is length 1
113
113
114
- element : Real or Complex value when passed the same number of arguments as the dimension of the tensor .
115
- If passed more than n arguments, null. If the dimension of the tensor is n and element is passed
116
- k arguments with k < n, then this produces the corresponding (n-k)-dimensional tensor.
114
+ element : Real/ Complex/Fraction value when passed the same number of arguments as the degree of the Matrix .
115
+ If passed more than n arguments, null. If the degree of the Matrix is n and C< element > is passed
116
+ k arguments with k < n, then this produces the corresponding degree (n-k) tensor.
117
117
118
118
=head3 Update values (these need to be added)
119
119
@@ -366,7 +366,7 @@ sub isSquare {
366
366
367
367
=head3 C<isRow >
368
368
369
- Return true if the matix is 1-dimensional (i.e., is a matrix row)
369
+ Return true if the matix is degree 1 (i.e., is a matrix row)
370
370
371
371
Usage:
372
372
@@ -380,8 +380,7 @@ Usage:
380
380
381
381
sub isRow {
382
382
my $self = shift ;
383
- my @d = $self -> dimensions;
384
- return scalar (@d ) == 1;
383
+ return $self -> degree == 1;
385
384
}
386
385
387
386
=head3 C<isOne >
@@ -419,26 +418,30 @@ sub isOne {
419
418
}
420
419
} else {
421
420
for my $row (@{ $self -> {data } }) {
422
- if (!$row -> isOne) {
423
- return 0;
424
- }
421
+ return 0 unless $row -> isOne;
425
422
}
426
423
}
427
424
return 1;
428
425
}
429
426
430
427
=head3 C<isZero >
431
428
432
- Check for zero matrix.
429
+ Check for zero Matrix
433
430
434
431
Usage:
435
432
436
433
$A = Matrix([ [ 1, 2, 3, 4 ], [ 5, 6, 7, 8 ], [ 9, 10, 11, 12 ], [13, 14, 15, 16] ]);
437
- $A->isZero; # is false
434
+ $A->isZero; # is false
438
435
439
436
$B = Matrix([ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 0 ] ]);
440
437
$B->isZero; # is true;
441
438
439
+ $C = Matrix([ [ [ 1, 0 ], [ 0, 1 ] ], [ [ 1, 0 ], [ 0, 1 ] ] ]);
440
+ $C->isZero; # is false
441
+
442
+ $D = Matrix([ [ [ 0, 0 ], [ 0, 0 ] ], [ [ 0, 0 ], [ 0, 0 ] ] ]);
443
+ $D->isZero; # is true
444
+
442
445
=cut
443
446
444
447
sub isZero {
@@ -447,58 +450,99 @@ sub isZero {
447
450
return 1;
448
451
}
449
452
450
- #
451
- # See if the matrix is triangular, diagonal, symmetric, orthogonal
452
- #
453
+ =head3 C<isUpperTriangular >
454
+
455
+ Check if a Matrix is upper triangular (for degree > 2, applies to frontal slice matrices)
456
+
457
+ =cut
453
458
454
459
sub isUpperTriangular {
455
460
my $self = shift ;
456
461
my @d = $self -> dimensions;
457
462
return 1 if scalar (@d ) == 1;
458
- return 0 if scalar (@d ) > 2;
459
- for my $i (2 .. $d [0]) {
460
- for my $j (1 .. ($i - 1 < $d [1] ? $i - 1 : $d [1])) {
461
- return 0 unless $self -> element($i , $j ) == 0;
463
+ if (scalar (@d ) == 2) {
464
+ for my $i (2 .. $d [0]) {
465
+ for my $j (1 .. ($i - 1 < $d [1] ? $i - 1 : $d [1])) {
466
+ return 0 unless $self -> element($i , $j ) == 0;
467
+ }
468
+ }
469
+ } else {
470
+ for my $row (@{ $self -> {data } }) {
471
+ return 0 unless $row -> isUpperTriangular;
462
472
}
463
473
}
464
474
return 1;
465
475
}
466
476
477
+ =head3 C<isLowerTriangular >
478
+
479
+ Check if a Matrix is lower triangular (for degree > 2, applies to frontal slice matrices)
480
+
481
+ =cut
482
+
467
483
sub isLowerTriangular {
468
484
my $self = shift ;
469
485
my @d = $self -> dimensions;
470
486
if (scalar (@d ) == 1) {
471
487
for ((@{ $self -> {data } })[ 1 .. $# { $self -> {data } } ]) {
472
488
return 0 unless $_ == 0;
473
489
}
474
- }
475
- return 0 if scalar (@d ) > 2;
476
- for my $i (1 .. $d [0] - 1) {
477
- for my $j ($i + 1 .. $d [1]) {
478
- return 0 unless $self -> element($i , $j ) == 0;
490
+ } elsif (scalar (@d ) == 2) {
491
+ for my $i (1 .. $d [0]) {
492
+ for my $j ($i + 1 .. $d [1]) {
493
+ return 0 unless $self -> element($i , $j ) == 0;
494
+ }
495
+ }
496
+ } else {
497
+ for my $row (@{ $self -> {data } }) {
498
+ return 0 unless $row -> isLowerTriangular;
479
499
}
480
500
}
481
501
return 1;
482
502
}
483
503
504
+ =head3 C<isDiagonal >
505
+
506
+ Check if a Matrix is diagonal (for degree > 2, applies to frontal slice matrices)
507
+
508
+ =cut
509
+
484
510
sub isDiagonal {
485
511
my $self = shift ;
486
512
return $self -> isSquare && $self -> isUpperTriangular && $self -> isLowerTriangular;
487
513
}
488
514
515
+ =head3 C<isSymmetric >
516
+
517
+ Check if a Matrix is symmetric (for degree > 2, applies to frontal slice matrices)
518
+
519
+ =cut
520
+
489
521
sub isSymmetric {
490
522
my $self = shift ;
491
523
return 0 unless $self -> isSquare;
492
- my $d = ($self -> dimensions)[0];
493
- return 1 if $d == 1;
494
- for my $i (1 .. $d - 1) {
495
- for my $j ($i + 1 .. $d ) {
496
- return 0 unless $self -> element($i , $j ) == $self -> element($j , $i );
524
+ my @d = $self -> dimensions;
525
+ return 1 if $d [-1] == 1;
526
+ if (scalar (@d ) == 2) {
527
+ for my $i (1 .. $d [0] - 1) {
528
+ for my $j ($i + 1 .. $d [0]) {
529
+ return 0 unless $self -> element($i , $j ) == $self -> element($j , $i );
530
+ }
531
+ }
532
+ } else {
533
+ for my $row (@{ $self -> {data } }) {
534
+ return 0 unless $row -> isSymmetric;
497
535
}
498
536
}
499
537
return 1;
500
538
}
501
539
540
+ =head3 C<isOrthogonal >
541
+
542
+ Check if a Matrix is orthogonal (for degree > 2, applies to frontal slice matrices)
543
+
544
+ =cut
545
+
502
546
sub isOrthogonal {
503
547
my $self = shift ;
504
548
return 0 unless $self -> isSquare;
@@ -510,52 +554,75 @@ sub isOrthogonal {
510
554
return $M -> isOne;
511
555
}
512
556
513
- #
514
- # See if the matrix is in (reduced) row echelon form
515
- #
557
+ =head3 C<isREF >
558
+
559
+ Check if a Matrix is in row echelon form (for degree > 2, applies to frontal slice matrices)
560
+
561
+ =cut
516
562
517
563
sub isREF {
518
564
my $self = shift ;
519
565
my @d = $self -> dimensions;
520
566
return 1 if scalar (@d ) == 1;
521
- return 0 if scalar (@d ) > 2;
522
- my $k = 0;
523
- for my $i (1 .. $d [0]) {
524
- for my $j (1 .. $d [1]) {
525
- if ($j <= $k ) {
526
- return 0 unless $self -> element($i , $j ) == 0;
527
- } elsif ($self -> element($i , $j ) != 0) {
528
- $k = $j ;
529
- last ;
530
- } elsif ($j == $d [1]) {
531
- $k = $d [1] + 1;
567
+ if (scalar (@d ) == 2) {
568
+ my $k = 0;
569
+ for my $i (1 .. $d [0]) {
570
+ for my $j (1 .. $d [1]) {
571
+ if ($j <= $k ) {
572
+ return 0 unless $self -> element($i , $j ) == 0;
573
+ } elsif ($self -> element($i , $j ) != 0) {
574
+ $k = $j ;
575
+ last ;
576
+ } elsif ($j == $d [1]) {
577
+ $k = $d [1] + 1;
578
+ }
532
579
}
533
580
}
581
+ } else {
582
+ for my $row (@{ $self -> {data } }) {
583
+ return 0 unless $row -> isREF;
584
+ }
534
585
}
535
586
return 1;
536
587
}
537
588
589
+ =head3 C<isRREF >
590
+
591
+ Check if a Matrix is in reduced row echelon form (for degree > 2, applies to frontal slice matrices)
592
+
593
+ =cut
594
+
538
595
sub isRREF {
539
596
my $self = shift ;
540
597
my @d = $self -> dimensions;
541
- return 1 if scalar (@d ) == 1;
542
- return 0 if scalar (@d ) > 2;
543
- my $k = 0;
544
- for my $i (1 .. $d [0]) {
545
- for my $j (1 .. $d [1]) {
546
- if ($j <= $k ) {
547
- return 0 unless $self -> element($i , $j ) == 0;
548
- } elsif ($self -> element($i , $j ) != 0) {
549
- return 0 unless $self -> element($i , $j ) == 1;
550
- for my $m (1 .. $i - 1) {
551
- return 0 unless $self -> element($m , $j ) == 0;
598
+ if (scalar (@d ) == 1) {
599
+ for my $i (1 .. $d [0]) {
600
+ next if $self -> element($i ) == 0;
601
+ return $self -> element($i ) == 1 ? 1 : 0;
602
+ }
603
+ return 1;
604
+ } elsif (scalar (@d ) == 2) {
605
+ my $k = 0;
606
+ for my $i (1 .. $d [0]) {
607
+ for my $j (1 .. $d [1]) {
608
+ if ($j <= $k ) {
609
+ return 0 unless $self -> element($i , $j ) == 0;
610
+ } elsif ($self -> element($i , $j ) != 0) {
611
+ return 0 unless $self -> element($i , $j ) == 1;
612
+ for my $m (1 .. $i - 1) {
613
+ return 0 unless $self -> element($m , $j ) == 0;
614
+ }
615
+ $k = $j ;
616
+ last ;
617
+ } elsif ($j == $d [1]) {
618
+ $k = $d [1] + 1;
552
619
}
553
- $k = $j ;
554
- last ;
555
- } elsif ($j == $d [1]) {
556
- $k = $d [1] + 1;
557
620
}
558
621
}
622
+ } else {
623
+ for my $row (@{ $self -> {data } }) {
624
+ return 0 unless $row -> isREF;
625
+ }
559
626
}
560
627
return 1;
561
628
}
@@ -850,7 +917,7 @@ sub I {
850
917
851
918
=head3 C<E >
852
919
853
- Get an elementary matrix of the requested size and type. These include matrix that upon left multiply will
920
+ Get a degree 2 elementary matrix of the requested size and type. These include matrix that upon left multiply will
854
921
perform row operations.
855
922
856
923
=over
@@ -963,7 +1030,7 @@ sub E {
963
1030
964
1031
=head3 C<P >
965
1032
966
- Creates a permutation matrix of the requested size.
1033
+ Creates a degree 2 permutation matrix of the requested size.
967
1034
968
1035
C<< Value::Matrix->P(n,(cycles)) >> in general where C<cycles > is a sequence of array references
969
1036
of the cycles.
@@ -1036,7 +1103,7 @@ sub P {
1036
1103
1037
1104
=head3 C<Zero >
1038
1105
1039
- Create a zero matrix of requested size. If called on existing matrix, creates a matrix as
1106
+ Create a degree 2 zero matrix of requested size. If called on existing matrix, creates a matrix as
1040
1107
the same size as given matrix.
1041
1108
1042
1109
Usage:
@@ -1069,7 +1136,8 @@ sub Zero {
1069
1136
1070
1137
=head3 C<row >
1071
1138
1072
- Extract a given row from the matrix.
1139
+ Extract a given row from the matrix. For a degree 1 Matrix, $M->row(1) will return $M itself.
1140
+ Otherwise, a "row" is defined by the first index. For an degree n Matrix, a "row" will be a degree (n-1) Matrix.
1073
1141
1074
1142
Usage:
1075
1143
@@ -1090,7 +1158,9 @@ sub row {
1090
1158
1091
1159
=head3 C<column >
1092
1160
1093
- Extract a given column from the matrix.
1161
+ Extract a given column from the matrix. For a degree 1 Matrix, C<$M- > column(j)> will return the jth entry.
1162
+ Otherwise, for an degree n Matrix, C<$M- > column(j)> returns an degree n Matrix tensor using j for the second index.
1163
+ To obtain the corresponding degree (n-1) Matrix, see C<slice() > .
1094
1164
1095
1165
Usage:
1096
1166
@@ -1119,11 +1189,11 @@ sub column {
1119
1189
1120
1190
=head3 C<element >
1121
1191
1122
- Extract an element from the given row/col .
1192
+ Extract an element from the given position .
1123
1193
1124
1194
Usage:
1125
1195
1126
- $A = Matrix([ [ 1, 2, 3, 4 ], [ 5, 6, 7, 8 ], [ 9, 10, 11, 12 ] ]);
1196
+ $A = Matrix([ [ 1, 2, 3, 4 ], [ 5, 6, 7, 8 ], [ 9, 10, 11, 12 ] ]);
1127
1197
$A->element(2,3); # returns 7
1128
1198
1129
1199
$B = Matrix([ [ [ 1, 2 ], [ 3, 4 ] ], [ [ 5, 6 ], [ 7, 8 ] ] ]);
@@ -1204,6 +1274,8 @@ sub det {
1204
1274
my $self = shift ;
1205
1275
$self -> wwMatrixLR;
1206
1276
Value-> Error(" Can't take determinant of non-square matrix" ) unless $self -> isSquare;
1277
+ my $n = $self -> degree;
1278
+ Value-> Error(" Can't take determinant of degree $n matrix" ) unless ($n <= 2);
1207
1279
return Value::makeValue($self -> {lrM }-> det_LR);
1208
1280
}
1209
1281
0 commit comments