func NewMultiTaskLasso() *MultiTaskLasso {
	m := NewMultiTaskElasticNet()
	m.L1Ratio = 1.
	return m
}
NewMultiTaskLasso creates a *RegularizedRegression with Alpha=1 and L1Ratio=1
package linearmodel
import (
	"math"
	"strings"
	"sync"
	"github.com/pa-m/sklearn/base"
	"gonum.org/v1/gonum/mat"
)
type CDResult struct {
	Gap, Eps float64
	NIter    int
}
type ElasticNet struct {
	LinearRegression
	Tol, Alpha, L1Ratio float64
	MaxIter             int
	Selection           string
	WarmStart, Positive bool
	CDResult            CDResult
}
type Lasso = ElasticNet
type MultiTaskElasticNet = Lasso
type MultiTaskLasso = Lasso
func (*ElasticNet) IsClassifier() bool { return false }
func (regr *ElasticNet) PredicterClone() base.Predicter {
	clone := *regr
	return &clone
}
func (regr *ElasticNet) GetNOutputs() int {
	_, nOutputs := regr.Coef.Dims()
	return nOutputs
}
func (regr *ElasticNet) Fit(Xmatrix, Ymatrix mat.Matrix) base.Fiter {
	X0, Y0 := base.ToDense(Xmatrix), base.ToDense(Ymatrix)
	var X, Y, YOffset *mat.Dense
	X, Y, regr.XOffset, YOffset, regr.XScale = PreprocessData(X0, Y0, regr.FitIntercept, regr.Normalize, nil)
	NSamples, NFeatures := X.Dims()
	_, NOutputs := Y.Dims()
	l1reg := regr.Alpha * regr.L1Ratio * float64(NSamples)
	l2reg := regr.Alpha * (1. - regr.L1Ratio) * float64(NSamples)
	if !regr.WarmStart {
		regr.Coef = mat.NewDense(NFeatures, NOutputs, nil)
	}
	random := strings.EqualFold("random", regr.Selection)
	if NOutputs == 1 {
		y := &mat.VecDense{}
		w := &mat.VecDense{}
		w.ColViewOf(regr.Coef, 0)
		y.ColViewOf(Y, 0)
		regr.CDResult = *enetCoordinateDescent(w, l1reg, l2reg, X, y, regr.MaxIter, regr.Tol, nil, random, regr.Positive)
	} else {
		regr.CDResult = *enetCoordinateDescentMultiTask(regr.Coef, l1reg, l2reg, X, Y, regr.MaxIter, regr.Tol, nil, random, regr.Positive)
	}
	regr.LinearModel.setIntercept(regr.XOffset, YOffset, regr.XScale)
	return regr
}
func NewElasticNet() *ElasticNet {
	return NewMultiTaskElasticNet()
}
func NewMultiTaskElasticNet() *MultiTaskElasticNet {
	regr := &ElasticNet{}
	regr.FitIntercept = true
	regr.Tol = 1e-4
	regr.Alpha = 1.
	regr.L1Ratio = .5
	regr.MaxIter = 1000
	regr.Selection = "cyclic"
	return regr
}
func NewLasso() *Lasso {
	m := NewMultiTaskElasticNet()
	m.L1Ratio = 1.
	return m
}