傅立叶空间中的滤波器的行为与预期不同

2024-03-03

这是我提出的已回答问题的后续内容,可以找到here https://stackoverflow.com/questions/54022376/inverse-fft-returns-negative-values-when-it-should-not.

我在 3D 框中有几个具有关联质量的点(x、y、z 坐标)。我想绘制给定半径球体中质量密度的直方图R。这个想法是计算我的盒子的 3D 直方图(分箱比半径小得多),对其进行 FFT,乘以滤波器(真实空间中的球)并对结果进行逆 FFT。从那里,我只计算每个 3D-bin 中获得的值的 1D 直方图。

Following the issue I had by using an analytic expression of the filter in Fourier space, I am now generating the ball in real space and take its FFT to obtain my filter. However, the histogram I get out of this method is really strange, where I would expect a Gaussian I am getting this: Normalised Histogram of the mass density in my box

我的代码如下:

import numpy as np
import matplotlib.pyplot as plt
import random
from numba import njit


# 1. Generate a bunch of points with masses from 1 to 3 separated by a radius of 1 cm

size = 100

radius = 1
rangeX = (0, size)
rangeY = (0, size)
rangeZ = (0, size)
rangem = (1,3)
qty = 300000  # or however many points you want


deltas = set()
for x in range(-radius, radius+1):
    for y in range(-radius, radius+1):
        for z in range(-radius, radius+1):
            if x*x + y*y + z*z<= radius*radius:
                deltas.add((x,y,z))

X = []
Y = []
Z = []
M = []
excluded = set()
for i in range(qty):
    x = random.randrange(*rangeX)
    y = random.randrange(*rangeY)
    z = random.randrange(*rangeZ)
    m = random.uniform(*rangem)
    if (x,y,z) in excluded: continue
    X.append(x)
    Y.append(y)
    Z.append(z)
    M.append(1)
    excluded.update((x+dx, y+dy, z+dz) for (dx,dy,dz) in deltas)

#print("There is ",len(X)," points in the box")



# Compute the 3D histogram

a = np.vstack((X, Y, Z)).T

b = 200
R = 10

H, edges = np.histogramdd(a, weights=M, bins = b)  

Fh = np.fft.fftn(H, axes=(-3,-2, -1))

# Generate the filter in real space

Kreal = np.zeros((b,b,b))


X = edges[0]
Y = edges[1]
Z = edges[2]

mid = int(b/2)

s = (X.max()-X.min()+Y.max()-Y.min()+Z.max()-Z.min())/(3*b)

cst = 1/2 + (1/12 - (R/s)**2)*np.arctan((0.5*np.sqrt((R/s)**2-0.5))/(0.5-(R/s)**2)) + 1/3*np.sqrt((R/s)**2-0.5) + ((R/s)**2 - 1/12)*np.arctan(0.5/(np.sqrt((R/s)**2-0.5))) - 4/3*(R/s)**3*np.arctan(0.25/((R/s)*np.sqrt((R/s)**2-0.5)))


@njit(parallel=True)
def remp(Kreal):
    for i in range(b):
        for j in range(b):
            for k in range(b):
                a = cst - np.sqrt((X[i]-X[mid])**2 + (Y[j]-Y[mid])**2 + (Z[k]-Z[mid])**2)/s
                if a >= 0.1 and a < 0.2:
                    Kreal[i][j][k] = 0.1
                elif a >= 0.2 and a < 0.3:
                   Kreal[i][j][k] = 0.2 
                elif a >= 0.3 and a < 0.4:
                   Kreal[i][j][k] = 0.3
                elif a >= 0.4 and a < 0.5:
                   Kreal[i][j][k] = 0.4
                elif a >= 0.5 and a < 0.6:
                   Kreal[i][j][k] = 0.5
                elif a >= 0.6 and a < 0.7:
                   Kreal[i][j][k] = 0.6
                elif a >= 0.7 and a < 0.8:
                   Kreal[i][j][k] = 0.7
                elif a >= 0.8 and a < 0.9:
                   Kreal[i][j][k] = 0.8
                elif a >= 0.9 and a < 0.99:
                   Kreal[i][j][k] = 0.9
                elif a >= 0.99:
                   Kreal[i][j][k] = 1
    return Kreal


Kreal = remp(Kreal)

Kreal = np.fft.ifftshift(Kreal)

Kh = np.fft.fftn(Kreal, axes=(-3,-2, -1))

Gh = np.multiply(Fh, Kh)

