Symbolic computation with formulas and solver - symbolic-math

I am looking for a programming language and a way to automatize the following problems.
Given a formula connecting different variables, say g=GM/r^2, and values for all but one of the variables, (g=9.8,M=5E25,G=6.7E-11), how can I program a routine which:
a) Identifies the unknown variable
b) symbolically, solves the formula
c) finally, substitutes values of known variables and solves the equation for the unknown.
I am far from an expert in programming and the only thing it came to my mind was a slow process in which, one checks variable after variable which one has not been set to a value and according to that use the appropriate rearrangement of the formula to calculate the unknown.
(eg. in our case, the program checks variable after variable until it find that r is the unknown. Then, it uses the same formula but ready to calculate r, i.e. r=sqrt(GM/g))
I am sure there is a fast an elegant language to do this but I cannot figure it out.
Thanks in advance for your help.

Well, here is one way to do it, using Maxima.
eq : g = G * M / r^2;
known_values : [g = 9.8, M = 5e25, G = 6.7e-11];
eq1 : subst (known_values, eq);
remaining_var : listofvars (eq1);
solve (eq1, remaining_var);
=> [r = -5000000*sqrt(670)/7, r = 5000000*sqrt(670)/7]
You can use the function float to get a floating point value from that.
You can probably also do it with Sympy or something else.

For such a simple case, the approach that you suggest is quite appropriate.
The "slow" process might take on the order of 10 nanoseconds to find the unknown variable (using a compiled language), so I wouldn't worry so much.
Indeed symbolic computation programs are able to derive the explicit formulas, that you can retranscript in most programming languages
g=GM/r²
G=gr²/M
M=gr²/G
r=√GM/g
// C code
if (g == 0) g= G * M / (r * r);
else if (G == 0) G= g * r * r / M;
else if (M == 0) M= g * r * r / G;
else r= Math.sqrt(G * M / g);
For instance, the free Microsoft Mathematics can do it. But in this particular case, just do it by hand.
For a completely integrated solution with built-in scripting, think of Mathematica, Mathcad, Maple and the like.

Related

Elementwise product between a vector and a matrix using GNU Blas subroutines

I am working on C, using GNU library for scientific computing. Essentially, I need to do the equivalent of the following MATLAB code:
x=x.*(A*x);
where x is a gsl_vector, and A is a gsl_matrix.
I managed to do (A*x) with the following command:
gsl_blas_dgemv(CblasNoTrans, 1.0, A, x, 1.0, res);
where res is an another gsl_vector, which stores the result. If the matrix A has size m * m, and vector x has size m * 1, then vector res will have size m * 1.
Now, what remains to be done is the elementwise product of vectors x and res (the results should be a vector). Unfortunately, I am stuck on this and cannot find the function which does that.
If anyone can help me on that, I would be very grateful. In addition, does anyone know if there is some better documentation of GNU rather than https://www.gnu.org/software/gsl/manual/html_node/GSL-BLAS-Interface.html#GSL-BLAS-Interface which so far is confusing me.
Finally, would I lose in time performance if I do this step by simply using a for loop (the size of the vector is around 11000 and this step will be repeated 500-5000 times)?
for (i = 0; i < m; i++)
gsl_vector_set(res, i, gsl_vector_get(x, i) * gsl_vector_get(res, i));
Thanks!
The function you want is:
gsl_vector_mul(res, x)
I have used Intel's MKL, and I like the documentation on their website for these BLAS routines.
The for-loop is ok if GSL is well designed. For example gsl_vector_set() and gsl_vector_get() can be inlined. You could compare the running time with gsl_blas_daxpy. The for-loop is well optimized if the timing result is similar.
On the other hand, you may want to try a much better matrix library Eigen, with which you can implement your operation with the code similar to this
x = x.array() * (A * x).array();

Haskell : Increment index in a loop

