Skip to content

Commit

Permalink
-added test and gain sched identify method to attempt to estiamate a …
Browse files Browse the repository at this point in the history
…large number of gains when thresholds are given.
  • Loading branch information
Steinar Elgsæter committed Feb 1, 2024
1 parent c0d1ff6 commit b866e25
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 10 deletions.
46 changes: 44 additions & 2 deletions Dynamic/Identification/GainSchedIdentifier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,48 @@ static public GainSchedParameters Identify(UnitDataSet dataSet, GainSchedFitting
/// <returns></returns>
public static GainSchedParameters IdentifyGainsForGivenThresholds(UnitDataSet dataSet, GainSchedFittingSpecs gsFittingSpecs)
{
return null;
var vec = new Vec();
GainSchedParameters ret = new GainSchedParameters();
ret.GainSchedParameterIndex = gsFittingSpecs.uGainScheduledInputIndex;
ret.LinearGainThresholds = gsFittingSpecs.uGainThresholds;

const int WIDTH = 1; //

int number_of_inputs = dataSet.U.GetLength(1);
double gsVarMinU = vec.Min(Array2D<double>.GetColumn(dataSet.U, ret.GainSchedParameterIndex));
double gsVarMaxU = 0;
var linearGains = new List<double[]>();
for (int curGainIdx = 0; curGainIdx < ret.LinearGainThresholds.Count()+1; curGainIdx++)
{
double[] uMinFit = new double[number_of_inputs];
double[] uMaxFit = new double[number_of_inputs];

if (curGainIdx < ret.LinearGainThresholds.Count()- WIDTH)
gsVarMaxU = ret.LinearGainThresholds[curGainIdx+ WIDTH];//NB! +1
else
gsVarMaxU = vec.Max(Array2D<double>.GetColumn(dataSet.U, ret.GainSchedParameterIndex));
for (int idx = 0; idx < number_of_inputs; idx++)
{
if (idx == ret.GainSchedParameterIndex)
{
uMinFit[idx] = gsVarMinU;
uMaxFit[idx] = gsVarMaxU;
}
else
{
uMinFit[idx] = double.NaN;
uMaxFit[idx] = double.NaN;
}
}
var idResults = IdentifySingleGainForGivenThresholds(ref dataSet, uMinFit, uMaxFit);
if (curGainIdx>-1+ WIDTH)
gsVarMinU = ret.LinearGainThresholds[curGainIdx- WIDTH];
// if (idResults.Item1 != null)
linearGains.Add(idResults.Item1);
}
// final gain:above the highest threshold
ret.LinearGains = linearGains;
return ret;
}


Expand Down Expand Up @@ -203,7 +244,8 @@ private static (double[], double) IdentifySingleGainForGivenThresholds(ref UnitD
fittingSpecs.U_min_fit = u_min_fit;
fittingSpecs.U_max_fit = u_max_fit;
fittingSpecs.u0 = new double[] { u_min_fit[0] + (u_max_fit[0] - u_min_fit[0]) / 2 };
var unitModel = UnitIdentifier.IdentifyLinear(ref dataSet, fittingSpecs, false); ;
// var unitModel = UnitIdentifier.IdentifyLinear(ref dataSet, fittingSpecs, false); ;
var unitModel = UnitIdentifier.IdentifyLinearAndStatic(ref dataSet, fittingSpecs, false); ;
var unitParams = unitModel.GetModelParameters();

return (unitParams.LinearGains, unitParams.TimeConstant_s);
Expand Down
58 changes: 50 additions & 8 deletions TimeSeriesAnalysis.Tests/Tests/GainSchedIdentifyTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,48 @@ public class GainSchedIdentifyTests
int timeBase_s = 1;
const double TimeConstantAllowedDev_s = 0.5;

[Test]
public void GainEstOnly_CorrectTresholdsGiven_CorrectGainsReturned()
{
int N = 100;

var gainSched_tenThresholds_singleInput = new GainSchedParameters
{
TimeConstant_s = null,
TimeConstantThresholds = null,
LinearGains = new List<double[]> { new double[] { 0 }, new double[] { 1 }, new double[] { 2 }, new double[] { 3 }, new double[] { 4 }, new double[] { 5 },
new double[] { 6 }, new double[] { 7 }, new double[] { 8 }, new double[] { 9 }, new double[] { 10 } },
LinearGainThresholds = new double[] { 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5 },
TimeDelay_s = 0,
Bias = 5,
GainSchedParameterIndex = 0
};

var refModel = new GainSchedModel(gainSched_tenThresholds_singleInput);
var gsFittingSpecs= new GainSchedFittingSpecs();
gsFittingSpecs.uGainThresholds = refModel.GetModelParameters().LinearGainThresholds;

var plantSim = new PlantSimulator(new List<ISimulatableModel> { refModel });
var inputData = new TimeSeriesDataSet();
var input = TimeSeriesCreator.ThreeSteps(N / 4, N * 2 / 4, N * 3 / 4, N, 0, 1, 2, 3).
Concat(TimeSeriesCreator.ThreeSteps(N / 4, N * 2 / 4, N * 3 / 4, N, 4, 5, 6, 7)).
Concat(TimeSeriesCreator.ThreeSteps(N / 4, N * 2 / 4, N * 3 / 4, N, 8, 9, 10, 11)).ToArray();
inputData.Add(plantSim.AddExternalSignal(refModel, SignalType.External_U, (int)INDEX.FIRST), input);
inputData.CreateTimestamps(timeBase_s);

// Act
var isSimulatable = plantSim.Simulate(inputData, out TimeSeriesDataSet simData);
Assert.IsTrue(isSimulatable);
var dataSet = new UnitDataSet();
dataSet.Y_meas = simData.GetValues(refModel.ID, SignalType.Output_Y);
dataSet.U = Array2D<double>.CreateFromList(new List<double[]> { inputData.GetValues(refModel.ID,SignalType.External_U)});

GainSchedIdentifier.IdentifyGainsForGivenThresholds(dataSet, gsFittingSpecs);

}



/*
[TestCase()]
public void ReturnsParametersWithNumberOfLinearGainsNotExceeding2()
Expand Down Expand Up @@ -82,7 +124,7 @@ public void ReturnsParametersWithNumberOfLinearGainsNotExceeding2()
}
*/
[TestCase()]
public void GainEstimationOnly_GainsNotLargerThanTheBiggestPossibleGain()
public void GainAndThreshold_GainsNotLargerThanTheBiggestPossibleGain()
{
int N = 500;

Expand Down Expand Up @@ -161,7 +203,7 @@ public void GainEstimationOnly_GainsNotLargerThanTheBiggestPossibleGain()
[TestCase(5, 2.5)]
[TestCase(6, 3.0)]*/
[TestCase(7, 4.0)]
public void ThresholdEstimation_LinearGainThresholdAtReasonablePlace(int ver, double gain_sched_threshold)
public void GainAndThreshold_LinearGainThresholdAtReasonablePlace(int ver, double gain_sched_threshold)
{
int N = 300;
// Arrange
Expand Down Expand Up @@ -231,11 +273,10 @@ public void ThresholdEstimation_LinearGainThresholdAtReasonablePlace(int ver, do
[TestCase(1, 35)]
[TestCase(38, 40)]
[TestCase(40, 20)]*/
public void GainEstimationOnly_TwoGains_TimeConstantsAndThresholdFoundOk(double TimeConstant1_s, double TimeConstant2_s)
public void GainAndThreshold_TwoGains_TimeConstantsAndThresholdFoundOk(double TimeConstant1_s, double TimeConstant2_s)
{
int N = 300;


// Arrange
var unitData = new UnitDataSet("test");
double[] u1 = TimeSeriesCreator.ThreeSteps(N/5, N/3, N/2, N, -2, -1, 0, 1);
Expand Down Expand Up @@ -288,9 +329,6 @@ public void GainEstimationOnly_TwoGains_TimeConstantsAndThresholdFoundOk(double
}





/* Shared.EnablePlots();
Plot.FromList(new List<double[]> {
simY1,
Expand All @@ -309,7 +347,7 @@ public void GainEstimationOnly_TwoGains_TimeConstantsAndThresholdFoundOk(double
[TestCase(5, 3.5)]
[TestCase(6, 4.0)]*/
// [TestCase(7, 4.5)]
public void ThresholdEstimation_ThresholdsWithinUminAndUmax(int ver, double gain_sched_threshold)
public void GainAndThreshold_ThresholdsWithinUminAndUmax(int ver, double gain_sched_threshold)
{
int N = 250;
// Arrange
Expand Down Expand Up @@ -449,5 +487,9 @@ public void GainSchedIdentify_AllTimeConstantsArePositive(int ver, double gain_s
// Shared.DisablePlots();
}
*/




}
}

0 comments on commit b866e25

Please sign in to comment.