/********************************************************
* Speaker Verification Implemented Security *
* CA4 Project *
* Written by: Ronan Crowley (97084603) *
* and Paul Connolly (97307599) *
********************************************************/
// This class calculates the threshold value for a user. the threshold is calculated
// from 5 anti users. This class is given the log likelihood sum values from
// 5 antispeakers. It calculates the mean and standard deviation of the anti speaker
// samples. the threshold is calculated as the mean of the anti speakers plus 1.2.....
// times the standard deviation.
/* sample use
calcThreshold thresholdobject = new calcThreshold();
double threshold = thresholdobject.getThreshold(username, zvalue);
*/
import java.io.*;
import java.util.*;
import java.lang.*;
public class calcThreshold
{
private static int datasize =25;
/** Empty Constructor **/
public void calcThreshold()
{
}
/** Method that is geiven a username and accuracy required vale as argument. It reads 25 values
from an antithreshold file and 5 values from a threshold file. It returns a threshold value.
**/
static public double getThreshold(String username, double accuracy)
{
// Local Variables !
String theLine;
double[] data;
data = new double[datasize];
double[] data1;
data1 = new double[5];
double mean = 0.0;
double mean1 = 0.0;
double stddev=0.0;
double stddev1=0.0;
double probRejectUser=0.0;
double probAcceptWrongUser=accuracy;
try {
// Read Strings from antithreshold.txt and convert them to doubles !
// DEPRECATED:
// DataInputStream input = new DataInputStream(new FileInputStream("users\\"+username+"\\antithreshold.txt"));
BufferedReader input = new BufferedReader(new FileReader("users\\"+username+"\\antithreshold.txt"));
int i=0;
while ((theLine = input.readLine()) != null) {
//Create 25 doubles.....
try {
data[i] = Double.valueOf(theLine.trim()).doubleValue();
} catch (NumberFormatException nfe) {
System.out.println("NumberFormatException: " + nfe.getMessage());
}
i++;
}
input.close();
// Read Strings from threshold.txt and convert them to doubles !
// DEPRECATED:
// DataInputStream input1 = new DataInputStream(new FileInputStream("users\\"+username+"\\threshold.txt"));
BufferedReader input1 = new BufferedReader(new FileReader("users\\"+username+"\\threshold.txt"));
i=0;
while ((theLine = input1.readLine()) != null) {
//Create 5 doubles.....
try {
data1[i] = Double.valueOf(theLine.trim()).doubleValue();
} catch (NumberFormatException nfe) {
System.out.println("NumberFormatException: " + nfe.getMessage());
}
i++;
}
input1.close();
}
catch (IOException e) {
System.err.println("IOException: " + e);
}
//Calculate mean for antithreshold values
mean =mean(data);
System.out.println("MEAN OF INCORRECT: "+mean);
//calculate standard deviation for antithreshold values
stddev=std(data,mean);
System.out.println("STD of INCORRECT: "+stddev);
//Calculate mean for threshold values
mean1 =mean1(data1);
System.out.println("MEAN OF CORRECT: "+mean1);
//calculate standard deviation of threshold values
stddev1=std1(data1,mean1);
System.out.println("STD of CORRECT: "+stddev1);
//Calculate threshold
double threshold = mean+(accuracy*stddev);
System.out.println("THRESHOLD "+threshold);
//calculate prob of rejecting the user
probRejectUser = ((threshold-mean1)/stddev1);
System.out.println("PROB REJECTING USER in z form: "+probRejectUser);
//convert to 5 format
probRejectUser=zToPercent(probRejectUser);
System.out.println("PROB REJECTING USER in % form: "+probRejectUser);
System.out.println("PROB Accpet anti user z form: "+probAcceptWrongUser);
//convert to % format
probAcceptWrongUser=zToPercent(probAcceptWrongUser);
System.out.println("PROB Accpet anti user z form: "+probAcceptWrongUser);
//Write Threshold value to t.txt in user's directory
try
{
PrintWriter tout = new PrintWriter( new FileWriter( "users\\"+username+"\\t.txt" ) );
tout.println(threshold); //Line 1 = Threshold
tout.println(accuracy); //Line 2 = Accuracy Reference (initially 1.2817 = 10%)
tout.println(probAcceptWrongUser); //Line 3 = % Chance of accepting incorrect user
tout.println(probRejectUser); //Line 4 = % Chance of rejecting correct user
tout.close();
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
return threshold;
}
/** Method to calculate the mean of the data (5 values from threshold.txt).
@param data = The array of doubles whose mean is being calculated.
**/
static public double mean1(double[] data)
{
double sum=0.0;
for (int i=0;i<5;i++ )
{
sum+=data[i];
}
return (sum/datasize);
}
/** Method to calculate the mean of the data (25 values from antithreshold.txt).
@param data = The array of doubles whose mean is being calculated.
**/
static public double mean(double[] data)
{
double sum=0.0;
for (int i=0;i<datasize;i++ )
{
sum+=data[i];
}
return (sum/datasize);
}
/** Method to calculate Standard Deviation
@param data = The array of doubles whose Standard Deviation is being calculated.
@param mean = The mean of the values int the array of doubles also passed in.
**/
static public double std(double[] data, double mean)
{
double totaldev= 0.0; //sum of deviations
// Sum the deviations
for(int i=0; i < datasize; i++){
totaldev += Math.pow((data[i] - mean),2);
}
//Divide the total deviations by n-1 and get square root
return Math.sqrt(totaldev/24);
}
/** Method to calculate Standard Deviation
@param data = The array of doubles whose Standard Deviation is being calculated.
@param mean = The mean of the values int the array of doubles also passed in.
**/
static public double std1(double[] data, double mean)
{
double totaldev= 0.0; //sum of deviations
// Sum the deviations
for(int i=0; i < 5; i++){
totaldev += Math.pow((data[i] - mean),2);
}
//Divide the total deviations by n-1 and get square root
return Math.sqrt(totaldev/4);
}
/** method which when given a z values, returns the percentage this z value represents **/
public static double zToPercent(double zvalue)
{
//enure zvalue is in absolute format
if (zvalue<0){
zvalue=zvalue * (-1);
}
if (zvalue>=3.7191){
return 0.0001;
}
else if (zvalue>=3.2908){
return 0.0005;
}
else if (zvalue>=3.0905){
return 0.001;
}
else if (zvalue>=2.5762){
return 0.005;
}
else if (zvalue>=2.3268){
return 0.01;
}
else if (zvalue>=2.0542){
return 0.02;
}
else if (zvalue>=1.6452){
return 0.05;
}
else if (zvalue>=1.2817){
return 0.10;
}
else if (zvalue>=1.0364){
return 0.15;
}
else if (zvalue>=0.8415){
return 0.20;
}
else if (zvalue>=0.6742){
return 0.25;
}
else
return 0.0;
}
/** Method which when given a percentage required, returns the closest z value.**/
public static double percentToZ(double percent)
{
if (percent>=.5)
return 0.0000;
else if (percent>=0.25)
return 0.6742;
else if (percent>=0.20)
return 0.8415;
else if (percent>=0.15)
return 1.0364;
else if (percent>=0.10)
return 1.2817;
else if (percent>=0.05)
return 1.6452;
else if (percent>=0.02)
return 2.0542;
else if (percent>=0.01)
return 2.3268;
else if (percent>=0.001)
return 3.0905;
else if (percent>=0.0005)
return 3.2908;
else if (percent>=0.0001)
return 3.7101;
else return 0.0;
}
/** Main method to allow for standalone testing ! **/
public static void main(String args[])
{
//double[] data={-1727,-4697,-4360,-7713,-6470,-2871,-3668,-3016,-1728,-2697,-2525,-2903,-3444,-4171,-4349,-3107,-5266,-3974,-8256,-7455,-2380,-4238,-4479,-4189,-5149};
double threshold;
threshold=getThreshold(args[0], 1.2817);
}
}