Bernstein basis polynomials: Difference between revisions
Content added Content deleted
m (→{{header|Wren}}: Correct capitalization for ALGOL 60) |
(Added Object Icon. Added some comment lines to the Python.) |
||
Line 468: | Line 468: | ||
println(" bern ", qbern2, " --> bern ", qbern3a) |
println(" bern ", qbern2, " --> bern ", qbern3a) |
||
</syntaxhighlight>{{out}} Same as Python example. |
</syntaxhighlight>{{out}} Same as Python example. |
||
=={{header|ObjectIcon}}== |
|||
<syntaxhighlight lang="objecticon"> |
|||
#!/bin/env oiscript |
|||
import |
|||
io(), |
|||
ipl.lists(list2str) |
|||
final abstract class Bernstein () |
|||
public static from_monomial_degree2 (a0_a1_a2) |
|||
# Subprogram (1): transform monomial coefficients [a0, a1, a2] to |
|||
# Bernstein coefficients [b0, b1, b2]. |
|||
local a0, a1, a2 |
|||
a0 := a0_a1_a2[1]; a1 := a0_a1_a2[2]; a2 := a0_a1_a2[3] |
|||
return [a0, a0 + (0.5 * a1), a0 + a1 + a2] |
|||
end |
|||
public static evaluate_degree2 (b0_b1_b2, t) |
|||
# Subprogram (2): evaluate, at t, the polynomial with Bernstein |
|||
# coefficients [b0, b1, b2]. Use de Casteljau's |
|||
# algorithm. |
|||
local b0, b1, b2 |
|||
local s, b01, b12, b012 |
|||
b0 := b0_b1_b2[1]; b1 := b0_b1_b2[2]; b2 := b0_b1_b2[3] |
|||
s := 1 - t |
|||
b01 := (s * b0) + (t * b1) |
|||
b12 := (s * b1) + (t * b2) |
|||
b012 := (s * b01) + (t * b12) |
|||
return b012 |
|||
end |
|||
public static from_monomial_degree3 (a0_a1_a2_a3) |
|||
# Subprogram (3): transform monomial coefficients [a0, a1, a2, a3] |
|||
# to Bernstein coefficients [b0, b1, b2, b3]. |
|||
local a0, a1, a2, a3 |
|||
a0 := a0_a1_a2_a3[1]; a1 := a0_a1_a2_a3[2] |
|||
a2 := a0_a1_a2_a3[3]; a3 := a0_a1_a2_a3[4] |
|||
# |
|||
# In Object Icon, the same symbol / is used for both floating |
|||
# point and integer division. Thus you will get the WRONG result |
|||
# if you write 1/3 instead of 1.0/3.0, etc. (This is |
|||
# error-encouraging language design but true of many languages. I |
|||
# fell victim while writing this code.) |
|||
# |
|||
return [a0, a0 + ((1.0 / 3.0) * a1), |
|||
a0 + ((2.0 / 3.0) * a1) + ((1.0 / 3.0) * a2), |
|||
a0 + a1 + a2 + a3] |
|||
end |
|||
public static evaluate_degree3 (b0_b1_b2_b3, t) |
|||
# Subprogram (4): evaluate, at t, the polynomial with Bernstein |
|||
# coefficients [b0, b1, b2, b3]. Use de Casteljau's |
|||
# algorithm. |
|||
local b0, b1, b2, b3 |
|||
local s, b01, b12, b23, b012, b123, b0123 |
|||
b0 := b0_b1_b2_b3[1]; b1 := b0_b1_b2_b3[2] |
|||
b2 := b0_b1_b2_b3[3]; b3 := b0_b1_b2_b3[4] |
|||
s := 1 - t |
|||
b01 := (s * b0) + (t * b1) |
|||
b12 := (s * b1) + (t * b2) |
|||
b23 := (s * b2) + (t * b3) |
|||
b012 := (s * b01) + (t * b12) |
|||
b123 := (s * b12) + (t * b23) |
|||
b0123 := (s * b012) + (t * b123) |
|||
return b0123 |
|||
end |
|||
public static degree2_to_degree3 (q0_q1_q2) |
|||
# Subprogram (5): transform the quadratic Bernstein coefficients |
|||
# [q0, q1, q2] to the cubic Bernstein coefficients |
|||
# [c0, c1, c2, c3]. |
|||
local q0, q1, q2 |
|||
q0 := q0_q1_q2[1]; q1 := q0_q1_q2[2]; q2 := q0_q1_q2[3] |
|||
return [q0, ((1.0 / 3.0) * q0) + ((2.0 / 3.0) * q1), |
|||
((2.0 / 3.0) * q1) + ((1.0 / 3.0) * q2), q2] |
|||
end |
|||
end # final abstract class Bernstein |
|||
final abstract class Monomial () |
|||
public static evaluate_degree2 (a0_a1_a2, t) |
|||
# Evaluate, at t, the polynomial with monomial coefficients [a0, |
|||
# a1, a2]. |
|||
local a0, a1, a2 |
|||
a0 := a0_a1_a2[1]; a1 := a0_a1_a2[2]; a2 := a0_a1_a2[3] |
|||
return a0 + (t * (a1 + (t * a2))) # Horner form. |
|||
end |
|||
public static evaluate_degree3 (a0_a1_a2_a3, t) |
|||
# Evaluate, at t, the polynomial with monomial coefficients [a0, |
|||
# a1, a2, a3]. |
|||
local a0, a1, a2, a3 |
|||
a0 := a0_a1_a2_a3[1]; a1 := a0_a1_a2_a3[2] |
|||
a2 := a0_a1_a2_a3[3]; a3 := a0_a1_a2_a3[4] |
|||
return a0 + (t * (a1 + (t * (a2 + (t * a3))))) # Horner form. |
|||
end |
|||
end # final abstract class Monomial |
|||
procedure lstr (lst) |
|||
return "[" || list2str (lst, ", ") || "]" |
|||
end |
|||
procedure main () |
|||
local x |
|||
local pmono2, qmono2, pbern2, qbern2 |
|||
local pmono3, qmono3, rmono3, pbern3, qbern3, rbern3 |
|||
local pbern3a, qbern3a |
|||
# |
|||
# For the following polynomials, use Subprogram (1) to find |
|||
# coefficients in the degree-2 Bernstein basis: |
|||
# |
|||
# p(x) = 1 |
|||
# q(x) = 1 + 2x + 3x² |
|||
# |
|||
# Display the results. |
|||
# |
|||
pmono2 := [1, 0, 0] |
|||
qmono2 := [1, 2, 3] |
|||
pbern2 := Bernstein.from_monomial_degree2 (pmono2) |
|||
qbern2 := Bernstein.from_monomial_degree2 (qmono2) |
|||
io.write ("Subprogram (1) examples:") |
|||
io.write (" mono ", lstr (pmono2), " --> bern ", lstr (pbern2)) |
|||
io.write (" mono ", lstr (qmono2), " --> bern ", lstr (qbern2)) |
|||
# |
|||
# Use Subprogram (2) to evaluate p(x) and q(x) at x = 0.25, 7.50. |
|||
# Display the results. Optionally also display results from |
|||
# evaluating in the original monomial basis. |
|||
# |
|||
io.write ("Subprogram (2) examples:") |
|||
every x := 0.25 | 7.50 do |
|||
io.write (" p(", x, ") = ", |
|||
Bernstein.evaluate_degree2 (pbern2, x), |
|||
" (mono: ", |
|||
Monomial.evaluate_degree2 (pmono2, x), ")") |
|||
every x := 0.25 | 7.50 do |
|||
io.write (" q(", x, ") = ", |
|||
Bernstein.evaluate_degree2 (qbern2, x), |
|||
" (mono: ", |
|||
Monomial.evaluate_degree2 (qmono2, x), ")") |
|||
# |
|||
# For the following polynomials, use Subprogram (3) to find |
|||
# coefficients in the degree-3 Bernstein basis: |
|||
# |
|||
# p(x) = 1 |
|||
# q(x) = 1 + 2x + 3x² |
|||
# r(x) = 1 + 2x + 3x² + 4x³ |
|||
# |
|||
# Display the results. |
|||
# |
|||
pmono3 := [1, 0, 0, 0] |
|||
qmono3 := [1, 2, 3, 0] |
|||
rmono3 := [1, 2, 3, 4] |
|||
pbern3 := Bernstein.from_monomial_degree3 (pmono3) |
|||
qbern3 := Bernstein.from_monomial_degree3 (qmono3) |
|||
rbern3 := Bernstein.from_monomial_degree3 (rmono3) |
|||
io.write ("Subprogram (3) examples:") |
|||
io.write (" mono ", lstr (pmono3), " --> bern ", lstr (pbern3)) |
|||
io.write (" mono ", lstr (qmono3), " --> bern ", lstr (qbern3)) |
|||
io.write (" mono ", lstr (rmono3), " --> bern ", lstr (rbern3)) |
|||
# |
|||
# Use Subprogram (4) to evaluate p(x), q(x), and r(x) at x = 0.25, |
|||
# 7.50. Display the results. Optionally also display results from |
|||
# evaluating in the original monomial basis. |
|||
# |
|||
io.write ("Subprogram (4) examples:") |
|||
every x := 0.25 | 7.50 do |
|||
io.write (" p(", x, ") = ", |
|||
Bernstein.evaluate_degree3 (pbern3, x), |
|||
" (mono: ", |
|||
Monomial.evaluate_degree3 (pmono3, x), ")") |
|||
every x := 0.25 | 7.50 do |
|||
io.write (" q(", x, ") = ", |
|||
Bernstein.evaluate_degree3 (qbern3, x), |
|||
" (mono: ", |
|||
Monomial.evaluate_degree3 (qmono3, x), ")") |
|||
every x := 0.25 | 7.50 do |
|||
io.write (" r(", x, ") = ", |
|||
Bernstein.evaluate_degree3 (rbern3, x), |
|||
" (mono: ", |
|||
Monomial.evaluate_degree3 (rmono3, x), ")") |
|||
# |
|||
# For the following polynomials, using the result of Subprogram (1) |
|||
# applied to the polynomial, use Subprogram (5) to get coefficients |
|||
# for the degree-3 Bernstein basis: |
|||
# |
|||
# p(x) = 1 |
|||
# q(x) = 1 + 2x + 3x² |
|||
# |
|||
# Display the results. |
|||
# |
|||
io.write ("Subprogram (5) examples:") |
|||
pbern3a := Bernstein.degree2_to_degree3 (pbern2) |
|||
qbern3a := Bernstein.degree2_to_degree3 (qbern2) |
|||
io.write (" bern ", lstr (pbern2), " --> bern ", lstr (pbern3a)) |
|||
io.write (" bern ", lstr (qbern2), " --> bern ", lstr (qbern3a)) |
|||
end |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Subprogram (1) examples: |
|||
mono [1, 0, 0] --> bern [1, 1.0, 1] |
|||
mono [1, 2, 3] --> bern [1, 2.0, 6] |
|||
Subprogram (2) examples: |
|||
p(0.25) = 1.0 (mono: 1.0) |
|||
p(7.5) = 1.0 (mono: 1.0) |
|||
q(0.25) = 1.6875 (mono: 1.6875) |
|||
q(7.5) = 184.75 (mono: 184.75) |
|||
Subprogram (3) examples: |
|||
mono [1, 0, 0, 0] --> bern [1, 1.0, 1.0, 1] |
|||
mono [1, 2, 3, 0] --> bern [1, 1.666666667, 3.333333333, 6] |
|||
mono [1, 2, 3, 4] --> bern [1, 1.666666667, 3.333333333, 10] |
|||
Subprogram (4) examples: |
|||
p(0.25) = 1.0 (mono: 1.0) |
|||
p(7.5) = 1.0 (mono: 1.0) |
|||
q(0.25) = 1.6875 (mono: 1.6875) |
|||
q(7.5) = 184.75 (mono: 184.75) |
|||
r(0.25) = 1.75 (mono: 1.75) |
|||
r(7.5) = 1872.25 (mono: 1872.25) |
|||
Subprogram (5) examples: |
|||
bern [1, 1.0, 1] --> bern [1, 1.0, 1.0, 1] |
|||
bern [1, 2.0, 6] --> bern [1, 1.666666667, 3.333333333, 6] |
|||
</pre> |
|||
=={{header|Python}}== |
=={{header|Python}}== |
||
Line 545: | Line 776: | ||
# Display the results. Optionally also display results from evaluating |
# Display the results. Optionally also display results from evaluating |
||
# in the original monomial basis. |
# in the original monomial basis. |
||
# |
|||
print("Subprogram (2) examples:") |
print("Subprogram (2) examples:") |
||
for x in (0.25, 7.50): |
for x in (0.25, 7.50): |
||
Line 578: | Line 810: | ||
# 7.50. Display the results. Optionally also display results from |
# 7.50. Display the results. Optionally also display results from |
||
# evaluating in the original monomial basis. |
# evaluating in the original monomial basis. |
||
# |
|||
print("Subprogram (4) examples:") |
print("Subprogram (4) examples:") |
||
for x in (0.25, 7.50): |
for x in (0.25, 7.50): |