Permutation test: Difference between revisions
m
→{{header|Wren}}: Minor tidy
(Updated second D entry) |
m (→{{header|Wren}}: Minor tidy) |
||
(41 intermediate revisions by 22 users not shown) | |||
Line 9:
was measured and reported in this table.
:::::::{| style="text-align: left; width:
|+ 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}}==
<
procedure Permutation_Test is
Line 115 ⟶ 150:
New_Line;
end;
end Permutation_Test;</
This solution uses an auxiliary package Iterate_Subsets. Here is the Spec:
<
Subset_Size, More_Elements: Positive;
package Iterate_Subsets is
Line 134 ⟶ 169:
end Iterate_Subsets;
</syntaxhighlight>
And here is the implementation:
<
function First return Subset is
Line 171 ⟶ 206:
end Last;
end Iterate_Subsets;</
{{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}}
<
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</
{{out}}
<pre>
Line 226 ⟶ 294:
=={{header|C}}==
<
int data[] = { 85, 88, 75, 66, 25, 29, 83, 39, 97,
Line 254 ⟶ 322:
100 * le / total, le, 100 * gt / total, gt);
return 0;
}</
Output:<syntaxhighlight lang="text"><= : 87.197168% 80551
> : 12.802832% 11827</
=={{header|C sharp|C#}}==
{{trans|Java}}
<syntaxhighlight lang="cs">using System;
using System.Collections.Generic;
namespace PermutationTest {
class Program {
static readonly List<int> DATA = new List<int>{
85, 88, 75, 66, 25, 29, 83, 39, 97,
68, 41, 10, 49, 16, 65, 32, 92, 28, 98
};
static int Pick(int at, int remain, int accu, int treat) {
if (remain == 0) {
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);
}
static void Main() {
int treat = 0;
double total = 1.0;
for (int i = 0; i <= 8; i++) {
treat += DATA[i];
}
for (int i = 19; i >= 11; i--) {
total *= i;
}
for (int i = 9; i >= 1; --i) {
total /= i;
}
int gt = Pick(19, 9, 0, treat);
int le = (int) (total - gt);
Console.WriteLine("<= {0}% {1}", 100.0 * le / total, le);
Console.WriteLine(" > {0}% {1}", 100.0 * gt / total, gt);
}
}
}</syntaxhighlight>
{{out}}
<pre><= 87.1971681569205% 80551
> 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}}==
<
(let ((more 0) (leq 0)
(all-data (append s1 s2))
Line 282 ⟶ 437:
(format t "<=: ~a ~6f%~% >: ~a ~6f%~%"
x (* 100e0 (/ x s))
y (* 100e0 (/ y s))))</
>: 11827 12.803%</
=={{header|D}}==
<
auto permutationTest(T)(in T[] a, in T[] b) pure nothrow @safe {
Line 300 ⟶ 455:
immutable under = permutationTest(treatmentGroup, controlGroup);
writefln("Under =%6.2f%%\nOver =%6.2f%%", under, 100.0 - under);
}</
{{out}}
<pre>Under = 87.20%
Line 307 ⟶ 462:
Alternative version:
{{trans|C}}
<
import std.stdio, std.algorithm, std.range;
Line 330 ⟶ 485:
writefln(" > : %2.2f%% %d", 100.0 * gt / t, gt);
writefln("<= : %2.2f%% %d", 100.0 * le / t, le);
}</
{{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}}
<syntaxhighlight lang="elixir">defmodule Permutation do
def statistic(ab, a) do
sumab = Enum.sum(ab)
suma = Enum.sum(a)
suma / length(a) - (sumab - suma) / (length(ab) - length(a))
end
def test(a, b) do
ab = a ++ b
tobs = statistic(ab, a)
{under, count} = Enum.reduce(comb(ab, length(a)), {0,0}, fn perm, {under, count} ->
if statistic(ab, perm) <= tobs, do: {under+1, count+1},
else: {under , count+1}
end)
under * 100.0 / count
end
defp comb(_, 0), do: [[]]
defp comb([], _), do: []
defp comb([h|t], m) do
(for l <- comb(t, m-1), do: [h|l]) ++ comb(t, m)
end
end
treatmentGroup = [85, 88, 75, 66, 25, 29, 83, 39, 97]
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]</syntaxhighlight>
{{out}}
<pre>
under = 87.20%, over = 12.80%
</pre>
=={{header|GAP}}==
<
b := [68, 41, 10, 49, 16, 65, 32, 92, 28, 98];
Line 386 ⟶ 663:
# in order, % less or greater than original diff
PermTest(a, b);
[ "87.197", "12.802" ]</
=={{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.
<
import "fmt"
Line 461 ⟶ 781:
}
rc(0, 0)
}</
{{out}}
<pre>
Line 469 ⟶ 789:
=={{header|Haskell}}==
<
where f = scanl (*) 1 [1..]
Line 489 ⟶ 809:
[68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
in do putStr "> : "; print r
putStr "<=: "; print $ 100 - r</
{{out}}
<pre>
Line 497 ⟶ 817:
Somewhat faster, this goes from top down:
<
where f = scanl (*) 1 [1..]
Line 515 ⟶ 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</
In cases where the sample data are a large number of relatively small positive integers, counting number of partial sums is a lot faster:
<
f a n = merge a (map (addNum n) $ filter (\(l,_,_) -> l < len) a)
addNum n (a,s,c)
Line 543 ⟶ 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]</
=={{header|J}}==
<
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 553 ⟶ 873:
all=: trmt(#@[ ({. difm }.) |:@([ (comb ~.@,"1 i.@])&# ,) { ,) ctrl
smoutput 'under: ','%',~":100*mean all <: result
smoutput 'over: ','%',~":100*mean all > result</
Result:
<syntaxhighlight lang="text">under: 87.1972%
over: 12.8028%</
=={{header|Java}}==
{{trans|Kotlin}}
<syntaxhighlight lang="java">public class PermutationTest {
private static final int[] data = new int[]{
85, 88, 75, 66, 25, 29, 83, 39, 97,
68, 41, 10, 49, 16, 65, 32, 92, 28, 98
};
private static int pick(int at, int remain, int accu, int treat) {
if (remain == 0) 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);
}
public static void main(String[] args) {
int treat = 0;
double total = 1.0;
for (int i = 0; i <= 8; ++i) {
treat += data[i];
}
for (int i = 19; i >= 11; --i) {
total *= i;
}
for (int i = 9; i >= 1; --i) {
total /= i;
}
int gt = pick(19, 9, 0, treat);
int le = (int) (total - gt);
System.out.printf("<= : %f%% %d\n", 100.0 * le / total, le);
System.out.printf(" > : %f%% %d\n", 100.0 * gt / total, gt);
}
}</syntaxhighlight>
{{out}}
<pre><= : 87.197168% 80551
> : 12.802832% 11827</pre>
=={{header|jq}}==
{{works with|jq|1.4}}
'''Part 1: Combinations'''
<
def combination(r):
if r > length or r < 0 then empty
Line 568 ⟶ 925:
( .[1:]|combination(r))
end;
</syntaxhighlight>
'''Part 2: Permutation Test'''
<
def permutationTest(a; b):
Line 595 ⟶ 952:
| .[1] += 1 )
| .[0] * 100.0 / .[1] # under/count
;</
'''Example:'''
<
def controlGroup: [68, 41, 10, 49, 16, 65, 32, 92, 28, 98];
permutationTest(treatmentGroup; controlGroup) as $under
| "% under=\($under)", "% over=\(100 - $under)"</
{{out}}
$ jq -n -r -f permutation_test.jq
Line 607 ⟶ 964:
% over=12.856957284201869
=={{header|
{{works with|Julia|0.6}}
The primary function for this solution is <tt>permutation_test</tt>, which relies on Julia's <tt>combinations</tt> (from <tt>Combinatorics</tt> module) function to provide all of the possible study arm assignments. <tt>bifurcate</tt> splits the pooled results into "treatment" and "control" groups according to the indices provided by <tt>combinations</tt>.
'''Functions'''
<syntaxhighlight lang="julia">using Combinatorics
meandiff(a::Vector{T}, b::Vector{T}) where T <: Real = mean(a) - mean(b)
function bifurcate(a::AbstractVector, sel::Vector{T}) where T <: Integer
x = a[sel]
asel = trues(length(a))
asel[sel] = false
y = a[asel]
return x, y
end
function permutation_test(treated::Vector{T}, control::Vector{T}) where T <: Real
effect0 = meandiff(treated, control)
pool = vcat(treated, control)
tlen = length(treated)
plen = length(pool)
better = worse = 0
for subset in combinations(1:plen, tlen)
t, c = bifurcate(pool, subset)
if effect0 < meandiff(t, c)
better += 1
else
worse += 1
end
end
return better, worse
end</syntaxhighlight>
'''Main'''
<syntaxhighlight 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]
(better, worse) = permutation_test(treated, control)
tot = better + worse
println("Permutation test using the following data:")
println("Treated: ", treated)
println("Control: ", control)
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))</syntaxhighlight>
{{out}}
<pre>Permutation test using the following data:
Treated: [85, 88, 75, 66, 25, 29, 83, 39, 97]
Control: [68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
There are 92378 different permuted groups of these data.
11827, 12.80% showed better than actual results.
80551, 87.20% showed equalivalent or worse results.</pre>
=={{header|Kotlin}}==
{{trans|C}}
<syntaxhighlight lang="scala">// version 1.1.2
val data = intArrayOf(
85, 88, 75, 66, 25, 29, 83, 39, 97,
68, 41, 10, 49, 16, 65, 32, 92, 28, 98
)
fun pick(at: Int, remain: Int, accu: Int, treat: Int): Int {
if (remain == 0) return if (accu > treat) 1 else 0
return pick(at - 1, remain - 1, accu + data[at - 1], treat) +
if (at > remain) pick(at - 1, remain, accu, treat) else 0
}
fun main(args: Array<String>) {
var treat = 0
var total = 1.0
for (i in 0..8) treat += data[i]
for (i in 19 downTo 11) total *= i
for (i in 9 downTo 1) total /= i
val gt = pick(19, 9, 0, treat)
val le = (total - gt).toInt()
System.out.printf("<= : %f%% %d\n", 100.0 * le / total, le)
System.out.printf(" > : %f%% %d\n", 100.0 * gt / total, gt)
}</syntaxhighlight>
{{out}}
<pre>
<= : 87.197168% 80551
> : 12.802832% 11827
</pre>
=={{header|M2000 Interpreter}}==
{{trans|C}}
<syntaxhighlight lang="m2000 interpreter">
Module Checkit {
Global data(), treat=0
data()=(85, 88, 75, 66, 25, 29, 83, 39, 97,68, 41, 10, 49, 16, 65, 32, 92, 28, 98)
Function pick(at, remain, accu) {
If remain Else =If(accu>treat->1,0):Exit
=pick(at-1,remain-1,accu+data(at-1))+If(at>remain->pick(at-1, remain, accu),0)
}
total=1
For i=0 to 8 {treat+=data(i)}
For i=19 to 11 {total*=i}
For i=9 to 1 {total/=i}
gt=pick(19,9,0)
le=total-gt
Print Format$("<= : {0:1}% {1}", 100*le/total, le)
Print Format$(" > : {0:1}% {1}", 100*gt/total, gt)
}
Checkit
</syntaxhighlight>
{{out}}
<pre><= : 87.2% 80551
> : 12.8% 11827
</pre>
Slower version, using a lambda function with a series of inner lambda functions to return each combination at a time.
<syntaxhighlight lang="m2000 interpreter">
Module CheckThis {
Function CombinationsStep (a, nn) {
c1=lambda (&f, &a) ->{=car(a) : a=cdr(a) : f=len(a)=0}
m=len(a)
c=c1
n=m-nn+1
p=2
while m>n {
c1=lambda c2=c,n=p, z=(,) (&f, &m) ->{if len(z)=0 then z=cdr(m)
=cons(car(m),c2(&f, &z)):if f then z=(,) : m=cdr(m) : f=len(m)+len(z)<n
}
c=c1
p++
m--
}
=lambda c, a (&f) ->c(&f, &a)
}
treated=(85, 88, 75, 66, 25, 29, 83, 39, 97)
placebo=(68, 41, 10, 49, 16, 65, 32, 92, 28, 98)
treat=0
m=each(treated): while m {treat+=array(m)}
total=1
for i=len(placebo)+1 to len(placebo) +len(treated):total*=i:next i
for i=len(placebo)-1 to 1: total/=i:next i
d=total div 10**int(log(total))
k=false
StepA=CombinationsStep(cons(treated, placebo),len(treated))
counter=0
gt=0
While not k {
comb=StepA(&k)
accu=0
m=each(comb)
while m {accu+=array(m)}
gt+=if(accu>treat->1,0)
counter++
if counter mod d=0 then Print over str$(counter/total," #0.0%"): Refresh 1000
}
print over str$(counter/total," #0.0%")
print
lt=total-gt
print Format$("less or equal={0:1}%, greater={1:1}%, total={2}",lt/total*100, gt/total*100, total)
}
CheckThis
</syntaxhighlight>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight 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}]</
{{out}}
<pre><=: 80551 87.1972%
>: 11827 12.8028%</pre>
=={{header|
{{trans|C}}
<syntaxhighlight lang="nim">import strformat
const data = [85, 88, 75, 66, 25,
29, 83, 39, 97, 68,
41, 10, 49, 16, 65,
32, 92, 28, 98]
func pick(at, remain, accu, treat: int): int =
if remain == 0:
return if accu > treat: 1 else: 0
return pick(at - 1, remain - 1, accu + data[at - 1], treat) +
(if at > remain:
var treat = 0
var le, gt = 0
var total = 1.0
for i in countup(0, 8):
treat += data[i]
for i in countdown(19, 11):
total *= float(i)
for i in countdown(9, 1):
total /= float(i)
gt = pick(19, 9, 0, treat)
le = int(total - float(gt))
echo fmt"<= : {100.0 * float(le) / total:.6f}% {le}"
echo fmt" > : {100.0 * float(gt) / total:.6f}% {gt}"</syntaxhighlight>
{{out}}
<pre>
<= : 87.197168% 80551
> : 12.802832% 11827
</pre>
=={{header|Perl}}==
<
use warnings;
use strict;
Line 738 ⟶ 1,261:
92
28
98</
{{out}}
equal 313 0.339%
Line 744 ⟶ 1,267:
greater 11827 12.803%
=={{header|
{{Trans|C}}
<!--<syntaxhighlight lang="phix">(phixonline)-->
<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>
<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>
<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>
<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>
<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>
<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>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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;">"<= : %f%% %d\n > : %f%% %d\n"</span><span style="color: #0000FF;">,</span>
<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>
<= : 87.197168% 80551
> : 12.802832% 11827
</pre>
=={{header|PicoLisp}}==
<syntaxhighlight lang="picolisp">(load "@lib/simul.l") # For 'subsets'
(scl 2)
(de _stat (A)
(let (LenA (length A) SumA (apply + A))
(-
(*/ SumA LenA)
(*/ (- SumAB SumA) (- LenAB LenA)) ) ) )
(de permutationTest (A B)
(let
(AB (append A B)
SumAB (apply + AB)
LenAB (length AB)
Tobs (_stat A)
Count 0 )
(*/
(sum
'((Perm)
(inc 'Count)
(and (>= Tobs (_stat Perm)) 1) )
(subsets (length A) AB) )
100.0
Count ) ) )
(setq
*TreatmentGroup (0.85 0.88 0.75 0.66 0.25 0.29 0.83 0.39 0.97)
*ControlGroup (0.68 0.41 0.10 0.49 0.16 0.65 0.32 0.92 0.28 0.98) )
(let N (permutationTest *TreatmentGroup *ControlGroup)
(prinl "under = " (round N) "%, over = " (round (- 100.0 N)) "%") )</syntaxhighlight>
{{out}}
<pre>under = 87.85%, over = 12.15%</pre>
=={{header|PureBasic}}==
Line 800 ⟶ 1,344:
the treatment group or the control group
<syntaxhighlight lang="purebasic">
Define.f meanTreated,meanControl,diffInMeans
Line 892 ⟶ 1,436:
Debug StrF(100*diffLessOrEqual/TotalComBinations,2)+" "+Str(diffLessOrEqual)
Debug StrF(100*diffGreater /TotalComBinations,2)+" "+Str(diffGreater)
</syntaxhighlight>
{{out}}
Line 899 ⟶ 1,443:
12.80 11827
</pre>
=={{header|Python}}==
{{trans|Tcl}}
<
def statistic(ab, a):
Line 922 ⟶ 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))</
{{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:
<
def permutationTest(a, b):
Line 941 ⟶ 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))</
{{out}}
<pre>under=87.20%, over=12.80%</pre>
=={{header|R}}==
<
perms <- combinations(length(treatment)+length(control),
length(treatment),
Line 998 ⟶ 1,497:
p <- mean(rowMeans(perms) <= mean(treatment))
c(under=p, over=(1-p))
}</
<
+ c(68, 41, 10, 49, 16, 65, 32, 92, 28, 98))
under over
0.8719717 0.1280283 </
=={{header|Racket}}==
{{trans|Common Lisp}}
<
(define-syntax-rule (inc! x)
Line 1,034 ⟶ 1,532:
more (real->decimal-string (* 100. (/ more sum)) 2)
leq (real->decimal-string (* 100. (/ leq sum)) 2))))
</syntaxhighlight>
{{out}}
Line 1,040 ⟶ 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 '''C''' version, with some generalizations and optimization added.
<syntaxhighlight lang="rexx">/*REXX program performs a permutation test on N + M subjects (volunteers): */
/* ↑ ↑ */
/* │ │ */
/* │ └─────control population. */
/* └────────treatment population. */
n= 9 /*define the number of the control pop.*/
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*/
say '# of volunteers & control population: ' w
say 'volunteer population given treatment: ' right(n, L)
say ' control population given a placebo: ' right(m, L)
say
say 'treatment population efficacy % (percentages): ' subword(data, 1, n)
say ' control population placebo % (percentages): ' subword(data, n+1 )
say
do v= 0 for w ; #.v= word(data, v+1) ; end
treat= 0; do i= 0 to n-1 ; treat= treat + #.i ; end
tot= 1; do j= w to m+1 by -1 ; tot= tot * j ; end
do k=w%2 to 1 by -1 ; tot= tot / k ; end
GT= picker(n+m, n, 0) /*compute the GT value from PICKER func*/
LE= tot - GT /* " " LE " via subtraction.*/
say "<= " format(100 * LE / tot, ,3)'%' LE /*display number with 3 decimal places.*/
say " > " format(100 * GT / tot, ,3)'%' GT /* " " " " " " */
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
picker: procedure expose #. treat; parse arg it,rest,eff /*get the arguments.*/
if rest==0 then return eff > treat /*is REST = to zero?*/
if it>rest then q= picker(it-1, rest, eff) /*maybe recurse. */
else q= 0
itP= it - 1 /*set temporary var.*/
return picker(itP, rest - 1, eff + #.itP) + q /*recurse. */</syntaxhighlight>
{{out|output|text= when using the default input:}}
<pre>
# of volunteers & control population: 19
volunteer population given treatment: 9
control population given a placebo: 10
treatment population efficacy % (percentages): 85 88 75 66 25 29 83 39 97
control population placebo % (percentages): 68 41 10 49 16 65 32 92 28 98
<= 87.197% 80551
> 12.803% 11827
</pre>
=={{header|Ruby}}==
{{trans|Python}}
<
sumab, suma = ab.inject(:+).to_f, a.inject(:+).to_f
suma / a.size - (sumab - suma) / (ab.size - a.size)
Line 1,063 ⟶ 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]</
{{out}}
Line 1,069 ⟶ 1,649:
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>
=={{header|Scala}}==
===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)].
<syntaxhighlight lang="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)
private var (total, treat) = (1.0, 0)
private def pick(at: Int, remain: Int, accu: Int, treat: Int): Int = {
if (remain == 0) return if (accu > treat) 1 else 0
pick(at - 1, remain - 1, accu + data(at - 1), treat) +
(if (at > remain) pick(at - 1, remain, accu, treat) else 0)
}
for (i <- 0 to 8) treat += data(i)
for (j <- 19 to 11 by -1) total *= j
for (g <- 9 to 1 by -1) total /= g
private val gt = pick(19, 9, 0, treat)
private val le = (total - gt).toInt
println(f"<= : ${100.0 * le / total}%f%% ${le}%d")
println(f" > : ${100.0 * gt / total}%f%% ${gt}%d")
}</syntaxhighlight>
=={{header|Seed7}}==
<
include "float.s7i";
Line 1,109 ⟶ 1,778:
writeln("<= : " <& 100.0 * flt(le) / flt(total) digits 6 <& "% " <& le);
writeln(" > : " <& 100.0 * flt(gt) / flt(total) digits 6 <& "% " <& gt);
end func;</
{{out}}
<= : 87.197168% 80551
> : 12.802832% 11827
=={{header|Sidef}}==
{{trans|Ruby}}
<syntaxhighlight lang="ruby">func statistic(ab, a) {
var(sumab, suma) = (ab.sum, a.sum)
suma/a.size - ((sumab-suma) / (ab.size-a.size))
}
func permutationTest(a, b) {
var ab = (a + b)
var tobs = statistic(ab, a)
var under = (var count = 0)
ab.combinations(a.len, {|*perm|
statistic(ab, perm) <= tobs && (under += 1)
count += 1
})
under * 100 / count
}
var treatmentGroup = [85, 88, 75, 66, 25, 29, 83, 39, 97]
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))</syntaxhighlight>
{{out}}
<pre>
under=87.20%, over=12.80%
</pre>
=={{header|Tcl}}==
<
# Difference of means; note that the first list must be the concatenation of
Line 1,164 ⟶ 1,857:
set count [tcl::mathfunc::double $count]
list [expr {$overcount / $count}] [expr {$undercount / $count}]
}</
Demonstration code:
<
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}]]</
{{out}}
<pre>under=86.90%, over=13.10%</pre>
=={{header|Ursala}}==
<
#import nat
#import flo
Line 1,189 ⟶ 1,882:
#show+
t = --* *-'%'@lrNCC printf/$'%0.2f' times/$100. f(treatment_group,control_group)</
{{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}}
<
ab := a.extend(b);
tObs := a.sum(0);
Line 1,209 ⟶ 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));</
{{out}}
<pre>
|