<commit_before>#include "findIntervals.h"
#include <iomanip>

#include <vector>

#include <iostream>
#include <fstream>
#include <stdexcept>

#include <assert.h>
using namespace std;

void partitionGaussian(const vector<Param> &params) {

}

// Maxima can be found by using the mean as initial guesses. In the case of overlapping components
// They should converge to the same point. Unlike minimas, they don't have pathological zero derivatives
vector<double> findPeriodicMaxima(const vector<Param> &params, double period, int images) {
    vector<double> maximas;
    for(int k=0; k<params.size(); k++) {
        double xn_old = params[k].u;
        bool found = false;
        const double delta = 1e-4;

        // careful: change this to a long if need to be >2e9
        int iteration = 0;
        while(!found) {
            iteration++;
            // Saddle points suck. If the simple algorithm doesn't converge
            // it's probably due to a saddle point. 
            if(iteration >= 1e7) {
                throw(std::runtime_error("findPeriodicMaxima: maximum iteration count reached!"));
            }
            double xn_new = xn_old + delta*periodicGaussianMixtureDx(params, xn_old, period, images);
            xn_new = normalize(xn_new);
            if(fabsp(xn_new, xn_old, period) < 1e-8)
                found = true;
            xn_old = xn_new;
        }
        bool skip = false;
        // if two gaussians are too close to each other, discard it
        for(int i=0; i<maximas.size(); i++)
            if(fabsp(xn_old, maximas[i], period) < 1e-3)
                skip = true;
        if(!skip) 
            maximas.push_back(xn_old);
    }
    return maximas;
}

// Find the minima via the bisection of the periodicGaussianMixture derivative
// So far, this is the best method, superior to that of Golden Section Search and Gradient Descent
vector<double> findPeriodicMinimaBS(const vector<Param> &params, double period, int images) {
    vector<double> minima;
    vector<double> maxima = findPeriodicMaxima(params, period, images);
    assert(maxima.size() > 0);
    sort(maxima.begin(), maxima.end());
    const double tol = 1e-6;
    const double perturb = 1e-1;

    for(int k=0; k<maxima.size(); k++) {
        double ak = maxima[k];
        double bk = maxima[(k+1)%maxima.size()];
        ak = normalize(ak+perturb);
        bk = normalize(bk-perturb);
        double mk = 0;
        double my = 0;
        int iteration = 0;
        do {
            if(iteration > 1e6)
                throw(std::runtime_error("Error: findPeriodicMinimumBS maximized number of iterations reached."));
            else
                iteration++;
            
            //suppose we have the maximas:
            // a b c d, where a<b<c<d 
            // there are minimas in (a,b) (b,c) (c,d) (d,a)
            // the if statement takes care of the (d,a) case
            if(bk < ak)
                mk = normalize((ak+period+bk)/2.0);<commit_msg>Decreased perturb amount. Unit tests still pass<commit_after>#include "findIntervals.h"
#include <iomanip>

#include <vector>

#include <iostream>
#include <fstream>
#include <stdexcept>

#include <assert.h>
using namespace std;

void partitionGaussian(const vector<Param> &params) {

}

// Maxima can be found by using the mean as initial guesses. In the case of overlapping components
// They should converge to the same point. Unlike minimas, they don't have pathological zero derivatives
vector<double> findPeriodicMaxima(const vector<Param> &params, double period, int images) {
    vector<double> maximas;
    for(int k=0; k<params.size(); k++) {
        double xn_old = params[k].u;
        bool found = false;
        const double delta = 1e-4;

        // careful: change this to a long if need to be >2e9
        int iteration = 0;
        while(!found) {
            iteration++;
            // Saddle points suck. If the simple algorithm doesn't converge
            // it's probably due to a saddle point. 
            if(iteration >= 1e7) {
                throw(std::runtime_error("findPeriodicMaxima: maximum iteration count reached!"));
            }
            double xn_new = xn_old + delta*periodicGaussianMixtureDx(params, xn_old, period, images);
            xn_new = normalize(xn_new);
            if(fabsp(xn_new, xn_old, period) < 1e-8)
                found = true;
            xn_old = xn_new;
        }
        bool skip = false;
        // if two gaussians are too close to each other, discard it
        for(int i=0; i<maximas.size(); i++)
            if(fabsp(xn_old, maximas[i], period) < 1e-3)
                skip = true;
        if(!skip) 
            maximas.push_back(xn_old);
    }
    return maximas;
}

// Find the minima via the bisection of the periodicGaussianMixture derivative
// So far, this is the best method, superior to that of Golden Section Search and Gradient Descent
vector<double> findPeriodicMinimaBS(const vector<Param> &params, double period, int images) {
    vector<double> minima;
    vector<double> maxima = findPeriodicMaxima(params, period, images);
    assert(maxima.size() > 0);
    sort(maxima.begin(), maxima.end());
    const double tol = 1e-6;
    const double perturb = 1e-2;

    for(int k=0; k<maxima.size(); k++) {
        double ak = maxima[k];
        double bk = maxima[(k+1)%maxima.size()];
        ak = normalize(ak+perturb);
        bk = normalize(bk-perturb);
        double mk = 0;
        double my = 0;
        int iteration = 0;
        do {
            if(iteration > 1e6)
                throw(std::runtime_error("Error: findPeriodicMinimumBS maximized number of iterations reached."));
            else
                iteration++;
            
            //suppose we have the maximas:
            // a b c d, where a<b<c<d 
            // there are minimas in (a,b) (b,c) (c,d) (d,a)
            // the if statement takes care of the (d,a) case
            if(bk < ak)
                mk = normalize((ak+period+bk)/2.0);
{'fraction_non_alphanumeric': 0.11068447412353923, 'fraction_numerical': 0.009015025041736227, 'mean_word_length': 2.2630718954248366, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5867137', 'n_tokens_mistral': 1902, 'n_tokens_neox': 1803, 'n_words': 569}