View Javadoc
1   package net.bmahe.genetics4j.gp;
2   
3   import java.util.Arrays;
4   import java.util.Objects;
5   import java.util.function.BiFunction;
6   import java.util.function.Function;
7   import java.util.function.Supplier;
8   
9   import org.apache.commons.lang3.Validate;
10  
11  import net.bmahe.genetics4j.gp.math.ImmutableCoefficientOperation;
12  import net.bmahe.genetics4j.gp.math.ImmutableCoefficientOperation.Builder;
13  
14  public final class OperationFactories {
15  
16  	private OperationFactories() {
17  	}
18  
19  	@SuppressWarnings("rawtypes")
20  	public static OperationFactory ofOperationSupplier(final Class[] acceptedTypes, final Class returnedType,
21  			final Supplier<Operation> buildSupplier) {
22  		Objects.requireNonNull(acceptedTypes);
23  		Objects.requireNonNull(returnedType);
24  		Objects.requireNonNull(buildSupplier);
25  
26  		return new OperationFactory() {
27  
28  			@Override
29  			public Class returnedType() {
30  				return returnedType;
31  			}
32  
33  			@Override
34  			public Class[] acceptedTypes() {
35  				return acceptedTypes;
36  			}
37  
38  			@Override
39  			public Operation build(final InputSpec inputSpec) {
40  				return buildSupplier.get();
41  			}
42  		};
43  	}
44  
45  	@SuppressWarnings("rawtypes")
46  	public static OperationFactory of(final Class[] acceptedTypes, final Class returnedType,
47  			final Function<InputSpec, Operation> operationBuilder) {
48  		Objects.requireNonNull(acceptedTypes);
49  		Objects.requireNonNull(returnedType);
50  		Objects.requireNonNull(operationBuilder);
51  
52  		return new OperationFactory() {
53  			@Override
54  			public Class[] acceptedTypes() {
55  				return acceptedTypes;
56  			}
57  
58  			@Override
59  			public Class returnedType() {
60  				return returnedType;
61  			}
62  
63  			@Override
64  			public Operation build(final InputSpec inputSpec) {
65  				return operationBuilder.apply(inputSpec);
66  			}
67  		};
68  	}
69  
70  	@SuppressWarnings("rawtypes")
71  	public static OperationFactory of(final String name, final Class[] acceptedTypes, final Class returnedType,
72  			final BiFunction<Object[], Object[], Object> compute) {
73  		Validate.notBlank(name);
74  		Objects.requireNonNull(acceptedTypes);
75  		Objects.requireNonNull(returnedType);
76  		Objects.requireNonNull(compute);
77  
78  		return new OperationFactory() {
79  
80  			@Override
81  			public Class[] acceptedTypes() {
82  				return acceptedTypes;
83  			}
84  
85  			@Override
86  			public Class returnedType() {
87  				return returnedType;
88  			}
89  
90  			@Override
91  			public Operation build(final InputSpec inputSpec) {
92  				return ImmutableOperation.of(name, Arrays.asList(acceptedTypes), returnedType, compute);
93  			}
94  		};
95  	}
96  
97  	@SuppressWarnings("rawtypes")
98  	public static OperationFactory ofCoefficient(final String name, final Class returnedType, final Object value) {
99  		Validate.notBlank(name);
100 		Objects.requireNonNull(returnedType);
101 		Objects.requireNonNull(value);
102 
103 		return new OperationFactory() {
104 
105 			@Override
106 			public Class[] acceptedTypes() {
107 				return new Class[] {};
108 			}
109 
110 			@Override
111 			public Class returnedType() {
112 				return returnedType;
113 			}
114 
115 			@Override
116 			public Operation build(final InputSpec inputSpec) {
117 				final Builder<Object> operationBuilder = ImmutableCoefficientOperation.builder();
118 
119 				operationBuilder.name(name)
120 						.value(value)
121 						.returnedType(returnedType)
122 						.prettyName(name + "[" + value + "]");
123 
124 				return operationBuilder.build();
125 			}
126 		};
127 	}
128 
129 	public static <T> OperationFactory ofTerminal(final String name, final Class<T> returnedType,
130 			final Supplier<T> compute) {
131 		Validate.notBlank(name);
132 		Objects.requireNonNull(returnedType);
133 		Objects.requireNonNull(compute);
134 
135 		return of(name, new Class[] {}, returnedType, (input, parameter) -> {
136 			return compute.get();
137 		});
138 	}
139 
140 	public static <T, U> OperationFactory ofUnary(final String name, final Class<T> acceptedType,
141 			final Class<U> returnedType, final Function<T, U> compute) {
142 		Validate.notBlank(name);
143 		Objects.requireNonNull(acceptedType);
144 		Objects.requireNonNull(returnedType);
145 		Objects.requireNonNull(compute);
146 
147 		return of(name, new Class[] { acceptedType }, returnedType, (input, parameters) -> {
148 			Objects.requireNonNull(parameters);
149 
150 			final Object parameter1 = parameters[0];
151 			Objects.requireNonNull(parameter1);
152 			Validate.isInstanceOf(acceptedType, parameter1);
153 
154 			@SuppressWarnings("unchecked")
155 			final T operand = (T) parameter1;
156 
157 			return compute.apply(operand);
158 		});
159 	}
160 
161 	@SuppressWarnings("unchecked")
162 	public static <T, U, V> OperationFactory ofBinary(final String name, final Class<T> acceptedType1,
163 			final Class<U> acceptedType2, final Class<V> returnedType, final BiFunction<T, U, V> compute) {
164 		Validate.notBlank(name);
165 		Objects.requireNonNull(acceptedType1);
166 		Objects.requireNonNull(acceptedType2);
167 		Objects.requireNonNull(returnedType);
168 		Objects.requireNonNull(compute);
169 
170 		return of(name, new Class[] { acceptedType1, acceptedType2 }, returnedType, (input, parameters) -> {
171 			Objects.requireNonNull(parameters);
172 
173 			final Object parameter1 = parameters[0];
174 			Objects.requireNonNull(parameter1);
175 			Validate.isInstanceOf(acceptedType1, parameter1);
176 			final T operand1 = (T) parameter1;
177 
178 			final Object parameter2 = parameters[1];
179 			Objects.requireNonNull(parameter2);
180 			Validate.isInstanceOf(acceptedType2, parameter2);
181 			final U operand2 = (U) parameter2;
182 
183 			return compute.apply(operand1, operand2);
184 		});
185 	}
186 }