convert PDL scalar to Perl scalar - perl

I have a function that uses PDL. The final step is a dot product so it returns a scalar. However, when I try to print this scalar, it is clearly still a piddle and prints like this on screen:
[
[ 3 ]
]
I'm wondering how I can convert it back to the regular Perl scalar so that it prints like:
3
More importantly, what is the consequence if I don't convert and take that piddle on to further arithmetic manipulations in a pure Perl context (that does not involve PDL). Thx!

Use the sclr method, which converts a single-element PDL matrix with any number of dimensions into a simple Perl scalar
my $dotp = sclr($mata x $matb);

To answer the second question ("what is the consequence if I don't convert and take that piddle on to further arithmetic manipulations in a pure Perl context (that does not involve PDL)"); there are two major considerations:
PDL entities ("ndarrays") have overloaded arithmetic so that any Perl scalars used with them will get promoted, and the results will also be ndarrays. For scalar (single-element) ndarrays this is probably undesirable since PDL operations have a performance hit that isn't worth it for a single element
the ndarray shown in the example has one element, but it is 2-dimension (1x1); to be a proper scalar ndarray, you'd do $dotp->squeeze to drop all length-1 dims

Related

MATLAB arrays and containers

I've just started with MATLAB, having mainly played around with Python previously. I've just made my first associative array, and am a little confused with how it's dealing with commas and spaces. My array is:
co_comma=containers.Map({'Open University','UCL',' University of Edinburgh','Birkbeck'},{193835,21210,24525,17822})
I also made a second associative array, splitting using spaces:
co_space=containers.Map({'Open University' 'UCL' ' University of Edinburgh' 'Birkbeck'},{193835 21210 24525 17822})
They both give the following:
Map with properties:
Count: 4
KeyType: char
ValueType: double
But co_comma==co_space gives False:
ans =
logical
0
Questions:
how are these associative arrays different
what actually is a container? Although I've never thought of lists etc in this way, Python seems to have containers in the form of lists/tuples/general iterables - https://stackoverflow.com/a/11576019/11357695. So is a matlab string container vs a matlab char array different in the same way as (for example) python lists and python tuples are different?
Thanks :D
Many things mixed in here!
Clarifications:
A matlab container is only equivalent to a python dictionary, not a list/tuple/general iterable.
Both of your containers are created the same. You seem to be naming them comma and space, but this distinction does not even reach the definition of the container.
Both {'Open University','UCL',' University of Edinburgh','Birkbeck'} and {'Open University' 'UCL' ' University of Edinburgh' 'Birkbeck'} create the exact same cell array, so the input to container.map is the same. you are comparing a=[5]; and b=5, as a MATLAB-valid analogy. They are the same.
For objects, most programing languages (including python!) will give you false when you compare two objects that contain the same values, yet are different objects. Only basic variables tend to compare by value, and not by some sort of objecID. In your case, simply doing isequal(co_comma,co_space) will return true, so their values are the same (as we already know, from the previous point)
Containers are not generally used in MATLAB, unless you specifically want a dictionary.
So here's the deal with Matlab: Matlab is an oddball. In Matlab, everything is an array, and there is no real distinction between regular "values" and "containers" or "collections" like there is in many programming languages. In Matlab, any numeric value is a numeric array. Any string value is actually an array of strings. Every value is iterable and can be used in a for loop or other "list"-like context. And every type or class in Matlab must implement collection/container behaviors as well as its "plain" value semantics.
Scalar values in Matlab are actually degenerate cases of two-dimensional arrays that are 1-by-1 in size. The number 42? Actually a 1-long array of doubles. The string "foo"? Actually a 1-long array of strings. Everything in Matlab is actually like a list in Python (or, more accurately, a NumPy series or array).
A cell array is an array of things, which can contain any other type of array in each of its elements. This is used for heterogeneous collections.
A char array is a bit weird, because it is used to represent strings, but its elements are not themselves strings, but rather characters. Plain char arrays are used in a weird way to represent lists of strings: you make a 2-D char array, and read each row as a string that is padded with spaces on the right. Lists of strings that are different lengths used to be represented as "cellstrs", which are cell arrays that contain char row vectors in each element. It's weird; see my blog post about it. The new string array makes most uses of other string types obsolete. You might want to use strings here. In Matlab, string literals are double-quoted, and char literals are single-quoted.
The word "container" doesn't have a specific technical meaning in Matlab, and is not really a thing. There's the containers package, but the only thing in it is containers.Map; there are no other types of containers and no generalization of what it means to be a container. One of the Matlab developers had an idea for making containers like this, but it never really went anywhere. And as far as I can tell, containers.Map hardly gets used at all: containers.Map is a pass-by-reference "handle" object, whereas most Matlab types are pass-by-value, so Map can't be used easily with most Matlab code.
So, putting aside the weirdness of chars, everything in Matlab has array semantics, and is effectively an iterable container like Python lists or tuples. And in Matlab, most values and objects are immutable and pass-by-value, so they are more like Python tuples than Python lists.

random binomial distributed dataset in perl

