<commit_before>/*
 * matrix.go, part of gochem.
 * 
 * 
 * Copyright 2012 <NAME> <rmera{at}chemDOThelsinkiDOTfi>
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as 
 * published by the Free Software Foundation; either version 2.1 of the 
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General 
 * Public License along with this program.  If not, see 
 * <http://www.gnu.org/licenses/>.
 * 
 * 
 * Gochem is developed at the laboratory for instruction in Swedish, Department of Chemistry,
 * University of Helsinki, Finland.  
 * 
 * 
 */
/***Dedicated to the long life of the Ven. <NAME>***/

	
package chem



import "github.com/skelterjohn/go.matrix"
import "math"
import "fmt"

//These ones are basic math, belonging more to the go.matrix package
//If there is something similar already made
//in go.matrix this functions will be deleted. Otherwise they could be
//made methods for DenseMatrix and included in go.matrix

//Some of this functions don't return error messages because they are meant to
//Be inserted in mathematical expressions and thus they need to return only one value.

/*SetRows replaces the coordinates of atoms in the positions given by atomlist with the coordinates
in newcoords (in order) If atomlist contains a single element, it replaces as many coordinates
as given in newcoords, starting 
at the element in atomlist. In the latter case, the function checks that there are enough coordinates to
replace and panics if not. */
func SetRows(target, newcoords *matrix.DenseMatrix, atomlist []int) *matrix.DenseMatrix{
	//If supplies a list with one number, the newcoords will replace the old coords
	//Starting that number. We do check that you don't put more coords than spaces we have.
	returned:=target.Copy()
	if len(atomlist)==1{
		if newcoords.Rows()>target.Rows()-atomlist[0]-1{
			panic(fmt.Sprintf("Cant replace starting from position %d: Not enough atoms in molecule", atomlist[0]))
			} 
		returned.SetMatrix(atomlist[0],0,newcoords)
		return returned
		}
	//If the list has more than one atom
	lenatoms:=target.Rows()	
	for k,j:=range(atomlist){
		if j>lenatoms-1{
			panic(fmt.Sprintf("Requested position number: %d (%d) out of range",k,j))
			}
		returned.SetMatrix(j,0,newcoords.GetRowVector(k))
		}
	return returned
	}
	



//Somerows, given a list of ints and the desired frame, returns an slice matrix.DenseMatrix
//containing the coordinates of the atoms with the corresponding index.
//This function returns a copy, not a reference, so changes to the returned matrix
//don't alter the original. It check for correctness of the frame and the
//Atoms requested.
func SomeRows(M *matrix.DenseMatrix, clist []int) (*matrix.DenseMatrix){
	rows:=M.Rows()
	ret:=make([][]float64,0,len(clist))
	for k,j:=range(clist){
		if j>rows-1{
			panic(fmt.Sprintf("Coordinate requested (Number: %d, value: %d) out of range!",k,j))
			}
		tmp:=M.GetRowVector(j).Array()
		if len(tmp)!=3{
			panic(fmt.Sprintf("Coordinate %d has %d components instead of 3",k, len(tmp)))
			}
		ret=append(ret,tmp)
		}
	return matrix.MakeDenseMatrixStacked(ret)
	}
	
//SafeSomeRows, given a list of ints and the desired frame, returns an slice matrix.DenseMatrix
//containing the coordinates of the atoms with the corresponding index.
//This function returns a copy, not a reference, so changes to the returned matrix
//don't alter the original. It check for correctness of the frame and the
//Atoms requested. Unlike SomeRow, which panics in these cases, SafeSomeRows returns an error. if problems,
//or nil.
func SafeSomeRows(M *matrix.DenseMatrix, clist []int) (*matrix.DenseMatrix, error){
	rows:=M.Rows()
	ret:=make([][]float64,0,len(clist))
	for k,j:=range(clist){
		if j>rows-1{
			return nil, fmt.Errorf("Coordinate requested (Number: %d, value: %d) out of range!",k,j)
			}
		tmp:=M.GetRowVector(j).Array()
		if len(tmp)!=3{
			return nil, fmt.Errorf("Coordinate %d has %d components instead of 3",k, len(tmp))
			}
		ret=append(ret,tmp)
		}
	return matrix.MakeDenseMatrixStacked(ret)
	}	
	
//Unitarize takes a vector and divides it by its norm
//thus obtaining an unitary vector pointing in the same direction as 
//vector.
func Unitarize(vector *matrix.DenseMatrix) *matrix.DenseMatrix{
	norm:=vector.TwoNorm()
	norm=1.0/norm
	F:=vector.Copy()
	F.Scale(norm)
	return F
	}

//AddRow adds the row vector row to each row of the matrix big, in place. Both need the same ammount of columns.
func AddRow(big,row *matrix.DenseMatrix)(error){
	bigrows:=big.Rows()
	if big.Cols() != row.Cols() || row.Rows()!=1{
		return fmt.Errorf("Ill-formed matrices for multiplication")
		}
	for i:=0;i<bigrows;i++{
		j:=big.GetRowVector(i)
		j.Add(row)
		}
	return nil
	}

