How to interpolate between a series of datapoints using a nested for loop?

I am trying to take my dataset of n points and expand it to a dataset of m points using a for loop and the linspace function.
The desired result is a row vector of size 1x(pts*s) with the new interpolated data, but I get this error:
"Index exceeds the number of array elements. Index must not exceed 144."
close all
clear all
pts = 20; % number of points to add between each existing point
x = [48.105633802816904, 49.725352112676056, 52.47887323943662, 56.04225352112676, 57.82394366197183, 60.09154929577465, 62.521126760563384, 63.16901408450705, 61.54929577464789, 60.73943661971831, 60.41549295774648, 59.767605633802816, 59.28169014084507, 59.28169014084507, 59.11971830985916, 59.11971830985916, 58.471830985915496, 62.03521126760564, 65.59859154929578, 68.02816901408451, 70.94366197183099, 72.23943661971832, 74.34507042253522, 75.47887323943662, 77.2605633802817, 78.23239436619718, 79.36619718309859, 79.36619718309859, 77.09859154929578, 76.2887323943662, 76.2887323943662, 75.96478873239437, 74.66901408450704, 75.3169014084507, 74.99295774647888, 75.80281690140845, 77.09859154929578, 79.36619718309859, 81.95774647887325, 84.71126760563381, 87.46478873239437, 90.38028169014085, 92.80985915492958, 97.1830985915493, 95.72535211267606, 99.61267605633803, 101.71830985915493, 103.3380281690141, 105.28169014084507, 105.60563380281691, 106.09154929577466, 106.09154929577466, 105.76760563380282, 104.30985915492958, 102.20422535211269, 100.90845070422536, 99.61267605633803, 99.2887323943662, 98.1549295774648, 98.47887323943662, 97.83098591549296, 98.1549295774648, 97.99295774647888, 98.47887323943662, 99.2887323943662, 100.2605633802817, 102.04225352112677, 104.63380281690141, 106.73943661971832, 108.6830985915493, 109.6549295774648, 109.8169014084507, 110.62676056338029, 112.08450704225352, 113.70422535211269, 115.64788732394366, 117.42957746478874, 119.04929577464789, 118.0774647887324, 117.10563380281691, 115.48591549295774, 113.86619718309859, 111.43661971830986, 109.8169014084507, 109.6549295774648, 109.97887323943662, 111.11267605633803, 112.57042253521128, 114.8380281690141, 116.45774647887325, 118.0774647887324, 119.85915492957747, 121.64084507042254, 124.3943661971831, 127.4718309859155, 128.2816901408451, 127.4718309859155, 126.82394366197184, 126.3380281690141, 126.17605633802818, 128.6056338028169, 130.71126760563382, 132.16901408450704, 134.27464788732394, 135.73239436619718, 137.35211267605635, 138, 136.70422535211267, 136.21830985915494, 135.8943661971831, 136.21830985915494, 136.21830985915494, 136.8661971830986, 138.80985915492957, 141.2394366197183, 143.34507042253523, 144.1549295774648, 144.47887323943664, 145.1267605633803, 146.74647887323945, 148.69014084507043, 150.4718309859155, 152.4154929577465, 154.19718309859155, 156.14084507042253, 160.19014084507043, 158.73239436619718, 160.83802816901408, 160.67605633802816, 160.51408450704227, 157.7605633802817, 154.35915492957747, 152.4154929577465, 152.25352112676057, 153.06338028169014, 154.6830985915493, 156.95070422535213, 159.05633802816902, 159.70422535211267, 159.54225352112675, 159.70422535211267, 161.8098591549296, 165.3732394366197, 168.93661971830986];
s = size(x, 2); % size of data
x_new = zeros(1,s*pts); % empty row vector for new data
for j = pts
for i = s
x_new(1,j) = linspace(x(i),x(i+1),pts)
j = j*pts
end
end

 Accepted Answer

