| 1500 | return out; |
| 1501 | } |
| 1502 | |
| 1503 | std::vector<float> solve_euler( |
| 1504 | const HeartCodecWeightsRuntime & runtime, |
| 1505 | std::vector<float> x, |
| 1506 | const std::vector<float> & incontext_x, |
| 1507 | int64_t incontext_length, |
| 1508 | const std::vector<float> & mu, |
| 1509 | int64_t num_steps, |
| 1510 | float guidance_scale) { |
| 1511 | const auto & config = runtime.assets().codec_config; |
| 1512 | const int64_t batch = 1; |
| 1513 | const int64_t frames = static_cast<int64_t>(mu.size()) / config.dim; |
| 1514 | const int64_t latent_dim = config.out_channels; |
| 1515 | if (num_steps <= 0 || frames <= 0 || |
| 1516 | static_cast<int64_t>(x.size()) != batch * frames * latent_dim || |
| 1517 | static_cast<int64_t>(incontext_x.size()) != batch * frames * latent_dim) { |
| 1518 | throw std::runtime_error("HeartCodec Euler solver shape mismatch"); |
| 1519 | } |
| 1520 | const std::vector<float> noise = x; |
| 1521 | float t = 0.0F; |
| 1522 | float dt = 1.0F / static_cast<float>(num_steps); |
| 1523 | for (int64_t step = 1; step <= num_steps; ++step) { |
| 1524 | for (int64_t frame = 0; frame < incontext_length; ++frame) { |
| 1525 | for (int64_t channel = 0; channel < latent_dim; ++channel) { |
| 1526 | const size_t index = static_cast<size_t>(frame * latent_dim + channel); |
| 1527 | x[index] = (1.0F - (1.0F - 1.0e-6F) * t) * noise[index] + t * incontext_x[index]; |
| 1528 | } |
| 1529 | } |
| 1530 | std::vector<float> dphi; |
| 1531 | if (guidance_scale > 1.0F) { |
| 1532 | auto uncond = make_flow_input(x, incontext_x, mu, batch, frames, latent_dim, config.dim, false); |
| 1533 | auto cond = make_flow_input(x, incontext_x, mu, batch, frames, latent_dim, config.dim, true); |
| 1534 | uncond.insert(uncond.end(), cond.begin(), cond.end()); |
| 1535 | const std::vector<float> timesteps = {t, t}; |
| 1536 | auto estimate = runtime.estimate_flow(uncond, 2, frames, timesteps); |
| 1537 | dphi.resize(static_cast<size_t>(frames * latent_dim), 0.0F); |
| 1538 | const size_t row_elems = static_cast<size_t>(frames * latent_dim); |
| 1539 | for (size_t i = 0; i < row_elems; ++i) { |
| 1540 | const float uncond_value = estimate.values[i]; |
no test coverage detected