Permutation test: Difference between revisions

m
m (→‎{{header|Wren}}: Minor tidy)
 
(13 intermediate revisions by 11 users not shown)
Line 9:
was measured and reported in this table.
 
:::::::{| style="text-align: left; width: 5025%;" border="4" cellpadding="2" cellspacing="2"
|+ Table of experimental results
|- style="background-color: rgb(255, 204, 255);"
Line 44:
* Report the percentage of alternative groupings for which the difference in means is less or equal to the actual experimentally observed difference in means, and the percentage for which it is greater.
* Note that they should sum to 100%.
 
 
Extremely dissimilar values are evidence of an effect not entirely due
Line 51 ⟶ 52:
that's easier than loading them at run time. Test your solution on the
data given above.
<br><br>
 
=={{header|11l}}==
{{trans|Kotlin}}
 
<syntaxhighlight lang="11l">V data = [85, 88, 75, 66, 25, 29, 83, 39, 97,
68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
 
F pick(at, remain, accu, treat)
I remain == 0
R I accu > treat {1} E 0
R pick(at - 1, remain - 1, accu + :data[at - 1], treat) +
(I at > remain {pick(at - 1, remain, accu, treat)} E 0)
 
V treat = 0
V total = 1.0
L(i) 0..8
treat += data[i]
L(i) (19..11).step(-1)
total *= i
L(i) (9..1).step(-1)
total /= i
 
V gt = pick(19, 9, 0, treat)
V le = Int(total - gt)
 
print(‘<= : #.6% #.’.format(100 * le / total, le))
print(‘ > : #.6% #.’.format(100 * gt / total, gt))</syntaxhighlight>
 
{{out}}
<pre>
<= : 87.197168% 80551
> : 12.802832% 11827
</pre>
 
=={{header|Ada}}==
 
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO; with Iterate_Subsets;
 
procedure Permutation_Test is
Line 115 ⟶ 150:
New_Line;
end;
end Permutation_Test;</langsyntaxhighlight>
 
This solution uses an auxiliary package Iterate_Subsets. Here is the Spec:
<langsyntaxhighlight Adalang="ada">generic
Subset_Size, More_Elements: Positive;
package Iterate_Subsets is
Line 134 ⟶ 169:
 
end Iterate_Subsets;
</syntaxhighlight>
</lang>
 
And here is the implementation:
 
<langsyntaxhighlight Adalang="ada">package body Iterate_Subsets is
 
function First return Subset is
Line 171 ⟶ 206:
end Last;
 
end Iterate_Subsets;</langsyntaxhighlight>
 
{{out}}
Line 178 ⟶ 213:
</pre>
 
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f PERMUTATION_TEST.AWK
# converted from C
BEGIN {
# "treatment..................control......................"
n = split("85,88,75,66,25,29,83,39,97,68,41,10,49,16,65,32,92,28,98",data,",")
for (i=1; i<=n; i++) { # make AWK array look like a C array
data[i-1] = data[i]
}
delete data[n]
total = 1
for (i=0; i<9; i++) { treat += data[i] }
for (i=19; i>10; i--) { total *= i }
for (i=9; i>0; i--) { total /= i }
gt = pick(19,9,0,treat)
le = total - gt
printf("<= : %9.6f%% %6d\n",100*le/total,le)
printf(" > : %9.6f%% %6d\n",100*gt/total,gt)
exit(0)
}
function pick(at,remain,accu,treat) {
if (!remain) {
return (accu > treat) ? 1 : 0
}
return pick(at-1,remain-1,accu+data[at-1],treat) + ( (at > remain) ? pick(at-1,remain,accu,treat) : 0 )
}
</syntaxhighlight>
{{out}}
<pre>
<= : 87.197168% 80551
> : 12.802832% 11827
</pre>
 
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang="bbcbasic"> ntreated% = 9
nplacebo% = 10
DIM results%(ntreated% + nplacebo% - 1)
Line 218 ⟶ 286:
N% = (N% + (N% >>> 4)) AND &0F0F0F0F
N% += N% >>> 8 : N% += N% >>> 16
= N% AND &7F</langsyntaxhighlight>
{{out}}
<pre>
Line 226 ⟶ 294:
 
=={{header|C}}==
<langsyntaxhighlight Clang="c">#include <stdio.h>
 
int data[] = { 85, 88, 75, 66, 25, 29, 83, 39, 97,
Line 254 ⟶ 322:
100 * le / total, le, 100 * gt / total, gt);
return 0;
}</langsyntaxhighlight>
Output:<syntaxhighlight lang="text"><= : 87.197168% 80551
> : 12.802832% 11827</langsyntaxhighlight>
 
=={{header|C++ sharp|C#}}==
This is a translaion of C
<lang cpp>#include<iostream>
#include<vector>
#include<numeric>
#include<functional>
 
class
{
public:
int64_t operator()(int n, int k){ return partial_factorial(n, k) / factorial(n - k);}
private:
int64_t partial_factorial(int from, int to) { return from == to ? 1 : from * partial_factorial(from - 1, to); }
int64_t factorial(int n) { return n == 0 ? 1 : n * factorial(n - 1);}
}combinations;
 
int main()
{
static constexpr int treatment = 9;
const std::vector<int> data{ 85, 88, 75, 66, 25, 29, 83, 39, 97,
68, 41, 10, 49, 16, 65, 32, 92, 28, 98 };
 
int treated = std::accumulate(data.begin(), data.begin() + treatment, 0);
 
std::function<int (int, int, int)> pick;
pick = [&](int n, int from, int accumulated)
{
if(n == 0)
return accumulated > treated ? 1 : 0;
else
return pick(n - 1, from - 1, accumulated + data[from - 1]) +
(from > n ? pick(n, from - 1, accumulated) : 0);
};
 
int total = combinations(data.size(), treatment);
int greater = pick(treatment, data.size(), 0);
int lesser = total - greater;
 
std::cout << "<= : " << 100.0 * lesser / total << "% " << lesser << std::endl
<< " > : " << 100.0 * greater / total << "% " << greater << std::endl;
}</lang>
Output:<lang><= : 87.197168% 80551
> : 12.802832% 11827</lang>
 
=={{header|C#}}==
{{trans|Java}}
<langsyntaxhighlight lang="cs">using System;
using System.Collections.Generic;
 
Line 340 ⟶ 364:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>&lt;= 87.1971681569205% 80551
&gt; 12.8028318430795% 11827</pre>
 
=={{header|C++}}==
This is a translaion of C
<syntaxhighlight lang="cpp">#include<iostream>
#include<vector>
#include<numeric>
#include<functional>
 
class
{
public:
int64_t operator()(int n, int k){ return partial_factorial(n, k) / factorial(n - k);}
private:
int64_t partial_factorial(int from, int to) { return from == to ? 1 : from * partial_factorial(from - 1, to); }
int64_t factorial(int n) { return n == 0 ? 1 : n * factorial(n - 1);}
}combinations;
 
int main()
{
static constexpr int treatment = 9;
const std::vector<int> data{ 85, 88, 75, 66, 25, 29, 83, 39, 97,
68, 41, 10, 49, 16, 65, 32, 92, 28, 98 };
 
int treated = std::accumulate(data.begin(), data.begin() + treatment, 0);
 
std::function<int (int, int, int)> pick;
pick = [&](int n, int from, int accumulated)
{
if(n == 0)
return accumulated > treated ? 1 : 0;
else
return pick(n - 1, from - 1, accumulated + data[from - 1]) +
(from > n ? pick(n, from - 1, accumulated) : 0);
};
 
int total = combinations(data.size(), treatment);
int greater = pick(treatment, data.size(), 0);
int lesser = total - greater;
 
std::cout << "<= : " << 100.0 * lesser / total << "% " << lesser << std::endl
<< " > : " << 100.0 * greater / total << "% " << greater << std::endl;
}</syntaxhighlight>
Output:<syntaxhighlight lang="text"><= : 87.197168% 80551
> : 12.802832% 11827</syntaxhighlight>
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(defun perm-test (s1 s2)
(let ((more 0) (leq 0)
(all-data (append s1 s2))
Line 369 ⟶ 437:
(format t "<=: ~a ~6f%~% >: ~a ~6f%~%"
x (* 100e0 (/ x s))
y (* 100e0 (/ y s))))</langsyntaxhighlight>output<syntaxhighlight lang="text"><=: 80551 87.197%
>: 11827 12.803%</langsyntaxhighlight>
 
=={{header|D}}==
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.array, combinations3;
 
auto permutationTest(T)(in T[] a, in T[] b) pure nothrow @safe {
Line 387 ⟶ 455:
immutable under = permutationTest(treatmentGroup, controlGroup);
writefln("Under =%6.2f%%\nOver =%6.2f%%", under, 100.0 - under);
}</langsyntaxhighlight>
{{out}}
<pre>Under = 87.20%
Line 394 ⟶ 462:
Alternative version:
{{trans|C}}
<langsyntaxhighlight lang="d">void main() @safe {
import std.stdio, std.algorithm, std.range;
 
Line 417 ⟶ 485:
writefln(" > : %2.2f%% %d", 100.0 * gt / t, gt);
writefln("<= : %2.2f%% %d", 100.0 * le / t, le);
}</langsyntaxhighlight>
{{out}}
<pre> > : 12.80% 11827
<= : 87.20% 80551</pre>
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{Trans|Go}}
<syntaxhighlight lang="delphi">
program Permutation_test;
 
{$APPTYPE CONSOLE}
 
uses
System.SysUtils;
 
procedure Comb(n, m: Integer; emit: TProc<TArray<Integer>>);
var
s: TArray<Integer>;
last: Integer;
 
procedure rc(i, next: Integer);
begin
for var j := next to n - 1 do
begin
s[i] := j;
if i = last then
emit(s)
else
rc(i + 1, j + 1);
end;
end;
 
begin
SetLength(s, m);
last := m - 1;
rc(0, 0);
end;
 
begin
var tr: TArray<Integer> := [85, 88, 75, 66, 25, 29, 83, 39, 97];
var ct: TArray<Integer> := [68, 41, 10, 49, 16, 65, 32, 92, 28, 98];
 
// collect all results in a single list
var all: TArray<Integer> := concat(tr, ct);
 
// compute sum of all data, useful as intermediate result
var sumAll := 0;
for var r in all do
inc(sumAll, r);
 
// closure for computing scaled difference.
// compute results scaled by len(tr)*len(ct).
// this allows all math to be done in integers.
var sd :=
function(trc: TArray<Integer>): Integer
begin
var sumTr := 0;
for var x in trc do
inc(sumTr, all[x]);
result := sumTr * length(ct) - (sumAll - sumTr) * length(tr);
end;
 
// compute observed difference, as an intermediate result
var a: TArray<Integer>;
SetLength(a, length(tr));
for var i := 0 to High(a) do
a[i] := i;
 
var sdObs := sd(a);
 
// iterate over all combinations. for each, compute (scaled)
// difference and tally whether leq or gt observed difference.
var nLe, nGt: Integer;
 
comb(length(all), length(tr),
procedure(c: TArray<Integer>)
begin
if sd(c) > sdObs then
inc(nGt)
else
inc(nle);
end);
 
// print results as percentage
var pc := 100 / (nLe + nGt);
writeln(format('differences <= observed: %f%%', [nle * pc]));
writeln(format('differences > observed: %f%%', [ngt * pc]));
 
{$IFNDEF UNIX} readln; {$ENDIF}
end.</syntaxhighlight>
 
=={{header|Elixir}}==
{{trans|Ruby}}
<langsyntaxhighlight lang="elixir">defmodule Permutation do
def statistic(ab, a) do
sumab = Enum.sum(ab)
Line 451 ⟶ 605:
controlGroup = [68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
under = Permutation.test(treatmentGroup, controlGroup)
:io.fwrite "under = ~.2f%, over = ~.2f%~n", [under, 100-under]</langsyntaxhighlight>
 
{{out}}
Line 459 ⟶ 613:
 
=={{header|GAP}}==
<langsyntaxhighlight lang="gap">a := [85, 88, 75, 66, 25, 29, 83, 39, 97];
b := [68, 41, 10, 49, 16, 65, 32, 92, 28, 98];
 
Line 509 ⟶ 663:
# in order, % less or greater than original diff
PermTest(a, b);
[ "87.197", "12.802" ]</langsyntaxhighlight>
 
 
=={{header|FreeBASIC}}==
{{trans|Phix}}
<syntaxhighlight lang="freebasic">
Dim Shared datos(18) As Integer => {85, 88, 75, 66, 25, 29, 83, 39, 97,_
68, 41, 10, 49, 16, 65, 32, 92, 28, 98}
 
Function pick(at As Integer, remain As Integer, accu As Integer, treat As Integer) As Integer
If remain = 0 Then
If accu > treat Then Return 1 Else Return 0
End If
Dim a As Integer
If at > remain Then a = pick(at-1, remain, accu, treat) Else a = 0
Return pick(at-1, remain-1, accu+datos(at), treat) + a
End Function
 
Dim As Integer treat = 0, le, gt, total = 1, i
 
For i = 1 To 9
treat += datos(i)
Next i
For i = 19 To 11 Step -1
total *= i
Next i
For i = 9 To 1 Step -1
total /= i
Next i
 
gt = pick(19, 9, 0, treat)
le = total - gt
 
Print Using "<= : ##.######% #####"; 100*le/total; le
Print Using " > : ##.######% #####"; 100*gt/total; gt
Sleep
</syntaxhighlight>
{{out}}
<pre>
<= : 92.076035% 85058
> : 7.923965% 7320
</pre>
 
 
=={{header|Go}}==
A version doing all math in integers until computing final percentages.
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 584 ⟶ 781:
}
rc(0, 0)
}</langsyntaxhighlight>
{{out}}
<pre>
Line 592 ⟶ 789:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">binomial n m = (f !! n) `div` (f !! m) `div` (f !! (n - m))
where f = scanl (*) 1 [1..]
 
Line 612 ⟶ 809:
[68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
in do putStr "> : "; print r
putStr "<=: "; print $ 100 - r</langsyntaxhighlight>
{{out}}
<pre>
Line 620 ⟶ 817:
 
Somewhat faster, this goes from top down:
<langsyntaxhighlight lang="haskell">binomial n m = (f !! n) `div` (f !! m) `div` (f !! (n - m))
where f = scanl (*) 1 [1..]
 
Line 638 ⟶ 835:
(a, b) = perms [85, 88, 75, 66, 25, 29, 83, 39, 97]
[68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
lt = (fromIntegral a) / (fromIntegral b) * 100</langsyntaxhighlight>
 
In cases where the sample data are a large number of relatively small positive integers, counting number of partial sums is a lot faster:
<langsyntaxhighlight lang="haskell">combs maxsum len x = foldl f [(0,0,1)] x where
f a n = merge a (map (addNum n) $ filter (\(l,_,_) -> l < len) a)
addNum n (a,s,c)
Line 666 ⟶ 863:
-- how many combinations are less than current sum
main = print$ permtest [85, 88, 75, 66, 25, 29, 83, 39, 97]
[68, 41, 10, 49, 16, 65, 32, 92, 28, 98]</langsyntaxhighlight>
 
=={{header|J}}==
<langsyntaxhighlight lang="j">require'stats'
trmt=: 0.85 0.88 0.75 0.66 0.25 0.29 0.83 0.39 0.97
ctrl=: 0.68 0.41 0.1 0.49 0.16 0.65 0.32 0.92 0.28 0.98
Line 676 ⟶ 873:
all=: trmt(#@[ ({. difm }.) |:@([ (comb ~.@,"1 i.@])&# ,) { ,) ctrl
smoutput 'under: ','%',~":100*mean all <: result
smoutput 'over: ','%',~":100*mean all > result</langsyntaxhighlight>
 
Result:
<syntaxhighlight lang="text">under: 87.1972%
over: 12.8028%</langsyntaxhighlight>
 
=={{header|Java}}==
{{trans|Kotlin}}
<langsyntaxhighlight Javalang="java">public class PermutationTest {
private static final int[] data = new int[]{
85, 88, 75, 66, 25, 29, 83, 39, 97,
Line 713 ⟶ 910:
System.out.printf(" > : %f%% %d\n", 100.0 * gt / total, gt);
}
}</langsyntaxhighlight>
{{out}}
<pre><= : 87.197168% 80551
Line 721 ⟶ 918:
{{works with|jq|1.4}}
'''Part 1: Combinations'''
<langsyntaxhighlight lang="jq"># combination(r) generates a stream of combinations of r items from the input array.
def combination(r):
if r > length or r < 0 then empty
Line 728 ⟶ 925:
( .[1:]|combination(r))
end;
</syntaxhighlight>
</lang>
'''Part 2: Permutation Test'''
<langsyntaxhighlight lang="jq"># a and b should be arrays:
def permutationTest(a; b):
 
Line 755 ⟶ 952:
| .[1] += 1 )
| .[0] * 100.0 / .[1] # under/count
;</langsyntaxhighlight>
'''Example:'''
<langsyntaxhighlight lang="jq">def treatmentGroup: [85, 88, 75, 66, 25, 29, 83, 39, 97];
def controlGroup: [68, 41, 10, 49, 16, 65, 32, 92, 28, 98];
 
permutationTest(treatmentGroup; controlGroup) as $under
| "% under=\($under)", "% over=\(100 - $under)"</langsyntaxhighlight>
{{out}}
$ jq -n -r -f permutation_test.jq
Line 772 ⟶ 969:
 
'''Functions'''
<langsyntaxhighlight lang="julia">using Combinatorics
 
meandiff(a::Vector{T}, b::Vector{T}) where T <: Real = mean(a) - mean(b)
Line 799 ⟶ 996:
end
return better, worse
end</langsyntaxhighlight>
 
'''Main'''
<langsyntaxhighlight lang="julia">const treated = [85, 88, 75, 66, 25, 29, 83, 39, 97]
const control = [68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
 
Line 814 ⟶ 1,011:
println("\nThere are $tot different permuted groups of these data.")
@printf("%8d, %5.2f%% showed better than actual results.\n", better, 100 * better / tot)
print(@sprintf("%8d, %5.2f%% showed equalivalent or worse results.", worse, 100 * worse / tot))</langsyntaxhighlight>
 
{{out}}
Line 827 ⟶ 1,024:
=={{header|Kotlin}}==
{{trans|C}}
<langsyntaxhighlight lang="scala">// version 1.1.2
 
val data = intArrayOf(
Line 850 ⟶ 1,047:
System.out.printf("<= : %f%% %d\n", 100.0 * le / total, le)
System.out.printf(" > : %f%% %d\n", 100.0 * gt / total, gt)
}</langsyntaxhighlight>
 
{{out}}
Line 857 ⟶ 1,054:
> : 12.802832% 11827
</pre>
 
=={{header|M2000 Interpreter}}==
{{trans|C}}
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Checkit {
Global data(), treat=0
Line 877 ⟶ 1,075:
}
Checkit
</syntaxhighlight>
</lang>
{{out}}
<pre><= : 87.2% 80551
Line 885 ⟶ 1,083:
Slower version, using a lambda function with a series of inner lambda functions to return each combination at a time.
 
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module CheckThis {
Function CombinationsStep (a, nn) {
Line 930 ⟶ 1,128:
}
CheckThis
</syntaxhighlight>
</lang>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<langsyntaxhighlight lang="mathematica">"<=: " <> ToString[#1] <> " " <> ToString[100. #1/#2] <> "%\n >: " <>
ToString[#2 - #1] <> " " <> ToString[100. (1 - #1/#2)] <> "%" &[
Count[Total /@ Subsets[Join[#1, #2], {Length@#1}],
n_ /; n <= Total@#1],
Binomial[Length@#1 + Length@#2, Length@#1]] &[{85, 88, 75, 66, 25,
29, 83, 39, 97}, {68, 41, 10, 49, 16, 65, 32, 92, 28, 98}]</langsyntaxhighlight>
{{out}}
<pre><=: 80551 87.1972%
Line 945 ⟶ 1,143:
=={{header|Nim}}==
{{trans|C}}
<langsyntaxhighlight lang="nim">import strformat
 
const data = [85, 88, 75, 66, 25,
Line 972 ⟶ 1,170:
le = int(total - float(gt))
echo fmt"<= : {100.0 * float(le) / total:.6f}% {le}"
echo fmt" > : {100.0 * float(gt) / total:.6f}% {gt}"</langsyntaxhighlight>
{{out}}
<pre>
Line 980 ⟶ 1,178:
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">#!/usr/bin/perl
use warnings;
use strict;
Line 1,063 ⟶ 1,261:
92
28
98</langsyntaxhighlight>
{{out}}
equal 313 0.339%
less 80238 86.858%
greater 11827 12.803%
 
=={{header|Perl 6}}==
The use of <code>.race</code> to allow concurrent calculations means that multiple 'workers' will be updating <code>@trials</code> simultaneously. To avoid race conditions, the <code>⚛++</code> operator is used, which guarantees safe updates without the use of locks. That is turn requires declaring that array as being composed of <code>atomicint</code>.
{{works with|Rakudo|2018.09}}
 
<lang perl6>sub stats ( @test, @all ) {
([+] @test / +@test) - ([+] flat @all, (@test X* -1)) / @all - @test
}
 
my int @treated = <85 88 75 66 25 29 83 39 97>;
my int @control = <68 41 10 49 16 65 32 92 28 98>;
my int @all = flat @treated, @control;
 
my $base = stats( @treated, @all );
 
my atomicint @trials[3] = 0, 0, 0;
 
@all.combinations(+@treated).race.map: { @trials[ 1 + ( stats( $_, @all ) <=> $base ) ]⚛++ }
 
say 'Counts: <, =, > ', @trials;
say 'Less than : %', 100 * @trials[0] / [+] @trials;
say 'Equal to : %', 100 * @trials[1] / [+] @trials;
say 'Greater than : %', 100 * @trials[2] / [+] @trials;
say 'Less or Equal: %', 100 * ( [+] @trials[0,1] ) / [+] @trials;</lang>
 
{{out}}
<pre>
Counts: <, =, > 80238 313 11827
Less than : %86.858343
Equal to : %0.338825
Greater than : %12.802832
Less or Equal: %87.197168
</pre>
 
=={{header|Phix}}==
{{Trans|C}}
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>constant data = {85, 88, 75, 66, 25, 29, 83, 39, 97,
<span style="color: #008080;">constant</span> <span style="color: #000000;">data</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">85</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">88</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">75</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">66</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">25</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">29</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">83</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">39</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">97</span><span style="color: #0000FF;">,</span>
68, 41, 10, 49, 16, 65, 32, 92, 28, 98 }
<span style="color: #000000;">68</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">41</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">10</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">49</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">16</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">65</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">32</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">92</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">28</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">98</span> <span style="color: #0000FF;">}</span>
function pick(int at, int remain, int accu, int treat)
<span style="color: #008080;">function</span> <span style="color: #000000;">pick</span><span style="color: #0000FF;">(</span><span style="color: #004080;">int</span> <span style="color: #000000;">at</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">int</span> <span style="color: #000000;">remain</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">int</span> <span style="color: #000000;">accu</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">int</span> <span style="color: #000000;">treat</span><span style="color: #0000FF;">)</span>
if remain=0 then return iff(accu>treat?1:0) end if
<span style="color: #008080;">if</span> <span style="color: #000000;">remain</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">accu</span><span style="color: #0000FF;">></span><span style="color: #000000;">treat</span><span style="color: #0000FF;">?</span><span style="color: #000000;">1</span><span style="color: #0000FF;">:</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return pick(at-1, remain-1, accu+data[at], treat) +
<span style="color: #008080;">return</span> <span style="color: #000000;">pick</span><span style="color: #0000FF;">(</span><span style="color: #000000;">at</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">remain</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">accu</span><span style="color: #0000FF;">+</span><span style="color: #000000;">data</span><span style="color: #0000FF;">[</span><span style="color: #000000;">at</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">treat</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span>
iff(at>remain?pick(at-1, remain, accu, treat):0)
<span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">at</span><span style="color: #0000FF;">></span><span style="color: #000000;">remain</span><span style="color: #0000FF;">?</span><span style="color: #000000;">pick</span><span style="color: #0000FF;">(</span><span style="color: #000000;">at</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">remain</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">accu</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">treat</span><span style="color: #0000FF;">):</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
int treat = 0, le, gt
<span style="color: #004080;">int</span> <span style="color: #000000;">treat</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">le</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">gt</span>
atom total = 1;
<span style="color: #004080;">atom</span> <span style="color: #000000;">total</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">;</span>
for i=1 to 9 do treat += data[i] end for
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span> <span style="color: #000000;">treat</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">data</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
for i=19 to 11 by -1 do total *= i end for
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">19</span> <span style="color: #008080;">to</span> <span style="color: #000000;">11</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span> <span style="color: #000000;">total</span> <span style="color: #0000FF;">*=</span> <span style="color: #000000;">i</span> <span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
for i=9 to 1 by -1 do total /= i end for
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">9</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span> <span style="color: #000000;">total</span> <span style="color: #0000FF;">/=</span> <span style="color: #000000;">i</span> <span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
gt = pick(19, 9, 0, treat)
<span style="color: #000000;">gt</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">pick</span><span style="color: #0000FF;">(</span><span style="color: #000000;">19</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">treat</span><span style="color: #0000FF;">)</span>
le = total - gt;
<span style="color: #000000;">le</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">total</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">gt</span><span style="color: #0000FF;">;</span>
printf(1,"<= : %f%% %d\n > : %f%% %d\n",
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"&lt;= : %f%% %d\n &gt; : %f%% %d\n"</span><span style="color: #0000FF;">,</span>
{100*le/total, le, 100*gt/total, gt})</lang>
<span style="color: #0000FF;">{</span><span style="color: #000000;">100</span><span style="color: #0000FF;">*</span><span style="color: #000000;">le</span><span style="color: #0000FF;">/</span><span style="color: #000000;">total</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">le</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">100</span><span style="color: #0000FF;">*</span><span style="color: #000000;">gt</span><span style="color: #0000FF;">/</span><span style="color: #000000;">total</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">gt</span><span style="color: #0000FF;">})</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 1,131 ⟶ 1,298:
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(load "@lib/simul.l") # For 'subsets'
 
(scl 2)
Line 1,162 ⟶ 1,329:
 
(let N (permutationTest *TreatmentGroup *ControlGroup)
(prinl "under = " (round N) "%, over = " (round (- 100.0 N)) "%") )</langsyntaxhighlight>
{{out}}
<pre>under = 87.85%, over = 12.15%</pre>
Line 1,177 ⟶ 1,344:
the treatment group or the control group
 
<syntaxhighlight lang="purebasic">
<lang PureBasic>
 
Define.f meanTreated,meanControl,diffInMeans
Line 1,269 ⟶ 1,436:
Debug StrF(100*diffLessOrEqual/TotalComBinations,2)+" "+Str(diffLessOrEqual)
Debug StrF(100*diffGreater /TotalComBinations,2)+" "+Str(diffGreater)
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,276 ⟶ 1,443:
12.80 11827
</pre>
 
 
=={{header|Python}}==
{{trans|Tcl}}
<langsyntaxhighlight lang="python">from itertools import combinations as comb
 
def statistic(ab, a):
Line 1,299 ⟶ 1,465:
controlGroup = [68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
under = permutationTest(treatmentGroup, controlGroup)
print("under=%.2f%%, over=%.2f%%" % (under, 100. - under))</langsyntaxhighlight>
{{out}}
<pre>under=89.11%, over=10.89%</pre>
 
The above solution does a different thing than the other solutions. I'm not really sure why. If you want to do the same thing as the other solutions, then this is the solution:
<langsyntaxhighlight lang="python">from itertools import combinations as comb
 
def permutationTest(a, b):
Line 1,318 ⟶ 1,484:
controlGroup = [68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
under = permutationTest(treatmentGroup, controlGroup)
print("under=%.2f%%, over=%.2f%%" % (under, 100. - under))</langsyntaxhighlight>
{{out}}
<pre>under=87.20%, over=12.80%</pre>
Line 1,324 ⟶ 1,490:
=={{header|R}}==
 
<langsyntaxhighlight lang="r">permutation.test <- function(treatment, control) {
perms <- combinations(length(treatment)+length(control),
length(treatment),
Line 1,331 ⟶ 1,497:
p <- mean(rowMeans(perms) <= mean(treatment))
c(under=p, over=(1-p))
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="r">> permutation.test(c(85, 88, 75, 66, 25, 29, 83, 39, 97),
+ c(68, 41, 10, 49, 16, 65, 32, 92, 28, 98))
under over
0.8719717 0.1280283 </langsyntaxhighlight>
 
 
=={{header|Racket}}==
{{trans|Common Lisp}}
 
<langsyntaxhighlight Racketlang="racket">#lang racket/base
 
(define-syntax-rule (inc! x)
Line 1,367 ⟶ 1,532:
more (real->decimal-string (* 100. (/ more sum)) 2)
leq (real->decimal-string (* 100. (/ leq sum)) 2))))
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,373 ⟶ 1,538:
<=: 80551 87.20%
>: 11827 12.80%
</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
The use of <code>.race</code> to allow concurrent calculations means that multiple 'workers' will be updating <code>@trials</code> simultaneously. To avoid race conditions, the <code>⚛++</code> operator is used, which guarantees safe updates without the use of locks. That is turn requires declaring that array as being composed of <code>atomicint</code>.
{{works with|Rakudo|2018.09}}
 
<syntaxhighlight lang="raku" line>sub stats ( @test, @all ) {
([+] @test / +@test) - ([+] flat @all, (@test X* -1)) / @all - @test
}
 
my int @treated = <85 88 75 66 25 29 83 39 97>;
my int @control = <68 41 10 49 16 65 32 92 28 98>;
my int @all = flat @treated, @control;
 
my $base = stats( @treated, @all );
 
my atomicint @trials[3] = 0, 0, 0;
 
@all.combinations(+@treated).race.map: { @trials[ 1 + ( stats( $_, @all ) <=> $base ) ]⚛++ }
 
say 'Counts: <, =, > ', @trials;
say 'Less than : %', 100 * @trials[0] / [+] @trials;
say 'Equal to : %', 100 * @trials[1] / [+] @trials;
say 'Greater than : %', 100 * @trials[2] / [+] @trials;
say 'Less or Equal: %', 100 * ( [+] @trials[0,1] ) / [+] @trials;</syntaxhighlight>
 
{{out}}
<pre>
Counts: <, =, > 80238 313 11827
Less than : %86.858343
Equal to : %0.338825
Greater than : %12.802832
Less or Equal: %87.197168
</pre>
 
=={{header|REXX}}==
This REXX program is modeled after the &nbsp; '''C''' &nbsp; version, with some generalizations and optimization added.
<langsyntaxhighlight lang="rexx">/*REXX program performs a permutation test on N + M subjects (volunteers): */
/* ↑ ↑ */
/* │ │ */
Line 1,385 ⟶ 1,584:
data= 85 88 75 66 25 29 83 39 97 68 41 10 49 16 65 32 92 28 98
w= words(data); m= w - n /*w: volunteers + control population*/
L= length(w) /*L: used to align some output numbers*/
L= length(w)
say '# of volunteers & control population: ' w
say 'volunteer population given treatment: ' right(n, L)
Line 1,409 ⟶ 1,608:
else q= 0
itP= it - 1 /*set temporary var.*/
return picker(itP, rest - 1, eff + #.itP) + q /*recurse. */</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default input:}}
<pre>
Line 1,425 ⟶ 1,624:
=={{header|Ruby}}==
{{trans|Python}}
<langsyntaxhighlight lang="ruby">def statistic(ab, a)
sumab, suma = ab.inject(:+).to_f, a.inject(:+).to_f
suma / a.size - (sumab - suma) / (ab.size - a.size)
Line 1,444 ⟶ 1,643:
controlGroup = [68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
under = permutationTest(treatmentGroup, controlGroup)
puts "under=%.2f%%, over=%.2f%%" % [under, 100 - under]</langsyntaxhighlight>
 
{{out}}
<pre>
under=87.20%, over=12.80%
</pre>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">
fn main() {
let treatment = vec![85, 88, 75, 66, 25, 29, 83, 39, 97];
let control = vec![68, 41, 10, 49, 16, 65, 32, 92, 28, 98];
 
let mut data_set = control.clone();
data_set.extend_from_slice(&treatment);
 
let greater = combinations(treatment.iter().sum(), treatment.len() as i64, &data_set) as f64;
let lesser = combinations(control.iter().sum(), control.len() as i64, &data_set) as f64;
let total = binomial(data_set.len() as i64, treatment.len() as i64) as f64;
 
println!("<= : {}%", (lesser / total * 100.0));
println!(" > : {}%", (greater / total * 100.0));
}
 
fn factorial(x: i64) -> i64 {
let mut product = 1;
for a in 1..(x + 1) {
product *= a;
}
product
}
 
fn binomial(n: i64, k: i64) -> i64 {
let numerator = factorial(n);
let denominator = factorial(k) * factorial(n - k);
numerator / denominator
}
 
fn combinations(total: i64, number: i64, data: &[i64]) -> i64 {
if total < 0 {
return binomial(data.len() as i64, number);
}
 
if number == 0 {
return 0;
}
 
if number > data.len() as i64 {
return 0;
}
 
if number == data.len() as i64 {
if total < data.iter().sum() {
return 1;
} else {
return 0;
}
}
 
let tail = &data[1..];
combinations(total - data[0], number - 1, &tail) + combinations(total, number, &tail)
}
</syntaxhighlight>
{{out}}
<pre>
<= : 86.8583428954946%
> : 12.80283184307952%
</pre>
 
Line 1,454 ⟶ 1,715:
===Imperative version (Ugly, side effects)===
{{Out}}Best seen running in your browser either by [https://scalafiddle.io/sf/69o8tJX/0 ScalaFiddle (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/jpUyNPetRXabZkEKc68FAA Scastie (remote JVM)].
<langsyntaxhighlight Scalalang="scala">object PermutationTest extends App {
private val data =
Array(85, 88, 75, 66, 25, 29, 83, 39, 97, 68, 41, 10, 49, 16, 65, 32, 92, 28, 98)
Line 1,476 ⟶ 1,737:
println(f" > : ${100.0 * gt / total}%f%% ${gt}%d")
 
}</langsyntaxhighlight>
 
=={{header|Seed7}}==
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "float.s7i";
 
Line 1,516 ⟶ 1,778:
writeln("<= : " <& 100.0 * flt(le) / flt(total) digits 6 <& "% " <& le);
writeln(" > : " <& 100.0 * flt(gt) / flt(total) digits 6 <& "% " <& gt);
end func;</langsyntaxhighlight>
{{out}}
<= : 87.197168% 80551
Line 1,523 ⟶ 1,785:
=={{header|Sidef}}==
{{trans|Ruby}}
<langsyntaxhighlight lang="ruby">func statistic(ab, a) {
var(sumab, suma) = (ab.sum, a.sum)
suma/a.size - ((sumab-suma) / (ab.size-a.size))
Line 1,542 ⟶ 1,804:
var controlGroup = [68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
var under = permutationTest(treatmentGroup, controlGroup)
say ("under=%.2f%%, over=%.2f%%" % (under, 100 - under))</langsyntaxhighlight>
{{out}}
<pre>
Line 1,549 ⟶ 1,811:
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
 
# Difference of means; note that the first list must be the concatenation of
Line 1,595 ⟶ 1,857:
set count [tcl::mathfunc::double $count]
list [expr {$overcount / $count}] [expr {$undercount / $count}]
}</langsyntaxhighlight>
Demonstration code:
<langsyntaxhighlight lang="tcl">set treatmentGroup {0.85 0.88 0.75 0.66 0.25 0.29 0.83 0.39 0.97}
set controlGroup {0.68 0.41 0.10 0.49 0.16 0.65 0.32 0.92 0.28 0.98}
lassign [permutationTest $treatmentGroup $controlGroup] over under
puts [format "under=%.2f%%, over=%.2f%%" [expr {$under*100}] [expr {$over*100}]]</langsyntaxhighlight>
{{out}}
<pre>under=86.90%, over=13.10%</pre>
 
=={{header|Ursala}}==
<langsyntaxhighlight Ursalalang="ursala">#import std
#import nat
#import flo
Line 1,620 ⟶ 1,882:
#show+
 
t = --* *-'%'@lrNCC printf/$'%0.2f' times/$100. f(treatment_group,control_group)</langsyntaxhighlight>
{{out}}
<pre>
12.80%
87.20%</pre>
 
=={{header|Wren}}==
{{trans|C}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "./fmt" for Fmt
 
var data = [85, 88, 75, 66, 25, 29, 83, 39, 97, 68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
 
var pick // recursive
pick = Fn.new { |at, remain, accu, treat|
if (remain == 0) return (accu > treat) ? 1 : 0
return pick.call(at-1, remain-1, accu + data[at-1], treat) +
((at > remain) ? pick.call(at-1, remain, accu, treat) : 0)
}
 
var treat = 0
var total = 1
for (i in 0..8) treat = treat + data[i]
for (i in 19..11) total = total * i
for (i in 9..1) total = total / i
var gt = pick.call(19, 9, 0, treat)
var le = (total - gt).truncate
Fmt.print("<= : $f\% $d", 100 * le / total, le)
Fmt.print(" > : $f\% $d", 100 * gt / total, gt)</syntaxhighlight>
 
{{out}}
<pre>
<= : 87.197168% 80551
> : 12.802832% 11827
</pre>
 
=={{header|XPL0}}==
{{trans|C}}
<syntaxhighlight lang "XPL0">include xpllib; \For Print
 
int Data;
 
func Pick(At, Remain, Accu, Treat);
int At, Remain, Accu, Treat;
[if Remain = 0 then return if Accu > Treat then 1 else 0;
return Pick(At-1, Remain-1, Accu + Data(At-1), Treat) +
(if At > Remain then Pick(At-1, Remain, Accu, Treat) else 0);
];
 
int Treat, GT, LE, I;
real Total;
[Treat:= 0; Total:= 1.;
Data:= [85, 88, 75, 66, 25, 29, 83, 39, 97,
68, 41, 10, 49, 16, 65, 32, 92, 28, 98];
for I:= 0 to 8 do Treat:= Treat + Data(I);
for I:= 19 downto 11 do Total:= Total * float(I);
for I:= 9 downto 1 do Total:= Total / float(I);
GT:= Pick(19, 9, 0, Treat);
LE:= (fix(Total) - GT);
Print("<= : %f% %d\n", 100. * float(LE) / Total, LE);
Print(" > : %f% %d\n", 100. * float(GT) / Total, GT);
]</syntaxhighlight>
{{out}}
<pre>
<= : 87.19717% 80551
> : 12.80283% 11827
</pre>
 
=={{header|zkl}}==
A solution that is not going to scale gracefully at all.
{{trans|D}}
<langsyntaxhighlight lang="zkl">fcn permutationTest(a,b){
ab := a.extend(b);
tObs := a.sum(0);
Line 1,640 ⟶ 1,964:
controlGroup := T(68, 41, 10, 49, 16, 65, 32, 92, 28, 98);
under := permutationTest(treatmentGroup, controlGroup);
println("Under =%6.2f%%\nOver =%6.2f%%".fmt(under, 100.0 - under));</langsyntaxhighlight>
{{out}}
<pre>
9,482

edits