pts=20;
x = [48.105633802816904, 49.725352112676056, 52.47887323943662, 56.04225352112676, 57.82394366197183, 60.09154929577465, 62.521126760563384, 63.16901408450705, 61.54929577464789, 60.73943661971831, 60.41549295774648, 59.767605633802816, 59.28169014084507, 59.28169014084507, 59.11971830985916, 59.11971830985916, 58.471830985915496, 62.03521126760564, 65.59859154929578, 68.02816901408451, 70.94366197183099, 72.23943661971832, 74.34507042253522, 75.47887323943662, 77.2605633802817, 78.23239436619718, 79.36619718309859, 79.36619718309859, 77.09859154929578, 76.2887323943662, 76.2887323943662, 75.96478873239437, 74.66901408450704, 75.3169014084507, 74.99295774647888, 75.80281690140845, 77.09859154929578, 79.36619718309859, 81.95774647887325, 84.71126760563381, 87.46478873239437, 90.38028169014085, 92.80985915492958, 97.1830985915493, 95.72535211267606, 99.61267605633803, 101.71830985915493, 103.3380281690141, 105.28169014084507, 105.60563380281691, 106.09154929577466, 106.09154929577466, 105.76760563380282, 104.30985915492958, 102.20422535211269, 100.90845070422536, 99.61267605633803, 99.2887323943662, 98.1549295774648, 98.47887323943662, 97.83098591549296, 98.1549295774648, 97.99295774647888, 98.47887323943662, 99.2887323943662, 100.2605633802817, 102.04225352112677, 104.63380281690141, 106.73943661971832, 108.6830985915493, 109.6549295774648, 109.8169014084507, 110.62676056338029, 112.08450704225352, 113.70422535211269, 115.64788732394366, 117.42957746478874, 119.04929577464789, 118.0774647887324, 117.10563380281691, 115.48591549295774, 113.86619718309859, 111.43661971830986, 109.8169014084507, 109.6549295774648, 109.97887323943662, 111.11267605633803, 112.57042253521128, 114.8380281690141, 116.45774647887325, 118.0774647887324, 119.85915492957747, 121.64084507042254, 124.3943661971831, 127.4718309859155, 128.2816901408451, 127.4718309859155, 126.82394366197184, 126.3380281690141, 126.17605633802818, 128.6056338028169, 130.71126760563382, 132.16901408450704, 134.27464788732394, 135.73239436619718, 137.35211267605635, 138, 136.70422535211267, 136.21830985915494, 135.8943661971831, 136.21830985915494, 136.21830985915494, 136.8661971830986, 138.80985915492957, 141.2394366197183, 143.34507042253523, 144.1549295774648, 144.47887323943664, 145.1267605633803, 146.74647887323945, 148.69014084507043, 150.4718309859155, 152.4154929577465, 154.19718309859155, 156.14084507042253, 160.19014084507043, 158.73239436619718, 160.83802816901408, 160.67605633802816, 160.51408450704227, 157.7605633802817, 154.35915492957747, 152.4154929577465, 152.25352112676057, 153.06338028169014, 154.6830985915493, 156.95070422535213, 159.05633802816902, 159.70422535211267, 159.54225352112675, 159.70422535211267, 161.8098591549296, 165.3732394366197, 168.93661971830986];
s = numel(x); % size of data
x_new=cell(1,s-1);
for i = 1:s-1
t= linspace(x(i),x(i+1),pts+1);
x_new{i}=t(1:end-1);
end
x_new=[cell2mat(x_new), x(end)]
x_new = 1×2718
48.1056 48.1909 48.2761 48.3614 48.4466 48.5319 48.6171 48.7024 48.7876 48.8729 48.9581 49.0434 49.1286 49.2139 49.2991 49.3844 49.4696 49.5549 49.6401 49.7254 49.8703 50.0152 50.1601 50.3050 50.4500 50.5949 50.7398 50.8847 51.0297 51.1746

3 Comments

