|
221 | 221 | # TODO: optimized implementations for DiffEq wrappers
|
222 | 222 |
|
223 | 223 | #=
|
224 |
| -Compute the derivative df of a real-valued callable f on a collection of points x. |
| 224 | +Compute the derivative df of a callable f on a collection of points x. |
225 | 225 | Single point implementations.
|
226 | 226 | =#
|
227 | 227 | function finite_difference(f, x::T, fdtype::DataType, funtype::DataType=Val{:Real}, f_x::Union{Void,T}=nothing) where T<:Number
|
@@ -428,51 +428,37 @@ function finite_difference_jacobian!(J::StridedMatrix{<:Number}, f, x::StridedAr
|
428 | 428 | m, n = size(J)
|
429 | 429 | epsilon_elemtype = compute_epsilon_elemtype(epsilon, x)
|
430 | 430 | if fdtype == Val{:forward}
|
431 |
| - epsilon_factor = compute_epsilon_factor(Val{:forward}, eltype(x)) |
| 431 | + epsilon_factor = compute_epsilon_factor(Val{:forward}, epsilon_elemtype) |
432 | 432 | @inbounds for i in 1:n
|
433 |
| - epsilon = compute_epsilon(Val{:forward}, x[i], epsilon_factor) |
| 433 | + epsilon = compute_epsilon(Val{:forward}, real(x[i]), epsilon_factor) |
434 | 434 | epsilon_inv = one(returntype) / epsilon
|
435 | 435 | for j in 1:m
|
436 | 436 | if i==j
|
437 | 437 | if typeof(fx) == Void
|
438 |
| - J[j,i] = (f(x[j]+epsilon) - f(x[j])) * epsilon_inv |
| 438 | + J[j,i] = ( real( f(x[j]+epsilon) - f(x[j]) ) + im*imag( f(x[j]+im*epsilon) - f(x[j]) ) ) * epsilon_inv |
439 | 439 | else
|
440 |
| - if typeof(fx) == Void |
441 |
| - J[j,i] = (f(x[j]+epsilon) - f(x[j])) * epsilon_inv |
442 |
| - else |
443 |
| - J[j,i] = (f(x[j]+epsilon) - fx[j]) * epsilon_inv |
444 |
| - end |
| 440 | + J[j,i] = ( real( f(x[j]+epsilon) - fx[j] ) + im*imag( f(x[j]+im*epsilon) - fx[j] ) ) * epsilon_inv |
445 | 441 | end
|
446 | 442 | else
|
447 | 443 | J[j,i] = zero(returntype)
|
448 | 444 | end
|
449 | 445 | end
|
450 | 446 | end
|
451 | 447 | elseif fdtype == Val{:central}
|
452 |
| - epsilon_factor = compute_epsilon_factor(Val{:central}, eltype(x)) |
| 448 | + epsilon_factor = compute_epsilon_factor(Val{:central}, epsilon_elemtype) |
453 | 449 | @inbounds for i in 1:n
|
454 |
| - epsilon = compute_epsilon(Val{:central}, x[i], epsilon_factor) |
| 450 | + epsilon = compute_epsilon(Val{:central}, real(x[i]), epsilon_factor) |
455 | 451 | epsilon_double_inv = one(returntype) / (2 * epsilon)
|
456 | 452 | for j in 1:m
|
457 | 453 | if i==j
|
458 |
| - J[j,i] = (f(x[j]+epsilon) - f(x[j]-epsilon)) * epsilon_double_inv |
459 |
| - else |
460 |
| - J[j,i] = zero(returntype) |
461 |
| - end |
462 |
| - end |
463 |
| - end |
464 |
| - elseif fdtype == Val{:complex} |
465 |
| - epsilon = eps(epsilon_elemtype) |
466 |
| - epsilon_inv = one(epsilon_elemtype) / epsilon |
467 |
| - @inbounds for i in 1:n |
468 |
| - for j in 1:m |
469 |
| - if i==j |
470 |
| - J[j,i] = imag(f(x[j]+im*epsilon)) * epsilon_inv |
| 454 | + J[j,i] = ( real( f(x[j]+epsilon)-f(x[j]-epsilon) ) + im*imag( f(x[j]+im*epsilon) - f(x[j]-im*epsilon) ) ) * epsilon_double_inv |
471 | 455 | else
|
472 | 456 | J[j,i] = zero(returntype)
|
473 | 457 | end
|
474 | 458 | end
|
475 | 459 | end
|
| 460 | + else |
| 461 | + error("Unrecognized fdtype: must be Val{:forward} or Val{:central}.") |
476 | 462 | end
|
477 | 463 | J
|
478 | 464 | end
|
0 commit comments