| 447 | } |
| 448 | |
| 449 | static void combine_cost_function(const tal_t *working_ctx, |
| 450 | const struct graph *graph, |
| 451 | const double *arc_prob_cost, |
| 452 | const s64 *arc_fee_cost, const s8 *biases, |
| 453 | s64 mu, s64 *arc_cost) |
| 454 | { |
| 455 | /* probabilty and fee costs are not directly comparable! |
| 456 | * Scale by ratio of (positive) medians. */ |
| 457 | const double k = |
| 458 | get_median_ratio(working_ctx, graph, arc_prob_cost, arc_fee_cost); |
| 459 | const double ln_30 = log(30); |
| 460 | const size_t max_num_arcs = graph_max_num_arcs(graph); |
| 461 | |
| 462 | for(struct arc arc = {.idx=0};arc.idx < max_num_arcs; ++arc.idx) |
| 463 | { |
| 464 | if (arc_is_dual(graph, arc) || !arc_enabled(graph, arc)) |
| 465 | continue; |
| 466 | |
| 467 | const double pcost = arc_prob_cost[arc.idx]; |
| 468 | const s64 fcost = arc_fee_cost[arc.idx]; |
| 469 | double combined; |
| 470 | u32 chanidx; |
| 471 | int chandir; |
| 472 | s32 bias; |
| 473 | |
| 474 | assert(fcost != INFINITE); |
| 475 | assert(pcost != DBL_MAX); |
| 476 | combined = fcost*mu + (MU_MAX-mu)*pcost*k; |
| 477 | |
| 478 | /* Bias is in human scale, where "bigger is better" */ |
| 479 | arc_to_parts(arc, &chanidx, &chandir, NULL, NULL); |
| 480 | bias = biases[(chanidx << 1) | chandir]; |
| 481 | if (bias != 0) { |
| 482 | /* After some trial and error, this gives a nice |
| 483 | * dynamic range (25 seems to be "infinite" in |
| 484 | * practice): |
| 485 | * e^(-bias / (100/ln(30))) |
| 486 | */ |
| 487 | double bias_factor = exp(-bias / (100 / ln_30)); |
| 488 | arc_cost[arc.idx] = combined * bias_factor; |
| 489 | } else { |
| 490 | arc_cost[arc.idx] = combined; |
| 491 | } |
| 492 | /* and the respective dual */ |
| 493 | struct arc dual = arc_dual(graph, arc); |
| 494 | arc_cost[dual.idx] = -combined; |
| 495 | } |
| 496 | } |
| 497 | |
| 498 | /* Get the fee cost associated to this directed channel. |
| 499 | * Cost is expressed as PPM of the payment. |
no test coverage detected