Changeset 848


Ignore:
Timestamp:
Nov 15, 2009, 9:09:37 PM (12 years ago)
Author:
malischewski
Message:

Added Cost-functions: Bigram log 2, sinkov, percentaged from Enigma Plugin (These use Enigma_*gram_Frequency.txt at the moment)

Location:
trunk/CrypPlugins/CostFunction
Files:
3 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/CrypPlugins/CostFunction/CostFunction.cs

    r834 r848  
    2525using System.ComponentModel;
    2626using Cryptool.PluginBase.Control;
    27 
     27using System.IO;
    2828namespace Cryptool.Plugins.CostFunction
    2929{
     
    3939        private Boolean stopped = true;
    4040        private IControlCost controlSlave;
    41         #endregion
    42 
    43         #region CostFunctionInOut       
     41        private String bigramInput;
     42               
     43
     44
     45        private IDictionary<int, IDictionary<string, double[]>> statistics;
     46     
     47        #endregion
     48        #region internal constants
     49        internal const int ABSOLUTE = 0;
     50        internal const int PERCENTAGED = 1;
     51        internal const int LOG2 = 2;
     52        internal const int SINKOV = 3;
     53        #endregion
     54        #region CostFunctionInOut
    4455
    4556        [PropertyInfo(Direction.InputData, "Text Input", "Input your Text here", "", DisplayLevel.Beginner)]
     
    7182        }
    7283
    73         [PropertyInfo(Direction.OutputData, "Value", "The value of the function wull be send here", "", DisplayLevel.Beginner)]
     84        [PropertyInfo(Direction.OutputData, "Value", "The value of the function will be send here", "", DisplayLevel.Beginner)]
    7485        public double Value
    7586        {
     
    162173
    163174                ProgressChanged(0.5, 1);
    164 
     175                bigramInput = ByteArrayToString(array);
    165176                switch (settings.FunctionType)
    166177                {
     
    174185                        break;
    175186
     187                    case 2: // Log 2 Bigrams
     188                        this.Value = calculateNGrams(bigramInput,2,2);
     189                        break;
     190
     191                    case 3: // sinkov Bigrams
     192                        this.Value = calculateNGrams(bigramInput,2,3);
     193                        break;
     194                    case 4: //percentaged Bigrams
     195                        this.Value = calculateNGrams(bigramInput,2,1);
     196                        break;
    176197                    default:
    177198                        this.Value = -1;
     
    304325        }//end calculateEntropy
    305326
     327
     328        /// <summary>
     329        /// This method calculates a trigram log2 score of a given text on the basis of a given grams dictionary.
     330        /// Case is insensitive.
     331        /// </summary>
     332        /// <param name="input">The text to be scored</param>
     333        /// <param name="length">n-gram length</param>
     334        /// <returns>The trigram score result</returns>
     335        public double calculateNGrams(string input, int length, int valueSelection)
     336        {
     337            this.statistics = new Dictionary<int, IDictionary<string, double[]>>();
     338            double score = 0;
     339            IDictionary<string, double[]> corpusGrams = GetStatistics(length);
     340
     341            // FIXME: case handling?
     342
     343            HashSet<string> inputGrams = new HashSet<string>();
     344
     345            foreach (string g in GramTokenizer.tokenize(input, length, false))
     346            {
     347                // ensure each n-gram is counted only once
     348                if (inputGrams.Add(g))
     349                {
     350                    if (corpusGrams.ContainsKey(g))
     351                    {
     352                        score += corpusGrams[g][valueSelection];
     353                        GuiLogMessage(input, NotificationLevel.Info);
     354           
     355                    }
     356                }
     357            }
     358            return score;
     359        }
     360        public IDictionary<string, double[]> GetStatistics(int gramLength)
     361        {
     362            // FIXME: inputTriGrams is not being used!
     363
     364            // FIXME: implement exception handling
     365            if (!statistics.ContainsKey(gramLength))
     366            {
     367                GuiLogMessage("Trying to load default statistics for " + gramLength + "-grams", NotificationLevel.Info);
     368                statistics[gramLength] = LoadDefaultStatistics(gramLength);               
     369            }
     370
     371            return statistics[gramLength];
     372        }
     373
     374
     375        private IDictionary<string, double[]> LoadDefaultStatistics(int length)
     376        {
     377            Dictionary<string, double[]> grams = new Dictionary<string, double[]>();
     378
     379            StreamReader reader = new StreamReader(Path.Combine(PluginResource.directoryPath, GetStatisticsFilename(length)));
     380
     381            string line;
     382            while ((line = reader.ReadLine()) != null)
     383            {
     384                if (line.StartsWith("#"))
     385                    continue;
     386
     387                string[] tokens = WordTokenizer.tokenize(line).ToArray();
     388                if (tokens.Length == 0)
     389                    continue;
     390                //Debug.Assert(tokens.Length == 2, "Expected 2 tokens, found " + tokens.Length + " on one line");
     391
     392                grams.Add(tokens[0], new double[] { Double.Parse(tokens[1]), 0, 0, 0 });
     393            }
     394
     395            double sum = grams.Values.Sum(item => item[ABSOLUTE]);
     396            GuiLogMessage("Sum of all n-gram counts is: " + sum, NotificationLevel.Debug);
     397
     398            // calculate scaled values
     399            foreach (double[] g in grams.Values)
     400            {
     401                g[PERCENTAGED] = g[ABSOLUTE] / sum;
     402                g[LOG2] = Math.Log(g[ABSOLUTE], 2);
     403                g[SINKOV] = Math.Log(g[PERCENTAGED], Math.E);
     404            }
     405
     406            return grams;
     407        }
     408
     409        /// <summary>
     410        /// Get file name for default n-gram frequencies.
     411        /// </summary>
     412        /// <param name="length"></param>
     413        /// <exception cref="NotSupportedException">No default n-gram frequencies available</exception>
     414        /// <returns></returns>
     415        private string GetStatisticsFilename(int length)
     416        {
     417            if (length < 1)
     418            {
     419                throw new ArgumentOutOfRangeException("There is no known default statistic for an n-gram length of " + length);
     420            }
     421
     422            return "Enigma_" + length + "gram_Frequency.txt";
     423        }
     424        public string ByteArrayToString(byte[] arr)
     425        {
     426            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
     427            return enc.GetString(arr);
     428        }
     429
     430
    306431        #endregion
    307432
     
    353478                case 1: //Entropy
    354479                    return RelationOperator.LessThen;
     480                case 2: // Bigrams: log 2
     481                    return RelationOperator.LargerThen;
    355482                default:
    356483                    throw new NotImplementedException("The value " + ((CostFunctionSettings)this.plugin.Settings).FunctionType + " is not implemented.");
     
    405532                case 1: //Entropy
    406533                    return plugin.calculateEntropy(array);
     534                case 2: // Bigrams: log 2
     535                    return plugin.calculateNGrams(plugin.ByteArrayToString(array), 2, 2);
     536                case 3: // Bigrams: Sinkov
     537                    return plugin.calculateNGrams(plugin.ByteArrayToString(array), 2, 3);
     538                case 4: // Bigrams: Percentaged
     539                    return plugin.calculateNGrams(plugin.ByteArrayToString(array), 2, 1);
    407540                default:
    408541                    throw new NotImplementedException("The value " + ((CostFunctionSettings)this.plugin.Settings).FunctionType + " is not implemented.");
     
    414547   
    415548}
     549
  • trunk/CrypPlugins/CostFunction/CostFunction.csproj

    r692 r848  
    44    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    55    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    6     <ProductVersion>9.0.21022</ProductVersion>
     6    <ProductVersion>9.0.30729</ProductVersion>
    77    <SchemaVersion>2.0</SchemaVersion>
    88    <ProjectGuid>{3C72FF93-48C2-4929-B3B2-83F165AAE636}</ProjectGuid>
     
    7171    <Resource Include="icon.png" />
    7272  </ItemGroup>
     73  <ItemGroup>
     74    <None Include="Enigma_1gram_Frequency.txt">
     75      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     76    </None>
     77  </ItemGroup>
     78  <ItemGroup>
     79    <None Include="Enigma_3gram_Frequency.txt">
     80      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     81    </None>
     82  </ItemGroup>
     83  <ItemGroup>
     84    <None Include="Enigma_2gram_Frequency.txt">
     85      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     86    </None>
     87  </ItemGroup>
    7388  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
    7489  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
  • trunk/CrypPlugins/CostFunction/CostFunctionSettings.cs

    r761 r848  
    3333        #endregion
    3434       
    35         [TaskPane("FunctionType", "Select the type of function", null, 1, false, DisplayLevel.Beginner, ControlType.ComboBox, new string[] { "Index of coincidence", "Entropy" })]
     35        [TaskPane("FunctionType", "Select the type of function", null, 1, false, DisplayLevel.Beginner, ControlType.ComboBox, new string[] { "Index of coincidence", "Entropy", "Bigrams: log 2", "Bigrams: Sinkov", "Bigrams: Percentaged" })]
    3636        public int FunctionType
    3737        {
Note: See TracChangeset for help on using the changeset viewer.