Einzelnen Beitrag anzeigen

Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#11

Re: Mittelwert und Standardabweichung

  Alt 22. Apr 2006, 00:01
Hi

du solltest mehrere Dinge berücksichtigen bei dieser Datenmenge:

1.) mit Stream arbeiten, statt den alten Blockread() etcpp.
2.) mit Buffern arbeiten, dh. deine Daten werden in einen Bufferspeicher geladen und von da ausgewertet
3.) die Konvertierung der Strings live durchführen, quasi "on the fly"
4.) die Berechnung des Durchschnittes und der Standardabweichung mit einer speziellen Formel durchführen. Dabei wird die normale Formel der Standardabweichung so umgestellt das sie auf Grund des Binomials nun sequientiell berechnet werden kann. Man kann also sequientiell deine Zahlen einlesen und wiederum "on the fly" diese Werte berechnen.

Anbei mal ein Lösungsvorschlag:

Delphi-Quellcode:
procedure XYZ;
const
  BufferSize = 1024 * 4;
var
  Stream: TFileStream;
  Buffer: String;
  Value: Integer; // aktuelle Zahl in der Datei
  ValueSign: Integer; // Vorzeichen von Value
  ValueCount: Integer; // Anzahl der gelesenen Zahlen aus der Datei
  ValueValid: Boolean; // enthält Value eine gültige Zahl ?
  Avg: Double; // kummulierte Summe aller Zahlen -> Avg / ValueCount == Durchschnitt
  Dev: Double; // kummulierte Quadrate aller Zahlen -> Dev * ValueCount - Avg / (ValueCount * (ValueCount -1)) == Standardabweichung
  CurChar,EndChar: PChar; // Anfang/Ende des Buffer
  Symbol: Char; // aktuell auszuwertende Ziffer/Buchstabe
begin
// initialisierung
  CurChar := nil;
  EndChar := nil;
  Value := 0;
  ValueSign := +1;
  ValueValid := False;
  ValueCount := 0;
  Avg := 0;
  Dev := 0;
// Buffer allozieren, Stream öffnen
  SetLength(Buffer, BufferSize);
  Stream := TFileStream.Create('Filename', fmOpenRead or fmShareDenyNone);
  try
    repeat
    // solange noch Zeichen im Buffer diese in Zahlen umwandeln
      while CurChar < EndChar do
      begin
        Symbol := CurChar^;
        if Symbol in ['0'..'9'] then
        begin // String in Zahl umwandeln
          Value := Value * 10 + Ord(Symbol) - Ord('0');
          ValueValid := True;
        end else
          if ValueValid then
          begin // falls in Value eine gültige Zahl war diese in Avg/Dev kummulieren
            Value := Value * ValueSign;
            Avg := Avg + Value;
            Dev := Dev + Sqr(Value);
            Inc(ValueCount);
            // 1.)
            ValueValid := False;
            Value := 0;
            ValueSign := +1;
          end else
            if Symbol = '-then
              ValueSign := -1;
        Inc(CurChar);
      end;
    // Buffer aus Datei laden
      CurChar := PChar(Buffer);
      EndChar := CurChar + Stream.Read(Buffer[1], BufferSize);
    until EndChar = CurChar;
    if ValueValid then
    begin // letzte eventuell nicht per Leerzeichen abgeschlossene Zahl berücksichtigen
      Value := Value * ValueSign;
      Avg := Avg + Value;
      Dev := Dev + Sqr(Value);
      Inc(ValueCount);
    end;
  finally
    Stream.Free;
  end;
// Standardabweichung berechnen
  Dev := (Dev * ValueCount - Sqr(Avg)) / (Sqr(ValueCount) - ValueCount);
// Durchschnitt berechnen
  Avg := Avg / ValueCount;
// Auf Grund obiger Formeln kann die Standardabweichung und der Durchschnitt zu jedem
// Zeitpunkt in Source bei 1.) fortlaufend berechnet werden -> also sequientiell
end;
Gruß hagen
  Mit Zitat antworten Zitat