Density = np.real(np.fft.ifftn(Gh,axes=(-3,-2, -1)))

# Generate the filter in fourier space using its analytic expression

kx = 2*np.pi*np.fft.fftfreq(len(edges[0][:-1]))*len(edges[0][:-1])/(np.amax(X)-np.amin(X))
ky = 2*np.pi*np.fft.fftfreq(len(edges[1][:-1]))*len(edges[1][:-1])/(np.amax(Y)-np.amin(Y))
kz = 2*np.pi*np.fft.fftfreq(len(edges[2][:-1]))*len(edges[2][:-1])/(np.amax(Z)-np.amin(Z))

kr = np.sqrt(kx[:,None,None]**2 + ky[None,:,None]**2 + kz[None,None,:]**2)
kr *= R
Kh = (np.sin(kr)-kr*np.cos(kr))*3/(kr)**3


Kh[0,0,0] = 1


Gh = np.multiply(Fh, Kh)

Density2 = np.real(np.fft.ifftn(Gh,axes=(-3,-2, -1)))


D = Density.flatten()
N = np.mean(D)

D2 = Density2.flatten()
N2 = np.mean(D2)


# I then compute the histogram I want

hist, bins = np.histogram(D/N, bins='auto', density=True)
bin_centers = (bins[1:]+bins[:-1])*0.5
plt.plot(bin_centers, hist,'.',label = "Defining the Filter in real space")


hist, bins = np.histogram(D2/N2, bins='auto', density=True)
bin_centers = (bins[1:]+bins[:-1])*0.5
plt.plot(bin_centers, hist,'.',label = "Using analytic expression")



plt.xlabel('Normalised Density')
plt.ylabel('Probability density')
plt.legend()
plt.show()

你明白为什么会发生这种情况吗?非常感谢您的帮助。

PS:一长串if当我在真实空间中定义过滤器时的语句来自我在网格上绘制球体的方式。我将值 1 分配给所有 100% 在球体内的 bin,然后该值随着 bin 中球体占据的体积减小而减小。我检查它给了我一个所需半径的球体。有关该主题的详细信息可以找到here http://geonumerics.mit.edu/assets/docs/papers/dem_lbm_mapping.pdf(第 2.5 部分和图 8 的准确性)。

--EDIT--

仅当所有粒子质量相同时,代码才会表现得像这样


我的问题来自于我如何生成过滤器。在我的代码中,我将权重与不完全位于球体中的体素相关联的方式是不连续的:例如,我将权重 0.1 赋予体积比在 0.1 和 0.2 之间的体素。

因此,当所有点具有相同的质量时,会发生什么:我的网格中有 1 的倍数,我将其与有限数量的系数相乘,因此我的网格可以采用有限数量的可能值,因此有些箱是空的或至少“不太满”。当粒子的质量分布更加连续时,这种情况就不太可能发生。

因此,解决方法是为体素指定正确的权重。

def remp(Kreal):
for i in range(b):
    for j in range(b):
        for k in range(b):
            a = cst - np.sqrt((X[i]-X[mid])**2 + (Y[j]-Y[mid])**2 + (Z[k]-Z[mid])**2)/s
            if a >= 0.1 and a < 0.99:
                Kreal[i][j][k] = a
            elif a >= 0.99:
               Kreal[i][j][k] = 1
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

傅立叶空间中的滤波器的行为与预期不同 的相关文章

