Advertisement
Guest User

Untitled

a guest
Oct 21st, 2014
170
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.70 KB | None | 0 0
  1. BeginPackage["PermanentCode`"];
  2.  
  3. Permanent::usage = "<
  4. Permanent[mArg_List/;MatrixQ[a]] is computed by Glynn's formula.
  5.  
  6. The algorithm requires O(m^2 2^m) operations, where m is the dimension
  7. of the matrix arg.
  8.  
  9. When the argument is numeric, compiled C-code is executed.
  10.  
  11. When the argument is non-numeric, a "Permanent::symbolic" message
  12. is issued, and the permanent is calculated symbolically.
  13.  
  14. Implementation Notes:
  15.  
  16. (1) Glynn's formula is simplified with a view to speed-by-simplicity
  17. (at negligible cost in formal efficiency); in brief the algorithm
  18. is implemented as a sequence of BLAS-compatible calls to built-in
  19. Mathematica (BLAS) functions.
  20.  
  21. (2) At present the algorithm does not fully exploit the Gray-code
  22. structure of the permutation list [Delta]PermutationList.
  23.  
  24. URL: http://en.wikipedia.org/wiki/Computing_the_permanent#Glynn_formula
  25. URL: http://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms>";
  26.  
  27. Permanent::symbolic = "<
  28. ADVISORY: Permanent[_] argument is a non-numeric `1`[Cross]`2` matrix>";
  29. On[Permanent::symbolic];
  30.  
  31. [Delta]PermutationList::usage = "<
  32. List of Gray-code permutations, saved in-memory
  33. for use by Permanent[_]'s Glynn formula.>";
  34.  
  35. classicalPermanent::usage = "<
  36. classicalPermanent[_] computes the matrix permanent
  37. (slowly!) by expansion of the index permutation
  38. >";
  39.  
  40. Begin["`Private`"];
  41.  
  42. classicalPermanent[mArg_] := Block[
  43. {rowList,colPerms},
  44. rowList = Table[i,{i,1,mArg//Length}];
  45. colPerms = rowList//Permutations;
  46. Map[
  47. (MapThread[mArg[[#1,#2]]&,{rowList,#}]//
  48. Times@@#&)&,
  49. colPerms
  50. ]//Plus@@#&
  51. ];
  52.  
  53. [Delta]PermutationList[1] = {{1}};
  54. [Delta]PermutationList[m_Integer]/;(m>1) := (
  55. (* Conserve memory by purging irrelevant DownValues.
  56. These rules may exist for arbitrarily large arguments,
  57. so a pattern-matched undefine "=." is applied *)
  58. ([Delta]PermutationList//DownValues)[[All,1]]//
  59. ReplaceAll[#,HoldPattern[[Delta]PermutationList[a_]]:>a]&//ReleaseHold//
  60. Select[#,(IntegerQ[#]&&(#!=1)&&(#!=m-1))&]&//
  61. Map[([Delta]PermutationList[#]=.;)&,#]&;
  62. (* now define-and-return the requested [Delta]PermutationList *)
  63. [Delta]PermutationList[m] = [Delta]PermutationList[m-1]//
  64. (* idiom: the pipe holds [Delta]PermutationList[m-1], so conserve
  65. memory by deleting its DownValue immediately *)
  66. (If[m>2,[Delta]PermutationList[m-1]=.;];#)&//(
  67. (* reflect DownValue[m-1] in Gray-code order *)
  68. Map[({1,1}~Join~(#//Rest))&,#] ~ Join ~
  69. Map[({1,-1}~Join~(#//Rest))&,#//Reverse]
  70. )&
  71. );
  72.  
  73. Permanent[ (* numeric evaluation *)
  74. mArg_List/;(MatrixQ[mArg,NumericQ])
  75. ] := compiledGlynnAlgorithm[
  76. [Delta]PermutationList[mArg//Length],
  77. mArg
  78. ]//Total[#[[1 ;; ;; 2]]] - Total[#[[2 ;; ;; 2]]]&//
  79. #/2^((mArg//Length)-1)&
  80.  
  81. compiledGlynnAlgorithm = Compile[{
  82. {d, _Integer, 1},
  83. {a, _Complex, 2}
  84. },
  85. Apply[Times,(d.a)],
  86. CompilationTarget -> "C",
  87. RuntimeAttributes -> {Listable},
  88. Parallelization -> True
  89. ];
  90.  
  91. Permanent[ (* symbolic evaluation *)
  92. mArg_List/;
  93. (
  94. MatrixQ[mArg] &&
  95. (!MatrixQ[mArg,NumericQ]) &&
  96. (mArg//Length//Message[Permanent::symbolic,#,#]&;True)
  97. )
  98. ] := Map[
  99. Apply[Times,(#.mArg)]&,
  100. [Delta]PermutationList[mArg//Length]
  101. ]//Total[#[[1 ;; ;; 2]]] - Total[#[[2 ;; ;; 2]]]&//
  102. #/2^((mArg//Length)-1)&;
  103.  
  104. End[];
  105. EndPackage[];
  106.  
  107. nPerm = 4;
  108. Table[[DoubleStruckCapitalC][i,j],{i,1,nPerm},{j,1,nPerm}]//
  109. Permanent[#]-classicalPermanent[#]&//
  110. Expand//
  111. If[
  112. #===0,
  113. Print["VALIDATED: ",nPerm,"[Cross]",nPerm," symbolic permanent"];,
  114. Print["ERROR: ",nPerm,"[Cross]",nPerm," symbolic permanent"];
  115. ]&;
  116.  
  117. nPerm = 5;
  118. Table[[DoubleStruckCapitalC][i,j],{i,1,nPerm},{j,1,nPerm}]//
  119. Permanent[#]-classicalPermanent[#]&//
  120. Expand//
  121. If[
  122. #===0,
  123. Print["VALIDATED: ",nPerm,"[Cross]",nPerm," symbolic permanent"];,
  124. Print["ERROR: ",nPerm,"[Cross]",nPerm," symbolic permanent"];
  125. ]&;
  126.  
  127. nPerm = 6;
  128. nPerm//{#,#}&//(
  129. 1*RandomVariate[NormalDistribution[0,1],#]+
  130. I*RandomVariate[NormalDistribution[0,1],#]
  131. )*1/Sqrt[2]&//
  132. {Permanent[#],classicalPermanent[#]}&//
  133. (#[[1]]-#[[2]])/Sqrt[#[[2]][Conjugate]*#[[2]]]&//
  134. If[
  135. Abs[#]<1000*10^(-$MachinePrecision),
  136. Print["VALIDATED: ",nPerm,"[Cross]",nPerm," compiled numeric permanent"];,
  137. Print["ERROR: ",nPerm,"[Cross]",nPerm," compiled numeric permanent"];
  138. ]&;
  139.  
  140. nPerm = 7;
  141. nPerm//{#,#}&//(
  142. 1*RandomVariate[NormalDistribution[0,1],#]+
  143. I*RandomVariate[NormalDistribution[0,1],#]
  144. )*1/Sqrt[2]&//
  145. {Permanent[#],classicalPermanent[#]}&//
  146. (#[[1]]-#[[2]])/Sqrt[#[[2]][Conjugate]*#[[2]]]&//
  147. If[
  148. Abs[#]<100*10^(-$MachinePrecision),
  149. Print["VALIDATED: ",nPerm,"[Cross]",nPerm," compiled numeric permanent"];,
  150. Print["ERROR: ",nPerm,"[Cross]",nPerm," compiled numeric permanent"];
  151. ]&;
  152.  
  153. Print["--------------"];
  154. Print["*** first Permanent[_] evaluation ***"];
  155. Do[
  156. nPerm//{#,#}&//(
  157. 1*RandomVariate[NormalDistribution[0,1],#]+
  158. I*RandomVariate[NormalDistribution[0,1],#]
  159. )*1/Sqrt[2]&//(
  160. (* first call stores Gray-code array *)
  161. (Permanent[#]//AbsoluteTiming)//First//1000*#&//Round//
  162. Print["Benchmark: Permanent[ ",nPerm,"[Cross]",nPerm," ] took ",#," ms"]&;
  163. )&;,{nPerm,20,12,-1}];
  164.  
  165. Print["--------------"];
  166. Print["*** second Permanent[_] evaluation ***"];
  167. Do[
  168. nPerm//{#,#}&//(
  169. 1*RandomVariate[NormalDistribution[0,1],#]+
  170. I*RandomVariate[NormalDistribution[0,1],#]
  171. )*1/Sqrt[2]&//(
  172. (* second call runs fast *)
  173. Permanent[#];
  174. (Permanent[#]//AbsoluteTiming)//First//1000*#&//Round//
  175. Print["Benchmark: Permanent[ ",nPerm,"[Cross]",nPerm," ] took ",#," ms"]&;
  176. )&;,{nPerm,20,12,-1}];
  177.  
  178. Print["--------------"];
  179. Print["*** (large) Permanent[ 25[Cross]25 ] evaluation ***"];
  180.  
  181. 25//{#,#}&//(
  182. 1*RandomVariate[NormalDistribution[0,1],#]+
  183. I*RandomVariate[NormalDistribution[0,1],#]
  184. )*1/Sqrt[2]&//(
  185. (Permanent[#]//AbsoluteTiming)//First//Round//
  186. Print["Benchmark: Permanent[ ",25,"[Cross]",25," ] took ",#," s"]&;
  187. (Permanent[#]//AbsoluteTiming)//First//Round//
  188. Print["Benchmark: Permanent[ ",25,"[Cross]",25," ] took ",#," s"]&;
  189. )&;
  190.  
  191. VALIDATED: 4[Cross]4 symbolic permanent
  192. VALIDATED: 5[Cross]5 symbolic permanent
  193. VALIDATED: 6[Cross]6 compiled numeric permanent
  194. VALIDATED: 7[Cross]7 compiled numeric permanent
  195. --------------
  196. *** first Permanent[_] evaluation ***
  197. Benchmark: Permanent[ 20[Cross]20 ] took 1908 ms
  198. Benchmark: Permanent[ 19[Cross]19 ] took 926 ms
  199. Benchmark: Permanent[ 18[Cross]18 ] took 428 ms
  200. Benchmark: Permanent[ 17[Cross]17 ] took 235 ms
  201. Benchmark: Permanent[ 16[Cross]16 ] took 120 ms
  202. Benchmark: Permanent[ 15[Cross]15 ] took 52 ms
  203. Benchmark: Permanent[ 14[Cross]14 ] took 22 ms
  204. Benchmark: Permanent[ 13[Cross]13 ] took 13 ms
  205. Benchmark: Permanent[ 12[Cross]12 ] took 8 ms
  206. --------------
  207. *** second Permanent[_] evaluation ***
  208. Benchmark: Permanent[ 20[Cross]20 ] took 250 ms
  209. Benchmark: Permanent[ 19[Cross]19 ] took 118 ms
  210. Benchmark: Permanent[ 18[Cross]18 ] took 55 ms
  211. Benchmark: Permanent[ 17[Cross]17 ] took 27 ms
  212. Benchmark: Permanent[ 16[Cross]16 ] took 16 ms
  213. Benchmark: Permanent[ 15[Cross]15 ] took 22 ms
  214. Benchmark: Permanent[ 14[Cross]14 ] took 10 ms
  215. Benchmark: Permanent[ 13[Cross]13 ] took 4 ms
  216. Benchmark: Permanent[ 12[Cross]12 ] took 1 ms
  217. --------------
  218. *** (large) Permanent[ 25[Cross]25 ] evaluation ***
  219. Benchmark: Permanent[ 25[Cross]25 ] took 75 s
  220. Benchmark: Permanent[ 25[Cross]25 ] took 11 s
  221.  
  222. compiledGlynnAlgorithmAlt = Compile[{
  223. {d, _Complex, 2}, {a, _Complex, 2}},
  224. Total@Map[Apply[Times, (#.a)*#] &, d],
  225. CompilationTarget -> "C",
  226. RuntimeAttributes -> {Listable},
  227. Parallelization -> True];
  228.  
  229.  
  230. n = 20;
  231. rc = RandomComplex[{-I - 1, I + 1}, {n, n}];
  232. a = compiledGlynnAlgorithmAlt[δGrayCodeList[n], rc]; // AbsoluteTiming
  233. b = compiledGlynnAlgorithm[δGrayCodeList[n], rc]; // AbsoluteTiming
  234. a == b
  235. (* {0.582192, Null} *)
  236. (* {0.690600, Null} *)
  237. (* True *)
  238.  
  239. δGrayCodeListSigns[n_] := δGrayCodeListSigns[n] = Times @@@ δGrayCodeList[n]
  240.  
  241. compiledGlynnAlgorithmKnownSign =
  242. Compile[{{d, _Integer, 2}, {a, _Complex, 2}, {s, _Integer, 1}},
  243. s.Map[ Apply[Times, (#.a)] &, d]
  244. , CompilationTarget -> "C"
  245. , RuntimeAttributes -> {Listable}];
  246.  
  247. n = 20;
  248. rc = RandomComplex[{-I - 1, I + 1}, {n, n}];
  249.  
  250. a = compiledGlynnAlgorithmAlt[δGrayCodeList[n], rc]; // AbsoluteTiming
  251. b = compiledGlynnAlgorithm[δGrayCodeList[n], rc]; // AbsoluteTiming
  252. c = compiledGlynnAlgorithmKnownSign[
  253. δGrayCodeList[n], rc, δGrayCodeListSigns[n]
  254. ]; // AbsoluteTiming
  255.  
  256. Abs[c - b]/Abs[b]
  257.  
  258. (* {0.565806, Null} *)
  259. (* {0.614640, Null} *)
  260. (* {0.430388, Null} *)
  261. (* 2.49266*10^-13 *)
  262.  
  263. compiledGlynnAlgorithm = Compile[{{d, _Integer, 1}, {a, _Complex, 2}},
  264. Apply[Times, (d.a) d],
  265. CompilationTarget -> "C", RuntimeAttributes -> {Listable}, Parallelization -> True]
  266.  
  267. Permanent[mArg_List /; (MatrixQ[mArg, NumericQ])] :=
  268. Total@compiledGlynnAlgorithm[δGrayCodeList[mArg // Length], mArg] //
  269. #/2^((mArg // Length) - 1) &;
  270.  
  271. compiledGlynnAlgorithm = Compile[{{d, _Integer, 1}, {a, _Complex, 2}},
  272. Apply[Times, (d.a)],
  273. CompilationTarget -> "C", RuntimeAttributes -> {Listable}, Parallelization -> True]
  274.  
  275. Permanent[mArg_List /; (MatrixQ[mArg, NumericQ])] :=
  276. Module[{x},
  277. x = compiledGlynnAlgorithm[δGrayCodeList[mArg // Length], mArg];
  278. (Total[x[[;; ;; 2]]] - Total[x[[2 ;; ;; 2]]]) // #/2^((mArg // Length) - 1) &]
  279.  
  280. permanentC =
  281. Compile[{{m, _Real, 2}}, With[{len = Length[m]}, (-1)^len*Module[
  282. {s = {0.}, u = 0.},
  283. Do[
  284. s = N[IntegerDigits[n, 2, len]];
  285. u += (-1)^Round[Total[s]]*(Times @@ (m.s)),
  286. {n, 2^len - 1}];
  287. u]], CompilationTarget -> "C"];
  288.  
  289. SeedRandom[11111];
  290. testmats = Table[RandomInteger[1, {n, n}], {n, 8, 20, 2}];
  291.  
  292. one-sample "A" K-S test: p = 0.837777
  293. one-sample "B" K-S test: p = 0.362924
  294. two-sample "AvsB" K-S test: p = 0.831093
  295.  
  296. (* ------------------------------------------------ *)
  297. (* --- set boson-sampling simulation parameters --- *)
  298. (* ------------------------------------------------ *)
  299.  
  300. nPhoton = 10; (* number of photons detected:
  301. n = 10 runs fast; n = 20 runs slow *)
  302. nSampleMax = 10^5; (* upper bound to matrix samples;
  303. nSampleMax >= 10^5 is recommended *)
  304. tSampleMax = 24*3600; (* time-used upper bound in seconds *)
  305. kSample = 32; (* number of Kolmogorov-Smirnov samples *)
  306.  
  307. (* --------------------------------------- *)
  308. (* --- construct Haar-random unitaries --- *)
  309. (* --------------------------------------- *)
  310.  
  311. mNode = nPhoton^2;
  312. iSeed=2^nPhoton;
  313.  
  314. SeedRandom[iSeed];
  315. Umatrix = RandomVariate[NormalDistribution[],{mNode,mNode}] +
  316. I * RandomVariate[NormalDistribution[],{mNode,mNode}]//
  317. SingularValueDecomposition//
  318. #[[1]].ConjugateTranspose[#[[3]]]&;
  319.  
  320. (* ------------------------------------------------- *)
  321. (* --- set the scale of the median |permanent|^2 --- *)
  322. (* ------------------------------------------------- *)
  323.  
  324. PessoanPostulate::usage = "<
  325. Per the boson-sampling experiments of Lund et al. "Boson sampling
  326. from a gaussian state" (PRL 2014, see Figure 1), let $n$ be the
  327. number of photons detected among $m=n^2$ output modes. Then for
  328. a Haar-distributed unitary scattering the median value of the
  329. squared permanent is (empirically) $2n\Gamma(n+1/2)/m^n$.
  330. >";
  331.  
  332. PessoanPostulate = 2 nPhoton Gamma[nPhoton+1/2]/mNode^nPhoton;
  333.  
  334. (* ------------------------------------------------------ *)
  335. (* --- sample combinatorically random output channels --- *)
  336. (* ------------------------------------------------------ *)
  337.  
  338. permEstimatedRMS = Sqrt[PessoanPostulate//N];
  339. amplitudeScale = permEstimatedRMS^(-1.0/nPhoton);
  340.  
  341. SeedRandom[iSeed+1];
  342. sample$PermanentDistribution = For[
  343. iSample=0,
  344. iSample<nSampleMax,
  345. iSample++,
  346. Umatrix//RandomChoice[#,nPhoton]&//
  347. Transpose//RandomChoice[#,nPhoton]&//
  348. (* from a superabundance of caution, rescale
  349. such that the computed permament is [ScriptCapitalO](1) *)
  350. (#*amplitudeScale)&//Permanent//
  351. (#*permEstimatedRMS)&//Sow;
  352. ]//Hold//
  353. TimeConstrained[#//ReleaseHold,tSampleMax]&//
  354. Reap//Last//Last;
  355.  
  356. normedSortedData = sample$PermanentDistribution//
  357. Map[(1/PessoanPostulate)*(#*#[Conjugate]//Re)&,#]&//Sort;
  358.  
  359. (* ----------------------------------------------------------- *)
  360. (* --- construct distributions both empirical and smoothed --- *)
  361. (* ----------------------------------------------------------- *)
  362.  
  363. combinatorialDistribution = normedSortedData//
  364. Log[10,#]&//
  365. EmpiricalDistribution;
  366.  
  367. empiricalDistribution = normedSortedData//
  368. Rule[#,(#//Log[10,#]&)]&//
  369. EmpiricalDistribution//Sow[#,"empiricalD"]&;
  370.  
  371. smoothDistribution = empiricalDistribution//
  372. RandomVariate[#,{10*(normedSortedData//Length)//Round}]&//
  373. SmoothKernelDistribution[#,0.1]&//Sow[#,"smoothD"]&;
  374.  
  375. (* ------------------------------------------------ *)
  376. (* --- construct inverse distributions and CDFs --- *)
  377. (* ------------------------------------------------ *)
  378.  
  379. inverseCDF = empiricalDistribution//InverseCDF;
  380. forwardCDF = empiricalDistribution//CDF;
  381. inverseSmoothCDF = smoothDistribution//InverseCDF;
  382. inverseCombinatorialCDF = combinatorialDistribution//InverseCDF;
  383.  
  384. (* ------------------------------------------------------ *)
  385. (* --- simulate k-sample experiments by Alice and Bob --- *)
  386. (* ------------------------------------------------------ *)
  387.  
  388. SeedRandom[iSeed+2];
  389. AliceBobSimulationData = smoothDistribution//
  390. RandomVariate[#,{2,kSample}]&;
  391.  
  392. {{"one-sample "A" ","one-sample "B" ","two-sample "AvsB""},{
  393. KolmogorovSmirnovTest[AliceBobSimulationData[[1]],smoothDistribution],
  394. KolmogorovSmirnovTest[AliceBobSimulationData[[2]],smoothDistribution],
  395. KolmogorovSmirnovTest[AliceBobSimulationData[[1]],AliceBobSimulationData[[2]]]
  396. }}//Transpose//
  397. Map[Print[#[[1]]," K-S test: p = ",#[[2]]]&,#]&;
  398.  
  399. (* ----------------------------- *)
  400. (* --- plot it all up nicely --- *)
  401. (* ----------------------------- *)
  402.  
  403. nPlotPts = 500;
  404.  
  405. range = normedSortedData//Log[10,#]&//
  406. {#[[4;;5]]//Mean,#[[-5;;-4]]//Mean}&//
  407. Map[forwardCDF,#]&;
  408.  
  409. theSmoothSample = Range[1/2,nPlotPts]/nPlotPts//
  410. Select[#,(#>range[[1]])&]&//
  411. Select[#,(#<range[[2]])&]&//
  412. Map[{#,inverseSmoothCDF[#]}&,#//N]&;
  413.  
  414. smoothPlot = theSmoothSample//
  415. ListPlot[
  416. #,
  417. PlotJoined->True,
  418. PlotRange->{{0,1},{-3,3}},
  419. PlotStyle->{
  420. Directive[Black,AbsoluteThickness[1.8]]
  421. },
  422. AspectRatio->0.8,
  423. AxesOrigin->{0.5,0.0},
  424. Ticks->{{None,None},{None,None}},
  425. AxesStyle->Directive[Black,AbsoluteThickness[1.2]],
  426. Frame->True,
  427. FrameStyle->Directive[Black,AbsoluteThickness[1.2]],
  428. FrameTicks -> {
  429. {{
  430. Range[-3,3,1],
  431. {"0.001","0.01","0.1","1","10","100","1000"}
  432. }//Transpose,None},
  433. {{
  434. Range[0,1,0.2],
  435. {"0","0.2","0.4","0.6","0.8","1"}
  436. }//Transpose,None}
  437. },
  438. FrameTicksStyle->Directive[Black,AbsoluteThickness[0.6],FontSize->Medium],
  439. GridLines[Rule]{
  440. Range[0,1,0.1],
  441. Outer[#1+#2&,Range[-3,2,1],Range[1,10,1]//Log[10,#]&]//
  442. Flatten
  443. },
  444. GridLinesStyle[Rule]Directive[Black,AbsoluteThickness[0.6],Opacity[0.2]]
  445. ]&;
  446.  
  447. AliceBobInverseCDFPlot = AliceBobSimulationData//
  448. Map[((#//EmpiricalDistribution//
  449. InverseCDF[#]&)[x])&,#]&//
  450. Plot[#,{x,0,1},
  451. Exclusions -> None, Frame -> None, GridLines -> None, Axes -> None,
  452. PlotPoints->400,MaxRecursion->3,
  453. PlotRange->{{0,1},{-3,3}},
  454. PlotStyle->{
  455. Directive[RGBColor[0.8,0,0],AbsoluteThickness[1.2],Opacity[0.65]],
  456. Directive[RGBColor[0,0,0.8],AbsoluteThickness[1.2],Opacity[0.65]]
  457. }
  458. ]&;
  459.  
  460. AliceBobRegionPlot = AliceBobSimulationData//
  461. Map[((#//EmpiricalDistribution//
  462. InverseCDF[#]&)[x])&,#]&//
  463. RegionPlot[
  464. {
  465. y<#[[1]] && y>#[[2]],
  466. y<#[[2]] && y>#[[1]]
  467. },
  468. {x,0,1},{y,-3,3},
  469. Background -> None,
  470. Frame -> None, GridLines -> None, Axes -> None,
  471. PlotRange->{{0,1},{-3,3}},
  472. PlotPoints->200,MaxRecursion->2,
  473. BoundaryStyle -> None,
  474. PlotStyle -> {
  475. Directive[Red,Opacity[0.125]],
  476. Directive[Blue,Opacity[0.125]]
  477. }
  478. ]&;
  479.  
  480. Show[smoothPlot,AliceBobRegionPlot,AliceBobInverseCDFPlot,
  481. PlotLabel -> Style[
  482. "boson-sampling Kolmogorov-Smirnov analysis n(n="<>
  483. (nPhoton//ToString)<>
  484. " photons, k=" <>
  485. (kSample//ToString)<>
  486. " detections, m=" <>
  487. (mNode//ToString)<>
  488. " modes)",
  489. FontSize->Medium,
  490. Black
  491. ],
  492. Background -> None,
  493. FrameLabel->{
  494. Style["cumulative probability",FontSize->Medium,Black],
  495. Style["(inverse CDF)/(2n[CapitalGamma](n+1/2)m^-n)",FontSize->Medium,Black]
  496. }
  497. ]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement