Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
R
rotagaporp-c
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Ivan Kondov
rotagaporp-c
Commits
2eb89527
Commit
2eb89527
authored
6 years ago
by
Ivan Kondov
Browse files
Options
Downloads
Patches
Plain Diff
divided difference tests, arbitrary precision for newtonian related funcs
parent
a68056bb
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
classical/newtonian.py
+68
-21
68 additions, 21 deletions
classical/newtonian.py
classical/tests.py
+13
-0
13 additions, 0 deletions
classical/tests.py
with
81 additions
and
21 deletions
classical/newtonian.py
+
68
−
21
View file @
2eb89527
"""
Newtonian propagator for classical particle dynamics
"""
import
numpy
as
np
import
sympy
as
sp
from
propagators
import
Propagator
from
liouville
import
LiouvillePowersQP
...
...
@@ -27,14 +28,29 @@ def divdiff_2(x, y, dtype=float):
return
np
.
diagonal
(
a
)
def
leja_points_ga
(
number
):
"""
calculate Leja interpolation points based on algorithm from
def
leja_points_ga
(
number
,
fpprec
=
'
fixed
'
,
prec
=
None
,
ptype
=
'
real
'
):
"""
calculate Leja interpolation points based on
an
algorithm from
G. Ashkenazi et al. JCP 103, 10005 (1995)
"""
center
=
0.0
trials
=
np
.
linspace
(
-
1.
,
1.
,
3
*
number
).
tolist
()
if
ptype
==
'
real
'
:
if
fpprec
==
'
fixed
'
:
dtype
=
np
.
float64
center
=
dtype
(
0
)
trials
=
np
.
linspace
(
dtype
(
-
1
),
dtype
(
1
),
3
*
number
).
tolist
()
isclose
=
np
.
isclose
else
:
flt
=
sp
.
Float
tol
=
flt
(
10
**
(
-
prec
/
2
),
prec
)
center
,
low
,
high
=
flt
(
0
,
prec
),
flt
(
-
1
,
prec
),
flt
(
1
,
prec
)
step
=
(
high
-
low
)
/
(
3
*
number
-
1
)
trials
=
np
.
arange
(
low
,
high
+
step
,
step
).
tolist
()
isclose
=
lambda
x
,
y
:
abs
(
x
-
y
)
<=
tol
elif
ptype
==
'
complex
'
:
# fixme: complex trial points in fixed and arbitrary precision
pass
for
index
,
trial
in
enumerate
(
trials
):
if
np
.
isclose
(
trial
,
center
):
if
isclose
(
trial
,
center
):
del
trials
[
index
]
chosen
=
[
trials
.
pop
(
0
)]
while
len
(
chosen
)
<
number
:
...
...
@@ -43,17 +59,31 @@ def leja_points_ga(number):
scaling
=
np
.
prod
(
np
.
absolute
(
center
-
np
.
array
(
chosen
)))
**
(
1.
/
number
)
return
np
.
array
(
chosen
)
/
scaling
,
scaling
def
leja_points_jb
(
nflp
):
"""
calculate fast Leja points based on algorithm from
def
leja_points_jb
(
nflp
,
fpprec
=
'
fixed
'
,
prec
=
None
,
ptype
=
'
real
'
):
"""
calculate fast Leja points based on an algorithm from
Baglama et al. Electronic Trans. Numer. Anal. 7, 124 (1998)
"""
zs
=
np
.
empty
(
nflp
)
zt
=
np
.
empty
(
nflp
)
zprod
=
np
.
empty
(
nflp
)
index
=
np
.
empty
((
nflp
,
2
),
dtype
=
np
.
int
)
if
fpprec
==
'
fixed
'
:
dtype
=
np
.
float64
if
ptype
==
'
real
'
else
np
.
complex128
left
=
dtype
(
-
1
)
right
=
dtype
(
1
)
else
:
dtype
=
np
.
object
if
ptype
==
'
real
'
:
left
=
sp
.
Float
(
-
1
,
prec
)
right
=
sp
.
Float
(
1
,
prec
)
else
:
# fixme: complex initial points in arbitrary precision
pass
zs
=
np
.
empty
(
nflp
,
dtype
=
dtype
)
zt
=
np
.
empty
(
nflp
,
dtype
=
dtype
)
zprod
=
np
.
empty
(
nflp
,
dtype
=
dtype
)
index
=
np
.
empty
((
nflp
,
2
),
dtype
=
np
.
uint32
)
zt
[
0
]
=
-
1.
zt
[
1
]
=
1.
zt
[
0
]
=
left
zt
[
1
]
=
right
zt
[
2
]
=
(
zt
[
0
]
+
zt
[
1
])
/
2
zs
[
0
]
=
(
zt
[
1
]
+
zt
[
2
])
/
2
zs
[
1
]
=
(
zt
[
2
]
+
zt
[
0
])
/
2
...
...
@@ -97,30 +127,47 @@ def newton_scalar(lambdas, func, vals, scale=1.0, shift=0.0):
class
Newtonian
(
Propagator
):
"""
Newtonian propagator for classical particle dynamics
"""
name
=
'
newtonian
'
def
__init__
(
self
,
delta
=
1.0
,
lambda_min
=
None
,
nterms
=
10
,
liouville
=
LiouvillePowersQP
,
**
kwargs
):
def
__init__
(
self
,
delta
=
1.0
,
lambda_min
=
None
,
nterms
=
None
,
liouville
=
LiouvillePowersQP
,
liou_params
=
{},
fpprec
=
'
fixed
'
,
prec
=
None
,
**
kwargs
):
Propagator
.
__init__
(
self
,
**
kwargs
)
assert
delta
>
0
assert
nterms
>
0
self
.
fpprec
=
fpprec
self
.
prec
=
prec
self
.
delta
=
delta
self
.
nterms
=
nterms
self
.
lambda_min
=
-
self
.
delta
/
2.
if
lambda_min
is
None
else
lambda_min
lambdas
,
scaling
=
leja_points_ga
(
self
.
nterms
)
lambdas
,
scaling
=
self
.
ip_points
(
algo
=
'
ga
'
)
self
.
scale
=
self
.
delta
*
scaling
self
.
shift
=
(
self
.
lambda_min
+
self
.
delta
/
2.
)
/
self
.
scale
lamb_sc
=
(
lambdas
*
self
.
scale
+
self
.
shift
)
if
self
.
substep
is
None
:
self
.
ddiffs
=
divdiff_1
(
lambdas
,
np
.
exp
(
lamb_sc
*
self
.
tstep
)
)
self
.
ddiffs
=
self
.
dd_coeffs
(
lambdas
,
lamb_sc
,
self
.
tstep
)
else
:
self
.
ddiffs
=
np
.
array
([
divdiff_1
(
lambdas
,
np
.
exp
(
lamb_sc
*
st
))
for
st
in
self
.
subtime
])
self
.
ddiffs
=
np
.
array
([
self
.
dd_coeffs
(
lambdas
,
lamb_sc
,
st
)
for
st
in
self
.
subtime
])
self
.
iln
=
liouville
(
self
.
nterms
,
self
.
syst
,
scale
=
1.
/
self
.
scale
,
shift
=-
self
.
shift
,
nodes
=
lambdas
,
shift
=-
self
.
shift
,
nodes
=
lambdas
,
fpprec
=
fpprec
,
recursion
=
'
newton
'
)
def
dd_coeffs
(
self
,
lamb
,
lamb_sc
,
t
,
algo
=
1
):
"""
select the algorithm for divided differences
"""
algo_map
=
{
1
:
divdiff_1
,
2
:
divdiff_2
}
if
self
.
fpprec
==
'
fixed
'
:
return
algo_map
[
algo
](
lamb
,
np
.
exp
(
lamb_sc
*
t
))
elif
self
.
fpprec
==
'
multi
'
:
return
algo_map
[
algo
](
lamb
,
[
sp
.
exp
(
i
)
for
i
in
lamb_sc
*
t
])
def
ip_points
(
self
,
ptype
=
'
real
'
,
algo
=
'
ga
'
):
"""
select the algorithm for interpolation points
"""
algo_map
=
{
'
ga
'
:
leja_points_ga
,
'
jb
'
:
leja_points_jb
,
'
ch
'
:
chebyshev_points
}
return
algo_map
[
algo
](
self
.
nterms
,
fpprec
=
self
.
fpprec
,
prec
=
self
.
prec
,
ptype
=
ptype
)
def
step
(
self
,
time
,
q
,
p
):
"""
perform a time step with initial coordinate and momentum
"""
qt
=
np
.
dot
(
self
.
ddiffs
,
self
.
iln
.
qobj
.
get_val_float
(
q
,
p
))
...
...
This diff is collapsed.
Click to expand it.
classical/tests.py
+
13
−
0
View file @
2eb89527
...
...
@@ -349,6 +349,19 @@ class PointsTest(unittest.TestCase):
self
.
assertTrue
(
np
.
allclose
(
pol
,
func
(
vals
),
atol
=
1e-3
))
class
DividedDifferenceTest
(
unittest
.
TestCase
):
"""
Tests for finite difference functions
"""
def
divided_difference_test
(
self
):
"""
compare two algorithms for divided differences
"""
from
newtonian
import
divdiff_1
,
divdiff_2
nodes
=
np
.
arange
(
-
1
,
1
,
0.1
)
funcvals
=
lambda
x
:
2
*
np
.
exp
(
3
*
x
)
diffs1
=
divdiff_1
(
nodes
,
funcvals
(
nodes
))
diffs2
=
divdiff_2
(
nodes
,
funcvals
(
nodes
))
self
.
assertTrue
(
np
.
allclose
(
diffs1
,
diffs2
))
class
NewtonianPropagatorTest
(
unittest
.
TestCase
):
"""
Tests for the Newtonian polynomial propagator
"""
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment