To test a matrix algorithm, I would like to be able to calculate with variables instead of numbers only but not change the algorithm itself.
The direction in which I assume there is a solution (but probably there are others equally welcome) would be to use polymorphism within PDL or replace the PDL library with a symbolic library with the same API as PDL has.
To illustrate my point, the following is a simple algorithm implemented using PDL:
use utf8;
use strict;
use warnings;
use PDL;
sub algorithm ($$) {
my $alpha = shift;
my $beta = shift;
my $A = pdl(
[ cos $alpha, -sin $alpha ],
[ sin $alpha, cos $alpha ],
);
my $B = pdl(
[ cos $beta, -sin $beta ],
[ sin $beta, cos $beta ],
);
print $A x $B;
}
Now to test the code, instead of many calls like
algorithm 0.1, 0.1;
algorithm 0.2, 0.1;
algorithm 0.1, 0.2;
…
use a single call similar to
algorithm 'α', 'β';
or – equally acceptable – similar to
algorithm pdl('α'), pdl('β');
which would eventually output a matrix of terms in the named variables α and β (of course, Latin variable names a and b should be equally possible).
Ideally, nothing in the algorithm would have to change for this; in the end, I want to test the algorithm as it is, not a different algorithm. Adding a use PDL::Symbolic qw( pdl ); or use SPDL qw( pdl ); statement in the header as extension or replacement of use PDL; to me seems an acceptably small exception to the rule of not changing anything.
The only solution which comes to my mind is basically to re-implement the PDL API, at least the functions used in my algorithm and probably with less consideration for efficiency, but using a symbolic object instead of each piddle cell, and probably expanded with an indexing-naming feature for the cells within larger piddles for improved usability.
Is there a better way than programming this library myself from scratch?
Very short answer: No.
Slightly more helpful answer: PDL's whole purpose is to operate on binary data (as C or Fortran would), in the computer's memory (using the "shared memory" model), at great speed. You are describing an entirely different piece of software.
Related
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
I want to edit this to get numberOfCircuits on its own on the left. Is there a possible way to do this in MATLAB?
e1=power(offeredTraffic,numberOfCircuits)/factorial(numberOfCircuits)/sum
The math for this problem is given in https://math.stackexchange.com/questions/61755/is-there-a-way-to-solve-for-an-unknown-in-a-factorial, but it's unclear how to do this with Matlab's functionality.
I'm guessing the easy part is rearranging:
fact_to_invert = power(offeredTraffic,numberOfCircuits)/sum/e1;
Inverting can be done, for instance, by using fzero. First define a continuous factorial based on the gamma function:
fact = #(n) gamma(n+1);
Then use fzero to invert it numerically:
numberOfCircuits_from_inverse = fzero(#(x) fact(x)-fact_to_invert,1);
Of course you should round the result for safe measure, and if it's not an integer then something's wrong.
Note: it's very bad practice (and brings 7 years bad luck) to name a variable with a name which is also a built-in, such as sum in your example.
I am trying to implement block truncation coding (BTC) on an image in matlab. In order to do BTW you have to calculate the mean and standard deviation of each 4x4 block of pixels. However, I need to store the mean as a variable number of bits as in the number of bits that the mean will be stored in is passed into the function that calculates the mean. I'm not sure how to do this part, can anyone help?
An easy and clean approach to variable bit lengths-encoding would require the use of the fixed-point toolbox. E.g. as follows
function o = encode1(val, numBits)
o = fi(val, 0, numBits, 0)
If you are rather bound to pure Matlab you could just and them away and 'simulate' the precision loss if you only want to benchmark your encoding.
function o = encode2(val, numBits)
o = bitand(uint8(val), 256 - 2^(8-numBits));
On the other hand, if you're planning to actually encode into a file and not just simulate the encoding, you would need to establish a bit-stream which is not byte-aligned. This can be a bit tiring to do. Trading off efficiency for ease of implementation, you could use dec2bin to work with a string of '0' and '1' characters. Again, toolboxes can be of help here, e.g. the communication systems toolbox provides the de2bi function.
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
There is one thing I do not like on Matlab: It tries sometimes to be too smart. For instance, if I have a negative square root like
a = -1; sqrt(a)
Matlab does not throw an error but switches silently to complex numbers. The same happens for negative logarithms. This can lead to hard to find errors in a more complicated algorithm.
A similar problem is that Matlab "solves" silently non quadratic linear systems like in the following example:
A=eye(3,2); b=ones(3,1); x = A \ b
Obviously x does not satisfy A*x==b (It solves a least square problem instead).
Is there any possibility to turn that "features" off, or at least let Matlab print a warning message in this cases? That would really helps a lot in many situations.
I don't think there is anything like "being smart" in your examples. The square root of a negative number is complex. Similarly, the left-division operator is defined in Matlab as calculating the pseudoinverse for non-square inputs.
If you have an application that should not return complex numbers (beware of floating point errors!), then you can use isreal to test for that. If you do not want the left division operator to calculate the pseudoinverse, test for whether A is square.
Alternatively, if for some reason you are really unable to do input validation, you can overload both sqrt and \ to only work on positive numbers, and to not calculate the pseudoinverse.
You need to understand all of the implications of what you're writing and make sure that you use the right functions if you're going to guarantee good code. For example:
For the first case, use realsqrt instead
For the second case, use inv(A) * b instead
Or alternatively, include the appropriate checks before/after you call the built-in functions. If you need to do this every time, then you can always write your own functions.