我搜索过很多帖子,找不到我需要的内容。我看到找到与目标最接近的数字的解决方案,但我需要找到该数字的数字,然后可以选择不完全对称的“抛物线”形状数据集另一侧的最接近数字。我基本上使用:
List<int> list = new List<int> { 2, 5, 7, 10 };
int number = 9;
int closest = list.Aggregate((x,y) => Math.Abs(x-number) < Math.Abs(y-
number) ? x : y);
这就是我找到第一个目标号码的方法。现在我需要找到一个值几乎相等的第二个数字,但是在抛物线的另一边(我真的需要这些数字的索引,但我可以将这些数字放在一起)。我的方法不断出现一个数字。基本上我需要移动到抛物线上的近似对称索引以选择等效数字。为了说明这一点,我正在计算波束宽度,即特定点处抛物线边缘之间的距离。请告诉我这是否有意义,如果我需要在你投票之前解释更多。我做了大量的研究和测试。我很难提供更多代码,因为它来自一个没有互联网的价值500,000美元的测试系统,所以我无法复制和粘贴我的代码。如果需要更多代码,我可以去额外的院子,只是试图避免损害昂贵的嵌入式Windows系统。
以下是我需要更进一步的相关文章 located here
修改添加完整代码:
fileName = textBox10.Text;
SetupControlState(true);
if (comboBox2.SelectedIndex == 0)
{
cent = false;
}
else if (comboBox2.SelectedIndex == 1)
{
cent = true;
}
testHPositions = new List<double>();
testHMeasurements = new List<double>();
testVPositions = new List<double>();
testVMeasurements = new List<double>();
double horzRange = Double.Parse(textBox12.Text);
double vertRange = Double.Parse(textBox11.Text);
double refGain = Double.Parse(textBox14.Text);
double stepSize = Double.Parse(textBox13.Text);
testBorePos = new double[1, 2];
_worker = new BackgroundWorker();
_worker.WorkerSupportsCancellation = true;
testBoreRun.Enabled = false;
button2.Enabled = true;
_worker.RunWorkerAsync();
_worker.DoWork += new DoWorkEventHandler((state, args) =>
{
// try
// {
dev1 = new VisaDevice("inst0", "TCPIP0::192.168.0.10::inst0::INSTR"); //textBox1.Text);
if (!cent)
{
Double startfreq = double.Parse(textBox2.Text) * 1000000000;
Double stopfreq = double.Parse(textBox1.Text) * 1000000000;
dev1.SendBlocking("FREQ:STAR " + startfreq.ToString(), true);
string responseFreq = "";
dev1.QueryBlocking("FREQ:STAR?", ref responseFreq, true);
dev1.SendBlocking("FREQ:STOP " + stopfreq.ToString(), true);
dev1.QueryBlocking("FREQ:STOP?", ref responseFreq, true);
}
else if (cent)
{
Double freq = double.Parse(textBox9.Text) * 1000000000;
Double span = double.Parse(textBox8.Text) * 1000000000;
dev1.SendBlocking("FREQ:CENT " + freq.ToString(), true);
string responseFreq = "";
dev1.QueryBlocking("FREQ:CENT?", ref responseFreq, true);
dev1.SendBlocking("FREQ:SPAN " + span.ToString(), true);
dev1.QueryBlocking("FREQ:SPAN?", ref responseFreq, true);
// this.InvokeEx(f => f.stringReadTextBox.AppendText("Spectrum Analyzer Connected" + Environment.NewLine));
}
string progID;
Util U = new Util();
progID = "ASCOM.iOptron.Telescope";
if (progID != "")
{
PauseClass pause;
pause = new PauseClass();
Telescope T = new Telescope(progID);
T.Connected = true;
pause.Pause(5000);
T.Tracking = false;
T.TargetDeclination = 1;
T.TargetRightAscension = 1;
this.InvokeEx(f => f.stringReadTextBox.AppendText(" Connected to " + progID + Environment.NewLine));
this.InvokeEx(f => f.stringReadTextBox.AppendText(" Connected to Spectrum Analyzer" + Environment.NewLine));
T.SlewToAltAz(180.00, 45 - vertRange);
double Alt = T.Altitude;
for (int i = 0; i < ((vertRange * 2) / stepSize) + 1; i++)
{
if (_worker.CancellationPending)
break;
T.SlewToAltAz(180, Alt + stepSize * i);
this.InvokeEx(f => f.stringReadTextBox.AppendText("Test Altitude = " +(T.Altitude - 45).ToString("F") + Environment.NewLine));
testVPositions.Add(T.Altitude);
dev1.SendBlocking("INIT", true); //Start single measurement
string respOPC = "", responseState = "", responseMarkerY = "";
dev1.QueryBlocking("*OPC?", ref respOPC, true); //Wait for operation complete
dev1.QueryBlocking("STAT:QUES:MEAS?", ref responseState, true); //Check State
dev1.QueryBlocking("CALC:MARK:Y?", ref responseMarkerY, true); // Get the result
this.InvokeEx(f => f.stringReadTextBox.AppendText(responseMarkerY + Environment.NewLine));
testVMeasurements.Add(Double.Parse(responseMarkerY));
if (testVMeasurements.Count > ((vertRange * 2) / stepSize))
{
this.InvokeEx(f => f.stringReadTextBox.AppendText("Vertical Scanning Is Complete!" + Environment.NewLine));
double maxVamp = testVMeasurements.Max();
int index2 = testVMeasurements.IndexOf(testVMeasurements.Max());
double maxVPos = testVPositions[index2];
testBorePos[0, 1] = maxVPos;
this.InvokeEx(f => f.stringReadTextBox.AppendText("Vertical Max Amplitude = " + maxVamp + Environment.NewLine));
this.InvokeEx(f => f.stringReadTextBox.AppendText("Vertical Position of Max Amplitude = " + (maxVPos - 45).ToString("F") + Environment.NewLine));
}
}
if (!_worker.CancellationPending)
{
T.SlewToAltAz(180.00 - horzRange, testBorePos[0, 1]);
}
double Az = T.Azimuth;
for (int i = 0; i < ((horzRange * 2) / stepSize) + 1; i++)
{
if (_worker.CancellationPending)
break;
if (vertRange > 20)
{
this.InvokeEx(f => f.stringReadTextBox.AppendText("Vertical Range Cannot Be Greater than +/- 20 Degreez" + Environment.NewLine));
break;
}
T.SlewToAltAz(Az + stepSize * i,testBorePos[0,1]);
this.InvokeEx(f => f.stringReadTextBox.AppendText("Test Azimuth = " + (T.Azimuth-180).ToString("F") + Environment.NewLine));
testHPositions.Add(T.Azimuth);
dev1.SendBlocking("INIT", true); //Start single measurement
string respOPC = "", responseState = "", responseMarkerY = "", responseMarkerX = "";
// string responseFreq = "";
dev1.QueryBlocking("*OPC?", ref respOPC, true); //Wait for operation complete
dev1.QueryBlocking("STAT:QUES:MEAS?", ref responseState, true); //Check State
dev1.QueryBlocking("CALC:MARK:Y?", ref responseMarkerY, true); // Get the result
dev1.QueryBlocking("CALC:MARK:X?", ref responseMarkerX, true); // Get the result
this.InvokeEx(f => f.stringReadTextBox.AppendText(responseMarkerY + Environment.NewLine));
testHMeasurements.Add(Double.Parse(responseMarkerY));
if (testHMeasurements.Count > ((horzRange * 2) / stepSize))
{
_worker.CancelAsync();
stop = false;
this.InvokeEx(f => f.testBoreRun.Enabled = true);
this.InvokeEx(f => f.button2.Enabled = false);
this.InvokeEx(f => f.stringReadTextBox.AppendText("Horizontal Scanning Is Complete!" + Environment.NewLine));
double maxHamp =testHMeasurements.Max();
int index =testHMeasurements.IndexOf(testHMeasurements.Max());
double maxHPos =testHPositions[index];
testBorePos[0, 0] = maxHPos;
this.InvokeEx(f => f.stringReadTextBox.AppendText("Horizontal Max Amplitude = " + maxHamp + Environment.NewLine));
this.InvokeEx(f => f.stringReadTextBox.AppendText("Horizontal Position of Max Amplitude = " +( maxHPos-180).ToString("F") + Environment.NewLine));
this.InvokeEx(f => f.stringReadTextBox.AppendText("Antenna Under Test Peak Amplitude located at (" + (testBorePos[0, 0] - 180).ToString("F") + " , " + (testBorePos[0, 1] - 45).ToString("F") + ")" + Environment.NewLine));
this.InvokeEx(f => f.SetupControlState(false));
T.SlewToAltAz(testBorePos[0, 0], testBorePos[0, 1]);
dev1.SendBlocking("INIT", true); //Start single measurement
maxAmpTest = new double();
string respOPC2 = "", responseState2 = "", responseMarkerY2 = "";
dev1.QueryBlocking("*OPC?", ref respOPC2, true); //Wait for operation complete
dev1.QueryBlocking("STAT:QUES:MEAS?", ref responseState2, true); //Check State
dev1.QueryBlocking("CALC:MARK:Y?", ref responseMarkerY2, true); // Get the result
maxAmpTest = Double.Parse(responseMarkerY2);
double target = maxAmpTest - 3;
这是我被困的地方:
// int indexbeam = testHMeasurements.IndexOf(target);
// indexList = testHMeasurements.IndexOf(testHMeasurements.FindAll(s => s.Equals(target)).First());
double closest = testHMeasurements.Aggregate((x, y) => Math.Abs(x - target) < Math.Abs(y - target) ? x : y);
var result = Enumerable.Range(0, testHMeasurements.Count).Where(j => testHMeasurements[j] ==closest).ToList();
// int beamIndex1 = testHMeasurements.IndexOf(testHMeasurements.OrderBy(item => Math.Abs(target - item)).First());
// int beamIndex2 = testHMeasurements.IndexOf(testHMeasurements.OrderBy(item => Math.Abs((beamIndex1 + 1) - item)).First());
double beam1 =( testHPositions[result[0]]) - 180;
double beam2 = (testHPositions[result[1]]) - 180;
beamWidth = Math.Abs(beam1) + Math.Abs(beam2);
this.InvokeEx(f => f.stringReadTextBox.AppendText("Antenna Under Test Amplitude = " + responseMarkerY2 + Environment.NewLine));
this.InvokeEx(f => f.stringReadTextBox.AppendText(" Antenna Under Test Gain = " + (maxAmpTest - refAmp + refGain) + Environment.NewLine));
this.InvokeEx(f => f.stringReadTextBox.AppendText(" Antenna Under Test Beam Width = " +beamWidth.ToString("F") + Environment.NewLine));
testGain = maxAmpTest - refAmp + refGain;
}
}
T.Connected = false;
T.Dispose();
dev1.Dispose();
if (_worker.CancellationPending)
{
Save();
// Cleanup Excel resources
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
});
答案 0 :(得分:2)
首先,你必须找到抛物线。由于您的数据仅接近抛物线,因此需要使用名为Quadratic Regression或Polynomial Regression的统计方法来查找等式a
,b
和c
的参数
y = ax 2 + bx + c
定义抛物线,最适合点数给出的数据集
(x i ,y i )
使用数学库或谷歌搜索算法。
一旦得到抛物线,确定抛物线的对称轴,即抛物线的find the x-value of where the minimum或最大值(如果抛物线是颠倒的)。
x s = -b / 2a
现在,一旦你有一个给定的x值,你可以通过在x s上镜像x来找到抛物线另一侧的一个
X&#39; = 2x s - x
这是二维抛物线的解释。如果你有一个三维抛物线,即一个Paraboloid原则保持不变,但数学更复杂。 Google为Paraboloid Regression。抛物面天线的曲面具有抛物线的横截面形状,在几何学上称为抛物面。
只有解决了数学问题后,才能开始编程并在列表中查找点。
答案 1 :(得分:0)
事实证明,这个问题实际上可以通过编程解决,无需高级数学。给定y值并要求在非对称/抛物线弧上找到两个相应的x值,您可以简单地将顶点处的弧分成两部分,然后扫描两个阵列中的每一个以获得匹配的x值。它的作用就像一个魅力 - 只需要一点批判性的思考而不是思考它(数学主要的东西:p)