Indexing vectors with a zero and creating a "predicted" vector knowing what the diff should be

6 ビュー (過去 30 日間)
I have some measured values as below (that should be multiples of some fixed value)
xmeasured =
-52.9734
-39.7061
-26.4657
-13.0291
0
13.0255
26.4704
39.5217
52.9689
I now what the real seperation between each element should be (and it should be fixed) at 13.1459
I want to create another Column (or vector) with the following "predicted" values where either side of zero, the values are multiples of 13.1459, i.e
Predicted =
(-3 x 13.1459)
(-2 x 13.1459)
(-1 x 13.1459)
-13.1459
0
13.1459
(2 x 13.1459)
(3 x 13.1459)
So I can then calculate the difference between measured and predicted.
My data can be any size and the 0 isn't necessarily in the middle (although it is always present somewhere)
  3 件のコメント
Walter Roberson
Walter Roberson 2025 年 6 月 25 日
xmeasured = [ ...
-52.9734;
-39.7061;
-26.4657;
-13.0291;
0;
13.0255;
26.4704;
39.5217;
52.9689];
polyfit(-4:4, xmeasured, 1)
ans = 1×2
13.2230 -0.0209
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Looks like 13.1459 is not an especially good predictor.
Jason
Jason 2025 年 6 月 25 日
編集済み: Jason 2025 年 6 月 25 日
Thats the nature of optical distortion, its a 3rd order effect that starts off with the "correct spacing" but then gets worse. That predictor is just for the central spots as this is the true spacing in absence of optical distortion and allows you to define a refence to then calculate the distortion

サインインしてコメントする。

採用された回答

Paul
Paul 2025 年 6 月 25 日
This solution is similar in spirit to that in this comment, which I think is the best approach based on how the problem has been described, particularly that the xmeaured data can stray more than one bin away from the uniformly spaced prediction.
xmeasured = [ ...
-52.9734;
-39.7061;
-26.4657;
-13.0291;
0;
13.0255;
26.4704;
39.5217;
52.9689];
idx = find(xmeasured==0);
n = (1:numel(xmeasured)).'-idx;
xuni = n*13.1459;
[xmeasured,xuni]
ans = 9×2
-52.9734 -52.5836 -39.7061 -39.4377 -26.4657 -26.2918 -13.0291 -13.1459 0 0 13.0255 13.1459 26.4704 26.2918 39.5217 39.4377 52.9689 52.5836
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
  2 件のコメント
Walter Roberson
Walter Roberson 2025 年 6 月 25 日
I have to wonder whether it is certain that there will be an exact 0, and not an approximate 0 instead...
Steven Lord
Steven Lord 2025 年 6 月 25 日
In that case you could use min with ComparisonMethod "abs" to locate the smallest magnitude value in the array.
xmeasured = [ ...
-52.9734;
-39.7061;
-26.4657;
-13.0291;
-0.001; % not exactly 0
13.0255;
26.4704;
39.5217;
52.9689];
[minValue1, minLocation1] = min(xmeasured, [], ComparisonMethod = "abs")
minValue1 = -1.0000e-03
minLocation1 = 5
In releases prior to the introduction of that option you could take the abs of the data before calling min but then you'd have to potentially negate the result. Compare the signs of minValue1 and minValue2.
[minValue2, minLocation2] = min(abs(xmeasured))
minValue2 = 1.0000e-03
minLocation2 = 5
The ComparisonMethod is necessary in this case. For real data, by default MATLAB looks for the smallest real part of your data.
[minValue3, minLocation3] = min(xmeasured)
minValue3 = -52.9734
minLocation3 = 1

サインインしてコメントする。

その他の回答 (2 件)

Steven Lord
Steven Lord 2025 年 6 月 25 日
If you believe they are uniformly spaced, the isuniform function can confirm this (and give you the uniform spacing) or refute it (and tell you the spacing is NaN.) Your vector isn't uniformly spaced, as you can see by inspection from the difference in the absolute values of the two elements surrounding the 0 in your data. isuniform correctly says that it is not uniformly spaced.
xmeasured = [ ...
-52.9734;
-39.7061;
-26.4657;
-13.0291;
0;
13.0255;
26.4704;
39.5217;
52.9689];
[isUniformlySpaced, stepsize] = isuniform(xmeasured)
isUniformlySpaced = logical
0
stepsize = NaN
If you want them to be an ideal distance apart, figure out what multiple of that ideal distance each element is:
idealSpacing = 13.1459;
multipliers = xmeasured ./ idealSpacing
multipliers = 9×1
-4.0297 -3.0204 -2.0132 -0.9911 0 0.9908 2.0136 3.0064 4.0293
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
You can round the multipliers to the nearest integer then multiply by the spacing.
xideal = round(multipliers)*idealSpacing
xideal = 9×1
-52.5836 -39.4377 -26.2918 -13.1459 0 13.1459 26.2918 39.4377 52.5836
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
xideal ought to be uniform from the way it was constructed, and isuniform confirms it is:
[isIdealUniform, spacing] = isuniform(xideal)
isIdealUniform = logical
1
spacing = 13.1459
Is the spacing calculated by isuniform the same as the spacing used to create xideal?
spacing - idealSpacing
ans = 0
How different are the measured and ideal vectors?
D = xmeasured - xideal
D = 9×1
-0.3898 -0.2684 -0.1739 0.1168 0 -0.1204 0.1786 0.0840 0.3853
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
  1 件のコメント
