Pascal matrix generation: Difference between revisions

Content added Content deleted
m (→‎{{header|REXX}}: added/changed comments and whitespace, used a template for the output section.)
(Rename Perl 6 -> Raku, alphabetize, minor clean-up)
Line 43: Line 43:
;Note:
;Note:
The   [[Cholesky decomposition]]   of a Pascal symmetric matrix is the Pascal lower-triangle matrix of the same size.
The   [[Cholesky decomposition]]   of a Pascal symmetric matrix is the Pascal lower-triangle matrix of the same size.
<br><br>
<br><br>


=={{header|360 Assembly}}==
=={{header|360 Assembly}}==
Line 939: Line 939:
1 4 10 20 35
1 4 10 20 35
1 5 15 35 70
1 5 15 35 70
</pre>

=={{header|C++}}==
{{works with|GCC|version 7.2.0 (Ubuntu 7.2.0-8ubuntu3.2) }}
<lang cpp>#include <iostream>
#include <vector>

typedef std::vector<std::vector<int>> vv;

vv pascal_upper(int n) {
vv matrix(n);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (i > j) matrix[i].push_back(0);
else if (i == j || i == 0) matrix[i].push_back(1);
else matrix[i].push_back(matrix[i - 1][j - 1] + matrix[i][j - 1]);
}
}
return matrix;
}

vv pascal_lower(int n) {
vv matrix(n);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (i < j) matrix[i].push_back(0);
else if (i == j || j == 0) matrix[i].push_back(1);
else matrix[i].push_back(matrix[i - 1][j - 1] + matrix[i - 1][j]);
}
}
return matrix;
}

vv pascal_symmetric(int n) {
vv matrix(n);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (i == 0 || j == 0) matrix[i].push_back(1);
else matrix[i].push_back(matrix[i][j - 1] + matrix[i - 1][j]);
}
}
return matrix;
}


void print_matrix(vv matrix) {
for (std::vector<int> v: matrix) {
for (int i: v) {
std::cout << " " << i;
}
std::cout << std::endl;
}
}

int main() {
std::cout << "PASCAL UPPER MATRIX" << std::endl;
print_matrix(pascal_upper(5));
std::cout << "PASCAL LOWER MATRIX" << std::endl;
print_matrix(pascal_lower(5));
std::cout << "PASCAL SYMMETRIC MATRIX" << std::endl;
print_matrix(pascal_symmetric(5));
}</lang>
{{out}}
<pre>
PASCAL UPPER MATRIX
1 1 1 1 1
0 1 2 3 4
0 0 1 3 6
0 0 0 1 4
0 0 0 0 1
PASCAL LOWER MATRIX
1 0 0 0 0
1 1 0 0 0
1 2 1 0 0
1 3 3 1 0
1 4 6 4 1
PASCAL SYMMETRIC MATRIX
1 1 1 1 1
1 2 3 4 5
1 3 6 10 15
1 4 10 20 35
1 5 15 35 70
</pre>
</pre>


Line 1,109: Line 1,027:
| 1 4 10 20 35|
| 1 4 10 20 35|
| 1 5 15 35 70|</pre>
| 1 5 15 35 70|</pre>

=={{header|C++}}==
{{works with|GCC|version 7.2.0 (Ubuntu 7.2.0-8ubuntu3.2) }}
<lang cpp>#include <iostream>
#include <vector>

typedef std::vector<std::vector<int>> vv;

vv pascal_upper(int n) {
vv matrix(n);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (i > j) matrix[i].push_back(0);
else if (i == j || i == 0) matrix[i].push_back(1);
else matrix[i].push_back(matrix[i - 1][j - 1] + matrix[i][j - 1]);
}
}
return matrix;
}

vv pascal_lower(int n) {
vv matrix(n);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (i < j) matrix[i].push_back(0);
else if (i == j || j == 0) matrix[i].push_back(1);
else matrix[i].push_back(matrix[i - 1][j - 1] + matrix[i - 1][j]);
}
}
return matrix;
}

vv pascal_symmetric(int n) {
vv matrix(n);
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (i == 0 || j == 0) matrix[i].push_back(1);
else matrix[i].push_back(matrix[i][j - 1] + matrix[i - 1][j]);
}
}
return matrix;
}


void print_matrix(vv matrix) {
for (std::vector<int> v: matrix) {
for (int i: v) {
std::cout << " " << i;
}
std::cout << std::endl;
}
}

int main() {
std::cout << "PASCAL UPPER MATRIX" << std::endl;
print_matrix(pascal_upper(5));
std::cout << "PASCAL LOWER MATRIX" << std::endl;
print_matrix(pascal_lower(5));
std::cout << "PASCAL SYMMETRIC MATRIX" << std::endl;
print_matrix(pascal_symmetric(5));
}</lang>
{{out}}
<pre>
PASCAL UPPER MATRIX
1 1 1 1 1
0 1 2 3 4
0 0 1 3 6
0 0 0 1 4
0 0 0 0 1
PASCAL LOWER MATRIX
1 0 0 0 0
1 1 0 0 0
1 2 1 0 0
1 3 3 1 0
1 4 6 4 1
PASCAL SYMMETRIC MATRIX
1 1 1 1 1
1 2 3 4 5
1 3 6 10 15
1 4 10 20 35
1 5 15 35 70
</pre>


=={{header|Common Lisp}}==
=={{header|Common Lisp}}==
Line 1,950: Line 1,950:
[1,4,10,20,35]
[1,4,10,20,35]
[1,5,15,35,70]</pre>
[1,5,15,35,70]</pre>

=={{header|Julia}}==
Julia has a built-in <code>binomial</code> function to compute the binomial coefficients, and we can construct the Pascal matrices with this function using list comprehensions:
<lang Julia>julia> [binomial(j,i) for i in 0:4, j in 0:4]
5×5 Array{Int64,2}:
1 1 1 1 1
0 1 2 3 4
0 0 1 3 6
0 0 0 1 4
0 0 0 0 1

julia> [binomial(i,j) for i in 0:4, j in 0:4]
5×5 Array{Int64,2}:
1 0 0 0 0
1 1 0 0 0
1 2 1 0 0
1 3 3 1 0
1 4 6 4 1

julia> [binomial(j+i,i) for i in 0:4, j in 0:4]
5×5 Array{Int64,2}:
1 1 1 1 1
1 2 3 4 5
1 3 6 10 15
1 4 10 20 35
1 5 15 35 70
</lang>


=={{header|jq}}==
=={{header|jq}}==
Line 2,054: Line 2,027:
1 4 10 20 35
1 4 10 20 35
1 5 15 35 70</lang>
1 5 15 35 70</lang>

=={{header|Julia}}==
Julia has a built-in <code>binomial</code> function to compute the binomial coefficients, and we can construct the Pascal matrices with this function using list comprehensions:
<lang Julia>julia> [binomial(j,i) for i in 0:4, j in 0:4]
5×5 Array{Int64,2}:
1 1 1 1 1
0 1 2 3 4
0 0 1 3 6
0 0 0 1 4
0 0 0 0 1

julia> [binomial(i,j) for i in 0:4, j in 0:4]
5×5 Array{Int64,2}:
1 0 0 0 0
1 1 0 0 0
1 2 1 0 0
1 3 3 1 0
1 4 6 4 1

julia> [binomial(j+i,i) for i in 0:4, j in 0:4]
5×5 Array{Int64,2}:
1 1 1 1 1
1 2 3 4 5
1 3 6 10 15
1 4 10 20 35
1 5 15 35 70
</lang>


=={{header|Kotlin}}==
=={{header|Kotlin}}==
Line 2,264: Line 2,264:


</pre>
</pre>

=={{header|Mathematica}}==
=={{header|Mathematica}}==
One solution is to generate a symmetric Pascal matrix then use the built in method to
One solution is to generate a symmetric Pascal matrix then use the built in method to
Line 2,529: Line 2,530:
1, 4, 10, 20, 35
1, 4, 10, 20, 35
1, 5, 15, 35, 70</pre>
1, 5, 15, 35, 70</pre>
=={{header|Perl 6}}==
{{Works with|rakudo|2016-12}}
Here is a rather more general solution than required. The <tt>grow-matrix</tt> function will grow any N by N matrix into an N+1 x N+1 matrix, using any function of the three leftward/upward neighbors, here labelled "West", "North", and "Northwest". We then define three iterator functions that can grow Pascal matrices, and use those iterators to define three constants, each of which is an infinite sequence of ever-larger Pascal matrices. Normal subscripting then pulls out the ones of the specified size.
<lang perl6># Extend a matrix in 2 dimensions based on 3 neighbors.
sub grow-matrix(@matrix, &func) {
my $n = @matrix.shape eq '*' ?? 1 !! @matrix.shape[0];
my @m[$n+1;$n+1];
for ^$n X ^$n -> ($i, $j) {
@m[$i;$j] = @matrix[$i;$j];
}
# West North NorthWest
@m[$n; 0] = func( 0, @m[$n-1;0], 0 );
@m[ 0;$n] = func( @m[0;$n-1], 0, 0 );
@m[$_;$n] = func( @m[$_;$n-1], @m[$_-1;$n], @m[$_-1;$n-1]) for 1 ..^ $n;
@m[$n;$_] = func( @m[$n;$_-1], @m[$n-1;$_], @m[$n-1;$_-1]) for 1 .. $n;
@m;
}

