【问题标题】:Sample a function and store its values对函数进行采样并存储其值
【发布时间】:2021-05-31 01:30:51
【问题描述】:

我在边长为 1 的正方形上定义了两个变量 u 和 v 的函数 f(u,v)。
计时器启动,对于计时器的每个刻度,我需要在该正方形的一组离散点 (u,v) 上评估此函数数千次。这个点 (u,v) 在计时器的每个滴答声中都可能不同,并且没有理由假设它们总是相同的。 出于性能原因,我想对正方形的一些点进行采样 [f(0,0), f(0,0.1), f(0,0.2), ..., f(0.1,0),...f (1,1)] 并在计时器开始之前只评估一次函数,然后尽快获取它们。

字典可以解决问题吗?还是有更好的结构?

我忘了补充一点,显然我不需要边 1 平方的所有可能的 u、v 值,而是那些属于离散网格的值。

【问题讨论】:

  • 如果函数返回该时间步的该点的值,那么听起来您需要在每个时间步为每个点调用该函数。当然,您可以预先计算每个值(如果它是确定性和恒定的),但听起来这只是解决您遇到的任何问题。
  • 我忘了补充一点,显然我不需要边 1 平方的所有可能的 u、v 值,但那些属于离散网格的值。
  • 我们是否应该假设函数评估复杂且耗时? u 和 v 的取值范围是多少?将值编码为整数的 2D 矩阵可能非常有效。您不必担心 1000x1000 矩阵,对于现代计算机,这应该不是问题。如果它变得非常大,它可能无济于事。
  • 是的,你可以假设这个函数很耗时。它用于求解一个 4 次方程,因此它包含大量对 Math.Sqrt 的调用。
  • 你也可以假设u和v的取值范围都是[0,1]

标签: c# performance math graphics sampling


【解决方案1】:

如果您需要在常规网格上采样,您可以简单地将它们存储在一个二维数组中,即T[11,11],只需将您的 u,v 坐标乘以 10,或者您的采样有多密集,然后截断为一个 int获取您的索引。

字典也可以,但它可能会产生更大的开销,因为它需要对键进行哈希处理。对于常规网格,二维数组更有意义,而字典可能更适合非常规采样模式。

更复杂的方法可能是 kd 或四叉树。这些允许非常规样本模式的有效存储,同时仍然允许对最近点的有效查询。但从你的描述中听起来你不需要这个。 This answer 很好地介绍了网格、四叉树和 kd 树。

【讨论】:

  • 您好 Jonash,您能否详细介绍一下这个最新的 kd 或四叉树方法?
  • @Antonio Spagnuolo 添加了一个很好的解释的链接。
  • 嗨乔纳什,你认为这是截断双精度值以获取其索引的最准确方法吗? int indexU = (int) Math.Round(u /gridStep,MidpointRounding.AwayFromZero);
  • @antonio Spagnuolo 如果你保证只有正值,我会使用int indexU = (int)(u/gridStep)。如果你想允许 1.0 坐标,你应该确保你的网格大小为1/gridStep + 1。还要考虑如何处理 0-1 范围之外的值。例外?夹子?
  • 感谢您的洞察力。幸运的是,我只需要处理 0-1 范围内的值,所以我不担心异常。
猜你喜欢
  • 1970-01-01
  • 2012-03-10
  • 2014-07-03
  • 1970-01-01
  • 1970-01-01
  • 2017-06-12
  • 1970-01-01
  • 2012-02-06
  • 1970-01-01
相关资源
最近更新 更多