I really don't understand PDL's input functions. Personally, I've been using the rcols feature to create pdls, as was recommended to me in various places around the web.
I have an input file like this :
3 -4 -1
0 5 2
3 5 6
2 5 2
5 5 5
5 5 6
which, I want to assign to a Piddle. When I assign it to a piddle like so,
my #pdls = rcols $in_fh, { COLSEP => "\\s" } ;
my $pdl = pdl(#pdls[1 .. $#pdls]);
When I print #pdls this is printed :
[
[ 3 0 3 2 5 5]
[-4 5 5 5 5 5]
[-1 2 6 2 5 6]
]
Which made me think it pulled my file by columns, and not rows. Which makes sense looking at the code, really. When I saved this output to a file(After stripping out all the brackets) this is how it looked. :
3 0 3 2 5 5
-4 5 5 5 5 5
-1 2 6 2 5 6
When I ran the same script on the new input file, the result does not follow the same process as before :
[
[ 0 -4 -1]
[ 3 0 0]
[ 0 5 2]
[ 0 0 0]
[ 0 5 6]
[ 3 0 0]
[ 0 5 2]
[ 2 0 0]
[ 0 5 5]
[ 5 0 0]
[ 0 5 6]
[ 5 0 0]
]
And I have no idea why it is doing so. In essence, I want to be able to read my text file into a piddle. Does anyone see what I'm missing, or able to offer any explanation?
Thanks for any help.
As is occasionally the case in PDL, the design of things with several dimensions can be a bit counter-intuitive. But it is designed overall so it's easy to just adjust dimensions. Here, rcols and wcols treat data in files in a FORTRAN-style column-major way. It is easy to adjust that using the transpose method:
pdl> p $x = sequence(3,4)
[
[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]
]
pdl> wcols($x->transpose, 'myfile')
pdl> p pdl(rcols('myfile', {colsep => qr/\s+/}))->transpose
Reading data into ndarrays of type: [ Double Double Double ]
Read in 4 elements.
[
[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]
]
Maybe its just better to make a "3,6 matrix of zeros" then set in each value individually, (which means putting the data from a file into a 1D pdl() first) I would use a open() to read it into a scaler then put that in a 1D piddle; which can be rather involved ... once you get it in a 1D piddle do this:
open(FILE,"yourfile"); while (<FILE>) { $x = $_; }
close FILE;
$y = zeros(3,6);
p $x = sequence(18);
[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17]
for $c(0..5) { for $d(0..2) { $y($d,$c) .= $x($e++) }}
p $y
[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]
[12 13 14]
[15 16 17]
Related
I read MATLAB diff.m readme, still couldn't figure out the following:
a = [1 2 3]'
b = [3 2 1 4; 1 1 1 5; 5 5 5 6]
diff([a b]') =
2 -1 2
-1 0 0
-1 0 0
3 4 1
what rule is MATLAB applying here? does MATLAB apply different rule if one of the matrices (i.e. a or b) is logical matrix? or both a and b are logical matrix?
MATLAB applies the same rule regardless of the input matrices. Run your code line-by-line in the command window and see.
a and b are like this:
>> a = [1 2 3]'
a =
1
2
3
>> b = [3 2 1 4; 1 1 1 5; 5 5 5 6]
b =
3 2 1 4
1 1 1 5
5 5 5 6
then [a b]':
>> [a b]'
ans =
1 2 3
3 1 5
2 1 5
1 1 5
4 5 6
Now apply the diff rule on this as follows:
[ row 2 - row 1 ]
[ row 3 - row 2 ]
[ row 4 - row 3 ]
[ row 5 - row 4 ]
you will get
>> diff([a b]')
ans =
2 -1 2
-1 0 0
-1 0 0
3 4 1
a =
[1
2
3]
So,
[a b] =
[ 1 3 2 1 4
2 1 1 1 5
3 5 5 5 6 ]
and thus
[a b]' =
[ 1 2 3
3 1 5
2 1 5
1 1 5
4 5 6 ]
and then diff takes the differences along the first dimension whose size is not 0 (i.e. down each column).
This gives the result
diff([a b]') =
[ 2 -1 2
-1 0 0
-1 0 0
3 4 1 ].
How can I shuffle the contents of a matrix and preserve it as a matrix? The shuffle function works for lists but not for matrices
show shuffle [1 2 3 4 5]
1 2 3 5 4
set m matrix:from-row-list
[[1 2 3 4 5]]
show shuffle m
SHUFFLE expected input to be a list but got the
org.nlogo.extensions.matrix.MatrixExtension$LogoMatrix {{matrix: [ [
1 2 3 4 5 ] ]}} instead.
There may be an easier way, but you could jump to a list, shuffle, then come back to a matrix based on the dimensions of your original matrix.
extensions [ matrix ]
to setup
ca
let m matrix:from-row-list [ [ 1 2 3 ] [ 4 5 6 ] [ 7 8 9 ] ]
let sm shuffled-matrix m
print matrix:pretty-print-text sm
reset-ticks
end
; Reporter returns a shuffled matrix
to-report shuffled-matrix [ mat ]
; Get the number of columns
let cols last matrix:dimensions mat
; Shuffle the matrix values as a list
let shuf-vals shuffle reduce sentence matrix:to-row-list mat
; Use the shuffled values to generate a new matrix
; with the same dimensions as the original
report matrix:from-row-list ( subsetter shuf-vals cols )
end
; Reporter returns a list cut into sublists
; based on the len value passed
to-report subsetter [ ls len ]
; Generate subsetting indices for the sublists
let vals ( range 0 ( length ls ) len )
; Make subsets of ls based on the subsetting indices
report map [ i -> sublist ls i ( i + len ) ] vals
end
A few example outputs from setup:
[[ 1 6 7 ]
[ 9 5 8 ]
[ 3 4 2 ]]
[[ 4 6 8 ]
[ 1 9 2 ]
[ 7 5 3 ]]
[[ 2 9 4 ]
[ 6 3 8 ]
[ 5 1 7 ]]
I have a matrix m and I want to have a user defined function which allows me to control the elements that are multiplied by a value.
The function matrix:set-and-report looks promising but I'm not sure how to implement this for multiple elements.
For example, I would like to multiply the first 3 elements of the matrix by -1 to move from this:
let m matrix:from-row-list [1 2 3 4 5 6]
print m
to this:
let n matrix:from-row-list [-1 -2 -3 4 5 6]
With matrix:set-and-report you were indeed pretty close to a solution. Please check the example, I hope this is what you were looking for. The report function has matrix as an input. Than you specify the row, than the index were you want to start the multiplication, where to end it, and finally the multiplier.
Extensions [
matrix
]
to test
let m matrix:from-row-list [ [1 2 3 4 5 6] [1 2 3 4 5 6] ]
print (word "original matrix " m)
print (word "modified matrix " matrix-row-manipulation m 0 0 3 -1)
end
to-report matrix-row-manipulation [matrix row columen-index-start columen-index-end multiplier]
let index (range columen-index-start columen-index-end 1)
foreach index [ i ->
set matrix matrix:set-and-report matrix row i (matrix:get matrix row i * multiplier )
]
report matrix
end
This will return you:
observer> test
original matrix {{matrix: [ [ 1 2 3 4 5 6 ][ 1 2 3 4 5 6 ] ]}}
modified matrix {{matrix: [ [ -1 -2 -3 4 5 6 ][ 1 2 3 4 5 6 ] ]}}
I'm looking for a built in way to create a list of consecutive integers: 1 to n.
IE: [0 1 2 3 4 5 6 7 8]
Does it exist? Currently I'm manually creating the list, which is wasteful.
Manual method: let group-list [0 1 2 3 4 5 6 7 8]
Found the answer:
show n-values 9 [?] will display [0 1 2 3 4 5 6 7 8]
show n-values 9 [? + 1] will display [1 2 3 4 5 6 7 8 9]
I have sort of data,
A = [2 4 6 8 10]
B = [1 2 3 4 5 6 7 8 9 10]
How to write program that can subtracts each value of A from all values of B.
To better understand,
Take A = 2, subtract from all B = [1 2 3 4 5 6 7 8 9 10],
then take A = 4, subtract from all B = [1 2 3 4 5 6 7 8 9 10]
and so on...
If you want to create a new array C that contains, in row i the result of B-A(i), you use bsxfun:
A = [2 4 6 8 10];
B = [1 2 3 4 5 6 7 8 9 10];
C = bsxfun(#minus,B,A') %'#
C =
-1 0 1 2 3 4 5 6 7 8
-3 -2 -1 0 1 2 3 4 5 6
-5 -4 -3 -2 -1 0 1 2 3 4
-7 -6 -5 -4 -3 -2 -1 0 1 2
-9 -8 -7 -6 -5 -4 -3 -2 -1 0
If you want to create a new array C that contains the result of B-A(1)-A(2)-..., you write
C = B-sum(A)
C =
-29 -28 -27 -26 -25 -24 -23 -22 -21 -20