I'm trying to compute the Goodness of Fit of a bi-modal Gaussian distribution.
To do this, Mathematica seems to require a symbolic distribution function to which to compare.
Because such a bi-modal distribution is not a stock distribution, I'm trying to define one.
The obvious use of
MixtureDistribution[{fs,(1-fs),{NormalDistribution[\[mu]S,\[sigma]S],NormalDistribution[\[mu]L,\[sigma]L]}]
generates a distribution that can be plotted, but the analysis used by DistributionFitTest[] fails.
This topic has been addressed in previous questions in discussions between #Sasha and #Jagra:
DistributionFitTest[] for custom distributions in Mathematica
Minimizing NExpectation for a custom distribution in Mathematica
but I was unable to find a resolution that enabled the use of
DistributionFitTest[data,dist,"HypothesisTestData"]
when dist is not a built-in distribution type.
Because the distribution I'm modeling is composed of simple pieces, describing the properties of the distribution is not too difficult, and I have attempted to describe as many features as I know in order to create a well defined distribution that Mathematica 8 would recognize as one of its own. My attempt to define every parameter I can think of follows:
modelDist /:
PDF[modelDist[fS_, \[Mu]S_, \[Sigma]S_, \[Mu]L_, \[Sigma]L_], x_] :=
PDF[MixtureDistribution[{fS, 1 - fS}, {NormalDistribution[\[Mu]S, \[Sigma]S], NormalDistribution[\[Mu]L, \[Sigma]L]}], x];
modelDist /:
CDF[modelDist[fS_, \[Mu]S_, \[Sigma]S_, \[Mu]L_, \[Sigma]L_], x_] :=
CDF[MixtureDistribution[{fS, 1 - fS}, {NormalDistribution[\[Mu]S, \[Sigma]S], NormalDistribution[\[Mu]L, \[Sigma]L]}], x];
modelDist /:
DistributionDomain[modelDist[fS_, \[Mu]S_, \[Sigma]S_, \[Mu]L_, \[Sigma]L_]] :=
Interval[{-Infinity, Infinity}];
modelDist /:
Random`DistributionVector[modelDist[fS_, \[Mu]S_, \[Sigma]S_, \[Mu]L_, \[Sigma]L_], n_, prec_] :=
RandomVariate[MixtureDistribution[{fS, 1 - fS}, {NormalDistribution[\[Mu]S, \[Sigma]S], NormalDistribution[\[Mu]L, \[Sigma]L]}], n, WorkingPrecision -> prec];
modelDist /:
DistributionParameterQ[modelDist[fS_, \[Mu]S_, \[Sigma]S_, \[Mu]L_, \[Sigma]L_]] :=
!TrueQ[Not[Element[{fS, \[Mu]S, \[Sigma]S, \[Mu]L, \[Sigma]L}, Reals] && fS > 0 && fS < 1 && \[Sigma]S > 0 && \[Sigma]L > 0]];
modelDist /:
DistributionParameterAssumptions[modelDist[fS_, \[Mu]S_, \[Sigma]S_, \[Mu]L_, \[Sigma]L_]] :=
Element[{fS, \[Mu]S, \[Sigma]S, \[Mu]L, \[Sigma]L}, Reals] && fS > 0 && fS < 1 && \[Sigma]S > 0 && \[Sigma]L > 0;
modelDist /:
MomentGeneratingFunction[modelDist[fS_, \[Mu]S_, \[Sigma]S_, \[Mu]L_, \[Sigma]L_], t_] :=
fS E^(t \[Mu]S + (t^2 \[Sigma]S^2)/2) + (1 - fS) E^(t \[Mu]L + (t^2 \[Sigma]L^2)/2);
modelDist /:
CharacteristicFunction[modelDist[fS_, \[Mu]S_, \[Sigma]S_, \[Mu]L_, \[Sigma]L_], t_] :=
fS E^(I t \[Mu]S + (t^2 \[Sigma]S^2)/2) + (1 - fS) E^(I t \[Mu]L + (t^2 \[Sigma]L^2)/2)
modelDist /:
Moment[modelDist[fS_, \[Mu]S_, \[Sigma]S_, \[Mu]L_, \[Sigma]L_], n_] :=
Piecewise[{{fS*\[Sigma]S^n*(-1 + n)!!*Hypergeometric1F1[-(n/2), 1/2, -(\[Mu]S^2/(2*\[Sigma]S^2))] + (1 - fS) * \[Sigma]L^n*(-1 + n)!! * Hypergeometric1F1[-(n/2), 1/2, -(\[Mu]L^2/(2*\[Sigma]L^2))], Mod[n, 2] == 0}}, \[Mu]S*\[Sigma]S^(-1 + n)*n!!* Hypergeometric1F1[(1 - n)/2, 3/2, -(\[Mu]S^2/(2*\[Sigma]S^2))] + (1 - fS) * \[Mu]L*\[Sigma]L^(-1 + n)*n!! * Hypergeometric1F1[(1 - n)/2, 3/2, -(\[Mu]L^2/(2*\[Sigma]L^2))]];
modelDist /:
Mean[modelDist[fS_, \[Mu]S_, \[Sigma]S_, \[Mu]L_, \[Sigma]L_]] :=
fS \[Mu]S + (1 - fS) \[Mu]L
modelDist /:
Expectation[expr_, x_ \[Distributed] modelDist[fS_, \[Mu]S_, \[Sigma]S_, \[Mu]L_, \[Sigma]L_]] :=
fS*Expectation[expr, x \[Distributed] NormalDistribution[\[Mu]S, \[Sigma]S]] + (1 - fS)*Expectation[expr, x \[Distributed] NormalDistribution[\[Mu]L, \[Sigma]L]]
Everything seems to work up through the definition of Expectation, which throws
TagSetDelayed::tagpos: Tag modelDist in Expectation[expr_,x_\[Distributed]modelDist[fS_,\[Mu]S_,\[Sigma]S_,\[Mu]L_,\[Sigma]L_]] is too deep for an assigned rule to be found.
I don't know that having a definition for the expectation will magically make everything work, but it's the next step to to try, as having the Expectation allows computation of the Variance, and for all I know, that is the last tag that I need to define. Is there a syntax that will properly define this Expectation[] and pass the expression straight from my modelDist[] to its constituent NormalDistribution[]s?
(And if this entirely the wrong way to go about this, some advice to that effect would be appreciated.)
Related
I have several places in my script where I work with version numbers:
Scenario 1
#define AppVerText() \
GetVersionComponents(SourceDir + '\Meeting Schedule Assistant.exe', \
Local[0], Local[1], Local[2], Local[3]), \
Str(Local[0]) + "." + Str(Local[1]) + "." + Str(Local[2])
Scenario 2
{ Is the installed version at least 14.14 ? }
Result := (Major < 14) or
((Major = 14) and ((Minor < 14) or
((Minor = 14) and ((Bld < 26429) or
((Bld = 26429) and (Rbld < 3))))));
if (Result) then
The various values were extracted from registry keys.
Scenario 3
{ Check Windows Version }
WindowsVersion := GetWindowsVersion;
Log(Format('Windows Version: %x', [WindowsVersion]));
(* Windows must be Win 7 SP1 (6.1.7601), Win 8.1 (6.3.9200) or higher,
eg: Win 10 (10.0.10240)
See: http://www.jrsoftware.org/ishelp/index.php?topic=winvernotes
Microsoft .Net Framework 4.6.2 will only work with these operating systems. *)
if (WindowsVersion < MakeVersion(6, 1, 7601)) or
((WindowsVersion >= MakeVersion(6, 2, 0)) and
(WindowsVersion < MakeVersion(6, 3, 0))) then
begin
MsgBox(SetupMessage(msgWindowsVersionNotSupported), mbError, MB_OK);
Result := False;
end;
Which calls:
function MakeVersion(Major, Minor, Build: Cardinal): Cardinal;
begin
Result := (Major shl 24) + (Minor shl 16) + Build;
end;
I just wondered if we were able to make use of the new "version" Pascal functions etc. introduced in Inno Setup 6.1?
You can make use of ComparePackedVersion function (together with PackVersionComponents):
Result :=
(ComparePackedVersion(
PackVersionComponents(Major, Minor, Bld, Rbld),
PackVersionComponents(14, 14, 26429, 3)) < 0);
It's not much improvement in terms of code length. But it's way less error prone and easier to understand.
I believe it's actually safe to compare the packed versions numbers directly (at least unless your major version is not higher than 2^15). Though PackVersionComponents discourages that.
Result :=
(PackVersionComponents(Major, Minor, Bld, Rbld) <
PackVersionComponents(14, 14, 26429, 3));
Related question: Compare version strings in Inno Setup
For the Windows version test, you can combine that with GetWindowsVersionEx:
GetWindowsVersionEx(WinVer);
WinVerPacked := PackVersionComponents(WinVer.Major, WinVer.Minor, WinVer.Build, 0);
if (ComparePackedVersion(WinVerPacked, PackVersionComponents(6, 1, 7601, 0)) < 0) or
((ComparePackedVersion(WinVerPacked, PackVersionComponents(6, 2, 0, 0)) >= 0) and
(ComparePackedVersion(WinVerPacked, PackVersionComponents(6, 3, 0, 0)) < 0)) then
begin
MsgBox(SetupMessage(msgWindowsVersionNotSupported), mbError, MB_OK);
Result := False;
end;
And similarly as above, this should work too:
if (WinVerPacked < PackVersionComponents(6, 1, 7601, 0)) or
((WinVerPacked >= PackVersionComponents(6, 2, 0, 0)) and
(WinVerPacked < PackVersionComponents(6, 3, 0, 0))) then
There's nothing to be improved on your first scenario.
My problem is simple.
I am searching a mathematical function to distribute number over an interval.
For example I have this list :
[2; 4; 9; 14]
And in my case I wish
2 -> 1 = f(2)
14 -> 20 = f(14)
4 -> f(4) = ?
9 -> f(9) = ?
This is just an example I am searching for f(x).
Someone would have any idea ?
Thanks for advance ! :)
If you want a linear function, then:
f(x) = lowerFunc + (x - lowerX) * (upperFunc - lowerFunc) / (upperX - lowerX),
where:
lowerFunc: function value at the lower end
upperFunc: function value at the upper end
lowerX: x parameter at the lower end
upperX: x parameter at the upper end.
For your example:
f(x) = 1 + (x - 2) * (20 - 1) / (14 - 2)
= 1 + (x - 2) * 19/12
f(2) = 1
f(4) = 4.1666
f(9) = 12.08333
f(14) = 20
I'm trying to convert, just for fun, a code listing written in a language called Seed7 into Python. I've got it just about to beta phase, except for one part. This is the extract of the Seed7 listing:
x1 := flt(column) + 0.5;
y1 := flt(row) + 0.5;
angle := (course - 1.0) * 0.785398;
delta_x := cos(angle);
delta_y := -sin(angle);
inquad := TRUE;
blocked := FALSE;
number := 1;
while number <= distance do
y1 := y1 + delta_y;
x1 := x1 + delta_x;
row := trunc(y1);
column := trunc(x1);
if column < 1 or column > 8 or row < 1 or row > 8 then
inquad := FALSE;
number := distance;
else
if sect[row][column] <> 1 then (* Object blocking move *)
blocked := TRUE;
number := distance;
end if;
end if;
incr(number);
end while;
Which all makes sense, except for the fact that I don't understand how the functions cos() and sin() work in Seed7.
The manual says:
sin
const func float: sin (in float: x)
Compute the sine of x, where x is given in radians.
Returns:
the trigonometric sine of an angle.
but I can't make the equivalent in Python.
This problem is purely one caused by me not understanding Python properly (and not really being that great with maths either), so I come here to ask someone who does understand these things.
What code is required to make the above code work in Python? Help!!! :-)
Many thanks,
Joseph.
Edit: I think the problem is the incr() function. Basically, it is possible to warp in this game less than 1. From the help files:
writeln("Warp - One warp moves you the width of a quadrant. A warp of .5 will move you");
writeln("halfway through a quadrant. Moving diagonally across a quadrant to the next");
writeln("will require 1.414 warps. Warp 3 will move you 3 quadrants providing nothing");
writeln("in your present quadrant blocks your exit. Once you leave the quadrant that");
writeln("you were in, you will enter hyperspace; coming out of hyperspace will place you");
writeln("randomly in the new quadrant. Klingons in a given quadrant will fire at you");
writeln("whenever you leave, enter, or move within the quadrant. Entering a course or");
writeln("warp of zero can be used to return to the command mode.")
My code looks like this:
x1 = float(column) + 0.5
y1 = float(row) + 0.5
angle = (course - 1.0) * 0.785398
deltaX = math.cos(angle)
deltaY = -math.sin(angle)
inQuad = True
blocked = False
num = 1
while num <= distance:
y1 += deltaY
x1 += deltaX
row = int(round(y1))
column = int(round(x1))
if column < 0 or column > 7 or row < 0 or row > 7:
inQuad = False
num = distance
else:
if sect[row][column] != 1:
blocked = True
num = distance
num += 1
The thing is I'm using num+=1 at the end there, as opposed to incr, but I don't understand incr. As I have said, I've been a bit long out of the game, and certain things are really catching me out.
Any help in shining a light would be appreciated.
Joseph.
A guess:
If Seed7 expects radians, you may need to convert degrees to radians before applying sin or cos:
import math
math.sin(math.radians(1))
I have seen this code for the SRL6 Simba scripting language based on Delphi
dist:= hypot(xs - xe, ys - ye);
wind:= minE(wind, dist);
if (dist < 1) then
dist := 1;
PDist := (dist/TDist);
And
if (getSystemTime() > t) then
break;
dist:= hypot(xs - xe, ys - ye);
wind:= minE(wind, dist);
Really, we are focusing on the bottom line of the last snippet - minE(..). What could this function mean? I know it's mathematical, and yes I've Googled for an hour with no avail! Thanks for the help
MinE is only a wrapper for extended values. As seen in this example:
function ps_MinE(a, b : extended) : extended; extdecl;
begin
result := min(a,b);
end;
Consider the following list :
dalist = {{47.9913, 11.127, 208}, {47.5212, 10.3002, 208},
{49.7695, 9.96838, 160}, {48.625, 12.7042, 436}}
Those are coordinatees of Eye fixations on a screen where, within each sublist,
#1 is the X coordinate,
#2 the Y coordinate and
#3, the duration spent at that particular location
I then use the following :
Disk[{#[[1]], #[[2]]}, 3N[#[[3]]/Total[dalist[[All, 3]]]]] & /# dalist
to draw disk with duration weighted diameter.
I would like to draw cross instead where the 2 segments intersect at their middle and the length of each is equivalent to the disk diameter as illustrated bellow.
This is what I have yet :
Graphics[{
Line[{{#[[1]] - 3 N[#[[3]]/Total[dalist[[All, 3]]]], #[[2]]},
{#[[1]] + 3 N[#[[3]]/Total[dalist[[All, 3]]]], #[[2]]}}] & /# dalist,
Line[{{#[[1]], #[[2]] - 3 N[#[[3]]/Total[dalist[[All, 3]]]]},
{#[[1]], #[[2]] + 3 N[#[[3]]/Total[dalist[[All, 3]]]]}}] & /# dalist}]
I was wondering if there was a simpler way, using something similar to PlotMarkers that exist in ListPlot
Use two lines. Something like:
pointTrans =
{
Line[{{#[[1]] - l, #[[2]]}, {#[[1]] + l, #[[2]]}}],
Line[{{#[[1]], #[[2]] - l}, {#[[1]], #[[2]] + l}}]
} /. l -> #[[3]]/Mean[dalist[[All, 3]]] &;
pointTrans /# dalist // Graphics // Show
As you can already draw the circles, why not just use that like so:
circles=Graphics[Disk[{#[[1]], #[[2]]}, 3 N[#[[3]]/Total[dalist[[All, 3]]]]] & /# dalist]
and then
circles /. Disk[{x_, y_}, r_] :> Line[{{{x, y - r/2}, {x, y + r/2}}, {{x - r/2, y}, {x + r/2, y}}}]
giving
I think a little helper function is convenient here:
makeCross[{x_, y_, r_}, total_] := With[{scale = 3*r/total},
Line[{{{x - scale, y}, {x + scale, y}}, {{x, y - scale}, {x, y + scale}}}]]
total = Total[dalist[[All, 3]]];
Graphics[makeCross[#, mean] & /# dalist]
You could also use BubbleChart:
plus[{x:{x0_, x1_}, y:{y0_, y1_}}, __] :=
Line[{{{x0, Mean[y]}, {x1, Mean[y]}}, {{Mean[x], y0}, {Mean[x], y1}}}]
BubbleChart[dalist, ChartElementFunction -> plus] (*or maybe "MarkerBubble" instead of plus*)
I would like to offer this modification of Artefacto's code.
pointTrans =
With[{l = #3/2/Mean#dalist[[All, 3]]},
Line#{{{# - l, #2}, {# + l, #2}}, {{#, #2 - l}, {#, #2 + l}}}
] &;
Graphics[{Thick, pointTrans ### dalist}]