# I am but mad north-northwest...
sub madd-n-nw(@m) { grow-matrix @m, -> $w, $n, $nw { $n + $nw } }
sub madd-w-nw(@m) { grow-matrix @m, -> $w, $n, $nw { $w + $nw } }
sub madd-w-n (@m) { grow-matrix @m, -> $w, $n, $nw { $w + $n } }

# Define 3 infinite sequences of Pascal matrices.
constant upper-tri = [1], &madd-w-nw ... *;
constant lower-tri = [1], &madd-n-nw ... *;
constant symmetric = [1], &madd-w-n ... *;

show_m upper-tri[4];
show_m lower-tri[4];
show_m symmetric[4];

sub show_m (@m) {
my \n = @m.shape[0];
for ^n X ^n -> (\i, \j) {
print @m[i;j].fmt("%{1+max(@m).chars}d");
print "\n" if j+1 eq n;
}
say '';
}</lang>
{{out}}
<pre> 1 1 1 1 1
0 1 2 3 4
0 0 1 3 6
0 0 0 1 4
0 0 0 0 1

1 0 0 0 0
1 1 0 0 0
1 2 1 0 0
1 3 3 1 0
1 4 6 4 1

1 1 1 1 1
1 2 3 4 5
1 3 6 10 15
1 4 10 20 35
1 5 15 35 70</pre>


=={{header|Phix}}==
=={{header|Phix}}==
Line 3,040: Line 2,983:
[4,] 1 4 10 20 35
[4,] 1 4 10 20 35
[5,] 1 5 15 35 70</lang>
[5,] 1 5 15 35 70</lang>

=={{header|Racket}}==
=={{header|Racket}}==


Line 3,090: Line 3,034:


</pre>
</pre>

=={{header|Raku}}==
(formerly Perl 6)
{{Works with|rakudo|2016-12}}
Here is a rather more general solution than required. The <tt>grow-matrix</tt> function will grow any N by N matrix into an N+1 x N+1 matrix, using any function of the three leftward/upward neighbors, here labelled "West", "North", and "Northwest". We then define three iterator functions that can grow Pascal matrices, and use those iterators to define three constants, each of which is an infinite sequence of ever-larger Pascal matrices. Normal subscripting then pulls out the ones of the specified size.
<lang perl6># Extend a matrix in 2 dimensions based on 3 neighbors.
sub grow-matrix(@matrix, &func) {
my $n = @matrix.shape eq '*' ?? 1 !! @matrix.shape[0];
my @m[$n+1;$n+1];
for ^$n X ^$n -> ($i, $j) {
@m[$i;$j] = @matrix[$i;$j];
}
# West North NorthWest
@m[$n; 0] = func( 0, @m[$n-1;0], 0 );
@m[ 0;$n] = func( @m[0;$n-1], 0, 0 );
@m[$_;$n] = func( @m[$_;$n-1], @m[$_-1;$n], @m[$_-1;$n-1]) for 1 ..^ $n;
@m[$n;$_] = func( @m[$n;$_-1], @m[$n-1;$_], @m[$n-1;$_-1]) for 1 .. $n;
@m;
}

# I am but mad north-northwest...
sub madd-n-nw(@m) { grow-matrix @m, -> $w, $n, $nw { $n + $nw } }
sub madd-w-nw(@m) { grow-matrix @m, -> $w, $n, $nw { $w + $nw } }
sub madd-w-n (@m) { grow-matrix @m, -> $w, $n, $nw { $w + $n } }

# Define 3 infinite sequences of Pascal matrices.
constant upper-tri = [1], &madd-w-nw ... *;
constant lower-tri = [1], &madd-n-nw ... *;
constant symmetric = [1], &madd-w-n ... *;

show_m upper-tri[4];
show_m lower-tri[4];
show_m symmetric[4];

sub show_m (@m) {
my \n = @m.shape[0];
for ^n X ^n -> (\i, \j) {
print @m[i;j].fmt("%{1+max(@m).chars}d");
print "\n" if j+1 eq n;
}
say '';
}</lang>
{{out}}
<pre> 1 1 1 1 1
0 1 2 3 4
0 0 1 3 6
0 0 0 1 4
0 0 0 0 1

1 0 0 0 0
1 1 0 0 0
1 2 1 0 0
1 3 3 1 0
1 4 6 4 1

1 1 1 1 1
1 2 3 4 5
1 3 6 10 15
1 4 10 20 35
1 5 15 35 70</pre>


=={{header|REXX}}==
=={{header|REXX}}==
Line 3,687: Line 3,691:
1 4 10 20 35
1 4 10 20 35
1 5 15 35 70</pre>
1 5 15 35 70</pre>

=={{header|VBScript}}==
=={{header|VBScript}}==
<lang vb>
<lang vb>