If I may suggest one slightly less efficient but simpler solution:
close all
clear all
pts = 20; % number of points to add between each existing point
x = [48.105633802816904, 49.725352112676056, 52.47887323943662, 56.04225352112676, 57.82394366197183, 60.09154929577465, 62.521126760563384, 63.16901408450705, 61.54929577464789, 60.73943661971831, 60.41549295774648, 59.767605633802816, 59.28169014084507, 59.28169014084507, 59.11971830985916, 59.11971830985916, 58.471830985915496, 62.03521126760564, 65.59859154929578, 68.02816901408451, 70.94366197183099, 72.23943661971832, 74.34507042253522, 75.47887323943662, 77.2605633802817, 78.23239436619718, 79.36619718309859, 79.36619718309859, 77.09859154929578, 76.2887323943662, 76.2887323943662, 75.96478873239437, 74.66901408450704, 75.3169014084507, 74.99295774647888, 75.80281690140845, 77.09859154929578, 79.36619718309859, 81.95774647887325, 84.71126760563381, 87.46478873239437, 90.38028169014085, 92.80985915492958, 97.1830985915493, 95.72535211267606, 99.61267605633803, 101.71830985915493, 103.3380281690141, 105.28169014084507, 105.60563380281691, 106.09154929577466, 106.09154929577466, 105.76760563380282, 104.30985915492958, 102.20422535211269, 100.90845070422536, 99.61267605633803, 99.2887323943662, 98.1549295774648, 98.47887323943662, 97.83098591549296, 98.1549295774648, 97.99295774647888, 98.47887323943662, 99.2887323943662, 100.2605633802817, 102.04225352112677, 104.63380281690141, 106.73943661971832, 108.6830985915493, 109.6549295774648, 109.8169014084507, 110.62676056338029, 112.08450704225352, 113.70422535211269, 115.64788732394366, 117.42957746478874, 119.04929577464789, 118.0774647887324, 117.10563380281691, 115.48591549295774, 113.86619718309859, 111.43661971830986, 109.8169014084507, 109.6549295774648, 109.97887323943662, 111.11267605633803, 112.57042253521128, 114.8380281690141, 116.45774647887325, 118.0774647887324, 119.85915492957747, 121.64084507042254, 124.3943661971831, 127.4718309859155, 128.2816901408451, 127.4718309859155, 126.82394366197184, 126.3380281690141, 126.17605633802818, 128.6056338028169, 130.71126760563382, 132.16901408450704, 134.27464788732394, 135.73239436619718, 137.35211267605635, 138, 136.70422535211267, 136.21830985915494, 135.8943661971831, 136.21830985915494, 136.21830985915494, 136.8661971830986, 138.80985915492957, 141.2394366197183, 143.34507042253523, 144.1549295774648, 144.47887323943664, 145.1267605633803, 146.74647887323945, 148.69014084507043, 150.4718309859155, 152.4154929577465, 154.19718309859155, 156.14084507042253, 160.19014084507043, 158.73239436619718, 160.83802816901408, 160.67605633802816, 160.51408450704227, 157.7605633802817, 154.35915492957747, 152.4154929577465, 152.25352112676057, 153.06338028169014, 154.6830985915493, 156.95070422535213, 159.05633802816902, 159.70422535211267, 159.54225352112675, 159.70422535211267, 161.8098591549296, 165.3732394366197, 168.93661971830986];
s = numel(x); % size of data
y_new = [];
for i = 1:s-1
tmp = linspace(x(i),x(i+1), pts);
y_new = [y_new, tmp];
end
I can't quite see how it's simpler. You are missing one final step,
for i = 1:s-1
tmp = linspace(x(i),x(i+1), pts);
y_new = [y_new, tmp];
end
y_new=[y_new,x(end)]
which will make the code the same number of lines as the version with cells.
Yes, you're right. But ieven with that addition, my code is still not correct since I have elements from original array x appear twice inside the array (I didn't use end-1 like you did). In any case, mycode becomes more complicated. I stand corrected.

Sign in to comment.

More Answers (2)

Another loop-free solution:
pts=4;
x=[1,2,5];
s=numel(x);
x_new=interp1(x, linspace(1,s, (s-1)*pts+1) )
x_new = 1×9
1.0000 1.2500 1.5000 1.7500 2.0000 2.7500 3.5000 4.2500 5.0000
If pts is a power of 2, there is a simpler (and loop-free) method using interp2,
pts=4;
x=[1,2,5];
x_new=interp2([x;x],log2(pts));
x_new=x_new(1,:)
x_new = 1×9
1.0000 1.2500 1.5000 1.7500 2.0000 2.7500 3.5000 4.2500 5.0000

Products

Release

R2022a

Asked:

on 1 Mar 2023

Answered:

on 1 Mar 2023

Community Treasure Hunt

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

Start Hunting!