예제 #1
0
파일: gonum.go 프로젝트: rmera/gochem
//gnEigen wraps the matrix.DenseMatrix.Eigen() function in order to guarantee
//That the eigenvectors and eigenvalues are sorted according to the eigenvalues
//It also guarantees orthonormality and handness. I don't know how many of
//these are already guaranteed by Eig(). Will delete the unneeded parts
//And even this whole function when sure. The main reason for this function
//Is the compatibiliy with go.matrix. This function should dissapear when we
//have a pure Go blas.
func EigenWrap(in *Matrix, epsilon float64) (*Matrix, []float64, error) {
	if epsilon < 0 {
		epsilon = appzero
	}
	efacs := mat64.Eigen(mat64.DenseCopyOf(in.Dense), epsilon)
	evecsprev := &Matrix{efacs.V}
	evalsmat := efacs.D()
	d, _ := evalsmat.Dims()
	evals := make([]float64, d, d)
	for k, _ := range evals {
		evals[k] = evalsmat.At(k, k)
	}
	evecs := Zeros(3)
	fn := func() { evecs.Copy(evecsprev.T()) }
	err := mat64.Maybe(fn)
	if err != nil {
		return nil, nil, Error{err.Error(), []string{"mat64.Copy/math64.T", "EigenWrap"}, true}

	}
	//evecs.TCopy(evecs.Dense)
	eig := eigenpair{evecs, evals[:]}
	sort.Sort(eig)
	//Here I should orthonormalize vectors if needed instead of just complaining.
	//I think orthonormality is guaranteed by  DenseMatrix.Eig() If it is, Ill delete all this
	//If not I'll add ortonormalization routines.
	eigrows, _ := eig.evecs.Dims()
	for i := 0; i < eigrows; i++ {
		vectori := eig.evecs.VecView(i)
		for j := i + 1; j < eigrows; j++ {
			vectorj := eig.evecs.VecView(j)
			if math.Abs(vectori.Dot(vectorj)) > epsilon && i != j {
				reterr := Error{fmt.Sprintln("Eigenvectors ", i, "and", j, " not orthogonal. v", i, ":", vectori, "\nv", j, ":", vectorj, "\nDot:", math.Abs(vectori.Dot(vectorj)), "eigmatrix:", eig.evecs), []string{"EigenWrap"}, true}
				return eig.evecs, evals[:], reterr
			}
		}
		if math.Abs(vectori.Norm(0)-1) > epsilon {
			//Of course I could just normalize the vectors instead of complaining.
			//err= fmt.Errorf("Vectors not normalized %s",err.Error())

		}
	}
	//Checking and fixing the handness of the matrix.This if-else is Jannes idea,
	//I don't really know whether it works.
	//	eig.evecs.TCopy(eig.evecs)
	if det(eig.evecs) < 0 { //Right now, this will fail if the matrix is not 3x3 (30/10/2013)
		eig.evecs.Scale(-1, eig.evecs) //SSC
	} else {
		/*
			eig.evecs.TransposeInPlace()
			eig.evecs.ScaleRow(0,-1)
			eig.evecs.ScaleRow(2,-1)
			eig.evecs.TransposeInPlace()
		*/
	}
	//	eig.evecs.TCopy(eig.evecs)
	return eig.evecs, eig.evals, nil //Returns a slice of evals
}
예제 #2
0
파일: cmaes.go 프로젝트: jgcarvalho/zdd
// erro no ask -> não devo passar loc.X como x
func (c *CMAES) ask() []float64 {

	lenC, _ := c.C.Dims()
	if float64(c.CountEval-c.EigenEval) > float64(c.Lambda)/(c.C1+c.Cmu)/float64(lenC)/10.0 {

		c.EigenEval = c.CountEval

		c.C.Add(c.C, c.C.T())
		c.C.Scale(0.5, c.C)

		eig := mat64.Eigen(c.C, 0.000001)
		// fmt.Println("here")
		c.D = eig.D()
		c.B = eig.V
		// fmt.Println("# Entrou no loop")
		// fmt.Println("# ask c.B", c.B)
		// fmt.Println("# ask c.D", c.D)
		// fmt.Println("# ask c.C", c.C)
		// fmt.Println("# ask c.InvSqrtC", c.InvSqrtC)
		// fmt.Println("# here")
		for i := 0; i < c.N; i++ {
			if c.D.At(i, i) < 0 {
				c.D.Set(i, i, -1*math.Sqrt(-1*c.D.At(i, i)))
			} else {
				c.D.Set(i, i, math.Sqrt(c.D.At(i, i)))
			}

		}
		c.InvSqrtC.Inverse(c.D)
		c.InvSqrtC.Mul(c.B, c.InvSqrtC)
		c.InvSqrtC.Mul(c.InvSqrtC, c.B.T())
		// fmt.Println("Entrou no loop")
		// fmt.Println("ask c.B", c.B)
		// fmt.Println("ask c.D", c.D)
		// fmt.Println("ask c.C", c.C)
		// fmt.Println("ask c.InvSqrtC", c.InvSqrtC)
	}
	randn := make([]float64, c.N)
	for i := 0; i < c.N; i++ {
		randn[i] = c.D.At(i, i) * rand.NormFloat64()
	}
	tmp := mat64.NewDense(c.N, 1, randn)
	tmp.Mul(c.B, tmp)
	newL := make([]float64, c.N)
	for i := 0; i < c.N; i++ {
		newL[i] = c.Xmean[i] + c.Sigma*tmp.At(i, 0)
	}

	// fmt.Println("ask tmp", tmp)

	return newL
}
예제 #3
0
func (t Tournament) Ranks() []float64 {
	m := t.Matrix()
	eig := mat64.Eigen(m, 1e-10)
	_, c := eig.V.Dims()
	var ranks []float64
	for i := 0; i < c; i++ {
		ranks = eig.V.Col(nil, i)
		sense := math.Copysign(1, ranks[0])
		for _, val := range ranks {
			if sense == 0 {
				sense = math.Copysign(1, val)
			}
			if val*sense < 0 {
				ranks = nil
				break
			}
		}

		if ranks != nil {
			min := 1e100
			max := 0.0
			for i := range ranks {
				col := t.Matrix().Col(nil, i)
				row := t.Matrix().Row(nil, i)
				tot := 0.0
				for j := range col {
					tot += col[j] + row[j]
				}
				ranks[i] = ranks[i] * sense / tot // normalize to # games
				min = math.Min(ranks[i], min)
				max = math.Max(ranks[i], max)
			}

			// uncomment this to make min score = 0 and max score = 1
			//for i := range ranks {
			//	ranks[i] = (ranks[i] - min) / (max - min)
			//}
			break
		}
	}

	return ranks
}
예제 #4
0
func main() {
	flag.Parse()
	log.SetFlags(0)

	var tourn Tournament

	if *demo {
		tourn = Tournament{
			{"bob-r", "joe-c"},
			{"bob-r", "tim-c"},
			{"bob-r", "tim-c"},
			{"bob-r", "tim-c"},
			{"joe-r", "tim-c"},
			{"joe-r", "bob-c"},
			{"tim-r", "joe-c"},
			{"tim-r", "bob-c"},
			{"bob-c", "joe-r"},
			{"bob-c", "tim-r"},
			{"joe-c", "tim-r"},
			{"joe-c", "bob-r"},
			{"tim-c", "joe-r"},
			{"tim-c", "bob-r"},
		}
	} else {
		matches, err := ParseMatches(os.Stdin)
		if err != nil {
			log.Fatal(err)
		}
		tourn = Tournament(matches)
	}

	if *graph {
		tourn.Graph(os.Stdout)
		return
	} else if *matrix {
		prefix := "tournmat = "
		fmt.Printf("%v%v\n", prefix, mat64.Formatted(tourn.Matrix(), mat64.Prefix(strings.Repeat(" ", len(prefix)))))
		return
	} else if *eigvect {
		eig := mat64.Eigen(tourn.Matrix(), 1e-10)
		prefix := "eigvects = "
		fmt.Printf("%v%.4v\n", prefix, mat64.Formatted(eig.V, mat64.Prefix(strings.Repeat(" ", len(prefix)))))
		return
	} else if *eigval {
		eig := mat64.Eigen(tourn.Matrix(), 1e-10)
		prefix := "eigvals = "
		fmt.Printf("%v%.4v\n", prefix, mat64.Formatted(eig.D(), mat64.Prefix(strings.Repeat(" ", len(prefix)))))
		return
	}

	ranks := tourn.Ranks()
	if ranks == nil {
		log.Fatalf("no valid eigenvector ranking found")
	}

	players := tourn.Players()
	for i, rank := range ranks {
		fmt.Printf("%v\t%.2v\n", players[i], rank)
	}

}