Example #1
0
gsl_matrix* ok_periodogram_full(ok_kernel* k, int type, int algo, bool circular, unsigned int sample,
                                const unsigned int samples, const double Pmin, const double Pmax) {

    k = K_clone(k);
    K_calculate(k);

    // Input data for LS periodogram
    gsl_matrix* data = ok_buf_to_matrix(K_compileData(k), K_getNdata(k), DATA_SIZE);


    if (type == PS_TYPE_RESIDUALS) {
        // If residuals periodogram, subtract signal from data
        for (int i = 0; i < data->size1; i++)
            MSET(data, i, T_SVAL, MGET(data, i, T_SVAL) - MGET(data, i, T_PRED));
    } else if (type == PS_TYPE_DATA) {
        // If full periodogram, then start with no planets
        K_removePlanet(k, -1);
    }

    // Calculate LS periodogram
    gsl_matrix* ret = ok_periodogram_ls(data, samples, Pmin, Pmax, 0, T_TIME, T_SVAL, T_ERR, NULL);
    int np = K_getNplanets(k) + 1;

    // Number of minimizable offsets
    int no = 0;
    for (int i = 0; i < DATA_SETS_SIZE; i++)
        if (VIGET(k->parFlags, i) & MINIMIZE) {
            no++;
        }

    // Calculate baseline chi^2 (Chi^2_H)

    double Chi2_H = _kminimize(k, algo);

    // Normalizing factor for power
    double nd = 0.5 * (K_getNdata(k) - no);



    #pragma omp parallel for
    for (int r = 0; r < samples; r++) {
        double P = MGET(ret, r, PS_TIME);
        double K = sqrt(MGET(ret, r, PS_Z));

        ok_kernel* k2 = K_clone(k);
        K_calculate(k2);

        double args[] = {PER, P, DONE};
        K_addPlanet(k2, args);
        K_setElement(k2, np, SEMIAMP, K);

        K_setElementFlag(k2, np, PER, ACTIVE);

        if (circular) {
            K_setElementFlag(k2, np, ECC, ACTIVE);
            K_setElementFlag(k2, np, LOP, ACTIVE);
        }

        double Chi2_K = _kminimize(k2, algo);

        double z = nd * (Chi2_H - Chi2_K) / Chi2_H;
        MSET(ret, r, PS_Z, z);
        fflush(stdout);
    }

    return ret;

}
Example #2
0
int K_minimize_lm(ok_kernel* k, int maxiter, double params[]) {
    double min_chi_par = 1e-4;
    K_calculate(k);
    double prev_chi2 = k->chi2;
    bool high_df = false;
    int max_iter_at_scale = 200;
    double initial_st = 1.;
    
    int max_kt = 1;
    for (int i = 0; i < k->ndata; i++)
        if (k->compiled[i][T_FLAG] == T_TIMING) {
            high_df = true;
            max_kt = 2;
            max_iter_at_scale = 500;
            break;
        }
    
    if (params != NULL) {
        int i = 0;
        while (true) {
            if (params[i] == DONE)
                break;
            if (params[i] == OPT_LM_MINCHI_PAR) 
                min_chi_par = params[i+1];
            else if (params[i] == OPT_LM_HIGH_DF) 
                high_df = !((int) params[i+1] == 0);
            else if (params[i] == OPT_LM_MAX_ITER_AT_SCALE) 
                max_iter_at_scale = (int) params[i+1];
            else if (params[i] == OPT_LM_INITIAL_SCALE)
                initial_st = params[i+1];
            i+=2;
        }
    }
    unsigned int npars = 0;
    
    // Count all the parameters to minimize on
    for (int i = 1; i < k->system->nplanets + 1; i++)
        for (int j = 0; j < ELEMENTS_SIZE; j++)
            npars += (MIGET(k->plFlags, i, j) & MINIMIZE ? 1 : 0);
    for (int i = 0; i < k->parFlags->size; i++)
        npars += (VIGET(k->parFlags, i) & MINIMIZE ? 1 : 0);

    if (npars == 0)
        return 0;
    
    // Create a pointer table (flat array -> matrices)
    double** pars = (double**) malloc(sizeof(double*) * npars);
    double prevpars[npars];
    
    double* steps = (double*) malloc(npars * sizeof(double));
    double* stepscale = (double*) malloc(npars * sizeof(double));
    int* parstype = (int*) malloc(npars * sizeof(int));
    
    gsl_vector* x = gsl_vector_alloc(npars);
    
    
    int idx = 0;
    for (int i = 1; i < k->system->nplanets + 1; i++)
        for (int j = 0; j < ELEMENTS_SIZE; j++)
            if (MIGET(k->plFlags, i, j) & MINIMIZE) {
                pars[idx] = gsl_matrix_ptr(k->system->elements, i, j);
                x->data[idx] = MGET(k->system->elements, i, j);
                prevpars[idx] = x->data[idx];
                steps[idx] = stepscale[idx] = MGET(k->plSteps, i, j);
                parstype[idx] = j;
                
                if (steps[idx] < 1e-10) {
                    printf("Warning: step for element %d of planet %d is <= 0\n", j, i);
                }
                
                idx++;
            }

    for (int i = 0; i < k->parFlags->size; i++)
        if (VIGET(k->parFlags, i) & MINIMIZE) {
            pars[idx] = gsl_vector_ptr(k->params, i);
            x->data[idx] = VGET(k->params, i);
            prevpars[idx] = x->data[idx];
            steps[idx] = stepscale[idx] = VGET(k->parSteps, i);
            parstype[idx] = PARTYPE_PAR;
            
            if (steps[idx] < 1e-10)
                printf("Warning: step for parameter %d is <= 0\n", i);
            
            idx++;
        }
        
    
    
    gsl_multifit_fdfsolver * s
        = gsl_multifit_fdfsolver_alloc (gsl_multifit_fdfsolver_lmsder, k->ndata, npars);
    
    
    
    
    ok_lm_params sp;
    sp.k = k;
    sp.pars = pars;
    sp.best = (double*) malloc(sizeof(double) * npars);
    sp.stepscale = stepscale;
    sp.compiled = k->compiled;
    sp.f0 = (double*) malloc(sizeof(double)*k->ndata);
    sp.f1 = (double*) malloc(sizeof(double)*k->ndata);
    sp.f2 = (double*) malloc(sizeof(double)*k->ndata);
    sp.f3 = (double*) malloc(sizeof(double)*k->ndata);
    sp.parstype = parstype;
    sp.ndata = k->ndata;
    sp.iterations = 0;
    sp.maxiterations = maxiter;
    sp.npars = npars;
    sp.every = (k->intMethod == KEPLER ? 10 : 1);
    sp.status = PROGRESS_CONTINUE;
    sp.high_df = high_df;
    sp.min_chi = k->chi2;
    sp.st = initial_st;
    
    for (int i = 0; i < npars; i++)
        sp.best[i] = *(pars[i]);
    
    gsl_multifit_function_fdf fdf;
    fdf.f = &K_lm_f;
    fdf.df = &K_lm_jac;
    fdf.fdf = &K_lm_fdf;
    fdf.n = k->ndata;
    fdf.p = npars;
    fdf.params = &sp;
    
    gsl_multifit_fdfsolver_set (s, &fdf, x);
    
    bool improved = true;
    int status = 0;
    int kt = 0;
    int tot_iter = 0;
    int iter_at_scale = 0;
    
    
    bool last_ditch = false;
    while (improved || last_ditch) {
        k->flags |= NEEDS_SETUP;
        iter_at_scale = 0;
        
        while (true) {
            double chi2 = sp.min_chi;
            int status = gsl_multifit_fdfsolver_iterate (s);

            iter_at_scale++;
            tot_iter++;
            if (chi2 - sp.min_chi > min_chi_par)
                iter_at_scale = 0;
            
            if (status || iter_at_scale > max_iter_at_scale) {
                break;
            }
        }
        
        gsl_multifit_fdfsolver_set (s, &fdf, x);
        
        
        for (int i = 0; i < npars; i++) {
            *(pars[i]) = sp.best[i];
            x->data[i] = sp.best[i];
        }
        
        k->flags |= NEEDS_SETUP;
        K_calculate(k);
        
        if (fabs(prev_chi2 - sp.min_chi)/fabs(sp.min_chi) > 1e-2 && iter_at_scale > 1) {
            kt = 0;
            last_ditch = false;
        } else {
            sp.st *= 0.1;
        }
        
        improved = (kt < max_kt || fabs(sp.min_chi - prev_chi2)/fabs(sp.min_chi) > 1e-2);
        
        if (last_ditch)
            break;
        
        if (! improved && kt <= 3) {
            last_ditch = true;
            sp.st *= 0.1;
        }
        
        kt++;
        //printf("-> %d %d %d %e %e, last_ditch=%d\n", iter_at_scale, kt, improved, sp.st, sp.min_chi, last_ditch);
        prev_chi2 = k->chi2;
        
        for (int idx = 0; idx < npars; idx++)
            stepscale[idx] = steps[idx] * sp.st;
        
        if (sp.iterations > maxiter || sp.st < 1e-12)
            break;
    }
    
    for (int i = 0; i < npars; i++) {
        *(pars[i]) = sp.best[i];
        x->data[i] = sp.best[i];
    }

    k->flags |= NEEDS_SETUP;
    K_calculate(k);

    
    free(sp.stepscale);
    free(sp.f0);
    free(sp.f1);
    free(sp.f2);
    free(sp.f3);
    free(sp.pars);
    free(sp.parstype);
    free(sp.best);
    
    if (sp.status == PROGRESS_STOP)
        return PROGRESS_STOP;
    else 
        return status;
   
}