随机推荐

  • 在每个 json 文档之前添加标题行

    我有一个包含 1000 个 json 对象的 json 文件 有没有办法在每个 json 文档之前添加标题行 有没有最简单的方法 示例 我有 1000 个这样的对象 id 58 first name Louis last name Jord
  • Android:如何找到assets文件夹的绝对路径?

    我需要获取应用程序中资产文件夹的绝对路径 因为我想使用网络服务器提供文件 并且它需要绝对路径 这可能吗 我本以为可能会有这样的事情 String rootDir getAssets getRootDirectory 但没有 任何帮助表示赞赏
  • VSCode 启动时的 net::ERR_CONNECTION_RESET

    当我启动 VSCode 时 我不断收到此消息 2022 08 01 13 59 02 322 renderer1 error net ERR CONNECTION RESET Error net ERR CONNECTION RESET a
  • Cloudfront CORS 问题在 Rails 应用程序上提供字体

    访问我的网站时 我不断从控制台收到此错误消息 font from origin https xxx cloudfront net has been blocked from loading by Cross Origin Resource
  • 与多列进行字符串匹配以查找 r 中可能的结果

    我有两个数据框 DF1 和 DF2 在 DF1 中 我有不同的字符串组合 在 DF2 中 我有不同字符串组合的结果 我需要将 DF1 与 DF2 中的字符串或字符串组合进行匹配 并根据字符串匹配创建多个结果列作为结果数据帧 DF Resul
  • HRESULT:0x80131040:找到的程序集的清单定义与程序集引用不匹配

    找到的程序集的清单定义与程序集引用不匹配 通过 ncover 运行 nunit 时得到此信息 任何想法 这是程序集之间的不匹配 从程序集引用的 DLL 没有预期的方法签名 清理解决方案 重建所有内容 然后重试 另外 如果这是对 GAC 中某
  • Magento API 的创建发票方法无法正常工作

    我正在尝试使用 XMLRPC 在 Android 应用程序中使用 Magento API 创建销售订单发票 我正在使用方法 sales order invoice create 用于创建发票 此方法在给定数量的响应中为我提供发票 ID 如中
  • 如何通过 API Laravel 处理用户注册

    我一直在阅读和观看一些有关 Laravel API 开发的教程 尽管我使用过一些 Laravel 但我对 API 开发完全是新手 从我读过的所有教程来看 它们处理的是 登录 获取一些数据 更新信息 删除信息 甚至将一些信息插入数据库 我的问
  • C# .NET 中的 Web 响应最多只能运行几次

    我正在使用 twitter api 开发一个应用程序 其中涉及编写一个方法来检查用户是否存在 这是我的代码 public static bool checkUserExists string user string URL https tw
  • 如何在 Struts 2 中向我的所有视图公开一个对象?

    我有一个使用 Struts 2 和 Freemarker 模板以及 Spring 4 的 Web 应用程序 我有一些配置字符串存储在 properties我需要在每个页面上呈现的文件 例如 我们的 CDN 路径 其中包含版本字符串 现在这些
  • OSError:libgdal.dylib:无法打开文件

    问题是 Docker 无法正常运行 因为OSError opt homebrew Cellar gdal 3 3 0 2 lib libgdal dylib cannot open shared object file No such fi
  • 使用 Pyx 绘制大括号

    如何使用 Pyx 在任意两个点之间绘制一条 支撑 线 它看起来像这样 大括号示例http tof canardpc com view d16770a8 0fc6 4e9d b43c a11eaa09304d http tof canardp
  • 如何编写一个以两个矩阵 A 和 B 作为输入并输出乘积矩阵 A*B 的函数?

    如何编写一个以两个矩阵 A 和 B 作为输入并输出乘积矩阵 A B 的函数 使用 MATLAB 带有循环和条件 我的尝试 function prodAB MultiplicoMatrices A B prod 0 prodAB for i
  • 发生特定情况时如何停止 Kotlin 流程

    如果代码中发生某些情况 我想取消 kotlin 流程 假设我有一个方法如下 fun test Flow
  • 自定义设备控制器不工作

    我有两个模型居民和用户 它们都包含 roll number 属性 我现在已经在驻留模型中输入了数据 当用户注册哪个是 Devise 资源时 它会检查驻留模型中是否存在相同的 roll number 然后就可以注册用户了 所以基本上我向 De
  • 替换JS中某个字符的所有实例?

    我正在尝试创建一个简单的函数来替换 JS 中字符串中某个字符的所有实例 在这种情况下 我想替换所有a s with o s 我很确定代码是正确的 但输出仍然是原始字符串 function replaceLetter string for v
  • mongorestore 随机崩溃(致命错误)

    我使用的是 macOS 10 12 mongod version db version v3 2 8 git version ed70e33130c977bda0024c125b56d159573dbaf0 OpenSSL version
  • 如何在源代码中查找搜索词

    我正在寻找一种在项目的 C C 代码中搜索给定术语的方法 同时忽略注释和字符串中出现的任何情况 由于代码库相当大 我正在寻找一种方法自动地识别与我的搜索词匹配的代码行 因为它们需要手动检查 如果可能的话 我想在我的 Linux 系统上执行搜
  • 绘制相同值时显示更大的点

    当我绘制以下示例时 Participant lt c 1 12 AnswersDay1 lt c 9 3 9 13 7 12 10 7 9 0 12 11 Day1Group lt c 0 1 0 1 0 1 0 1 0 1 0 1 Pus
  • 傅立叶空间中的滤波器的行为与预期不同

    这是我提出的已回答问题的后续内容 可以找到here https stackoverflow com questions 54022376 inverse fft returns negative values when it should