public static double[] ClassicalAttackXORAPUFMultiRecovered(int bitNumber, int attackRepeatNumber, InvariantData invData, VariantData[] variantDataArray) { //Create the XOR APUF for parallel runs XORArbiterPUF[] xArray = new XORArbiterPUF[attackRepeatNumber]; for (int i = 0; i < xArray.Length; i++) { xArray[i] = (XORArbiterPUF)invData.GetPUFatIndex(i); } sbyte[][] trainingData = invData.GetTrainingData(); //these will be phi vectors sbyte[][] allTrainingResponses = invData.GetTrainingResponseAll(); //first index PUF, second index sample //create the objective function for parallel runs ObjectiveFunctionResponseXOR[] rObjArray = new ObjectiveFunctionResponseXOR[attackRepeatNumber]; for (int i = 0; i < rObjArray.Length; i++) { rObjArray[i] = new ObjectiveFunctionResponseXOR(); } double[][] solutionList = new double[attackRepeatNumber][]; Random[] randomGeneratorArray = new Random[attackRepeatNumber]; for (int r = 0; r < attackRepeatNumber; r++) { randomGeneratorArray[r] = new Random((int)DateTime.Now.Ticks); System.Threading.Thread.Sleep(10); //prevent the random number generators from being the same } var watch = System.Diagnostics.Stopwatch.StartNew(); Parallel.For(0, attackRepeatNumber, a => { Random randomGenerator = randomGeneratorArray[a]; //remove the dependences for parallelization int dimensionNumber = (bitNumber + 1) * xArray[a].GetPUFNum(); //the weights of all the XOR APUFs sbyte[] trainingResponse = allTrainingResponses[a]; //Generate the first solution randomly for CMA-ES double[] firstSolution = new double[dimensionNumber]; for (int i = 0; i < firstSolution.Length; i++) { firstSolution[i] = randomGenerator.NextDouble(); } Console.Out.WriteLine("Beginning CMA-ES run # " + a.ToString()); //CMAESCandidate solutionCMAES = CMAESMethods.ComputeCMAES(dimensionNumber, rObjArray[a], trainingData, trainingResponse, firstSolution, randomGenerator); CMAESCandidate solutionCMAES = CMAESMethods.RecoveredCMAES(randomGenerator, a, rObjArray[a], invData, variantDataArray[a]); double solutionVal = solutionCMAES.GetObjectiveFunctionValue(); solutionList[a] = solutionCMAES.GetWeightVector(); //store the solution in independent memory Console.Out.WriteLine("CMA-ES on core " + a.ToString() + " finished."); //Console.Out.WriteLine("Final training value is "+solutionVal.ToString()); //} }); watch.Stop(); Console.Out.WriteLine("Elapsed Time is " + watch.ElapsedMilliseconds.ToString()); //measure the accuracy Random randomGenerator2 = new Random((int)DateTime.Now.Ticks); double averageAccuracy = 0; double[] solutionAccuracies = new double[attackRepeatNumber]; for (int a = 0; a < solutionList.Length; a++) { sbyte[][] testingData = new sbyte[AppConstants.TestingSize][]; //these will be phi vectors sbyte[] testingResponse = new sbyte[AppConstants.TestingSize]; DataGeneration.GenerateTrainingData(xArray[a], testingData, testingResponse, randomGenerator2); double accMeasures = rObjArray[0].ObjFunValue(solutionList[a], testingData, testingResponse); solutionAccuracies[a] = accMeasures; averageAccuracy = averageAccuracy + accMeasures; } averageAccuracy = averageAccuracy / (double)attackRepeatNumber; Console.Out.WriteLine("The average accuracy for the XOR APUF is " + averageAccuracy.ToString()); return(solutionAccuracies); }
//Run the CMA-ES from a recovered file public static CMAESCandidate RecoveredCMAES(Random randomGenerator, int coreNumberForSaving, PUFObjectiveFunction pFunction, InvariantData invData, VariantData varData) { double stopFitness = 0.98; //non-specific variables (used by each core) int stopeval = invData.GetMaxEval(); sbyte[][] trainingData = invData.GetTrainingData(); sbyte[] targets = invData.GetTrainingResponseForPUF(coreNumberForSaving); //core specific variables (specific to each run of CMA-ES) int counteval = varData.GetCurrentEval(); int n = varData.GetDimensionNum(); int lambdaVal = varData.GetLambda(); Matrix <double> xMean = varData.GetXMean(); Matrix <double> D = varData.GetD(); Matrix <double> B = varData.GetB(); double sigma = varData.GetSigma(); Matrix <double> weights = varData.GetWeights(); Matrix <double> ps = varData.GetPS(); double cs = varData.GetCS(); double mueff = varData.GetMueff(); double cc = varData.GetCC(); Matrix <double> pc = varData.GetPC(); Matrix <double> invsqrtC = varData.GetInvSqrtC(); Matrix <double> C = varData.GetMatrixC(); double mu = varData.GetMu(); double c1 = varData.GetC1(); double cmu = varData.GetCmu(); double damps = varData.GetDamps(); double chiN = varData.GetChiN(); double eigeneval = varData.GetEigenVal(); CMAESCandidate globalBestCandidate = varData.GetGlobalBest(); Matrix <double> oneOverD = Matrix <double> .Build.Dense(n, 1); //Don't need to copy this because we get it from D //just a sanity check if (varData.coreNumber != coreNumberForSaving) { throw new Exception("The saved core number and current core number don't match."); } //the next 40 lines contain the 20 lines of interesting code //CMAESCandidate[] candidateArray = new CMAESCandidate[lambdaVal]; List <CMAESCandidate> candidateArray = new List <CMAESCandidate>(); for (int i = 0; i < lambdaVal; i++) { candidateArray.Add(new CMAESCandidate()); } while (counteval < stopeval) { Matrix <double> arx = Matrix <double> .Build.Dense(n, lambdaVal); //fill in the initial solutions for (int i = 0; i < lambdaVal; i++) { Matrix <double> randD = Matrix <double> .Build.Dense(n, 1); for (int j = 0; j < n; j++) { randD[j, 0] = D[j, 0] * GenerateRandomNormalVariableForCMAES(randomGenerator, 0, 1.0); } Matrix <double> inputVector = xMean + sigma * B * randD; double[] tempWeightVector = new double[inputVector.RowCount]; for (int k = 0; k < inputVector.RowCount; k++) { tempWeightVector[k] = inputVector[k, 0]; } candidateArray[i] = new CMAESCandidate(tempWeightVector, trainingData, targets, pFunction); counteval = counteval + 1; } candidateArray.Sort(); //This maybe problematic, not sure about sorting in C# candidateArray.Reverse(); Matrix <double> xOld = xMean.Clone(); //Get the new mean value Matrix <double> arxSubset = Matrix <double> .Build.Dense(n, (int)mu); //in Maltab this variable would be "arx(:,arindex(1:mu)) //This replaces line arxSubset[:, i] = CandidateList[i].InputVector for (int i = 0; i < mu; i++) { for (int j = 0; j < n; j++) { arxSubset[j, i] = candidateArray[i].GetWeightVector()[j]; } } xMean = arxSubset * weights; //Line 76 Matlab //Cumulation: Update evolution paths ps = (1 - cs) * ps + Math.Sqrt(cs * (2.0 - cs) * mueff) * invsqrtC * (xMean - xOld) / sigma; //Compute ps.^2 equivalent double psSquare = 0; for (int i = 0; i < ps.RowCount; i++) { psSquare = psSquare + ps[i, 0] * ps[i, 0]; } //Compute hsig double hSig = 0.0; double term1ForHsig = psSquare / (1.0 - Math.Pow(1.0 - cs, 2.0 * counteval / lambdaVal)) / n; double term2ForHsig = 2.0 + 4.0 / (n + 1.0); if (term1ForHsig < term2ForHsig) { hSig = 1.0; } //Compute pc, Line 82 Matlab pc = (1.0 - cc) * pc + hSig * Math.Sqrt(cc * (2.0 - cc) * mueff) * (xMean - xOld) / sigma; //Adapt covariance matrix C Matrix <double> repmatMatrix = Tile((int)mu, xOld); //NOT SURE IF THIS IS RIGHT IN C# FIX repmatMatrix = numpy.tile(xold, mu) Matrix <double> artmp = (1.0 / sigma) * (arxSubset - repmatMatrix); // C = (1-c1-cmu) * C + c1 * (pc * pc' + (1-hsig) * cc*(2-cc) * C) + cmu * artmp * diag(weights) * artmp' #This is the original Matlab line for reference C = (1.0 - c1 - cmu) * C + c1 * (pc * pc.Transpose() + (1 - hSig) * cc * (2.0 - cc) * C) + cmu * artmp * Diagonalize1DMatrix(weights) * artmp.Transpose(); //Adapt step size sigma //sigma = sigma * Math.Exp((cs / damps) * (numpy.linalg.norm(ps) / chiN - 1)) sigma = sigma * Math.Exp((cs / damps) * (ps.L2Norm() / chiN - 1)); //NOT SURE IF THIS IS RIGHT FIX IN C# //Update B and D from C if ((counteval - eigeneval) > (lambdaVal / (c1 + cmu) / n / 10.0)) { eigeneval = counteval; //C = numpy.triu(C) + numpy.transpose(numpy.triu(C, 1)) #enforce symmetry C = C.UpperTriangle() + C.StrictlyUpperTriangle().Transpose(); //NOT SURE IF THIS IS RIGHT FIX IN C# //eigen decomposition Evd <double> eigen = C.Evd(); B = eigen.EigenVectors; Vector <System.Numerics.Complex> vectorEigenValues = eigen.EigenValues; for (int i = 0; i < vectorEigenValues.Count; i++) { D[i, 0] = vectorEigenValues[i].Real; } //take sqrt of D for (int i = 0; i < vectorEigenValues.Count; i++) { D[i, 0] = Math.Sqrt(D[i, 0]); } for (int i = 0; i < n; i++) { oneOverD[i, 0] = 1.0 / D[i, 0]; } Matrix <double> middleTerm = Diagonalize1DMatrix(oneOverD); //#Built in Numpy function doesn't create the right size matrix in this case (ex: Numpy gives 1x1 but should be 5x5) invsqrtC = B * middleTerm * B.Transpose(); } globalBestCandidate = candidateArray[0]; //Stopping condition if (globalBestCandidate.GetObjectiveFunctionValue() > stopFitness) { return(globalBestCandidate); } //Time to save the state VariantData varDataUpdated = new VariantData(coreNumberForSaving, counteval, n, lambdaVal, xMean, D, B, sigma, weights, ps, cs, mueff, cc, invsqrtC, C, mu, pc, c1, cmu, damps, chiN, eigeneval, globalBestCandidate); string fname = AppConstants.SaveDir + counteval.ToString() + "VariantData" + coreNumberForSaving.ToString(); FileInfo fi = new FileInfo(fname); Stream str = fi.Open(FileMode.OpenOrCreate, FileAccess.Write); BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(str, varDataUpdated); str.Close(); Console.Out.WriteLine("Iteration #" + counteval.ToString()); Console.Out.WriteLine("Current Value=" + (candidateArray[candidateArray.Count - 1].GetObjectiveFunctionValue()).ToString()); }//end while loop return(globalBestCandidate); //just in case everything terminates }