public void bv16width() { var limit = 12; var set1 = BitVector16.All(limit).Select(x => x.Scalar).ToArray(); Claim.eq(mathspan.max(set1.ToSpan()), (ushort)0b111111111111); var set2 = Random.BitVectors(n16, limit).TakeArray((int)Pow2.pow(limit * 2)); Span <int> dist = stackalloc int[limit + 1]; for (var i = 0; i < set2.Length; i++) { var v = set2[i]; Claim.lteq(v.MinWidth, limit); ++dist[v.MinWidth]; } //should approach 2^(limit - 1) double idealRatio = Pow2.pow(limit - 1); Span <double> ratios = stackalloc double[dist.Length]; for (var i = 1; i < dist.Length; i++) { ratios[i] = ((double)dist[i] / Pow2.pow(i)); } var delta = mathspan.sub(ratios.Slice(1), idealRatio); Claim.yea(math.lt(math.abs(delta.Last()), 3.0)); }
public static BitVector16 clmulr(BitVector16 a, BitVector16 b, BitVector32 poly) { var prod = dinx.clmul(a, b); prod ^= (uint)dinx.clmul(prod >> 16, poly); prod ^= (uint)dinx.clmul(prod >> 16, poly); return((ushort)prod); }
public static BitVector8 clmulr(BitVector8 a, BitVector8 b, BitVector16 poly) { var prod = dinx.clmul(a, b); prod ^= (ushort)dinx.clmul((ushort)(prod >> 8), poly); prod ^= (ushort)dinx.clmul((ushort)(prod >> 8), poly); return((byte)prod); }
/// <summary> /// Compultes the scalar product between two bitvectors using modular arithmetic /// </summary> /// <param name="lhs">The first vector</param> /// <param name="rhs">The second vector</param> public static int ModProd(BitVector16 lhs, BitVector16 rhs) { var result = 0; for (var i = 0; i < lhs.Length; i++) { var x = lhs[i] ? 1 : 0; var y = rhs[i] ? 1 : 0; result += x * y; } return(result % 2); }
public static BitVector16 mul_ref(BitVector16 a, BitVector16 b) { ulong r = Redux; var p = 0ul; ulong x = a; ulong y = b; for (var i = 0; i < 16; i++) { if ((x & (1ul << i)) != 0) { p ^= (y << i); } } for (var i = 30; i >= 16; i--) { if ((p & (1ul << i)) != 0) { p ^= (r << (i - 16)); } } return((ushort)p); }
public static ref BitVector16 flip(BitVector16 x, ref BitVector16 z) { z.data = math.flip(x.data); return(ref z); }
public static BitVector16 flip(BitVector16 x) => math.flip(x.data);
public static ref BitVector16 flip(ref BitVector16 x) { math.flip(ref x.data); return(ref x); }
public static ref BitVector16 negate(BitVector16 x, ref BitVector16 z) { math.negate(x.data, ref z.data); return(ref z); }
public static BitVector16 negate(BitVector16 x) => math.negate(x.data);
public static ref BitVector16 srl(ref BitVector16 x, int offset) { math.srl(ref x.data, offset); return(ref x); }
public static BitVector16 xor(BitVector16 x, BitVector16 y) => math.xor(x.data, y.data);
public static FixedBits <BitVector16, ushort> ToFixedBits(this BitVector16 src) => src;
public static ref BitVector16 sll(BitVector16 x, int offset, ref BitVector16 z) { z.assign(Bits.sll(x.Scalar, offset)); return(ref z); }
public static BitVector16 sll(BitVector16 x, int offset) => Bits.sll(x.Scalar, offset);
public static ref BitVector16 sll(ref BitVector16 x, int offset) { x.assign(Bits.sll(x.Scalar, offset)); return(ref x); }
public static ref BitVector16 srl(BitVector16 x, int offset, ref BitVector16 z) { z.data = math.srl(x.data, offset); return(ref z); }
public static BitVector16 srl(BitVector16 x, int offset) => math.srl(x.data, offset);
public static BitVector16 mul(BitVector16 a, BitVector16 b) => Bits.clmulr(a, b, Redux);
public static BitVector16 ToBitVector(this BitString src, N16 n) => BitVector16.FromBitString(src);
public static BitVector16 and(BitVector16 x, BitVector16 y) => math.and(x.data, y.data);
public static ref BitVector16 mask(Perm spec, out BitVector16 mask) { mask = BitVector16.Mask(spec); return(ref mask); }
public static ref BitVector16 negate(ref BitVector16 x) { math.negate(ref x.data); return(ref x); }
public static ref BitVector16 xor(BitVector16 x, BitVector16 y, ref BitVector16 z) { math.xor(x.data, y.data, ref z.data); return(ref z); }
public static BitVector <N16, ushort> ToGeneric(this BitVector16 src) => src;