Jason
Jason 2025 年 6 月 25 日
編集済み: Jason 2025 年 6 月 25 日
thanks steven, Ill work tthrough your answer. But just a qucik comment regarding
Your vector isn't uniformly spaced, as you can see by inspection from the difference in the absolute values of the two elements surrounding the 0 in your data. isuniform correctly says that it is not uniformly spaced.
The measured values are not expected to be uniformly spaced, there is 1: noise on each spacing as well as 2: optical distortion so as we go further from the centre the measured values deviate more and more from what they should be.
This variation (distortion) is exactly what Im trying to measure. I know the spacing in the middle (is representative of what the real spacing should be, albeit with a little noise. I calc this and take the median and then use this as my real spacing to then subtract the measured from

サインインしてコメントする。


Matt J
Matt J 2025 年 6 月 25 日
編集済み: Matt J 2025 年 6 月 26 日
Here's an approach using the an integer-constrained linear fitting routine minL1intlin, downloadable from
Basically, if t=13.1459 is the true, known spacing, we can formulate the problem as solving for the unknown integer shift s that best fits the linear equations,
xmeasured = t*(1:n)'-t*s
and subject to the constraints 1<=s<=n. The latter ensures that zero is somewhere in the prediction, xpredicted.
xmeasured =[-52.9734
-39.7061
-26.4657
-13.0291
0
13.0255
26.4704
39.5217
52.9689];
t=13.1459;
n=numel(xmeasured);
xt=(1:n)'*t;
e=ones(n,1)*t;
s=round(minL1intlin(-e,xmeasured-xt,1,[],[],[],[],1,n))
Running HiGHS 1.7.1: Copyright (c) 2024 HiGHS under MIT licence terms Coefficient ranges: Matrix [1e+00, 1e+01] Cost [1e+00, 1e+00] Bound [1e+00, 9e+00] RHS [7e+01, 7e+01] Presolving model 18 rows, 10 cols, 36 nonzeros 0s 18 rows, 10 cols, 36 nonzeros 0s Solving MIP model with: 18 rows 10 cols (0 binary, 1 integer, 0 implied int., 9 continuous) 36 nonzeros Nodes | B&B Tree | Objective Bounds | Dynamic Constraints | Work Proc. InQueue | Leaves Expl. | BestBound BestSol Gap | Cuts InLp Confl. | LpIters Time 0 0 0 0.00% 0 inf inf 0 0 0 0 0.0s T 0 0 0 0.00% 0 1.7172 100.00% 0 0 0 9 0.0s Solving report Status Optimal Primal bound 1.7172 Dual bound 1.7172 Gap 0% (tolerance: 0.01%) Solution status feasible 1.7172 (objective) 0 (bound viol.) 8.881784197e-16 (int. viol.) 0 (row viol.) Timing 0.01 (total) 0.00 (presolve) 0.00 (postsolve) Nodes 1 LP iterations 9 (total) 0 (strong br.) 0 (separation) 0 (heuristics) Optimal solution found. Intlinprog stopped at the root node because the objective value is within a gap tolerance of the optimal value, options.AbsoluteGapTolerance = 1e-06. The intcon variables are integer within tolerance, options.ConstraintTolerance = 1e-06.
s = 5
xpredicted=xt-t*s
xpredicted = 9×1
-52.5836 -39.4377 -26.2918 -13.1459 0 13.1459 26.2918 39.4377 52.5836
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
residuals=xmeasured-xpredicted
residuals = 9×1
-0.3898 -0.2684 -0.1739 0.1168 0 -0.1204 0.1786 0.0840 0.3853
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
  1 件のコメント
Matt J
Matt J 2025 年 6 月 25 日
編集済み: Matt J 2025 年 6 月 26 日
I suspect the closed-form solution for s is,
s=median( round( xmeasured/t - (1:n)' ));
s=clip(s,1,n);
but can't immediately think of a proof for it.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeDescriptive Statistics についてさらに検索

製品


リリース

R2024b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by