I have a function that calculates f(n) in Haskell.
I have to write a loop so that it will start calculating values from f(0) to f(n), and will every time compare the value of f(i) with some fixed value.
I am an expert in OOP, hence I am finding it difficult to think in the functional way.
For example, I have to write something like
while (number < f(i))
i++
How would I write this in Haskell?
The standard approach here is
Create an infinite list containing all values of f(n).
Search this list until you find what you're after.
For example,
takeWhile (number <) $ map f [0..]
If you want to give up after you reach "n", you can easily add that as a separate step:
takeWhile (number <) $ take n $ map f [0..]
or, alternatively,
takeWhile (number <) $ map f [0 .. n]
You can do all sorts of other filtering, grouping and processing in this way. But it requires a mental shift. It's a bit like the difference between writing a for-loop to search a table, versus writing an SQL query. Think about Haskell as a bit like SQL, and you'll usually see how to structure your code.
You can generate the list of the is such that f i is larger than your number:
[ i | i<-[0..] , f i > number ]
Then, you can simply take the first one, if that's all you want:
head [ i | i<-[0..] , f i > number ]
Often, many idiomatic loops in imperative programming can be rephrased as list comprehensions, or expressed through map, filter, foldl, foldr. In the general case, when the loop is more complex, you can always exploit recursion instead.
Keep in mind that a "blind" translation from imperative to functional programming will often lead to non-idiomatic, hard-to-read code, as it would be the case when translating in the opposite direction. Still, I find it relieving that such translation is always possible.
If you are new to functional programming, I would advise against learning it by translating what you know about imperative programming. Rather, start from scratch following a good book (LYAH is a popular choice).
The first thing that's weird from a functional approach is that it's unclear what the result of your computation is. Do you care about the final result of f (i)? Perhaps you care about i itself. Without side effects everything neends to have a value.
Let's assume you want the final value of the function f (i) as soon as some comparison fails. You can simulate your own while loops using recursion and guards!
while :: Int -> Int -> (Int -> Int) -> Int
while start number f
| val >= number = val
| otherwise = while (start + 1) number f
where
val = f start
Instead of explicit recursion, you can use until e.g.
findGreaterThan :: (Int -> Int) -> Int -> Int -> (Int, Int)
findGreaterThan f init max = until (\(v, i) -> v >= max) (\(v, i) -> (f v, i + 1)) (init, 0)
this returns a pair containing the first value to fail the condition and the number of iterations of the given function.

Appending to array within a loop

I am a SAS programmer learning R.
I have a matrix receivables read from a csv file.
I wish to read the value in the "transit" column, if the value of "id" column of a row is >= 1100000000.
I did this (loop 1):
x = vector()
for (i in 1:length(receivables[,"transit"])){
if(receivables[i,"id"] >= 1100000000){
append(x, receivables[i,"transit"]);
}
}
But, it does not work because after running the loop x is still empty.
>x
logical(0)
However, I was able to accomplish my task with (loop 2):
k=0
x=vector()
for (i in 1:length(receivables[,"transit"])){
if(receivables[i,"id"] >= 1100000000){
k=k+1
x[k] = receivables[i,"transit"]
}
}
Or, with (loop 3):
x = vector()
for (i in 1:length(receivables[,"transit"])){
if(receivables[i,"id"] >= 1100000000){
x <- append(x, receivables[i,"transit"]);
}
}
Why didn't the append function work in the loop as it would in command line?
Actually, to teach me how to fish, what is the attitude/beatitude one must bear in mind when operating functions in a loop as opposed to operating them in command line.
Which is more efficient? Loop 2 or loop 3?
Ok, a few things.
append didn't work in your first attempt because you did not assign the result to anything. In general, R does not work "in place". It is more of a functional language, which means that changes must always be assigned to something. (There are exceptions, but trying to bend this rule too early will get you in trouble.)
A bigger point is that "growing" objects in R is a big no-no. You will quickly start to wonder why anyone could possible use R, because growing objects like this will quickly become very, very slow.
Instead, learn to use vectorized operations, like:
receivables[receivables[,"id"] >= 1100000000,"transit"]

MATLAB min(array) gives index exceeds array dimensions [duplicate]