I try to do in perl what I succeedd in R but is difficult to combine with my downstream needs.
in R I did the following
library("MASS")
d <- rnegbin(100000, mu = 250, theta = 2)
hist(d, breaks=1000, xlim=c(0,1000))
producing the nice graph I need with a peak round 180-200 and a tail to the right.
Could someone help me code the perl equivalent using Math::Random
I tried this but do not get the right shape
use Math::Random qw(random_negative_binomial);
# random_negative_binomial($n, $ne, $p)
# When called in an array context, returns an array of $n outcomes
# generated from the negative binomial distribution with number of
# events $ne and probability of an event in each trial $p.
# When called in a scalar context, generates and returns only one
# such outcome as a scalar, regardless of the value of $n.
# Argument restrictions: $ne is rounded using int(), the result must be positive.
# $p must be between 0 and 1 exclusive.
# I tried different variable values but never got the right shape
my #dist = random_negative_binomial($n, $ne, $p);
what values do I need to mimic the R results?
I need the same range of values on X and the same general shape
Thanks for any help, I did not find illustrated examples of that package
Stephane
I don't know much about statistics, but since nobody else comes forward: I would use the Perl Data Language PDL (which I use for other things) and fetch the PDL::Stats::Distr module. You can find an example that looks somewhat similar to yours here http://pdl-stats.sourceforge.net/Distr.htm. The module includes pmf_binomial (mass function) and mme_binomial (distribution). You will also need the PGPLOT module.
You will need some random data:
$data = pdl 1..100000; ## generate linear 1 - 100000
$data = $data->random; ## make them random between 0..1

bsxfun() Invalid output dimensions

I have a function that takes upto seven arguments and returns a row vector. The first three arguments are vectors (column, column, row) and the remaining four are optional scalars.
I want to use bsxfun() to apply the function to a vector of its last argument. Below is my attempt to do that.
o = #(m,pulse,N0,samples_per_pulse,sample_select,filter,channel_cutoff) ELE452Functions.EvaluateBER(m,pulse,N0,samples_per_pulse,sample_select,filter,channel_cutoff);
oo = #(m,pulse,N0,samples_per_pulse,sample_select,filter,channel_cutoff) bsxfun(#(N0,channel_cutoff) o(m,pulse,N0,samples_per_pulse,sample_select,filter,channel_cutoff), N0' , channel_cutoff);
when I try to call the function with a vector, oo(m,pulse,N0,1,1,1,[0.5 0.2]); for example, I get this error:
Error using bsxfun
Invalid output dimensions.
I am not experienced in using bsxfun and I tried to follow the documentation.
Update:
May be this is a clearer way to ask my question:
I want to use bsxfun to rewrite (improve) the code below with out a loop.
for i=1:length(channel_normalized_cuttoffs)
BER_LPchannel(i,:) = ELE452Functions.EvaluateBER(m,pulse,N0,1,1,1,channel_normalized_cuttoffs(i));
end
The idea behind bsxfun is to evaluate a certain function for all possible combinations of two elements (b in bsxfun stands for binary), each coming from one of the arrays. (NB: This is valid if you use it with a row and a column vector. But bsxfun can also do more.)
What you want to achieve is simply: For all entries of a single array, evaluate a function.
So bsxfun is just not the correct choice here.
You could use arrayfun instead, but this still may not perform a lot better than your original for loop, as it looks like the Matlab JIT Compiler would be able to optimize most of it, considering it's simplicity.
As I don't have the code of your function, I'm not able to test it, but your solution might look a lot like this:
evalBER = #(CNcutoffi) ELE452Functions.EvaluateBER(m,pulse,N0,1,1,1,CNcutoffi);
BER_LPchannel = arrayfun(evalBER, channel_normalized_cuttoffs, 'UniformOutput', false)

Perl - Square Root results

I am quite new to the world of Perl and I am stuck with the sqrt function.
By stuck I mean the function is not returning the value it should.
After reading a text file with coordinate information, 8 values are stored in separate variables ($x1, $y1, $x2, $y2 and so forth). Then, a subroutine is called, which calculates the distance between the points and then other things. However, it doesn't do what it is supposed to do because the results of the sqrt function are not the ones they should! I thought it was a problem with how the variables were obtained and stored, but after performing the sqrt with the literal values, it also produces a wrong number.
Here are the values
-2130.07 207.56 -2084.46 210.76 -1892.78 -2525.74 -1938.39 -2528.93
And here are the sqrt calculations...
$side1=sqrt(($x1-$x2)^2+($y1-$y2)^2);
$sidecheck=sqrt((-2130.07-(-2084.46))^2+(207.56-210.76)^2);
Both $side1 and $sidecheck return a value of 6.7823 instead of 45.722.
Is there a way to sort this out? Thanks!
In Perl and few other Languages, the power of a number is not the caret, its a double asterisk. So you need to write
$sidecheck=sqrt((-2130.07-(-2084.46))**2+(207.56-210.76)**2);
The ^ is the bitwise XOR operator. To square a value, use **

Vectorizing scalars/vector division

If for example I have:
Q1=4;
Q2=5;
PG=2:60
A1=Q1./sqrt(PG);
A2=Q2./sqrt(PG);
plot(PG,A1)
plot(PG,A2)
can I do sth like : ?
Q=[Q1,Q2];
A=Q./sqrt(PG);
plot(PG,A(1))
plot(PG,A(2))
or sth to avoid the A1 and A2?
A=bsxfun(#rdivide,[Q1;Q2],sqrt(PG)) will do (note the semicolon, not comma, between Q1 and Q2), but if the code in the question is your use case and you ever want anyone else to read and understand the code, I'd advise against using it.
You have to address the rows of A using A(1,:) and A(2,:) (no matter how you get to A), but you probably want to plot(PG,A) anyway.
[edit after first comment:]
rdivide is simply the name of the function usually denoted ./ in MATLAB code, applicable to arrays of the same size or a scalar and an array. bsxfun will simply apply a two-argument function to the other two arguments supplied to it in a way it considers best-fitting (to simplify a bit). arrayfun does something similar: applying a function to all elements of one array. To apply here, one would need a function having PG hard-coded inside.