// Path: core/src/main/java/net/xsoftlab/ml4j/minfunc/LBFGS.java
// public class LBFGS extends MinFunc {
// 
// 	/**
// 	 * 初始化
// 	 * 
// 	 * @param model
// 	 *            训练模型
// 	 */
// 	public LBFGS(BaseModel model) {
// 		super();
// 		this.model = model;
// 
// 		this.theta = model.getInitTheta();
// 	}
// 
// 	/**
// 	 * 初始化
// 	 * 
// 	 * @param model
// 	 *            训练模型
// 	 * @param maxIter
// 	 *            最大训练次数
// 	 */
// 	public LBFGS(BaseModel model, int maxIter) {
// 
// 		this(model);
// 		this.maxIter = maxIter;
// 	}
// 
// 	@Override
// 	public FloatMatrix train() {
// 
// 		model.compute(theta, 3);
// 		float cost0 = model.getCost();// 初始cost
// 		FloatMatrix gk = model.getGradient();// 初始梯度
// 
// 		float cost1, lamda;// lamda:一维搜索步长
// 		FloatMatrix d, sk, yk, gk1;// dk,sk,xk+1,gk
// 
// 		if (logFlag)
// 			logger.debug("迭代次数 \t\t步长 \t\t    cost");
// 
// 		int l, m = 3;// limit
// 		float alpha, beta;
// 		FloatMatrix ql;
// 		LinkedList<FloatMatrix> sl = new LinkedList<FloatMatrix>();
// 		LinkedList<FloatMatrix> yl = new LinkedList<FloatMatrix>();
// 		LinkedList<Float> pl = new LinkedList<Float>();
// 		Float[] alphal = new Float[m];
// 
// 		for (int k = 0; k < maxIter; k++) {
// 
// 			l = k <= m ? k : m;
// 			ql = gk;
// 
// 			for (int i = l - 1; i >= 0; i--) {
// 				alpha = sl.get(i).transpose().mmul(ql).mul(pl.get(i)).get(0);
// 				ql = ql.sub(yl.get(i).mul(alpha));
// 				alphal[i] = alpha;
// 			}
// 
// 			d = ql;
// 			for (int i = 0; i < l; i++) {
// 				beta = yl.get(i).transpose().mmul(d).mul(pl.get(i)).get(0);
// 				d = sl.get(i).mul(alphal[i] - beta).add(d);
// 			}
// 
// 			d = d.neg();
// 			lamda = Wolfe.lineSearch(model, theta, d);
// 			sk = d.mul(lamda);
// 			theta = theta.add(sk);
// 
// 			model.compute(theta, 3);
// 			cost1 = model.getCost();
// 			gk1 = model.getGradient();
// 
// 			if (logFlag) {
// 				logger.debug("  {} \t   {}   \t {}", new Object[] { k + 1, cost0 - cost1, cost1 });
// 			}
// 
// 			if (gk1.transpose().mmul(gk1).get(0) < epsilon) {
// 				logger.info("\n已达到梯度精度阈值.\n");
// 				break;
// 			}
// 
// 			if (cost0 - cost1 < epsilon) {
// 				logger.info("\n已达到cost精度阈值.\n");
// 				break;
// 			}
// 
// 			yk = gk1.sub(gk);
// 
// 			yl.add(yk);
// 			if (yl.size() > m)
// 				yl.removeFirst();
// 
// 			sl.add(sk);
// 			if (sl.size() > m)
// 				sl.removeFirst();
// 
// 			pl.add(1f / yk.transpose().mmul(sk).get(0));
// 			if (pl.size() > m)
// 				pl.removeFirst();
// 
// 			gk = gk1;
// 			cost0 = cost1;
// 		}
// 
// 		return theta;
// 	}
// }
// 
// Path: core/src/main/java/net/xsoftlab/ml4j/minfunc/MinFunc.java
// public abstract class MinFunc {
// 
// 	protected BaseModel model;// 训练模型
// 	protected int maxIter = 500;// 最大训练次数
// 	protected float epsilon = (float) 1e-6;// 精度阈值
// 
// 	protected FloatMatrix theta;// 参数
// 	protected boolean logFlag = true;// 是否打印过程日志
// 
// 	Logger logger = LoggerFactory.getLogger(this.getClass());
// 
// 	/**
// 	 * 计算最优化theta
// 	 * 
// 	 * @return theta
// 	 */
// 	public abstract FloatMatrix train();
// 
// 	public void setEpsilon(float epsilon) {
// 		this.epsilon = epsilon;
// 	}
// 
// 	public void setTheta(FloatMatrix theta) {
// 		this.theta = theta;
// 	}
// 
// 	public void setCostFlag(boolean costFlag) {
// 		this.logFlag = costFlag;
// 	}
// }


import net.xsoftlab.ml4j.minfunc.LBFGS;
import net.xsoftlab.ml4j.minfunc.MinFunc;
import org.jblas.FloatMatrix;
package net.xsoftlab.ml4j.model.supervised;



/**
 * 模型接口
 * 
 * @author 王彦超
 *
 */
public abstract class BaseModel {

