Skip to content

Commit 4525488

Browse files
authored
Update CombinedOptimizer.cs
1 parent 39989a4 commit 4525488

1 file changed

Lines changed: 41 additions & 24 deletions

File tree

src/Optimizers/CombinedOptimizer.cs

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public OptimizationResults Optimize(OptimizationSnapshot os)
3939
// Process and store results
4040
foreach (var deviceId in uniqueDeviceIds)
4141
{
42-
if (rxAdjRssiDict.TryGetValue(deviceId, out var rxAdjRssi) &&
42+
if (rxAdjRssiDict.TryGetValue(deviceId, out var rxAdjRssi) &&
4343
nodeAbsorptions.TryGetValue(deviceId, out var absorption))
4444
{
4545
results.RxNodes[deviceId] = new ProposedValues
@@ -59,7 +59,7 @@ public OptimizationResults Optimize(OptimizationSnapshot os)
5959
return results;
6060
}
6161

62-
private (Dictionary<string, double> RxAdjRssi, Dictionary<(string, string), double> PathAbsorption, double Error)
62+
private (Dictionary<string, double> RxAdjRssi, Dictionary<(string, string), double> PathAbsorption, double Error)
6363
OptimizeRxAdjRssiAndPathAbsorption(List<Measure> allNodes, List<string> uniqueDeviceIds, ConfigOptimization optimization)
6464
{
6565
var pathPairs = new HashSet<(string, string)>(allNodes.Select(n => (Min(n.Rx.Id, n.Tx.Id), Max(n.Rx.Id, n.Tx.Id))));
@@ -119,31 +119,48 @@ public OptimizationResults Optimize(OptimizationSnapshot os)
119119
return (rxAdjRssiDict, pathAbsorptionDict, result.FunctionInfoAtMinimum.Value);
120120
}
121121

122-
private Dictionary<string, double> OptimizeNodeAbsorptions(List<Measure> allNodes, List<string> uniqueDeviceIds,
122+
private Dictionary<string, double> OptimizeNodeAbsorptions(List<Measure> allNodes, List<string> uniqueDeviceIds,
123123
Dictionary<string, double> rxAdjRssiDict, Dictionary<(string, string), double> pathAbsorptionDict, ConfigOptimization optimization)
124124
{
125-
var obj = ObjectiveFunction.ValueAndGradient(x =>
126-
{
127-
// Objective function (error calculation) remains the same
128-
var value = CalculateError(allNodes, rxAdjRssiDict, pathAbsorptionDict: absorptionDict);
129-
130-
// Numerically approximate the gradient
131-
var gradient = new double[x.Count];
132-
double epsilon = 1e-5;
133-
134-
for (int i = 0; i < x.Count; i++)
135-
{
136-
var xPlusEps = x.Clone();
137-
xPlusEps[i] += epsilon;
125+
// Fix: Use ObjectiveFunction.Gradient() instead of ValueAndGradient
126+
var obj = ObjectiveFunction.Gradient(
127+
x => {
128+
var nodeAbsorptionDict = new Dictionary<string, double>();
129+
for (int i = 0; i < uniqueDeviceIds.Count; i++)
130+
{
131+
var absorption = x[i];
132+
if (absorption < optimization?.AbsorptionMin || absorption > optimization?.AbsorptionMax)
133+
return double.PositiveInfinity;
134+
nodeAbsorptionDict[uniqueDeviceIds[i]] = absorption;
135+
}
138136

139-
var errorPlusEps = CalculateError(allNodes, rxAdjRssiDict, pathAbsorptionDict: absorptionDict);
140-
gradient[i] = (errorPlusEps - value) / epsilon;
141-
}
137+
return CalculateError(allNodes, rxAdjRssiDict, nodeAbsorptionDict: nodeAbsorptionDict);
138+
},
139+
x => {
140+
var nodeAbsorptionDict = new Dictionary<string, double>();
141+
for (int i = 0; i < uniqueDeviceIds.Count; i++)
142+
{
143+
nodeAbsorptionDict[uniqueDeviceIds[i]] = x[i];
144+
}
145+
146+
// Numerically approximate the gradient
147+
var gradient = Vector<double>.Build.Dense(x.Count);
148+
double epsilon = 1e-5;
149+
double baseError = CalculateError(allNodes, rxAdjRssiDict, nodeAbsorptionDict: nodeAbsorptionDict);
142150

143-
return (value, Vector<double>.Build.Dense(gradient));
144-
});
151+
for (int i = 0; i < x.Count; i++)
152+
{
153+
var tempDict = new Dictionary<string, double>(nodeAbsorptionDict);
154+
tempDict[uniqueDeviceIds[i]] += epsilon;
155+
156+
var errorPlusEps = CalculateError(allNodes, rxAdjRssiDict, nodeAbsorptionDict: tempDict);
157+
gradient[i] = (errorPlusEps - baseError) / epsilon;
158+
}
159+
160+
return gradient;
161+
});
145162

146-
var initialGuess = Vector<double>.Build.Dense(uniqueDeviceIds.Count,
163+
var initialGuess = Vector<double>.Build.Dense(uniqueDeviceIds.Count,
147164
(optimization?.AbsorptionMax - optimization?.AbsorptionMin) / 2 + optimization?.AbsorptionMin ?? 3d);
148165

149166
var solver = new BfgsMinimizer(1e-7, 1e-7, 1e-7);
@@ -158,7 +175,7 @@ private Dictionary<string, double> OptimizeNodeAbsorptions(List<Measure> allNode
158175
return nodeAbsorptions;
159176
}
160177

161-
private double CalculateError(List<Measure> nodes, Dictionary<string, double> rxAdjRssiDict,
178+
private double CalculateError(List<Measure> nodes, Dictionary<string, double> rxAdjRssiDict,
162179
Dictionary<string, double> nodeAbsorptionDict = null, Dictionary<(string, string), double> pathAbsorptionDict = null)
163180
{
164181
return nodes.Select(n =>
@@ -189,4 +206,4 @@ private double CalculateError(List<Measure> nodes, Dictionary<string, double> rx
189206

190207
private static string Min(string a, string b) => string.Compare(a, b) < 0 ? a : b;
191208
private static string Max(string a, string b) => string.Compare(a, b) >= 0 ? a : b;
192-
}
209+
}

0 commit comments

Comments
 (0)