Neo4j Cypher реализует полиномиальное деление - PullRequest
0 голосов
/ 19 июня 2020

Я написал реализацию полиномиального деления на Cypher.

Для того, чтобы разделение было определено, в запросе должно выполняться количество вычитаний в разах деления.
Каждый раз, когда запрос выполняется частично разделенный член записывается в узел для следующей итерации.

Я пробовал UNWIND диапазон, представляющий количество вычитаний, и вместо создания узла :nextDividend я установил поле с частичным делимым. Запрос не выполняется.

Возможно, предложение о том, как заставить разделение работать в одном вызове запроса?

MATCH (nDividend:NextDividend) WHERE ID(nDividend)=2475273
WITH nDividend
MATCH (nDivisor:NextDivisor) WHERE  ID(nDivisor)=2475298
WITH nDividend.Scalar AS scalar,nDividend.Degree AS degree,nDividend.Divisor AS divisor,nDividend.ScalarO AS scalarO,nDividend.DegreeO AS degreeO,nDividend.DivisorO AS divisorO,
     nDividend.ScalarOSize AS scalarOSize ,nDividend.ScalarSize AS scalarSize ,nDividend.IndxHghstTerm AS indxHghstTerm, 
     nDivisor.Scalar AS scalarN, nDivisor.Degree AS degreeN, nDivisor.Divisor AS divisorN, nDivisor.ScalarSize AS scalarSizeN, nDivisor.IndxHghstTerm AS indxHghstTermN,nDivisor,nDividend as nD

WITH scalar,degree,divisor,scalarO,degreeO,divisorO,scalarOSize,scalarSize,indxHghstTerm,scalarN,degreeN,divisorN,scalarSizeN,indxHghstTermN,nDivisor,nD

WITH apoc.number.exact.div(scalar[indxHghstTerm],scalarN[indxHghstTermN]) AS rScalar, apoc.number.exact.sub(degree[indxHghstTerm],degreeN[indxHghstTermN]) AS rDegree,scalar,degree,divisor,scalarO,degreeO,divisorO,scalarOSize,scalarSize,indxHghstTerm,scalarN,degreeN,divisorN,scalarSizeN,indxHghstTermN,nDivisor,nD    

WITH [x IN RANGE(0,scalarSizeN-1) | {Scalar:CASE WHEN scalarN[x]='0' THEN '0' ELSE apoc.number.exact.mul(scalarN[x],rScalar) END, 
                                     Degree:CASE WHEN scalarN[x]='0' THEN degreeN[x] ELSE  apoc.number.exact.add(degreeN[x],rDegree) END ,Divisor:'1'} ] AS termsForSub,
                                     scalar,degree,divisor,scalarO,degreeO,divisorO,scalarOSize,scalarSize,indxHghstTerm,scalarN,degreeN,divisorN,scalarSizeN,indxHghstTermN,
                                     COLLECT(rScalar) AS rScalarC,COLLECT(rDegree) AS rDegreeC,nD,nDivisor,rScalar,rDegree 

SET nDivisor.RScalar = nDivisor.RScalar+rScalarC, nDivisor.RDegree=nDivisor.RDegree+rDegreeC    

WITH [x IN RANGE(indxHghstTermN+1,SIZE(termsForSub)-1) | {Scalar:apoc.number.exact.sub(scalar[(x-indxHghstTermN-1)+(indxHghstTerm+1)],termsForSub[x].Scalar),Degree:degree[(x-indxHghstTermN-1)+(indxHghstTerm+1)],Divisor:'1'}] as sbtractedTerms,scalar,degree,divisor,scalarO,degreeO,divisorO,scalarOSize,scalarSize,indxHghstTerm,scalarN,degreeN,divisorN,scalarSizeN,indxHghstTermN,nD

WITH scalar,degree,divisor,scalarO,degreeO,divisorO,scalarOSize,scalarSize,indxHghstTerm,scalarN,degreeN,divisorN,scalarSizeN,indxHghstTermN,sbtractedTerms,indxHghstTerm+(scalarSizeN-indxHghstTermN) AS nextTermIndex,nD   

WITH {Scalar:scalarO[nextTermIndex], Degree:degreeO[nextTermIndex ], Divisor:divisorO[nextTermIndex ]} AS nextTerm,sbtractedTerms,scalarO,degreeO,divisorO,scalarOSize, nextTermIndex+1>scalarOSize AS lastDivision,nD           
WITH COLLECT(nextTerm) AS nextTermC,sbtractedTerms,scalarO,degreeO,divisorO,scalarOSize,lastDivision,nD,nextTerm.Degree AS nTDegree

WITH sbtractedTerms + nextTermC as nextDividend  ,sbtractedTerms,scalarO,degreeO,divisorO,scalarOSize,lastDivision,nD,nTDegree

UNWIND nextDividend AS nDU
WITH COLLECT(nDU.Degree) AS tDeg ,nextDividend,scalarO,degreeO,divisorO,scalarOSize,lastDivision,nD,SIZE(nextDividend) AS nDividendSize,CASE WHEN nTDegree IS Null THEN 0 ELSE nTDegree END AS nTDegree
WITH [x IN RANGE(toInteger(nTDegree),scalarOSize-1) WHERE NOT (toString(x) IN tDeg) | {Scalar:'0',Degree:toString(x),Divisor:'1'} ] AS zeroScalar,
     nextDividend,scalarO,degreeO,divisorO,scalarOSize,lastDivision,nD, nDividendSize,nTDegree     
WITH zeroScalar+nextDividend as theDividend,nDividendSize,nTDegree,scalarO,degreeO,divisorO,scalarOSize,lastDivision,nD                                                

UNWIND theDividend AS tDividendU
WITH {Scalar:tDividendU.Scalar,Degree:tDividendU.Degree,Divisor:tDividendU.Divisor} AS tDiv,nDividendSize,nTDegree,scalarO,degreeO,divisorO,scalarOSize,lastDivision,nD ORDER BY toInteger(tDividendU.Degree) DESC
WITH COLLECT(tDiv.Scalar) AS tSca,COLLECT(tDiv.Degree) AS tDeg,COLLECT(tDiv.Divisor) AS tDiv,nDividendSize,nTDegree,scalarO,degreeO,divisorO,scalarOSize,lastDivision,nD

WITH tSca,tDeg,tDiv,SIZE(tSca) AS tDivSize,scalarO,degreeO,divisorO,scalarOSize,lastDivision,nD
WITH [x IN range(0,tDivSize-1) WHERE NOT (tSca[x]='0' ) | x ] AS sIndexList,tDiv,tSca,tDeg,tDivSize,scalarO,degreeO,divisorO,scalarOSize,lastDivision,nD

UNWIND sIndexList as sIU
WITH min(sIU) as indxHghstTerm,tDiv,tSca,tDeg,tDivSize,scalarO,degreeO,divisorO,scalarOSize,lastDivision,nD

CREATE (c:NextDividend {Scalar:tSca,Degree:tDeg,Divisor:tDiv,ScalarO:scalarO,DegreeO:degreeO,DivisorO:divisorO, ScalarSize:tDivSize, ScalarOSize:scalarOSize,IndxHghstTerm:indxHghstTerm})
MERGE (nD) -[:PDivide]->(c)
RETURN id(nD),id(c),lastDivision
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...