Forward difference: Difference between revisions

m
(Added Rust example)
m (→‎{{header|Wren}}: Minor tidy)
 
(3 intermediate revisions by 3 users not shown)
Line 477:
order: attr "order"
if order = null -> order: 1
loop 1..order 'n -> block: vsub block drop block 1
return block
]
Line 2,980:
{-2921}
</pre>
 
=={{header|RPL}}==
===Iterative approach===
{| class="wikitable" ≪
! RPL code
! Comment
|-
|
'''IF''' OVER SIZE OVER > '''THEN'''
'''WHILE''' DUP '''REPEAT'''
SWAP { } 2 3 PICK SIZE '''FOR''' j
OVER j GET + '''NEXT'''
LIST→ →ARRY
SWAP OVER SIZE { } + RDM -
SWAP 1 - '''END'''
DROP '''END'''
≫ ‘<span style="color:blue">DIFFN</span>’ STO
|
<span style="color:blue">DIFFN</span> ''( [array] order → [nth_difference] ) ''
if order < array size
while order > 0
initialize loop
to build { array[2]...array[n] }
convert list into array
pop last item of array and substract
order -= 1
clean stack
|}
[90, 47, 58, 29, 22, 32, 55, 5, 55, 73] 1 <span style="color:blue">DIFFN</span>
[90, 47, 58, 29, 22, 32, 55, 5, 55, 73] 3 <span style="color:blue">DIFFN</span>
{{out}}
<pre>
2: [-43, 11, -29, -7, 10, 23, -50, 50, 18]
1: [-94, 62, -5, -4, -86, 173, -132]
</pre>
===Direct approach===
We use here local variables and algebraic notation to increase code readability.
{| class="wikitable" ≪
! RPL code
! Comment
|-
|
≪ → n
≪ '<span style="color:green">F</span>' STO
{ } 1 <span style="color:green">F</span> SIZE 1 - '''FOR''' j
-1 n ^ '<span style="color:green">F</span>' j GET *
1 n '''FOR''' k
'COMB(n,k)*(-1)^(n-k)*<span style="color:green">F</span>(j+k)' EVAL +
'''NEXT'''
+ '''NEXT'''
LIST→ →ARRY '<span style="color:green">F</span>' PURGE
≫ ≫ ‘<span style="color:blue">DIFFN</span>’ STO
|
<span style="color:blue">DIFFN</span> ''( [array] order → [nth_difference] ) ''
store array in global variable F
initialize output array building loop
put 1st term of sum (k=0) in stack // reverse Polish notation
loop
add terms for 0<k≤n // algebraic notation
add sum to list
convert list into array, clean memory
|}
Postfix fans can replace the following line
'COMB(n,k)*(-1)^(n-k)*<span style="color:green">F</span>(j+k)' EVAL + '''NEXT'''
by
n k COMB -1 n k - ^ * '<span style="color:green">F</span>' j k + GET * + '''NEXT'''
On HP-48G and newer models, first difference is directly returned by the <code>ΔLIST</code> instruction, so we can simplify the above code, provided that input is given as a list { } instead of an array [ ]:
≪ 1 SWAP '''START''' ΔLIST '''NEXT''' ≫ ‘<span style="color:blue">DIFFN</span>’ STO
 
 
=={{header|Ruby}}==
Line 3,471 ⟶ 3,544:
=={{header|Wren}}==
{{libheader|Wren-fmt}}
<syntaxhighlight lang="ecmascriptwren">import "./fmt" for Fmt
 
var forwardDiff = Fn.new { |a, order|
Line 3,502 ⟶ 3,575:
8: 1017 -1904
9: -2921
</pre>
 
=={{header|XPL0}}==
{{trans|ALGOL W}}
<syntaxhighlight lang "XPL0">\Calculate forward differences
 
\Sets elements of B to the first order forward differences of A.
\A should have bounds 1 :: N, B should have bounds 1 :: N - 1.
procedure FirstOrderFDifference ( A, B, N );
integer A, B, N, I;
for I := 2 to N do B( I - 1 ) := A( I ) - A( I - 1 );
 
integer V ( 1 + 10 );
integer Diff( 1 + 9 );
integer VPos, Length, List, I, Order;
begin
\construct the initial values array
VPos := 1;
List:= [90, 47, 58, 29, 22, 32, 55, 5, 55, 73];
for I := 0 to 10-1 do begin
V( VPos ) := List( I );
VPos := VPos + 1
end;
 
\calculate and show the differences
Format(8, 0); \set output format
Length := 10;
for Order := 1 to Length - 1 do begin
FirstOrderFDifference( V, Diff, Length );
Length := Length - 1;
IntOut(0, Order); Text(0, " : ");
for I := 1 to Length do RlOut(0, float(Diff( I ) ));
CrLf(0);
for I := 1 to Length do V( I ) := Diff( I )
end
end</syntaxhighlight>
{{out}}
<pre>
1 : -43 11 -29 -7 10 23 -50 50 18
2 : 54 -40 22 17 13 -73 100 -32
3 : -94 62 -5 -4 -86 173 -132
4 : 156 -67 1 -82 259 -305
5 : -223 68 -83 341 -564
6 : 291 -151 424 -905
7 : -442 575 -1329
8 : 1017 -1904
9 : -2921
</pre>
 
9,476

edits