package org.matheclipse.core.reflection.system;

import org.matheclipse.core.eval.exception.Validate;
import org.matheclipse.core.eval.interfaces.AbstractFunctionEvaluator;
import org.matheclipse.core.expression.F;
import org.matheclipse.core.interfaces.IAST;
import org.matheclipse.core.interfaces.IExpr;

public class Outer extends AbstractFunctionEvaluator {
	class Generating {
		final private IAST fOuterList;

		final private IAST fInnerList;

		final private int fHeadOffset;

		public Generating(IAST outerList, IAST innerList, int headOffset) {
			this.fOuterList = outerList;
			this.fInnerList = innerList;
			this.fHeadOffset = headOffset;
		}

		/**
		 * Outer product - every element from the first list will be combined with the second list
		 * 
		 */
		public IAST outer(IAST first, IAST second) {
			IAST result1 = fOuterList.clone();
			IAST result2;
			IAST temp;
			for (int i = fHeadOffset; i < first.size(); i++) {

				if (first.get(i).isAST()) {
					result1.add(outer(first.get(i), second));
				} else {
					result2 = fOuterList.clone();
					for (int j = fHeadOffset; j < second.size(); j++) {

						if (second.get(j).isAST()) {
							result2.add(outer(first.get(i), (IAST) second.get(j)));
						} else {
							temp = fInnerList.clone();
							temp.add(first.get(i));
							temp.add(second.get(j));
							result2.add(temp);
						}
					}
					result1.add(result2);
				}
			}

			return result1;
		}

		private IAST outer(IExpr element, IAST second) {
			IAST result = fOuterList.clone();
			IAST temp;
			for (int j = fHeadOffset; j < second.size(); j++) {

				if (second.get(j).isAST()) {
					result.add(outer(element, (IAST) second.get(j)));
				} else {
					temp = fInnerList.clone();
					temp.add(element);
					temp.add(second.get(j));
					result.add(temp);
				}
			}

			return result;
		}

	}

	public Outer() {
	}

	@Override
	public IExpr evaluate(final IAST ast) {
		Validate.checkSize(ast, 4);
		if (ast.arg1().isSymbol() && ast.arg2().isAST() && ast.arg3().isAST()) {
			Generating gen = new Generating(F.List(), F.ast(ast.arg1()), 1);
			return gen.outer((IAST) ast.arg2(), (IAST) ast.arg3());
		}
		return null;
	}

}

 

Ads help maintain this website.