solving the Chapman-Richards equation - ms-solver-foundation

I need to find a way to solve the Chapman-Richards with 3 parameters. The equation is
F=a(1-EXP(-bt)) power c
It is a nonlinear problem. The goal is to minimize the error and the constraints are that the 3 variables must be >= 0.0001. Our current implementation uses Excel and the Solver plugin (GRG nonlinear method). But now, we need to implement all this without making use of Excel.
My questions are:
1. Is it possible to use MS Solver Foundation to solve this problem?
I have read some docs and understand that MS Solver Foundation uses either the Nelder Mead Solver or the hybrid local search solver to solve nonlinear problems. Does anyone know if my particular problem can be solved using these methods? And, will the results be same as using GRG nonlinear method of Excel's Solver addin?
If not, is it possible to implement the GRG nonlinear method of Excel Solver?
Is there any other way to implement this?
Thanks for your replies in advance.
kar
Addendum:
Sorry, I forgot to mention that t is the time variable. a, b, and c are the parameters which can be changed by the solver.

Yes, it can be done with the Nelder-Mead solver in Solver Foundation. Here is some example code in C#. Just make sure you reference the Microsoft.Solver.Foundation assembly.
private const double t = 1.0;
public static void Main()
{
var solver = new NelderMeadSolver();
// Objective function.
int objId;
solver.AddRow("obj", out objId);
solver.AddGoal(objId, 0, true);
// Define variables.
int aId, bId, cId;
solver.AddVariable("a", out aId);
solver.AddVariable("b", out bId);
solver.AddVariable("c", out cId);
// Define bounds.
solver.SetLowerBound(aId, 0.001);
solver.SetLowerBound(bId, 0.001);
solver.SetLowerBound(cId, 0.001);
// Assign objective function delegate.
solver.FunctionEvaluator = FunctionValue;
// Solve.
var param = new NelderMeadSolverParams();
var solution = solver.Solve(param);
Console.WriteLine("The Result is " + solution.Result + ".");
Console.WriteLine("The minimium objective value is " +
solution.GetValue(objId) + ".");
Console.WriteLine("a = " + solution.GetValue(aId) + ".");
Console.WriteLine("b = " + solution.GetValue(bId) + ".");
Console.WriteLine("c = " + solution.GetValue(cId) + ".");
Console.ReadKey();
}
private static double FunctionValue(INonlinearModel model, int rowVid,
ValuesByIndex values, bool newValues)
{
var a = values[model.GetIndexFromKey("a")];
var b = values[model.GetIndexFromKey("b")];
var c = values[model.GetIndexFromKey("c")];
return a * Math.Pow(1.0-Math.Exp(-b * t), c);
}

I solved it with Visual Studio 2013 and Visual Basic, there is the traslation of the code.
Private Sub NelderMead()
Dim Solver As New Microsoft.SolverFoundation.Solvers.NelderMeadSolver
Dim objId As Integer
Solver.AddRow("obj", objId)
Solver.AddGoal(objId, 0, True)
Dim aId, bId, cId As Integer
Solver.AddVariable("a", aId)
Solver.AddVariable("b", bId)
Solver.AddVariable("c", cId)
Solver.SetLowerBound(aId, 0.001)
Solver.SetLowerBound(bId, 0.001)
Solver.SetLowerBound(cId, 0.001)
Solver.FunctionEvaluator = AddressOf FunctionValue
Dim Par As New Microsoft.SolverFoundation.Solvers.NelderMeadSolverParams
Dim Solucion = Solver.Solve(Par)
Debug.Print(Solucion.Result)
End Sub
Function FunctionValue(Model As Microsoft.SolverFoundation.Services.INonlinearModel, _
rowVid As Integer, _
Values As Microsoft.SolverFoundation.Services.ValuesByIndex, _
newValues As Boolean) As Object
Dim a, b, c As Double
a = Values(Model.GetIndexFromKey("a"))
b = Values(Model.GetIndexFromKey("b"))
c = Values(Model.GetIndexFromKey("c"))
Return a * Math.Pow(1.0 - Math.Exp(-b * t), c)
End Function

Related

How can I make a code that tells VB6 that tells VB6 that you're inputting something other than Whole numbers?

Introduction: Hi, everyone! I'm new to VB6! How can I make a code that tells VB6 that tells VB6 that you're inputting something other than Whole numbers?
Details: I'm making an arithmetic progression calculator (I think the code is not needed? but I'll just provide just in case.) Here is my code:
Option Explicit
Private Sub btCalc_Click()
Dim A As Long
Dim N As Long
Dim D As Long
Dim R As Long
Dim F As Long
A = Val(txtInitterm.Text)
N = Val(txtTermint.Text)
D = Val(txtFinterm.Text)
R = Val(txtTermint.Text)
F = N / 2 * (2 * A + (N - 1) * D)
lblOutput.Caption = F
End Sub
and I wanna notify or tell VB6 that I'm putting in a fraction, not an integer and uses that fraction to do operations.
NOTE: String Fraction to Value in VBA this doesn't answer my question... :D
Thank you for helping me, everyone! it's much appreciated.
There is no Application.Evaluate(...) in Vb6 like in VBA, so you have to do it like the "question" in "String Fraction to Value in VBA". Extract the logic to a function for re-use, and replace the Val(...) calls with the function for use.
Something like below would likely work, although you may want to provide better error handling in the obvious bad-math cases. I simply return zero and mark them with a comment.
Option Explicit
Private Sub btCalc_Click()
Dim A As Long, N As Long, D As Long, R As Long, F As Long
A = GetFrac(txtInitterm)
N = GetFrac(txtTermint)
D = GetFrac(txtFinterm)
R = GetFrac(txtTermint)
F = N / 2 * (2 * A + (N - 1) * D)
lblOutput.Caption = F
End Sub
Public Function GetFrac(ByVal S As String) As Double
GetFrac = 0 ' default return on error
If InStr(S, "/") = 0 Then GetFrac = Val(S): Exit Function
Dim P() As String, N As Double, D As Double
P = Split(S, "/")
If UBound(P) <> 1 Then Exit Function ' bad input -- multiple /'s
N = Val(P(0))
D = Val(P(1))
If D = 0 Then Exit Function ' div by 0
GetFrac = N / D
End Function

Are unsigned long types available to LibreOffice Basic?

I'm want to write a simple 32-bit FNV hash function for LibreOffice Calc. However, LibreOffice Basic only supports signed long data types, so you will get an "Inadmissible value or data type. Overflow." error on line 7 with the following code:
Function Hash(strText as String) as Long
Dim h As Long
Dim nextChar As String
Dim temp As Long
h = 2166136261
For i = 1 To Len(strText)
nextChar = Mid(strText, i, 1)
temp = Asc(nextChar)
h = h XOR temp
h = h * 16777619
Next
Hash = h
End Function
Because the h variable is assigned 2166136261 in the code above, it is obviously out of bounds. Is it possible to work with unsigned long (0 to 4294967295) data types in LibreOffice Basic? If so, how?
You could do this:
Sub CallHash
oMasterScriptProviderFactory = createUnoService(_
"com.sun.star.script.provider.MasterScriptProviderFactory")
oScriptProvider = oMasterScriptProviderFactory.createScriptProvider("")
oScript = oScriptProvider.getScript(_
"vnd.sun.star.script:foo.py$hash?language=Python&location=user")
hashString = oScript.invoke(Array("bar"), Array(), Array())
MsgBox hashString
End Sub
foo.py:
def hash(strText):
h = 2166136261
for nextChar in strText:
temp = ord(nextChar)
h = h ^ temp
h = h * 16777619
return str(h)
Or drop Basic and use only Python-UNO.
There are unsigned long values in the UNO API. However, I didn't find any API methods to perform calculations on this object.
Dim o As Object
o = CreateUnoValue("unsigned long", 2166136261)

How to generate a model for my code using boolector?

I'm experimenting a bit with boolector so I'm trying to create model for simple code. Suppose that I have the following pseudo code:
int a = 5;
int b = 4;
int c = 3;
For this simple set of instructions I can create the model and all works fine. The problem is when I have other instructions after that like
b = 10;
c = 20;
Obviously it fails to generate the model because b cannot be equal to 4 and 10 within the same module. One of the maintainer suggested me to use boolector_push and boolector_pop in order to create new Contexts when needed.
The code for boolector_push is :
void
boolector_push (Btor *btor, uint32_t level)
{
BTOR_ABORT_ARG_NULL (btor);
BTOR_TRAPI ("%u", level);
BTOR_ABORT (!btor_opt_get (btor, BTOR_OPT_INCREMENTAL),
"incremental usage has not been enabled");
if (level == 0) return;
uint32_t i;
for (i = 0; i < level; i++)
{
BTOR_PUSH_STACK (btor->assertions_trail,
BTOR_COUNT_STACK (btor->assertions));
}
btor->num_push_pop++;
}
Instead for boolector_pop is
void
boolector_pop (Btor *btor, uint32_t level)
{
BTOR_ABORT_ARG_NULL (btor);
BTOR_TRAPI ("%u", level);
BTOR_ABORT (!btor_opt_get (btor, BTOR_OPT_INCREMENTAL),
"incremental usage has not been enabled");
BTOR_ABORT (level > BTOR_COUNT_STACK (btor->assertions_trail),
"can not pop more levels (%u) than created via push (%u).",
level,
BTOR_COUNT_STACK (btor->assertions_trail));
if (level == 0) return;
uint32_t i, pos;
BtorNode *cur;
for (i = 0, pos = 0; i < level; i++)
pos = BTOR_POP_STACK (btor->assertions_trail);
while (BTOR_COUNT_STACK (btor->assertions) > pos)
{
cur = BTOR_POP_STACK (btor->assertions);
btor_hashint_table_remove (btor->assertions_cache, btor_node_get_id (cur));
btor_node_release (btor, cur);
}
btor->num_push_pop++;
}
In my opinion, those 2 functions maintains track of the assertions generated using boolector_assert so how is it possible to obtain the final and correct model using boolector_push and boolector_pop considering that the constraints are going to be the same?
What am I missing?
Thanks
As you suspected, solver's push and pop methods aren't what you're looking for here. Instead, you have to turn the program you are modeling into what's known as SSA (Static Single Assignment) form. Here's the wikipedia article on it, which is quite informative: https://en.wikipedia.org/wiki/Static_single_assignment_form
The basic idea is that you "treat" your mutable variables as time-varying values, and give them unique names as you make multiple assignments to them. So, the following:
a = 5
b = a + 2
c = b + 3
c = c + 1
b = c + 6
becomes:
a0 = 5
b0 = a0 + 2
c0 = b0 + 3
c1 = c0 + 1
b1 = c1 + 6
etc. Note that conditionals are tricky to deal with, and generally require what's known as phi-nodes. (i.e., merging the values of branches.) Most compilers do this sort of conversion automatically for you, as it enables many optimizations down the road. You can either do it by hand, or use an algorithm to do it for you, depending on your particular problem.
Here's another question on stack-overflow, that's essentially asking for something similar: Z3 Conditional Statement
Hope this helps!

matlab oop "use data of hole class" for calculation

