Скачиваний:
24
Добавлен:
01.05.2014
Размер:
9 Кб
Скачать
/*
 * $Id: Distribution.java 138 2006-03-20 18:30:51Z ip $
 *
 */
package ru.iplabs.eltech.sem10.qual_4;

import java.text.NumberFormat;
import java.util.Arrays;
import java.util.Random;

/**
 * 
 * @author Poukhkal Ivan
 * <p>Класс представляет собой обобщение "распределения" и содержив большей частью те операции, 
 * которые требуется выполнить в конкретной лабрабстуд #4. Зачем сделан абстрактным? Хо-о-роший 
 * вопрос.</p>
 */
public abstract class Distribution {

    /**
     * <p>Массив данных (об ошибках). В работе их не больше 30.</p>
     */
    protected double[] data;
    
    /**
     * <p>Некая интегральная оценка для ошибок. Используется в критерии проверки для hat B и в 
     * функции g. @see Конспект</p>
     */
    private double A = 0.0;
    
    private NumberFormat form = NumberFormat.getInstance();


    /**
     * <p>Устанавливает формат вывода всех числовых данных.</p>
     * @param mind <p>Минимальное число знаков после запятой при выводе double's</p>
     * @param maxd <p>Максимальное число знаков после запятой при выводе double's</p>
     */
    private void setFloatFormat(int mind, int maxd) {
        form.setMaximumFractionDigits(maxd);
        form.setMinimumFractionDigits(mind);
    }
    
    /**
     * <p>Раз конструктор. Принимает на вход размер массива, создает его и ничего больше не делает.
     * После него нужно вручную применять <code>generation</code>.</p>
     * @param n число элементов массива
     */
    public Distribution(int n) {
        data = new double[n];
        setFloatFormat(0, 3);
    } 
    
    /**
     * <p>Два конструктор. Принимает на вход массив и копирует его себе.</p>
     * @param vector массив, который уже содержит данные
     */
    public Distribution(double[] vector) {
        data = new double[vector.length];
        for (int i = 0; i <= vector.length-1; i++) {
            data[i] = vector[i];
        }
        setFloatFormat(0, 3);
    }

    /**
     * <p>Три конструктор. Принимает на вход массив и копирует <code>perc</code> его процентов 
     * себе, начиная с индекса 0. Нужно в определенных местах л/р.</p>
     * @param vector массив, который уже содержит данные
     * @param perc сколько процентов отщипнуть (число от 0 до 1)   
     */
    public Distribution(double[] vector, double perc) {
        int len = (int)Math.round(vector.length*perc);
        data = new double[len];
        for (int i = 0; i <= (len-1); i++) {
            data[i] = vector[i];
        }
        setFloatFormat(0, 3);
    }
    
    /**
     * <p>Функция преобразования. Делает из равномерного распределения какое-нибудь другое.
     * Определением ее - головная боль исключительно потомков.</p> 
     */
    public abstract void transform();

    /**
     * <p>Заполняет массив равномерно распределенными случайными числами. Затем молча их сортирует, 
     * поскольку того хочет лабораторная работа.</p>
     * @param range правая граница для генератора СЧ
     */
    public void generation(int range) {
        Random counter = new Random();
        for (int i = 0; i <= data.length-1; i++) {
            data[i] = counter.nextInt(range);
        }
        Arrays.sort(data);
    }


    /**
     * <p>Возвращает распределение в формате TeX'овской таблицы.</p> 
     */
    public String getDataTeXFormat() {
            StringBuffer result = new StringBuffer();
            result.append("\\hline \n");
            int i = 0;
            while (i <= data.length-1) {
                result.append(form.format(data[i]));
                if ((i+1)%6 != 0) {
                    result.append(" & ");
                }
                else {
                    result.append("\\\\\n\\hline\n");
                }
                i++;
            }
            
            return result.toString();
        }

    /**
     * @return Возвращает массив данных.
     */
    public double[] getData() {
        return data;
    }

    /**
     * @param data The data to set.
     */
    public void setData(double[] data) {
        this.data = data;
    }

    /**
     * <p>Проверяет существование hat B.</p>
     * @see Конспект
     * @return <p>существует ли hat B</p> 
     */
    public boolean existsBHat() {
        A = sumiXi() / sumXi();
        
        if (A > (data.length + 1)/2) {
            return true;
        }
        else {
            return false;
        }
    }