	protected FloatMatrix x;// 特征矩阵
	protected FloatMatrix y;// 标签
	protected float lambda = 0f;// 正则化系数

// Path: core/src/main/java/net/xsoftlab/ml4j/minfunc/LBFGS.java
// public class LBFGS extends MinFunc {
// 
// 	/**
// 	 * 初始化
// 	 * 
// 	 * @param model
// 	 *            训练模型
// 	 */
// 	public LBFGS(BaseModel model) {
// 		super();
// 		this.model = model;
// 
// 		this.theta = model.getInitTheta();
// 	}
// 
// 	/**
// 	 * 初始化
// 	 * 
// 	 * @param model
// 	 *            训练模型
// 	 * @param maxIter
// 	 *            最大训练次数
// 	 */
// 	public LBFGS(BaseModel model, int maxIter) {
// 
// 		this(model);
// 		this.maxIter = maxIter;
// 	}
// 
// 	@Override
// 	public FloatMatrix train() {
// 
// 		model.compute(theta, 3);
// 		float cost0 = model.getCost();// 初始cost
// 		FloatMatrix gk = model.getGradient();// 初始梯度
// 
// 		float cost1, lamda;// lamda:一维搜索步长
// 		FloatMatrix d, sk, yk, gk1;// dk,sk,xk+1,gk
// 
// 		if (logFlag)
// 			logger.debug("迭代次数 \t\t步长 \t\t    cost");
// 
// 		int l, m = 3;// limit
// 		float alpha, beta;
// 		FloatMatrix ql;
// 		LinkedList<FloatMatrix> sl = new LinkedList<FloatMatrix>();
// 		LinkedList<FloatMatrix> yl = new LinkedList<FloatMatrix>();
// 		LinkedList<Float> pl = new LinkedList<Float>();
// 		Float[] alphal = new Float[m];
// 
// 		for (int k = 0; k < maxIter; k++) {
// 
// 			l = k <= m ? k : m;
// 			ql = gk;
// 
// 			for (int i = l - 1; i >= 0; i--) {
// 				alpha = sl.get(i).transpose().mmul(ql).mul(pl.get(i)).get(0);
// 				ql = ql.sub(yl.get(i).mul(alpha));
// 				alphal[i] = alpha;
// 			}
// 
// 			d = ql;
// 			for (int i = 0; i < l; i++) {
// 				beta = yl.get(i).transpose().mmul(d).mul(pl.get(i)).get(0);
// 				d = sl.get(i).mul(alphal[i] - beta).add(d);
// 			}
// 
// 			d = d.neg();
// 			lamda = Wolfe.lineSearch(model, theta, d);
// 			sk = d.mul(lamda);
// 			theta = theta.add(sk);
// 
// 			model.compute(theta, 3);
// 			cost1 = model.getCost();
// 			gk1 = model.getGradient();
// 
// 			if (logFlag) {
// 				logger.debug("  {} \t   {}   \t {}", new Object[] { k + 1, cost0 - cost1, cost1 });
// 			}
// 
// 			if (gk1.transpose().mmul(gk1).get(0) < epsilon) {
// 				logger.info("\n已达到梯度精度阈值.\n");
// 				break;
// 			}
// 
// 			if (cost0 - cost1 < epsilon) {
// 				logger.info("\n已达到cost精度阈值.\n");
// 				break;
// 			}
// 
// 			yk = gk1.sub(gk);
// 
// 			yl.add(yk);
// 			if (yl.size() > m)
// 				yl.removeFirst();
// 
// 			sl.add(sk);
// 			if (sl.size() > m)
// 				sl.removeFirst();
// 
// 			pl.add(1f / yk.transpose().mmul(sk).get(0));
// 			if (pl.size() > m)
// 				pl.removeFirst();
// 
// 			gk = gk1;
// 			cost0 = cost1;
// 		}
// 
// 		return theta;
// 	}
// }
// 
// Path: core/src/main/java/net/xsoftlab/ml4j/minfunc/MinFunc.java
// public abstract class MinFunc {
// 
// 	protected BaseModel model;// 训练模型
// 	protected int maxIter = 500;// 最大训练次数
// 	protected float epsilon = (float) 1e-6;// 精度阈值
// 
// 	protected FloatMatrix theta;// 参数
// 	protected boolean logFlag = true;// 是否打印过程日志
// 
// 	Logger logger = LoggerFactory.getLogger(this.getClass());
// 
// 	/**
// 	 * 计算最优化theta
// 	 * 
// 	 * @return theta
// 	 */
// 	public abstract FloatMatrix train();
// 
// 	public void setEpsilon(float epsilon) {
// 		this.epsilon = epsilon;
// 	}
// 
// 	public void setTheta(FloatMatrix theta) {
// 		this.theta = theta;
// 	}
// 
// 	public void setCostFlag(boolean costFlag) {
// 		this.logFlag = costFlag;
// 	}
// }


// Path: core/src/main/java/net/xsoftlab/ml4j/model/supervised/BaseModel.java
import net.xsoftlab.ml4j.minfunc.LBFGS;
import net.xsoftlab.ml4j.minfunc.MinFunc;
import org.jblas.FloatMatrix;

package net.xsoftlab.ml4j.model.supervised;



/**
 * 模型接口
 * 
 * @author 王彦超
 *
 */
public abstract class BaseModel {

	protected FloatMatrix x;// 特征矩阵
	protected FloatMatrix y;// 标签
	protected float lambda = 0f;// 正则化系数

	protected int m;// 样本数量