Esempio n. 1
0
func (m *Matrix) AggregateProcedure(aggr Float64Float64Func, f Float64Func, cond Float64Procedure) float64 {
	if m.Size() == 0 {
		return math.NaN()
	}
	var a float64
	n := runtime.GOMAXPROCS(-1)
	if n > 1 && m.Rows()*m.Columns() > common.MatrixThreshold {
		n = common.Min(n, m.Rows())
		ch := make(chan float64, n)
		k := m.Rows() / n
		var idx0, idx1 int
		for j := 0; j < n; j++ {
			idx0 = j * k
			if j == n-1 {
				idx1 = m.Rows()
			} else {
				idx1 = idx0 + k
			}
			go func() {
				elem := m.GetQuick(idx0, 0)
				b := 0
				if cond(elem) {
					b = aggr(b, f(elem))
				}
				d := 1
				for r := idx0; r < idx1; r++ {
					for c := d; c < m.Columns(); c++ {
						elem = m.GetQuick(r, c)
						if cond(elem) {
							b = aggr(b, f(elem))
						}
					}
					d = 0
				}
				ch <- b
			}()
		}
		a = <-ch
		for j := 1; j < n; j++ {
			a = aggr(a, <-ch)
		}
	} else {
		a := 0.0
		elem := m.GetQuick(0, 0)
		if cond(elem) {
			a = aggr(a, f(elem))
		}
		d := 1 // First cell already done.
		for r := 0; r < m.Rows(); r++ {
			for c := d; c < m.Columns(); c++ {
				elem = m.GetQuick(r, c)
				if cond(elem) {
					a = aggr(a, f(elem))
				}
			}
			d = 0
		}
	}
	return a
}
Esempio n. 2
0
func (m *Matrix) AssignFunc(f Float64Func) *Matrix {
	n := runtime.GOMAXPROCS(-1)
	if n > 1 && m.Rows()*m.Columns() > common.MatrixThreshold {
		n = common.Min(n, m.Rows())
		done := make(chan bool, n)
		k := m.Rows() / n
		var idx0, idx1 int
		for j := 0; j < n; j++ {
			idx0 = j * k
			if j == n-1 {
				idx1 = m.Rows()
			} else {
				idx1 = idx0 + k
			}
			go func() {
				for r := idx0; r < idx1; r++ {
					for c := 0; c < m.Columns(); c++ {
						m.SetQuick(r, c, f(m.GetQuick(r, c)))
					}
				}
				done <- true
			}()
		}
		for j := 0; j < n; j++ {
			<-done
		}
	} else {
		for r := 0; r < m.Rows(); r++ {
			for c := 0; c < m.Columns(); c++ {
				m.SetQuick(r, c, f(m.GetQuick(r, c)))
			}
		}
	}
	return m
}
Esempio n. 3
0
// Sets all cells to the state specified by "values". "values"
// is required to have the same number of cells as the receiver.
//
// The values are copied. So subsequent changes in "values" are not
// reflected in the matrix, and vice-versa.
func (v *Vector) AssignArray(values []float64) (*Vector, error) {
	if len(values) != v.Size() {
		return v, fmt.Errorf("Must have same number of cells: length=%d size()=%d",
			len(values), v.Size())
	}
	n := runtime.GOMAXPROCS(-1)
	if n > 1 && v.Size() > common.VectorThreshold {
		n = common.Min(n, v.Size())
		done := make(chan bool, n)
		k := v.Size() / n
		var idx0, idx1 int
		for j := 0; j < n; j++ {
			idx0 = j * k
			if j == n-1 {
				idx1 = v.Size()
			} else {
				idx1 = idx0 + k
			}
			go func() {
				for i := idx0; i < idx1; i++ {
					v.SetQuick(i, values[i])
				}
				done <- true
			}()
		}
		for j := 0; j < n; j++ {
			<-done
		}
	} else {
		for i, val := range values {
			v.SetQuick(i, val)
		}
	}
	return v, nil
}
Esempio n. 4
0
// Assigns the result of a function to each cell; x[i] = f(x[i]).
func (v *Vector) AssignFunc(f Float64Func) *Vector {
	n := runtime.GOMAXPROCS(-1)
	if n > 1 && v.Size() > common.VectorThreshold {
		n = common.Min(n, v.Size())
		done := make(chan bool, n)
		k := v.Size() / n
		var idx0, idx1 int
		for j := 0; j < n; j++ {
			idx0 = j * k
			if j == n-1 {
				idx1 = v.Size()
			} else {
				idx1 = idx0 + k
			}
			go func() {
				for i := idx0; i < idx1; i++ {
					v.SetQuick(i, f(v.GetQuick(i)))
				}
				done <- true
			}()
		}
		for j := 0; j < n; j++ {
			<-done
		}
	} else {
		for i := 0; i < v.Size(); i++ {
			v.SetQuick(i, f(v.GetQuick(i)))
		}
	}
	return v
}
Esempio n. 5
0
// Fills the cell values into the specified 1-dimensional array.
// The values are copied. So subsequent changes in <tt>values</tt> are not
// reflected in the matrix, and vice-versa. The returned array
// values has the form:
//     for i:=0; i < Size; i++ {values[i] = Get(i)}
func (v *Vector) FillArray(values []float64) error {
	if len(values) < v.Size() {
		return fmt.Errorf("values too small")
	}
	n := runtime.GOMAXPROCS(-1)
	if n > 1 && v.Size() > common.VectorThreshold {
		n = common.Min(n, v.Size())
		done := make(chan bool, n)
		k := v.Size() / n
		var idx0, idx1 int
		for j := 0; j < n; j++ {
			idx0 = j * k
			if j == n-1 {
				idx1 = v.Size()
			} else {
				idx1 = idx0 + k
			}
			go func() {
				for i := idx0; i < idx1; i++ {
					values[i] = v.GetQuick(i)
				}
				done <- true
			}()
		}
		for j := 0; j < n; j++ {
			<-done
		}
	} else {
		for i := 0; i < v.Size(); i++ {
			values[i] = v.GetQuick(i)
		}
	}
	return nil
}
Esempio n. 6
0
// Return the minimum value of this matrix together with its location.
func (v *Vector) MinLocation() (float64, int) {
	var location int
	var minValue float64
	n := runtime.GOMAXPROCS(-1)
	if n > 1 && v.Size() > common.VectorThreshold {
		n = common.Min(n, v.Size())
		c := make(chan vectorElement, n)
		k := v.Size() / n
		var idx0, idx1 int
		for j := 0; j < n; j++ {
			idx0 = j * k
			if j == n-1 {
				idx1 = v.Size()
			} else {
				idx1 = idx0 + k
			}
			go func() {
				loc := idx0
				min := v.GetQuick(loc)
				for i := idx0 + 1; i < idx1; i++ {
					elem := v.GetQuick(i)
					if min > elem {
						min = elem
						loc = i
					}
				}
				c <- vectorElement{min, loc}
			}()
		}
		vl0 := <-c
		minValue = vl0.value
		location = vl0.location
		for j := 1; j < n; j++ {
			vl := <-c
			if minValue > vl.value {
				minValue = vl.value
				location = vl.location
			}
		}
	} else {
		location = 0
		minValue = v.GetQuick(location)
		for i := 1; i < v.Size(); i++ {
			elem := v.GetQuick(i)
			if minValue > elem {
				minValue = elem
				location = i
			}
		}
	}
	return minValue, location
}
Esempio n. 7
0
// Returns the dot product of two vectors x and y, which is
// Sum(x[i]*y[i]). Where x == this. Operates on cells at
// indexes from .. Min(Size(), y.Size(),from+length)-1.
func (v *Vector) ZDotProductRange(y Vec, from, length int) float64 {
	if from < 0 || length <= 0 {
		return 0
	}

	tail := from + length
	if v.Size() < tail {
		tail = v.Size()
	}
	if y.Size() < tail {
		tail = y.Size()
	}
	length = tail - from

	var sum float64
	n := runtime.GOMAXPROCS(-1)
	if n > 1 && v.Size() > common.VectorThreshold {
		n = common.Min(n, length)
		c := make(chan float64, n)
		k := length / n
		var idx0, idx1 int
		for j := 0; j < n; j++ {
			idx0 = j * k
			if j == n-1 {
				idx1 = length
			} else {
				idx1 = idx0 + k
			}
			go func() {
				s := 0.0
				for i := idx0; i < idx1; i++ {
					idx := k + from
					s += v.GetQuick(idx) * y.GetQuick(idx)
				}
				c <- s
			}()
		}
		sum = <-c
		for j := 1; j < n; j++ {
			sum += <-c
		}
	} else {
		sum = 0.0
		i := tail - 1
		for k := 0; k < length; i-- {
			sum += v.GetQuick(i) * y.GetQuick(i)
			k++
		}
	}
	return sum
}
Esempio n. 8
0
func (m *Matrix) AggregateMatrix(other Mat, aggr Float64Float64Func, f Float64Float64Func) (float64, error) {
	err := m.checkShape(other)
	if err != nil {
		return math.NaN(), err
	}
	if m.Size() == 0 {
		return math.NaN(), nil
	}
	a := 0.0
	n := runtime.GOMAXPROCS(-1)
	if n > 1 && m.Rows()*m.Columns() > common.MatrixThreshold {
		n = common.Min(n, m.Rows())
		ch := make(chan float64, n)
		k := m.Rows() / n
		var idx0, idx1 int
		for j := 0; j < n; j++ {
			idx0 = j * k
			if j == n-1 {
				idx1 = m.Rows()
			} else {
				idx1 = idx0 + k
			}
			go func() {
				a := f(m.GetQuick(idx0, 0), other.GetQuick(idx0, 0))
				d := 1
				for r := idx0; r < idx1; r++ {
					for c := d; c < m.Columns(); c++ {
						a = aggr(a, f(m.GetQuick(r, c), other.GetQuick(r, c)))
					}
					d = 0
				}
				ch <- d
			}()
		}
		a = <-ch
		for j := 1; j < n; j++ {
			a = aggr(a, <-ch)
		}
	} else {
		a := f(m.GetQuick(0, 0), other.GetQuick(0, 0))
		d := 1 // First cell already done.
		for r := 0; r < m.Rows(); r++ {
			for c := d; c < m.Columns(); c++ {
				a = aggr(a, f(m.GetQuick(r, c), other.GetQuick(r, c)))
			}
			d = 0
		}
	}
	return a, nil
}
Esempio n. 9
0
// Applies a function to all cells with a given indexes and aggregates the
// results.
func (v *Vector) AggregateIndexed(aggr Float64Float64Func, f Float64Func, indexList []int) float64 {
	if v.Size() == 0 {
		return math.NaN()
	}
	size := len(indexList)
	var elem float64
	var a float64
	n := runtime.GOMAXPROCS(-1)
	if n > 1 && v.Size() > common.VectorThreshold {
		n = common.Min(n, v.Size())
		c := make(chan float64, n)
		k := v.Size() / n
		var idx0, idx1 int
		for j := 0; j < n; j++ {
			idx0 = j * k
			if j == n-1 {
				idx1 = v.Size()
			} else {
				idx1 = idx0 + k
			}
			go func() {
				var b float64 = f(v.GetQuick(indexList[idx0]))
				var elem float64
				for i := idx0 + 1; i < idx1; i++ {
					elem = v.GetQuick(indexList[i])
					b = aggr(b, f(elem))
				}
				c <- b
			}()
		}
		a = <-c
		for j := 1; j < n; j++ {
			a = aggr(a, <-c)
		}
	} else {
		a = f(v.GetQuick(indexList[0]))
		for i := 1; i < size; i++ {
			elem = v.GetQuick(indexList[i])
			a = aggr(a, f(elem))
		}
	}
	return a
}
Esempio n. 10
0
func (m *Matrix) AggregateProcedureSelection(aggr Float64Float64Func, f Float64Func, rowList, columnList []int) float64 {
	if m.Size() == 0 {
		return math.NaN()
	}
	size := len(rowList)
	var a float64
	n := runtime.GOMAXPROCS(-1)
	if n > 1 && size > common.MatrixThreshold {
		n = common.Min(n, size)
		ch := make(chan float64, n)
		k := size / n
		var idx0, idx1 int
		for j := 0; j < n; j++ {
			idx0 = j * k
			if j == n-1 {
				idx1 = size
			} else {
				idx1 = idx0 + k
			}
			go func() {
				b := f(m.GetQuick(rowList[idx0], columnList[idx0]))
				for i := idx0 + 1; i < idx1; i++ {
					elem := m.GetQuick(rowList[i], columnList[i])
					b = aggr(b, f(elem))
				}
				ch <- b
			}()
		}
		a = <-ch
		for j := 1; j < n; j++ {
			a = aggr(a, <-ch)
		}
	} else {
		a = f(m.GetQuick(rowList[0], columnList[0]))
		for i := 1; i < len(rowList); i++ {
			elem := m.GetQuick(rowList[i], columnList[i])
			a = aggr(a, f(elem))
		}
	}
	return a
}
Esempio n. 11
0
// Applies a function to each corresponding cell of two matrices and
// aggregates the results. Returns a value v such that
// v==a(size()) where
// a(i) == aggr( a(i-1), f(get(i), other.get(i)) ) and terminators
// are a(1) == f(get(0), other.get(0)), a(0)==NaN.
//
// Example:
//
// 	 x = 0 1 2 3
// 	 y = 0 1 2 3
//
// 	 // Sum( x[i]*y[i] )
// 	 x.aggregate(y, Plus, Mult)
// 	 --> 14
//
// 	 // Sum( (x[i]+y[i])^2 )
// 	 x.aggregate(y, Plus, Chain(Square, Plus))
// 	 --> 56
func (v *Vector) AggregateVector(other Vec, aggr, f Float64Float64Func) (float64, error) {
	err := v.checkSize(other)
	if err != nil {
		return math.NaN(), err
	}
	if v.Size() == 0 {
		return math.NaN(), nil
	}
	a := f(v.GetQuick(0), other.GetQuick(0))
	n := runtime.GOMAXPROCS(-1)
	if n > 1 && v.Size() > common.VectorThreshold {
		n = common.Min(n, v.Size())
		c := make(chan float64, n)
		k := v.Size() / n
		var idx0, idx1 int
		for j := 0; j < n; j++ {
			idx0 = j * k
			if j == n-1 {
				idx1 = v.Size()
			} else {
				idx1 = idx0 + k
			}
			go func() {
				b := f(v.GetQuick(idx0), other.GetQuick(idx0))
				for i := idx0 + 1; i < idx1; i++ {
					a = aggr(a, f(v.GetQuick(i), other.GetQuick(i)))
				}
				c <- b
			}()
		}
		for j := 1; j < n; j++ {
			a = aggr(a, <-c)
		}
	} else {
		for i := 1; i < v.Size(); i++ {
			a = aggr(a, f(v.GetQuick(i), other.GetQuick(i)))
		}
	}
	return a, nil
}
Esempio n. 12
0
// Returns the number of cells having non-zero values; ignores tolerance.
func (v *Vector) Cardinality() int {
	var cardinality int
	n := runtime.GOMAXPROCS(-1)
	if n > 1 && v.Size() > common.VectorThreshold {
		n = common.Min(n, v.Size())
		c := make(chan int, n)
		k := v.Size() / n
		var idx0, idx1 int
		for j := 0; j < n; j++ {
			idx0 = j * k
			if j == n-1 {
				idx1 = v.Size()
			} else {
				idx1 = idx0 + k
			}
			go func() {
				card := 0
				for i := idx0; i < idx1; i++ {
					if v.GetQuick(i) != 0.0 {
						card += 1
					}
				}
				c <- card
			}()
		}
		cardinality = <-c
		for j := 1; j < n; j++ {
			cardinality += <-c
		}
	} else {
		cardinality = 0
		for i := 0; i < v.Size(); i++ {
			if v.GetQuick(i) != 0.0 {
				cardinality += 1
			}
		}
	}
	return cardinality
}
Esempio n. 13
0
// Swaps each element v[i] with other[i].
func (v *Vector) Swap(other Vec) error {
	err := v.checkSize(other)
	if err != nil {
		return err
	}
	n := runtime.GOMAXPROCS(-1)
	if n > 1 && v.Size() > common.VectorThreshold {
		n = common.Min(n, v.Size())
		done := make(chan bool, n)
		k := v.Size() / n
		var idx0, idx1 int
		for j := 0; j < n; j++ {
			idx0 = j * k
			if j == n-1 {
				idx1 = v.Size()
			} else {
				idx1 = idx0 + k
			}
			go func() {
				for i := idx0; i < idx1; i++ {
					tmp := v.GetQuick(i)
					v.SetQuick(i, other.GetQuick(i))
					other.SetQuick(i, tmp)
				}
				done <- true
			}()
		}
		for j := 0; j < n; j++ {
			<-done
		}
	} else {
		for i := 0; i < v.Size(); i++ {
			tmp := v.GetQuick(i)
			v.SetQuick(i, other.GetQuick(i))
			other.SetQuick(i, tmp)
		}
	}
	return nil
}
Esempio n. 14
0
// Assigns to each cell the result of a function taking as first argument
// the current cell's value of this matrix, and as second argument the
// current cell's value of "y".
func (v *Vector) AssignVectorFunc(y Vec, f Float64Float64Func) (*Vector, error) {
	if y.Size() != v.Size() {
		return v, fmt.Errorf("Incompatible sizes: %d and %d",
			y.Size(), v.Size())
		//		return v, fmt.Errorf("Incompatible sizes: %s and %s",
		//			v.StringShort(), NewFormatter().VectorShape(y))
	}
	n := runtime.GOMAXPROCS(-1)
	if n > 1 && v.Size() > common.VectorThreshold {
		n = common.Min(n, v.Size())
		done := make(chan bool, n)
		k := v.Size() / n
		var idx0, idx1 int
		for j := 0; j < n; j++ {
			idx0 = j * k
			if j == n-1 {
				idx1 = v.Size()
			} else {
				idx1 = idx0 + k
			}
			go func() {
				for i := idx0; i < idx1; i++ {
					v.SetQuick(i, f(v.GetQuick(i), y.GetQuick(i)))
				}
				done <- true
			}()
		}
		for j := 0; j < n; j++ {
			<-done
		}
	} else {
		// the general case x[i] = f(x[i],y[i])
		for i := 0; i < v.Size(); i++ {
			v.SetQuick(i, f(v.GetQuick(i), y.GetQuick(i)))
		}
	}
	return v, nil
}
Esempio n. 15
0
// Assigns a value to all cells that satisfy a condition.
func (v *Vector) AssignProcedure(cond Float64Procedure, value float64) *Vector {
	n := runtime.GOMAXPROCS(-1)
	if n > 1 && v.Size() > common.VectorThreshold {
		n = common.Min(n, v.Size())
		done := make(chan bool, n)
		k := v.Size() / n
		var idx0, idx1 int
		for j := 0; j < n; j++ {
			idx0 = j * k
			if j == n-1 {
				idx1 = v.Size()
			} else {
				idx1 = idx0 + k
			}
			go func() {
				for i := idx0; i < idx1; i++ {
					elem := v.GetQuick(i)
					if cond(elem) {
						v.SetQuick(i, value)
					}
				}
				done <- true
			}()
		}
		for j := 0; j < n; j++ {
			<-done
		}
	} else {
		for i := 0; i < v.Size(); i++ {
			elem := v.GetQuick(i)
			if cond(elem) {
				v.SetQuick(i, value)
			}
		}
	}
	return v
}
Esempio n. 16
0
// Replaces all cell values of the receiver with the values of another
// matrix. Both matrices must have the same size. If both matrices share
// the same cells (as is the case if they are views derived from the same
// matrix) and intersect in an ambiguous way, then replaces as if
// using an intermediate auxiliary deep copy of "other".
func (v *Vector) AssignVector(other Vec) (*Vector, error) {
	if v.Size() != other.Size() {
		return v, fmt.Errorf("Incompatible sizes: %d and %d",
			v.Size(), other.Size())
		//		return v, fmt.Errorf("Incompatible sizes: %s and %s",
		//			v.StringShort(), NewFormatter().VectorShape(other))
	}
	n := runtime.GOMAXPROCS(-1)
	if n > 1 && v.Size() > common.VectorThreshold {
		n = common.Min(n, v.Size())
		done := make(chan bool, n)
		k := v.Size() / n
		var idx0, idx1 int
		for j := 0; j < n; j++ {
			idx0 = j * k
			if j == n-1 {
				idx1 = v.Size()
			} else {
				idx1 = idx0 + k
			}
			go func() {
				for i := idx0; i < idx1; i++ {
					v.SetQuick(i, other.GetQuick(i))
				}
				done <- true
			}()
		}
		for j := 0; j < n; j++ {
			<-done
		}
	} else {
		for i := 0; i < v.Size(); i++ {
			v.SetQuick(i, other.GetQuick(i))
		}
	}
	return v, nil
}
Esempio n. 17
0
// Applies a function to each cell and aggregates the results. Returns a
// value v such that v==a(size()) where
// a(i) == aggr( a(i-1), f(get(i)) ) and terminators are
// a(1) == f(get(0)), a(0)==NaN.
//
// Example:
//
// 	 matrix = 0 1 2 3
//
// 	 // Sum( x[i]*x[i] )
// 	 matrix.Aggregate(Plus, Square)
// 	 --> 14
func (v *Vector) Aggregate(aggr Float64Float64Func, f Float64Func) float64 {
	if v.Size() == 0 {
		return math.NaN()
	}
	a := f(v.GetQuick(0))
	n := runtime.GOMAXPROCS(-1)
	if n > 1 && v.Size() > common.VectorThreshold {
		n = common.Min(n, v.Size())
		c := make(chan float64, n)
		k := v.Size() / n
		var idx0, idx1 int
		for j := 0; j < n; j++ {
			idx0 = j * k
			if j == n-1 {
				idx1 = v.Size()
			} else {
				idx1 = idx0 + k
			}
			go func() {
				var b float64
				for i := idx0 + 1; i < idx1; i++ {
					b = aggr(b, f(v.GetQuick(i)))
				}
				c <- b
			}()
		}
		for j := 1; j < n; j++ {
			a = aggr(a, <-c)
		}
	} else {
		for i := 1; i < v.Size(); i++ {
			a = aggr(a, f(v.GetQuick(i)))
		}
	}
	return a
}