Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F84939433
generic_pivoted_greedy_approximant.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Wed, Sep 25, 16:56
Size
42 KB
Mime Type
text/x-python
Expires
Fri, Sep 27, 16:56 (1 d, 23 h)
Engine
blob
Format
Raw Data
Handle
21108655
Attached To
R6746 RationalROMPy
generic_pivoted_greedy_approximant.py
View Options
# Copyright (C) 2018 by the RROMPy authors
#
# This file is part of RROMPy.
#
# RROMPy is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# RROMPy is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with RROMPy. If not, see <http://www.gnu.org/licenses/>.
#
from
abc
import
abstractmethod
from
copy
import
deepcopy
as
copy
import
numpy
as
np
from
matplotlib
import
pyplot
as
plt
from
rrompy.reduction_methods.pivoted.generic_pivoted_approximant
import
(
GenericPivotedApproximantBase
,
GenericPivotedApproximantNoMatch
,
GenericPivotedApproximant
,
PODGlobal
)
from
rrompy.utilities.base.types
import
(
Np1D
,
Tuple
,
List
,
paramVal
,
paramList
,
ListAny
)
from
rrompy.utilities.base
import
verbosityManager
as
vbMng
from
rrompy.utilities.numerical
import
dot
from
rrompy.utilities.numerical.point_matching
import
(
pointMatching
,
chordalMetricAdjusted
,
potential
)
from
rrompy.utilities.exception_manager
import
(
RROMPyException
,
RROMPyAssert
,
RROMPyWarning
)
from
rrompy.parameter
import
checkParameterList
,
emptyParameterList
__all__
=
[
'GenericPivotedGreedyApproximantNoMatch'
,
'GenericPivotedGreedyApproximant'
]
class
GenericPivotedGreedyApproximantBase
(
GenericPivotedApproximantBase
):
_allowedEstimatorKindsMarginal
=
[
"LEAVE_ONE_OUT"
,
"LOOK_AHEAD"
,
"LOOK_AHEAD_RECOVER"
]
def
__init__
(
self
,
*
args
,
**
kwargs
):
self
.
_preInit
()
from
rrompy.parameter.parameter_sampling
import
SparseGridSampler
as
SG
SGBase
=
SG
([[
0.
],
[
1.
]],
"UNIFORM"
)
self
.
_addParametersToList
([
"matchingWeightError"
,
"cutOffToleranceError"
,
"errorEstimatorKindMarginal"
,
"greedyTolMarginal"
,
"maxIterMarginal"
],
[
0.
,
"AUTO"
,
"LEAVE_ONE_OUT"
,
1e-1
,
1e2
],
[
"samplerMarginalGrid"
],
[
SGBase
],
toBeExcluded
=
[
"samplerMarginal"
])
super
()
.
__init__
(
*
args
,
**
kwargs
)
self
.
_postInit
()
@property
def
muBoundsMarginal
(
self
):
"""Value of muBoundsMarginal."""
return
self
.
samplerMarginalGrid
.
lims
@property
def
scaleFactorDer
(
self
):
"""Value of scaleFactorDer."""
if
self
.
_scaleFactorDer
==
"NONE"
:
return
1.
if
self
.
_scaleFactorDer
==
"AUTO"
:
return
self
.
_scaleFactorOldPivot
return
self
.
_scaleFactorDer
@scaleFactorDer.setter
def
scaleFactorDer
(
self
,
scaleFactorDer
):
if
hasattr
(
self
,
"_scaleFactorDer"
):
scaleFactorDerold
=
self
.
scaleFactorDer
else
:
scaleFactorDerold
=
-
1
if
isinstance
(
scaleFactorDer
,
(
str
,)):
scaleFactorDer
=
scaleFactorDer
.
upper
()
self
.
_scaleFactorDer
=
scaleFactorDer
self
.
_approxParameters
[
"scaleFactorDer"
]
=
self
.
_scaleFactorDer
if
scaleFactorDerold
!=
self
.
_scaleFactorDer
:
self
.
resetSamples
()
@property
def
samplerMarginalGrid
(
self
):
"""Value of samplerMarginalGrid."""
return
self
.
_samplerMarginalGrid
@samplerMarginalGrid.setter
def
samplerMarginalGrid
(
self
,
samplerMarginalGrid
):
if
'refine'
not
in
dir
(
samplerMarginalGrid
):
raise
RROMPyException
(
"Marginal sampler type not recognized."
)
if
(
hasattr
(
self
,
'_samplerMarginalGrid'
)
and
self
.
_samplerMarginalGrid
is
not
None
):
samplerOld
=
self
.
samplerMarginalGrid
self
.
_samplerMarginalGrid
=
samplerMarginalGrid
self
.
_approxParameters
[
"samplerMarginalGrid"
]
=
(
self
.
samplerMarginalGrid
)
if
(
not
'samplerOld'
in
locals
()
or
samplerOld
!=
self
.
samplerMarginalGrid
):
self
.
resetSamples
()
@property
def
errorEstimatorKindMarginal
(
self
):
"""Value of errorEstimatorKindMarginal."""
return
self
.
_errorEstimatorKindMarginal
@errorEstimatorKindMarginal.setter
def
errorEstimatorKindMarginal
(
self
,
errorEstimatorKindMarginal
):
errorEstimatorKindMarginal
=
errorEstimatorKindMarginal
.
upper
()
if
errorEstimatorKindMarginal
not
in
(
self
.
_allowedEstimatorKindsMarginal
):
RROMPyWarning
((
"Marginal error estimator kind not recognized. "
"Overriding to 'LEAVE_ONE_OUT'."
))
errorEstimatorKindMarginal
=
"LEAVE_ONE_OUT"
self
.
_errorEstimatorKindMarginal
=
errorEstimatorKindMarginal
self
.
_approxParameters
[
"errorEstimatorKindMarginal"
]
=
(
self
.
errorEstimatorKindMarginal
)
@property
def
matchingWeightError
(
self
):
"""Value of matchingWeightError."""
return
self
.
_matchingWeightError
@matchingWeightError.setter
def
matchingWeightError
(
self
,
matchingWeightError
):
self
.
_matchingWeightError
=
matchingWeightError
self
.
_approxParameters
[
"matchingWeightError"
]
=
(
self
.
matchingWeightError
)
@property
def
cutOffToleranceError
(
self
):
"""Value of cutOffToleranceError."""
return
self
.
_cutOffToleranceError
@cutOffToleranceError.setter
def
cutOffToleranceError
(
self
,
cutOffToleranceError
):
if
isinstance
(
cutOffToleranceError
,
(
str
,)):
cutOffToleranceError
=
cutOffToleranceError
.
upper
()
\
.
strip
()
.
replace
(
" "
,
""
)
if
cutOffToleranceError
!=
"AUTO"
:
RROMPyWarning
((
"String value of cutOffToleranceError not "
"recognized. Overriding to 'AUTO'."
))
cutOffToleranceError
==
"AUTO"
self
.
_cutOffToleranceError
=
cutOffToleranceError
self
.
_approxParameters
[
"cutOffToleranceError"
]
=
(
self
.
cutOffToleranceError
)
@property
def
greedyTolMarginal
(
self
):
"""Value of greedyTolMarginal."""
return
self
.
_greedyTolMarginal
@greedyTolMarginal.setter
def
greedyTolMarginal
(
self
,
greedyTolMarginal
):
if
greedyTolMarginal
<
0
:
raise
RROMPyException
(
"greedyTolMarginal must be non-negative."
)
if
(
hasattr
(
self
,
"_greedyTolMarginal"
)
and
self
.
greedyTolMarginal
is
not
None
):
greedyTolMarginalold
=
self
.
greedyTolMarginal
else
:
greedyTolMarginalold
=
-
1
self
.
_greedyTolMarginal
=
greedyTolMarginal
self
.
_approxParameters
[
"greedyTolMarginal"
]
=
self
.
greedyTolMarginal
if
greedyTolMarginalold
!=
self
.
greedyTolMarginal
:
self
.
resetSamples
()
@property
def
maxIterMarginal
(
self
):
"""Value of maxIterMarginal."""
return
self
.
_maxIterMarginal
@maxIterMarginal.setter
def
maxIterMarginal
(
self
,
maxIterMarginal
):
if
maxIterMarginal
<=
0
:
raise
RROMPyException
(
"maxIterMarginal must be positive."
)
if
(
hasattr
(
self
,
"_maxIterMarginal"
)
and
self
.
maxIterMarginal
is
not
None
):
maxIterMarginalold
=
self
.
maxIterMarginal
else
:
maxIterMarginalold
=
-
1
self
.
_maxIterMarginal
=
maxIterMarginal
self
.
_approxParameters
[
"maxIterMarginal"
]
=
self
.
maxIterMarginal
if
maxIterMarginalold
!=
self
.
maxIterMarginal
:
self
.
resetSamples
()
def
resetSamples
(
self
):
"""Reset samples."""
super
()
.
resetSamples
()
if
not
hasattr
(
self
,
"_temporaryPivot"
):
self
.
_mus
=
emptyParameterList
()
self
.
musMarginal
=
emptyParameterList
()
if
hasattr
(
self
,
"samplerMarginalGrid"
):
self
.
samplerMarginalGrid
.
reset
()
if
hasattr
(
self
,
"samplingEngine"
)
and
self
.
samplingEngine
is
not
None
:
self
.
samplingEngine
.
resetHistory
()
def
getErrorEstimatorMarginalLeaveOneOut
(
self
)
->
Np1D
:
err
=
np
.
zeros
(
len
(
self
.
trainedModel
.
data
.
musMarginal
))
self
.
_musMarginalTestIdxs
=
np
.
arange
(
len
(
err
))
if
len
(
err
)
<=
1
:
err
[:]
=
np
.
inf
return
err
_tMdataFull
=
copy
(
self
.
trainedModel
.
data
)
if
self
.
cutOffToleranceError
==
"AUTO"
:
cutOffTolErr
=
self
.
cutOffTolerance
else
:
cutOffTolErr
=
self
.
cutOffToleranceError
_musMExcl
=
None
self
.
verbosity
-=
35
self
.
trainedModel
.
verbosity
-=
35
foci
=
self
.
samplerPivot
.
normalFoci
()
ground
=
self
.
samplerPivot
.
groundPotential
()
for
j
in
range
(
len
(
err
)):
jEff
=
j
-
(
j
>
0
)
muTest
=
self
.
trainedModel
.
data
.
musMarginal
[
jEff
]
polesEx
=
self
.
trainedModel
.
data
.
HIs
[
jEff
]
.
poles
idxExEff
=
np
.
where
(
potential
(
polesEx
,
foci
)
-
ground
<=
cutOffTolErr
*
ground
)[
0
]
polesEx
=
polesEx
[
idxExEff
]
if
self
.
matchingWeightError
!=
0
:
resEx
=
self
.
trainedModel
.
data
.
HIs
[
jEff
]
.
coeffs
[
idxExEff
]
else
:
resEx
=
None
if
j
>
0
:
self
.
musMarginal
.
insert
(
_musMExcl
,
j
-
1
)
_musMExcl
=
self
.
musMarginal
[
j
]
self
.
musMarginal
.
pop
(
j
)
if
len
(
polesEx
)
==
0
:
continue
self
.
_updateTrainedModelMarginalSamples
([
j
])
self
.
_finalizeMarginalization
()
polesAp
=
self
.
trainedModel
.
interpolateMarginalPoles
(
muTest
)[
...
,
0
]
idxApEff
=
np
.
where
(
potential
(
polesAp
,
foci
)
-
ground
<=
cutOffTolErr
*
ground
)[
0
]
polesAp
=
polesAp
[
idxApEff
]
if
self
.
matchingWeightError
!=
0
:
resAp
=
self
.
trainedModel
.
interpolateMarginalCoeffs
(
muTest
)[
idxApEff
,
:,
0
]
if
self
.
POD
!=
PODGlobal
:
resEx
=
self
.
trainedModel
.
data
.
projMat
[:,
:
resEx
.
shape
[
1
]]
.
dot
(
resEx
.
T
)
resAp
=
self
.
trainedModel
.
data
.
projMat
[:,
:
resAp
.
shape
[
1
]]
.
dot
(
resAp
.
T
)
else
:
resAp
=
None
dist
=
chordalMetricAdjusted
(
polesEx
,
polesAp
,
self
.
matchingWeightError
,
resEx
,
resAp
,
self
.
HFEngine
,
False
)
pmR
,
pmC
=
pointMatching
(
dist
)
err
[
j
]
=
np
.
mean
(
dist
[
pmR
,
pmC
])
self
.
_updateTrainedModelMarginalSamples
()
self
.
musMarginal
.
append
(
_musMExcl
)
self
.
verbosity
+=
35
self
.
trainedModel
.
verbosity
+=
35
self
.
trainedModel
.
data
=
_tMdataFull
return
err
def
getErrorEstimatorMarginalLookAhead
(
self
)
->
Np1D
:
if
not
hasattr
(
self
.
trainedModel
,
"_musMExcl"
):
err
=
np
.
zeros
(
0
)
err
[:]
=
np
.
inf
self
.
_musMarginalTestIdxs
=
np
.
zeros
(
0
,
dtype
=
int
)
return
err
err
=
np
.
zeros
(
len
(
self
.
trainedModel
.
_musMExcl
))
self
.
_musMarginalTestIdxs
=
np
.
array
(
self
.
trainedModel
.
_idxExcl
,
dtype
=
int
)
self
.
verbosity
-=
35
self
.
trainedModel
.
verbosity
-=
35
if
self
.
cutOffToleranceError
==
"AUTO"
:
cutOffTolErr
=
self
.
cutOffTolerance
else
:
cutOffTolErr
=
self
.
cutOffToleranceError
foci
=
self
.
samplerPivot
.
normalFoci
()
ground
=
self
.
samplerPivot
.
groundPotential
()
for
j
,
(
muTest
,
HITest
)
in
enumerate
(
zip
(
self
.
trainedModel
.
_musMExcl
,
self
.
trainedModel
.
_HIsExcl
)):
polesEx
=
HITest
.
poles
idxExEff
=
np
.
where
(
potential
(
polesEx
,
foci
)
-
ground
<=
cutOffTolErr
*
ground
)[
0
]
polesEx
=
polesEx
[
idxExEff
]
if
self
.
matchingWeightError
!=
0
:
resEx
=
HITest
.
coeffs
[
idxExEff
]
else
:
resEx
=
None
if
len
(
polesEx
)
==
0
:
continue
polesAp
=
self
.
trainedModel
.
interpolateMarginalPoles
(
muTest
)[
...
,
0
]
idxApEff
=
np
.
where
(
potential
(
polesAp
,
foci
)
-
ground
<=
cutOffTolErr
*
ground
)[
0
]
polesAp
=
polesAp
[
idxApEff
]
if
self
.
matchingWeightError
!=
0
:
resAp
=
self
.
trainedModel
.
interpolateMarginalCoeffs
(
muTest
)[
idxApEff
,
:,
0
]
if
self
.
POD
!=
PODGlobal
:
resEx
=
self
.
trainedModel
.
data
.
projMat
[:,
:
resEx
.
shape
[
1
]]
.
dot
(
resEx
.
T
)
resAp
=
self
.
trainedModel
.
data
.
projMat
[:,
:
resAp
.
shape
[
1
]]
.
dot
(
resAp
.
T
)
else
:
resAp
=
None
dist
=
chordalMetricAdjusted
(
polesEx
,
polesAp
,
self
.
matchingWeightError
,
resEx
,
resAp
,
self
.
HFEngine
,
False
)
pmR
,
pmC
=
pointMatching
(
dist
)
err
[
j
]
=
np
.
mean
(
dist
[
pmR
,
pmC
])
self
.
verbosity
+=
35
self
.
trainedModel
.
verbosity
+=
35
return
err
def
errorEstimatorMarginal
(
self
,
return_max
:
bool
=
False
)
->
Np1D
:
vbMng
(
self
.
trainedModel
,
"INIT"
,
"Evaluating error estimator at mu = {}."
.
format
(
self
.
trainedModel
.
data
.
musMarginal
),
10
)
if
self
.
errorEstimatorKindMarginal
==
"LEAVE_ONE_OUT"
:
err
=
self
.
getErrorEstimatorMarginalLeaveOneOut
()
else
:
#if self.errorEstimatorKindMarginal[: 10] == "LOOK_AHEAD":
err
=
self
.
getErrorEstimatorMarginalLookAhead
()
vbMng
(
self
.
trainedModel
,
"DEL"
,
"Done evaluating error estimator"
,
10
)
if
not
return_max
:
return
err
idxMaxEst
=
np
.
where
(
err
>
self
.
greedyTolMarginal
)[
0
]
return
err
,
idxMaxEst
,
err
[
idxMaxEst
]
def
plotEstimatorMarginal
(
self
,
est
:
Np1D
,
idxMax
:
List
[
int
],
estMax
:
List
[
float
]):
if
not
(
np
.
any
(
np
.
isnan
(
est
))
or
np
.
any
(
np
.
isinf
(
est
))):
fig
=
plt
.
figure
(
figsize
=
plt
.
figaspect
(
1.
/
self
.
nparMarginal
))
for
jpar
in
range
(
self
.
nparMarginal
):
ax
=
fig
.
add_subplot
(
1
,
self
.
nparMarginal
,
1
+
jpar
)
if
self
.
errorEstimatorKindMarginal
==
"LEAVE_ONE_OUT"
:
musre
=
copy
(
self
.
trainedModel
.
data
.
musMarginal
.
re
.
data
)
else
:
#if self.errorEstimatorKindMarginal[: 10] == "LOOK_AHEAD":
musre
=
np
.
real
(
self
.
trainedModel
.
_musMExcl
)
if
len
(
idxMax
)
>
0
and
estMax
is
not
None
:
maxrej
=
musre
[
idxMax
,
jpar
]
errCP
=
copy
(
est
)
idx
=
np
.
delete
(
np
.
arange
(
self
.
nparMarginal
),
jpar
)
while
len
(
musre
)
>
0
:
if
self
.
nparMarginal
==
1
:
currIdx
=
np
.
arange
(
len
(
musre
))
else
:
currIdx
=
np
.
where
(
np
.
isclose
(
np
.
sum
(
np
.
abs
(
musre
[:,
idx
]
-
musre
[
0
,
idx
]),
1
),
0.
))[
0
]
currIdxSorted
=
currIdx
[
np
.
argsort
(
musre
[
currIdx
,
jpar
])]
ax
.
semilogy
(
musre
[
currIdxSorted
,
jpar
],
errCP
[
currIdxSorted
],
'k.-'
,
linewidth
=
1
)
musre
=
np
.
delete
(
musre
,
currIdx
,
0
)
errCP
=
np
.
delete
(
errCP
,
currIdx
)
ax
.
semilogy
(
self
.
musMarginal
.
re
(
jpar
),
(
self
.
greedyTolMarginal
,)
*
len
(
self
.
musMarginal
),
'*m'
)
if
len
(
idxMax
)
>
0
and
estMax
is
not
None
:
ax
.
semilogy
(
maxrej
,
estMax
,
'xr'
)
ax
.
grid
()
plt
.
tight_layout
()
plt
.
show
()
def
_addMarginalSample
(
self
,
mus
:
paramList
):
mus
=
checkParameterList
(
mus
,
self
.
nparMarginal
)[
0
]
if
len
(
mus
)
==
0
:
return
nmus
=
len
(
mus
)
vbMng
(
self
,
"MAIN"
,
(
"Adding marginal sample point{} no. {}{} at {} to training "
"set."
)
.
format
(
"s"
*
(
nmus
>
1
),
len
(
self
.
musMarginal
)
+
1
,
"--{}"
.
format
(
len
(
self
.
musMarginal
)
+
nmus
)
*
(
nmus
>
1
),
mus
),
3
)
self
.
musMarginal
.
append
(
mus
)
self
.
setupApproxPivoted
(
mus
)
self
.
_poleMatching
()
if
(
self
.
errorEstimatorKindMarginal
[:
10
]
==
"LOOK_AHEAD"
and
not
self
.
firstGreedyIterM
):
ubRange
=
len
(
self
.
trainedModel
.
data
.
musMarginal
)
if
hasattr
(
self
.
trainedModel
,
"_idxExcl"
):
shRange
=
len
(
self
.
trainedModel
.
_musMExcl
)
else
:
shRange
=
0
testIdxs
=
list
(
range
(
ubRange
+
shRange
-
len
(
mus
),
ubRange
+
shRange
))
for
j
in
testIdxs
[::
-
1
]:
self
.
musMarginal
.
pop
(
j
-
shRange
)
if
hasattr
(
self
.
trainedModel
,
"_idxExcl"
):
testIdxs
=
self
.
trainedModel
.
_idxExcl
+
testIdxs
self
.
_updateTrainedModelMarginalSamples
(
testIdxs
)
self
.
_finalizeMarginalization
()
self
.
_SMarginal
=
len
(
self
.
musMarginal
)
self
.
_approxParameters
[
"SMarginal"
]
=
self
.
SMarginal
self
.
trainedModel
.
data
.
approxParameters
[
"SMarginal"
]
=
self
.
SMarginal
def
greedyNextSampleMarginal
(
self
,
muidx
:
List
[
int
],
plotEst
:
str
=
"NONE"
)
\
->
Tuple
[
Np1D
,
List
[
int
],
float
,
paramVal
]:
RROMPyAssert
(
self
.
_mode
,
message
=
"Cannot add greedy sample."
)
if
(
self
.
errorEstimatorKindMarginal
[:
10
]
==
"LOOK_AHEAD"
and
not
self
.
firstGreedyIterM
):
if
not
hasattr
(
self
.
trainedModel
,
"_idxExcl"
):
raise
RROMPyException
((
"Sample index to be added not present "
"in trained model."
))
testIdxs
=
copy
(
self
.
trainedModel
.
_idxExcl
)
skippedIdx
=
0
for
cj
,
j
in
enumerate
(
self
.
trainedModel
.
_idxExcl
):
if
j
in
muidx
:
testIdxs
.
pop
(
skippedIdx
)
self
.
musMarginal
.
insert
(
self
.
trainedModel
.
_musMExcl
[
cj
],
j
-
skippedIdx
)
else
:
skippedIdx
+=
1
if
len
(
self
.
trainedModel
.
_idxExcl
)
<
(
len
(
muidx
)
+
len
(
testIdxs
)):
raise
RROMPyException
((
"Sample index to be added not present "
"in trained model."
))
self
.
_updateTrainedModelMarginalSamples
(
testIdxs
)
self
.
_SMarginal
=
len
(
self
.
musMarginal
)
self
.
_approxParameters
[
"SMarginal"
]
=
self
.
SMarginal
self
.
trainedModel
.
data
.
approxParameters
[
"SMarginal"
]
=
(
self
.
SMarginal
)
self
.
firstGreedyIterM
=
False
idxAdded
=
self
.
samplerMarginalGrid
.
refine
(
muidx
)
self
.
_addMarginalSample
(
self
.
samplerMarginalGrid
.
points
[
idxAdded
])
errorEstTest
,
muidx
,
maxErrorEst
=
self
.
errorEstimatorMarginal
(
True
)
if
plotEst
==
"ALL"
:
self
.
plotEstimatorMarginal
(
errorEstTest
,
muidx
,
maxErrorEst
)
return
(
errorEstTest
,
self
.
_musMarginalTestIdxs
[
muidx
],
maxErrorEst
,
self
.
samplerMarginalGrid
.
points
[
muidx
])
def
_preliminaryTrainingMarginal
(
self
):
"""Initialize starting snapshots of solution map."""
RROMPyAssert
(
self
.
_mode
,
message
=
"Cannot start greedy algorithm."
)
if
np
.
sum
(
self
.
samplingEngine
.
nsamples
)
>
0
:
return
self
.
resetSamples
()
self
.
_addMarginalSample
(
self
.
samplerMarginalGrid
.
generatePoints
(
self
.
SMarginal
))
def
_finalizeSnapshots
(
self
):
self
.
samplingEngine
=
self
.
_samplingEngineOld
for
muM
,
sEN
in
zip
(
self
.
musMargLoc
,
self
.
samplingEngs
):
self
.
samplingEngine
.
samples
+=
[
sEN
.
samples
]
self
.
samplingEngine
.
nsamples
+=
[
sEN
.
nsamples
]
self
.
samplingEngine
.
mus
+=
[
sEN
.
mus
]
self
.
samplingEngine
.
musMarginal
.
append
(
muM
)
self
.
samplingEngine
.
_derIdxs
+=
[[(
0
,)
*
self
.
npar
]
for
_
in
range
(
sEN
.
nsamples
)]
if
self
.
POD
:
self
.
samplingEngine
.
RPOD
+=
[
sEN
.
RPOD
]
self
.
samplingEngine
.
samples_full
+=
[
copy
(
sEN
.
samples_full
)]
if
self
.
POD
==
PODGlobal
:
self
.
samplingEngine
.
coalesceSamples
(
self
.
interpRcondMarginal
)
else
:
self
.
samplingEngine
.
coalesceSamples
()
def
_preSetupApproxPivoted
(
self
,
mus
:
paramList
)
->
Tuple
[
ListAny
,
ListAny
]:
self
.
computeScaleFactor
()
if
self
.
trainedModel
is
None
:
self
.
trainedModel
=
self
.
tModelType
()
self
.
trainedModel
.
verbosity
=
self
.
verbosity
self
.
trainedModel
.
timestamp
=
self
.
timestamp
datadict
=
{
"mu0"
:
self
.
mu0
,
"mus"
:
None
,
"projMat"
:
np
.
zeros
((
0
,
0
)),
"scaleFactor"
:
self
.
scaleFactor
,
"rescalingExp"
:
self
.
HFEngine
.
rescalingExp
,
"directionPivot"
:
self
.
directionPivot
}
self
.
trainedModel
.
data
=
self
.
initializeModelData
(
datadict
)[
0
]
self
.
trainedModel
.
data
.
Qs
,
self
.
trainedModel
.
data
.
Ps
=
[],
[]
self
.
_trainedModelOld
=
copy
(
self
.
trainedModel
)
self
.
_scaleFactorOldPivot
=
copy
(
self
.
scaleFactor
)
self
.
scaleFactor
=
self
.
scaleFactorPivot
self
.
_temporaryPivot
=
1
self
.
_samplingEngineOld
=
copy
(
self
.
samplingEngine
)
self
.
musMargLoc
,
self
.
samplingEngs
=
[],
[
None
]
*
len
(
mus
)
Qs
,
Ps
=
[
None
]
*
len
(
mus
),
[
None
]
*
len
(
mus
)
self
.
verbosity
-=
15
return
Qs
,
Ps
def
_postSetupApproxPivoted
(
self
,
mus
:
paramList
,
Qs
:
ListAny
,
Ps
:
ListAny
):
self
.
scaleFactor
=
self
.
_scaleFactorOldPivot
del
self
.
_scaleFactorOldPivot
,
self
.
_temporaryPivot
self
.
_finalizeSnapshots
()
del
self
.
_samplingEngineOld
,
self
.
musMargLoc
,
self
.
samplingEngs
self
.
_mus
=
self
.
samplingEngine
.
musCoalesced
self
.
trainedModel
=
self
.
_trainedModelOld
del
self
.
_trainedModelOld
self
.
trainedModel
.
data
.
mus
=
copy
(
self
.
mus
)
self
.
trainedModel
.
data
.
musMarginal
=
copy
(
self
.
musMarginal
)
padRight
=
self
.
samplingEngine
.
nsamplesTot
-
self
.
trainedModel
.
nmus
nmusOld
=
len
(
self
.
trainedModel
.
data
.
Ps
)
for
j
in
range
(
nmusOld
):
self
.
trainedModel
.
data
.
Ps
[
j
]
.
pad
(
0
,
padRight
)
self
.
trainedModel
.
data
.
HIs
[
j
]
.
pad
(
0
,
padRight
)
if
hasattr
(
self
.
trainedModel
,
"_PsExcl"
):
nmusOldExcl
=
len
(
self
.
trainedModel
.
_PsExcl
)
for
j
in
range
(
nmusOldExcl
):
self
.
trainedModel
.
_PsExcl
[
j
]
.
pad
(
0
,
padRight
)
self
.
trainedModel
.
_HIsExcl
[
j
]
.
pad
(
0
,
padRight
)
nmusOld
+=
nmusOldExcl
padLeft
=
self
.
trainedModel
.
nmus
for
j
in
range
(
len
(
mus
)):
nsj
=
self
.
samplingEngine
.
nsamples
[
nmusOld
+
j
]
if
self
.
POD
==
PODGlobal
:
rRightj
=
self
.
samplingEngine
.
RPODCPart
[:,
padLeft
:
padLeft
+
nsj
]
Ps
[
j
]
.
postmultiplyTensorize
(
rRightj
.
T
)
else
:
padRight
-=
nsj
Ps
[
j
]
.
pad
(
padLeft
,
padRight
)
padLeft
+=
nsj
pMat
=
self
.
samplingEngine
.
samplesCoalesced
.
data
pMatEff
=
dot
(
self
.
HFEngine
.
C
,
pMat
)
if
self
.
approx_state
else
pMat
self
.
trainedModel
.
data
.
projMat
=
pMatEff
self
.
trainedModel
.
data
.
Qs
+=
Qs
self
.
trainedModel
.
data
.
Ps
+=
Ps
self
.
trainedModel
.
data
.
approxParameters
=
copy
(
self
.
approxParameters
)
self
.
verbosity
+=
15
@abstractmethod
def
setupApproxPivoted
(
self
,
mus
:
paramList
)
->
int
:
if
self
.
checkComputedApproxPivoted
():
return
-
1
RROMPyAssert
(
self
.
_mode
,
message
=
"Cannot setup approximant."
)
vbMng
(
self
,
"INIT"
,
"Setting up pivoted approximant."
,
10
)
Qs
,
Ps
=
self
.
_preSetupApproxPivoted
()
pass
self
.
_postSetupApproxPivoted
(
mus
,
Qs
,
Ps
)
vbMng
(
self
,
"DEL"
,
"Done setting up pivoted approximant."
,
10
)
return
0
def
setupApprox
(
self
,
plotEst
:
str
=
"NONE"
)
->
int
:
"""Compute greedy snapshots of solution map."""
if
self
.
checkComputedApprox
():
return
-
1
RROMPyAssert
(
self
.
_mode
,
message
=
"Cannot start greedy algorithm."
)
vbMng
(
self
,
"INIT"
,
"Starting computation of snapshots."
,
3
)
max2ErrorEst
,
self
.
firstGreedyIterM
=
np
.
inf
,
True
self
.
_preliminaryTrainingMarginal
()
if
self
.
errorEstimatorKindMarginal
==
"LEAVE_ONE_OUT"
:
muidx
=
[]
else
:
#if self.errorEstimatorKindMarginal[: 10] == "LOOK_AHEAD":
muidx
=
np
.
arange
(
len
(
self
.
trainedModel
.
data
.
musMarginal
))
while
self
.
firstGreedyIterM
or
(
max2ErrorEst
>
self
.
greedyTolMarginal
and
self
.
samplerMarginalGrid
.
npoints
<
self
.
maxIterMarginal
):
errorEstTest
,
muidx
,
maxErrorEst
,
mu
=
\
self
.
greedyNextSampleMarginal
(
muidx
,
plotEst
)
if
len
(
maxErrorEst
)
>
0
:
max2ErrorEst
=
np
.
max
(
maxErrorEst
)
vbMng
(
self
,
"MAIN"
,
(
"Uniform testing error estimate "
"{:.4e}."
)
.
format
(
max2ErrorEst
),
3
)
else
:
max2ErrorEst
=
0.
if
plotEst
==
"LAST"
:
self
.
plotEstimatorMarginal
(
errorEstTest
,
muidx
,
maxErrorEst
)
vbMng
(
self
,
"DEL"
,
(
"Done computing snapshots (final snapshot count: "
"{})."
)
.
format
(
np
.
sum
(
self
.
samplingEngine
.
nsamples
)),
3
)
if
(
self
.
errorEstimatorKindMarginal
==
"LOOK_AHEAD_RECOVER"
and
len
(
self
.
trainedModel
.
_idxExcl
)
>
0
):
vbMng
(
self
,
"INIT"
,
"Recovering {} test models."
.
format
(
len
(
self
.
trainedModel
.
_idxExcl
)),
7
)
for
j
,
mu
in
zip
(
self
.
trainedModel
.
_idxExcl
,
self
.
trainedModel
.
_musMExcl
):
self
.
musMarginal
.
insert
(
mu
,
j
)
self
.
_updateTrainedModelMarginalSamples
()
self
.
_finalizeMarginalization
()
self
.
_SMarginal
=
len
(
self
.
musMarginal
)
self
.
_approxParameters
[
"SMarginal"
]
=
self
.
SMarginal
self
.
trainedModel
.
data
.
approxParameters
[
"SMarginal"
]
=
(
self
.
SMarginal
)
vbMng
(
self
,
"DEL"
,
"Done recovering test models."
,
7
)
return
0
def
checkComputedApprox
(
self
)
->
bool
:
return
(
super
()
.
checkComputedApprox
()
and
len
(
self
.
mus
)
==
len
(
self
.
trainedModel
.
data
.
mus
))
def
checkComputedApproxPivoted
(
self
)
->
bool
:
return
(
super
()
.
checkComputedApprox
()
and
len
(
self
.
musMarginal
)
==
len
(
self
.
trainedModel
.
data
.
musMarginal
))
class
GenericPivotedGreedyApproximantNoMatch
(
GenericPivotedGreedyApproximantBase
,
GenericPivotedApproximantNoMatch
):
"""
ROM pivoted greedy interpolant computation for parametric problems (without
pole matching) (ABSTRACT).
Args:
HFEngine: HF problem solver.
mu0(optional): Default parameter. Defaults to 0.
directionPivot(optional): Pivot components. Defaults to [0].
approxParameters(optional): Dictionary containing values for main
parameters of approximant. Recognized keys are:
- 'POD': whether to compute POD of snapshots; defaults to True;
- 'scaleFactorDer': scaling factors for derivative computation;
defaults to 'AUTO';
- 'cutOffTolerance': tolerance for ignoring parasitic poles;
defaults to np.inf;
- 'matchingWeightError': weight for pole matching optimization in
error estimation; defaults to 0;
- 'cutOffToleranceError': tolerance for ignoring parasitic poles
in error estimation; defaults to 'AUTO', i.e. cutOffTolerance;
- 'S': total number of pivot samples current approximant relies
upon;
- 'samplerPivot': pivot sample point generator;
- 'SMarginal': number of starting marginal samples;
- 'samplerMarginalGrid': marginal sample point generator via sparse
grid;
- 'errorEstimatorKindMarginal': kind of marginal error estimator;
available values include 'LEAVE_ONE_OUT', 'LOOK_AHEAD', and
'LOOK_AHEAD_RECOVER'; defaults to 'LEAVE_ONE_OUT';
- 'greedyTolMarginal': uniform error tolerance for marginal greedy
algorithm; defaults to 1e-1;
- 'maxIterMarginal': maximum number of marginal greedy steps;
defaults to 1e2;
- 'radialDirectionalWeightsMarginal': radial basis weights for
marginal interpolant; defaults to 1;
- 'interpRcondMarginal': tolerance for marginal interpolation;
defaults to None.
Defaults to empty dict.
approx_state(optional): Whether to approximate state. Defaults to
False.
verbosity(optional): Verbosity level. Defaults to 10.
Attributes:
HFEngine: HF problem solver.
mu0: Default parameter.
directionPivot: Pivot components.
mus: Array of snapshot parameters.
musMarginal: Array of marginal snapshot parameters.
approxParameters: Dictionary containing values for main parameters of
approximant. Recognized keys are in parameterList.
parameterListSoft: Recognized keys of soft approximant parameters:
- 'POD': whether to compute POD of snapshots;
- 'scaleFactorDer': scaling factors for derivative computation;
- 'cutOffTolerance': tolerance for ignoring parasitic poles;
- 'matchingWeightError': weight for pole matching optimization in
error estimation;
- 'cutOffToleranceError': tolerance for ignoring parasitic poles
in error estimation;
- 'errorEstimatorKindMarginal': kind of marginal error estimator;
- 'greedyTolMarginal': uniform error tolerance for marginal greedy
algorithm;
- 'maxIterMarginal': maximum number of marginal greedy steps;
- 'radialDirectionalWeightsMarginal': radial basis weights for
marginal interpolant;
- 'interpRcondMarginal': tolerance for marginal interpolation.
parameterListCritical: Recognized keys of critical approximant
parameters:
- 'S': total number of pivot samples current approximant relies
upon;
- 'samplerPivot': pivot sample point generator;
- 'SMarginal': total number of marginal samples current approximant
relies upon;
- 'samplerMarginalGrid': marginal sample point generator via sparse
grid.
approx_state: Whether to approximate state.
verbosity: Verbosity level.
POD: Whether to compute POD of snapshots.
scaleFactorDer: Scaling factors for derivative computation.
cutOffTolerance: Tolerance for ignoring parasitic poles.
matchingWeightError: Weight for pole matching optimization in error
estimation.
cutOffToleranceError: Tolerance for ignoring parasitic poles in error
estimation.
S: Total number of pivot samples current approximant relies upon.
samplerPivot: Pivot sample point generator.
SMarginal: Total number of marginal samples current approximant relies
upon.
samplerMarginalGrid: Marginal sample point generator via sparse grid.
errorEstimatorKindMarginal: Kind of marginal error estimator.
greedyTolMarginal: Uniform error tolerance for marginal greedy
algorithm.
maxIterMarginal: Maximum number of marginal greedy steps.
radialDirectionalWeightsMarginal: Radial basis weights for marginal
interpolant.
interpRcondMarginal: Tolerance for marginal interpolation.
muBounds: list of bounds for pivot parameter values.
muBoundsMarginal: list of bounds for marginal parameter values.
samplingEngine: Sampling engine.
uHF: High fidelity solution(s) with parameter(s) lastSolvedHF as
sampleList.
lastSolvedHF: Parameter(s) corresponding to last computed high fidelity
solution(s) as parameterList.
uApproxReduced: Reduced approximate solution(s) with parameter(s)
lastSolvedApprox as sampleList.
lastSolvedApproxReduced: Parameter(s) corresponding to last computed
reduced approximate solution(s) as parameterList.
uApprox: Approximate solution(s) with parameter(s) lastSolvedApprox as
sampleList.
lastSolvedApprox: Parameter(s) corresponding to last computed
approximate solution(s) as parameterList.
"""
def
_poleMatching
(
self
):
vbMng
(
self
,
"INIT"
,
"Compressing poles."
,
10
)
self
.
trainedModel
.
initializeFromRational
()
vbMng
(
self
,
"DEL"
,
"Done compressing and matching poles."
,
10
)
def
_updateTrainedModelMarginalSamples
(
self
,
idx
:
ListAny
=
[]):
self
.
trainedModel
.
updateEffectiveSamples
(
idx
)
class
GenericPivotedGreedyApproximant
(
GenericPivotedGreedyApproximantBase
,
GenericPivotedApproximant
):
"""
ROM pivoted greedy interpolant computation for parametric problems (with
pole matching) (ABSTRACT).
Args:
HFEngine: HF problem solver.
mu0(optional): Default parameter. Defaults to 0.
directionPivot(optional): Pivot components. Defaults to [0].
approxParameters(optional): Dictionary containing values for main
parameters of approximant. Recognized keys are:
- 'POD': whether to compute POD of snapshots; defaults to True;
- 'scaleFactorDer': scaling factors for derivative computation;
defaults to 'AUTO';
- 'matchingWeight': weight for pole matching optimization; defaults
to 1;
- 'cutOffTolerance': tolerance for ignoring parasitic poles;
defaults to np.inf;
- 'cutOffSharedRatio': required ratio of marginal points to share
resonance in cut off strategy; defaults to 1.;
- 'matchingWeightError': weight for pole matching optimization in
error estimation; defaults to 0;
- 'cutOffToleranceError': tolerance for ignoring parasitic poles
in error estimation; defaults to 'AUTO', i.e. cutOffTolerance;
- 'S': total number of pivot samples current approximant relies
upon;
- 'samplerPivot': pivot sample point generator;
- 'SMarginal': number of starting marginal samples;
- 'samplerMarginalGrid': marginal sample point generator via sparse
grid;
- 'errorEstimatorKindMarginal': kind of marginal error estimator;
available values include 'LEAVE_ONE_OUT', 'LOOK_AHEAD', and
'LOOK_AHEAD_RECOVER'; defaults to 'LEAVE_ONE_OUT';
- 'polybasisMarginal': type of polynomial basis for marginal
interpolation; allowed values include 'MONOMIAL', 'CHEBYSHEV'
and 'LEGENDRE'; defaults to 'MONOMIAL';
- 'MMarginal': degree of marginal interpolant; defaults to 'AUTO',
i.e. maximum allowed;
- 'greedyTolMarginal': uniform error tolerance for marginal greedy
algorithm; defaults to 1e-1;
- 'maxIterMarginal': maximum number of marginal greedy steps;
defaults to 1e2;
- 'polydegreetypeMarginal': type of polynomial degree for marginal;
defaults to 'TOTAL';
- 'radialDirectionalWeightsMarginal': radial basis weights for
marginal interpolant; defaults to 1;
- 'interpRcondMarginal': tolerance for marginal interpolation;
defaults to None.
Defaults to empty dict.
approx_state(optional): Whether to approximate state. Defaults to
False.
verbosity(optional): Verbosity level. Defaults to 10.
Attributes:
HFEngine: HF problem solver.
mu0: Default parameter.
directionPivot: Pivot components.
mus: Array of snapshot parameters.
musMarginal: Array of marginal snapshot parameters.
approxParameters: Dictionary containing values for main parameters of
approximant. Recognized keys are in parameterList.
parameterListSoft: Recognized keys of soft approximant parameters:
- 'POD': whether to compute POD of snapshots;
- 'scaleFactorDer': scaling factors for derivative computation;
- 'matchingWeight': weight for pole matching optimization;
- 'cutOffTolerance': tolerance for ignoring parasitic poles;
- 'cutOffSharedRatio': required ratio of marginal points to share
resonance in cut off strategy;
- 'matchingWeightError': weight for pole matching optimization in
error estimation;
- 'cutOffToleranceError': tolerance for ignoring parasitic poles
in error estimation;
- 'errorEstimatorKindMarginal': kind of marginal error estimator;
- 'polybasisMarginal': type of polynomial basis for marginal
interpolation;
- 'MMarginal': degree of marginal interpolant;
- 'greedyTolMarginal': uniform error tolerance for marginal greedy
algorithm;
- 'maxIterMarginal': maximum number of marginal greedy steps;
- 'polydegreetypeMarginal': type of polynomial degree for marginal;
- 'radialDirectionalWeightsMarginal': radial basis weights for
marginal interpolant;
- 'interpRcondMarginal': tolerance for marginal interpolation.
parameterListCritical: Recognized keys of critical approximant
parameters:
- 'S': total number of pivot samples current approximant relies
upon;
- 'samplerPivot': pivot sample point generator;
- 'SMarginal': total number of marginal samples current approximant
relies upon;
- 'samplerMarginalGrid': marginal sample point generator via sparse
grid.
approx_state: Whether to approximate state.
verbosity: Verbosity level.
POD: Whether to compute POD of snapshots.
scaleFactorDer: Scaling factors for derivative computation.
matchingWeight: Weight for pole matching optimization.
cutOffTolerance: Tolerance for ignoring parasitic poles.
cutOffSharedRatio: Required ratio of marginal points to share resonance
in cut off strategy.
matchingWeightError: Weight for pole matching optimization in error
estimation.
cutOffToleranceError: Tolerance for ignoring parasitic poles in error
estimation.
S: Total number of pivot samples current approximant relies upon.
samplerPivot: Pivot sample point generator.
SMarginal: Total number of marginal samples current approximant relies
upon.
samplerMarginalGrid: Marginal sample point generator via sparse grid.
errorEstimatorKindMarginal: Kind of marginal error estimator.
polybasisMarginal: Type of polynomial basis for marginal interpolation.
MMarginal: Degree of marginal interpolant.
greedyTolMarginal: Uniform error tolerance for marginal greedy
algorithm.
maxIterMarginal: Maximum number of marginal greedy steps.
polydegreetypeMarginal: Type of polynomial degree for marginal.
radialDirectionalWeightsMarginal: Radial basis weights for marginal
interpolant.
interpRcondMarginal: Tolerance for marginal interpolation.
muBounds: list of bounds for pivot parameter values.
muBoundsMarginal: list of bounds for marginal parameter values.
samplingEngine: Sampling engine.
uHF: High fidelity solution(s) with parameter(s) lastSolvedHF as
sampleList.
lastSolvedHF: Parameter(s) corresponding to last computed high fidelity
solution(s) as parameterList.
uApproxReduced: Reduced approximate solution(s) with parameter(s)
lastSolvedApprox as sampleList.
lastSolvedApproxReduced: Parameter(s) corresponding to last computed
reduced approximate solution(s) as parameterList.
uApprox: Approximate solution(s) with parameter(s) lastSolvedApprox as
sampleList.
lastSolvedApprox: Parameter(s) corresponding to last computed
approximate solution(s) as parameterList.
"""
def
_poleMatching
(
self
):
vbMng
(
self
,
"INIT"
,
"Compressing and matching poles."
,
10
)
self
.
trainedModel
.
initializeFromRational
(
self
.
HFEngine
,
self
.
matchingWeight
,
self
.
POD
==
PODGlobal
,
False
)
vbMng
(
self
,
"DEL"
,
"Done compressing and matching poles."
,
10
)
def
_updateTrainedModelMarginalSamples
(
self
,
idx
:
ListAny
=
[]):
self
.
trainedModel
.
updateEffectiveSamples
(
idx
,
self
.
HFEngine
,
self
.
matchingWeight
,
self
.
POD
==
PODGlobal
,
False
)
def
getErrorEstimatorMarginalLeaveOneOut
(
self
)
->
Np1D
:
if
not
hasattr
(
self
,
"_MMarginal_isauto"
):
if
not
hasattr
(
self
,
"_MMarginalOriginal"
):
self
.
_MMarginalOriginal
=
self
.
MMarginal
self
.
MMarginal
=
self
.
_MMarginalOriginal
self
.
_reduceDegreeNNoWarn
=
1
err
=
super
()
.
getErrorEstimatorMarginalLeaveOneOut
()
del
self
.
_reduceDegreeNNoWarn
return
err
Event Timeline
Log In to Comment