How do I calculate the sqrt in MathNet.Symbolics - mathnet-numerics

I'm using the MathNet.Symbolics library to simplyfy expressions like this :
string f = Infix.Print(Infix.ParseOrThrow("A+5*2"))
This works as expected (f = A+10) but trying to get the root of a number is a lot harder than I expected. For example :
string f = Infix.Print(Infix.ParseOrThrow("sqrt(9)"))
f = "sqrt(9)" instead of f = "3" as you would expect.
string f = Infix.Print(Infix.ParseOrThrow("sqrt(x^2)"))
f = "sqrt(x^2)" insted of f = "x"
string f = Infix.Print(Infix.ParseOrThrow("9^(1/2)"))
also doesn't work. Insted it gets simplified to f = "sqrt(9)"
How do I force it to calculate the sqrt of a number/variable?
Are there any other problems I could expect to run into when using the "auto-simplification" of MathNet.Symbolics?

You need to run the expression through the Evaluate method:
string f = Infix.Print(Infix.ParseOrThrow("sqrt(9)"));
double result = Evaluate.Evaluate(null, f);

Related

How to add, subtract, etc. two structs element-by-element when they have the same fields

I have various structs with fields W, P, E, which contain numerical values. I want to develop a clean way to add and subtract these structs without unpacking and repacking in subfunctions each time (which has been my solution thus far)
For example, given:
S.W = 2
S.P = 3
S.E = 4
M.W = 20
M.P = 30
M.E = 40
I want to be able to do X = S + M and end up with:
X.W = 22
X.P = 33
X.E = 44
My current attempt to do this, is by means of a new class, which looks as follows:
classdef CV
properties
W
P
E
end
methods
function r = plus(o1,o2)
r = CV;
r.E = o1.E + o2.E;
r.P = o1.P + o2.P;
r.W = o1.W + o2.W;
end
end
end
This allows for doing S + M and returns a new variable in the same form as the inputs. I'm generally unfamiliar with classes, and wanted to know if this is proper form. If so, I might go ahead and add functions for minus and times in the methods section. However, this seems like it requires a lot of repetitive code and I feel there must be a simpler solution. Any advice is much appreciated.
The following code directly works on structs without nesting them in a class. It is assumed that the two input structs have the same field names (in this example W, P, and E), however, the order of those may be arbitrary (you mentioned in a comment that this is important for your application).
function X = structplus(S, M)
fn = fieldnames(S);
for i = 1 : numel(fn)
X.(fn{i}) = M.(fn{i}) + S.(fn{i});
end
end
So defining
S.W = 2
S.P = 3
S.E = 4
M.E = 40
M.P = 30
M.W = 20
(note the reverse order of M) and calling
X = structplus(S, M)
yields a struct with field names that are ordered like the first argument:
X =
struct with fields:
W: 22
P: 33
E: 44
To expand on Le Phlaux's answer, you can provide a function handle to the required binary operator (e.g. #plus, #minus) and work on sub-structures recursively
function out = structBinaryFunc(in1, in2, func)
fn = fieldnames(in1);
for ii = 1:numel(fn)
if isstruct(in1.(fn{ii}))
out.(fn{ii}) = structBinaryFunc(in1.(fn{ii}), in2.(fn{ii}), func)
else
out.(fn{ii}) = func(in1.(fn{ii}), in2.(fn{ii}));
end
end
For your example you would call X = structBinaryFunc(S, M, #plus);.

not enough argument, self-defined function in matlab

I am a newbie of matlab and am trying to define a pretty complex function to plot it. The content of file is following:
function [res] = distribution (input)
a = factorial(30)
b = factorial(input) * factorial(30-input)
c = power(0.05, input)
d = power(0.95, 30-input)
a/b*c*d
end
in the file named distribution with .m extension. But when I run it error returns: "Error using distribution (line 4). Not enough input arguments."
I read through the "Getting Started" and find no solution. Does anyone have suggestions on this?
The name of the single argument to your function distribution(..), namely argument input, conflicts with the existing native input command of Matlab,
input: Prompt for user input.
...
x = input(prompt)
Try choosing a different name of this argument (in example below: foo), and also remember to return your result by assigning it to the return variable res:
function res = distribution (foo)
a = factorial(30);
b = factorial(foo) * factorial(30-foo);
c = power(0.05, foo);
d = power(0.95, 30-foo);
res = a/b*c*d; % <--- note, return parameter assignment
end

Use of if statement in for loop in this code

What does the statement for if=ilow:ihigh mean in this program?
function [d]=for_taup(m,dt,h,q,N,flow,fhigh);
nt= max(size(m));
nh = max(size(h));
M = fft(m,[],1);
D = zeros(nt,nh);
i = sqrt(-1);
ilow = floor(flow*dt*nt)+1; if ilow<1; ilow=1;end;
ihigh = floor(fhigh*dt*nt)+1;
if ihigh>floor(nt/2)+1; ihigh=floor(nt/2)+1;end
for if=ilow:ihigh
f = 2.*pi*(if-1)/nt/dt;
L = exp(i*f*(h.^N)’*q);
x = M(if,:)’;
y = L * x;
D(if,:) = y’;
D(nt+2-if,:) = conj(y)’;
end
D(nt/2+1,:) = zeros(1,nh);
d = real(ifft(D,[],1));
return;
if is used as a variable name. I am surprised that this does not raise a syntax error: most languages would forbid the use of "reserved" keywords. Maybe it would be a good idea to replace if with a different name in order to clarify your code and avoid confusion.
As far as MATLAB is concerned, this code doesn't really mean anything, because it's just a syntax error. if is reserved keyword, and you can't create a variable called if. As such, it just instantly errors and won't run.
You should probably replace all occurrences of the variable if (although not the keyword if in lines 8 and 10) with some other variable name. Avoid i, since you're using that as the imaginary unit.

Defining relationship for symbolic variable in MATLAB

Let's say I have a symbolic variable "q" that depends on another symbolic variable "t".
This is how I define each symbolic variables.
t= sym('t');
q = sym('q(t)');
And I have an expression that contains this (when I use pretty(expression))
result = blah1* diff(q(t),t) *blah2
I want to make this particular part a new variable. Let's say "qdot"
In the end, I want it to be like this.
result2 = blah1*qdot*blah2
I'm in the process of figuring it out. Thank you in advance.
You should use the subs function. Here is how to use it for your particular question
function Rewrite()
t = sym('t');
q = sym('q(t)');
a = sym('a');
blah1 = a^2;
blah2 = t^3;
result1 = blah1*diff(q,t)*blah2;
qDot = sym('qDot');
result2 = subs(result1, diff(q,t), qDot)
% result2 = a^2*qDot*t^3;
end
Note that
result2 = subs(result1, 'diff(q(t),t)', qDot)
and
newMiddle = sym('qDot');
result2 = subs(result1, diff(q,t), newMiddle)
also give the desired result.

Use limit value at a point

I have the following lines of code
arg1 = ( x<=a ).*(log(x)) + ( x>a).*(log(2*a-x));
num = sinh(arg1);
den = const + cosh(arg1);
re = num./den + const2;
re1 = ;
But re is not defined at x=0, as log blows up at 0. But re has a limiting value at 0 which is defined as const3.
I want re1 as const3 when x=0 and as re when x>0.
I tried using piecewise as
re1:= piecewise([x = 0, const3],[ x>0, re]);
But this does not work.
I get the error "Undefined function or method re1 for input arguments of type char.
How should I get the desired result?
Just use logical indexing:
re1 = re;
re1(x == 0) = const3;
and, even though it's probably "impossible", my experience tells me it's a good idea to do this as well:
re1(x >= 2*a) = const3;
You will need Symbolic Math Toolbox.
In general, if you define f(x) as a function and want to calculate the limit at x=a, you do as follow,
sym x
const3 = limit (sym (f),x,a)
This might help: http://www.mathworks.in/help/symbolic/limit.html