internal static double[] FindEmptyDirection(int numberOfDimensions, VectorSectorIndexCalculator vsic, List <float[]> unitVectorsFromLocalPeerToNeighbors) // solves a linear inequation { foreach (var directionVector in vsic.EnumerateDirections()) { // are all vectors along directionVector? bool neighbor_along_directionVector_exists = false; foreach (var unitVectorFromLocalPeerToNeighbor in unitVectorsFromLocalPeerToNeighbors) { double multProduct = 0; for (int dimensionI = 0; dimensionI < numberOfDimensions; dimensionI++) { multProduct += unitVectorFromLocalPeerToNeighbor[dimensionI] * directionVector[dimensionI]; } if (multProduct > 0) { neighbor_along_directionVector_exists = true; break; } } if (neighbor_along_directionVector_exists == false) { return(directionVector); } } return(null); }
public static double GetMutualP2pConnectionValue(ICryptoLibrary cryptoLibrary, RegistrationId registrationId1, ushort neighborsBusySectorIds1, RegistrationId registrationId2, ushort neighborsBusySectorIds2, int numberOfDimensions, bool thisConnectionAlreadyExists, bool anotherNeighborToSameSectorExists1, bool anotherNeighborToSameSectorExists2, bool allowConnectionsToSameRegistrationId) { if (registrationId1.Equals(registrationId2)) { return(allowConnectionsToSameRegistrationId ? SameRegistrationIdConnectionValue : -SameRegistrationIdConnectionValue); } double r = 0; var distance = registrationId1.GetDistanceTo(cryptoLibrary, registrationId2, numberOfDimensions).ToDouble(); r -= distance; if (thisConnectionAlreadyExists) { if (anotherNeighborToSameSectorExists1 == false) { r += EmptySectorOccupationValue; } if (anotherNeighborToSameSectorExists2 == false) { r += EmptySectorOccupationValue; } } else { var vsic = new VectorSectorIndexCalculator(numberOfDimensions); var vector1to2 = RegistrationId.GetDifferenceVectorF(registrationId1, registrationId2, cryptoLibrary, numberOfDimensions); var vector1to2SectorIndex = vsic.GetSectorIndex(vector1to2); var vector1to2IsInVacantSector = ((neighborsBusySectorIds1 >> vector1to2SectorIndex) & 0x0001) == 0; if (vector1to2IsInVacantSector) { r += EmptySectorOccupationValue; } var vector2to1 = new float[numberOfDimensions]; for (int i = 0; i < numberOfDimensions; i++) { vector2to1[i] = -vector1to2[i]; } var vector2to1SectorIndex = vsic.GetSectorIndex(vector2to1); var vector2to1IsInVacantSector = ((neighborsBusySectorIds2 >> vector2to1SectorIndex) & 0x0001) == 0; if (vector2to1IsInVacantSector) { r += EmptySectorOccupationValue; } } return(r); }
async Task TestDirections(DateTime timeNowUtc) { if (ConnectedNeighborsCanBeUsedForNewRequests.Count() >= _configuration.MinDesiredNumberOfNeighbors) { // enough neighbors if (_latestEmptyDirectionsTestTimeUtc == null || timeNowUtc > _latestEmptyDirectionsTestTimeUtc.Value.AddSeconds(_configuration.TestDirectionsMinIntervalS)) { _latestEmptyDirectionsTestTimeUtc = timeNowUtc; var logger = new Logger(Engine, this, null, DrpPeerEngine.VisionChannelModuleName_p2p); var numberOfDimensions = Engine.Configuration.SandboxModeOnly_NumberOfDimensions; var vsic = new VectorSectorIndexCalculator(numberOfDimensions); foreach (var directionVector in vsic.EnumerateDirections()) { await TestDirection(logger, directionVector); } } } }
public P2pConnectionValueCalculator(float[] localPeerVector, IEnumerable <float[]> currentNeighborsVectors, Action <string> wtl) { _localPeerVector = localPeerVector; if (!_vsics.TryGetValue(NumberOfDimensions, out _vsic)) { _vsic = new VectorSectorIndexCalculator(NumberOfDimensions); _vsics.Add(NumberOfDimensions, _vsic); } _currentNeighborsCountPerSectors = new int[_vsic.IndexesCount]; int neighborIndex = 0; var vectorsFromLocalPeerToNeighbors = new List <float[]>(); foreach (var neighborVector in currentNeighborsVectors) { var vectorFromLocalPeerToNeighbor = new float[NumberOfDimensions]; float vectorFromLocalPeerToNeighbor_length = 0; for (int i = 0; i < NumberOfDimensions; i++) { var vectorFromLocalPeerToNeighbor_i = RegistrationIdDistance.GetDifferenceInLoopedRegistrationIdSpace(_localPeerVector[i], neighborVector[i]); vectorFromLocalPeerToNeighbor[i] = vectorFromLocalPeerToNeighbor_i; vectorFromLocalPeerToNeighbor_length += vectorFromLocalPeerToNeighbor_i * vectorFromLocalPeerToNeighbor_i; } vectorFromLocalPeerToNeighbor_length = (float)Math.Sqrt(vectorFromLocalPeerToNeighbor_length); var sectorIndex = _vsic.GetSectorIndex(vectorFromLocalPeerToNeighbor); _currentNeighborsCountPerSectors[sectorIndex]++; for (int i = 0; i < NumberOfDimensions; i++) { vectorFromLocalPeerToNeighbor[i] /= vectorFromLocalPeerToNeighbor_length; } wtl?.Invoke($"neighbor#{neighborIndex} localToNeighbor=[{String.Join(";", vectorFromLocalPeerToNeighbor.Select(x => x.ToString()))}] sectorIndex={sectorIndex}"); vectorsFromLocalPeerToNeighbors.Add(vectorFromLocalPeerToNeighbor); neighborIndex++; } _emptyDirectionVector = null; //_emptyDirectionVector = FindEmptyDirection(NumberOfDimensions, _vsic, vectorsFromLocalPeerToNeighbors); //if (_emptyDirectionVector != null) //{ // _thereIsNeighborAlongEmptyDirectionVector = false; // neighborIndex = 0; // foreach (var vectorFromLocalPeerToNeighbor in vectorsFromLocalPeerToNeighbors) // { // float mulResult = 0; // for (int i = 0; i < NumberOfDimensions; i++) // mulResult += vectorFromLocalPeerToNeighbor[i] * _emptyDirectionVector[i]; // wtl?.Invoke($"neighbor#{neighborIndex}=[{String.Join(";", vectorFromLocalPeerToNeighbor.Select(x => x.ToString()))}]:mulResult={mulResult};"); // if (mulResult > 0) // { // _thereIsNeighborAlongEmptyDirectionVector = true; // break; // } // neighborIndex++; // } //} if (wtl != null) { for (int sectorIndex = 0; sectorIndex < _vsic.IndexesCount; sectorIndex++) { wtl.Invoke($"sector{sectorIndex} simplexVector=[{String.Join(";", _vsic.GetSimplexVector(sectorIndex).Select(x => x.ToString()))}]"); } if (_emptyDirectionVector != null) { wtl.Invoke($"emptyDirectionVector=[{String.Join(";", _emptyDirectionVector.Select(x => x.ToString()))}]"); } else { wtl.Invoke($"emptyDirectionVector=null"); } } }