I am developing a daywise production plan in Excel VBA - vba

I am unable to find solution to make a range with calculate Numbers
SAP size Qty 1 2 3 4 5 6
3MCY5 120/80-16 20 0 0 0 0 0 0
3MCY6 120/80-17 11308 4 4 4 4 4 4
3MCY7 120/80-18 34862 12 12 12 12 12 12
3MCY8 120/80-19 39463 8 8 8 8 8 8
3MCY9 120/80-20 29849 12 12 12 12 12 12
3MCY10 120/80-21 165430 56 56 56 56 56 56
3MCY11 120/80-22 25000 12 12 12 12 12 12
3MCY12 120/80-23 45000 14 14 14 14 14 14

Related

missing “for loop” - pdb distance calculation

I've found many posts to calculate distance between atoms, even I've written my own code for it. Now I want it to be in very less number of lines, I've written something like follows
#!/usr/bin/perl -w
#ARGV = <>;
for ( $i = 0; $i <= $#ARGV; $i++ ) {
#temp = split( /\s+/, $ARGV[$i] );
if ( $temp[0] eq "ATOM" and $temp[2] eq "CA" ) {
( $n1, $ax, $ay, $az ) = #temp[ 5, 6, 7, 8 ];
if ( $temp[0] eq "ATOM" and $temp[2] eq "CA" ) {
( $n2, $bx, $by, $bz ) = #temp[ 5, 6, 7, 8 ];
}
$dista = sprintf( "%0.3f",
sqrt( ( $ax - $bx )**2 + ( $ay - $by )**2 + ( $az - $bz )**2 ) );
print "$n1\t$n2\t$dista\n";
}
}
A sample input file is http://www.rcsb.org/pdb/files/5PTI.pdb. When I run the program it is not taking the next "CA" atom to calculate the distance, I want to calculate first "CA" to all other "CA" atoms and 2nd CA to all other CA's and so on. I know for loop is missing in my code, I tried to include that but something was going wrong. Where can I modify my code to get correct results.
In order to compare all distinct pairs of atoms you need to access the file data out of order, so it is best to read all of the relevant data into memory before doing the calculations.
This program uses a while loop to read all of the CA ATOM numbers and positions into #data, and then calculates the distance between every different pair using a double nested for loop
use strict;
use warnings;
my #data;
while ( <> ) {
my #fields = split;
next unless $fields[0] eq 'ATOM' and $fields[2] eq 'CA';
push #data, [ #fields[5..8] ];
}
for my $i (0 .. $#data-1) {
my ($an, $ax, $ay, $az) = #{ $data[$i] };
for my $j ($i+1 .. $#data) {
my ($bn, $bx, $by, $bz) = #{ $data[$j] };
my ($dx, $dy, $dz) = ($ax-$bx, $ay-$by, $az-$bz);
my $dist = sqrt($dx*$dx + $dy*$dy + $dz*$dz);
printf "%3d %3d %6.3f\n", $an, $bn, $dist;
}
}
output
1 2 3.772
1 3 6.357
1 4 8.230
1 5 6.883
1 6 8.835
1 7 11.836
1 8 14.819
1 9 16.272
1 10 18.781
1 11 22.069
1 12 23.577
1 13 27.304
1 14 28.550
1 15 30.435
1 16 29.411
1 17 27.994
1 18 25.290
1 19 23.197
1 20 19.549
1 21 16.377
1 22 13.683
1 23 10.803
1 24 12.584
1 25 10.300
1 26 13.713
1 27 14.787
1 28 11.633
1 29 13.140
1 30 13.576
1 31 16.899
1 32 19.413
1 33 20.494
1 34 23.292
1 35 22.504
1 36 25.633
1 37 25.598
1 38 24.936
1 39 22.477
1 40 19.299
1 41 16.005
1 42 12.638
1 43 11.659
1 44 14.746
1 45 15.146
1 46 18.399
1 47 17.588
1 48 15.860
1 49 15.021
1 50 13.194
1 51 11.300
1 52 10.500
1 53 9.874
1 54 7.246
1 55 5.502
1 56 7.255
1 57 8.869
1 58 12.364
2 3 3.712
2 4 5.264
2 5 5.705
2 6 7.882
2 7 9.931
2 8 13.310
2 9 14.660
2 10 16.571
2 11 19.974
2 12 20.988
2 13 24.611
2 14 26.005
2 15 28.222
2 16 27.436
2 17 26.450
2 18 23.863
2 19 22.267
2 20 18.602
2 21 15.926
2 22 13.079
2 23 10.991
2 24 13.023
2 25 11.272
2 26 14.827
2 27 16.369
2 28 13.696
2 29 14.802
2 30 14.428
2 31 17.305
2 32 19.214
2 33 19.670
2 34 22.010
2 35 20.704
2 36 23.494
2 37 23.285
2 38 22.198
2 39 19.454
2 40 16.542
2 41 13.059
2 42 9.817
2 43 9.717
2 44 13.047
2 45 14.062
2 46 17.571
2 47 17.545
2 48 16.496
2 49 16.013
2 50 13.461
2 51 11.599
2 52 12.013
2 53 11.355
2 54 7.839
2 55 6.843
2 56 9.812
2 57 12.211
2 58 15.658
3 4 3.765
3 5 5.298
3 6 5.675
3 7 7.436
3 8 11.137
3 9 13.211
3 10 14.962
3 11 18.642
3 12 19.458
3 13 22.991
3 14 24.871
3 15 27.175
3 16 26.862
3 17 25.995
3 18 23.864
3 19 22.429
3 20 18.984
3 21 16.478
3 22 13.154
3 23 11.180
3 24 12.363
3 25 10.420
3 26 13.564
3 27 15.868
3 28 13.932
3 29 15.417
3 30 15.143
3 31 17.475
3 32 19.250
3 33 19.132
3 34 21.369
3 35 20.109
3 36 22.662
3 37 22.879
3 38 21.582
3 39 18.587
3 40 15.998
3 41 12.239
3 42 9.840
3 43 9.607
3 44 13.335
3 45 15.232
3 46 18.951
3 47 19.301
3 48 18.221
3 49 18.412
3 50 15.954
3 51 13.507
3 52 14.244
3 53 14.343
3 54 10.830
3 55 9.041
3 56 11.810
3 57 14.209
3 58 17.229
4 5 3.820
4 6 5.318
4 7 5.362
4 8 8.786
4 9 10.091
4 10 11.574
4 11 15.140
4 12 15.971
4 13 19.569
4 14 21.246
4 15 23.537
4 16 23.146
4 17 22.377
4 18 20.242
4 19 19.031
4 20 15.631
4 21 13.511
4 22 10.308
4 23 9.277
4 24 10.980
4 25 10.254
4 26 13.570
4 27 15.521
4 28 13.857
4 29 14.475
4 30 13.337
4 31 15.229
4 32 16.434
4 33 16.013
4 34 17.953
4 35 16.460
4 36 18.973
4 37 19.118
4 38 17.898
4 39 15.038
4 40 12.292
4 41 8.585
4 42 6.257
4 43 6.086
4 44 9.793
4 45 12.070
4 46 15.828
4 47 16.653
4 48 16.036
4 49 16.682
4 50 13.996
4 51 11.475
4 52 13.125
4 53 13.565
4 54 9.951
4 55 8.588
4 56 11.858
4 57 14.982
4 58 17.912
5 6 3.786
5 7 5.549
5 8 8.148
5 9 9.417
5 10 12.003
5 11 15.345
5 12 17.034
5 13 20.795
5 14 22.183
5 15 23.943
5 16 23.209
5 17 21.821
5 18 19.548
5 19 17.663
5 20 14.226
5 21 11.392
5 22 8.020
5 23 5.923
5 24 7.697
5 25 6.909
5 26 10.530
5 27 12.000
5 28 10.100
5 29 10.716
5 30 9.947
5 31 12.216
5 32 14.072
5 33 14.342
5 34 16.948
5 35 16.188
5 36 19.251
5 37 19.710
5 38 19.200
5 39 16.885
5 40 13.668
5 41 10.418
5 42 7.851
5 43 5.721
5 44 9.267
5 45 10.954
5 46 14.616
5 47 14.695
5 48 13.357
5 49 14.154
5 50 12.112
5 51 9.007
5 52 10.078
5 53 11.232
5 54 8.148
5 55 5.688
5 56 8.503
5 57 11.702
5 58 14.362
6 7 3.831
6 8 6.572
6 9 9.275
6 10 11.961
6 11 15.547
6 12 17.196
6 13 20.827
6 14 22.748
6 15 24.452
6 16 24.212
6 17 22.799
6 18 21.078
6 19 19.207
6 20 16.153
6 21 13.423
6 22 9.721
6 23 7.486
6 24 7.340
6 25 5.698
6 26 8.505
6 27 11.057
6 28 10.121
6 29 11.598
6 30 11.538
6 31 13.190
6 32 15.162
6 33 14.966
6 34 17.633
6 35 17.217
6 36 20.067
6 37 21.104
6 38 20.504
6 39 18.040
6 40 15.210
6 41 11.855
6 42 10.280
6 43 8.110
6 44 11.650
6 45 13.922
6 46 17.544
6 47 17.700
6 48 16.106
6 49 17.323
6 50 15.639
6 51 12.259
6 52 13.014
6 53 14.602
6 54 11.760
6 55 8.788
6 56 10.724
6 57 13.305
6 58 15.397
7 8 3.788
7 9 6.501
7 10 8.500
7 11 12.241
7 12 13.561
7 13 17.118
7 14 19.243
7 15 21.116
7 16 21.202
7 17 20.145
7 18 18.765
7 19 17.426
7 20 14.643
7 21 12.683
7 22 9.085
7 23 8.406
7 24 8.404
7 25 8.354
7 26 10.628
7 27 13.077
7 28 12.781
7 29 13.456
7 30 12.474
7 31 13.236
7 32 14.271
7 33 13.178
7 34 15.234
7 35 14.441
7 36 16.903
7 37 18.077
7 38 17.268
7 39 14.740
7 40 12.239
7 41 9.000
7 42 8.569
7 43 6.762
7 44 10.022
7 45 13.081
7 46 16.670
7 47 17.588
7 48 16.646
7 49 18.349
7 50 16.355
7 51 13.074
7 52 14.771
7 53 16.437
7 54 13.415
7 55 11.103
7 56 13.508
7 57 16.519
7 58 18.574
8 9 3.829
8 10 6.391
8 11 9.730
8 12 11.714
8 13 15.183
8 14 17.246
8 15 18.615
8 16 18.817
8 17 17.467
8 18 16.564
8 19 15.151
8 20 12.958
8 21 11.376
8 22 8.076
8 23 8.330
8 24 7.464
8 25 8.810
8 26 10.170
8 27 12.231
8 28 12.876
8 29 12.969
8 30 11.707
8 31 11.373
8 32 11.921
8 33 10.304
8 34 12.345
8 35 12.170
8 36 14.656
8 37 16.484
8 38 16.239
8 39 14.329
8 40 11.939
8 41 9.623
8 42 10.141
8 43 7.644
8 44 9.770
8 45 12.967
8 46 16.144
8 47 17.164
8 48 16.234
8 49 18.629
8 50 17.098
8 51 13.644
8 52 15.542
8 53 17.852
8 54 15.331
8 55 12.977
8 56 14.899
8 57 17.929
8 58 19.411
9 10 3.796
9 11 6.560
9 12 9.191
9 13 12.815
9 14 14.244
9 15 15.405
9 16 15.226
9 17 13.799
9 18 12.745
9 19 11.505
9 20 9.462
9 21 8.624
9 22 6.111
9 23 8.130
9 24 8.288
9 25 10.836
9 26 12.463
9 27 13.537
9 28 14.017
9 29 13.030
9 30 10.756
9 31 9.762
9 32 9.230
9 33 7.106
9 34 8.767
9 35 8.406
9 36 11.173
9 37 12.963
9 38 13.196
9 39 11.907
9 40 9.274
9 41 7.975
9 42 9.009
9 43 6.426
9 44 7.058
9 45 10.329
9 46 13.110
9 47 14.574
9 48 14.241
9 49 16.984
9 50 15.450
9 51 12.315
9 52 14.872
9 53 17.243
9 54 15.016
9 55 13.356
9 56 15.411
9 57 18.781
9 58 20.275
10 11 3.828
10 12 5.496
10 13 9.172
10 14 10.923
10 15 12.620
10 16 12.993
10 17 12.458
10 18 11.905
10 19 11.855
10 20 10.354
10 21 10.795
10 22 9.077
10 23 11.601
10 24 12.078
10 25 14.440
10 26 16.059
10 27 17.305
10 28 17.774
10 29 16.703
10 30 14.136
10 31 12.928
10 32 11.515
10 33 8.580
10 34 8.535
10 35 6.945
10 36 8.611
10 37 10.409
10 38 10.097
10 39 8.733
10 40 6.955
10 41 6.570
10 42 9.147
10 43 8.045
10 44 7.942
10 45 11.516
10 46 13.970
10 47 16.239
10 48 16.684
10 49 19.362
10 50 17.428
10 51 14.794
10 52 17.795
10 53 19.775
10 54 17.311
10 55 16.195
10 56 18.651
10 57 22.165
10 58 23.882
11 12 3.829
11 13 6.896
11 14 7.832
11 15 8.935
11 16 9.358
11 17 8.968
11 18 9.167
11 19 9.914
11 20 9.600
11 21 11.270
11 22 10.756
11 23 13.943
11 24 14.437
11 25 17.339
11 26 18.680
11 27 19.414
11 28 20.142
11 29 18.516
11 30 15.604
11 31 13.656
11 32 11.238
11 33 7.743
11 34 6.051
11 35 4.259
11 36 5.107
11 37 7.753
11 38 8.381
11 39 8.497
11 40 7.487
11 41 8.904
11 42 11.750
11 43 10.782
11 44 9.363
11 45 12.346
11 46 13.858
11 47 16.459
11 48 17.387
11 49 20.381
11 50 18.730
11 51 16.466
11 52 19.658
11 53 21.770
11 54 19.716
11 55 18.921
11 56 21.179
11 57 24.715
11 58 26.195
12 13 3.798
12 14 5.872
12 15 8.412
12 16 9.787
12 17 10.835
12 18 11.309
12 19 12.940
12 20 12.564
12 21 14.413
12 22 13.731
12 23 16.751
12 24 17.446
12 25 19.934
12 26 21.458
12 27 22.598
12 28 23.145
12 29 21.769
12 30 18.861
12 31 17.257
12 32 14.923
12 33 11.528
12 34 9.487
12 35 6.828
12 36 5.623
12 37 7.368
12 38 6.441
12 39 6.083
12 40 6.825
12 41 8.668
12 42 12.254
12 43 12.427
12 44 11.299
12 45 14.440
12 46 16.010
12 47 19.024
12 48 20.323
12 49 23.002
12 50 20.893
12 51 18.915
12 52 22.282
12 53 23.962
12 54 21.538
12 55 21.023
12 56 23.674
12 57 27.301
12 58 29.102
13 14 3.879
13 15 6.705
13 16 9.300
13 17 11.362
13 18 12.772
13 19 15.105
13 20 15.435
13 21 17.730
13 22 17.366
13 23 20.477
13 24 21.031
13 25 23.571
13 26 24.880
13 27 26.028
13 28 26.780
13 29 25.340
13 30 22.400
13 31 20.523
13 32 17.874
13 33 14.332
13 34 11.618
13 35 9.221
13 36 6.442
13 37 8.090
13 38 7.079
13 39 7.719
13 40 9.752
13 41 12.037
13 42 15.744
13 43 16.183
13 44 14.857
13 45 17.760
13 46 18.893
13 47 22.081
13 48 23.627
13 49 26.366
13 50 24.297
13 51 22.512
13 52 25.936
13 53 27.588
13 54 25.210
13 55 24.803
13 56 27.451
13 57 31.078
13 58 32.820
14 15 3.805
14 16 5.952
14 17 8.843
14 18 10.375
14 19 13.401
14 20 14.307
14 21 17.253
14 22 17.705
14 23 21.206
14 24 22.143
14 25 25.041
14 26 26.510
14 27 27.150
14 28 27.737
14 29 25.808
14 30 22.545
14 31 20.510
14 32 17.400
14 33 14.104
14 34 10.779
14 35 8.226
14 36 4.525
14 37 5.440
14 38 5.667
14 39 8.155
14 40 10.012
14 41 13.178
14 42 16.588
14 43 17.017
14 44 14.871
14 45 17.120
14 46 17.488
14 47 20.842
14 48 22.838
14 49 25.579
14 50 23.675
14 51 22.349
14 52 25.908
14 53 27.494
14 54 25.489
14 55 25.493
14 56 28.046
14 57 31.725
14 58 33.414
15 16 3.763
15 17 6.550
15 18 9.298
15 19 12.391
...etc.
I would do it in this way
use strict;
use warnings;
sub get_ca_atom {
my #result = split;
return
$result[0] eq 'ATOM'
&& $result[2] eq 'CA'
&& #result > 8 ? [ #result[ 5 .. 8 ] ] : ();
}
my #atoms = map get_ca_atom, <>;
while (#atoms) {
my $a = shift #atoms;
for my $b (#atoms) {
my $dist
= sqrt( ( $$a[1] - $$b[1] )**2
+ ( $$a[2] - $$b[2] )**2
+ ( $$a[3] - $$b[3] )**2 );
printf "%s\t%s\t%0.3f\n", $$a[0], $$b[0], $dist;
}
}
But in reality I would like to separate handling with the atom internals from the main algorithm to be clear and communicate an intention of the code as good as possible. There is nothing worse than dealing your own code after few months when written without keeping this in mind.
use strict;
use warnings;
# handle CA ATOM record
use constant { ATOM_TAG => 0, ATOM_TYPE => 2 };
use constant ATOM_SPLICE => ( 5 .. 8 );
use constant { NAME => 0, X => 1, Y => 2, Z => 3 };
sub get_ca_atom {
my #result = split;
return
$result[ATOM_TAG] eq 'ATOM'
&& $result[ATOM_TYPE] eq 'CA'
&& #result > (ATOM_SPLICE)[-1] ? [ #result[ATOM_SPLICE] ] : ();
}
sub get_name { shift->[NAME] }
sub distance {
my ( $a, $b ) = #_;
sqrt( ( $$a[X] - $$b[X] )**2
+ ( $$a[Y] - $$b[Y] )**2
+ ( $$a[Z] - $$b[Z] )**2 );
}
# end of handle CA ATOM record
my #atoms = map get_ca_atom, <>;
while (#atoms) {
my $a = shift #atoms;
for my $b (#atoms) {
my $dist = distance( $a, $b );
printf "%s\t%s\t%0.3f\n", get_name($a), get_name($b), $dist;
}
}
Then you can play with the main algorithm as you wish. For example above code reads all file content into memory which should not be a problem in the real task most time. But if you wish to keep only CA ATOMS just change the line with map to the following.
my #atoms;
while (<>) {
my $atom = get_ca_atom;
push #atoms, $atom if $atom;
}
As you can see, intention of the code is slowly missing with more lines but it can be opposite sometimes. The main objection to code is communicating intention even it would mean more lines of code. Especially you should not mix the low level with the high level which was the reason why I separated distance and get_name in the second code example.
If you prefer to process atoms in order as they go, you can use following code, but notice you will not save memory because you need #atoms stored anyway for calculating distance.
my #atoms;
while (<>) {
my $atom = get_ca_atom;
next unless $atom;
for my $a (#atoms) {
my $dist = distance( $atom, $a );
printf "%s\t%s\t%0.3f\n", get_name($a), get_name($atom), $dist;
}
push #atoms, $atom;
}
Note output comes in a different order. And also note I used next unless $atom; instead of using if ($atom) { and enclosing rest of the loop in block. The reason is I want to emphasize: Just skip it if it's not what you expect. If you would like to surprise yourself with the third different order of output you can replace push with unshift.

How can I show the samples/genotype names for each cluster?

My question is how can I show the sample names for each cluster?
example:
Cluster 1: X20, X45, ..., X10
Cluster2: X104, X50,..., X33
## creating clusters of hclust
##get 10 groups out of the sample
out1 <- cutree(hc1, k = 50)
## draw dendogram with red borders around the 5 clusters
rect.hclust(hc1, k=50, border="red")
save(out1, file = "out1.rda")
load("out1.rda")
## number of samples in each cluster
> table(out1)
out1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
10 22 108 181 122 21 12 28 5 75 27 14 39 4 5 4 11 9 29 2 5 4 14
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
4 2 22 23 3 10 1 6 11 8 2 5 9 6 4 5 1 1 1 2 9 14 1
47 48 49 50
4 1 1 1
Cluster dendrogram showing 50 clusters (clickhere)

How to find match of elements and extract matrix

A=[
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
26 17 24 3 4]
b= 23;
C= 11;
Now, 1st column of matrix A must be check to find any element matches with inputs b and also c. Then, to get matrix
D=
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
Try from these links
[matching indices][1]
[matching data in matrix][2]
[extracting data from matrix][3]

Random chose N items from array and update it in BASH SCRIPT

I am trying to random choose a number of items of an array and then update it to do it again till the last set:
#! /bin/bash
A=({1..27})
T=${#A[#]} #number of items in the array
N=3 #number of items to be chosen
V=$(($T/$N)) #number of times to loop
echo ${A[#]} " >> ${#A[#]}"
for ((n=0;n<$V;n++)); do
A1=()
for I in `shuf --input-range=0-$(( ${#A[*]} - 1 )) | head -${N}`; do #random chooses N items random
S=`echo ${A[$I]}` #the chosen items
#echo $S
A1+=("$S|") #creates an array with the chosen items
A=("${A[#]/$S}") #deletes the the chosen items from array
done
echo ${A[#]} " >> ${#A[#]}"
echo ${A1[#]} " >> ${#A1[#]}"
done
The type of output I am getting with this code is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 >> 27
1 4 5 6 7 8 9 10 11 1 1 14 15 16 17 18 19 1 2 4 5 6 7 >> 27
20| 2| 3| >> 3
4 6 7 8 9 0 1 4 6 7 8 9 2 4 6 7 >> 27
1| | 5| >> 3
6 7 8 9 0 1 6 7 8 9 2 6 7 >> 27
| | 4| >> 3
7 8 9 0 1 7 8 9 2 7 >> 27
6| | | >> 3
7 8 9 0 1 7 8 9 7 >> 27
| | 2| >> 3
7 9 0 1 7 9 7 >> 27
8| | | >> 3
7 9 1 7 9 7 >> 27
| | 0| >> 3
7 9 1 7 9 7 >> 27
| | | >> 3
1 >> 27
9| 7| | >> 3
Any ideas why it works fine in the start and fails in the end??
There are some improvements that could be made to your script:
Use lowercase letters
Quote your expansion ("${a[#]}").
Remove items by doing unset a[j].
Re-build array with a=("${a[#]}").
No need for head as shuf could produce a counted result with -n.
Avoid the use of backquotes, use $(…) instead.
That will reduce the script to:
#!/bin/bash
t=27 #number of items in the array
n=3 #number of items to be chosen
a=( $(seq 1 "$t") )
a1=()
while (( ${#a[#]} >= n )); do
for j in $(shuf -n "$n" --input-range=0-$((${#a[#]}-1)) ); do # choose $n random items.
a1+=("${a[j]}") # append to an array the chosen items.
unset "a[j]" # deletes the the chosen items from array.
done
a=("${a[#]}") # re-build the array.
echo "a ${a[#]} >> ${#a[#]}"
echo "a1 ${a1[#]} >> ${#a1[#]}"
done
This will produce this output:
a 1 2 3 5 6 7 8 9 10 11 12 14 15 16 18 19 20 21 22 23 24 25 26 27 >> 24
a1 17 13 4 >> 3
a 1 2 5 6 7 8 10 11 12 14 15 16 18 19 20 21 22 23 24 26 27 >> 21
a1 17 13 4 25 3 9 >> 6
a 1 2 5 6 7 8 10 11 14 15 16 18 21 22 23 24 26 27 >> 18
a1 17 13 4 25 3 9 12 20 19 >> 9
a 1 2 5 7 8 10 11 14 15 16 21 22 24 26 27 >> 15
a1 17 13 4 25 3 9 12 20 19 23 6 18 >> 12
a 2 7 8 10 11 14 15 16 22 24 26 27 >> 12
a1 17 13 4 25 3 9 12 20 19 23 6 18 1 5 21 >> 15
a 2 8 10 14 15 22 24 26 27 >> 9
a1 17 13 4 25 3 9 12 20 19 23 6 18 1 5 21 7 11 16 >> 18
a 2 10 14 24 26 27 >> 6
a1 17 13 4 25 3 9 12 20 19 23 6 18 1 5 21 7 11 16 22 8 15 >> 21
a 14 26 27 >> 3
a1 17 13 4 25 3 9 12 20 19 23 6 18 1 5 21 7 11 16 22 8 15 2 24 10 >> 24
a >> 0
a1 17 13 4 25 3 9 12 20 19 23 6 18 1 5 21 7 11 16 22 8 15 2 24 10 14 26 27 >> 27
But the same array a1 could be built just in one step with shuf:
#!/bin/bash
t=27 # number of items in the array
n=3 # number of items to be chosen
a1=( $(shuf --input-range=1-"$t") )
printf '%3s ' "${a1[#]}"; echo
Which will print:
$ ./script.sh
15 23 1 9 24 2 21 11 12 10 19 25 27 13 5 26 4 7 14 3 22 20 17 18 16 6 8
Or, if the result must be in $n elements per line:
#!/bin/bash
t=27 # number of items in the array
n=3 # number of items to be chosen
a1=( $(shuf --input-range=1-"$t") )
while ((i+n<=t)); do
printf '%3s ' "${a1[#]:i:n}"; echo
((i+=n))
done
Printing:
$ ./script.sh
7 19 16
4 20 26
11 23 2
13 6 15
22 12 25
18 14 10
21 8 9
5 24 27
1 3 17
Looks like a simpler solution.
There are a few wrong things in your script, especially the way you (think you) delete the elements from the array. You're not deleting any elements, you're only replacing their values by the empty string in every field!. That's why your array has 27 elements all the way through, and after the first iteration, all the 2's and 3's are removed from each field. Here's a more idiomatic script:
#! /bin/bash
a=( {1..27} )
n=3 #number of items to be chosen
while ((${#a[#]}>=n)); do
a1=()
for ((i=0;i<n;++i)); do
# pick an index
x=$((RANDOM%${#a[#]}))
# append its value to array a1
a1+=( "${a[x]}" )
# unset it
unset 'a[x]'
# reconstruct array a (make it non-sparse again)
a=( "${a[#]}" )
done
# print array
printf 'a: %s >> %s\n' "${a[*]}" "${#a[#]}"
# print chosen elements
printf 'a1: %s >> %s\n' "${a1[*]}" "${#a1[#]}"
done

Matlab: repeat and concatenate rows and cols into new array

I have two 4-by-4 arrays:
a1 = [ 1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16 ]
a2 = [ 17 18 19 20; 21 22 23 24; 25 26 27 28; 29 30 31 32 ]
I need to create 16-by-8 array C:
1 2 3 4 17 18 19 20
1 2 3 4 21 22 23 24
1 2 3 4 25 26 27 28
1 2 3 4 29 30 31 32
5 6 7 8 17 18 19 20
5 6 7 8 21 22 23 24
5 6 7 8 25 26 27 28
5 6 7 8 29 30 31 32
9 10 11 12 17 18 19 20
9 10 11 12 21 22 23 24
9 10 11 12 25 26 27 28
9 10 11 12 29 30 31 32
13 14 15 16 17 18 19 20
13 14 15 16 21 22 23 24
13 14 15 16 25 26 27 28
13 14 15 16 29 30 31 32
The left half (from 1st to 4th column) of the result array C should repeat 4 times i-th row of the array a1, the right half (from 5th to 8th column) should repeat 4 times the array a2.
Below is my code.
p=4
n=4
for i=1:n
b=n*i;
a=n*(i-1)+1;
for j=1:p
for k=a:b
C(k,j)=a1(i,j);
end;
end;
end;
for i=1:n
b=n*i;
a=n*(i-1)+1;
for j=p+1:2*p
l=1;
for k=a:b
C(k,j)=a2(l,j-p);
l=l+1;
end;
end;
end;
C;
size_C=size(C)
Question. Is it possible to create result array C without for-loop? Which functions can I use?
You can use ndgrid to generate the row indices and then concatenate:
[ii, jj] = ndgrid(1:size(a2,1), 1:size(a1,1));
C = [a1(jj,:) a2(ii,:)];
Yes it's possible.
One way of doing it is by using kron and repmat
C = [ kron(a1, ones(4,1)) repmat(a2, 4, 1)]
Perhaps the 4 should be derived from the size of one of the matrixes
With focus on performance, here's one using reshape and repmat -
% Store sizes
M = size(a1,1);
N = size(a2,1);
% Get the replicated version for a1 and a2 separately
parte1 = reshape(repmat(reshape(a1,1,M,[]),[N,1,1]),M*N,[])
parte2 = repmat(a2,[M,1]);
% Do columnar concatenatation for final output
out = [parte1 parte2]
Sample run on a generic case -
a1 = % 3 x 4 array
5 2 6 9
7 4 7 6
9 8 6 1
a2 = % 2 x 5 array
7 7 1 9 2
6 8 8 7 9
out =
5 2 6 9 7 7 1 9 2
5 2 6 9 6 8 8 7 9
7 4 7 6 7 7 1 9 2
7 4 7 6 6 8 8 7 9
9 8 6 1 7 7 1 9 2
9 8 6 1 6 8 8 7 9

Resources