Скачиваний:
31
Добавлен:
01.05.2014
Размер:
2 Кб
Скачать
unit ContingencyTables;

interface

  uses
    dmmTypes,
    Statistics,
    Utils;

  function chiSquared(matrix : D2DArray; yates : boolean) : double;
  function chiVal(matrix :D2DArray; useYates : boolean) : double ;
  function chiCell(freq : double; expected : double; yates : boolean) : double;

implementation
  
  function chiSquared(matrix : D2DArray; yates : boolean) : double;
  var
    df : integer;
  begin
    df := (length(matrix) - 1) * (length(matrix[0]) - 1);
    result := Statistics.chiSquaredProbability(chiVal(matrix, yates), df);
  end;

  function chiVal(matrix :D2DArray; useYates : boolean) : double ;
  var
    df, nrows, ncols, row, col : integer;
    rtotal, ctotal : DArray;
    expect, chival, n : double;
    yates : boolean;
  begin
    expect := 0;
    chival := 0;
    n := 0;
    yates := true;

    nrows := length(matrix);
    ncols := length(matrix[0]);
    SetLength(rtotal, nrows);
    SetLength(ctotal, ncols);

    row := 0;
    while ( row < nrows ) do
    begin
      col := 0;
      while ( col < ncols) do
      begin
	      rtotal[row] := rtotal[row] + matrix[row][col];
	      ctotal[col] := ctotal[col] + matrix[row][col];
	      n := n + matrix[row][col];
        inc(col)
      end;
      inc(row);
    end;
    df := (nrows - 1)*(ncols - 1);
    if ((df > 1) or (not useYates)) then
      yates := false
    else
      if (df <= 0) then
      begin
        result := 0;
        exit;
      end;
    chival := 0.0;

    row := 0;
    while ( row < nrows) do
    begin
      if (Utils.gr(rtotal[row], 0)) then
      begin
        col := 0;
  	    while ( col < ncols) do
        begin
	        if (Utils.gr(ctotal[col], 0)) then
          begin
	          expect := (ctotal[col] * rtotal[row]) / n;
	          chival := chival + chiCell (matrix[row][col], expect, yates);
          end;
          inc(col);
	      end;
      end;
      inc(row);
    end;
    result := chival;
  end;

  function chiCell(freq : double; expected : double; yates : boolean) : double;
  var
    diff : double;
  begin
    if (Utils.smOrEq(expected, 0)) then
    begin
      result := 0;
      exit;
    end;

    diff := abs(freq - expected);
    if (yates) then
    begin
      diff := diff - 0.5;

      if (diff < 0) then  diff := 0;
    end;

    result:= (diff * diff / expected);
  end;

end.
Соседние файлы в папке DMCore