Ruby returning imaginary number - ruby

Getting a confusing result when doing an exponential equation in ruby:
shifted_x = -97.0
exponent = 1.5
shifted_x**exponent
# Result: (0.0-955.3392067742221i)
-97.0**1.5
# Result: -955.3392067742221
My expectation is that the results would be the same but they are not. What changes when using the variable that causes ruby to return an imaginary (or complex) number?

Operator precedence.
-97.0**1.5 is equivalent to -(97.0**1.5)
shifted_x**exponent is, of course, equivalent to (-97.0)**1.5
Note that (-97.0)**1.5 is equivalent to sqrt((-97)^3) and taking the root of a negative real number gives you a complex number.

Related

gfortran compiler Error: result of exponentiation exceeds the range of INTEGER(4)

I have this line in fortran and I'm getting the compiler error in the title. dFeV is a 1d array of reals.
dFeV(x)=R1*5**(15) * (a**2) * EXP(-(VmigFe)/kbt)
for the record, the variable names are inherited and not my fault. I think this is an issue with not having the memory space to compute the value on the right before I store it on the left as a real (which would have enough room), but I don't know how to allocate more space for that computation.
The problem arises as one part of your computation is done using integer arithmetic of type integer(4).
That type has an upper limit of 2^31-1 = 2147483647 whereas your intermediate result 5^15 = 30517578125 is slightly larger (thanks to #evets comment).
As pointed out in your question: you save the result in a real variable.
Therefor, you could just compute that exponentiation using real data types: 5.0**15.
Your formula will end up like the following
dFeV(x)= R1 * (5.0**15) * (a**2) * exp(-(VmigFe)/kbt)
Note that integer(4) need not be the same implementation for every processor (thanks #IanBush).
Which just means that for some specific machines the upper limit might be different from 2^31-1 = 2147483647.
As indicated in the comment, the value of 5**15 exceeds the range of 4-byte signed integers, which are the typical default integer type. So you need to instruct the compiler to use a larger type for these constants. This program example shows one method. The ISO_FORTRAN_ENV module provides the int64 type. UPDATE: corrected to what I meant, as pointed out in comments.
program test_program
use ISO_FORTRAN_ENV
implicit none
integer (int64) :: i
i = 5_int64 **15_int64
write (*, *) i
end program
Although there does seem to be an additional point here that may be specific to gfortran:
integer(kind = 8) :: result
result = 5**15
print *, result
gives: Error: Result of exponentiation at (1) exceeds the range of INTEGER(4)
while
integer(kind = 8) :: result
result = 5**7 * 5**8
print *, result
gives: 30517578125
i.e. the exponentiation function seems to have an integer(4) limit even if the variable to which the answer is being assigned has a larger capacity.

Assignment problems with simple random number generation in Modelica

I am relatively new to Modelica (Dymola-environment) and I am getting very desperate/upset that I cannot solve such a simple problem as a random number generation in Modelica and I hope that you can help me out.
The simple function random produces a random number between 0 and 1 with an input seed seedIn[3] and produces the output seed seedOut[3] for the next time step or event. The call
(z,seedOut) = random(seedIn);
works perfectly fine.
The problem is that I cannot find a way in Modelica to compute this assignment over time by using the seedOut[3] as the next seedIn[3], which is very frustrating.
My simple program looks like this:
*model Randomgenerator
Real z;
Integer seedIn[3]( start={1,23,131},fixed=true), seedOut[3];
equation
(z,seedOut) = random(seedIn);
algorithm
seedIn := seedOut;
end Randomgenerator;*
I have tried nearly all possibilities with algorithm assignments, initial conditions and equations but none of them works. I just simply want to use seedOut in the next time step. One problem seems to be that when entering into the algorithm section, neither the initial conditions nor the values from the equation section are used.
Using the 'sample' and 'reinit' functions the code below will calculate a new random number at the frequency specified in 'sample'. Note the way of defining the "start value" of seedIn.
model Randomgenerator
Real seedIn[3] = {1,23,131};
Real z;
Real[3] seedOut;
equation
(z,seedOut) = random(seedIn);
when sample(1,1) then
reinit(seedIn,pre(seedOut));
end when;
end Randomgenerator;
The 'pre' function allows the use of the previous value of the variable. If this was not used, the output 'z' would have returned a constant value. Two things regarding the 'reinint' function, it requires use of 'when' and requires 'Real' variables/expressions hence seedIn and seedOut are now defined as 'Real'.
The simple "random" generator I used was:
function random
input Real[3] seedIn;
output Real z;
output Real[3] seedOut;
algorithm
seedOut[1] :=seedIn[1] + 1;
seedOut[2] :=seedIn[2] + 5;
seedOut[3] :=seedIn[3] + 10;
z :=(0.1*seedIn[1] + 0.2*seedIn[2] + 0.3*seedIn[3])/(0.5*sum(seedIn));
end random;
Surely there are other ways depending on the application to perform this operation. At least this will give you something to start with. Hope it helps.

Ruby the hard way ex39 .hash function with % operator

I am new to Ruby and learning it using Learn Ruby the Hard Way online book. I am not very clear in Ex39 : http://learnrubythehardway.org/book/ex39.html
Confusion code :
def Dict.hash_key(aDict, key)
# Given a key this will create a number and then convert it to
# an index for the aDict's buckets.
#takes the key arguments and converts it into a hash number
# that is divided by the length
#of the Dict. The remainder a number on the aDict.
return key.hash % aDict.length
end
What is % operator being used for. If key.has creates a unique number why we need to divide it by the length of the Dict ?
The % operator is the modulo operator. (As in most other current languages)
With it you can make sure, that the final number will never be larger than the value you did divide by.

using probability for rounding decimals

What might be a simple Ruby way to round numbers using probability, i.e., based on how close the value is to one boundary or the other (floor or ceiling)?
For example, given a current price value of 28.33, I need to add 0.014.
Equivalent to starting with 28.34 and needing to add 0.004, but the final value must be rounded to two decimal places(which can be provided as parameter, or fixed for now).
The final value should therefore be:
28.34 with 60% chance, since it is that much closer, OR
28.35 with 40% random chance
The reason it occured to me this could serve best is that the application is stateless and independent across runs, but still needs to approximate the net effect of accumulating the less significant digits normally rounded into oblivion (eg. micropenny values that do have an impact over time). For example, reducing a stop-loss by some variable increment every day (subtraction like -0.014 above instead).
It would be useful to extend this method to the Float class directly.
How about:
rand(lower..upper) < current ? lower.round(2) : upper.round(2)
EDIT:
The above will only work if you use Ruby 1.9.3 (due to earlier versions not supporting rand in a range).
Else
random_number = rand * (upper-lower) + lower
random_number < current ? lower.round(2) : upper.round(2)
Wound up using this method:
class Float
def roundProb(delta, prec=2)
ivalue=self
chance = rand # range 0..1, nominally averaged at 0.5
# puts lower=((ivalue + delta)*10**prec -0.5).round/10.0**prec # aka floor
# puts upper=((ivalue + delta)*10**prec +0.5).round/10.0**prec # ceiling
ovalue=((ivalue + delta)*10**prec +chance-0.5).round/10.0**prec # proportional probability
return ovalue
rescue
puts $#, $!
end
end
28.33.roundProb(0.0533)
=> 28.39
Maybe not the most elegant approach but seems to work for the general case of any precision, default 2. Even works on Ruby 1.8.7 I'm stuck with in one case, which lacks a precision parameter to round().

Order of operations question in Ruby

I'm initializing an instance of a class that tests the equality of two formulas.
The formula's calculated values are in fact equal:
RubyChem::Chemical.new("SOOS").fw
=> 96.0
RubyChem::Chemical.new("OSSO").fw
= 96.0
When I created a new class to check the equality of these two instances I'm a bit surprised by the results:
x = RubyChem::BalanceChem.new("SOOS","OSSO")
x.balanced
=>false
y = RubyChem::BalanceChem.new("SOOS","SOOS")
y.balanced
=> true
the RubyChem::BalanceChem initialize method is here:
def initialize(formula1, formula2)
#balanced = RubyChem::Chemical.new(formula1).fw == RubyChem::Chemical.new(formula2).fw
end
Why doesn't ruby fetch the fw values for formula1 and formula2 and check the equality of those values? What are the order of operations in Ruby and what is Ruby doing? I can see I lack an understanding of this issue. How can I make this work? Thank you in advance.
Ruby 1.8 has a bug when converting floats to string. Sometimes the given string not a good representation of the float. Here is an example with 0.56:
0.5600000000000005.to_s == 0.56.to_s #=> true
# should have returned false, since:
0.5600000000000005 == 0.56 #=> false
This explains why two apparently identical results are not actually identical.
You probably want to do compare within a certain margin of error, do some rounding before doing a comparison, or use exact types like BigDecimal or Rational.
You probably do not want to check floating point numbers for equality. Instead, you should compare deltas.
Try this in irb:
x = 1.000001
y = 1.0
x == y
(x-y).abs < 0.00001
So, you find a delta like 0.00001 that you feel would handle any variation in floating point arithmetic, and use it that way. You should never == floats.
This is likely another problem caused by floating point precision.
I can assure you that those values calculated before the equality is evaluated.
See the Ruby's operator precedence

Resources