distribution of a vector (U,V) - statistics

I'm struggling with the following statistics exercise, any help would be really appreciated
find the distribution of the vector (U,V) given that
U = X*Y and V = (1-X)*Y
X and Y are independent
X assumes beta distribution with parameters (a1,a2)
Y assumes chi-squared distribution with parameter 2*(a1+a2)

Related

Fitting of GLM with statsmodels

Python's statsmodels module offers a set of methods to estimate GLM as illustrated in https://www.statsmodels.org/devel/examples/notebooks/generated/glm.html
e.g.
glm_binom = sm.GLM(data.endog, data.exog, family=sm.families.Binomial())
What is the link function in above example? Is it logit link? How can I use other link like loglog?
I tried below without any success
glm_binom = sm.GLM(data.endog, data.exog, family=sm.families.Binomial(link = 'loglog'))
Any pointer will be very helpful
In the latest statsmodels stable release (currently v0.13.2), only the following link functions are available for each sm.families.family:
Family
ident
log
logit
probit
cloglog
pow
opow
nbinom
loglog
logc
Gaussian
X
X
X
X
X
X
X
X
X
Inv Gaussian
X
X
X
Binomial
X
X
X
X
X
X
X
X
X
Poisson
X
X
X
Neg Binomial
X
X
X
X
Gamma
X
X
X
Tweedie
X
X
X
Alternatively, the list of available link functions can be obtained by:
sm.families.family.<familyname>.links
Lastly, in order to change the default link function of the GLM in statsmodels you need to specify the link parameter in the family parameter:
sm.GLM(y, X, family=sm.families.Binomial(link=sm.families.links.loglog()))
P.S. The default link for the Binomial family is the logit link.

Haskell Store Data As Algorithm progresses

Say I had a Haskell algorithm which, through recursion, progressed through a Cartesian plane where each x/y coordinate had a specific value.
Position (0,0) is known, each other can be calculated by progressing back to the origin.
For example, to look at (0,3) I need to look at (-1,2), (0,2) and (1,2), which have to look in turn at (-2,1),(-1,1),(0,1) and (-1,1),(0,1),(1,1) and (0,1),(1,1),(2,1) respectively.
In order to avoid for (-1,1) and (0,1) to be calculated twice, is there any way I can create a data structure so that the algorithm can first look to see if a certain position ahs been calculated already and, if not, only then proceeds to calculating it?
Thanks :)
It sounds like memoization as m09 and cdk suggest might be what you're looking for. But if you want an algorithm that returns an array of positions, then simple boxed arrays (meaning they hold lazy values) and some knot tying can give you a nice declarative solution (sorry for the ugly code)
import Data.Array
-- for positive u
plane :: Int -> Array (Int,Int) Int
plane u = let knownOrigin = ((0,0) , 0)
l = negate u
otherCoords = [ (x,y) | let cs = [l .. u]
, x <- cs , y <- cs
, (x,y) /= (0,0)
]
a = array ((l,l),(u,u)) $
knownOrigin : map solution otherCoords
-- example recursive thing, referenceing lazy values in 'a':
solution c#(x,y) = let x' | x <0 = x+1
| x >0 = x-1
| x==0 = 0
y' | y <0 = y+1
| y >0 = y-1
| y==0 = 0
in (c , a ! (x',y') + 1)
in a
You could also use a Map or vector, or any other lazy structure that works best for your problem.

Conjugate Gradient method convergence

