I am trying to solve a system of equations and then have the results stored in variables variables for plotting or further calculation.
%pylab inline
from sympy import init_printing;init_printing()
from sympy import *
d,vf,a,vi,t,x,h,g,theta,ans=symbols('d vf a vi t x h g theta ans')
equations=[Eq(sin(theta),(0.5*g*t**2+h)/(vi*t)),Eq(cos(theta),x/(vi*t))]
ans=solve(equations,[h,t],dict=True)
but ans is just a single entry and I do not know how to get the equation for h by itself and the equation for t by itself. The results are however correct
thanks for any and all help ( I am using Ipython)
In [14]: ans
Out[14]:
⎡⎧ 2 ⎫⎤
⎢⎪ 0.5⋅g⋅x x ⎪⎥
⎢⎨h: - ─────────── + x⋅tan(θ), t: ─────────⎬⎥
⎢⎪ 2 2 vi⋅cos(θ)⎪⎥
⎣⎩ vi ⋅cos (θ) ⎭⎦
So you can see here, the answer is a list containing a dictionary. To get the first (and only) item of the list, use ans[0]. To get the elements of the dictionary, use [key] with the dictionary key, which in this case are the symbols you solved for. So to get the answers, you would do
In [16]: ans[0][h]
Out[16]:
2
0.5⋅g⋅x
- ─────────── + x⋅tan(θ)
2 2
vi ⋅cos (θ)
In [17]: ans[0][t]
Out[17]:
x
─────────
vi⋅cos(θ)
Related
How do i passed 2 variables to a lambda function, where x is a number and y is a symbol.
I have written this, but it wouldn't process
{[x;y]
// some calculation with x and y
}
each ((til 5) ,\:/: `a`b`c`d`f)
It seems to be complaining that i am missing another arg.
Here's an example that I think does what you're looking for:
q){string[x],string y}./: raze (til 5) ,\:/: `a`b`c`d`f
The issue with your example is that you need to raze the output of ((til 5) ,\:/: `a`b`c`d`f) to get your list of 2 inputs.
Passing a list of variables into a function is accomplished using "." (dot apply) http://code.kx.com/q/ref/unclassified/#apply
.e.g
q){x+y} . 10 2
12
In my example, I've then used an "each right" to then apply to each pair. http://code.kx.com/q/ref/adverbs/#each-right
Alternatively, you could use the each instead if you wrapped the function in another lamda
q){{string[x],string y} . x} each raze (til 5) ,\:/: `a`b`c`d`f
Instead of generating a list of arguments using cross or ",/:\:" and passing each of these into your function, modify your function with each left each right ("/:\:") to give you all combination. his should take the format;
x f/:\: y
Where x and y are both lists. Reusing the example {string[x],string y};
til[5] {string[x], string y}/:\:`a`b`c`d
This will give you a matrix of all combinations of x and y. If you want to flatten that list add a 'raze'
I'd like to write several messages and tables on the same .txt file.
For example:
x=[23.9,10.9,8.9,14.2]
y=[9.83,8.04,7.47,8.32]
file=fopen('Results.txt','wt');
fprintf(file,'Results1\n');
fprintf(file,'%.2f %.2f\r\n',x,y);
fprintf(file,'Results2\n');
fclose(file);
I get this result as .txt:
Results1
23.90 10.90
8.90 14.20
9.83 8.04
7.47 8.32
Results2
But I should get this one:
Results1
23.90 9.83
10.90 8.04
8.90 7.47
14.20 8.32
Results2
Instead of fprintf(file,'%.2f %.2f\r\n',x,y);), I was trying to use:
ResultsTable2 = table(x,y);
writetable(file,ResultsTable2);
but didn't succeed. How to write the required .txt file?
Careful examination of your output shows that all the elements of x were printed before all the elements of y.
The documentation confirms that this is the expected behavior. Check out this example
A1 = [9.9, 9900];
A2 = [8.8, 7.7 ; ...
8800, 7700];
formatSpec = 'X is %4.2f meters or %8.3f mm\n';
fprintf(formatSpec,A1,A2)
X is 9.90 meters or 9900.000 mm
X is 8.80 meters or 8800.000 mm
X is 7.70 meters or 7700.000 mm
Even though the arguments to fprintf are in the order A1, A2. It first prints all the values from A1, and then it prints all the values from A2 going in single index order.
Therefore, if you want to alternate values from x and y during printing, you need to interleave them in a new variable. There are several possible ways to do so.
One example,
XY = reshape([x;y], 1, []);
Then everything should print as expected
fprintf(file, '%.2f %.2f\r\n', XY);
% or if you want to print to command window
% fprintf('%.2f %.2f\r\n', XY);
23.90 9.83
10.90 8.04
8.90 7.47
14.20 8.32
The correct answer for how to output data with fprintf is given by Cecilia: each argument will be iterated completely through in the order it appears in the argument list, so you have to combine the data into one matrix argument that will be iterated through column-wise to generate the desired output.
You also mentioned trying to use a table and the writetable function, so I though I'd add the correct way to do that in case you were curious:
ResultsTable2 = table(x(:), y(:)); % Pass data as column vectors
writetable(ResultsTable2, 'Results.txt', 'WriteVariableNames', false);
I am trying to take the derivative of a function including a boolean variable with sympy.
My expected result:
Two different derivatives, depending on the boolean being either True or False (i.e. 1 or 0).
Example:
import sympy as sy
c, x = sy.symbols("c x", positive=True, real=True)
bo = sy.Function("bo")
fct1 = sy.Function("fct1")
fct2 = sy.Function("fct2")
FOC2 = sy.Function("FOC2")
y = 5
a = 2
b = 4
def fct1(x):
return -0.004*x**2 + 0.25*x + 4
# the following gives the smaller positive intercept with the x-axis)
# this intercept is the threshold value for the boolean function, bo
min(sy.solve(fct1(x)-y, x))
def bo(x):
if fct1(x) <= y:
return 1
else:
return 0
def fct2(c, x):
return a + b*c + bo(x)*c
def FOC2(c, x):
return sy.diff(fct2(c, x), c)
print(FOC2(c, x))
The min-function after the comments shows me the threshold of x for bo being True or False would be 4.29..., thus positive and real.
Output:
TypeError: cannot determine truth value of Relation
I understand that the truth value depends on x, which is a symbol. Thus, without knowing x one cannot determine bo.
But how would I get my expected result, where bo is symbolic?
First off, I would advise you to carefully consider what is going on in your code the way it is pasted above. You first define a few sympy functions, e.g.
fct1 = sy.Function("fct1")
So after this, fct1 is an undefined sympy.Function - undefined in the sense that it is neither specified what its arguments are, nor what the function looks like.
However, then you define same-named functions explicitly, as in
def fct1(x):
return -0.004*x**2 + 0.25*x + 4
Note however, that at this point, fct1 ceases to be a sympy.Function, or any sympy object for that matter: you overwrite the old definition, and it is now just a regular python function!
This is also the reason that you get the error: when you call bo(x), python tries to evaluate
-0.004*x**2 + 0.25*x + 4 <= 5
and return a value according to your definition of bo(). But python does not know whether the above is true (or how to make that comparison), so it complains.
I would suggest 2 changes:
Instead of python functions, as in the code, you could simply use sympy expressions, e.g.
fct1 = -0.004*x**2 + 0.25*x + 4
To get the truth value of your condition, I would suggest to use the Heaviside function (wiki), which evaluates to 0 for a negative argument, and to 1 for positive. Its implementation in sympy is sympy.Heaviside.
Your code could then look as follows:
import sympy as sy
c, x = sy.symbols("c x", positive=True, real=True)
y = 5
a = 2
b = 4
fct1 = -0.004*x**2 + 0.25*x + 4
bo = sy.Heaviside(y - fct1)
fct2 = a + b*c + bo * c
FOC2 = sy.diff(fct2, c)
print(FOC2)
Two comments on the line
bo = sy.Heaviside(y - fct1)
(1) The current implementation does not evaluate sympy.Heaviside(0)by default; this is beacause there's differing definitions around (some define it to be 1, others 1/2). You'd want it to be 1, to be in accordance with the (weak) inequality in the OP. In sympy 1.1, this can be achieved by passing an additional argument to Heaviside, namely whatever you want Heaviside(0) to evaluate to:
bo = sy.Heaviside(y - fct1, 1)
This is not supported in older versions of sympy.
(2) You will get your FOC2, again involving a Heaviside term. What I like about this, is that you could keep working with this expression, say if you wanted to take a second derivative and so on. If, for the sake of readability, you would prefer a piecewise expression - no problem. Just replace the according line with
bo = sy.Heaviside(y - fct1)._eval_rewrite_as_Piecewise(y-fct1)
Which will translate to a piecewise function automatically. (note that under older versions, this automatically implicitly uses Heaviside(0) = 0.5 - best to use (1) and (2) together:
bo = sy.Heaviside(y - fct1, 1)._eval_rewrite_as_Piecewise(y-fct1)
Unfortunately, I don't have a working sympy 1.1 at my hands right now and can only test the old code.
One more noteconcerning sympy's piecewise functions: they are much more readable if using sympy's latex printing, by inserting
sy.init_printing()
early in the code.
(Disclaimer: I am by no means an expert in sympy, and there might be other, preferable solutions out there. Just trying to make a suggestion!)
I am attempting to write a script to import a large .txt file containing multiple columns of data into seperate variables within Matlab.
I have reached a stage where I have my 7 datasets:
Var1= 3230 x 1 double
Var2= 3230 x 1 double
Var3= 3230 x 1 double
Var4= 3230 x 1 double
Var5= 3230 x 1 double
Var6= 3230 x 1 double
Var7= 3230 x 1 double
and an array containing all of the variable names in different cells:
nameArray= 1 x 7 cell
My question is: how do I create variables with the same names as those within nameArray and subsequently populate them with data from my datasets?
You have three options:
Use assignin:
assignin('caller', nameArray{1}, Var1)
assignin('caller', nameArray{2}, Var2)
...
This will create a variable with name nameArray{1} and value Var1 in the namespace of the caller.
Build a struct:
x = struct()
x.(nameArray{1}) = Var1
...
This builds a struct with dynamically assigned fields.
As #Scott suggests in his answer: Use readtable:
T = readTable('mydatafile.txt')
This yields a similar result as option 2. But T is of type table and not struct. Tables are availble in Matlab versions R2013b and newer.
And of course you should use a loop
You might want to consider using T = readTable('mydatafile.txt'). This allows you to load a file with seperate columns and access those colums using their column name, for example like this: T.MyFirstColumn. See the manual on readtable for some examples.
It looks like this has been asked many times, but none of the past posts seem to solve my question. All those had to do with matrix/vector while my code does not have any of these, just simple variables. It takes three variables as arguments. It works perfectly fine within the Matlab environment. I only got the error when I compiled it with mcc -m Normal.m and tried to run with the executable like this "./Normal 1 5 0.5". The complete error message is:
Error using /
Matrix dimensions must agree.
Error in Normal (line 4)
MATLAB:dimagree
It is complaining about line 4: N=2/dt, what is wrong with this?
Here is the code:
function val=Normal(l1,l2,dt)
const=(l2/l1-1);
N=2/dt;
S=1.0/sqrt(l2/l1);
Z(1)=S;
for i=2:N
t= -1+(i-1)*dt;
Z(i)=1.0/sqrt(const*t*t+1);
S=S+2*Z(i);
end
Z(21)=1.0/(l2/l1);
S=S+1.0/sqrt(l2/l1);
val=dt*S/2;
end
But dt is not a scalar when passed into the standalone through the command ./Normal 1 5 0.5. It is a character array with 3 elements ('0', '.','5')!
When passing numerical arguments to a standalone, they are passed as strings. Thus, inside the function, you need to convert '0.5' into a double, and similarly for l1 and l2:
dt = str2num(dt);
l1 = str2num(l1);
l2 = str2num(l2);
Note that you can use isdeployed to determine at runtime if the function is a standalone:
if isdeployed, dt = str2num(dt); end
And you might need to display the result:
if isdeployed, disp(val); end
Result:
>> system('Normal 1 5 0.5');
1.4307
>> Normal(1,5,0.5) % .m function for comparison
ans =
1.4307