В данном примере мы рассмотрим задачу вычисления экстремальных эллипсоидов — нахождения эллипсоидов, которые наилучшим образом аппроксимируют заданное множество.
Дополнительно мы покажем, как с помощью пакета JuMP можно изучать используемые преобразования (bridges) и исследовать альтернативные формулировки задачи.
Импортируем необходимые пакеты:
Resolving package versions...
No Changes to `~/.project/Project.toml`
No Changes to `~/.project/Manifest.toml`
Постановка задачи
Предположим, что нам дано множество S, состоящее из m точек в n-мерном пространстве:

Наша цель — найти оптимальный вектор c и оптимальную симметричную матрицу D, такие, чтобы эллипс:

содержал множество S и имел наименее возможный объём (площадь).
Оптимальные значения D и c задаются следующей задачей оптимизации:

Данные
Сгенерируем несколько точек:
создать_набор_точек (generic function with 1 method)
Для простоты этого примера возьмём m = 100 :
Модель JuMP
Теперь давайте построим модель JuMP. В результате решения задачи будет вычислены значения D и c.
solution_summary(; result = 1, verbose = false)
├ solver_name : Clarabel
├ Termination
│ ├ termination_status : OPTIMAL
│ ├ result_count : 1
│ └ raw_status : SOLVED
├ Solution (result = 1)
│ ├ primal_status : FEASIBLE_POINT
│ ├ dual_status : FEASIBLE_POINT
│ ├ objective_value : 7.92350e-03
│ └ dual_objective_value : 7.92350e-03
└ Work counters
├ solve_time (sec) : 2.76754e+00
└ barrier_iterations : 15
Результаты вычислений
В результате оптимизации модели, получаем значения D и c:
2×2 Matrix{Float64}:
0.012616 -0.02132
-0.02132 0.0410053
2-element Vector{Float64}:
-1.6318778932525726
-0.6704582481106572
Мы можем убедиться, что каждая точка лежит внутри эллипсоида, проверив, что величина наибольшего нормализованного радиуса не превышает единицу:
Совмещая полученное решение с графиком, мы видим эллипсоид, минимизирующий объём аппроксимации:
Альтернативные постановки задачи
Формулировка модели использует объект MOI.RootDetConeSquare. Однако, поскольку решатель Clarabel не поддерживает этот объект напрямую, JuMP автоматически переформулирует задачу в эквивалентную, которую поддерживает решатель Clarabel. Вы можете увидеть переформулировку, выбранную JuMP, с помощью команды print_active_bridges.
* Unsupported objective: MOI.VariableIndex
| bridged by:
| MOIB.Objective.FunctionConversionBridge{Float64, MOI.ScalarAffineFunction{Float64}, MOI.VariableIndex}
| may introduce:
| * Supported objective: MOI.ScalarAffineFunction{Float64}
* Unsupported constraint: MOI.ScalarAffineFunction{Float64}-in-MOI.LessThan{Float64}
| bridged by:
| MOIB.Constraint.LessToGreaterBridge{Float64, MOI.ScalarAffineFunction{Float64}, MOI.ScalarAffineFunction{Float64}}
| may introduce:
| * Unsupported constraint: MOI.ScalarAffineFunction{Float64}-in-MOI.GreaterThan{Float64}
| | bridged by:
| | MOIB.Constraint.VectorizeBridge{Float64, MOI.VectorAffineFunction{Float64}, MOI.Nonnegatives, MOI.ScalarAffineFunction{Float64}}
| | may introduce:
| | * Supported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.Nonnegatives
* Unsupported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.PositiveSemidefiniteConeSquare
| bridged by:
| MOIB.Constraint.SquareBridge{Float64, MOI.VectorAffineFunction{Float64}, MOI.ScalarAffineFunction{Float64}, MOI.PositiveSemidefiniteConeTriangle, MOI.PositiveSemidefiniteConeSquare}
| may introduce:
| * Unsupported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.PositiveSemidefiniteConeTriangle
| | bridged by:
| | MOIB.Constraint.SetDotScalingBridge{Float64, MOI.PositiveSemidefiniteConeTriangle, MOI.VectorAffineFunction{Float64}, MOI.VectorAffineFunction{Float64}}
| | may introduce:
| | * Supported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.Scaled{MOI.PositiveSemidefiniteConeTriangle}
| * Unsupported constraint: MOI.ScalarAffineFunction{Float64}-in-MOI.EqualTo{Float64}
| | bridged by:
| | MOIB.Constraint.VectorizeBridge{Float64, MOI.VectorAffineFunction{Float64}, MOI.Zeros, MOI.ScalarAffineFunction{Float64}}
| | may introduce:
| | * Supported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.Zeros
* Unsupported constraint: MOI.VectorOfVariables-in-MOI.PositiveSemidefiniteConeTriangle
| bridged by:
| MOIB.Constraint.SetDotScalingBridge{Float64, MOI.PositiveSemidefiniteConeTriangle, MOI.VectorAffineFunction{Float64}, MOI.VectorOfVariables}
| may introduce:
| * Supported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.Scaled{MOI.PositiveSemidefiniteConeTriangle}
* Unsupported constraint: MOI.VectorOfVariables-in-MOI.RootDetConeSquare
| bridged by:
| MOIB.Constraint.SquareBridge{Float64, MOI.VectorOfVariables, MOI.ScalarAffineFunction{Float64}, MOI.RootDetConeTriangle, MOI.RootDetConeSquare}
| may introduce:
| * Unsupported constraint: MOI.VectorOfVariables-in-MOI.RootDetConeTriangle
| | bridged by:
| | MOIB.Constraint.RootDetBridge{Float64, MOI.VectorAffineFunction{Float64}, MOI.VectorOfVariables, MOI.VectorOfVariables}
| | may introduce:
| | * Unsupported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.PositiveSemidefiniteConeTriangle
| | | bridged by:
| | | MOIB.Constraint.SetDotScalingBridge{Float64, MOI.PositiveSemidefiniteConeTriangle, MOI.VectorAffineFunction{Float64}, MOI.VectorAffineFunction{Float64}}
| | | may introduce:
| | | * Supported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.Scaled{MOI.PositiveSemidefiniteConeTriangle}
| | * Unsupported constraint: MOI.VectorOfVariables-in-MOI.GeometricMeanCone
| | | bridged by:
| | | MOIB.Constraint.GeoMeanToPowerBridge{Float64, MOI.VectorOfVariables}
| | | may introduce:
| | | * Supported constraint: MOI.VectorOfVariables-in-MOI.PowerCone{Float64}
| | | * Supported variable: MOI.Nonnegatives
| | * Supported variable: MOI.Reals
| * Unsupported constraint: MOI.ScalarAffineFunction{Float64}-in-MOI.EqualTo{Float64}
| | bridged by:
| | MOIB.Constraint.VectorizeBridge{Float64, MOI.VectorAffineFunction{Float64}, MOI.Zeros, MOI.ScalarAffineFunction{Float64}}
| | may introduce:
| | * Supported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.Zeros
Обратим внимание на первый пункт:
- Unsupported objective: MOI.VariableIndex
| bridged by:
| MOIB.Objective.FunctionConversionBridge{Float64}
| may introduce:
| * Supported objective: MOI.ScalarAffineFunction{Float64}
Здесь говорится о том, что Clarabel не поддерживает целевую функцию типа MOI.VariableIndex, и что JuMP использовал MOI.Bridges.Objective.FunctionConversionBridge, чтобы преобразовать её в целевую функцию типа MOI.ScalarAffineFunction{Float64}.
Мы можем оставить JuMP выполнять переформулированную задачу, или можем переписать нашу модель так, чтобы целевая функция была в формате, который Clarabel поддерживает напрямую:
Активные мосты (active bridges) — это концепция в контексте JuMP и MOI (MathOptInterface), которая используется для описания механизмов преобразования или адаптации между различными типами данных или структур в процессе оптимизации.
С помощью команды print_active_bridges, снова выведем активные мосты:
* Supported objective: MOI.ScalarAffineFunction{Float64}
* Unsupported constraint: MOI.ScalarAffineFunction{Float64}-in-MOI.LessThan{Float64}
| bridged by:
| MOIB.Constraint.LessToGreaterBridge{Float64, MOI.ScalarAffineFunction{Float64}, MOI.ScalarAffineFunction{Float64}}
| may introduce:
| * Unsupported constraint: MOI.ScalarAffineFunction{Float64}-in-MOI.GreaterThan{Float64}
| | bridged by:
| | MOIB.Constraint.VectorizeBridge{Float64, MOI.VectorAffineFunction{Float64}, MOI.Nonnegatives, MOI.ScalarAffineFunction{Float64}}
| | may introduce:
| | * Supported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.Nonnegatives
* Unsupported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.PositiveSemidefiniteConeSquare
| bridged by:
| MOIB.Constraint.SquareBridge{Float64, MOI.VectorAffineFunction{Float64}, MOI.ScalarAffineFunction{Float64}, MOI.PositiveSemidefiniteConeTriangle, MOI.PositiveSemidefiniteConeSquare}
| may introduce:
| * Unsupported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.PositiveSemidefiniteConeTriangle
| | bridged by:
| | MOIB.Constraint.SetDotScalingBridge{Float64, MOI.PositiveSemidefiniteConeTriangle, MOI.VectorAffineFunction{Float64}, MOI.VectorAffineFunction{Float64}}
| | may introduce:
| | * Supported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.Scaled{MOI.PositiveSemidefiniteConeTriangle}
| * Unsupported constraint: MOI.ScalarAffineFunction{Float64}-in-MOI.EqualTo{Float64}
| | bridged by:
| | MOIB.Constraint.VectorizeBridge{Float64, MOI.VectorAffineFunction{Float64}, MOI.Zeros, MOI.ScalarAffineFunction{Float64}}
| | may introduce:
| | * Supported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.Zeros
* Unsupported constraint: MOI.VectorOfVariables-in-MOI.PositiveSemidefiniteConeTriangle
| bridged by:
| MOIB.Constraint.SetDotScalingBridge{Float64, MOI.PositiveSemidefiniteConeTriangle, MOI.VectorAffineFunction{Float64}, MOI.VectorOfVariables}
| may introduce:
| * Supported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.Scaled{MOI.PositiveSemidefiniteConeTriangle}
* Unsupported constraint: MOI.VectorOfVariables-in-MOI.RootDetConeSquare
| bridged by:
| MOIB.Constraint.SquareBridge{Float64, MOI.VectorOfVariables, MOI.ScalarAffineFunction{Float64}, MOI.RootDetConeTriangle, MOI.RootDetConeSquare}
| may introduce:
| * Unsupported constraint: MOI.VectorOfVariables-in-MOI.RootDetConeTriangle
| | bridged by:
| | MOIB.Constraint.RootDetBridge{Float64, MOI.VectorAffineFunction{Float64}, MOI.VectorOfVariables, MOI.VectorOfVariables}
| | may introduce:
| | * Unsupported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.PositiveSemidefiniteConeTriangle
| | | bridged by:
| | | MOIB.Constraint.SetDotScalingBridge{Float64, MOI.PositiveSemidefiniteConeTriangle, MOI.VectorAffineFunction{Float64}, MOI.VectorAffineFunction{Float64}}
| | | may introduce:
| | | * Supported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.Scaled{MOI.PositiveSemidefiniteConeTriangle}
| | * Unsupported constraint: MOI.VectorOfVariables-in-MOI.GeometricMeanCone
| | | bridged by:
| | | MOIB.Constraint.GeoMeanToPowerBridge{Float64, MOI.VectorOfVariables}
| | | may introduce:
| | | * Supported constraint: MOI.VectorOfVariables-in-MOI.PowerCone{Float64}
| | | * Supported variable: MOI.Nonnegatives
| | * Supported variable: MOI.Reals
| * Unsupported constraint: MOI.ScalarAffineFunction{Float64}-in-MOI.EqualTo{Float64}
| | bridged by:
| | MOIB.Constraint.VectorizeBridge{Float64, MOI.VectorAffineFunction{Float64}, MOI.Zeros, MOI.ScalarAffineFunction{Float64}}
| | may introduce:
| | * Supported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.Zeros
Мы можем вручную реализовать некоторые другие переформулировки, чтобы изменить нашу модель на то, что ближе поддерживается Clarabel, следующим образом:
-
Заменить MOI.VectorOfVariables в ограничении MOI.PositiveSemidefiniteConeTriangle @variable(model, Z[1:n, 1:n], PSD) на MOI.VectorAffineFunction в MOI.PositiveSemidefiniteConeTriangle @constraint(model, Z >= 0, PSDCone()).
-
Заменить MOI.VectorOfVariables в ограничении MOI.PositiveSemidefiniteConeSquare [s z'; z Z] >= 0, PSDCone() на MOI.VectorAffineFunction в MOI.PositiveSemidefiniteConeTriangle @constraint(model, LinearAlgebra.Symmetric([s z'; z Z]) >= 0, PSDCone()).
-
Заменить MOI.ScalarAffineFunction в ограничениях MOI.GreaterThan на векторизованный эквивалент MOI.VectorAffineFunction в MOI.Nonnegatives.
-
Заменить MOI.VectorOfVariables в ограничении MOI.RootDetConeSquare на MOI.VectorAffineFunction в MOI.RootDetConeTriangle.
Данная формулировка выводит наиболее краткий результат:
* Supported objective: MOI.ScalarAffineFunction{Float64}
* Supported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.Nonnegatives
* Unsupported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.PositiveSemidefiniteConeTriangle
| bridged by:
| MOIB.Constraint.SetDotScalingBridge{Float64, MOI.PositiveSemidefiniteConeTriangle, MOI.VectorAffineFunction{Float64}, MOI.VectorAffineFunction{Float64}}
| may introduce:
| * Supported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.Scaled{MOI.PositiveSemidefiniteConeTriangle}
* Unsupported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.RootDetConeTriangle
| bridged by:
| MOIB.Constraint.RootDetBridge{Float64, MOI.VectorAffineFunction{Float64}, MOI.VectorAffineFunction{Float64}, MOI.VectorAffineFunction{Float64}}
| may introduce:
| * Unsupported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.PositiveSemidefiniteConeTriangle
| | bridged by:
| | MOIB.Constraint.SetDotScalingBridge{Float64, MOI.PositiveSemidefiniteConeTriangle, MOI.VectorAffineFunction{Float64}, MOI.VectorAffineFunction{Float64}}
| | may introduce:
| | * Supported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.Scaled{MOI.PositiveSemidefiniteConeTriangle}
| * Unsupported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.GeometricMeanCone
| | bridged by:
| | MOIB.Constraint.GeoMeanToPowerBridge{Float64, MOI.VectorAffineFunction{Float64}}
| | may introduce:
| | * Supported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.PowerCone{Float64}
| | * Supported variable: MOI.Nonnegatives
| * Supported variable: MOI.Reals
Обратите внимание, что нам все еще нужно устранить ограничения MOI.PositiveSemidefiniteConeTriangle.
Данная формулировка выводит ещё более краткий результат:
* Supported objective: MOI.ScalarAffineFunction{Float64}
* Supported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.Nonnegatives
* Unsupported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.RootDetConeTriangle
| bridged by:
| MOIB.Constraint.RootDetBridge{Float64, MOI.VectorAffineFunction{Float64}, MOI.VectorAffineFunction{Float64}, MOI.VectorAffineFunction{Float64}}
| may introduce:
| * Unsupported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.PositiveSemidefiniteConeTriangle
| | bridged by:
| | MOIB.Constraint.SetDotScalingBridge{Float64, MOI.PositiveSemidefiniteConeTriangle, MOI.VectorAffineFunction{Float64}, MOI.VectorAffineFunction{Float64}}
| | may introduce:
| | * Supported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.Scaled{MOI.PositiveSemidefiniteConeTriangle}
| * Unsupported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.GeometricMeanCone
| | bridged by:
| | MOIB.Constraint.GeoMeanToPowerBridge{Float64, MOI.VectorAffineFunction{Float64}}
| | may introduce:
| | * Supported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.PowerCone{Float64}
| | * Supported variable: MOI.Nonnegatives
| * Supported variable: MOI.Reals
* Supported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.Scaled{MOI.PositiveSemidefiniteConeTriangle}
Сейчас существует только один пункт с Unsupported constraint, показывающий, как JuMP переформулировал ограничение MOI.RootDetConeTriangle, добавив смесь ограничений MOI.PositiveSemidefiniteConeTriangle и MOI.GeometricMeanCone.
Поскольку Clarabel не поддерживает MOI.GeometricMeanCone по умолчанию, эти ограничения были дополнительно связаны с помощью MOI.Bridges.Constraint.GeoMeanToPowerBridge, преобразующего их в серию ограничений MOI.PowerCone.
Однако существует множество других способов, как можно переформулировать MOI.GeometricMeanCone в нечто, что поддерживает Clarabel. Давайте посмотрим, что произойдет, если использовать функцию remove_bridge для удаления MOI.Bridges.Constraint.GeoMeanToPowerBridge.
Теперь время, затраченное на решение, составляет:
При этом, ранее оно составляло:
Почему время решения разное?
* Supported objective: MOI.ScalarAffineFunction{Float64}
* Supported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.Nonnegatives
* Unsupported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.RootDetConeTriangle
| bridged by:
| MOIB.Constraint.RootDetBridge{Float64, MOI.VectorAffineFunction{Float64}, MOI.VectorAffineFunction{Float64}, MOI.VectorAffineFunction{Float64}}
| may introduce:
| * Unsupported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.PositiveSemidefiniteConeTriangle
| | bridged by:
| | MOIB.Constraint.SetDotScalingBridge{Float64, MOI.PositiveSemidefiniteConeTriangle, MOI.VectorAffineFunction{Float64}, MOI.VectorAffineFunction{Float64}}
| | may introduce:
| | * Supported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.Scaled{MOI.PositiveSemidefiniteConeTriangle}
| * Unsupported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.GeometricMeanCone
| | bridged by:
| | MOIB.Constraint.GeoMeantoRelEntrBridge{Float64, MOI.VectorOfVariables, MOI.VectorAffineFunction{Float64}, MOI.VectorAffineFunction{Float64}}
| | may introduce:
| | * Unsupported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.RelativeEntropyCone
| | | bridged by:
| | | MOIB.Constraint.RelativeEntropyBridge{Float64, MOI.ScalarAffineFunction{Float64}, MOI.VectorAffineFunction{Float64}, MOI.VectorAffineFunction{Float64}}
| | | may introduce:
| | | * Unsupported constraint: MOI.ScalarAffineFunction{Float64}-in-MOI.GreaterThan{Float64}
| | | | bridged by:
| | | | MOIB.Constraint.VectorizeBridge{Float64, MOI.VectorAffineFunction{Float64}, MOI.Nonnegatives, MOI.ScalarAffineFunction{Float64}}
| | | | may introduce:
| | | | * Supported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.Nonnegatives
| | | * Supported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.ExponentialCone
| | | * Supported variable: MOI.Reals
| | * Supported variable: MOI.Nonnegatives
| * Supported variable: MOI.Reals
* Supported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.Scaled{MOI.PositiveSemidefiniteConeTriangle}
На этот раз JuMP использовал MOI.Bridges.Constraint.GeoMeantoRelEntrBridge для переформулировки ограничения в набор MOI.RelativeEntropyCone, который затем был преобразован в поддерживаемые MOI.ExponentialCone.
Выводы
Поскольку две модели эквивалентны, можно сделать вывод, что для этой конкретной модели переформулировки имеют схожую производительность.
Однако в целом производительность конкретной переформулировки зависит от задачи и решателя. Поэтому JuMP выбирает минимизацию количества мостов в стандартной переформулировке, оставляя вам возможность исследовать альтернативные формулировки с использованием инструментов и техник, показанных в данном примере.
{"id": "id_7a39a3c1_b035_4c9a_8539_a7c9cd9a5714", "data": [{"xaxis": "x", "colorbar": {"y": 0.5092592592592593, "title": {"text": ""}, "len": 0.968358121901429, "x": 0.9934383202099737}, "yaxis": "y", "x": [-3.3490987156209817, 9.606491103968791, -7.037618436898614, -11.754019746431748, -20.957852892434254, 8.619381432633023, 8.366797422709963, -0.06460111270596264, 3.098486135619049, -5.898162576690571, 3.691425608843117, 18.152253962595875, 4.4226471308996125, 23.57487952824484, -12.89623892592521, -21.760546217869443, 12.4573932733573, -14.479153208391299, 0.05598700945245476, 0.5421743760276212, -17.011694846880467, 9.53007980816498, -15.195852811850786, -17.40511889593174, 20.751456578513665, -4.330945715350789, 3.4963878741775467, -11.49268802418483, 4.4437725439141005, 5.311923465920337, 1.2383306475215012, -14.452930689848062, 6.49818963962199, -3.5226333750304275, 0.3320881232891915, -10.323783564118976, 10.494725784039067, -7.10908496516043, 11.201109252151126, -21.217973830252866, 11.37457538789468, -0.23298212720050096, -8.161367669146566, 7.39814487485474, -6.9858954170696235, 16.229735907817478, 1.4795154015643537, -2.4526678033481435, -1.5124678412418802, -24.60078529292935, 4.619725886460332, -3.2411737208735403, 13.013613231382166, -1.4786370313016954, -5.946476060070587, 3.3228996687691246, 14.944998169364055, 4.897991469078823, -1.187521408457963, -8.439657644888959, -6.254769181098608, 13.804833020022382, 0.5398560701018709, 16.70952983259261, -6.027815597066124, -9.509919344387395, -5.382533401733241, -6.361793557338844, -9.250057004518778, 2.171790171261307, -12.156464760458084, 7.791970192874637, 3.6115867132497974, 7.472173346272949, 12.747957453006554, -3.3723282815745845, -3.2695545721389703, 2.1377496099265016, -2.453389796384996, -4.228296178879583, 0.18517262483331504, -3.6873579628354216, 16.193015350068006, 1.7458048409761118, -5.149027259166739, 1.680833993254939, -3.811483929528111, -2.974257322967, 13.563607923044666, -2.6818209492573883, 8.303191394133666, -6.347139808353712, -0.9038993062084054, -1.05619749770499, 4.728496423663663, -10.840430598343891, -2.6403177993428493, 5.269932106022182, 9.237435225607962, 11.243097800873667], "showlegend": false, "mode": "markers", "name": "", "legendgroup": "", "marker": {"symbol": "x", "color": "rgba(0, 128, 0, 1.000)", "line": {"color": "rgba(0, 0, 0, 1)", "width": 1}, "size": 8}, "y": [3.062500766630359, 2.5623005537280634, -2.9918984016612282, -6.417092656895781, -8.022880023472286, 6.030852968489048, 2.2240993493187964, -1.210171778000885, -0.23564010146122552, -2.4503703836716233, 1.3870520966542892, 10.65887258206088, 2.7347726265617283, 13.24967066777139, -10.959923375117897, -11.32948826780193, 5.3324822215880525, -6.35331482797913, 3.1737190747354003, -4.460524695937656, -12.254142246743807, 2.575928799574141, -9.968442592324177, -9.62754418968112, 11.21525362115118, -2.929459407607324, 1.9954183810321358, -8.204578289479647, 4.4853048588460025, -1.656373854909833, -0.1197106015249201, -9.489968879889162, 7.7302626175799, -2.9180811471577552, -3.163718196082942, -3.2339301501224806, 5.434462603540627, -3.2803707424621154, 9.279562448211124, -11.411970244509034, 4.300677662749332, -3.0286641123612164, -4.824191945417634, 6.71303318662357, -6.661338125918399, 5.553082219852242, 1.250296253184102, 0.14144970395596682, -4.862817901243207, -10.447422382786026, 1.7416704514206427, -0.8961845738542168, 7.614606483083802, 2.757464354290432, -2.7843565621950566, 1.3398007454480174, 6.839474788255538, 6.0562121699478695, 1.6142408423500965, -2.612031748376201, 1.309345349047747, 8.251373943625197, 4.459381386969271, 12.30475802376817, -3.4408863646031316, -7.907980208353036, -5.037499033773025, -3.4866093949139794, -4.717114894081754, -0.2790237161327206, -6.46811232018008, 5.011295773938353, 1.8766089592126478, 2.666969026229599, 6.540934993067022, -0.4169815325368356, -0.06507534583195311, -2.2605405584195344, 1.4147617719999217, -1.556648954224336, -1.223762315552699, -3.1143462990960926, 6.065252733366385, 1.0741098814797245, -1.4561003119420177, 5.58428300330767, -2.2399702734863034, -0.06775343869006648, 9.488106369878635, -1.5012526644451725, 4.849289691612516, -5.297980225261804, 2.117944792707555, -3.203301128423447, 2.004162948482073, -8.728547459569928, -1.9152415179497593, -1.0094685409099917, 3.9544602786788756, 5.864608538417655], "type": "scatter"}], "config": {"showlegend": true, "xaxis": {"showticklabels": true, "gridwidth": 0.5, "tickvals": [-20, -10, 0, 10, 20], "range": [-27.060863822222284, 27.060863822222284], "domain": [0.05100612423447069, 0.9934383202099737], "mirror": false, "tickangle": 0, "showline": true, "ticktext": ["-20", "-10", "0", "10", "20"], "zeroline": false, "tickfont": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "zerolinecolor": "rgba(0, 0, 0, 1)", "anchor": "y", "visible": true, "ticks": "inside", "tickmode": "array", "linecolor": "rgba(0, 0, 0, 1)", "showgrid": true, "title": {"text": "", "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}}, "gridcolor": "rgba(0, 0, 0, 0.1)", "tickcolor": "rgb(0, 0, 0)", "type": "linear"}, "paper_bgcolor": "rgba(255, 255, 255, 1.000)", "annotations": [], "height": 600, "margin": {"l": 0, "b": 20, "r": 0, "t": 20}, "plot_bgcolor": "rgba(255, 255, 255, 1.000)", "yaxis": {"showticklabels": true, "gridwidth": 0.5, "tickvals": [-20, -10, 0, 10, 20], "range": [-27.060863822222284, 27.060863822222284], "domain": [0.025080198308544768, 0.9934383202099738], "mirror": false, "tickangle": 0, "showline": true, "ticktext": ["-20", "-10", "0", "10", "20"], "zeroline": false, "tickfont": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "zerolinecolor": "rgba(0, 0, 0, 1)", "anchor": "x", "visible": true, "ticks": "inside", "tickmode": "array", "linecolor": "rgba(0, 0, 0, 1)", "showgrid": true, "title": {"text": "", "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}}, "gridcolor": "rgba(0, 0, 0, 0.1)", "tickcolor": "rgb(0, 0, 0)", "type": "linear"}, "legend": {"yanchor": "auto", "xanchor": "auto", "bordercolor": "rgba(0, 0, 0, 1)", "bgcolor": "rgba(255, 255, 255, 1.000)", "borderwidth": 1, "tracegroupgap": 0, "y": 1, "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "title": {"font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}, "text": ""}, "traceorder": "normal", "x": 1}, "width": 848.796875}}
{"id": "id_07007a72_f994_4eb6_a1dc_6aeae4e3a9c9", "data": [{"xaxis": "x", "colorbar": {"y": 0.5092592592592593, "title": {"text": ""}, "len": 0.968358121901429, "x": 0.9934383202099737}, "yaxis": "y", "x": [-3.3490987156209817, 9.606491103968791, -7.037618436898614, -11.754019746431748, -20.957852892434254, 8.619381432633023, 8.366797422709963, -0.06460111270596264, 3.098486135619049, -5.898162576690571, 3.691425608843117, 18.152253962595875, 4.4226471308996125, 23.57487952824484, -12.89623892592521, -21.760546217869443, 12.4573932733573, -14.479153208391299, 0.05598700945245476, 0.5421743760276212, -17.011694846880467, 9.53007980816498, -15.195852811850786, -17.40511889593174, 20.751456578513665, -4.330945715350789, 3.4963878741775467, -11.49268802418483, 4.4437725439141005, 5.311923465920337, 1.2383306475215012, -14.452930689848062, 6.49818963962199, -3.5226333750304275, 0.3320881232891915, -10.323783564118976, 10.494725784039067, -7.10908496516043, 11.201109252151126, -21.217973830252866, 11.37457538789468, -0.23298212720050096, -8.161367669146566, 7.39814487485474, -6.9858954170696235, 16.229735907817478, 1.4795154015643537, -2.4526678033481435, -1.5124678412418802, -24.60078529292935, 4.619725886460332, -3.2411737208735403, 13.013613231382166, -1.4786370313016954, -5.946476060070587, 3.3228996687691246, 14.944998169364055, 4.897991469078823, -1.187521408457963, -8.439657644888959, -6.254769181098608, 13.804833020022382, 0.5398560701018709, 16.70952983259261, -6.027815597066124, -9.509919344387395, -5.382533401733241, -6.361793557338844, -9.250057004518778, 2.171790171261307, -12.156464760458084, 7.791970192874637, 3.6115867132497974, 7.472173346272949, 12.747957453006554, -3.3723282815745845, -3.2695545721389703, 2.1377496099265016, -2.453389796384996, -4.228296178879583, 0.18517262483331504, -3.6873579628354216, 16.193015350068006, 1.7458048409761118, -5.149027259166739, 1.680833993254939, -3.811483929528111, -2.974257322967, 13.563607923044666, -2.6818209492573883, 8.303191394133666, -6.347139808353712, -0.9038993062084054, -1.05619749770499, 4.728496423663663, -10.840430598343891, -2.6403177993428493, 5.269932106022182, 9.237435225607962, 11.243097800873667], "showlegend": false, "mode": "markers", "name": "", "legendgroup": "", "marker": {"symbol": "x", "color": "rgba(0, 128, 0, 1.000)", "line": {"color": "rgba(0, 0, 0, 1)", "width": 1}, "size": 8}, "y": [3.062500766630359, 2.5623005537280634, -2.9918984016612282, -6.417092656895781, -8.022880023472286, 6.030852968489048, 2.2240993493187964, -1.210171778000885, -0.23564010146122552, -2.4503703836716233, 1.3870520966542892, 10.65887258206088, 2.7347726265617283, 13.24967066777139, -10.959923375117897, -11.32948826780193, 5.3324822215880525, -6.35331482797913, 3.1737190747354003, -4.460524695937656, -12.254142246743807, 2.575928799574141, -9.968442592324177, -9.62754418968112, 11.21525362115118, -2.929459407607324, 1.9954183810321358, -8.204578289479647, 4.4853048588460025, -1.656373854909833, -0.1197106015249201, -9.489968879889162, 7.7302626175799, -2.9180811471577552, -3.163718196082942, -3.2339301501224806, 5.434462603540627, -3.2803707424621154, 9.279562448211124, -11.411970244509034, 4.300677662749332, -3.0286641123612164, -4.824191945417634, 6.71303318662357, -6.661338125918399, 5.553082219852242, 1.250296253184102, 0.14144970395596682, -4.862817901243207, -10.447422382786026, 1.7416704514206427, -0.8961845738542168, 7.614606483083802, 2.757464354290432, -2.7843565621950566, 1.3398007454480174, 6.839474788255538, 6.0562121699478695, 1.6142408423500965, -2.612031748376201, 1.309345349047747, 8.251373943625197, 4.459381386969271, 12.30475802376817, -3.4408863646031316, -7.907980208353036, -5.037499033773025, -3.4866093949139794, -4.717114894081754, -0.2790237161327206, -6.46811232018008, 5.011295773938353, 1.8766089592126478, 2.666969026229599, 6.540934993067022, -0.4169815325368356, -0.06507534583195311, -2.2605405584195344, 1.4147617719999217, -1.556648954224336, -1.223762315552699, -3.1143462990960926, 6.065252733366385, 1.0741098814797245, -1.4561003119420177, 5.58428300330767, -2.2399702734863034, -0.06775343869006648, 9.488106369878635, -1.5012526644451725, 4.849289691612516, -5.297980225261804, 2.117944792707555, -3.203301128423447, 2.004162948482073, -8.728547459569928, -1.9152415179497593, -1.0094685409099917, 3.9544602786788756, 5.864608538417655], "type": "scatter"}, {"xaxis": "x", "colorbar": {"y": 0.5092592592592593, "title": {"text": ""}, "len": 0.968358121901429, "x": 0.9934383202099737}, "yaxis": "y", "x": [21.797167730251136, 22.278117237965304, 22.699304209936177, 23.059675898083764, 23.35833156086564, 23.594524714661716, 23.767664999594516, 23.87731965512143, 23.923214601710676, 23.90523512589741, 23.823426167007632, 23.677992204833284, 23.46929674853927, 23.19786142807982, 22.864364690395306, 22.469640103648185, 22.014674273736752, 21.500604378294145, 20.928715324336558, 20.30043653666482, 19.617338385046835, 18.88112825911101, 18.093646300761364, 17.256860804781095, 16.3728632991207, 15.44386331716733, 14.472182875062007, 13.460250667868623, 12.410595999101051, 11.325842458781624, 10.208701365832425, 9.061964991189985, 7.888499578582148, 6.691238180411467, 5.473173326651679, 4.237349545081284, 2.9868557515496104, 1.7248175292959178, 0.4543893166190336, -0.8212534775755709, -2.098922410644328, -3.3754239756516986, -4.6475675834743075, -5.9121735376121896, -7.166080981774065, -8.40615580037188, -9.62929845217764, -10.832451717562188, -12.012608339952198, -13.16681854240535, -14.29219740051659, -15.385932053226618, -16.445288733509642, -17.467619601367257, -18.450369362049436, -19.391081652960658, -20.287405183287145, -21.137099610999343, -21.93804114254027, -22.68822784120337, -23.385784630931653, -24.028967983031364, -24.61617027408567, -25.145923804175965, -25.61690446536734, -26.027935051288793, -26.377988199536116, -26.666188959542836, -26.891816979501016, -27.05430830686554, -27.153256797941847, -27.188415133033637, -27.15969543461327, -27.06716948696988, -26.911068556785985, -26.691782815091262, -26.40986036203813, -26.06600585693685, -25.661078756974213, -25.19609116901817, -24.67220531987775, -24.090730651341346, -23.45312054725411, -22.760968700815372, -22.016005131175497, -21.22009185928907, -20.375218253832177, -19.48349605881679, -18.547154115330514, -17.568532790594613, -16.550078128264783, -15.49433573459592, -14.403944415752159, -13.281629582165829, -12.130196436430618, -10.95252296175606, -9.751552728508342, -8.530287536817413, -7.291779913639865, -6.039125483031343, -4.77545522869855, -3.5039276681705442, -2.2277209581499404, -0.9500249507761663, 0.3259667793435677, 1.5970649174076057, 2.860092380045923, 4.111892256373865, 5.349335698625414, 6.569329742643021, 7.768825038677259, 8.944823473173141, 10.094385662492527, 11.214638299842557, 12.302781337046149, 13.356094983204233, 14.37194650275658, 15.34779679594951, 16.28120674526307, 17.169843311934482, 18.011485367340043, 18.80402924465996, 19.545493996949787, 20.23402634847618, 20.86790532694105, 21.445546565016016, 21.965506260435646], "showlegend": false, "mode": "lines", "name": "", "legendgroup": "", "line": {"color": "rgba(220, 20, 60, 1.000)", "shape": "linear", "dash": "solid", "width": 1}, "y": [9.538389185400858, 10.017181953798094, 10.469261187705975, 10.893496924478049, 11.288828795710083, 11.654268677608858, 11.988903160787038, 12.29189583331095, 12.562489371294811, 12.800007431816057, 13.003856343420399, 13.173526589991285, 13.308594084274848, 13.408721227877166, 13.473657755084444, 13.50324135839695, 13.497398094213253, 13.456142567650689, 13.37957789604021, 13.26789545118673, 13.121374381039288, 12.940380911966553, 12.725367433381633, 12.476871367004133, 12.19551382358575, 11.881998050456858, 11.537107673774408, 11.161704739864682, 10.75672756055638, 10.323188367889735, 9.86217078406357, 9.374827112944134, 8.862375459905541, 8.326096687200735, 7.767331212472884, 7.187475658409382, 6.587979361912446, 5.970340751511686, 5.336103602073132, 4.686853176166059, 4.024212261732152, 3.3498371159607694, 2.665413325508566, 1.9726515934106472, 1.2732834632139147, 0.5690569910199896, -0.13826762374470847, -0.846922437910796, -1.5551361835031647, -2.2611386949884054, -2.963165333766817, -3.6594613988498614, -4.3482865126988015, -5.02791897126221, -5.696660047339409, -6.352838236513834, -6.994813435043546, -7.620981039266432, -8.229775956273727, -8.81967651582717, -9.389208273742152, -9.936947697230297, -10.461525722990055, -10.961631179151986, -11.436014062525569, -11.883488662956198, -12.30293652698307, -12.693309253390332, -13.053631113664165, -13.383001490805873, -13.680597130405376, -13.945674198348499, -14.177570140014842, -14.375705336319317, -14.539584552457974, -14.668798175737114, -14.763023239391698, -14.822024229834048, -14.845653675315178, -14.83385251452737, -14.786650244226664, -14.704164845506346, -14.586602488905646, -14.434257019090781, -14.247509220396298, -14.02682586506256, -13.772758546548234, -13.485942300833898, -13.16709401916283, -12.817010656186232, -12.436567237991655, -12.026714674993483, -11.588477385152114, -11.122950733462597, -10.631298294112558, -10.114748942152728, -9.574593781949297, -9.012182920095421, -8.428922090847813, -7.826269142523224, -7.205730393636877, -6.568856867890641, -5.917240417421585, -5.252509744000585, -4.5763263281261475, -3.890380276188446, -3.196386096083514, -2.496078411836456, -1.7912076279446831, -1.083535554278321, -0.3748310024730417, 0.3331346351778501, 1.038591813281578, 1.7397772562878902, 2.4349383657595927, 3.122337600955911, 3.800256821779471, 4.467001583231692, 5.120905370642918, 5.760333765091126, 6.383688528598068, 6.989411598891873, 7.575988983751262, 8.141954545197693, 8.685893664076717, 9.206446775869153, 9.70231276889435], "type": "scatter"}], "config": {"showlegend": true, "xaxis": {"showticklabels": true, "gridwidth": 0.5, "tickvals": [-20, -10, 0, 10, 20], "range": [-27.060863822222284, 27.060863822222284], "domain": [0.05100612423447069, 0.9934383202099737], "mirror": false, "tickangle": 0, "showline": true, "ticktext": ["-20", "-10", "0", "10", "20"], "zeroline": false, "tickfont": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "zerolinecolor": "rgba(0, 0, 0, 1)", "anchor": "y", "visible": true, "ticks": "inside", "tickmode": "array", "linecolor": "rgba(0, 0, 0, 1)", "showgrid": true, "title": {"text": "", "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}}, "gridcolor": "rgba(0, 0, 0, 0.1)", "tickcolor": "rgb(0, 0, 0)", "type": "linear"}, "paper_bgcolor": "rgba(255, 255, 255, 1.000)", "annotations": [], "height": 600, "margin": {"l": 0, "b": 20, "r": 0, "t": 20}, "plot_bgcolor": "rgba(255, 255, 255, 1.000)", "yaxis": {"showticklabels": true, "gridwidth": 0.5, "tickvals": [-20, -10, 0, 10, 20], "range": [-27.060863822222284, 27.060863822222284], "domain": [0.025080198308544768, 0.9934383202099738], "mirror": false, "tickangle": 0, "showline": true, "ticktext": ["-20", "-10", "0", "10", "20"], "zeroline": false, "tickfont": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "zerolinecolor": "rgba(0, 0, 0, 1)", "anchor": "x", "visible": true, "ticks": "inside", "tickmode": "array", "linecolor": "rgba(0, 0, 0, 1)", "showgrid": true, "title": {"text": "", "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}}, "gridcolor": "rgba(0, 0, 0, 0.1)", "tickcolor": "rgb(0, 0, 0)", "type": "linear"}, "legend": {"yanchor": "auto", "xanchor": "auto", "bordercolor": "rgba(0, 0, 0, 1)", "bgcolor": "rgba(255, 255, 255, 1.000)", "borderwidth": 1, "tracegroupgap": 0, "y": 1, "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "title": {"font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}, "text": ""}, "traceorder": "normal", "x": 1}, "width": 848.796875}}