Beispiel #1
0
static inline void K_lm_calc(ok_kernel* k, double* f, const int ndata, const double** compiled, ok_lm_params* params) {
    k->flags |= NEEDS_SETUP;
    K_calculate(k);

    
    for (int i = 0; i < k->ndata; i++) {
        const double* comprow = compiled[i];
        int set = (int) comprow[T_SET];
        double n = K_getPar(k, set + DATA_SETS_SIZE);
        
        double diff = (comprow[T_PRED] - comprow[T_SVAL]);
        double s = comprow[T_ERR];
        
        if (((int) comprow[T_FLAG]) == T_RV && n > 1e-12)
            f[i] = diff / sqrt(s*s + n*n);
        else 
            f[i] = diff / s;   
    }
    
    if (k->chi2 < params->min_chi) {
        params->min_chi = k->chi2;
        for (int i = 0; i < params->npars; i++)
            params->best[i] = *(params->pars[i]);
    }
}
Beispiel #2
0
double K_crossval_l1o(ok_kernel* k, int minalgo, int maxiter, double params[]) {
    
    int nd = K_getNdata(k);
    
    
    int np = omp_get_max_threads();
    ok_kernel* ks[np];
    double lh[np];
    ok_progress prog = k->progress;
    
    for (int p = 0; p < np; p++) {
        ks[p] = K_clone(k);
        ks[p]->progress = NULL;
        lh[p] = 0.;
    }
    bool invalid = false;
    
    #pragma omp parallel for
    for (int i = 0; i < nd; i++) {
        if (invalid)
            continue;
        
        int p = omp_get_thread_num();
        gsl_matrix_memcpy(ks[p]->system->elements, k->system->elements);
        gsl_vector_memcpy(ks[p]->params, k->params);
        
        K_calculate(ks[p]);
        double err = ks[p]->compiled[i][T_ERR];
        int set = (int) (ks[p]->compiled[i][T_SET]);
        double n = K_getPar(ks[p], set + DATA_SETS_SIZE);
        
        
        ks[p]->compiled[i][T_ERR] = 100000.;
        
        K_minimize(ks[p], minalgo, maxiter, params);
        
        double s = sqrt(err*err + n*n);
        double diff = fabs(ks[p]->compiled[i][T_SVAL] - ks[p]->compiled[i][T_PRED]);
        lh[p] += log10(diff/s);
        ks[p]->compiled[i][T_ERR] = err;
        
        if (prog != NULL && omp_get_thread_num() == 0) {
            int ret = prog(i * np, nd, ks[p],
                    "K_crossVal_l1o");
            if (ret == PROGRESS_STOP) {
                invalid = true;
            }
        }
    }
 
    double lh2 = 0;
    for (int p = 0; p < np; p++) {
        lh2 += lh[p];
        K_free(ks[p]);
    }
    if (invalid)
        return -1;
    
    return fabs(lh2);
}
Beispiel #3
0
double K_getPhasedDataForPlanet(ok_kernel* k, int planet, int row, int column) {
    static gsl_matrix* phased_data = NULL;

    if (planet >= 1) {
        if (phased_data != NULL) {
            gsl_matrix_free(phased_data);
            phased_data = NULL;
        }
        double chi2 = k->chi2;
        double rms = k->rms;
        double jitter = k->jitter;
        double chi2_rvs = k->chi2_rvs;

        planet = MIN(planet, K_getNplanets(k));
        double mass = K_getElement(k, planet, MASS);
        double period = K_getElement(k, planet, PER);
        K_setElement(k, planet, MASS, 0);
        K_calculate(k);

        phased_data = K_getCompiledDataMatrix(k);
        double mint = MGET(phased_data, 0, T_TIME);
        for (int i = 0; i < MROWS(phased_data); i++) {
            double t = fmod((MGET(phased_data, i, T_TIME) - mint), period);
            double v = MGET(phased_data, i, T_SVAL) - MGET(phased_data, i, T_PRED);
            MSET(phased_data, i, T_TIME, t);
            MSET(phased_data, i, T_VAL, v);
        }

        ok_sort_matrix(phased_data, T_TIME);
        K_setElement(k, planet, MASS, mass);
        K_calculate(k);
        k->chi2 = chi2;
        k->rms = rms;
        k->jitter = jitter;
        k->chi2_rvs = chi2_rvs;
        return 1;
    } else {
        return MGET(phased_data, row, column);
    }
}
Beispiel #4
0
double _kminimize(ok_kernel* k, int algo) {
    K_calculate(k);

    double chi2 = K_getChi2_nr(k);
    while (true) {
        K_minimize(k, algo, 10000, NULL);

        if (K_getChi2_nr(k) - chi2 < -0.01)
            chi2 = K_getChi2_nr(k);
        else
            break;
    }

    return K_getChi2_nr(k);
}
Beispiel #5
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;

}
Beispiel #6
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;
   
}