Class: GSL4r::Complex::GSL_Complex

Inherits:
FFI::Struct
  • Object
show all
Defined in:
lib/gsl4r/complex.rb

Overview

Note, according to gnu.org/software/gsl/manual/html_node/Representation-of-complex-numbers.html the layout of the complex numbers struct is supposed to be platform dependent and opaque to applications using GSL. It also provides C Macros to help with this opaqueness. Unfortunately, we don’t have the luxury of using the macros, nor making the struct mapping opaque. Happily, in practice, on Linux 32 and 64bit, OSX 32 and 64 bit, and Solaris 64 bit, the struct appears to be identical. TODO: Need to check other platforms… TODO: Perhaps integrate use of FFI::Generator to auto-gen the layout for structs, based on the platform this package is installed onto?

Note, long double is not implemented, as its size is dependent on the platform. GCC on intel turns long double into the native 80-bit float of the x86 architecture. Microsoft VC aliases it back to double. It would be nice if we could guarantee that it was a 128 quadruple precision value, but… no.

Direct Known Subclasses

GSL_Complex_float

Constant Summary collapse

EPSILON =
5.0e-15
R =
0
I =
1

Class Method Summary collapse

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(called_method, *args, &block) ⇒ Object

This traps method calls intended to create shortened versions of the GSL function calls.

This first checks if the called method matches the Module function call gsl_complex_#called_method (where called_method might be ‘abs’).

If it finds a match (respond_to), it will then create a new method for the class as a whole (class_eval), making the method available to not just this instance of the class, but all existing instances and all those created after.

Finally, the creation is wrapped up in a synchronized call to ensure thread safety. It is only unsafe the first time the method is invoked (and non-existent at that point). Every time the method is invoked after, it should not hit method_missing. TODO: Is this true for java threads too, or is it per ‘vm’ per thread?



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/gsl4r/complex.rb', line 167

def method_missing( called_method, *args, &block )

	$globalGSLComplexLock.synchronize do

	  prefix = "gsl_complex_"

	  if ( ::GSL4r::Complex::Methods.respond_to?("#{prefix}#{called_method}") == false )
	    prefix = ""
	    if ( ::GSL4r::Complex::Methods.respond_to?("#{called_method}") == false )
 super # NoMethodError
	    end
	  end

	  self.class.class_eval <<-end_eval
	  def #{called_method}(*args, &block)
	    args.insert(0, self)
	    ::GSL4r::Complex::Methods::#{prefix}#{called_method}( *args, &block )
	  end
	  end_eval

	  __send__(called_method, *args, &block)
	end # globalGSLComplexLock.synchronize
end

Class Method Details

.c_assignment(name) ⇒ Object



87
88
89
# File 'lib/gsl4r/complex.rb', line 87

def c_assignment( name )
  "GSL_SET_COMPLEX(&#{name}, 2.0, 2.0);"
end

.c_equalsObject



91
92
# File 'lib/gsl4r/complex.rb', line 91

def c_equals()
end

.c_pointer_initializer(name) ⇒ Object



98
99
100
# File 'lib/gsl4r/complex.rb', line 98

def c_pointer_initializer( name )
  return ""
end

.c_to_r_assignment(v1, v2) ⇒ Object



79
80
81
# File 'lib/gsl4r/complex.rb', line 79

def c_to_r_assignment(v1,v2)
  "printf(\\\"  #{v1}.set(%.15g,%.15g)\\\\n\\\",GSL_REAL(#{v2}),GSL_IMAG(#{v2}));\\n"
end

.c_typeObject



83
84
85
# File 'lib/gsl4r/complex.rb', line 83

def c_type()
  "gsl_complex"
end

.c_value_initializer(name) ⇒ Object



94
95
96
# File 'lib/gsl4r/complex.rb', line 94

def c_value_initializer( name )
  return "gsl_complex #{name}; " + c_assignment( name )
end

.create(r = 0.0, i = 0.0) ⇒ Object



60
61
62
63
# File 'lib/gsl4r/complex.rb', line 60

def create( r=0.0, i=0.0 )
  myComplex = GSL_Complex.new
  myComplex.set( r, i )
end

.r_assignment(name) ⇒ Object



75
76
77
# File 'lib/gsl4r/complex.rb', line 75

def r_assignment( name )
  "#{name}.set(2.0,2.0)" # these numbers should make c_assignment for the test
end

.r_equals(v1, v2) ⇒ Object



71
72
73
# File 'lib/gsl4r/complex.rb', line 71

def r_equals(v1,v2)
  "#{v1.to_s}.equals(#{v2.to_s})"
end

.r_typeObject

the r_ and c_ methods are designed to help automate the building of tests and not for use in general



67
68
69
# File 'lib/gsl4r/complex.rb', line 67

def r_type()
  "GSL_Complex"
end

Instance Method Details

#equals(a) ⇒ Object



125
126
127
128
# File 'lib/gsl4r/complex.rb', line 125

def equals( a )
	return ( (a[:dat][R] - self[:dat][R]).abs < EPSILON &&
		(a[:dat][I] - self[:dat][I]).abs < EPSILON )
end

#imagObject



121
122
123
# File 'lib/gsl4r/complex.rb', line 121

def imag()
	return self[:dat][I]
end

#methodsObject

Play nice and have these methods show up in case someone is digging around for them using these reflection routines Note: this won’t show the shortened named forms that will automatically be generated when called.



107
108
109
110
# File 'lib/gsl4r/complex.rb', line 107

def methods
	a = super
	a + ::GSL4r::Complex::Methods.methods.grep(/^gsl_complex_/)
end

#public_methodsObject



112
113
114
115
# File 'lib/gsl4r/complex.rb', line 112

def public_methods
	a = super
	a + ::GSL4r::Complex::Methods.methods.grep(/^gsl_complex_/)
end

#realObject



117
118
119
# File 'lib/gsl4r/complex.rb', line 117

def real()
	return self[:dat][R]
end

#set(r, i) ⇒ Object



130
131
132
133
134
# File 'lib/gsl4r/complex.rb', line 130

def set( r, i )
	self[:dat][R] = r
	self[:dat][I] = i
	return self
end

#set_imag(i) ⇒ Object



140
141
142
# File 'lib/gsl4r/complex.rb', line 140

def set_imag( i )
	self[:dat][I] = i
end

#set_real(r) ⇒ Object



136
137
138
# File 'lib/gsl4r/complex.rb', line 136

def set_real( r )
	self[:dat][R] = r
end

#to_sObject



144
145
146
# File 'lib/gsl4r/complex.rb', line 144

def to_s()
	return "(#{self[:dat][R]},#{self[:dat][I]})"
end