First, sorry for the bad title - I'm new to OO programming - basically I'd like to understand how Matlab works with oop classes.
Before I ask my question, here is a basic example of what I want to do:
I have two houses and some data about them and I got the idea, to work with oop classes. Here is my .m file.
classdef building
properties
hohe = 0;
lange = 0;
breite = 0;
xabstandsolar = 0;
yabstandsolar = 0;
end
methods
function obj = building(hohe, lange, breite, xabstandsolar, yabstandsolar)
obj.hohe = hohe;
obj.lange = lange;
obj.breite = breite;
obj.xabstandsolar = xabstandsolar;
obj.yabstandsolar = yabstandsolar;
end
function hohenwinkel(h)
h = h
d = sqrt(obj.xabstandsolar^2 + yabstandsolar^2);
gamma_v = atand((obj.hohe - h)/(d));
end
end
end
I filled it with some data - for example
>>H1 = building(10,8,6,14,8)
>>H2 = building(18,8,6,14,0)
And now I want to calculate "gamma_v" (as an 1x2 array) for each building. Any ideas, how I can archive this?
Edit:
I want to create gamma_v (as an array) automatically for all objects in the class "building". There will be a lot more "houses" in the final script.
Your hohenwinkel method needs to accept two input arguments. The first argument for non-static methods is always the object itself (unlike C++, you'll have to explicitly list it as an input argument) and the second input will be your h variable. You'll also want to actually return the gamma_v value using an output argument for your method.
function gamma_v = hohenwinkel(obj, h)
d = sqrt(obj.xabstandsolar^2 + obj.yabstandsolar^2);
gamma_v = atand((obj.hohe - h)/(d));
end
Then you can invoke this method on each building to get the value
gamma_v1 = hohenwinkel(H1);
gamma_v2 = hohenwinkel(H2);
If you want to have an array of buildings, you can create that array
houses = [building(10,8,6,14,8), building(18,8,6,14,0)];
gamma_v = hohenwinkel(houses);
and then construct your hohenwinkel function to operate on each one and return the result
function gamma_v = hohenwinkel(obj, h)
if numel(obj) > 1
% Compute hohenwinkel for each one
gamma_v = arrayfun(#(x)hohenwinkel(x, h), obj);
return
end
d = sqrt(obj.xabstandsolar^2 + obj.yabstandsolar^2);
gamma_v = atand((obj.hohe - h)/(d));
end
there is some tricky solution (and its not recommended)(#Suever solution is better)
you should create a handle class
classdef gvclass<handle
properties
gvarr=[];
end
methods
function setgvarr(obj,value)
obj.gvarr=[obj.gvarr,value];
end
end
end
then use this class in your building class
classdef building<handle
properties
gv
hohe = 0;
lange = 0;
breite = 0;
xabstandsolar = 0;
yabstandsolar = 0;
end
methods
function obj = building(hohe, lange, breite, xabstandsolar, yabstandsolar,handle_of_your_gv_class,h)
obj.hohe = hohe;
obj.lange = lange;
obj.breite = breite;
obj.xabstandsolar = xabstandsolar;
obj.yabstandsolar = yabstandsolar;
obj.gv=handle_of_your_gv_class;
obj.hohenwinkel(h);
end
function hohenwinkel(obj,h)
d = sqrt(obj.xabstandsolar^2 + yabstandsolar^2);
gamma_v = atand((obj.hohe - h)/(d));
obj.gv.setgvarr(gamma_v);
end
end
end
finally before creating any building you should create an object of gv class and pass it to the building constructor,
Egv=gvclass();
H1 = building(10,8,6,14,8,Egv,2)
H2 = building(18,8,6,14,0,Egv,3)
and to access gv array:
Egv.gvarr
you should do more effort on this issue to debug possible errors.

how to compute ceiling of log2 in e hardware verification language

The 'e' language has a 'ilog2' function but I need a 'ceiling of log2' type function - what's the best way to do this?
I could invoke a Perl through the system command and use POSIX::ceil...
Invoking perl script might be computational expensive. Instead add 0.5 to log2 and typecast (not sure if e-language supports it) to integer.
Another try:
Let y = ilog2(x);
if ((x & x-1) == 0) //Check if x is power of 2
return y;
else
return y+1;
I would have done something like this:
ceil_log2(in : uint): uint is {
var bottom := ilog2(in);
result = (in == ipow(2,bottom)) ? bottom : bottom + 1;
};
If you don't mind doing it in real:
ceil_log2(in: uint): uint is {
result = ceil(log10(in)/log10(2)).as_a(uint);
};