Ik heb een functie ala: H=2x^2+3x^2y^2-10py+1 (1)
De daadwerkelijke functie, volledig uitgeschreven:
Deze functie sla ik op in 3 arrays:
Array 1 geeft de coefficient aan: [2,3,-10,1] (met fucntie boven genoemd bij (1) ) (double array)
Array 2 hoeveel vars er zijn: [2,4,1,0] (int array)
Array 3 welke vars [0,0,0,0,1,1,4] (0=x en 1=y, 3=px, 4=py) (deze array is de som van array 2 groot) (int array)
Verder heb ik een state vector, bij dit voorbeeld [statex,statey, statepx, statepy] (statex & statey zijn dus getallen, statepx & statepy zijn de impulsen, doubles)
En een afgeleide: [statexdot, stateydot, statepxdot, statepydot].
Dus elk punt heeft een coordinaat en een impuls. Stel dat je 2 dimensies hebt en 1 punt, dan heb je zoals boven staat. Het aantal states is dus het aantal dimensies*2.
Om de afgeleide te berkenen loop is alsvolgt door de 3 arrays heen:
(dCoefficient is array 1, iNumberOfVariabeles is array 2 en iVariabeles is array 3, dStates is toestandsvector en dStatesDot de afgeleide hiervan)
Dit deel maakt van 2x^2 de afgeleide 2x+2x=4x
Dit wordt on the fly ingevuld. Nadat deze code klaar is staat in dStateDot de uitkomst van de afgeleide van H naar dState met de waarden alvast ingevuld.
dState is van het type (x1,y1, px1, py1, x2, y2, px2, py2). dus eerst de lokatie dan de impuls vervolgens het volgende punt.
dState wordt berekend met:
Oftewel in het geval zoals bij functie (1) (irl is deze veel complexer):
dState[0]=dState[0]+dDeltaT*dStateDot[2] (x=x+dT*px)
dState[1]=dState[1]+dDeltaT*dStateDot[3] (y=y+dT*py)
dState[2]=dState[2]+dDeltaT*(-dStateDot[0] -dFriction*dStateDot[2]) (px=px+dT(-x-wrijving*px)
dState[3]=dState[3]+dDeltaT*(-dStateDot[1] -dFriction*dStateDot[3]) (py=py+dT(-y-wrijving*py)
Nu werkt dit proces prima als dFriction 0 is. (0<=dFriction<1). dDeltaT is de stapgrote in seconde, meestal 0.1
Als dFriction bijv 0.5 is zal dStateDot een afwijking gaat tonen. Deze zal in een situatie dat ie 0 moet bijven (zie de daadwerkelijke functie bovenin, met 2 nodes, 3 dimensies) langzaam groter dan 0 worden. Bij een stap wordt hij van 0 naar 1,4E-14, terwijl hij 0 moet blijven.
Waarom blijft ie niet nul? is dit een afrondingsfout oid?
Ik hoop dat alles duidelijk is
De daadwerkelijke functie, volledig uitgeschreven:
code:
1
| 0.5*px*px+0.5*py*py+0.5*pz*pz+0.5*pa*pa+0.5*pb*pb+0.5*pc*pc+0.5*x*x*x*x-2*x*x*x*a+1*x*x*a*a+1*x*x*y*y-2*x*x*y*b+1*x*x*b*b+1*x*x*z*z-2*x*x*z*c+1*x*x*c*c-1*x*x+2*x*a*x*a-2*x*a*a*a-2*x*a*y*y+4*x*a*y*b-2*x*a*b*b-2*x*a*z*z+4*x*a*z*c-2*x*a*c*c+2*x*a+0.5*a*a*a*a+1*a*a*y*y-2*a*a*y*b+1*a*a*b*b+1*a*a*z*z-2*a*a*z*c+1*a*a*c*c-1*a*a+0.5*y*y*y*y-2*y*y*y*b+1*y*y*b*b+1*y*y*z*z-2*y*y*z*c+1*y*y*c*c-1*y*y+2*y*b*y*b-2*y*b*b*b-2*y*b*z*z+4*y*b*z*c-2*y*b*c*c+2*y*b+0.5*b*b*b*b+1*b*b*z*z-2*b*b*z*c+1*b*b*c*c-1*b*b+0.5*z*z*z*z-2*z*z*z*c+1*z*z*c*c-1*z*z+2*z*c*z*c-2*z*c*c*c+2*z*c+0.5*c*c*c*c-1*c*c+0.5 |
Deze functie sla ik op in 3 arrays:
Array 1 geeft de coefficient aan: [2,3,-10,1] (met fucntie boven genoemd bij (1) ) (double array)
Array 2 hoeveel vars er zijn: [2,4,1,0] (int array)
Array 3 welke vars [0,0,0,0,1,1,4] (0=x en 1=y, 3=px, 4=py) (deze array is de som van array 2 groot) (int array)
Verder heb ik een state vector, bij dit voorbeeld [statex,statey, statepx, statepy] (statex & statey zijn dus getallen, statepx & statepy zijn de impulsen, doubles)
En een afgeleide: [statexdot, stateydot, statepxdot, statepydot].
Dus elk punt heeft een coordinaat en een impuls. Stel dat je 2 dimensies hebt en 1 punt, dan heb je zoals boven staat. Het aantal states is dus het aantal dimensies*2.
Om de afgeleide te berkenen loop is alsvolgt door de 3 arrays heen:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| memset(dStatesDot, 0x00,iNMax*sizeof(double)); while (iWhichCoeff<iMaxTerms){ if (dCoefficient[iWhichCoeff]==0) break; for (unsigned int iLoop=0;iLoop<iNumberOfVariabeles[iWhichCoeff];iLoop++){ dTemp=dCoefficient[iWhichCoeff]; for (unsigned int iLoop2=0;iLoop2<iNumberOfVariabeles[iWhichCoeff];iLoop2++){ if (iLoop!=iLoop2){ dTemp=dTemp*dStates[iVariabeles[iWhichVar+iLoop2]]; } } dStatesDot[iVariabeles[iWhichVar+iLoop]]+=dTemp; } iWhichVar+=iNumberOfVariabeles[iWhichCoeff]; iWhichCoeff++; } |
(dCoefficient is array 1, iNumberOfVariabeles is array 2 en iVariabeles is array 3, dStates is toestandsvector en dStatesDot de afgeleide hiervan)
Dit deel maakt van 2x^2 de afgeleide 2x+2x=4x
Dit wordt on the fly ingevuld. Nadat deze code klaar is staat in dStateDot de uitkomst van de afgeleide van H naar dState met de waarden alvast ingevuld.
dState is van het type (x1,y1, px1, py1, x2, y2, px2, py2). dus eerst de lokatie dan de impuls vervolgens het volgende punt.
dState wordt berekend met:
C++:
1
2
3
4
5
6
7
| for (int iLoop=0;iLoop<iN;iLoop++){ for (int iLoop2=0;iLoop2<iDimension;iLoop2++){ dStates[iLoop*2*iDimension+iLoop2+iDimension]+=dDeltaT*(-dStatesDot[iLoop*2*iDimension+iLoop2]-dFriction*dStatesDot[iLoop*2*iDimension+iLoop2+iDimension]); dStates[iLoop*2*iDimension+iLoop2]+=dDeltaT*(dStatesDot[iLoop*2*iDimension+iLoop2+iDimension]); } } |
Oftewel in het geval zoals bij functie (1) (irl is deze veel complexer):
dState[0]=dState[0]+dDeltaT*dStateDot[2] (x=x+dT*px)
dState[1]=dState[1]+dDeltaT*dStateDot[3] (y=y+dT*py)
dState[2]=dState[2]+dDeltaT*(-dStateDot[0] -dFriction*dStateDot[2]) (px=px+dT(-x-wrijving*px)
dState[3]=dState[3]+dDeltaT*(-dStateDot[1] -dFriction*dStateDot[3]) (py=py+dT(-y-wrijving*py)
Nu werkt dit proces prima als dFriction 0 is. (0<=dFriction<1). dDeltaT is de stapgrote in seconde, meestal 0.1
Als dFriction bijv 0.5 is zal dStateDot een afwijking gaat tonen. Deze zal in een situatie dat ie 0 moet bijven (zie de daadwerkelijke functie bovenin, met 2 nodes, 3 dimensies) langzaam groter dan 0 worden. Bij een stap wordt hij van 0 naar 1,4E-14, terwijl hij 0 moet blijven.
Waarom blijft ie niet nul? is dit een afrondingsfout oid?
Ik hoop dat alles duidelijk is
[ Voor 9% gewijzigd door elgringo op 18-06-2006 21:32 ]
if broken it is, fix it you should