numeric.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package R
  2. /*
  3. #cgo LDFLAGS: -lm -lR
  4. #cgo CFLAGS: -I /usr/share/R/include/
  5. #include <stdlib.h>
  6. #include <R.h>
  7. #include <Rinternals.h>
  8. #include <Rdefines.h>
  9. #include <R_ext/Parse.h>
  10. #include <Rembedded.h>
  11. void SetNumericVectorElt(SEXP vec, int i, double val) {
  12. REAL(vec)[i] = val;
  13. }
  14. double NumericVectorElt(SEXP vec, int i) {
  15. return REAL(vec)[i];
  16. }
  17. */
  18. import "C"
  19. func boundsCheck(i int, length int) {
  20. if i >= length || i < 0 {
  21. panic("Index out of bounds")
  22. }
  23. }
  24. type Expression interface {
  25. ToSexp() C.SEXP
  26. }
  27. type expression struct {
  28. expr C.SEXP
  29. length int
  30. }
  31. func (this *expression) ToSexp() C.SEXP {
  32. return this.expr
  33. }
  34. func (this *expression) Len() int {
  35. return this.length
  36. }
  37. func (this *expression) boundsCheck(i int) {
  38. boundsCheck(i, this.length)
  39. }
  40. type NumericVector struct {
  41. expression
  42. }
  43. func NewNumericVector(vector []float64) *NumericVector {
  44. length := len(vector)
  45. v := NumericVector{}
  46. v.expr = C.allocVector(C.REALSXP, C.R_xlen_t(length))
  47. v.length = length
  48. v.CopyFrom(vector)
  49. return &v
  50. }
  51. func (this *NumericVector) Get(i int) float64 {
  52. this.boundsCheck(i)
  53. C.Rf_protect(this.expr)
  54. defer C.Rf_unprotect(1)
  55. return float64(C.NumericVectorElt(this.expr, C.int(i)))
  56. }
  57. func (this *NumericVector) Set(i int, val float64) {
  58. this.boundsCheck(i)
  59. C.Rf_protect(this.expr)
  60. defer C.Rf_unprotect(1)
  61. C.SetNumericVectorElt(this.expr, C.int(i), C.double(val))
  62. }
  63. func (this *NumericVector) CopyFrom(src []float64) {
  64. C.Rf_protect(this.expr)
  65. defer C.Rf_unprotect(1)
  66. for i := 0; i < this.length; i++ {
  67. C.SetNumericVectorElt(this.expr, C.int(i), C.double(src[i]))
  68. }
  69. }
  70. func (this *NumericVector) ToArray() []float64 {
  71. C.Rf_protect(this.expr)
  72. defer C.Rf_unprotect(1)
  73. array := make([]float64, this.length)
  74. for i := 0; i < this.length; i++ {
  75. array[i] = float64(C.NumericVectorElt(this.expr, C.int(i)))
  76. }
  77. return array
  78. }