//SubRow substract the row bector row from each row of the matrix big, in place. Bothe ned the same ammount 
//of coulmn. This is not an efficient function since it contains two function calls, one to the DenseMatrix
//method Scale() and other to the function AddRow().
func SubRow(big,row *matrix.DenseMatrix)(error){
	row2:=row.Copy()<commit_msg>bugfix<commit_after>/*
 * matrix.go, part of gochem.
 * 
 * 
 * Copyright 2012 <NAME> <rmera{at}chemDOThelsinkiDOTfi>
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as 
 * published by the Free Software Foundation; either version 2.1 of the 
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General 
 * Public License along with this program.  If not, see 
 * <http://www.gnu.org/licenses/>.
 * 
 * 
 * Gochem is developed at the laboratory for instruction in Swedish, Department of Chemistry,
 * University of Helsinki, Finland.  
 * 
 * 
 */
/***Dedicated to the long life of the Ven. <NAME> <NAME>***/

	
package chem



import "github.com/skelterjohn/go.matrix"
import "math"
import "fmt"

//These ones are basic math, belonging more to the go.matrix package
//If there is something similar already made
//in go.matrix this functions will be deleted. Otherwise they could be
//made methods for DenseMatrix and included in go.matrix

//Some of this functions don't return error messages because they are meant to
//Be inserted in mathematical expressions and thus they need to return only one value.

/*SetRows replaces the coordinates of atoms in the positions given by atomlist with the coordinates
in newcoords (in order) If atomlist contains a single element, it replaces as many coordinates
as given in newcoords, starting 
at the element in atomlist. In the latter case, the function checks that there are enough coordinates to
replace and panics if not. */
func SetRows(target, newcoords *matrix.DenseMatrix, atomlist []int) *matrix.DenseMatrix{
	//If supplies a list with one number, the newcoords will replace the old coords
	//Starting that number. We do check that you don't put more coords than spaces we have.
	returned:=target.Copy()
	if len(atomlist)==1{
		if newcoords.Rows()>target.Rows()-atomlist[0]-1{
			panic(fmt.Sprintf("Cant replace starting from position %d: Not enough atoms in molecule", atomlist[0]))
			} 
		returned.SetMatrix(atomlist[0],0,newcoords)
		return returned
		}
	//If the list has more than one atom
	lenatoms:=target.Rows()	
	for k,j:=range(atomlist){
		if j>lenatoms-1{
			panic(fmt.Sprintf("Requested position number: %d (%d) out of range",k,j))
			}
		returned.SetMatrix(j,0,newcoords.GetRowVector(k))
		}
	return returned
	}
	



//Somerows, given a list of ints and the desired frame, returns an slice matrix.DenseMatrix
//containing the coordinates of the atoms with the corresponding index.
//This function returns a copy, not a reference, so changes to the returned matrix
//don't alter the original. It check for correctness of the frame and the
//Atoms requested.
func SomeRows(M *matrix.DenseMatrix, clist []int) (*matrix.DenseMatrix){
	rows:=M.Rows()
	ret:=make([][]float64,0,len(clist))
	for k,j:=range(clist){
		if j>rows-1{
			panic(fmt.Sprintf("Coordinate requested (Number: %d, value: %d) out of range!",k,j))
			}
		tmp:=M.GetRowVector(j).Array()
		if len(tmp)!=3{
			panic(fmt.Sprintf("Coordinate %d has %d components instead of 3",k, len(tmp)))
			}
		ret=append(ret,tmp)
		}
	return matrix.MakeDenseMatrixStacked(ret)
	}
	
//SafeSomeRows, given a list of ints and the desired frame, returns an slice matrix.DenseMatrix
//containing the coordinates of the atoms with the corresponding index.
//This function returns a copy, not a reference, so changes to the returned matrix
//don't alter the original. It check for correctness of the frame and the
//Atoms requested. Unlike SomeRow, which panics in these cases, SafeSomeRows returns an error. if problems,
//or nil.
func SafeSomeRows(M *matrix.DenseMatrix, clist []int) (*matrix.DenseMatrix, error){
	rows:=M.Rows()
	ret:=make([][]float64,0,len(clist))
	for k,j:=range(clist){
		if j>rows-1{
			return nil, fmt.Errorf("Coordinate requested (Number: %d, value: %d) out of range!",k,j)
			}
		tmp:=M.GetRowVector(j).Array()
		if len(tmp)!=3{
			return nil, fmt.Errorf("Coordinate %d has %d components instead of 3",k, len(tmp))
			}
		ret=append(ret,tmp)
		}
	return matrix.MakeDenseMatrixStacked(ret), nil
	}	
	
//Unitarize takes a vector and divides it by its norm
//thus obtaining an unitary vector pointing in the same direction as 
//vector.
func Unitarize(vector *matrix.DenseMatrix) *matrix.DenseMatrix{
	norm:=vector.TwoNorm()
	norm=1.0/norm
	F:=vector.Copy()
	F.Scale(norm)
	return F
	}

//AddRow adds the row vector row to each row of the matrix big, in place. Both need the same ammount of columns.
func AddRow(big,row *matrix.DenseMatrix)(error){
	bigrows:=big.Rows()
	if big.Cols() != row.Cols() || row.Rows()!=1{
		return fmt.Errorf("Ill-formed matrices for multiplication")
		}
	for i:=0;i<bigrows;i++{
		j:=big.GetRowVector(i)
		j.Add(row)
		}
	return nil
	}

//SubRow substract the row bector row from each row of the matrix big, in place. Bothe ned the same ammount 
//of coulmn. This is not an efficient function since it contains two function calls, one to the DenseMatrix
//method Scale() and other to the function AddRow().
func SubRow(big,row *matrix.DenseMatrix)(error){
	row2:=row.Copy()
{'fraction_non_alphanumeric': 0.10504472931845431, 'fraction_numerical': 0.005717974730240708, 'mean_word_length': 4.181079789775442, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6755888', 'n_tokens_mistral': 3530, 'n_tokens_neox': 3289, 'n_words': 1337}