This question already has an answer here:
sum(Array) says index exceeds matrix dimensions [duplicate]
(1 answer)
Closed 3 years ago.
I am trying to find the minimum value of a function of two variables, and then find the value of the variables.
My method is to iterate the function through several values of the variables and then use the min function to find the lowest value.
minval = -10;
maxval = 10;
n = 1;
for x = minval:maxval
for y = minval:maxval
f(n) = abs(x-1)+abs(y-1)+abs(x-3)+abs(y-5)+abs(x-8)+abs(y-3);
n=n+1;
end
end
f(n) = abs(x-1)+abs(y-1)+abs(x-3)+abs(y-5)+abs(x-8)+abs(y-3);
fmin = min(f)
The problem is with the last line:
fmin = min(f)
I am getting the error
??? Index exceeds matrix dimensions.
Error in ==> Lab2 at 65
fmin = min(f)
Why is this? Any help is greatly appreciated.
Don't define a variable named min. Try this:
which min
What does it tell you?
Note that functions in MATLAB can be overloaded by creating variables with the same name. When you do so, you prevent the function from being accessed by MATLAB. This is RARELY a good idea, so don't do it. The solution is
clear min
So you will delete that variable you have created. Of course, if there was something important in that variable, stuff it somewhere else first.
It does indeed look like you have declared a variable called min and so Matlab now treats it like a variable and not a function so it thinks you are trying to index the variable min with the vector f.
But just a comment on your code, leaving off whatever f(442) is you could achieve the same thing in a much more matlabesque fashion without loops like this:
minval = -10;
maxval = 10;
X = minval:maxval;
Y = X;
[xx, yy] = meshgrid(X, Y);
F = abs(xx-1) + abs(yy-1) + abs(xx-3) + abs(yy-5) +abs(xx-8) + abs(yy-3);
Your f is now equivalent to F(:)' (without the final value...), prove it to yourself like this: sum(f(1:end-1) == F(:)')
F as a matrix probably makes more sense than f as a flat vector anyway and you can find the min of F like this: min(F(:))
This code runs perfectly when I plug it into my version of Matlab.
If the error is occuring on line 65, then there must be something else going on in your program. Try and turn this part of your program into a function, so that it won't be impacted by everything else that you're working on.

Example equation translation in C?

Originally I asked: How to tranlate equations to programming instructions. Judging by the content found # Wikipedia: Category: Equations That's apparently too vague for simple Q&A. So I've deleted it.
Since I learn best by example, I would like to see what this equation looks like as a function in C.
(desired course is d, ground speed is Vg, heading is a, true airspeed is Va, wind direction is w, wind speed is Vw. d, a and w are angles. Vg, Va and Vw are consistent units of speed. \pi is 3.14159...)
The above equation is for calculating true ground speed Taken from the E6B flight computer
To be clear: I'm not asking for advice, opinions or rhetoric. I'm not asking you to do my homework. I'm asking for help to understand the process of translation from equation to functional implementation. Bear with me, I know there are quite a few aspects to be aware of in such an endeavour, I would simply like to explore the symmetry between these two symbol systems using my own knowledge, capabilities and understanding.
Due to the fact that I would like to explore the symmetry, I should ask that you keep program identifiers as closely related to their representation in the formula as possible. Key words, catch phrases and rule references pertinent to this example translation in context (code comments) are a plus.
If my question is flawed due to an OVERSIGHT, please express your opinion in the comments below.
You enter formulas very much like you would in a graphing calculator. The part with the cos would go like this:
#include <math.h>
int main(void) {
double d, w, da;
double result;
result = cos( ( M_PI * ( d - w + da ) ) / ( 180 * M_PI / 180 ) );
}
You can probably add the rest of the formula quite easily. Of course you have to initialize all your variables with something reasonable before computing the result, and finally do something with it. Don't put it all on one line, use temporary variables (so in the next step you substitute the previous result for the entire cos expression) and split the calculation to parts that you can meaningfully describe in domain-specific terms, if possible.
Now regarding what to do differently in programming compared to a math publication, often other programmers won't be experts in your domain. I don't know at all for example what that formula does just by looking at it. Therefore I'd appreciate renaming the variables and adding comments relevant to the practical use of the formula (your question didn't originally explain what the variable names mean so I came up with very plausible ones). Like this:
#include <math.h>
int main(void) {
double density, angledelta;
double weight; /* Weight of cake with plate included. */
double deg2rad;
double result;
deg2rad = M_PI / 180;
/* Calculate X coordinate of next cake slice intersection with cake perimeter
using fair cake splitting with density heuristics. */
result = cos( ( M_PI * ( density - weight + angledelta ) ) / ( 180 * deg2rad ) );
}
To naively convert an equation into c you break it into parts based off the order of operations. Then you can refine it as needed.
The way I would break it down:
The function would have the parametres: d, w, deltaA, Va, Vw
Step1 = d - w + ΔA
Step2 = Math.PI * Step1
Step3 = Step2 / 180 ignore the units(deg)
Step4 = cos(Step3)
Step5 = Va * Va
Step6 = Vw * Vw
Step7 = 2 * Va * Vw
Step8 = Step5 + Step6 - Step7
Step9 = Step8 * Step4
Step10 = Math.sqrt(Step9)
Return Step10

Resources