4
$\begingroup$

I have a function,

f[dist_, samp_]:=somework[dist, samp]

that I want to return Null or zero if passed a null distribution. I can't find a way to test for a difference between Null and Data distribution: none of ===, =!=, SameQ and == can identify them.

How can I tell if I'm being passed a Null value to handle it correctly?

f[dist_, samp_]:=something[dist, samp] /; TrueQ[dist==DataDistribution]

Seems to be close to what I want.

EDIT: Edited for some clarity.

Here's my function. If probKern is a Null, I want to return a Null, otherwise, I want to calculate the PDF for the sample, with the distribution. I can't quite get a handle on matching the types to make this work though.

calcPDF[probKern_, samp_] := 
 Null /; TrueQ[probKern != DataDistribution]

calcPDF[probKern_Symbol, samp_] := 
 PDF[probKern, samp] /; TrueQ[probKern == DataDistribution]

edit: Okay, I'm still having trouble with this. Here's what I have:

calcPDF[probKern_DataDistribution, samp_] := PDF[probKern, samp]  
calcPDF[Except[_DataDistribution, probkern_?DistributionParameterQ], samp_] := -1 
calcPDF[_] := $Failed

Given a data distribution and a value it works fine.

In[38]:= calcPDF[data, 3]

Out[38]= 0.007500611755

Given two numbers, it produces the symbolic value, rather than the -1 I was expect. (The -1 is just a placeholder)

In[39]:= calcPDF[3, 3]

Out[39]= calcPDF[3, 3]

EDIT dec 5th: Running calcPDF by hand seems to result in correct results, but now, when it is threaded over data, the result is a single result of whatever you return in the Except case. There's two sets of distributions I'm running over the sample data, so the final result is a list of two Nulls (or -1's).

If you remove the Except case, you get closer to the expected result - two lists 205 elements long, containing PDF's for entries with matching Distributions, and PDF[Null, value] for those without.

I'm confused.

Clear[calcPDF] (*calcPDF[probKern_, samp_]:=PDF[probKern, samp]; *) calcPDF[probKern_DataDistribution, samp_] := PDF[probKern, samp]; calcPDF[Except[DataDistribution], samp] := Null;

(* Pass a list of samples, and a list of distributions's *)

applyKernel[lsamples_, kernel_] := Thread[calcPDF[kernel, lsamples]];

(* Pass a list of samples, and a list of two lists of distribution's *)

predClass[samples_, kernels_] := Map[applyKernel[samples, #] &, kernels]; predPDF = predClass[predictionSamples[[1]], kernels]

$\endgroup$
  • 1
    $\begingroup$ What is a null distribution? $\endgroup$ – Sjoerd C. de Vries Dec 4 '12 at 21:29
  • $\begingroup$ f[dist_, samp_]:=something[dist, samp] /; TrueQ[dist==DataDistribution] Seems to do the trick. if my function isn't passed a valid Data Distribution it falls through to the default case. $\endgroup$ – user4860 Dec 4 '12 at 22:01
  • $\begingroup$ Your question is a bit cryptic. Do you mean perhaps that you want to test whether dist is either a distribution that belongs to your null hypothesis or a DataDistribution? For comparing distributions we have DistributionFitTest. $\endgroup$ – Sjoerd C. de Vries Dec 4 '12 at 22:01
  • $\begingroup$ Sorry, I'm looking to test whether dist is a DataDistribution or otherwise (I'm passing null myself). If it's a data distribution, I want to use it in a PDF. Otherwise, I want to pass on a Null value. as it stands when mathematica comes across the Null value, it passes on PDF[Null, some value]. $\endgroup$ – user4860 Dec 4 '12 at 22:31
  • $\begingroup$ Steven, you can format blocks of code by selecting them and pressing the { } button above the text box while editor your post. See Editing Help for more. $\endgroup$ – Mr.Wizard Dec 5 '12 at 6:58
9
$\begingroup$

I think you are wanting something like the following.

For a function that does something with a DataDistribution something else with any other distribution and otherwise fails we would do.

f[dist_DataDistribution]:= "do stuff"
f[Except[_DataDistribution, dist_?DistributionParameterQ]]:= "do other stuff"
f[_]:= $Failed

Now if you want to match a particular DataDistribution, say KernelMixtureDistribution you will need to give it that information in your pattern.

g[dist:DataDistribution["KernelMixture",___]]:= "do stuff"
g[Except[_DataDistribution, dist_?DistributionParameterQ]]:= "do other stuff"
g[_]:= $Failed

Edit:

I believe your confusion comes from what == is doing in your checks. When you try dist == DataDistribution you are asking if a particular object dist is the symbol DataDistribution. What you really want to know is whether the Head of dist is DataDistribution.

Edit 2:

Lets say you wanted to use this approach to compute CDF for distributions returning -1 if the computation isn't possible. You could set this up as.

cdf[dist_?DistributionParameterQ, x_]:= CDF[dist,x]
cdf[_,x_]:= -1

If you want separate treatment for DataDistribution say you can do that as well. Here I'm telling it to report what type of distribution was used and return the expression and -1 if it isn't a distribution.

cdf[dist_DataDistribution?DistributionParameterQ, x_]:= {dist["Type"], CDF[dist,x]}
cdf[dist_?DistributionParameterQ, x_]:= {Head[dist], CDF[dist,x]}
cdf[notAValidDist_, x_]:= {notAValidDist, -1}
$\endgroup$
  • $\begingroup$ This is absolutely what I want to do. At a later time I'll be doing different things based on the distribution. But for now, just answering the question is this a distribution or not gets me 95% of the way there. $\endgroup$ – user4860 Dec 4 '12 at 22:39
  • $\begingroup$ I'm still having trouble with this. What you have looks like it should work, but in test cases it doesn't. I'm sure I'm misunderstanding something though. $\endgroup$ – user4860 Dec 5 '12 at 5:04
  • $\begingroup$ Is there any way to make a fallthrough for not a distribution, rather than matching specific types (like numericQ). I thought of matching Numeric, string, etc but that seemed like a hacky way to go. $\endgroup$ – user4860 Dec 5 '12 at 17:20
  • $\begingroup$ This is what I have in the end. It seems far too messy for what it should be. There's no negation in the type pattern matching available is there? Something like ?!DataDistribution? calcPDF[probKern_DataDistribution, samp_] := PDF[probKern, samp] calcPDF[probKern_?NumericQ, samp_] := -1 calcPDF[probKern_?StringQ, samp_] := -1 calcPDF[probKern_?ListQ, samp_] := -1 $\endgroup$ – user4860 Dec 5 '12 at 18:28
  • $\begingroup$ Yes, that is too messy. If you want it to return -1 for anything that isn't a DataDistribution just replace your last 3 definitions with calcPDF[Except[_DataDistribution],samp_]:= -1. $\endgroup$ – Andy Ross Dec 5 '12 at 18:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy