peroxide_ad/lib.rs
1use proc_macro::TokenStream;
2use quote::{quote, format_ident};
3use syn::{Ident, Type, Token, parenthesized, Block};
4use syn::parse::{Parse, ParseStream};
5use syn::Result;
6
7type Function = Ident;
8type Variable = Ident;
9type Input = Type;
10type Return = Type;
11
12struct Signature {
13 function: Function,
14 var: Variable,
15 var_type: Input,
16 return_t: Return,
17 block: Block,
18}
19
20struct Closure {
21 var: Variable,
22 block: Block,
23}
24
25struct Syntax {
26 _fn_token: Token!(fn),
27 ident: Function,
28 _paren_token: syn::token::Paren,
29 paren_var: Ident,
30 _colon_token: syn::token::Colon,
31 paren_type: Type,
32 _rarrow_token: Token!(->),
33 return_t: Return,
34 block: Block,
35}
36
37struct ClosureSyntax {
38 _lb_token: Token!(|),
39 var: Ident,
40 _colon_token: syn::token::Colon,
41 _bar_type: Type,
42 _rb_token: Token!(|),
43 block: Block,
44}
45
46impl Parse for Signature {
47 fn parse(input: ParseStream) -> Result<Self> {
48 if input.is_empty() {
49 panic!("Empty signature!");
50 }
51
52 let content1;
53 let _fn_token = input.parse().unwrap();
54 let ident = input.parse().unwrap();
55 let _paren_token = parenthesized!(content1 in input);
56 let paren_var = content1.parse().unwrap();
57 let _colon_token = content1.parse().unwrap();
58 let paren_type = content1.parse().unwrap();
59 let _rarrow_token = input.parse().unwrap();
60 let return_t = input.parse().unwrap();
61 let block = input.parse().unwrap();
62 let syntax = Syntax {
63 _fn_token,
64 ident,
65 _paren_token,
66 paren_var,
67 _colon_token,
68 paren_type,
69 _rarrow_token,
70 return_t,
71 block,
72 };
73
74 Ok(Signature {
75 function: syntax.ident,
76 var: syntax.paren_var,
77 var_type: syntax.paren_type,
78 return_t: syntax.return_t,
79 block: syntax.block,
80 })
81 }
82}
83
84impl Parse for Closure {
85 fn parse(input: ParseStream) -> Result<Self> {
86 if input.is_empty() {
87 panic!("Empty signature!");
88 }
89
90 let _lb_token = input.parse()?;
91 let var = input.parse()?;
92 let _colon_token = input.parse()?;
93 let _bar_type = input.parse()?;
94 let _rb_token = input.parse()?;
95 let block = input.parse()?;
96
97 let syntax = ClosureSyntax {
98 _lb_token,
99 var,
100 _colon_token,
101 _bar_type,
102 _rb_token,
103 block,
104 };
105
106 Ok(Closure {
107 var: syntax.var,
108 block: syntax.block,
109 })
110 }
111}
112
113#[proc_macro_attribute]
114pub fn ad_function(_attr: TokenStream, input: TokenStream) -> TokenStream {
115 let signature = syn::parse_macro_input!(input as Signature);
116 let function = signature.function;
117 let var = signature.var;
118 let var_type = signature.var_type;
119 let return_t = signature.return_t;
120 let block = signature.block;
121
122 let ad_fn = format_ident!("{}_ad", function);
123 let grad_fn = format_ident!("{}_grad", function);
124 let hess_fn = format_ident!("{}_hess", function);
125
126 let tokens = quote!{
127 fn #function(#var: #var_type) -> #return_t {
128 #block
129 }
130
131 fn #ad_fn(#var: AD) -> AD {
132 #block
133 }
134
135 fn #grad_fn(#var: f64) -> f64 {
136 let ad = #ad_fn(AD1(#var, 1f64));
137 ad.dx()
138 }
139
140 fn #hess_fn(#var: f64) -> f64 {
141 let ad = #ad_fn(AD2(#var, 1f64, 0f64));
142 ad.ddx()
143 }
144 };
145 tokens.into()
146}
147
148#[proc_macro]
149pub fn ad_closure(input: TokenStream) -> TokenStream {
150 let closure = syn::parse_macro_input!(input as Closure);
151 let var = closure.var;
152 let block = closure.block;
153
154 let tokens = quote!{
155 |#var: AD| #block
156 };
157 tokens.into()
158}
159
160///// Maximum order for Taylor mode AD
161//const N: usize = 5;
162//
163//#[proc_macro]
164//pub fn ad_struct_def(_item: TokenStream) -> TokenStream {
165// let mut total = "".to_string();
166// for i in 1 .. N+1 {
167// let mut body = "pub d0: f64,\n".to_string();
168// for j in 1 .. i+1 {
169// body.push_str(&format!("pub d{}: f64,\n", j));
170// }
171// let one = format!("#[derive(Debug, Copy, Clone, PartialEq, Default)]
172// pub struct AD{} {{
173// {}
174// }}\n", i, body);
175// total.push_str(&one);
176// }
177// total.parse().unwrap()
178//}
179//
180//#[proc_macro]
181//pub fn ad_display(_item: TokenStream) -> TokenStream {
182// let mut total = "".to_string();
183// for i in 1 .. N+1 {
184// let mut body = "".to_string();
185// for j in 1 .. i+1 {
186// body.push_str(&format!("s.push_str(&format!(\" d{}: {{}}\n\", self.d{}));", j, j));
187// }
188// let one = format!("impl std::fmt::Display for AD{} {{
189// fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {{
190// let mut s = format!(\"AD\n d0: {{}}\n\", self.d0);
191// {}
192// write!(f, \"{{}}\", s)
193// }}
194// }}\n", i, body);
195// total.push_str(&one);
196// }
197// total.parse().unwrap()
198//}
199//
200//#[proc_macro]
201//pub fn ad_impl(_item: TokenStream) -> TokenStream {
202// let mut total = "".to_string();
203// for i in 1 .. N+1 {
204// let mut arg = "d0: f64, ".to_string();
205// let mut body = "d0,\n".to_string();
206// for j in 1 .. i {
207// arg.push_str(&format!("d{}: f64, ", j));
208// body.push_str(&format!("d{},\n", j));
209// }
210// arg.push_str(&format!("d{}: f64", i));
211// body.push_str(&format!("d{}", i));
212//
213// let one = format!("impl AD{} {{
214// pub fn new({}) -> Self {{
215// Self {{
216// {}
217// }}
218// }}
219//
220// pub fn print(&self) {{
221// println!(\"{{}}\", self);
222// }}
223//
224// pub fn iter(&self) -> ADIter{} {{
225// self.into_iter()
226// }}
227//
228// pub fn iter_mut(&mut self) -> ADIterMut{} {{
229// self.into_iter()
230// }}
231//
232// pub fn len(&self) -> usize {{
233// {}
234// }}
235// }}", i, arg, body, i, i, i+1);
236// total.push_str(&one);
237// }
238//
239// total.parse().unwrap()
240//}
241//
242//#[proc_macro]
243//pub fn ad_impl_from(_item: TokenStream) -> TokenStream {
244// let mut total = "".to_string();
245// for i in 1 .. N+1 {
246// for j in 1 .. i {
247// let mut body = "high.d0, ".to_string();
248// for k in 1 .. j {
249// body.push_str(&format!("high.d{}, ", k));
250// }
251// body.push_str(&format!("high.d{}", j));
252// // i -> j (i > j)
253// let one = format!("impl From<AD{}> for AD{} {{
254// fn from(high: AD{}) -> Self {{
255// Self::new({})
256// }}
257// }}\n", i, j, i, body);
258// let two = format!("impl<'a> From<&'a AD{}> for AD{} {{
259// fn from(high: &'a AD{}) -> Self {{
260// Self::new({})
261// }}
262// }}\n", i, j, i, body);
263// total.push_str(&one);
264// total.push_str(&two);
265// }
266// // i vs i (&AD -> AD)
267// {
268// let mut body = "high.d0, ".to_string();
269// for k in 1 .. i {
270// body.push_str(&format!("high.d{}, ", k));
271// }
272// body.push_str(&format!("high.d{}", i));
273// let two = format!("impl<'a> From<&'a AD{}> for AD{} {{
274// fn from(high: &'a AD{}) -> Self {{
275// Self::new({})
276// }}
277// }}\n", i, i, i, body);
278// total.push_str(&two);
279// }
280// for j in i+1 .. N+1 {
281// let mut body = "low.d0, ".to_string();
282// for k in 1 .. i+1 {
283// body.push_str(&format!("low.d{}, ", k));
284// }
285// for _k in i+1 .. j {
286// body.push_str("0f64, ");
287// }
288// body.push_str("0f64");
289// // i -> j (i <= j)
290// let one = format!("impl From<AD{}> for AD{} {{
291// fn from(low: AD{}) -> Self {{
292// Self::new({})
293// }}
294// }}\n", i, j, i, body);
295// let two = format!("impl<'a> From<&'a AD{}> for AD{} {{
296// fn from(low: &'a AD{}) -> Self {{
297// Self::new({})
298// }}
299// }}\n", i, j, i, body);
300// total.push_str(&one);
301// total.push_str(&two);
302// }
303// }
304// total.parse().unwrap()
305//}
306//
307//#[proc_macro]
308//pub fn ad_iter_def(_item: TokenStream) -> TokenStream {
309// let mut total = "".to_string();
310// for i in 1 .. N+1 {
311// let one = format!("#[derive(Debug)]
312// pub struct ADIntoIter{} {{
313// ad: AD{},
314// index: usize,
315// r_index: usize,
316// }}\n", i, i);
317// let two = format!("#[derive(Debug)]
318// pub struct ADIter{}<'a> {{
319// ad: &'a AD{},
320// index: usize,
321// r_index: usize,
322// }}\n", i, i);
323// let three = format!("#[derive(Debug)]
324// pub struct ADIterMut{}<'a> {{
325// ad: &'a mut AD{},
326// index: usize,
327// r_index: usize,
328// }}\n", i, i);
329// total.push_str(&one);
330// total.push_str(&two);
331// total.push_str(&three);
332// }
333// total.parse().unwrap()
334//}
335//
336//#[proc_macro]
337//pub fn ad_impl_into_iter(_item: TokenStream) -> TokenStream {
338// let mut total = "".to_string();
339// for i in 1 .. N+1 {
340// let one = format!("impl IntoIterator for AD{} {{
341// type Item = f64;
342// type IntoIter = ADIntoIter{};
343//
344// fn into_iter(self) -> Self::IntoIter {{
345// ADIntoIter{} {{
346// ad: self,
347// index: 0,
348// r_index: 0,
349// }}
350// }}
351// }}\n", i, i, i);
352// let two = format!("impl<'a> IntoIterator for &'a AD{} {{
353// type Item = f64;
354// type IntoIter = ADIter{}<'a>;
355//
356// fn into_iter(self) -> Self::IntoIter {{
357// ADIter{} {{
358// ad: self,
359// index: 0,
360// r_index: 0,
361// }}
362// }}
363// }}\n", i, i, i);
364// let three = format!("impl<'a> IntoIterator for &'a mut AD{} {{
365// type Item = f64;
366// type IntoIter = ADIterMut{}<'a>;
367//
368// fn into_iter(self) -> Self::IntoIter {{
369// ADIterMut{} {{
370// ad: self,
371// index: 0,
372// r_index: 0,
373// }}
374// }}
375// }}\n", i, i, i);
376// total.push_str(&one);
377// total.push_str(&two);
378// total.push_str(&three);
379// }
380// total.parse().unwrap()
381//}
382//
383//#[proc_macro]
384//pub fn ad_impl_iter(_item: TokenStream) -> TokenStream {
385// let mut total = "".to_string();
386// for i in 1 .. N+1 {
387// let mut body = "0 => self.ad.d0,\n".to_string();
388// for j in 1 .. i+1 {
389// body.push_str(&format!("{} => self.ad.d{},\n", j, j));
390// }
391// body.push_str("_ => return None,");
392// let one = format!("impl Iterator for ADIntoIter{} {{
393// type Item = f64;
394// fn next(&mut self) -> Option<Self::Item> {{
395// if self.index + self.r_index < {} {{
396// let result = match self.index {{
397// {}
398// }};
399// self.index += 1;
400// Some(result)
401// }} else {{
402// None
403// }}
404// }}
405//
406// fn size_hint(&self) -> (usize, Option<usize>) {{
407// let lower = self.ad.len() - (self.index + self.r_index);
408// let upper = self.ad.len() - (self.index + self.r_index);
409// (lower, Some(upper))
410// }}
411// }}\n", i, i+1, body);
412// let two = format!("impl<'a> Iterator for ADIter{}<'a> {{
413// type Item = f64;
414// fn next(&mut self) -> Option<Self::Item> {{
415// if self.index + self.r_index < {} {{
416// let result = match self.index {{
417// {}
418// }};
419// self.index += 1;
420// Some(result)
421// }} else {{
422// None
423// }}
424// }}
425// fn size_hint(&self) -> (usize, Option<usize>) {{
426// let lower = self.ad.len() - (self.index + self.r_index);
427// let upper = self.ad.len() - (self.index + self.r_index);
428// (lower, Some(upper))
429// }}
430// }}\n", i, i+1, body);
431// let three = format!("impl<'a> Iterator for ADIterMut{}<'a> {{
432// type Item = f64;
433// fn next(&mut self) -> Option<Self::Item> {{
434// if self.index + self.r_index < {} {{
435// let result = match self.index {{
436// {}
437// }};
438// self.index += 1;
439// Some(result)
440// }} else {{
441// None
442// }}
443// }}
444// fn size_hint(&self) -> (usize, Option<usize>) {{
445// let lower = self.ad.len() - (self.index + self.r_index);
446// let upper = self.ad.len() - (self.index + self.r_index);
447// (lower, Some(upper))
448// }}
449// }}\n", i, i+1, body);
450// total.push_str(&one);
451// total.push_str(&two);
452// total.push_str(&three);
453// }
454// total.parse().unwrap()
455//}
456//
457//#[proc_macro]
458//pub fn ad_impl_from_iter(_item: TokenStream) -> TokenStream {
459// let mut total = "".to_string();
460// for i in 1 .. N+1 {
461// let one = format!("impl FromIterator<f64> for AD{} {{
462// fn from_iter<I: IntoIterator<Item=f64>>(iter: I) -> Self {{
463// let mut z = Self::default();
464// for (i, elem) in iter.into_iter().enumerate() {{
465// z[i] = elem;
466// }}
467// z
468// }}
469// }}\n", i);
470// total.push_str(&one);
471// }
472// total.parse().unwrap()
473//}
474//
475//#[proc_macro]
476//pub fn ad_impl_double_ended_iter(_item: TokenStream) -> TokenStream {
477// let mut total = "".to_string();
478// for i in 1 .. N+1 {
479// let mut body = format!("0 => self.ad.d{},\n", i);
480// for j in 1 .. i+1 {
481// body.push_str(&format!("{} => self.ad.d{},\n", j, i-j));
482// }
483// body.push_str("_ => return None,");
484// let one = format!("impl DoubleEndedIterator for ADIntoIter{} {{
485// fn next_back(&mut self) -> Option<Self::Item> {{
486// if self.index + self.r_index == {} {{
487// return None;
488// }}
489// let result = match self.r_index {{
490// {}
491// }};
492// self.r_index += 1;
493// Some(result)
494// }}
495// }}\n", i, i+1, body);
496// let two = format!("impl<'a> DoubleEndedIterator for ADIter{}<'a> {{
497// fn next_back(&mut self) -> Option<Self::Item> {{
498// if self.index + self.r_index == {} {{
499// return None;
500// }}
501// let result = match self.r_index {{
502// {}
503// }};
504// self.r_index += 1;
505// Some(result)
506// }}
507// }}\n", i, i+1, body);
508// let three = format!("impl<'a> DoubleEndedIterator for ADIterMut{}<'a> {{
509// fn next_back(&mut self) -> Option<Self::Item> {{
510// if self.index + self.r_index == {} {{
511// return None;
512// }}
513// let result = match self.r_index {{
514// {}
515// }};
516// self.r_index += 1;
517// Some(result)
518// }}
519// }}\n", i, i+1, body);
520// total.push_str(&one);
521// total.push_str(&two);
522// total.push_str(&three);
523// }
524// total.parse().unwrap()
525//}
526//
527//#[proc_macro]
528//pub fn ad_impl_exact_size_iter(_item: TokenStream) -> TokenStream {
529// let mut total = "".to_string();
530// for i in 1 .. N+1 {
531// let one = format!("impl ExactSizeIterator for ADIntoIter{} {{
532// fn len(&self) -> usize {{
533// self.ad.len() - (self.index + self.r_index)
534// }}
535// }}\n", i);
536// let two = format!("impl<'a> ExactSizeIterator for ADIter{}<'a> {{
537// fn len(&self) -> usize {{
538// self.ad.len() - (self.index + self.r_index)
539// }}
540// }}\n", i);
541// let three = format!("impl<'a> ExactSizeIterator for ADIterMut{}<'a> {{
542// fn len(&self) -> usize {{
543// self.ad.len() - (self.index + self.r_index)
544// }}
545// }}\n", i);
546// total.push_str(&one);
547// total.push_str(&two);
548// total.push_str(&three);
549// }
550// total.parse().unwrap()
551//}
552//
553//#[proc_macro]
554//pub fn ad_impl_index(_item: TokenStream) -> TokenStream {
555// let mut total = "".to_string();
556// for i in 1 .. N+1 {
557// let mut body1 = "0 => &self.d0,\n".to_string();
558// let mut body2 = "0 => &mut self.d0,\n".to_string();
559// for j in 1 .. i+1 {
560// body1.push_str(&format!("{} => &self.d{},\n", j, j));
561// body2.push_str(&format!("{} => &mut self.d{},\n", j, j));
562// }
563// let one = format!("impl Index<usize> for AD{} {{
564// type Output = f64;
565//
566// fn index(&self, n: usize) -> &Self::Output {{
567// match n {{
568// {}
569// _ => panic!(\"{{}} exceed order of AD{}\", n),
570// }}
571// }}
572// }}\n", i, body1, i);
573// let two = format!("impl IndexMut<usize> for AD{} {{
574// fn index_mut(&mut self, n: usize) -> &mut Self::Output {{
575// match n {{
576// {}
577// _ => panic!(\"{{}} exceed order of AD{}\", n),
578// }}
579// }}
580// }}\n", i, body2, i);
581// total.push_str(&one);
582// total.push_str(&two);
583// }
584// total.parse().unwrap()
585//}
586//
587//#[proc_macro]
588//pub fn ad_impl_neg(_item: TokenStream) -> TokenStream {
589// let mut total = "".to_string();
590// for i in 1 .. N+1 {
591// let mut body = "-self.d0, ".to_string();
592// for j in 1 .. i {
593// body.push_str(&format!("-self.d{}, ", j));
594// }
595// body.push_str(&format!("-self.d{}", i));
596// let one = format!("impl Neg for AD{} {{
597// type Output = Self;
598// fn neg(self) -> Self::Output {{
599// AD{}::new({})
600// }}
601// }}\n", i, i, body);
602// total.push_str(&one);
603// }
604// total.parse().unwrap()
605//}
606//
607//#[proc_macro]
608//pub fn ad_impl_add(_item: TokenStream) -> TokenStream {
609// let mut total = "".to_string();
610// for i in 1 .. N+1 {
611// for j in 1 .. i {
612// let mut body = "".to_string();
613// for k in 0 .. j+1 {
614// body.push_str(&format!("z.d{} += rhs.d{};\n", k, k));
615// }
616// let one = format!("impl Add<AD{}> for AD{} {{
617// type Output = AD{};
618//
619// fn add(self, rhs: AD{}) -> Self::Output {{
620// let mut z = self.clone();
621// {}
622// z
623// }}
624// }}\n", j, i, i, j, body);
625// total.push_str(&one);
626// }
627// for j in i .. N+1 {
628// let mut body = "".to_string();
629// for k in 0 .. i+1 {
630// body.push_str(&format!("z.d{} += self.d{};\n", k, k));
631// }
632// let one = format!("impl Add<AD{}> for AD{} {{
633// type Output = AD{};
634//
635// fn add(self, rhs: AD{}) -> Self::Output {{
636// let mut z = rhs.clone();
637// {}
638// z
639// }}
640// }}\n", j, i, j, j, body);
641// total.push_str(&one);
642// }
643// }
644// total.parse().unwrap()
645//}
646//
647//#[proc_macro]
648//pub fn ad_impl_sub(_item: TokenStream) -> TokenStream {
649// let mut total = "".to_string();
650// for i in 1 .. N+1 {
651// for j in 1 .. i {
652// let mut body = "".to_string();
653// for k in 0 .. j+1 {
654// body.push_str(&format!("z.d{} -= rhs.d{};\n", k, k));
655// }
656// let one = format!("impl Sub<AD{}> for AD{} {{
657// type Output = AD{};
658//
659// fn sub(self, rhs: AD{}) -> Self::Output {{
660// let mut z = self.clone();
661// {}
662// z
663// }}
664// }}\n", j, i, i, j, body);
665// total.push_str(&one);
666// }
667// for j in i .. N+1 {
668// let mut body = "".to_string();
669// for k in 0 .. i+1 {
670// body.push_str(&format!("z.d{} += self.d{};\n", k, k));
671// }
672// let one = format!("impl Sub<AD{}> for AD{} {{
673// type Output = AD{};
674//
675// fn sub(self, rhs: AD{}) -> Self::Output {{
676// let mut z = -rhs.clone();
677// {}
678// z
679// }}
680// }}\n", j, i, j, j, body);
681// total.push_str(&one);
682// }
683// }
684// total.parse().unwrap()
685//}
686//
687//#[proc_macro]
688//pub fn ad_impl_mul(_item: TokenStream) -> TokenStream {
689// let mut total = "".to_string();
690// for i in 1 .. N+1 {
691// for j in 1 .. i+1 {
692// let one = format!("impl Mul<AD{}> for AD{} {{
693// type Output = AD{};
694//
695// fn mul(self, rhs: AD{}) -> Self::Output {{
696// let mut z = self.clone();
697// let y = Self::Output::from(rhs);
698// for t in 0 .. z.len() {{
699// z[t] = self.iter()
700// .take(t + 1)
701// .zip(y.iter().take(t+1).rev())
702// .enumerate()
703// .fold(0f64, |s, (k, (x1, y1))| s + (C(t, k) as f64) * x1 * y1)
704// }}
705// z
706// }}
707// }}\n", j, i, i, j);
708// let two = format!("impl<'a> Mul<&'a AD{}> for AD{} {{
709// type Output = AD{};
710//
711// fn mul(self, rhs: &'a AD{}) -> Self::Output {{
712// let mut z = self.clone();
713// let y = Self::Output::from(rhs);
714// for t in 0 .. z.len() {{
715// z[t] = self.iter()
716// .take(t + 1)
717// .zip(y.iter().take(t+1).rev())
718// .enumerate()
719// .fold(0f64, |s, (k, (x1, y1))| s + (C(t, k) as f64) * x1 * y1)
720// }}
721// z
722// }}
723// }}\n", j, i, i, j);
724// total.push_str(&one);
725// total.push_str(&two);
726// }
727// for j in i+1 .. N+1 {
728// let one = format!("impl Mul<AD{}> for AD{} {{
729// type Output = AD{};
730//
731// fn mul(self, rhs: AD{}) -> Self::Output {{
732// let mut z = rhs.clone();
733// let x = Self::Output::from(self);
734// for t in 0 .. z.len() {{
735// z[t] = x.iter()
736// .take(t + 1)
737// .zip(rhs.iter().take(t+1).rev())
738// .enumerate()
739// .fold(0f64, |s, (k, (x1, y1))| s + (C(t, k) as f64) * x1 * y1)
740// }}
741// z
742// }}
743// }}\n", j, i, j, j);
744// let two = format!("impl<'a> Mul<&'a AD{}> for AD{} {{
745// type Output = AD{};
746//
747// fn mul(self, rhs: &'a AD{}) -> Self::Output {{
748// let mut z = rhs.clone();
749// let x = Self::Output::from(self);
750// let y = Self::Output::from(rhs);
751// for t in 0 .. z.len() {{
752// z[t] = x.iter()
753// .take(t + 1)
754// .zip(y.iter().take(t+1).rev())
755// .enumerate()
756// .fold(0f64, |s, (k, (x1, y1))| s + (C(t, k) as f64) * x1 * y1)
757// }}
758// z
759// }}
760// }}\n", j, i, j, j);
761// total.push_str(&one);
762// total.push_str(&two);
763// }
764// }
765// total.parse().unwrap()
766//}
767//
768//#[proc_macro]
769//pub fn ad_impl_div(_item: TokenStream) -> TokenStream {
770// let mut total = "".to_string();
771// for i in 1 .. N+1 {
772// // i >= j (self >= rhs)
773// for j in 1 .. i+1 {
774// let one = format!("impl Div<AD{}> for AD{} {{
775// type Output = AD{};
776//
777// fn div(self, rhs: AD{}) -> Self::Output {{
778// let mut z = Self::Output::default();
779// let y = Self::Output::from(rhs);
780// z[0] = self[0] / y[0];
781// let y0 = 1f64 / y[0];
782// for i in 1 .. z.len() {{
783// let mut s = 0f64;
784// for (j, (y1, z1)) in y.iter().skip(1).take(i).zip(z.iter().take(i).rev()).enumerate() {{
785// s += (C(i, j+1) as f64) * y1 * z1;
786// }}
787// z[i] = y0 * (self[i] - s);
788// }}
789// z
790// }}
791// }}", j, i, i, j);
792// total.push_str(&one);
793// }
794// // i < j (self < rhs)
795// for j in i+1 .. N+1 {
796// let one = format!("impl Div<AD{}> for AD{} {{
797// type Output = AD{};
798//
799// fn div(self, rhs: AD{}) -> Self::Output {{
800// let mut z = Self::Output::default();
801// let x = Self::Output::from(self);
802// z[0] = x[0] / rhs[0];
803// let y0 = 1f64 / rhs[0];
804// for i in 1 .. z.len() {{
805// let mut s = 0f64;
806// for (j, (y1, z1)) in rhs.iter().skip(1).take(i).zip(z.iter().take(i).rev()).enumerate() {{
807// s += (C(i, j+1) as f64) * y1 * z1;
808// }}
809// z[i] = y0 * (x[i] - s);
810// }}
811// z
812// }}
813// }}", j, i, j, j);
814// total.push_str(&one);
815// }
816// }
817// total.parse().unwrap()
818//}
819//
820//#[proc_macro]
821//pub fn ad_impl_explogops(_item: TokenStream) -> TokenStream {
822// let mut total = "".to_string();
823// for i in 1 .. N+1 {
824// let one = format!("impl ExpLogOps for AD{} {{
825// fn exp(&self) -> Self {{
826// let mut z = Self::default();
827// z[0] = self[0].exp();
828// for i in 1 .. z.len() {{
829// z[i] = z.iter()
830// .take(i)
831// .zip(self.iter().skip(1).take(i).rev())
832// .enumerate()
833// .fold(0f64, |x, (k, (z1, x1))| x + (C(i-1, k) as f64) * x1 * z1);
834// }}
835// z
836// }}
837//
838// fn ln(&self) -> Self {{
839// let mut z = Self::default();
840// z[0] = self[0].ln();
841// let x0 = 1f64 / self[0];
842// for i in 1 .. z.len() {{
843// let mut s = 0f64;
844// for (k, (z1, x1)) in z.iter().skip(1).take(i-1).zip(self.iter().skip(1).take(i-1).rev()).enumerate() {{
845// s += (C(i-1, k+1) as f64) * z1 * x1;
846// }}
847// z[i] = x0 * (self[i] - s);
848// }}
849// z
850// }}
851//
852// fn log(&self, base: f64) -> Self {{
853// self.ln().iter().map(|x| x / base.ln()).collect()
854// }}
855// }}", i);
856// total.push_str(&one);
857// }
858// total.parse().unwrap()
859//}
860//
861//#[proc_macro]
862//pub fn ad_impl_powops(_item: TokenStream) -> TokenStream {
863// let mut total = "".to_string();
864// for i in 1 .. N+1 {
865// let one = format!("impl PowOps for AD{} {{
866// fn powi(&self, n: i32) -> Self {{
867// let mut z = self.clone();
868// for _i in 1 .. n {{
869// z = z * self;
870// }}
871// z
872// }}
873//
874// fn powf(&self, f: f64) -> Self {{
875// let ln_x = self.ln();
876// let mut z = Self::default();
877// z[0] = self.d0.powf(f);
878// for i in 1 .. z.len() {{
879// let mut s = 0f64;
880// for (j, (z1, ln_x1)) in z.iter().skip(1).take(i-1).zip(ln_x.iter().skip(1).take(i-1).rev()).enumerate() {{
881// s += (C(i-1, j+1) as f64) * z1 * ln_x1;
882// }}
883// z[i] = f * (z[0] * ln_x[i] + s);
884// }}
885// z
886// }}
887//
888// fn pow(&self, _f: Self) -> Self {{
889// unimplemented!()
890// }}
891// }}", i);
892// total.push_str(&one);
893// }
894// total.parse().unwrap()
895//}
896//
897//#[proc_macro]
898//pub fn ad_impl_trigops(_item: TokenStream) -> TokenStream {
899// let mut total = "".to_string();
900// for i in 1 .. N+1 {
901// let one = format!("impl TrigOps for AD{} {{
902// fn sin_cos(&self) -> (Self, Self) {{
903// let mut u = Self::default();
904// let mut v = Self::default();
905// u[0] = self[0].sin();
906// v[0] = self[0].cos();
907// for i in 1 .. u.len() {{
908// u[i] = v.iter()
909// .take(i)
910// .zip(self.iter().skip(1).take(i).rev())
911// .enumerate()
912// .fold(0f64, |x, (k, (v1, x1))| x + (C(i-1, k) as f64) * x1 * v1);
913// v[i] = -u.iter()
914// .take(i)
915// .zip(self.iter().skip(1).take(i).rev())
916// .enumerate()
917// .fold(0f64, |x, (k, (u1, x1))| x + (C(i-1, k) as f64) * x1 * u1);
918// }}
919// (u, v)
920// }}
921//
922// fn sinh_cosh(&self) -> (Self, Self) {{
923// let mut u = Self::default();
924// let mut v = Self::default();
925// u[0] = self[0].sinh();
926// v[0] = self[0].cosh();
927// for i in 1 .. u.len() {{
928// u[i] = v.iter()
929// .take(i)
930// .zip(self.iter().skip(1).take(i).rev())
931// .enumerate()
932// .fold(0f64, |x, (k, (v1, x1))| x + (C(i-1, k) as f64) * x1 * v1);
933// v[i] = u.iter()
934// .take(i)
935// .zip(self.iter().skip(1).take(i).rev())
936// .enumerate()
937// .fold(0f64, |x, (k, (u1, x1))| x + (C(i-1, k) as f64) * x1 * u1);
938// }}
939// (u, v)
940//
941// }}
942//
943// fn asin(&self) -> Self {{
944// unimplemented!()
945// }}
946//
947// fn acos(&self) -> Self {{
948// unimplemented!()
949// }}
950//
951// fn atan(&self) -> Self {{
952// unimplemented!()
953// }}
954//
955// fn asinh(&self) -> Self {{
956// unimplemented!()
957// }}
958//
959// fn acosh(&self) -> Self {{
960// unimplemented!()
961// }}
962//
963// fn atanh(&self) -> Self {{
964// unimplemented!()
965// }}
966// }}\n", i);
967// total.push_str(&one);
968// }
969// total.parse().unwrap()
970//}
971//
972//#[proc_macro]
973//pub fn def_ad(_item: TokenStream) -> TokenStream {
974// let mut from_into = "".to_string();
975// let mut to_ad = "".to_string();
976// for i in 1 .. N+1 {
977// from_into.push_str(&format!("+ From<AD{}>\n", i));
978// from_into.push_str(&format!("+ Into<AD{}>\n", i));
979// to_ad.push_str(&format!("fn to_ad{}(self) -> AD{} {{ self.into() }}\n", i, i));
980// }
981// let total = format!("pub trait AD:
982// std::fmt::Display
983// + Clone
984// + Copy
985// + PartialEq
986// + From<f64>
987// + Into<f64>
988// + Add<Output = Self>
989// + Sub<Output = Self>
990// + Mul<Output = Self>
991// + Div<Output = Self>
992// + Add<f64, Output = Self>
993// + Sub<f64, Output = Self>
994// + Mul<f64, Output = Self>
995// + Div<f64, Output = Self>
996// + PowOps
997// + ExpLogOps
998// + TrigOps
999// {}
1000// {{
1001// {}
1002// }}", from_into, to_ad);
1003// total.parse().unwrap()
1004//}
1005//
1006//#[proc_macro]
1007//pub fn ad_impl_ad(_item: TokenStream) -> TokenStream {
1008// let mut total = "".to_string();
1009// for i in 1 .. N+1 {
1010// let one = format!("impl AD for AD{} {{}}", i);
1011// total.push_str(&one);
1012// }
1013// total.parse().unwrap()
1014//}
1015//
1016//#[proc_macro]
1017//pub fn ad_impl_from_type(item: TokenStream) -> TokenStream {
1018// let mut total = "".to_string();
1019// for i in 1 .. N+1 {
1020// let one = format!("impl From<{}> for AD{} {{
1021// fn from(other: {}) -> Self {{
1022// let f = other as f64;
1023// let mut z = Self::default();
1024// z.d0 = f;
1025// z
1026// }}
1027// }}\n", item, i, item);
1028// total.push_str(&one);
1029// }
1030// total.parse().unwrap()
1031//}
1032//
1033//#[proc_macro]
1034//pub fn ad_impl_add_f64(_item: TokenStream) -> TokenStream {
1035// let mut total = "".to_string();
1036// for i in 1 .. N+1 {
1037// let one = format!("impl Add<f64> for AD{} {{
1038// type Output = Self;
1039//
1040// fn add(self, rhs: f64) -> Self::Output {{
1041// let mut z = self;
1042// z.d0 += rhs;
1043// z
1044// }}
1045// }}\n", i);
1046// total.push_str(&one);
1047// }
1048// total.parse().unwrap()
1049//}
1050//
1051//#[proc_macro]
1052//pub fn ad_impl_sub_f64(_item: TokenStream) -> TokenStream {
1053// let mut total = "".to_string();
1054// for i in 1 .. N+1 {
1055// let one = format!("impl Sub<f64> for AD{} {{
1056// type Output = Self;
1057//
1058// fn sub(self, rhs: f64) -> Self::Output {{
1059// let mut z = self;
1060// z.d0 -= rhs;
1061// z
1062// }}
1063// }}\n", i);
1064// total.push_str(&one);
1065// }
1066// total.parse().unwrap()
1067//}
1068//
1069//#[proc_macro]
1070//pub fn ad_impl_mul_f64(_item: TokenStream) -> TokenStream {
1071// let mut total = "".to_string();
1072// for i in 1 .. N+1 {
1073// let one = format!("impl Mul<f64> for AD{} {{
1074// type Output = Self;
1075//
1076// fn mul(self, rhs: f64) -> Self::Output {{
1077// self.iter().map(|x| x * rhs).collect()
1078// }}
1079// }}\n", i);
1080// total.push_str(&one);
1081// }
1082// total.parse().unwrap()
1083//}
1084//
1085//#[proc_macro]
1086//pub fn ad_impl_div_f64(_item: TokenStream) -> TokenStream {
1087// let mut total = "".to_string();
1088// for i in 1 .. N+1 {
1089// let one = format!("impl Div<f64> for AD{} {{
1090// type Output = Self;
1091//
1092// fn div(self, rhs: f64) -> Self::Output {{
1093// self.iter().map(|x| x / rhs).collect()
1094// }}
1095// }}\n", i);
1096// total.push_str(&one);
1097// }
1098// total.parse().unwrap()
1099//}
1100//
1101//#[proc_macro]
1102//pub fn f64_impl_add_ad(_item: TokenStream) -> TokenStream {
1103// let mut total = "".to_string();
1104// for i in 1 .. N+1 {
1105// let one = format!("impl Add<AD{}> for f64 {{
1106// type Output = AD{};
1107//
1108// fn add(self, rhs: AD{}) -> Self::Output {{
1109// let mut z = rhs;
1110// z.d0 += self;
1111// z
1112// }}
1113// }}\n", i, i, i);
1114// total.push_str(&one);
1115// }
1116// total.parse().unwrap()
1117//}
1118//
1119//#[proc_macro]
1120//pub fn f64_impl_sub_ad(_item: TokenStream) -> TokenStream {
1121// let mut total = "".to_string();
1122// for i in 1 .. N+1 {
1123// let one = format!("impl Sub<AD{}> for f64 {{
1124// type Output = AD{};
1125//
1126// fn sub(self, rhs: AD{}) -> Self::Output {{
1127// let mut z = -rhs;
1128// z.d0 += self;
1129// z
1130// }}
1131// }}\n", i, i, i);
1132// total.push_str(&one);
1133// }
1134// total.parse().unwrap()
1135//}
1136//
1137//#[proc_macro]
1138//pub fn f64_impl_mul_ad(_item: TokenStream) -> TokenStream {
1139// let mut total = "".to_string();
1140// for i in 1 .. N+1 {
1141// let one = format!("impl Mul<AD{}> for f64 {{
1142// type Output = AD{};
1143//
1144// fn mul(self, rhs: AD{}) -> Self::Output {{
1145// rhs.iter().map(|x| x * self).collect()
1146// }}
1147// }}\n", i, i, i);
1148// total.push_str(&one);
1149// }
1150// total.parse().unwrap()
1151//}
1152//
1153//#[proc_macro]
1154//pub fn f64_impl_div_ad(_item: TokenStream) -> TokenStream {
1155// let mut total = "".to_string();
1156// for i in 1 .. N+1 {
1157// let one = format!("impl Div<AD{}> for f64 {{
1158// type Output = AD{};
1159//
1160// fn div(self, rhs: AD{}) -> Self::Output {{
1161// let ad1 = AD1::from(self);
1162// ad1 / rhs
1163// }}
1164// }}\n", i, i, i);
1165// total.push_str(&one);
1166// }
1167// total.parse().unwrap()
1168//}
1169//
1170//
1171//#[proc_macro]
1172//pub fn f64_impl_from_ad(_item: TokenStream) -> TokenStream {
1173// let mut total = "".to_string();
1174// for i in 1 .. N+1 {
1175// let one = format!("impl From<AD{}> for f64 {{
1176// fn from(ad: AD{}) -> Self {{
1177// ad.d0
1178// }}
1179// }}\n", i, i);
1180// total.push_str(&one);
1181// }
1182// total.parse().unwrap()
1183//}
1184//
1185//#[proc_macro]
1186//pub fn ad_impl_stable_fn(_item: TokenStream) -> TokenStream {
1187// let mut total = "".to_string();
1188// for i in 2 .. N+1 {
1189// for j in 2 .. (i+1) {
1190// let one = format!("impl<F:Fn(AD{}) -> AD{}> StableFn<AD{}> for ADLift<F, AD{}> {{
1191// type Output = AD{};
1192// fn call_stable(&self, target: Self::Output) -> Self::Output {{
1193// self.f(AD{}::from(target)).into()
1194// }}
1195// }}\n", i, i, j, i, j, i);
1196// total.push_str(&one);
1197// }
1198// }
1199// total.parse().unwrap()
1200//}