I have written both Gauss Seidel and Conjugate Gradient iterative algorithms for solving matricies in Haskell (but this question is related to the methods not so much the language). My understanding was that both of these algorithms should have similar convergence characteristics and that the CG method should be faster in most cases. I have run many tests on symmetric positive definite matrices from http://math.nist.gov/MatrixMarket/ and I can almost never get the CG alg. to converge, while the GS almost always does. I cannot find any symmetric positive definite matrices with an accompanying right hand side vector for testing purposes online, so I have been just arbitrarily creating my own RHS (maybe this is part of the problem?). I can get the CG method to converge if I use (transpose A) * A instead of A in Ax = b, which is just forcing the matrix to be symmetric. I have included the CG code here. It will obviously not compile as-is. If someone needs it functioning to help, I will post it all. It is working correctly for the simple example here (Similar question) that came from (Pseudocode and example). Is there something I'm missing regarding Conjugate Gradient vs. Gauss Seidel Convergence criteria? Can anyone point me in the right direction to get this working? Thanks.
conjGrad :: (Floating a, Ord a, Show a) => a -> SpMCR a -> SpVCR a -> SpVCR a -> (SpVCR a, Int)
conjGrad tol mA b x0 = loop x0 r0 r0 rs0 1
where r0 = b - (mulMV mA x0)
rs0 = dot r0 r0
loop x r p rs i
| (varLog "residual = " $ sqrt rs') < tol = (x',i)
| otherwise = loop x' r' p' rs' (i+1)
where mAp = mulMV mA p
alpha = rs / (dot p mAp)
x' = x + (alpha .* p)
r' = r - (alpha .* mAp)
rs' = dot r' r'
beta = rs' / rs
p' = r' + (beta .* p)
(.*) :: (Num a) => a -> SpVCR a -> SpVCR a
(.*) s v = fmap (s *) v
EDIT : Sure enough, I failed to account for the fact that the MM file format only includes the lower diagonal of a symmetric matrix. Thanks. Now the algorithm converges but seems to take more iterations than it should. My understanding was that CG should always converge with a number of iterations less than the matrix order, when using exact arithmetic. Would the fact that were working with floating point (Double) make such a big difference (1.5 - 2 x the matrix order being the iterations required to reasonably converge) ?
Follow Up: For anyone who might stumble upon this, it turns out most of my problem was related to the matrices that I was using for the tests. It seems they were rather ill-conditioned for solving using the CG algorithm. Simple preconditioning helped in some cases.
You can answer your second question by using an exact library with floating such as CReal from here: http://hackage.haskell.org/package/numbers or getting rid of your logging (which I think is what introduces the floating constraint) and just using the rationals from Data.Ratio.
This will of course be terribly slow. But it should let you investigate the impact of floating point approximation on convergence.

How can I sample from a complex or compound distribution in Haskell?

