I want to seperate a rational function to num and denom:
i.e x*y/(2*z) ===> n = x*y d = 2*z
here is my code:
func = input('Enter the function: ');
[n d] = numden(func);
disp(n);
>> test
Enter the function: x*y/(2*z)
??? Error using ==> input
Undefined function or variable 'y'.
Error in ==> test at 1
func = input('Enter the function: ');
You have to use symbolic objects.
>> syms x y;
>> [n d] = numden(x*y/(x+y))
n =
x*y
d =
x + y
>>
Related
I want to integrate x^2 from 2 to 4 with the trapezoidal integration method. For this, I defined a function trap that takes 4 arguments:
function y = trap( fn, a, b, h )
n = (b-a)/h;
x = a + [1:n-1]*h;
y = h/2*(feval(fn, a) + feval(fn, b) + 2*sum(feval(fn,x)));
and a function f
function y= f(x)
y=x^2
end
Now, by executing trap(f,2,4,0.1), I get the following error:
Not enough input arguments.
Error in f (line 2)
y=x^2
What is the origin of that error?
You have to call trap using the function handle #f, not f.
trap(#f,2,4,0.1)
function y = trap( fn, a, b, h )
n = (b-a)/h;
x = a + [1:n-1]*h;
y = h/2*(fn(a) + fn(b) + 2*sum(fn(x)));
end
function y= f(x)
y = x.^2;
end
which gives, as expected,
ans =
18.67
Also you needed element-wise multiplication in f(x) to compute y = x.^2.
And feval is not necessary. You can directly call fn(a) to evaluate the function.
i'm studing matlab and I get some problem with a code.
First, I've created f1.m:
function y = f1(x)
y = exp(x) - pi;
end
Then, I built a code to find the roots by bisector method:
function [root, err, n] = bissect(f, a, b, errMax)
m = (a+b)/2;
err = (b-a)/2;
n = 0;
while err > errMax
if f(a)*f(m) > 0
a = m;
else
b = m;
end
m = (a+b)/2;
err = (b-a)/2;
n = n + 1;
end
root = m;
end
But, when i run
>> [r,err,n] = bissect(#f1, 1, 2, 0.1);
it returns:
Warning: Subscript indices must be integer values.
In C:\matlabR12\work\Codigo\bissect.m at line 12
??? Index exceeds matrix dimensions.
Error in ==> C:\matlabR12\work\Codigo\bissect.m
On line 12 ==> if f(a)*f(m) > 0
What am I doing wrong?
I'm using Matlab R12
I am new to matlab and want to calculate something like f(x)/f'(x). I want the user to input the function f(x), the parameter x and a value of x (suppose 5,so that I can evaluate f(5)/f'(5)) .Please suggest what I should do.
One approach is to use symbolic variables
function [ val ] = func( fun, num )
symfun = sym(fun);
dsymfun = diff(symfun);
y = symfun/dsymfun;
val = subs(y, num);
end
and then call it
e.g.
value = func('x^2', 5)
value =
5/2
Otherwise, you can provide your input as a symbolic variable:
function [ val ] = func( fun, num )
dfun = diff(fun);
y = fun/dfun;
val = subs(y, num);
end
and then write
syms x;
func(x^2, 5)
You can do this using polyder and polyval as follows:
f = input('Enter f(x): '); %e.g; Enter [1 3 4] if f(x)= x^2 + 3*x + 4
df = polyder(f); %f'(x)
x= input('Enter x: '); %Enter the value of 'x' e.g 5
fx_dfx= polyval(f,x)/ polyval(df,x) %f(x)/f'(x)
If you have Symbolic Math Toolbox, you can also do this using:
syms x; %Creating a symbolic variable x
f = input('Enter f(x): '); %Enter f(x) e.g: x^2 + 3*x + 4
f(x)= f; %Converting sym to symfun
df(x) = diff(f) %f'(x)
x_val= input('Enter x: '); %Enter the value of 'x' e.g 5
fx_dfx = double(f(x_val)/df(x_val)) %f(x)/f'(x)
I want to use this rational number in computations without losing the accuracy of the picture in Matlab:
f = 359.0 + 16241/16250.0
I think storing, for instance by f = uint64(359.0 + 16241/16250.0) loses accuracy, seen as 360 in Matlab.
I think the best way to handle the thing is never to store the value but to store its factors like
% f = a + b/c
a = 359
b = 16241
c = 16250
and then doing computation by the variables a, b and c, and giving the result as a picture.
Is this a good way to maintain the accuracy?
As you suggest, if you absolutely don't want to lose accuracy when storing a rational number, the best solution probably is to store the number in terms of its integer components.
Instead of your three components (f = a + b/c) you can reduce the reprentation to two components: f = n/d. Thus each rational number would be defined (and stored) as the two-component integer vector [n d]. For example, the number f in your example corresponds to n=5849991 and d=16250.
To simplify handling rational numbers stored this way, you could define a helper function which converts from the [n d] representation to n/d before applyling the desired operation:
useInteger = #(x, nd, fun) fun(x,double(nd(1))/double(nd(2)));
Then
>> x = sqrt(pi);
>> nd = int64([5849991 16250]);
>> useInteger(x, nd, #plus)
ans =
361.7719
>> useInteger(x, nd, #times)
ans =
638.0824
If you want to achieve arbitrarily high precision in computations, you should consider using variable-precision arithmetic (vpa) with string arguments. With that approach you get to specify how many digits you want:
>> vpa('sqrt(pi)*5849991/16250', 50)
ans =
638.08240465923757600307902117159072301901656248436
Perhaps create a Rational class and define the needed operations (plus,minus,times,etc.). Start with something like this:
Rational.m
classdef Rational
properties
n;
d;
end
methods
function obj = Rational(n,d)
GCD = gcd(n,d);
obj.n = n./GCD;
obj.d = d./GCD;
end
function d = dec(obj)
d = double(obj.n)/double(obj.d);
end
% X .* Y
function R = times(X,Y)
chkxy(X,Y);
if isnumeric(X),
N = X .* Y.n; D = Y.d;
elseif isnumeric(Y),
N = X.n .* Y; D = X.d;
else
N = X.n .* Y.n; D = X.d .* Y.d;
end
R = Rational(N,D);
end
% X * Y
function R = mtimes(X,Y)
R = times(X,Y);
end
% X ./ Y
function R = rdivide(X,Y)
if isnumeric(Y),
y = Rational(1,Y);
else
y = Rational(Y.d,Y.n);
end
R = times(X,y);
end
% X / Y
function R = mrdivide(X,Y)
R = rdivide(X,Y);
end
% X + Y
function R = plus(X,Y)
chkxy(X,Y);
if isnumeric(X),
N = X.*Y.d + Y.n; D = Y.d;
elseif isnumeric(Y),
N = Y.*X.d + X.n; D = X.d;
else
D = lcm(X.d,Y.d);
N = sum([X.n Y.n].*(D./[X.d Y.d]));
end
R = Rational(N,D);
end
% X - Y
function R = minus(X,Y)
R = plus(X,-Y);
end
% -X
function R = uminus(X)
R = Rational(-X.n,X.d);
end
function chkxy(X,Y)
if (~isa(X, 'Rational') && ~isnumeric(X)) || ...
(~isa(Y, 'Rational') && ~isnumeric(Y)),
error('X and Y must be Rational or numeric.');
end
end
end
end
Examples
Construct objects:
>> clear all % reset class definition
>> r1 = Rational(int64(1),int64(2))
r1 =
Rational with properties:
n: 1
d: 2
>> r2 = Rational(int64(3),int64(4))
r2 =
Rational with properties:
n: 3
d: 4
Add and subtract:
>> r1+r2
ans =
Rational with properties:
n: 5
d: 4
>> r1-r2
ans =
Rational with properties:
n: -1
d: 4
Multiply and divide:
>> r1*r2
ans =
Rational with properties:
n: 3
d: 8
>> r1/r2
ans =
Rational with properties:
n: 2
d: 3
Get decimal value:
>> r12 = r1/r2; % 2/3 ((1/2)/(3/4))
>> f = r12.dec
f =
0.6667
Extension to LuisMendo's answer
I got this as the error for your suggestion by py
>>> a = 638.08240465923757600307902117159072301901656248436059
>>> a
638.0824046592376 % do not know if Python is computing here with exact number
>>> b = 638.0824
>>> ave = abs(b+a)/2
>>> diff = abs(b-a)
>>> ave = abs(b+a)/2
>>> diff/ave
7.30193709165014e-09
which is more than the proposed error storing error above.
I run in WolframAlpha
x = sqrt(pi)
x*5849991/16250
and get
509.11609919757198016211937362635174599076143654820109
I am not sure if this is what you meant in your comment of your answer.
Extension to chappjc's answer.
I have now
[B,T,F] = tfrwv(data1, 1:length(data1), length(data1)); % here F double
fs = Rational(uint64(5849991), uint64(16250));
t = 1/fs;
imagesc(T*t, F*fs, B);
I run it
Error using .*
Integers can only be combined with integers of
the same class, or scalar doubles.
Error in .* (line 23)
N = X .* Y.n; D = Y.d;
Error in * (line 34)
R = times(X,Y);
How can you multiply in this class the double with Rational?
I want to solve equations in matlab, eg.
100+a/2=173*cos(b)
sqrt(3)*a/2=173*sin(b)
and the code would be:
[a,b]=solve('100+a/2=173*cos(b)','sqrt(3)*a/2=173*sin(b)','a','b')
However, if I want to take 100 as a variable, like
for k=1:100
[a,b]=solve('k+a/2=173*cos(b)','sqrt(3)*a/2=173*sin(b)','a','b')
end
There would be an error, how to make it?
degree=140/1000000;
p=42164000;
a=6378136.5;
b=6356751.8;
x_1=0;
y_1=p;
z_1=0;
for i=451:550
for j=451:550
alpha=(1145-i)*degree;
beta=(1145-j)*degree;
x_2=p/cos(alpha)*tan(beta);
y_2=0;
z_2=p*tan(alpha);
syms x y z x_1 x_2 y_1 y_2 z_1 z_2 a b
eq = [(x-x_1)*(y2-y_1)-(x_2-x_1)*(y-y_1),(x-x_1)*(z_2-z_1)-(x_2-x_1)*(z-z_1), b^2*(x^2+y^2)+a^2*(y^2)-a^2*b^2 ];
sol = solve(eq(1),x,eq(2),y, eq(3),z);
sol.x
sol.y
sol.z
end
end
I got the expression value, how do I get the numeric value of x,y,z?
[['x(1)=';'x(2)='],num2str(double(sol.x))]
not work ,shows
??? Error using ==> mupadmex
Error in MuPAD command: DOUBLE cannot convert the input expression into a double array.
If the input expression contains a symbolic variable, use the VPA function instead.
Error in ==> sym.sym>sym.double at 927
Xstr = mupadmex('mllib::double', S.s, 0);
Error in ==> f2 at 38
[['x(1)=';'x(2)='],num2str(double(sol.x))]
If you have access to the Symbolic Toolkit then you do the following:
syms a b k
eq = [k+a/2-173*cos(b), sqrt(3)*a/2-173*sin(b)];
sol = solve(eq(1),a,eq(2),b);
sol.a = simplify(sol.a);
sol.b = simplify(sol.b);
% There are two solutions for 'a' and 'b'
% check residuals for example k=20
subs(subs(eq,{a,b},{sol.a(1),sol.b(1)}),k,20)
% ans = 0.2e-13
subs(subs(eq,{a,b},{sol.a(2),sol.b(2)}),k,20)
% ans = 0.2e-13
Edit 1
Based on new code by OP the matlab script to solve this is:
clear all
clc
syms alpha beta
degree=140/1000000;
p=42164000;
a=6378136.5;
b=6356751.8;
x_1=0;
y_1=p;
z_1=0;
x_2 = p/cos(alpha)*tan(beta);
y_2 = 0;
z_2 = p*tan(alpha);
syms x y z
eq = [(x-x_1)*(y_2-y_1)-(x_2-x_1)*(y-y_1);...
(x-x_1)*(z_2-z_1)-(x_2-x_1)*(z-z_1); ...
b^2*(x^2+y^2)+a^2*(y^2)-a^2*b^2 ];
sol = solve(eq(1),x,eq(2),y,eq(3),z);
sol.x = simplify(sol.x);
sol.y = simplify(sol.y);
sol.z = simplify(sol.z);
pt_1 = [sol.x(1);sol.y(1);sol.z(1)] % First Solution Point
pt_2 = [sol.x(2);sol.y(2);sol.z(2)] % Second Solution Point
x = zeros(100,100);
y = zeros(100,100);
z = zeros(100,100);
for i=451:550
disp(['i=',num2str(i)])
for j=451:550
res = double(subs(pt_1,{alpha,beta},{(1145-i)*degree,(1145-j)*degree}));
x(i-450, j-450) = res(1);
y(i-450, j-450) = res(2);
z(i-450, j-450) = res(3);
end
end
disp('x=');
disp(x);
disp('y=');
disp(x);
disp('z=');
disp(x);
I would try
for i=1:100
k=num2str(i)
[a,b]=solve('100+a/2=173*cos(b)','sqrt(3)*a/2=173*sin(b)','a','b')
end
and then solve the equation