/*
 * Copyright 2011-2013 JOptimizer
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
package com.joptimizer.functions;

import cern.colt.matrix.DoubleFactory1D;
import cern.colt.matrix.DoubleFactory2D;
import cern.colt.matrix.DoubleMatrix1D;
import cern.colt.matrix.DoubleMatrix2D;
import cern.colt.matrix.linalg.Algebra;
import cern.colt.matrix.linalg.Property;

/**
 * 1/2 x.P.x + q.x + r
 * 
 * @author alberto trivellato (alberto.trivellato@gmail.com)
 */
public class QuadraticMultivariateRealFunction implements ConvexMultivariateRealFunction {

	/**
	 * Dimension of the function argument.
	 */
	protected int dim = -1;

	/**
	 * Quadratic factor.
	 */
	protected DoubleMatrix2D P = null;

	/**
	 * Linear factor.
	 */
	protected DoubleMatrix1D q = null;

	/**
	 * Constant factor.
	 */
	protected double r = 0;
	
	private Algebra ALG = Algebra.DEFAULT;

	public QuadraticMultivariateRealFunction(double[][] PMatrix, double[] qVector, double r) {
		
		this.P = (PMatrix!=null)? DoubleFactory2D.dense.make(PMatrix) : null;
		this.q = (qVector!=null)? DoubleFactory1D.dense.make(qVector) : null;
		this.r = r;
		
		if(P==null && q==null){
			throw new IllegalArgumentException("Impossible to create the function");
		}
		if (P != null && !Property.DEFAULT.isSquare(P)) {
			throw new IllegalArgumentException("Not quadratic argument");
		}
		
		this.dim = (P != null)? P.columns() : q.size();
		if (this.dim < 0) {
			throw new IllegalArgumentException("Impossible to create the function");
		}
	}

	public final double value(double[] X) {
		DoubleMatrix1D x = DoubleFactory1D.dense.make(X);
		double ret = r;
		if (P != null) {
			ret += 0.5 * ALG.mult(x, ALG.mult(P, x));
		}
		if (q != null) {
			ret += ALG.mult(q, x);
		}
		return ret;
	}

	public final double[] gradient(double[] X) {
		DoubleMatrix1D x = DoubleFactory1D.dense.make(X);
		DoubleMatrix1D ret = null;
		if(P!=null){
			if (q != null) {
				ret = P.zMult(x, q.copy(), 1, 1, false);
			} else {
				ret = ALG.mult(P, x);
			}
		}else{
			ret = q.copy();
		}
		return ret.toArray();
		
	}

	public final double[][] hessian(double[] X) {
		DoubleMatrix2D ret = null;
		if(P!=null){
			ret = P.copy();
		}else{
			//ret = DoubleFactory2D.dense.make(dim, dim);
			return FunctionsUtils.ZEROES_2D_ARRAY_PLACEHOLDER;
		}
		return ret.toArray();
	}

	public DoubleMatrix2D getP() {
		return P;
	}

	public DoubleMatrix1D getQ() {
		return q;
	}

	public double getR() {
		return r;
	}

	public int getDim() {
		return this.dim;
	}

}

 

Ads help maintain this website.