public bool TryGetValue(int key, out JaggedIndexing value) { if (dictionaryToIndex.TryGetValue(key, out var index)) { value = rawData[index]; return(true); } value = default; return(false); }
public float EvaluateExpression( NativeArray <float> inputParameters, JaggedIndexing parameterSampleSpace, NativeArray <OperatorDefinition> operatorData) { var evaler = new DynamicExpressionEvaluator { expression = this, inputParameters0 = inputParameters, parameterSampleSpace0 = parameterSampleSpace, inputParameters1 = default,
private void AssertFunctionResults(string expressionString, float[,] calls, object[] results, string[] paramNames = null) { var expressionCompiler = new ExpressionCompiler(paramNames == null ? new string[0] : paramNames); var operatorData = expressionCompiler.CompileToExpression(expressionString); var builder = new DynamicExpressionData(operatorData, expressionCompiler.parameters.Values.ToArray()); using var nativeOpData = new NativeArray <OperatorDefinition>(builder.OperatorSpaceNeeded, Allocator.Persistent); var paramSize = (ushort)calls.GetLength(1); var inputParams = new NativeArray <float>(paramSize, Allocator.Persistent); var opDataSpace = new JaggedIndexing { index = 0, length = builder.OperatorSpaceNeeded }; var expression = builder.WriteIntoOpDataArray( nativeOpData, opDataSpace); for (int call = 0; call < calls.GetLength(0); call++) { for (int param = 0; param < calls.GetLength(1); param++) { inputParams[param] = calls[call, param]; } var result = expression.EvaluateExpression( inputParams, new JaggedIndexing { index = 0, length = paramSize }, nativeOpData); if (results[call] is float floatVal) { Assert.AreEqual(result, floatVal); } else if (results[call] is bool boolValue) { if (boolValue) { Assert.IsTrue(result > 0); } else { Assert.IsFalse(result > 0); } } } inputParams.Dispose(); }
public void WriteIntoNativeData(NativeTurtleData nativeData, TurtleNativeDataWriter writer) { var vertexSlice = new JaggedIndexing { index = writer.indexInVertexes, length = (ushort)draft.vertexCount }; for (int i = 0; i < vertexSlice.length; i++) { var vertexDatum = new NativeVertexDatum { vertex = draft.vertices[i], normal = draft.normals[i], uv = draft.uvs[i], tangent = draft.tangents[i] }; nativeData.vertexData[i + writer.indexInVertexes] = vertexDatum; } writer.indexInVertexes += vertexSlice.length; var triangleCount = new JaggedIndexing { index = writer.indexInTriangles, length = (ushort)draft.triangles.Length }; for (int i = 0; i < triangleCount.length; i++) { nativeData.triangleData[i + writer.indexInTriangles] = draft.triangles[i]; } writer.indexInTriangles += triangleCount.length; var existingMaterialIndex = writer.materialsInOrder.IndexOf(material); if (existingMaterialIndex == -1) { existingMaterialIndex = writer.materialsInOrder.Count; writer.materialsInOrder.Add(material); } var blittable = new Blittable { translation = translation, alsoMove = alsoMove, vertexes = vertexSlice, trianges = triangleCount, materialIndex = (byte)existingMaterialIndex }; nativeData.allOrganData[writer.indexInOrganTemplates] = blittable; writer.indexInOrganTemplates++; }
public JaggedIndexing WriteDataFromArray(T[] array) { for (int i = 0; i < array.Length; i++) { data[filledIndexInData + i] = array[i]; } var jaggedIndex = new JaggedIndexing { index = filledIndexInData, length = (ushort)array.Length }; filledIndexInData += array.Length; return(jaggedIndex); }
public StructExpression WriteIntoOpDataArray( NativeArray <OperatorDefinition> dataArray, JaggedIndexing opSpace) { if (opSpace.length != OperatorSpaceNeeded) { throw new Exception("not enough space"); } for (int i = 0; i < opSpace.length; i++) { dataArray[i + opSpace.index] = definitionList[i]; } return(new StructExpression { operationDataSlice = opSpace }); }
private static byte SelectOutcomeIndex( ref Unity.Mathematics.Random rand, NativeArray <RuleOutcome.Blittable> outcomes, JaggedIndexing allOutcomes) { if (allOutcomes.length > 1) { var sample = rand.NextDouble(); double currentPartition = 0; for (byte i = 0; i < allOutcomes.length; i++) { var possibleOutcome = outcomes[i + allOutcomes.index]; currentPartition += possibleOutcome.probability; if (sample <= currentPartition) { return(i); } } throw new LSystemRuntimeException("possible outcome probabilities do not sum to 1"); } return(0); }
public void WriteDataIntoMemory( SystemLevelRuleNativeData dataArray, SymbolSeriesMatcherNativeDataWriter dataWriter) { ContextSuffix = forwardsMatchBuilder.BuildIntoManagedMemory(dataArray, dataWriter); ContextPrefix = backwardsMatchBuilder.BuildIntoManagedMemory(dataArray, dataWriter); foreach (var outcome in possibleOutcomes) { outcome.WriteIntoMemory(dataArray, dataWriter); } possibleOutcomeIndexing = new JaggedIndexing { index = dataWriter.indexInRuleOutcomes, length = (ushort)possibleOutcomes.Length }; for (int i = 0; i < possibleOutcomeIndexing.length; i++) { var possibleOutcome = possibleOutcomes[i]; dataArray.ruleOutcomeMemorySpace[i + dataWriter.indexInRuleOutcomes] = possibleOutcome.AsBlittable(); } dataWriter.indexInRuleOutcomes += possibleOutcomeIndexing.length; if (conditionalChecker != null) { var opSize = conditionalChecker.OperatorSpaceNeeded; conditionalCheckerBlittable = conditionalChecker.WriteIntoOpDataArray( dataArray.dynamicOperatorMemory, new JaggedIndexing { index = dataWriter.indexInOperatorMemory, length = opSize }); dataWriter.indexInOperatorMemory += opSize; } }
public void BasicRuleRejectsApplicationIfAnyParameters() { var ruleFromString = new BasicRule( RuleParser.ParseToRule("A -> AB", x => x), '[', ']'); var totalIncluded = new HashSet <int>("[]AB".Select(x => (int)x)); using var ruleNativeData = new SystemLevelRuleNativeData(new[] { ruleFromString }); var nativeWriter = new SymbolSeriesMatcherNativeDataWriter(); ruleFromString.WriteDataIntoMemory(ruleNativeData, nativeWriter); var symbols = new DependencyTracker <SymbolString <float> >( new SymbolString <float>(new int[] { 'A' }, new float[][] { new float[0] }) ); try { var globalParams = new float[0]; using var globalNative = new NativeArray <float>(globalParams, Allocator.Persistent); using var paramMemory = new NativeArray <float>(0, Allocator.Persistent); using var branchCache = new SymbolStringBranchingCache('[', ']', new[] { totalIncluded }, ruleNativeData); branchCache.BuildJumpIndexesFromSymbols(symbols); var random = new Unity.Mathematics.Random(); var matchSingleData = new LSystemSingleSymbolMatchData { isTrivial = false, tmpParameterMemorySpace = JaggedIndexing.GetWithNoLength(0) }; var preMatchSuccess = ruleFromString.AsBlittable().PreMatchCapturedParametersWithoutConditional( branchCache, symbols.Data, 0, paramMemory, matchSingleData.tmpParameterMemorySpace.index, ref matchSingleData, new TmpNativeStack <SymbolStringBranchingCache.BranchEventData>(5), globalNative, ruleNativeData.dynamicOperatorMemory, ref random, ruleNativeData.ruleOutcomeMemorySpace ); Assert.IsTrue(preMatchSuccess); Assert.AreEqual(0, matchSingleData.selectedReplacementPattern); Assert.AreEqual(0, matchSingleData.tmpParameterMemorySpace.length); Assert.AreEqual(2, matchSingleData.replacementSymbolIndexing.length); Assert.AreEqual(0, matchSingleData.replacementParameterIndexing.length); var symbolRawData = symbols.Data; symbolRawData.parameters[0] = new JaggedIndexing { index = 0, length = 1 }; matchSingleData = new LSystemSingleSymbolMatchData { isTrivial = false, tmpParameterMemorySpace = JaggedIndexing.GetWithNoLength(0) }; preMatchSuccess = ruleFromString.AsBlittable().PreMatchCapturedParametersWithoutConditional( branchCache, symbols.Data, 0, paramMemory, matchSingleData.tmpParameterMemorySpace.index, ref matchSingleData, new TmpNativeStack <SymbolStringBranchingCache.BranchEventData>(5), globalNative, ruleNativeData.dynamicOperatorMemory, ref random, ruleNativeData.ruleOutcomeMemorySpace ); Assert.IsFalse(preMatchSuccess); } finally { symbols.Dispose(); } }
private void AssertRuleReplacement( string ruleText, int[] sourceSymbols = null, float[][] sourceParameters = null, string expectedReplacementText = null, string axiom = null, int ruleParamMemoryStartIndex = 0, int matchIndex = 0, int paramTempMemorySize = 0, float[] globalParams = null, string[] globalParamNames = null, int expectedReplacementPatternIndex = 0, string includedSymbols = "[]ABCDE" ) { var totalIncluded = new HashSet <int>(includedSymbols.Select(x => (int)x)); globalParamNames = globalParamNames ?? new string[0]; using var symbols = new DependencyTracker <SymbolString <float> >( axiom == null ? new SymbolString <float>(sourceSymbols, sourceParameters) : SymbolString <float> .FromString(axiom, Allocator.Persistent) ); using var expectedReplacement = SymbolString <float> .FromString(expectedReplacementText, Allocator.Persistent); var ruleFromString = new BasicRule( RuleParser.ParseToRule(ruleText, x => x, globalParameters: globalParamNames), '[', ']'); using var ruleNativeData = new SystemLevelRuleNativeData(new[] { ruleFromString }); var nativeWriter = new SymbolSeriesMatcherNativeDataWriter(); ruleFromString.WriteDataIntoMemory(ruleNativeData, nativeWriter); globalParams = globalParams ?? new float[0]; using var globalNative = new NativeArray <float>(globalParams, Allocator.Persistent); var expectedTotalParamReplacement = expectedReplacement.parameters.data.Length; using var paramMemory = new NativeArray <float>(paramTempMemorySize, Allocator.Persistent); using var branchCache = new SymbolStringBranchingCache('[', ']', new[] { totalIncluded }, ruleNativeData); branchCache.BuildJumpIndexesFromSymbols(symbols); var random = new Unity.Mathematics.Random(); var matchSingleData = new LSystemSingleSymbolMatchData { isTrivial = false, tmpParameterMemorySpace = JaggedIndexing.GetWithNoLength(ruleParamMemoryStartIndex) }; var potentialMatch = ruleFromString.AsBlittable().PreMatchCapturedParametersWithoutConditional( branchCache, symbols.Data, matchIndex, paramMemory, matchSingleData.tmpParameterMemorySpace.index, ref matchSingleData, new TmpNativeStack <SymbolStringBranchingCache.BranchEventData>(5), globalNative, ruleNativeData.dynamicOperatorMemory, ref random, ruleNativeData.ruleOutcomeMemorySpace ); Assert.IsTrue(potentialMatch); Assert.AreEqual(expectedReplacementPatternIndex, matchSingleData.selectedReplacementPattern); Assert.AreEqual(paramTempMemorySize, matchSingleData.tmpParameterMemorySpace.length, "parameter temp memory size mismatch"); Assert.AreEqual(expectedReplacement.symbols.Length, matchSingleData.replacementSymbolIndexing.length, "replacement symbols size mismatch"); Assert.AreEqual(expectedReplacement.parameters.data.Length, matchSingleData.replacementParameterIndexing.length, "replacement parameter size mismatch"); matchSingleData.replacementSymbolIndexing.index = 0; matchSingleData.replacementParameterIndexing.index = 0; using var resultSymbols = new SymbolString <float>( expectedReplacement.symbols.Length, expectedReplacement.parameters.data.Length, Allocator.Persistent); ruleFromString.AsBlittable().WriteReplacementSymbols( globalNative, paramMemory, resultSymbols, matchSingleData, ruleNativeData.dynamicOperatorMemory, ruleNativeData.replacementsSymbolMemorySpace, ruleNativeData.ruleOutcomeMemorySpace, ruleNativeData.structExpressionMemorySpace ); Assert.AreEqual(expectedReplacementText, resultSymbols.ToString()); Assert.IsTrue(expectedReplacement.Equals(resultSymbols)); }
public TValue this[JaggedIndexing keyIndex, int indexInList] { get => rawData[keyIndex, indexInList];
public bool PreMatchCapturedParametersWithoutConditional( SymbolStringBranchingCache branchingCache, SymbolString <float> source, int indexInSymbols, NativeArray <float> parameterMemory, int startIndexInParameterMemory, ref LSystemSingleSymbolMatchData matchSingletonData, TmpNativeStack <SymbolStringBranchingCache.BranchEventData> helperStack, NativeArray <float> globalParams, NativeArray <OperatorDefinition> globalOperatorData, ref Unity.Mathematics.Random random, NativeArray <RuleOutcome.Blittable> outcomes) { var target = targetSymbolWithParameters; // parameters byte matchedParameterNum = 0; // context match if (contextPrefix.IsValid && contextPrefix.graphNodeMemSpace.length > 0) { var backwardsMatchMatches = branchingCache.MatchesBackwards( branchingCache.includeSymbols[ruleGroupIndex], indexInSymbols, contextPrefix, source, startIndexInParameterMemory + matchedParameterNum, parameterMemory, out var copiedParameters ); if (!backwardsMatchMatches) { return(false); } matchedParameterNum += copiedParameters; } var coreParametersIndexing = source.parameters[indexInSymbols]; if (coreParametersIndexing.length != target.parameterLength) { return(false); } if (coreParametersIndexing.length > 0) { for (int i = 0; i < coreParametersIndexing.length; i++) { var paramValue = source.parameters[coreParametersIndexing, i]; parameterMemory[startIndexInParameterMemory + matchedParameterNum] = paramValue; matchedParameterNum++; } } if (contextSuffix.IsCreated && contextSuffix.graphNodeMemSpace.length > 0) { var forwardMatch = branchingCache.MatchesForward( branchingCache.includeSymbols[ruleGroupIndex], indexInSymbols, contextSuffix, source, startIndexInParameterMemory + matchedParameterNum, parameterMemory, out var copiedParameters, helperStack); if (!forwardMatch) { return(false); } matchedParameterNum += copiedParameters; } matchSingletonData.tmpParameterMemorySpace = new JaggedIndexing { index = startIndexInParameterMemory, length = matchedParameterNum }; if (conditional.IsValid) { var conditionalMatch = conditional.EvaluateExpression( globalParams, new JaggedIndexing { index = 0, length = (ushort)globalParams.Length }, parameterMemory, matchSingletonData.tmpParameterMemorySpace, globalOperatorData) > 0; if (!conditionalMatch) { return(false); } } matchSingletonData.selectedReplacementPattern = SelectOutcomeIndex(ref random, outcomes, possibleOutcomeIndexing); var outcomeObject = outcomes[matchSingletonData.selectedReplacementPattern + possibleOutcomeIndexing.index]; matchSingletonData.replacementSymbolIndexing = JaggedIndexing.GetWithOnlyLength(outcomeObject.replacementSymbolSize); matchSingletonData.replacementParameterIndexing = JaggedIndexing.GetWithOnlyLength(outcomeObject.replacementParameterCount); return(true); }