在数据库中存储 Mandelbrot 值的最佳方法是什么?
我目前正在尝试渲染 Mandelbrot 集,并且很快意识到不必重新计算每次渲染的最大迭代计数会很有用……另一方面,需要跟踪大量数据的。在我看来(基于我对 RDMS 的有限经验),关系数据库可能不是最佳选择,因为我不希望随着数据集变大而影响性能。对于哈希表来说,这似乎是完美的情况,但我以前从未使用过哈希表,而且似乎无法弄清楚如何使用或管理一种现有的 Web 服务器语言(Python/PHP/其他语言)中的哈希表。
更明确一点:要存储的重要值是:
- 复平面上数字的原始实部
- 复平面上数字的原始虚部平面
- 最大迭代次数
- 在达到最大迭代次数之前或直到该点运行到无穷大之前已完成迭代 n 的次数
- n 次迭代后复平面上数字的最终实部
- n 次迭代后复平面上数字的最终虚部 > 迭代
在任何给定时间,给定原始实部、原始虚部和最大迭代次数,我想能够获得包含最终实部和虚部的结果集。
那么你觉得怎么样?哈希表是可行的方法吗?对于普通的数据结构来说,这个问题是否太复杂了?
任何帮助将不胜感激。提前致谢!
编辑
我将根据 julieaubert 的请求稍微解释一下这个问题。
我的目标是允许用户在没有计算延迟的情况下放大 Mandelbrot 集(即使是通过预定义的缩放)。我还希望能够在浏览器中执行此操作,该浏览器不断向服务器请求新的数据数组,给出新的 x 和 y 坐标以及要在复平面上查看的高度和宽度。然而,由于计算像素颜色值可以更快地完成(给定 max_iter、real_final 和 imag_final),而且由于允许用户调整颜色设置会很好,所以我将只发送浏览器我的帖子中枚举的变量并让用户的浏览器计算颜色。
看看这个:
如果你看看函数中,您可以看到点循环将重要值存储在名为 dataset 的变量中。然后,该变量在 drawMandelbrotFromData() 函数中使用,在该函数中执行计算每个像素颜色所需的剩余计算。
如果您单击“cleardabrot”,它将用白色矩形替换画布。如果您单击“refilldabrot”,它会再次运行 drawMandelbrotFromData() 函数...这样做是为了向您展示,只要它不必执行痛苦的迭代计算,它实际上可以多快地渲染集合。
因此,这里的最终目标是能够以任意精度计算这些值,以便用户可以缩放到集合的任何级别,让服务器找出这些精确点(或者最好是附近的点)是否有任何数据这些确切的点...尽管我不确定如何在不执行某种范围查询的情况下完成此操作),然后逐个像素地吐出信息。例如...
- 用户正在使用 300x300 画布。
- 他缩放到左上角为
x = .000001
和y = .0000231
的点。 - 他在此帧中选择的宽度和高度是
w = .00045
和h = .00045
他会将这些数字发送到服务器并依次接收一个数组300*300 个索引(一个代表每个点),每个索引都包含确定画布上每个像素的颜色所需的信息。我的问题是……存储预先计算的 Mandelbrot 数据的最佳方法是什么,以便用户可以输入任意 x、y、w 和 h 值并快速拉回复平面上的点的值范围。
I'm currently experimenting with rendering a Mandelbrot set and I've quickly come to realize that it would be useful to not have to recalculate the maximum iteration count for each rendering...on the other hand it's a lot of data to keep track of. It seems to me (based on my limited experience with RDMSes) that a relational database is probably not the way to go because I don't want the performance to be impacted as the data set gets larger. It almost seems like the perfect situation for a hash table, but I've never used one before and can't seem to work out how to use or manage one in one of the existing web server languages (Python/PHP/whatever).
To be a little more explicit: the important values to be stored are:
- The original real part of a number on the complex plane
- The original imaginary part of a number on the complex plane
- The number of max iterations
- The number of completed iterations n before max iterations is hit or until the point runs off to infinity
- The final real part of a number on the complex plane after n iterations
- The final imaginary part of a number on the complex plane after n iterations
At any given time, Given the original real part, the original imaginary part, and the max number of iterations, I'd like to be able to get a result set with the final real and imaginary parts.
So what do you think? Is a hash table the way to go? Is the problem too complex for mere mortal data structures?
Any help at all would be greatly appreciated. Thanks in advance!
Edit
I'll expound on the problem a bit at the kind request of julienaubert.
The goal I have is to allow a user to zoom in on a Mandelbrot set without the calculation delay (even if it is through pre-defined zooms). I also want to be able to do this in a browser that is constantly asking the server for a new data array give the new x and y coordinates and the height and width to be viewed on the complex plane. However, since calculating the pixel color value can be done much more quickly (given max_iter, real_final, and imag_final), and also since it would be nice to allow the user to adjust color settings, I'm going to only be sending the browser the variables enumerated in my post and let the user's browser calculate the color.
Take a look at this:
If you take a look at the drawMandelbrot() function, you can see that the point loops are storing the important values in a variable called dataset. This variable is then used in the drawMandelbrotFromData() function where it performs the remaining calculations needed to figure out the color for each pixel.
If you click "cleardabrot" it replaces the canvas with a white rectangle. If you click "refilldabrot", it runs the drawMandelbrotFromData() function again...this is done to show you how quickly it can actually render the set if only it didn't have to perform the painful iterative calculations.
So the ultimate goal here is to be able to calculate these values to arbitrary precision, so a user can zoom to any level of the set, have the server figure out if there are any data for those exact points (or, preferably, points NEAR those exact points...though I'm not sure how this could be done without performing a range query of some sort), and then spit back the information on a pixel-by-pixel basis. For example...
- A user is using a 300x300 canvas.
- He zooms to a point where the top left corner is
x = .000001
andy = .0000231
. - His chosen width and height in this frame is
w = .00045
andh = .00045
He would send those numbers off to the server and receive, in turn, an array with 300*300 indexes (one representing each point), each containing the requisite information to determine the color of each pixel on his canvas. My question here is...what is the best way to store pre-calculated Mandelbrot data such that a user can input arbitrary x, y, w, and h values and quickly pull back the values of the points on the complex plane in that range.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
从你的问题中不清楚为什么你需要这个?为什么同一点需要重新计算?
如果您正在尝试不同的 max_iterations 设置,您可以将每个像素级别的实际迭代保存在二进制文件、文本文件或图像或您认为方便加载/存储的任何内容(例如关系数据库)中。
如果您正在进行实时渲染并且正在使用一些需要重新计算递归方程的处理(在相同的原始点和相同的最大迭代次数),那么我想您可以通过查看来加快速度-上桌。
显然,您的查找表必须比计算速度更快。您需要一个查找表,其中以下操作总共花费的时间少于再次进行计算的时间。
取决于您如何在同一点重新计算/重新访问,您可以以这种方式划分您的问题索引很可能位于查找表中,并且查找表足够小,可以存储在 L1 或 L2 高速缓存中。
这些是一些想法..但你应该澄清你真正的问题是什么。
如果您只需要大量此类数据进行进一步分析,并且实时性不是要求,那么好吧...澄清您真正的问题是什么:)
更新的答案
它看起来类似于使用地图服务(放大/缩小、四处移动),也就是说,您实际上是在为给定区域提供图像并进行缩放。
但是在这种情况下,由于可能会查询任何缩放级别,因此您为一个用户缓存的任何内容都可能不会被下一个用户重复使用。我不确定为什么这样做有意义,而不是编写一个用户可以实时缩放的客户端软件(已经完成)。
无论如何。如果您的主要问题是带宽,但您有足够的计算能力,那么您可以将计算出的补丁的图像存储在高度压缩的文件中,质量稍低并缓存这些图像。然后,您可能需要将这些补丁缝合在一起,以提供用户想要的确切区域。诀窍是查询给定缩放和区域的最小补丁集。
我担心大多数查询会要求不存在的补丁(因为任何缩放级别都是可能的)。也许一些关于谷歌地图/地理信息系统如何工作的信息可以给你一些想法。如果你的主要问题是CPU,那么也许你可以采取不同的做法,让用户在Applet中进行计算(并可能发回结果)
如果你这样做是为了学习如何通过客户端服务器进行缓存/计算,那么你可能需要考虑一个不同的挑战,因为这个挑战可以通过任何像样的计算机在客户端解决。
It is not clear from your question why you need this? Why do you need to re-compute at the same point?
In case you are experimenting with different max_iterations settings, you can just save the actual_iterations taken at a per-pixel level in a binary-file, text-file or image or whatever you find convenient to load/store, e.g. a relational database.
If you are doing real-time rendering and you are using some processing which requires re-calculating the recurrence equation (at the same original point and with the same max iterations), then I would imagine you could speed this up by having a look-up table.
Obviously, your look-up table must be faster than doing the computation. You need a look-up table for which the below operations in total take less than doing the computation again.
Depending on how you will re-compute / re-access at the same points, you could divide your problem in such a way that it is highly likely that the index is in the look-up table and the look-up table is small enough to be stored in a L1 or L2 cache.
Those are some ideas.. but you should clarify what your real problem is.
In case you just need a lot of this data for further analysis and real-time is not the requirement, then well... clarify what your real issue is :)
answer for the update
It seems similar to using a map service (zoom in/out, move around), that is, you are essentially delivering an image for a given area and zoom.
However in this case, since any zoom-level may be queried, whatever you cache for one user, may not be re-used for the next user. I am not sure why it would make sense to do it this way rather than writing a client software in which the user can zoom real-time (which has been done).
In any case. If your main problem is bandwidth but you have plenty of computation power, then you could store images of a calculated patch in a highly compressed file, with a bit lower quality and cache these images. You may then need to stitch patches of these together to deliver the exact area the user wanted.. the trick would be to query the minimal set of patches given the zoom and area.
I fear that most queries would be asking for patches which does not exist (since any zoom-level is possible). Perhaps some info on how e.g. Google Maps / GIS systems work could give you some ideas. If your main problem is CPU, then maybe you could do this differently and let the user do the computation in an Applet (and possibly send back the result)
If you are doing this to learn how to cache/compute over client-server, you might want to consider a different challenge, as this one can be solved on client side by any decent computer.