给定一堆任意向量(存储在矩阵A中)和半径r,我想找到落在半径r球内的那些向量的所有整数值线性组合。然后我将存储在矩阵V中的必要坐标。例如,如果是线性组合
K=[0; 1; 0]
落在我的球体内,即类似
if norm(A*K) <= r then
V(:,1)=K
end
等
A中的向量肯定是给定晶格的最简单的基础,最大的向量将具有长度1.不确定是否以任何有用的方式限制向量,但我怀疑它可能。 - 他们不会像不太理想的基础那样有相似的指示。
我已经尝试了几种方法,但似乎没有一种方法特别令人满意。我似乎无法找到一个很好的模式来遍历格子。
我目前的方法是从中间开始(即所有0的线性组合)并逐个经过必要的坐标。它涉及存储一堆额外的矢量来跟踪,所以我可以遍历坐标的所有八分圆(在3D情况下)并逐个找到它们。这个实现看起来非常复杂并且不够灵活(特别是它似乎不容易推广到任意数量的维度 - 虽然这对于当前目的来说并不是绝对必要的,但它是一个很好的选择)
有没有很好的方法来找到所有必需的点?
(*理想情况下既高效又优雅**。如果真的有必要的话,在球体之外有一些额外的点,但最好不要那么多,这没关系。我绝对需要球体内的所有向量 - 如果它产生很大的差异,我最感兴趣的是3D案例。
**我很确定我当前的实现都不是。)
我发现类似的问题:
Find all points in sphere of radius r around arbitrary coordinate - 这实际上比我正在寻找的情况更为普遍。我只处理周期性格子,我的球体总是以0为中心,与格子上的一个点重合。 但我没有一个点列表,而是一个矢量矩阵,我可以用它来生成所有点。
How to efficiently enumerate all points of sphere in n-dimensional grid - 完全规则的超立方格子和曼哈顿距离的情况。我正在寻找完全任意的格子和欧几里德距离(或者,为了效率目的,显然是正方形)。
答案 0 :(得分:1)
我发现了一种让我现在感到更快乐的方法。可能仍有可能进行改进,因此如果您有更好的方法,或者在此代码中发现错误,请务必分享。虽然这就是我现在所拥有的:(全部用SciLab编写)
步骤1:计算出最大范围。感谢ElKamina的模糊建议,以及这个回复我对于math.se的另一个问题:https://math.stackexchange.com/a/1230160/49989
function I=findMaxComponents(A,r) //returns matrix I, takes matrix A, scalar r
[dims,vecs]=size(A); //figure out how many vectors there are in A (and, unnecessarily, how long they are)
U=eye(vecs,vecs); //builds matching unit matrix
iATA=pinv(A'*A); //finds the (pseudo-)inverse of A^T A
iAT=pinv(A'); //finds the (pseudo-)inverse of A^T
I=[]; //initializes I as an empty vector
for i=1:vecs
t=r*(iATA*U(:,i))/norm(iAT*U(:,i)) //put it all together as per above link
I=[I,t(i)]; //take only the maximized component and store it in I.
end
I=[-I;I]; //I want to go from minimum to maximum value.
endfunction
在我的问题中,我只询问了一般基础,即对于n维,一组n个任意但线性独立的向量。上述代码,通过使用伪逆,适用于任意形状的矩阵,类似地,Scilab&#34;甲&#39; &#34;返回共轭转置,而不仅仅是A的转置,因此它同样适用于复杂矩阵。
在最后一步中,我添加了相应的最小组件。
以一个这样的A为例,这在Scilab的控制台中给出了以下内容:
A =
0.9701425 - 0.2425356 0.
0.2425356 0.4850713 0.7276069
0.2425356 0.7276069 - 0.2425356
r=3;
I=findMaxComponents(A,r)
I =
- 2.9494438 - 3.4186986 - 4.0826424
2.9494438 3.4186986 4.0826424
I=int(I)
I =
- 2. - 3. - 4.
2. 3. 4.
对于每个组件,上面的值是仍然落在球体上的最大值,因此我可以安全地删除小数点后的部分以获得最大整数范围。因此,对于给定的矩阵A,我必须在第一个组件中从-2到2,在第二个组件中从-3到3,在第三个组件中从-4到4,我确定落在球体内的所有点上。接下来:
步骤2:使用上述信息,找到所有组合。
function K=findAllCombinations(I) //takes a matrix of the form produced by findMaxComponents() and returns a matrix which lists all the integer linear combinations in the respective ranges.
v=I(1,:); //starting from the minimal vector
K=[];
next=1; //keeps track of what component to advance next
changed=%F; //keeps track of whether to add the vector to the output
while or(v~=I(2,:)) //as long as not all components of v match all components of the maximum vector
if v <= I(2,:) then //if each current component is smaller than each largest possible component
if ~changed then
K=[K;v]; //store the vector and
end
v(next)=v(next)+1; //advance the component by 1
next=1; //also reset next to 1
changed=%F;
else
v(1:next)=I(1,1:next); //reset all components smaller than or equal to the current one and
next=next+1; //advance the next larger component next time
changed=%T;
end
end
K=[K;I(2,:)]'; //while loop ends a single iteration early so add the maximal vector too
//also transpose K to fit better with the other functions
endfunction
所以现在我已经拥有了,剩下的就是检查一个给定的组合是否实际上位于球体内部或外部。我要做的就是:
第3步:生成实际点
function points=generatePoints(A,K,r)
possiblePoints=A*K; //explicitly generates all the possible points
points=[];
for i=possiblePoints
if i'*i<=r*r then //filter those that are too far from the origin
points=[points i];
end
end
endfunction
我得到的所有组合都适合半径为r的球体。
对于上面的例子,输出相当长:对于半径为3的球体,最初有315个可能点,我得到163个剩余点。
前4个是:(每列是一个)
- 0.2425356 0.2425356 1.2126781 - 0.9701425
- 2.4253563 - 2.6678919 - 2.4253563 - 2.4253563
1.6977494 0. 0.2425356 0.4850713
所以剩下的工作就是优化。据推测,其中一些循环可以更快,特别是当尺寸数量增加时,我必须产生大量的点,我必须丢弃,所以也许有一种更好的方法,而不是采取(在给定坐标中扭曲) frame)以n-sphere的超盒为界,作为起点。
答案 1 :(得分:0)
让我们将K表示为X.
问题可以表示为:
(a11x1 + a12x2 ..)^ 2 +(a21x1 + a22x2 ..)^ 2 ...&lt; R ^ 2
(x1,x2,...)不会形成球体。
答案 2 :(得分:0)
在没有证明任何断言的情况下,我认为1)如果向量集不是最大等级,那么解的数量是无穷大的; 2)如果该集合具有最大秩,则由矢量生成的线性变换的图像是目标空间的子空间(例如,平面),其在较低维度的球体中与球体相交; 3)由此可以将问题简化为1-1线性变换(k维空间上的kxk矩阵); 4)由于矩阵是可逆的,你可以“拉回”#34;球体到包含格点的空间中的椭圆体,作为奖励,你得到椭圆体的一个很好的几何描述(主轴定理); 5)你的问题现在变成了确定椭圆体内格点的确切问题。
后一个问题与一个古老的问题(计算椭圆内的格点)有关,高斯考虑了这个问题,得出了一个很好的近似值。确定椭圆内的格点(oid)可能不是一个整洁的问题,但它可能一次减少一个维度(椭圆体和平面的横截面是另一个椭圆体)。