Skip to content

Commit 2a42f81

Browse files
committed
feat: add optimize/base/brentq
--- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: passed - task: lint_package_json status: passed - task: lint_repl_help status: passed - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: passed - task: lint_javascript_tests status: passed - task: lint_javascript_benchmarks status: passed - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: passed - task: lint_typescript_tests status: passed - task: lint_license_headers status: passed ---
1 parent baaed47 commit 2a42f81

10 files changed

Lines changed: 925 additions & 0 deletions

File tree

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<!--
2+
3+
@license Apache-2.0
4+
5+
Copyright (c) 2026 The Stdlib Authors.
6+
7+
Licensed under the Apache License, Version 2.0 (the "License");
8+
you may not use this file except in compliance with the License.
9+
You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing, software
14+
distributed under the License is distributed on an "AS IS" BASIS,
15+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
See the License for the specific language governing permissions and
17+
limitations under the License.
18+
19+
-->
20+
21+
# brentq
22+
23+
> Find a zero of a continuous function using Brent's method.
24+
25+
<section class="intro">
26+
27+
Finds a zero of a continuous function $f$ on the interval $\lbrack a, b \rbrack$ where the sign of $f(a)$ and $f(b)$ must be opposite.
28+
29+
</section>
30+
31+
<!-- /.intro -->
32+
33+
<section class="usage">
34+
35+
## Usage
36+
37+
```javascript
38+
var brentq = require( '@stdlib/optimize/base/brentq' );
39+
```
40+
41+
#### brentq( f, a, b&#91;, options&#93; )
42+
43+
Finds a zero of a continuous function `f` on the interval `[a, b]`.
44+
45+
```javascript
46+
function f( x ) {
47+
return ( x * x ) - 1;
48+
}
49+
50+
var root = brentq( f, 0, 2 );
51+
// returns 1.0
52+
```
53+
54+
The function accepts the following options:
55+
56+
- **maxIter**: maximum number of iterations. Default: `100`.
57+
- **xtol**: absolute tolerance. Default: `2e-12`.
58+
- **rtol**: relative tolerance. Default: `8.88e-16`.
59+
60+
</section>
61+
62+
<!-- /.usage -->
63+
64+
<section class="examples">
65+
66+
## Examples
67+
68+
<!-- eslint no-undef: "error" -->
69+
70+
```javascript
71+
var sin = require( '@stdlib/math/base/special/sin' );
72+
var brentq = require( '@stdlib/optimize/base/brentq' );
73+
74+
function f( x ) {
75+
return sin( x );
76+
}
77+
78+
var root = brentq( f, 3.0, 3.2 );
79+
console.log( root );
80+
// => 3.141592653589793
81+
```
82+
83+
</section>
84+
85+
<!-- /.examples -->
86+
87+
<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->
88+
89+
<section class="related">
90+
91+
</section>
92+
93+
<!-- /.related -->
94+
95+
<!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
96+
97+
<section class="links">
98+
99+
</section>
100+
101+
<!-- /.links -->
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2026 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
'use strict';
20+
21+
// MODULES //
22+
23+
var bench = require( '@stdlib/bench' );
24+
var isnan = require( '@stdlib/math/base/assert/is-nan' );
25+
var pkg = require( './../package.json' ).name;
26+
var brentq = require( './../lib' );
27+
28+
29+
// MAIN //
30+
31+
bench( pkg, function benchmark( b ) {
32+
var root;
33+
var i;
34+
35+
function f( x ) {
36+
return ( x * x ) - 1.0;
37+
}
38+
39+
b.tic();
40+
for ( i = 0; i < b.iterations; i++ ) {
41+
root = brentq( f, 0.0, 2.0 );
42+
if ( isnan( root ) ) {
43+
b.fail( 'should not return NaN' );
44+
}
45+
}
46+
b.toc();
47+
if ( isnan( root ) ) {
48+
b.fail( 'should not return NaN' );
49+
}
50+
b.pass( 'benchmark finished' );
51+
b.end();
52+
});
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
2+
{{alias}}( f, a, b[, options] )
3+
Finds a zero of a continuous function `f` on the interval `[a, b]`.
4+
5+
Parameters
6+
----------
7+
f: Function
8+
Objective function.
9+
a: number
10+
Lower bound.
11+
b: number
12+
Upper bound.
13+
options: Object (optional)
14+
Function options.
15+
options.maxIter: number (optional)
16+
Maximum number of iterations. Default: 100.
17+
options.xtol: number (optional)
18+
Absolute tolerance. Default: 2e-12.
19+
options.rtol: number (optional)
20+
Relative tolerance. Default: 8.88e-16.
21+
22+
Returns
23+
-------
24+
x: number
25+
Zero.
26+
27+
Examples
28+
--------
29+
> function f( x ) { return x*x - 1.0; };
30+
> {{alias}}( f, 0.0, 2.0 )
31+
1.0
32+
33+
See Also
34+
--------
35+
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2026 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
// TypeScript Version: 4.1
20+
21+
/**
22+
* Interface defining options.
23+
*/
24+
interface Options {
25+
/**
26+
* Maximum number of iterations.
27+
*/
28+
maxIter?: number;
29+
30+
/**
31+
* Absolute tolerance.
32+
*/
33+
xtol?: number;
34+
35+
/**
36+
* Relative tolerance.
37+
*/
38+
rtol?: number;
39+
}
40+
41+
/**
42+
* Callback function.
43+
*
44+
* @param x - input value
45+
* @returns function value
46+
*/
47+
type Unary = ( x: number ) => number;
48+
49+
/**
50+
* Finds a zero of a continuous function `f` on the interval `[a, b]`.
51+
*
52+
* @param f - objective function
53+
* @param a - lower bound
54+
* @param b - upper bound
55+
* @param options - function options
56+
* @returns zero
57+
*
58+
* @example
59+
* function f( x ) {
60+
* return x * x - 1.0;
61+
* }
62+
* var v = brentq( f, 0.0, 2.0 );
63+
* // returns 1.0
64+
*/
65+
declare function brentq( f: Unary, a: number, b: number, options?: Options ): number;
66+
67+
export = brentq;
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2026 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
import brentq = require( './index' );
20+
21+
/**
22+
* Callback function.
23+
*
24+
* @param x - input value
25+
* @returns result
26+
*/
27+
function f( x: number ): number {
28+
return x * x - 1.0;
29+
}
30+
31+
// TESTS //
32+
33+
// The function returns a number...
34+
{
35+
brentq( f, 0.0, 2.0 ); // $ExpectType number
36+
brentq( f, 0.0, 2.0, { 'maxIter': 20 } ); // $ExpectType number
37+
}
38+
39+
// The compiler throws an error if the function is provided an invalid first argument...
40+
{
41+
brentq( true, 0.0, 2.0 ); // $ExpectError
42+
brentq( false, 0.0, 2.0 ); // $ExpectError
43+
brentq( 5, 0.0, 2.0 ); // $ExpectError
44+
brentq( [], 0.0, 2.0 ); // $ExpectError
45+
brentq( {}, 0.0, 2.0 ); // $ExpectError
46+
brentq( 'abc', 0.0, 2.0 ); // $ExpectError
47+
}
48+
49+
// The compiler throws an error if the function is provided an invalid second argument...
50+
{
51+
brentq( f, true, 2.0 ); // $ExpectError
52+
brentq( f, false, 2.0 ); // $ExpectError
53+
brentq( f, [], 2.0 ); // $ExpectError
54+
brentq( f, {}, 2.0 ); // $ExpectError
55+
brentq( f, 'abc', 2.0 ); // $ExpectError
56+
}
57+
58+
// The compiler throws an error if the function is provided an invalid third argument...
59+
{
60+
brentq( f, 0.0, true ); // $ExpectError
61+
brentq( f, 0.0, false ); // $ExpectError
62+
brentq( f, 0.0, [] ); // $ExpectError
63+
brentq( f, 0.0, {} ); // $ExpectError
64+
brentq( f, 0.0, 'abc' ); // $ExpectError
65+
}
66+
67+
// The compiler throws an error if the function is provided an invalid options argument...
68+
{
69+
brentq( f, 0.0, 2.0, true ); // $ExpectError
70+
brentq( f, 0.0, 2.0, false ); // $ExpectError
71+
brentq( f, 0.0, 2.0, 5 ); // $ExpectError
72+
brentq( f, 0.0, 2.0, [] ); // $ExpectError
73+
brentq( f, 0.0, 2.0, 'abc' ); // $ExpectError
74+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2026 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
'use strict';
20+
21+
var pow = require( '@stdlib/math/base/special/pow' );
22+
var sin = require( '@stdlib/math/base/special/sin' );
23+
var brentq = require( './../lib' );
24+
25+
function f( x ) {
26+
return pow( x, 3 ) - ( 2.0 * x ) - 5.0;
27+
}
28+
29+
var root = brentq( f, 2.0, 3.0 );
30+
console.log( 'f(x) = x^3 - 2x - 5' );
31+
console.log( 'Root: %d', root );
32+
console.log( 'f(root): %d', f( root ) );
33+
34+
// Example with options
35+
function g( x ) {
36+
return sin( x );
37+
}
38+
39+
root = brentq( g, 3.0, 4.0, {
40+
'xtol': 1e-4
41+
});
42+
console.log( '\nf(x) = sin(x)' );
43+
console.log( 'Root matching 3.14 on [3, 4] with xtol 1e-4: %d', root );
44+
console.log( 'f(root): %d', g( root ) );

0 commit comments

Comments
 (0)