@@ -9,6 +9,8 @@ pub struct ComplexEvaluatorSettings {
99 pub ( crate ) log_real : bool ,
1010 /// Whether powf with real arguments yields real results.
1111 pub ( crate ) powf_real : bool ,
12+ /// Whether custom evaluator functions with real arguments yield real results.
13+ pub ( crate ) real_if_args_real : bool ,
1214 /// Report on the number of converted operations.
1315 pub ( crate ) verbose : bool ,
1416}
@@ -20,6 +22,7 @@ impl ComplexEvaluatorSettings {
2022 sqrt_real,
2123 log_real,
2224 powf_real,
25+ real_if_args_real : false ,
2326 verbose,
2427 }
2528 }
@@ -42,6 +45,12 @@ impl ComplexEvaluatorSettings {
4245 self
4346 }
4447
48+ /// Set that all custom evaluator functions with real arguments yield real results.
49+ pub fn real_if_args_real ( mut self ) -> Self {
50+ self . real_if_args_real = true ;
51+ self
52+ }
53+
4554 /// Set verbose reporting.
4655 pub fn verbose ( mut self ) -> Self {
4756 self . verbose = true ;
@@ -56,6 +65,7 @@ impl Default for ComplexEvaluatorSettings {
5665 sqrt_real : false ,
5766 log_real : false ,
5867 powf_real : false ,
68+ real_if_args_real : false ,
5969 verbose : false ,
6070 }
6171 }
@@ -66,8 +76,8 @@ impl<T: Default + PartialEq> ExpressionEvaluator<Complex<T>> {
6676 /// assembly output that uses real arithmetic instead of complex arithmetic
6777 /// where possible.
6878 ///
69- /// You can also set if all encountered sqrt, log, and powf operations with real
70- /// arguments are expected to yield real results.
79+ /// You can also set if all encountered sqrt, log, powf, and custom evaluator
80+ /// operations with real arguments are expected to yield real results.
7181 ///
7282 /// Must be called after all optimization functions and merging are performed
7383 /// on the evaluator, or the registration will be lost.
@@ -192,8 +202,15 @@ impl<T: Default + PartialEq> ExpressionEvaluator<Complex<T>> {
192202 }
193203 subcomponents[ * r] = * sc;
194204 }
195- Instr :: ExternalFun ( r, ..) => {
196- * sc = ComplexPhase :: Any ;
205+ Instr :: ExternalFun ( r, _, a) => {
206+ if settings. real_if_args_real
207+ && !a. is_empty ( )
208+ && a. iter ( ) . all ( |x| subcomponents[ * x] == ComplexPhase :: Real )
209+ {
210+ * sc = ComplexPhase :: Real ;
211+ } else {
212+ * sc = ComplexPhase :: Any ;
213+ }
197214 subcomponents[ * r] = * sc;
198215 }
199216 Instr :: IfElse ( ..) | Instr :: Goto ( ..) | Instr :: Label ( ..) => {
0 commit comments