C# 结晶学米勒指数从列表中删除等效指数
我正在用Miller指数(hkl)进行一些晶体学计算,即整数三元组(hkl)存储在C# 结晶学米勒指数从列表中删除等效指数,c#,list,filter,C#,List,Filter,我正在用Miller指数(hkl)进行一些晶体学计算,即整数三元组(hkl)存储在int[]数组中。我用的是C。到目前为止,如果设置最大hmax、kmax和lmax,我可以填充包含所有等价物的列表: List<int[]> milind = new List<int[]>; int[] mindex = new int[3]; for ( int h = -hmax ; h <= hmax; h++) { mindex[0] = h; for ( i
int[]
数组中。我用的是C。到目前为止,如果设置最大hmax、kmax和lmax,我可以填充包含所有等价物的列表:
List<int[]> milind = new List<int[]>;
int[] mindex = new int[3];
for ( int h = -hmax ; h <= hmax; h++)
{
mindex[0] = h;
for ( int k = -kmax ; k <= kmax; k++)
{
mindex[1] = k;
for ( int l = -lmax ; l <= lmax; l++)
{
mindex[2] = l;
milind.Add(mindex);
}
}
}
List milind=新列表;
int[]mindex=新int[3];
对于(int h=-hmax;h定义索引的“规范”形式,如下所示:
- [h] 为最大震级指数,符号为+1
- [k] 是第二大震级指数
- [l] 是剩余的索引
- 所有的共同因素都已考虑在内
现在将所有索引转换为它们的标准形式,如果它们是已经找到的索引的副本,则将其删除
此表单还允许对Miller索引进行排序,加快搜索速度等
我有一个物理学位,我知道米勒指数不能太大
这是一个“封圣”程序。它使用蛮力进行因式分解,但我相信这对于问题域来说已经足够了;如果性能是以后可以解决的问题
2013-03-09:更新为使用预计算的素数表Math.Abs(mi.K)和&Math.Abs(mi.H)>Math.Abs(mi.L)){
符号=数学符号(mi.H);
h=mi.h;
k=Math.Abs(mi.k)>Math.Abs(mi.L)?mi.k:mi.L;
l=Math.Abs(mi.K)>Math.Abs(mi.l)?mi.l:mi.K;
}else if(Math.Abs(mi.K)>Math.Abs(mi.H)&Math.Abs(mi.K)>Math.Abs(mi.L)){
符号=数学符号(mi.K);
h=mi.K;
k=Math.Abs(mi.H)>Math.Abs(mi.L)?mi.H:mi.L;
l=Math.Abs(mi.H)>Math.Abs(mi.l)?mi.l:mi.H;
}否则{
符号=数学符号(mi.L);
h=mi.L;
k=Math.Abs(mi.H)>Math.Abs(mi.k)?mi.H:mi.k;
l=Math.Abs(mi.H)>Math.Abs(mi.K)?mi.K:mi.H;
}
h*=符号;k*=符号;l*=符号;
foreach(素数中的var i,其中(i=>(i^2)
我只想补充一下皮特的答案。排除共同因素是不正确的。(200)反射不同于(100)反射。所以质数的所有努力都是不必要的
如果你有立方对称性,生成标准形式的最简单方法是通过取绝对值,然后对三个数字进行排序,使所有指数都为正。因此
[0,-2,-1]
->[0,2,1]
->[0,1,2]
如何在C中实现这一点?我是C#行业的新手。我要出去办事了。尝试一下,我将在90分钟左右与您联系。哦,我忘了提到hmax、kmax和lmax都大约为100。嗯,我可以通过调用例如MillerIndex mi=new MillerIndex(1,0,0);但这将如何集成到我的循环中呢?然而,目前我还没有弄明白这一点。我让你开始了,我展示了一种方法,将千禧骰子转化为标准形式。现在,您仍然需要编写一个循环来运行它们,识别规范形式上的重复项,并存储唯一的可能性。
public struct MillerIndex {
public int H { get; private set; }
public int K { get; private set; }
public int L { get; private set; }
public MillerIndex( int h, int k, int l) : this() {
H = h; K = k; L = l;
}
}
public static class MillereHandler {
static IList<int> Primes = new List<int> {2,3,5,7,11,13,17,19,23,29,31};
public static MillerIndex GetCanonical(MillerIndex mi) {
int h, k, l, sign;
if (Math.Abs(mi.H) > Math.Abs(mi.K) && Math.Abs(mi.H) > Math.Abs(mi.L) ) {
sign = Math.Sign(mi.H);
h = mi.H;
k = Math.Abs(mi.K) > Math.Abs(mi.L) ? mi.K : mi.L;
l = Math.Abs(mi.K) > Math.Abs(mi.L) ? mi.L : mi.K;
} else if (Math.Abs(mi.K) > Math.Abs(mi.H) && Math.Abs(mi.K) > Math.Abs(mi.L) ) {
sign = Math.Sign(mi.K);
h = mi.K;
k = Math.Abs(mi.H) > Math.Abs(mi.L) ? mi.H : mi.L;
l = Math.Abs(mi.H) > Math.Abs(mi.L) ? mi.L : mi.H;
} else {
sign = Math.Sign(mi.L);
h = mi.L;
k = Math.Abs(mi.H) > Math.Abs(mi.K) ? mi.H : mi.K;
l = Math.Abs(mi.H) > Math.Abs(mi.K) ? mi.K : mi.H;
}
h *= sign; k *= sign; l *= sign;
foreach (var i in Primes.Where(i=> (i^2) < l) ) {
while ( (h/i)*i == h && (k/i)*i == k && (l/i)*i == l ) {
h /= h/i; k /= k/i; l /= l/i;
}
}
return new MillerIndex(h, k, l);
}
}