# Mathematical modeller pseudocode

N

#### Nick S

Hello everyone on Ruby-Lang!

I'm currently experimenting with writing an iteration-based
mathematical modeller* and would like to bounce some ideas off you.

Currently the models are defined in somewhat cumbersome ruby, but I'd
like the method of model creation to be somewhat more elegant, and I
was wondering if the following (currently hypothetical) code could be

------------------- ** -------------------

@m = Modeller::Model.new

@m.step_size = 0.1

t = @m.independent_vart, 1.0)
x, v, a = @m.declare_varsx, :v, :a)

# x = 3*t + 2
@m.relationshiplinear, :x, :t) { |x, t|
x = 3*t + 2
}

# dx/dt = v
@m.relationshipdifferential, :x, :v, {:with_respect_to => :t}) {
|x, v|
d_dt(x) = v
}

# dv/dt = 2a^2
@m.relationshipdifferential, :v, :a {:with_respect_to => :t}) { |v,
a|
d_dt(v) = 2*(a**2)
}

@m.set_initial_valuesx => 5.0, :v => 0.0, :a => 0.0)

------------------- ** -------------------

I've given you a bit of context to show you how the rest of the model
is defined, but the important bit is the relationship definitions, and
I hope you can see how the relationships are meant to work. The
question really is -- is this possible? I need to extract a
relationship from the code passed into the blocks (it could just as
well be a string if that helps) ... and am at a loss as to how to parse
it/make it work.

To give a brief example, from the linear relationship above, what
should happen is I should be able to get 't' in terms of 'x' so I can
extract the raw value and adjust *that* with a linear relationship, and
then apply the whole process backwards to get the "actual" value of
'x'. In code:

------------------- ** -------------------

def update_value_with(var, upstream)
val = value_from_raw(
upstream.value/upstream.value(-1) *
raw_from_value(var.value)
)
var.set_value(val)
end

def raw_from_value(value)
(value - @const) / @factor
end

def value_from_raw(raw)
(raw * @factor) + @const
end

------------------- ** -------------------

I hope some of this is decipherable, and look forward to hearing your
innovative replies!

Nick S

* (à la Modellus [http://phoenix.sce.fct.unl.pt/modellus/] if any of
you know it -- although my modeller is currently at least 100-200 times
faster than Modellus -- admittedly with a more basic differential
equation algorithm)

K

#### konsu

i am probably too slow, but what is the question?

konstantin

Hello everyone on Ruby-Lang!

I'm currently experimenting with writing an iteration-based
mathematical modeller* and would like to bounce some ideas off you.

Currently the models are defined in somewhat cumbersome ruby, but I'd
like the method of model creation to be somewhat more elegant, and I
was wondering if the following (currently hypothetical) code could be

------------------- ** -------------------

@m = Modeller::Model.new

@m.step_size = 0.1

t = @m.independent_vart, 1.0)
x, v, a = @m.declare_varsx, :v, :a)

# x = 3*t + 2
@m.relationshiplinear, :x, :t) { |x, t|
x = 3*t + 2
}

# dx/dt = v
@m.relationshipdifferential, :x, :v, {:with_respect_to => :t}) {
|x, v|
d_dt(x) = v
}

# dv/dt = 2a^2
@m.relationshipdifferential, :v, :a {:with_respect_to => :t}) { |v,
a|
d_dt(v) = 2*(a**2)
}

@m.set_initial_valuesx => 5.0, :v => 0.0, :a => 0.0)

------------------- ** -------------------

I've given you a bit of context to show you how the rest of the model
is defined, but the important bit is the relationship definitions, and
I hope you can see how the relationships are meant to work. The
question really is -- is this possible? I need to extract a
relationship from the code passed into the blocks (it could just as
well be a string if that helps) ... and am at a loss as to how to parse
it/make it work.

To give a brief example, from the linear relationship above, what
should happen is I should be able to get 't' in terms of 'x' so I can
extract the raw value and adjust *that* with a linear relationship, and
then apply the whole process backwards to get the "actual" value of
'x'. In code:

------------------- ** -------------------

def update_value_with(var, upstream)
val = value_from_raw(
upstream.value/upstream.value(-1) *
raw_from_value(var.value)
)
var.set_value(val)
end

def raw_from_value(value)
(value - @const) / @factor
end

def value_from_raw(raw)
(raw * @factor) + @const
end

------------------- ** -------------------

I hope some of this is decipherable, and look forward to hearing your
innovative replies!

Nick S

* (à la Modellus [http://phoenix.sce.fct.unl.pt/modellus/] if any of
you know it -- although my modeller is currently at least 100-200 times
faster than Modellus -- admittedly with a more basic differential
equation algorithm)

N

#### Nick S

Sorry If I haven't been clear ... I was looking for input on how I
might parse the input to the @m.relationship...{ ... } calls.

K

#### konsu

here is the sample code that you posted

@m = Modeller::Model.new

@m.step_size = 0.1

t = @m.independent_vart, 1.0)
x, v, a = @m.declare_varsx, :v, :a)

# x = 3*t + 2
@m.relationshiplinear, :x, :t) { |x, t| x = 3*t + 2 }

when you call @m.relationship, what should happen? what is this method's
return value?

N

#### Nick S

Sorry, I'm clearly not making myself clear.

I'll try and explain myself.

I'm writing an iteration based mathematical/physical modeller. In this
model we have different variables as declared in the @m.declare_vars
line.

When the model is "run" (i.e. iterated) the model increments the
independent variable by the timestep (step_size), then looks for all
variables that have some sort of a relationship to the independent
variable, making appropriate adjustments to them.

The code above is all real, working code, except for the
@m.relationship calls. These are hypothetical and represent how I would
like to be able to define relationships in the model between different
variables.

The problem is that I need to be able to make some sense out of what
gets passed into the block.

To give you an example, using the code above, what *should* happen is
this (for example):

- the independent var, :t gets incremented.
- as a result of the @m.relationship call above, the variable t
(Variable is a class in this modeller) knows about its reverse
dependencies (the other variables in the model, in this case x, that
depend on t).
- it calls an update method on x, passing itself as a parameter
- in x, the update method in turn passes the call on to a
Relationship::Linear class's #update_with_value call passing itself and
t (which was passed to it by t) as parameters.
- because we keep a history of previous values within the Variable
class, we can implement a linear relationship like so:

------------------- ** -------------------
class Linear
def initialize
@factor = factor
@const = const
end

def update_value_with(var, upstream)
val = value_from_raw(
upstream.value/upstream.value(-1) *
raw_from_value(var.value)
)
var.set_value(val)
end

def raw_from_value(value)
(value - @const) / @factor
end

def value_from_raw(raw)
(raw * @factor) + @const
end
end
------------------- ** -------------------

What I hope you can see that we're doing here (in this earlier example)
is getting, as it were, the 'raw' value of our variable (i.e. the bit
that is *actually* proportional to t, rather than the whole value),
then multiplying that by the factor by which the upstream variable has
been multiplied, then putting on the @factor and @const again.

This works, except it requires you to declare the relationship in a
cumbersome and restrictive manner. What I'd like to do is to declare
the relationships in an intuitive manner as in the first code sample,
and then somehow be able to parse and rearrange the algebra that I'm
parsed, so that, for example, I could get t in terms of x, rather than
the other way round.

I currently can't see how to do this, and was hoping you could help.

Here's hoping I've now made myself sufficiently clear =)

Nick

K

#### konsu

Hello,

it seems that you are trying to find a way to treat code blocks as data. is
this correct?

i mean, given a code block such as { puts 'hello world' } you want to be
able to tell what this block does without evaluating it, right?

konstantin