2281 | | return pair<double,double>(sum_g/pg_sum,sigma); |
2282 | | } |
2283 | | |
2284 | | mat sample_mat(int n) |
2285 | | { |
2286 | | |
2287 | | /// \TODO tady je to spatne, tady nesmi byt conditions.size(), viz RARX.bayes() |
2288 | | if(conditions.size()-2-number_of_parameters>=0) |
2289 | | { |
2290 | | mat sample_mat; |
2291 | | map<double,toprow*> ordered_toprows; |
2292 | | double sum_a = 0; |
2293 | | |
2294 | | //cout << "Likelihoods of toprows:" << endl; |
2295 | | |
2296 | | for(polyhedron* top_ref = statistic.rows[number_of_parameters];top_ref!=statistic.end_poly;top_ref=top_ref->next_poly) |
2297 | | { |
2298 | | toprow* current_top = (toprow*)top_ref; |
2299 | | |
2300 | | sum_a+=current_top->probability; |
2301 | | /* |
2302 | | cout << current_top->probability << " "; |
2303 | | |
2304 | | for(set<vertex*>::iterator vert_ref = (*top_ref).vertices.begin();vert_ref!=(*top_ref).vertices.end();vert_ref++) |
2305 | | { |
2306 | | cout << round(100*(*vert_ref)->get_coordinates())/100 << " ; "; |
2307 | | } |
2308 | | */ |
2309 | | |
2310 | | // cout << endl; |
2311 | | ordered_toprows.insert(pair<double,toprow*>(sum_a,current_top)); |
2312 | | } |
2313 | | |
2314 | | // cout << "Sum N: " << normalization_factor << endl; |
2315 | | |
2316 | | while(sample_mat.cols()<n) |
2317 | | { |
2318 | | //// cout << "*************************************" << endl; |
2319 | | |
2320 | | |
2321 | | |
2322 | | double rnumber = randu()*sum_a; |
2323 | | |
2324 | | // cout << "RND:" << rnumber << endl; |
2325 | | |
2326 | | // This could be more efficient (log n), but map::upper_bound() doesn't let me dereference returned iterator |
2327 | | int toprow_count = 0; |
2328 | | toprow* sampled_toprow; |
2329 | | for(map<double,toprow*>::iterator top_ref = ordered_toprows.begin();top_ref!=ordered_toprows.end();top_ref++) |
2330 | | { |
2331 | | // cout << "CDF:"<< (*top_ref).first << endl; |
2332 | | toprow_count++; |
2333 | | |
2334 | | if((*top_ref).first >= rnumber) |
2335 | | { |
2336 | | sampled_toprow = (*top_ref).second; |
2337 | | break; |
2338 | | } |
2339 | | } |
2340 | | |
2341 | | //// cout << "Toprow/Count: " << toprow_count << "/" << ordered_toprows.size() << endl; |
2342 | | // cout << &sampled_toprow << ";"; |
2343 | | |
2344 | | rnumber = randu(); |
2345 | | |
2346 | | set<simplex*>::iterator s_ref; |
2347 | | double sum_b = 0; |
2348 | | int simplex_count = 0; |
2349 | | for(s_ref = sampled_toprow->triangulation.begin();s_ref!=sampled_toprow->triangulation.end();s_ref++) |
2350 | | { |
2351 | | simplex_count++; |
2352 | | |
2353 | | sum_b += (*s_ref)->probability; |
2354 | | |
2355 | | if(sum_b/sampled_toprow->probability >= rnumber) |
2356 | | break; |
2357 | | } |
2358 | | |
2359 | | //// cout << "Simplex/Count: " << simplex_count << "/" << sampled_toprow->triangulation.size() << endl; |
2360 | | //// cout << "Simplex factor: " << (*s_ref)->probability << endl; |
2361 | | //// cout << "Toprow factor: " << sampled_toprow->probability << endl; |
2362 | | //// cout << "Emlig factor: " << normalization_factor << endl; |
2363 | | // cout << &(*tri_ref) << endl; |
2364 | | |
2365 | | int number_of_runs = 0; |
2366 | | bool have_sigma = false; |
2367 | | double sigma = 0; |
2368 | | do |
2369 | | { |
2370 | | rnumber = randu(); |
2371 | | |
2372 | | double sum_g = 0; |
2373 | | for(int i = 0;i<(*s_ref)->positive_gamma_parameters.size();i++) |
2374 | | { |
2375 | | for(multimap<double,double>::iterator g_ref = (*s_ref)->positive_gamma_parameters[i].begin();g_ref != (*s_ref)->positive_gamma_parameters[i].end();g_ref++) |
2376 | | { |
2377 | | sum_g += (*g_ref).first/(*s_ref)->positive_gamma_sum; |
2378 | | |
2379 | | |
2380 | | if(sum_g>rnumber) |
2381 | | { |
2382 | | //itpp::Gamma_RNG* gamma = new itpp::Gamma_RNG(conditions.size()-number_of_parameters,1/(*g_ref).second); |
2383 | | //sigma = 1/(*gamma)(); |
2384 | | |
2385 | | GamRNG.setup(conditions.size()-number_of_parameters,(*g_ref).second); |
2386 | | |
2387 | | sigma = 1/GamRNG(); |
2388 | | |
2389 | | // cout << "Sigma mean: " << (*g_ref).second/(conditions.size()-number_of_parameters-1) << endl; |
2390 | | break; |
2391 | | } |
2392 | | } |
2393 | | |
2394 | | if(sigma!=0) |
2395 | | { |
2396 | | break; |
2397 | | } |
2398 | | } |
2399 | | |
2400 | | rnumber = randu(); |
2401 | | |
2402 | | double pg_sum = 0; |
2403 | | for(vector<multimap<double,double>>::iterator v_ref = (*s_ref)->positive_gamma_parameters.begin();v_ref!=(*s_ref)->positive_gamma_parameters.end();v_ref++) |
2404 | | { |
2405 | | for(multimap<double,double>::iterator pg_ref = (*v_ref).begin();pg_ref!=(*v_ref).end();pg_ref++) |
2406 | | { |
2407 | | pg_sum += exp(((*s_ref)->min_beta-(*pg_ref).second)/sigma)*pow((*pg_ref).second/sigma,(int)conditions.size()-number_of_parameters-1)*(*pg_ref).second/fact(conditions.size()-number_of_parameters-1)*(*pg_ref).first; |
2408 | | } |
2409 | | } |
2410 | | |
2411 | | double ng_sum = 0; |
2412 | | for(vector<multimap<double,double>>::iterator v_ref = (*s_ref)->negative_gamma_parameters.begin();v_ref!=(*s_ref)->negative_gamma_parameters.end();v_ref++) |
2413 | | { |
2414 | | for(multimap<double,double>::iterator ng_ref = (*v_ref).begin();ng_ref!=(*v_ref).end();ng_ref++) |
2415 | | { |
2416 | | ng_sum += exp(((*s_ref)->min_beta-(*ng_ref).second)/sigma)*pow((*ng_ref).second/sigma,(int)conditions.size()-number_of_parameters-1)*(*ng_ref).second/fact(conditions.size()-number_of_parameters-1)*(*ng_ref).first; |
2417 | | } |
2418 | | } |
2419 | | |
2420 | | if((pg_sum-ng_sum)/pg_sum>rnumber) |
2421 | | { |
2422 | | have_sigma = true; |
2423 | | } |
2424 | | |
2425 | | number_of_runs++; |
2426 | | } |
2427 | | while(!have_sigma); |
2428 | | |
2429 | | //// cout << "Sigma: " << sigma << endl; |
2430 | | //// cout << "Nr. of sigma runs: " << number_of_runs << endl; |
2431 | | |
2432 | | int dimension = (*s_ref)->vertices.size()-1; |
2433 | | |
2434 | | mat jacobian(dimension,dimension); |
2435 | | vec gradient = sampled_toprow->condition_sum.right(dimension); |
2436 | | |
2437 | | vertex* base_vert = *(*s_ref)->vertices.begin(); |
2438 | | |
2439 | | //// cout << "Base vertex coords(should be close to est. param.): " << base_vert->get_coordinates() << endl; |
2440 | | |
2441 | | int row_count = 0; |
2442 | | |
2443 | | for(set<vertex*>::iterator vert_ref = ++(*s_ref)->vertices.begin();vert_ref!=(*s_ref)->vertices.end();vert_ref++) |
2444 | | { |
2445 | | vec current_coords = (*vert_ref)->get_coordinates(); |
2446 | | |
2447 | | //// cout << "Coords of vertex[" << row_count << "]: " << current_coords << endl; |
2448 | | |
2449 | | vec relative_coords = current_coords-base_vert->get_coordinates(); |
2450 | | |
2451 | | jacobian.set_row(row_count,relative_coords); |
2452 | | |
2453 | | row_count++; |
2454 | | } |
2455 | | |
2456 | | //// cout << "Jacobian: " << jacobian << endl; |
2457 | | |
2458 | | //// cout << "Gradient before trafo:" << gradient << endl; |
2459 | | |
2460 | | gradient = jacobian*gradient; |
2461 | | |
2462 | | //// cout << "Gradient after trafo:" << gradient << endl; |
2463 | | |
2464 | | // vec normal_gradient = gradient/sqrt(gradient*gradient); |
2465 | | // cout << gradient << endl; |
2466 | | // cout << normal_gradient << endl; |
2467 | | // cout << sqrt(gradient*gradient) << endl; |
2468 | | |
2469 | | mat rotation_matrix = eye(dimension); |
2470 | | |
2471 | | |
2472 | | |
2473 | | for(int i = 1;i<dimension;i++) |
2474 | | { |
2475 | | vec x_axis = zeros(dimension); |
2476 | | x_axis.set(0,1); |
2477 | | |
2478 | | x_axis = rotation_matrix*x_axis; |
2479 | | |
2480 | | double t = abs(gradient[i]/gradient*x_axis); |
2481 | | |
2482 | | double sin_theta = sign(gradient[i])*t/sqrt(1+pow(t,2)); |
2483 | | double cos_theta = sign(gradient*x_axis)/sqrt(1+pow(t,2)); |
2484 | | |
2485 | | mat partial_rotation = eye(dimension); |
2486 | | |
2487 | | partial_rotation.set(0,0,cos_theta); |
2488 | | partial_rotation.set(i,i,cos_theta); |
2489 | | |
2490 | | partial_rotation.set(0,i,sin_theta); |
2491 | | partial_rotation.set(i,0,-sin_theta); |
2492 | | |
2493 | | rotation_matrix = rotation_matrix*partial_rotation; |
2494 | | |
2495 | | } |
2496 | | |
2497 | | // cout << rotation_matrix << endl; |
2498 | | |
2499 | | mat extended_rotation = rotation_matrix; |
2500 | | extended_rotation.ins_col(0,zeros(extended_rotation.rows())); |
2501 | | |
2502 | | //// cout << "Extended rotation: " << extended_rotation << endl; |
2503 | | |
2504 | | vec minima = itpp::min(extended_rotation,2); |
2505 | | vec maxima = itpp::max(extended_rotation,2); |
2506 | | |
2507 | | //// cout << "Minima: " << minima << endl; |
2508 | | //// cout << "Maxima: " << maxima << endl; |
2509 | | |
2510 | | vec sample_coordinates; |
2511 | | bool is_inside = true; |
2512 | | |
2513 | | vec new_sample; |
2514 | | sample_coordinates = new_sample; |
2515 | | |
2516 | | for(int j = 0;j<number_of_parameters;j++) |
2517 | | { |
2518 | | rnumber = randu(); |
2519 | | |
2520 | | double coordinate; |
2521 | | |
2522 | | if(j==0) |
2523 | | { |
2524 | | vec new_gradient = rotation_matrix*gradient; |
2525 | | |
2526 | | //// cout << "New gradient(should have only first component nonzero):" << new_gradient << endl; |
2527 | | |
2528 | | // cout << "Max: " << maxima[0] << " Min: " << minima[0] << " Grad:" << new_gradient[0] << endl; |
2529 | | |
2530 | | double log_bracket = 1-rnumber*(1-exp(new_gradient[0]/sigma*(minima[0]-maxima[0]))); |
2531 | | |
2532 | | coordinate = minima[0]-sigma/new_gradient[0]*log(log_bracket); |
2533 | | } |
2534 | | else |
2535 | | { |
2536 | | coordinate = minima[j]+rnumber*(maxima[j]-minima[j]); |
2537 | | } |
2538 | | |
2539 | | sample_coordinates.ins(j,coordinate); |
2540 | | } |
2541 | | |
2542 | | //// cout << "Sampled coordinates(gradient direction): " << sample_coordinates << endl; |
2543 | | |
2544 | | sample_coordinates = rotation_matrix.T()*sample_coordinates; |
2545 | | |
2546 | | //// cout << "Sampled coordinates(backrotated direction):" << sample_coordinates << endl; |
2547 | | |
2548 | | |
2549 | | for(int j = 0;j<sample_coordinates.size();j++) |
2550 | | { |
2551 | | if(sample_coordinates[j]<0) |
2552 | | { |
2553 | | is_inside = false; |
2554 | | } |
2555 | | } |
2556 | | |
2557 | | double above_criterion = ones(sample_coordinates.size())*sample_coordinates; |
2558 | | |
2559 | | if(above_criterion>1) |
2560 | | { |
2561 | | is_inside = false; |
2562 | | } |
2563 | | |
2564 | | if(is_inside) |
2565 | | { |
2566 | | sample_coordinates = jacobian.T()*sample_coordinates+(*base_vert).get_coordinates(); |
2567 | | |
2568 | | sample_coordinates.ins(0,sigma); |
2569 | | |
2570 | | //// cout << "Sampled coordinates(parameter space):" << sample_coordinates << endl; |
2571 | | |
2572 | | sample_mat.ins_col(0,sample_coordinates); |
2573 | | |
2574 | | // cout << sample_mat.cols() << ","; |
2575 | | } |
2576 | | |
2577 | | // cout << sampled_toprow->condition_sum.right(sampled_toprow->condition_sum.size()-1)*min_grad->get_coordinates()-sampled_toprow->condition_sum[0] << endl; |
2578 | | // cout << sampled_toprow->condition_sum.right(sampled_toprow->condition_sum.size()-1)*max_grad->get_coordinates()-sampled_toprow->condition_sum[0] << endl; |
2579 | | |
2580 | | |
2581 | | } |
2582 | | |
2583 | | cout << endl; |
2584 | | return sample_mat; |
2585 | | } |
2586 | | else |
2587 | | { |
2588 | | throw new exception("You are trying to sample from density that is not determined (parameters can't be integrated out)!"); |
| 2282 | return pair<double,double>(sampled_simplex->positive_gamma_sum/pg_sum,sigma); |
| 2283 | } |
| 2284 | |
| 2285 | pair<vec,mat> sample(int n, bool rejection) |
| 2286 | { |
| 2287 | vec probabilities; |
| 2288 | mat samples; |