Skip to content

Commit 2898045

Browse files
authored
feat: improve performance of the nonlinear functions (#138)
* feat: improve performance of the nonlinear functions * fix: fixup
1 parent 69655a6 commit 2898045

File tree

2 files changed

+62
-69
lines changed

2 files changed

+62
-69
lines changed

lib/NonlinearProblemLibrary/Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "NonlinearProblemLibrary"
22
uuid = "b7050fa9-e91f-4b37-bcee-a89a063da141"
3-
version = "0.1.2"
3+
version = "0.1.3"
44

55
[deps]
66
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"

lib/NonlinearProblemLibrary/src/NonlinearProblemLibrary.jl

Lines changed: 61 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ using SciMLBase, LinearAlgebra
66
# [test_nonlin](https://people.sc.fsu.edu/~jburkardt/m_src/test_nonlin/test_nonlin.html)
77

88
# ------------------------------------- Problem 1 ------------------------------------------
9-
function p1_f!(out, x, p = nothing)
9+
@inbounds @views function p1_f!(out, x, p = nothing)
1010
n = length(x)
1111
out[1] = 1.0 - x[1]
12-
out[2:n] .= 10.0 .* (x[2:n] .- x[1:(n - 1)] .* x[1:(n - 1)])
12+
@. out[2:n] = 10.0 * (x[2:n] - x[1:(n - 1)] * x[1:(n - 1)])
1313
nothing
1414
end
1515

@@ -21,7 +21,7 @@ p1_dict = Dict("n" => n, "start" => x_start, "sol" => x_sol,
2121
"title" => "Generalized Rosenbrock function")
2222

2323
# ------------------------------------- Problem 2 ------------------------------------------
24-
function p2_f!(out, x, p = nothing)
24+
@inbounds function p2_f!(out, x, p = nothing)
2525
out[1] = x[1] + 10.0 * x[2]
2626
out[2] = sqrt(5.0) * (x[3] - x[4])
2727
out[3] = (x[2] - 2.0 * x[3])^2
@@ -36,7 +36,7 @@ p2_dict = Dict("n" => n, "start" => x_start, "sol" => x_sol,
3636
"title" => "Powell singular function")
3737

3838
# ------------------------------------- Problem 3 ------------------------------------------
39-
function p3_f!(out, x, p = nothing)
39+
@inbounds function p3_f!(out, x, p = nothing)
4040
out[1] = 10000.0 * x[1] * x[2] - 1.0
4141
out[2] = exp(-x[1]) + exp(-x[2]) - 1.0001
4242
nothing
@@ -49,7 +49,7 @@ p3_dict = Dict("n" => n, "start" => x_start, "sol" => x_sol,
4949
"title" => "Powell badly scaled function")
5050

5151
# ------------------------------------- Problem 4 ------------------------------------------
52-
function p4_f!(out, x, p = nothing)
52+
@inbounds function p4_f!(out, x, p = nothing)
5353
temp1 = x[2] - x[1] * x[1]
5454
temp2 = x[4] - x[3] * x[3]
5555

@@ -66,15 +66,9 @@ x_start = [-3.0, -1.0, -3.0, -1.0]
6666
p4_dict = Dict("n" => n, "start" => x_start, "sol" => x_sol, "title" => "Wood function")
6767

6868
# ------------------------------------- Problem 5 ------------------------------------------
69-
function p5_f!(out, x, p = nothing)
70-
if 0.0 < x[1]
71-
temp = atan(x[2] / x[1]) / (2.0 * pi)
72-
elseif x[1] < 0.0
73-
temp = atan(x[2] / x[1]) / (2.0 * pi) + 0.5
74-
else
75-
temp = 0.25 * sign(x[2])
76-
end
77-
69+
@inbounds function p5_f!(out, x, p = nothing)
70+
temp1 = atan(x[2] / x[1]) / (2.0 * pi)
71+
temp = ifelse(0.0 < x[1], temp1, ifelse(x[1] < 0.0, temp1 + 0.5, 0.25 * sign(x[2])))
7872
out[1] = 10.0 * (x[3] - 10.0 * temp)
7973
out[2] = 10.0 * (sqrt(x[1] * x[1] + x[2] * x[2]) - 1.0)
8074
out[3] = x[3]
@@ -88,7 +82,7 @@ p5_dict = Dict("n" => n, "start" => x_start, "sol" => x_sol,
8882
"title" => "Helical valley function")
8983

9084
# ------------------------------------- Problem 6 ------------------------------------------
91-
function p6_f!(out, x, p = nothing)
85+
@inbounds function p6_f!(out, x, p = nothing)
9286
n = length(x)
9387
out .= 0
9488
for i in 1:29
@@ -114,8 +108,8 @@ function p6_f!(out, x, p = nothing)
114108
end
115109
end
116110

117-
out[1] = out[1] + 3.0 * x[1] - 2.0 * x[1] * x[2] + 2.0 * x[1]^3
118-
out[2] = out[2] + x[2] - x[2]^2 - 1.0
111+
out[1] += x[1] * (3.0 - 2.0 * x[2] + 2.0 * x[1]^2)
112+
out[2] += x[2] * (1.0 - x[2]) - 1.0
119113
nothing
120114
end
121115

@@ -125,7 +119,7 @@ x_start = zeros(n)
125119
p6_dict = Dict("n" => n, "start" => x_start, "sol" => x_sol, "title" => "Watson function")
126120

127121
# ------------------------------------- Problem 7 ------------------------------------------
128-
function p7_f!(out, x, p = nothing)
122+
@inbounds function p7_f!(out, x, p = nothing)
129123
n = length(x)
130124
out .= 0.0
131125
for j in 1:n
@@ -138,13 +132,9 @@ function p7_f!(out, x, p = nothing)
138132
t2 = t3
139133
end
140134
end
141-
out ./= n
142135

143-
for i in 1:n
144-
ip1 = i
145-
if ip1 % 2 == 0
146-
out[i] = out[i] + 1.0 / (ip1 * ip1 - 1)
147-
end
136+
@simd ivdep for i in 1:n
137+
out[i] = out[i] / n + ifelse(i % 2 == 0, 1.0 / (i * i - 1), 0.0)
148138
end
149139
nothing
150140
end
@@ -160,9 +150,10 @@ p7_dict = Dict("n" => n, "start" => x_start, "sol" => x_sol,
160150
"title" => "Chebyquad function")
161151

162152
# ------------------------------------- Problem 8 ------------------------------------------
163-
function p8_f!(out, x, p = nothing)
153+
@inbounds @views function p8_f!(out, x, p = nothing)
164154
n = length(x)
165-
out[1:(n - 1)] .= x[1:(n - 1)] .+ sum(x) .- (n + 1)
155+
sum_x = sum(x)
156+
@. out[1:(n - 1)] = x[1:(n - 1)] + sum_x - (n + 1)
166157
out[n] = prod(x) - 1.0
167158
nothing
168159
end
@@ -174,18 +165,18 @@ p8_dict = Dict("n" => n, "start" => x_start, "sol" => x_sol,
174165
"title" => "Brown almost linear function")
175166

176167
# ------------------------------------- Problem 9 ------------------------------------------
177-
function p9_f!(out, x, p = nothing)
168+
@inline function discrete_bvf_kernel(xk, k, h)
169+
return 2.0 * xk + 0.5 * h^2 * (xk + k * h + 1.0)^3
170+
end
171+
172+
@inbounds function p9_f!(out, x, p = nothing)
178173
n = length(x)
179174
h = 1.0 / (n + 1)
180-
for k in 1:n
181-
out[k] = 2.0 * x[k] + 0.5 * h^2 * (x[k] + k * h + 1.0)^3
182-
if 1 < k
183-
out[k] = out[k] - x[k - 1]
184-
end
185-
if k < n
186-
out[k] = out[k] - x[k + 1]
187-
end
175+
out[1] = discrete_bvf_kernel(x[1], 1, h) - x[2]
176+
for k in 2:(n - 1)
177+
out[k] = discrete_bvf_kernel(x[k], k, h) - x[k - 1] - x[k + 1]
188178
end
179+
out[n] = discrete_bvf_kernel(x[n], n, h) - x[n - 1]
189180
nothing
190181
end
191182

@@ -199,7 +190,7 @@ p9_dict = Dict("n" => n, "start" => x_start, "sol" => x_sol,
199190
"title" => "Discrete boundary value function")
200191

201192
# ------------------------------------- Problem 10 -----------------------------------------
202-
function p10_f!(out, x, p = nothing)
193+
@inbounds function p10_f!(out, x, p = nothing)
203194
n = length(x)
204195
h = 1.0 / (n + 1)
205196
for k in 1:n
@@ -230,11 +221,12 @@ p10_dict = Dict("n" => n, "start" => x_start, "sol" => x_sol,
230221
"title" => "Discrete integral equation function")
231222

232223
# ------------------------------------- Problem 11 -----------------------------------------
233-
function p11_f!(out, x, p = nothing)
224+
@inbounds function p11_f!(out, x, p = nothing)
234225
n = length(x)
235-
c_sum = sum(cos.(x))
236-
for k in 1:n
237-
out[k] = n - c_sum + k * (1.0 - cos(x[k])) - sin(x[k])
226+
c_sum = sum(cos, x)
227+
@simd ivdep for k in 1:n
228+
sxk, cxk = sincos(x[k])
229+
out[k] = n - c_sum + k * (1.0 - cxk) - sxk
238230
end
239231
nothing
240232
end
@@ -246,7 +238,7 @@ p11_dict = Dict("n" => n, "start" => x_start, "sol" => x_sol,
246238
"title" => "Trigonometric function")
247239

248240
# ------------------------------------- Problem 12 -----------------------------------------
249-
function p12_f!(out, x, p = nothing)
241+
@inbounds function p12_f!(out, x, p = nothing)
250242
n = length(x)
251243
sum1 = 0.0
252244
for j in 1:n
@@ -268,17 +260,15 @@ p12_dict = Dict("n" => n, "start" => x_start, "sol" => x_sol,
268260
"title" => "Variably dimensioned function")
269261

270262
# ------------------------------------- Problem 13 -----------------------------------------
271-
function p13_f!(out, x, p = nothing)
263+
@inline broyden_tridiag_kernel(xk) = (3.0 - 2.0 * xk) * xk + 1.0
264+
265+
@inbounds function p13_f!(out, x, p = nothing)
272266
n = length(x)
273-
for k in 1:n
274-
out[k] = (3.0 - 2.0 * x[k]) * x[k] + 1.0
275-
if 1 < k
276-
out[k] -= x[k - 1]
277-
end
278-
if k < n
279-
out[k] -= 2.0 * x[k + 1]
280-
end
267+
out[1] = broyden_tridiag_kernel(x[1]) -2.0 * x[2]
268+
for k in 2:(n - 1)
269+
out[k] = broyden_tridiag_kernel(x[k]) - x[k - 1] - 2.0 * x[k + 1]
281270
end
271+
out[n] = broyden_tridiag_kernel(x[n]) - x[n - 1]
282272
nothing
283273
end
284274

@@ -289,7 +279,7 @@ p13_dict = Dict("n" => n, "start" => x_start, "sol" => x_sol,
289279
"title" => "Broyden tridiagonal function")
290280

291281
# ------------------------------------- Problem 14 -----------------------------------------
292-
function p14_f!(out, x, p = nothing)
282+
@inbounds function p14_f!(out, x, p = nothing)
293283
n = length(x)
294284
ml = 5
295285
mu = 1
@@ -315,7 +305,7 @@ p14_dict = Dict("n" => n, "start" => x_start, "sol" => x_sol,
315305
"title" => "Broyden banded function")
316306

317307
# ------------------------------------- Problem 15 -----------------------------------------
318-
function p15_f!(out, x, p = nothing)
308+
@inbounds function p15_f!(out, x, p = nothing)
319309
out[1] = (x[1] * x[1] + x[2] * x[3]) - 0.0001
320310
out[2] = (x[1] * x[2] + x[2] * x[4]) - 1.0
321311
out[3] = (x[3] * x[1] + x[4] * x[3]) - 0.0
@@ -330,7 +320,7 @@ p15_dict = Dict("n" => n, "start" => x_start, "sol" => x_sol,
330320
"title" => "Hammarling 2 by 2 matrix square root problem")
331321

332322
# ------------------------------------- Problem 16 -----------------------------------------
333-
function p16_f!(out, x, p = nothing)
323+
@inbounds function p16_f!(out, x, p = nothing)
334324
out[1] = (x[1] * x[1] + x[2] * x[4] + x[3] * x[7]) - 0.0001
335325
out[2] = (x[1] * x[2] + x[2] * x[5] + x[3] * x[8]) - 1.0
336326
out[3] = x[1] * x[3] + x[2] * x[6] + x[3] * x[9]
@@ -350,7 +340,7 @@ p16_dict = Dict("n" => n, "start" => x_start, "sol" => x_sol,
350340
"title" => "Hammarling 3 by 3 matrix square root problem")
351341

352342
# ------------------------------------- Problem 17 -----------------------------------------
353-
function p17_f!(out, x, p = nothing)
343+
@inbounds function p17_f!(out, x, p = nothing)
354344
out[1] = x[1] + x[2] - 3.0
355345
out[2] = x[1]^2 + x[2]^2 - 9.0
356346
nothing
@@ -364,16 +354,18 @@ p17_dict = Dict("n" => n, "start" => x_start, "sol" => x_sol,
364354

365355
# ------------------------------------- Problem 18 -----------------------------------------
366356
function p18_f!(out, x, p = nothing)
367-
if x[1] != 0.0
368-
out[1] = x[2]^2 * (1.0 - exp(-x[1] * x[1])) / x[1]
369-
else
357+
if iszero(x[1])
370358
out[1] = 0.0
371-
end
372-
if x[2] != 0.0
373-
out[2] = x[1] * (1.0 - exp(-x[2] * x[2])) / x[2]
374359
else
360+
out[1] = x[2]^2 * (1.0 - exp(-x[1] * x[1])) / x[1]
361+
end
362+
363+
if iszero(x[2])
375364
out[2] = 0.0
365+
else
366+
out[2] = x[1] * (1.0 - exp(-x[2] * x[2])) / x[2]
376367
end
368+
377369
nothing
378370
end
379371

@@ -384,9 +376,10 @@ p18_dict = Dict("n" => n, "start" => x_start, "sol" => x_sol,
384376
"title" => "Sample problem 18")
385377

386378
# ------------------------------------- Problem 19 -----------------------------------------
387-
function p19_f!(out, x, p = nothing)
388-
out[1] = x[1] * (x[1]^2 + x[2]^2)
389-
out[2] = x[2] * (x[1]^2 + x[2]^2)
379+
@inbounds function p19_f!(out, x, p = nothing)
380+
tmp = x[1]^2 + x[2]^2
381+
out[1] = x[1] * tmp
382+
out[2] = x[2] * tmp
390383
nothing
391384
end
392385

@@ -397,7 +390,7 @@ p19_dict = Dict("n" => n, "start" => x_start, "sol" => x_sol,
397390
"title" => "Sample problem 19")
398391

399392
# ------------------------------------- Problem 20 -----------------------------------------
400-
function p20_f!(out, x, p = nothing)
393+
@inbounds function p20_f!(out, x, p = nothing)
401394
out[1] = x[1] * (x[1] - 5.0)^2
402395
nothing
403396
end
@@ -409,7 +402,7 @@ p20_dict = Dict("n" => n, "start" => x_start, "sol" => x_sol,
409402
"title" => "Scalar problem f(x) = x(x - 5)^2")
410403

411404
# ------------------------------------- Problem 21 -----------------------------------------
412-
function p21_f!(out, x, p = nothing)
405+
@inbounds function p21_f!(out, x, p = nothing)
413406
out[1] = x[1] - x[2]^3 + 5.0 * x[2]^2 - 2.0 * x[2] - 13.0
414407
out[2] = x[1] + x[2]^3 + x[2]^2 - 14.0 * x[2] - 29.0
415408
nothing
@@ -422,9 +415,9 @@ p21_dict = Dict("n" => n, "start" => x_start, "sol" => x_sol,
422415
"title" => "Freudenstein-Roth function")
423416

424417
# ------------------------------------- Problem 22 -----------------------------------------
425-
function p22_f!(out, x, p = nothing)
418+
@inbounds function p22_f!(out, x, p = nothing)
426419
out[1] = x[1] * x[1] - x[2] + 1.0
427-
out[2] = x[1] - cos(0.5 * pi * x[2])
420+
out[2] = x[1] - cospi(0.5 * x[2])
428421
nothing
429422
end
430423

@@ -435,7 +428,7 @@ p22_dict = Dict("n" => n, "start" => x_start, "sol" => x_sol,
435428
"title" => "Boggs function")
436429

437430
# ------------------------------------- Problem 23 -----------------------------------------
438-
function p23_f!(out, x, p = nothing)
431+
@inbounds function p23_f!(out, x, p = nothing)
439432
c = 0.9
440433
out[1:n] = x[1:n]
441434
μ = zeros(n)

0 commit comments

Comments
 (0)