What is an alternate solution if I can't overload a function? - vb.net

What I am doing is generic and has been done a thousand times, but I can't figure out how other programmers do this.
I am working with the Law of Sines to return an angle of A. There are two combinations, for instance:
Return Angle A given (side b, side a, angle B)
Return Angle A given (side c, side a, angle C)
----Note: All together there would be six, two for each angle)----
I can't overload the functions because the signatures are not unique. The parameters and return type are primitive type Double.
The use of Aliases works for reading the code but does nothing to resolve my issue.
One approach I thought of was to create a structure for each side and angle; however, I don't want to create any more complexity than needed.
Another solution could be using a strategy design pattern?
I'm a hobbyist programmer (still beginner level);I'm trying to build some good programming practices. Any help would be appreciated.

I would recommend a different naming convention and a boolean parameter:
Public Function GetAngle(adjacentSide As Double, oppositeSide As Double, knownAngle As Double, Optional knownAngleCorrespondsToAdjacentSide As Boolean = True) As Double
When called, you now know if it's:
GetAngle(c, a, C) 'or
GetAngle(b, a, B) 'or
GetAngle(b, a, C, False) 'or
GetAngle(c, a, B, False)
That said, since A, B, & C are arbitrary labels:
a b c
__________ __________ __________
\B C/ \C A/ \A B/
\ / \ / \ /
c \ / b => a \ / c => b\ / a
\ A/ \ B/ \ C/
\/ \/ \/
you either need two functions (Private would work fine) or just handle your calculations internally base on the boolean:
Public Function GetAngle(adjacentSide As Double, oppositeSide As Double, knownAngle As Double, Optional knownAngleCorrespondsToAdjacentSide As Boolean = True) As Double
If knownAngleCorrespondsToAdjacentSide Then
'Calculate one way
' or call private method
Else
'Calculate the other
' or call the other private method
End If
Return calculatedAngle
End Function

Probably the best thing to do would be to use one method. Your method's signature would look something like this:
Public Function GetAngle(commonSide As Double, commonAngle As Double, otherSide As Double) As Double
Your method would return the other, target angle of the triangle. I couldn't really think of better parameter names, though.

ASCII art time!
a
__________
\B C/
\ /
c \ / b
\ A/
\/
Given that b and B can be transposed with c and C, there are only three formulas you need:
A = ƒ(a, b, B), transpose (b, B) for (c, C) if necessary.
A = ƒ(a, b, C), transpose (b, C) for (c, B) if necessary.
A = ƒ(b, c, B), transpose (B) for (C) if necessary.
Given theses all have two lengths and an angle, you'll need three different method names:
GetAngleFromOppositeLineAndLooseAngle(oppositeLine , adjacentLine , looseAngle)
GetAngleFromOppositeLineAndJointAngle(oppositeLine , adjacentLine , jointAngle)
GetAngleFromAdjacentLines (adjacentLine1, adjacentLine2, looseAngle)
Otherwise, yes you'll have to pass a structure and discern the missing information. Use Nullable(Of Double) or Double.NaN to pass unknown values.

Related

How to use np.log or np.exp in GEKKO intermediate

I am using gekko to solve a system of equations. As an intermediate step I am using an intermediate that plugs the MV temperature into the following function:
def riedelVP(T, const):
'''Returns Vapor Pressure
INPUTS
:T - Temperature (K)
:const - A, B, C, D, E constants for eqn
OUTPUTS
:Y - Pressure in Pascals'''
# unpack constants
a, b, c, d, e = const
# plug into equation
Y = np.exp(a+b/T+c*np.log(T) + d*T**e)
return Y
When I do this, I get the following Error:
I have tried using T.value and T.value[0] as arguments into the function instead of T.
TypeError: loop of ufunc does not support argument 0 of type GKVariable which has no callable log method
How can I use a function with exp and log in a gekko intermediate
The problem in this case is that both the np.exp() function and the np.log function require an argument that is a float, while gekko variables are their own type. If you were to use gekko's methods for exponentiation and taking the logarithm in the function, it will work. To do so, use the m.exp or m.log methods. In this example, I already had a gekko model created using m = GEKKO(), then I could create the function:
def riedelVP(T, const):
'''Returns Vapor Pressure
INPUTS
:T - Temperature (K)
:const - A, B, C, D, E constants for eqn
OUTPUTS
:Y - Pressure in Pascals'''
# unpack constants
a, b, c, d, e = const
# plug into equation
Y = m.exp(a+b/T+c*m.log(T) + d*T**e)
return Y
Use gekko's analogous methods when type errors in functions occur.

Destructuring a list with equations in maxima

Say that I have the following list of equations:
list: [x=1, y=2, z=3];
I use this pattern often to have multiple return values from a function. Kind of of like how you would use an object, in for example, javascript. However, in javascript, I can do things like this. Say that myFunction() returns the object {x:1, y:2, z:3}, then I can destructure it with this syntax:
let {x,y,z} = myFunction();
And now x,y,z are assigned the values 1,2,3 in the current scope.
Is there anything like this in maxima? Now I use this:
x: subst(list, x);
y: subst(list, y);
z: subst(list, z);
How about this. Let l be a list of equations of the form somesymbol = somevalue. I think all you need is:
map (lhs, l) :: map (rhs, l);
Here map(lhs, l) yields the list of symbols, and map(rhs, l) yields the list of values. The operator :: means evaluate the left-hand side and assign the right-hand side to it. When the left-hand side is a list, then Maxima assigns each value on the right-hand side to the corresponding element on the left.
E.g.:
(%i1) l : [a = 12, b = 34, d = 56] $
(%i2) map (lhs, l) :: map (rhs, l);
(%o2) [12, 34, 56]
(%i3) values;
(%o3) [l, a, b, d]
(%i4) a;
(%o4) 12
(%i5) b;
(%o5) 34
(%i6) d;
(%o6) 56
You can probably achieve it and write a function that could be called as f(['x, 'y, 'z], list); but you will have to be able to make some assignments between symbols and values. This could be done by writing a tiny ad hoc Lisp function being:
(defun $assign (symb val) (set symb val))
You can see how it works (as a first test) by first typing (form within Maxima):
:lisp (defun $assign (symb val) (set symb val))
Then, use it as: assign('x, 42) which should assign the value 42 to the Maxima variable x.
If you want to go with that idea, you should write a tiny Lisp file in your ~/.maxima directory (this is a directory where you can put your most used functions); call it for instance myfuncs.lisp and put the function above (without the :lisp prefix); then edit (in the very same directory) your maxima-init.mac file, which is read at startup and add the two following things:
add a line containing load("myfuncs.lisp"); before the following part;
define your own Maxima function (in plain Maxima syntax with no need to care about Lisp). Your function should contain some kind of loop for performing all assignments; now you could use the assign(symbol, value) function for each variable.
Your function could be something like:
f(vars, l) := for i:1 thru length(l) do assign(vars[i], l[i]) $
which merely assign each value from the second argument to the corresponding symbol in the first argument.
Thus, f(['x, 'y], [1, 2]) will perform the expected assigments; of course you can start from that for doing more precisely what you need.

Which languages have a primitive operation for swapping variables?

In most languages, if you want to swap two variables, it's something like:
var c = b
b = a
a = c
Yes, you can do fancy hacks with XOR if you like but it's generally 3 lines of code for a single operation. Are there any languages that have swapping variables as a primitive in the language?
Lua, Python, Ruby and more support this notation:
a, b = b, a
And javascript sure needs no temporary variable either ;)
a = -(b = (a += b) - b) + a;
For more examples on how to swap variables (in 86 languages), see: http://rosettacode.org/wiki/Generic_swap
In most dynamic languages you can do something like this to swap:
a, b = b, a
Now a have the value of b, and b has the value of a. I am not sure if this is what you meant or not.

Optimizing partial computation in Haskell

I'm curious how to optimize this code :
fun n = (sum l, f $ f0 l, g $ g0 l)
where l = map h [1..n]
Assuming that f, f0, g, g0, and h are all costly, but the creation and storage of l is extremely expensive.
As written, l is stored until the returned tuple is fully evaluated or garbage collected. Instead, length l, f0 l, and g0 l should all be executed whenever any one of them is executed, but f and g should be delayed.
It appears this behavior could be fixed by writing :
fun n = a `seq` b `seq` c `seq` (a, f b, g c)
where
l = map h [1..n]
a = sum l
b = inline f0 $ l
c = inline g0 $ l
Or the very similar :
fun n = (a,b,c) `deepSeq` (a, f b, g c)
where ...
We could perhaps specify a bunch of internal types to achieve the same effects as well, which looks painful. Are there any other options?
Also, I'm obviously hoping with my inlines that the compiler fuses sum, f0, and g0 into a single loop that constructs and consumes l term by term. I could make this explicit through manual inlining, but that'd suck. Are there ways to explicitly prevent the list l from ever being created and/or compel inlining? Pragmas that produce warnings or errors if inlining or fusion fail during compilation perhaps?
As an aside, I'm curious about why seq, inline, lazy, etc. are all defined to by let x = x in x in the Prelude. Is this simply to give them a definition for the compiler to override?
If you want to be sure, the only way is to do it yourself. For any given compiler version, you can try out several source-formulations and check the generated core/assembly/llvm byte-code/whatever whether it does what you want. But that could break with each new compiler version.
If you write
fun n = a `seq` b `seq` c `seq` (a, f b, g c)
where
l = map h [1..n]
a = sum l
b = inline f0 $ l
c = inline g0 $ l
or the deepseq version thereof, the compiler might be able to merge the computations of a, b and c to be performed in parallel (not in the concurrency sense) during a single traversal of l, but for the time being, I'm rather convinced that GHC doesn't, and I'd be surprised if JHC or UHC did. And for that the structure of computing b and c needs to be simple enough.
The only way to obtain the desired result portably across compilers and compiler versions is to do it yourself. For the next few years, at least.
Depending on f0 and g0, it might be as simple as doing a strict left fold with appropriate accumulator type and combining function, like the famous average
data P = P {-# UNPACK #-} !Int {-# UNPACK #-} !Double
average :: [Double] -> Double
average = ratio . foldl' count (P 0 0)
where
ratio (P n s) = s / fromIntegral n
count (P n s) x = P (n+1) (s+x)
but if the structure of f0 and/or g0 doesn't fit, say one's a left fold and the other a right fold, it may be impossible to do the computation in one traversal. In such cases, the choice is between recreating l and storing l. Storing l is easy to achieve with explicit sharing (where l = map h [1..n]), but recreating it may be difficult to achieve if the compiler does some common subexpression elimination (unfortunately, GHC does have a tendency to share lists of that form, even though it does little CSE). For GHC, the flags fno-cse and -fno-full-laziness can help avoiding unwanted sharing.

First & Follow Sets check for simple grammar

Here's a few questions I had on a quiz in a class and just want to verify their correctness.
Grammar:
S -> ABC
A -> df | epsilon
B -> f | epsilon
C -> g | epsilon
1.) The Follow set of B contains g and epsilon (T/F)? Ans: F.
There is no epsilon in the Follow sets, correct? (Only $ aka end of input)
2.) The First set of S contains d, f, g, and epsilon (T/F)? Ans: T.
I said false for this because I thought First(S) = First(A), which g is not a part of. Who is correct?
You are correct. If epsilon is involved, it will be accounted for in the First set, not the Follow set. If it's possible for the production to end the string, then $ goes in the Follow set, not epsilon.
The quiz is correct. The production S can indeed start with any of d, f, and g, and it can also be started by the empty string. Consider the input string g. It matches S, right? A is satisfied by the empty string, B is satisfied by the empty string, and C is satisfied by g. Since A, B, and C are all satisfied, S is satisfied. The first character consumed by S is g, so g must be in First(S).