I'm trying to generate random masses for hypothetical planets in Haskell. I want to produce these masses by sampling a bi-modal distribution (ideally the superposition of two normal distributions: one corresponding to small planets and one corresponding to gas giants). I've looked at the statistics package, which provides the quantile function, which can turn a uniformly distributed Double into a Double on a number of distributions. But there doesn't seem to be any support for composing distributions.
This particular case could be hacked around by picking one distribution or the other to sample before-hand, but I'd like to do it with a single distribution, especially since I might need to tweak the overall distribution later. Eventually I might replace the normal distribution with real data from sky surveys.
I'm considering implementing rejection sampling myself, which can handle arbitrary distributions fairly simply, but it seems rather inefficient, and it certainly wouldn't be a good idea to implement it if a solution exists already as a library.
Is there a Haskell library that supports sampling from composed or explicitly specified distributions? Or an existing Haskell implementation of rejection sampling? Alternatively, is there an explicit formula for the inverse of the CDF of the sum of two normal distributions?
In the case of a simple mixture of distributions, you can get an efficient sampler via the 'hack' you first mentioned:
This particular case could be hacked around by picking one distribution or the other to sample before-hand, but I'd like to do it with a single distribution, especially since I might need to tweak the overall distribution later.
This is actually a case of Gibbs sampling, which is very prevalent in statistics. It's very flexible, and if you know the number of mixtures you're using, it will probably be hard to beat. Choose one individual distribution from the entire ensemble to sample from, and then sample from that conditional distribution. Rinse and repeat.
Here's a simple, unoptimized Haskell implementation for a mixture-of-Gaussians Gibbs sampler. It's pretty basic, but you get the idea:
import System.Random
import Control.Monad.State
type ModeList = [(Double, Double)] -- A list of mean/stdev pairs, for each mode.
-- Generate a Gaussian (0, 1) variate.
boxMuller :: StdGen -> (Double, StdGen)
boxMuller gen = (sqrt (-2 * log u1) * cos (2 * pi * u2), gen'')
where (u1, gen') = randomR (0, 1) gen
(u2, gen'') = randomR (0, 1) gen'
sampler :: ModeList -> State StdGen Double
sampler modeInfo = do
gen <- get
let n = length modeInfo
(z0, g0) = boxMuller gen
(c, g1) = randomR (0, n - 1) g0 -- Sample from the components.
(cmu, csig) = modeInfo !! c
put g1
return $ cmu + csig * z0 -- Sample from the conditional distribution.
Here's a example run: sampling 100 times from a one-dimensional mixture of two Gaussians. The modes are at x = -3 and x = 2.5, and each mixture component has its own separate variance. You could add as many modes as you want here.
main = do
let gen = mkStdGen 42
modeInfo = [(2.5, 1.0), (-3, 1.5)]
samples = (`evalState` gen) . replicateM 100 $ sampler modeInfo
print samples
Here's a smoothed density plot of those 100 samples (using R and ggplot2):
A more general purpose algorithm would be a rejection or importance sampler, and in the case of more complicated distributions you're probably going to want to hand-roll an appropriate MCMC routine. Here is a good introduction to Monte Carlo and MCMC.
Hmmmm. The best way I'm familiar with is to adapt the MonadRandom package to get a "probability monad", borrowing some tools from http://en.wikipedia.org/wiki/Normal_distribution#Generating_values_from_normal_distribution :
getRandomStrictlyBetween :: (Ord a, Random a, RandomGen m) =>
(a, a) -> a
getRandomStrictlyBetween (lo, hi) = do
x <- getRandomR (lo, hi)
-- x is uniformly randomly chosen from the *closed* interval
if lo < x && x < hi then return x else getRandomStrictlyBetween (lo, hi)
normalValue :: MonadRandom m => m Double
normalValue = do
u <- getRandomStrictlyBetween (0, 1)
v <- getRandomStrictlyBetween (0, 2 * pi)
return (sqrt (-2 * log u) * cos v) -- according to Wikipedia
and then you can derive more or less arbitrary distributions; for example, to get the distribution of a random variable that is y with probability p and z with probability (1 - p), you just write
do alpha <- getRandom -- double chosen from [0, 1)
if alpha < p then y else z
of which bimodal distributions appear to be a special case. To sample from these distributions, just do evalRandIO distribution to sample in the IO monad.

Graph representation in Haskell

I have chosen to represent a graph in Haskell by a list of nodes (ex. n=[1,2,3,4]) and a list of pairs representing the edges (example m=[(1,2), (2,3)]). Now I have to see if the graph is strongly connected.
My main issue is how to find if there is a way between 2 nodes in the graph. I wrote something like that:
-- sees if 2 nodes are adjacent
adjacent x y [] = False
adjacent x y (mu:m) =
if(x== (fst mu) && y==(snd mu)) then True
else adjacent x y m
-- the successor of a node, ex for the edge (1,2) the succ of 1 is 2
suc x [] = 0
suc x (l:list) =
if(x==(fst l)) then snd l
else suc x list
-- my main function
way 0 y list = False
way x y (mu:m)
| x==y = True
| (adjacent x y (mu:m)) == True = True
| otherwise =
if ((way (suc x (mu:m)) y (mu:m))==False) then way (suc x m) y m
else True
It works when I have nodes of degree 1, but for the nodes with a greater degree it doesn't always work. Can you give me a clue about it?
Here are some questions to ask yourself:
Should adjacent 3 2 [(1,2),(2,3)] be True?
How many successors to 1 are there in the graph [(1,2),(2,3),(1,4),(3,4)]
Why does, or doesn't, way need to have both a x==y case and an adjacent x y ... case?
In the recursion step of way does the == False test really tell you something that lets you recurse on the smaller graph of m?
In general, you haven't written type signatures for your top level functions. It is usually very instructive to do so, and will communicate your design more clearly:
type Vertex = Int
type Edge = (Vertex, Vertex)
type Graph = [Edge]
adjacent :: Vertex -> Vertex -> Graph -> Bool
suc :: Vertex -> Graph -> Vertex
way :: Vertex -> Vertex -> Graph -> Bool
Think about if those types make sense, and if they decompose your problem as you would expect, just thinking about graphs in general.
Is your aim really the way function, or is it to determine if the graph is connected? You might be presupposing too much about the way in which you can determine if the graph is connected.
Lastly, a small part about Haskell syntax: Like most other languages, function application binds very tightly, tighter than == and && operators. Unlike most other languages, function application doesn't use parenthesis. Hence, adjacent can be recoded as:
adjacent x y [] = False
adjacent x y (mu:m) =
if x == fst mu && y == snd mu then True
else adjacent x y m
Which in turn could be simplified to:
adjacent x y [] = False
adjacent x y (mu:m) = (x == fst mu && y == snd mu) || adjacent x y m
You have two errors of understanding:
m, your list of edges is static throughout the entire search. Don't eat it up as you recur in way.
Each vertex can have more than one edge leaving it. You want to know whether any of the neighbours of x has a way to y. To find the neighbours you first have to filter the list of edges to find only the edges leaving x.
You also need to build up a list of nodes you've already visited on your quest to find a connection. If you end up on a node you've already seen, then that particular path has failed.
Some hints to make your code a lot shorter: for adjacent, try elem.
For succ, try Data.Maybe.fromMaybe and lookup.

Resources