@@ -101,5 +101,84 @@ public void Should_SigmoidCrossEntropyWithLogits (double [] labels, double [] lo
101101 }
102102 }
103103
104+ private static IEnumerable < object [ ] > reduceProdData ( )
105+ {
106+ // Example from https://www.tensorflow.org/api_docs/python/tf/reduce_mean but adapted to return prod
107+ var x = new double [ , ] { { 1 , 1 } ,
108+ { 2 , 2 } } ;
109+
110+ yield return new object [ ] { x , null , 4.0 } ;
111+ yield return new object [ ] { x , 0 , new double [ ] { 2 , 2 } } ;
112+ yield return new object [ ] { x , 1 , new double [ ] { 1 , 4 } } ;
113+ }
114+
115+ [ Theory ]
116+ [ MemberData ( nameof ( reduceProdData ) ) ]
117+ public void Should_ReduceProd ( double [ , ] input , int ? axis , object expected )
118+ {
119+ using ( var graph = new TFGraph ( ) )
120+ using ( var session = new TFSession ( graph ) ) {
121+ var tinput = graph . Placeholder ( TFDataType . Double , new TFShape ( 2 , 2 ) ) ;
122+
123+ TFTensor [ ] result ;
124+ if ( axis != null ) {
125+ var taxis = graph . Const ( axis . Value ) ;
126+ TFOutput y = graph . ReduceProd ( tinput , taxis ) ;
127+ result = session . Run ( new [ ] { tinput , taxis } , new TFTensor [ ] { input , axis } , new [ ] { y } ) ;
128+
129+ double [ ] actual = ( double [ ] ) result [ 0 ] . GetValue ( ) ;
130+ TestUtils . MatrixEqual ( expected , actual , precision : 8 ) ;
131+ } else {
132+ TFOutput y = graph . ReduceProd ( tinput , axis : null ) ;
133+ result = session . Run ( new [ ] { tinput } , new TFTensor [ ] { input } , new [ ] { y } ) ;
134+
135+ double actual = ( double ) result [ 0 ] . GetValue ( ) ;
136+ TestUtils . MatrixEqual ( expected , actual , precision : 8 ) ;
137+ }
138+ }
139+ }
140+
141+ private static IEnumerable < object [ ] > reduceProdData2 ( )
142+ {
143+ yield return new object [ ] { null , 170170.0 } ;
144+ yield return new object [ ] { - 3 , new [ ] { 1.0 } } ;
145+ yield return new object [ ] { - 2 , new [ ] { 22.0 , 65.0 , 119.0 } } ;
146+ yield return new object [ ] { - 1 , new [ ] { 70.0 , 2431.0 } } ;
147+ yield return new object [ ] { 0 , new [ ] { 22.0 , 65.0 , 119.0 } } ;
148+ yield return new object [ ] { 1 , new [ ] { 70.0 , 2431.0 } } ;
149+ yield return new object [ ] { 2 , new [ ] { 1.0 } } ;
150+ yield return new object [ ] { 3 , new [ ] { 1.0 } } ;
151+ }
152+
153+ [ Theory ]
154+ [ MemberData ( nameof ( reduceProdData2 ) ) ]
155+ public void Should_ReduceProd2 ( int ? axis , object expected )
156+ {
157+ using ( var graph = new TFGraph ( ) )
158+ using ( var session = new TFSession ( graph ) ) {
159+
160+ double [ , ] test = {
161+ { 2 , 5 , 7 } ,
162+ { 11 , 13 , 17 } ,
163+ } ;
164+
165+ var x = graph . Const ( test ) ;
166+
167+ if ( axis == null || axis >= - 2 && axis < 2 ) {
168+ TFOutput y = graph . ReduceProd ( x , axis : axis == null ? ( TFOutput ? ) null : graph . Const ( axis ) ) ;
169+
170+ TFTensor [ ] result = session . Run ( new TFOutput [ ] { } , new TFTensor [ ] { } , new [ ] { y } ) ;
171+
172+ object actual = result [ 0 ] . GetValue ( ) ;
173+ TestUtils . MatrixEqual ( expected , actual , precision : 8 ) ;
174+ } else {
175+ Assert . Throws < TFException > ( ( ) => {
176+ TFOutput y = graph . ReduceProd ( x , axis : axis == null ? ( TFOutput ? ) null : graph . Const ( axis ) ) ;
177+ session . Run ( new TFOutput [ ] { } , new TFTensor [ ] { } , new [ ] { y } ) ;
178+ } ) ;
179+ }
180+ }
181+ }
182+
104183 }
105184}
0 commit comments