    /**
     * <p>Возвращает все необходимые расчеты для A, B и т.д. в формате TeX. Для получение всех цифр, 
     * начиная с hat B, вызывает <code>calcAndPrint</code>.</p>
     * @return TeX текст 
     */
    public String getCheckingTeXFormat() {
        StringBuffer out = new StringBuffer();
        out.append("\n$$\n");
        out.append("A = \\frac{\\sum_{i=1}^n(i X_i)}{\\sum_{i=1}^n(X_i)} = ");
        boolean cond = existsBHat();
        out.append(form.format(A));
        double leftval = (data.length + 1)/2d;
        if (cond) {
            out.append(" > "+form.format(leftval));
            out.append("\n$$\n");
            out = calcAndPrint(out);
        }
        else {
            out.append(" < "+form.format(leftval));
            out.append("\n$$\n");
            out.append("\n$$\n");
            out.append("B = \\infty");
            out.append("\n$$\n");
        }
        return out.toString();
    }
    
    /**
     * <p>Функция f. Ничего больше.</p>
     * @see Конспект
     * @return double 
     */
    private double f(int m) {
        double result = 0.0;
        for (int i = 1; i <= data.length; i++) {
            result += 1/(double)(m-i); 
        }
        return result;
    }
    
    /**
     * <p>Функция g. Ничего больше.</p>
     * @see Конспект 
     * @return double 
     */
    private double g(int m, double A) {
        return (data.length/(m - A));
    }
    
    /**
     * <p>Сумма i*Xi. Ничего больше.</p>
     * @see Конспект 
     * @return double 
     */
    private double sumiXi() {
        double sum = 0.0;
        
        for (int i = 0; i <= data.length - 1; i++) {
            sum += data[i] * (i+1);
        }
        return sum;
    }

    /**
     * <p>Сумма Xi. Ничего больше.</p>
     * @see Конспект 
     * @return double 
     */
    private double sumXi() {
        double sum = 0.0;
        
        for (int i = 0; i <= data.length - 1; i++) {
            sum += data[i];
        }
        return sum;
    }
    
    /**
     * <p>Рассчитывает все параметры (hat B, hat K, t_tst) и выводит все в TeX.</p>
     * @return StringBuffer, в котором лежит все, что только надо 
     */
    public StringBuffer calcAndPrint(StringBuffer out) {
        double KHat = 0.0;
        double ttest = 0.0;  
        int BHat = 0;
        int m = data.length + 1;
        double mindiff = Double.MAX_VALUE; // разность между функциями f и g
        double diff = Math.abs(f(m) - g(m, A));

        out.append("\n\\hline\n");
        out.append("$m$ & $f_m$ & $g_m(A)$ & $|f_m - g_m(A)|$ \\\\\n");
        
        while (mindiff > diff) {
            out.append("\\hline\n");
            out.append(m+" & "+form.format(f(m))+" & "+form.format(g(m, A))+" & "
                    +form.format(diff)+" \\\\\n");
            mindiff = diff;
            m++;
            diff = Math.abs(f(m) - g(m, A));
        }
        out.append("\\hline\n");
        out.append(m+" & "+form.format(f(m))+" & "+form.format(g(m, A))+" & "
                +form.format(diff)+" \\\\\n");
        out.append("\\hline\n");
        
        out.append("Минимальная разница (" + form.format(mindiff) + ") достигается при $m = " + (m-1)+"$\n");
        
        BHat = m - 2; 
        out.append("\n$$\n");
        out.append("\\hat B = "+BHat + " \\text{ ошибок}");
        out.append("\n$$\n");
        
        KHat = data.length / (BHat * sumXi() - sumiXi());
        setFloatFormat(0, 4);
        out.append("\n$$\n");
        out.append("\\hat K = "+form.format(KHat));
        out.append("\n$$\n");
        setFloatFormat(0, 3);
            
        double t_sum = 0.0;
        for (int i = 1; i <= BHat - data.length; i++) {
            t_sum += 1/(double)i; 
        }
        
        ttest = 1/KHat * t_sum;
        
        out.append("\nВремя до полного окончания тестирования --- "+form.format(Math.round(ttest)) + " дней.\n");
        
        double xi = 0.0;
        out.append("\n\\hline\n");
        out.append("Номер ошибки & Через дней \\\\\n");
        for (int i = data.length+1; i <= Math.min(data.length + 5, BHat); i++) {
            xi = 1 / (KHat * (BHat - (i-1)));
            out.append("\\hline\n");
            out.append(i+" & "+form.format(Math.round(xi))+" \\\\\n");
            
        }
        out.append("\\hline\n");

        return out;
    }
    
}
Соседние файлы в папке qual_4