Iam trying to solve 32 linear coupled differential equations where, when i add them before solving, they should get cancel and result should be exactly zero because the coefficients are so. But it is showing a non zero value in 10^-6 which i don't want. As it can be seen in the following program. When i add all the 'A' and 'W' values (coefficients) they are zero, but when i add them together it is giving a non zero value. please can some one help ?? (ROSE & LILLY are zero individually but why the LOTUS is not zero ?)
A1 = 507762.5`;
A2 = 126940.625`;
A3 = 18134.375`;
A4 = 1.468884375`*^6;
A5 = 489628.125`;
A = -2.61135`*^6;
W1 = -571967.7214761395`;
W2 = -190655.90715871312`;
W3 = 571967.7214761395`;
W4 = 190655.90715871312`;
ROSE = A1 + A2 + A3 + A4 + A5 + A;
LILLY = W1 + W2 + W3 + W4;
JASMINE = ROSE + LILLY
LOTUS = A1 + W1 + A2 + W2 + A3 + W3 + A4 + W4 + A5 + A
The inconsistency in your answer appears due to the default precision Mathematica sets. The rule of thumb is that the larger is the length of the digits after the decimal, the more precision you need. For example, in your code W3 needs higher precision to retain all the decimal parts that you mentioned than the variable A1.
However, I believe that Mathematica maintains a standard precision for all the calculations unless you specify it. You can specify the precision to an arbitrary value in Mathematica by the command SetPrecision. If you now specify a precision, say 50, to all the variables, then the inconsistency disappears. Hope this helps!
Related
Suppose I have a function phi(x1,x2)=k1*x1+k2*x2 which I have evaluated over a grid where the grid is a square having boundaries at -100 and 100 in both x1 and x2 axis with some step size say h=0.1. Now I want to calculate this sum over the grid with which I'm struggling:
What I was trying :
clear all
close all
clc
D=1; h=0.1;
D1 = -100;
D2 = 100;
X = D1 : h : D2;
Y = D1 : h : D2;
[x1, x2] = meshgrid(X, Y);
k1=2;k2=2;
phi = k1.*x1 + k2.*x2;
figure(1)
surf(X,Y,phi)
m1=-500:500;
m2=-500:500;
[M1,M2,X1,X2]=ndgrid(m1,m2,X,Y)
sys=#(m1,m2,X,Y) (k1*h*m1+k2*h*m2).*exp((-([X Y]-h*[m1 m2]).^2)./(h^2*D))
sum1=sum(sys(M1,M2,X1,X2))
Matlab says error in ndgrid, any idea how I should code this?
MATLAB shows:
Error using repmat
Requested 10001x1001x2001x2001 (298649.5GB) array exceeds maximum array size preference. Creation of arrays greater
than this limit may take a long time and cause MATLAB to become unresponsive. See array size limit or preference
panel for more information.
Error in ndgrid (line 72)
varargout{i} = repmat(x,s);
Error in new_try1 (line 16)
[M1,M2,X1,X2]=ndgrid(m1,m2,X,Y)
Judging by your comments and your code, it appears as though you don't fully understand what the equation is asking you to compute.
To obtain the value M(x1,x2) at some given (x1,x2), you have to compute that sum over Z2. Of course, using a numerical toolbox such as MATLAB, you could only ever hope to compute over some finite range of Z2. In this case, since (x1,x2) covers the range [-100,100] x [-100,100], and h=0.1, it follows that mh covers the range [-1000, 1000] x [-1000, 1000]. Example: m = (-1000, -1000) gives you mh = (-100, -100), which is the bottom-left corner of your domain. So really, phi(mh) is just phi(x1,x2) evaluated on all of your discretised points.
As an aside, since you need to compute |x-hm|^2, you can treat x = x1 + i x2 as a complex number to make use of MATLAB's abs function. If you were strictly working with vectors, you would have to use norm, which is OK too, but a bit more verbose. Thus, for some given x=(x10, x20), you would compute x-hm over the entire discretised plane as (x10 - x1) + i (x20 - x2).
Finally, you can compute 1 term of M at a time:
D=1; h=0.1;
D1 = -100;
D2 = 100;
X = (D1 : h : D2); % X is in rows (dim 2)
Y = (D1 : h : D2)'; % Y is in columns (dim 1)
k1=2;k2=2;
phi = k1*X + k2*Y;
M = zeros(length(Y), length(X));
for j = 1:length(X)
for i = 1:length(Y)
% treat (x - hm) as a complex number
x_hm = (X(j)-X) + 1i*(Y(i)-Y); % this computes x-hm for all m
M(i,j) = 1/(pi*D) * sum(sum(phi .* exp(-abs(x_hm).^2/(h^2*D)), 1), 2);
end
end
By the way, this computation takes quite a long time. You can consider either increasing h, reducing D1 and D2, or changing all three of them.
How to minimize function y12 + y22 + ... + yn2 with constraints y1*y2*...*yn = c; y1,y2,...,yn > 0 using dynamic programming? I have tried to solve this problem, but I have no idea how to create a recurrent function.
You need to think how to reduce the problem into "smaller problem"
D(i,c) = min { D(i-1, c/y) + y^2 | 1 <= y <= c }
In the above, you reduce the problem from y1,y2,....,yi to y1,...,y_{i-1}, and check all possible assignments for y_i - and chose the best out of them.
Base clauses will be:
D(0,0) = 0
D(i,0) = Infinity i>0
You can do a top-down or bottom-up DP solution with these recurrence formulas, assuming i,c are integers. (Might need to add stop clause of D(i,c) = Infinity if c is not natural
Based on your question and the clarification given, I think dynamic programming is not necessary. The minimal solution is to choose y1, ..., yn to be the prime factors of c (with repeats).
Example: Given c = 60, we let y1 = 2, y2 = 2, y3 = 3, y4 = 5.
Then the sum is y12 + y22 + y32 + y42 = 4 + 4 + 9 + 25 = 42.
If we took fewer factors, then the sum would be bigger:
y1 = 60, then sum = 602 = 3600.
y1 = 5, y2 = 6, then sum = 52 + 62 = 61.
y1 = 3, y2 = 4, y2 = 5, then sum = 32 + 42 + 45 = 50.
Informal justification - it is always beneficial to split the product:
Suppose c = ab, with a and b ≥ 2.
Then c2 = a2b2. (a2b2 > 2a2) and (a2b2 > 2b2) are both true.
Adding these inequalities we get 2a2b2 > 2a2 + 2b2.
Therefore c2 = a2b2 > a2 + b2.
Hi all I am working on Image processing and have written a short piece of code in MATLAB. The code is quite slow.
I am giving my code snippet here
for i=1:10
//find c1,c2,c3
//c1 c2 and c3 change at each iteration
u = (1./((abs(P-c1))^m) + 1./((abs(P-c2))^m) + 1./((abs(P-c3))^m));
u1 = 1./((abs(P-c1))^m)./u;
u2 = 1./((abs(P-c2))^m)./u;
u3 = 1./((abs(P-c3))^m)./u;
end
Let me explain the variables here:
P,u,u1,u2 and u3 are all matrices of size 512x512
c1,c2 and c3 are constants of dimension 1x1
m is a constant with value = 2
I want to repeat this operations in a loop (say 10 times). However my code is quite slow.
The results of the profiler are given below :
The total running time of the program was 4.6 secs. However the four steps listed above itself takes abour 80% of the time.
So I wanted to make my code run faster.
MY FIRST EDIT
My changed code snippet
for i=1:10
//find c1 and c2
//c1 and c2 changes at each iteration
a=((abs(P-c1))^m);
b=((abs(P-c2))^m);
c=((abs(P-c3))^m);
x=1./a; y=1./b; z=1./c;
u = (x + y + z);
u1 = x./u;
u2 = y./u;
u3 = z./u;
end
Now the program computes in 2.47 seconds computation time for the above steps are given below:
So this is way much more faster than my first method.
2nd edit
for i=1:10
//find c1,c2,c3
//c1 c2 and c3 change at each iteration
a=(P-c1).*(P-c1);
b=(P-c2).*(P-c2);
c=(P-c3).*(P-c3);
x=1./a; y=1./b; z=1./c;
u = (x + y + z);
u1 = x./u;
u2 = y./u;
u3 = z./u;
end
Now the program computes in 0.808 seconds.
The four steps described above computes above very quickly.
I am sure it can be made even faster. Can you guys please help me to further optimize my code.
It would be extremely helpful for matrices larger size than 512 such as 1024 , 2048 or likewise.
Thanks in advance.
Your current code is:
a=((abs(P-c1))^m);
b=((abs(P-c2))^m);
c=((abs(P-c3))^m);
x=1./a; y=1./b; z=1./c;
u = (x + y + z);
u1 = x./u;
u2 = y./u;
u3 = z./u;
Firstly, realize that the absolute value function is multiplicative. So |AB| = |A|x|B|. Now, abs(P-C1)^m is equivalent to abs( (P-C1)^m ).
Just a preliminary glance at it suggests that some of the computation in the bottleneck can be reused. Specifically, since c1,c2 and c3 are constants, the computation can be sped up a little bit if you try to reuse them (at the expense of additional memory).
temp_P2 = P*P;
temp_PCA = P*ones(size(P));
temp_PCB = ones(size(P))*P;
a = abs(temp_P2 - c1*temp_PCA - c1*temp_PCB + c1^2 * length(P))
The computation of temp_PCA and temp_PCB can also be avoided since multiplication by a constant matrix always amounts to the construction of a rank 1 matrix with either constant rows or columns.
I don't claim that any of these modifications will speed up your code but they are definitely worth trying.
The first suggestion is:
if m = 2 and it is not changing, why you don't try these alternatives:
A*A
and if m = 2 then do you really need abs ?
this part that you are doing
1./a
is faster than
a.^(-1)
so I don't see any better option in this part.
Another thing you can try is this. instead of:
x=1./a; y=1./b; z=1./c;
u = (x + y + z);
u1 = x./u;
u2 = y./u;
u3 = z./u;
You can have this:
u = (x + y + z);
u1 = 1./(a.*u);
u2 = 1./(b.*u);
u3 = 1./(c.*u);
this way I guess it is a little bit faster by removing 3 variables. but the code becomes less readable.
Given two circle segments of the same circle: A=[a1, a2] and B=[b1, b2], with:
a1, a2, b1, b2 values in degree between -inf and +inf
a1 <= a2 ; b1 <= b2
a2-a1<=360; b2-b1<=360
How can I find out if these two circle segments overlap?
(i.E. if they intersect or touch in at least one point)
Examples:
A=[ -45°, 45°]; B=[ 10°, 20°] ==> overlap
A=[ -45°, 45°]; B=[ 90°, 180°] ==> no overlap
A=[ -45°, 45°]; B=[ 180°, 360°] ==> overlap
A=[ -405°, -315°]; B=[ 180°, 360°] ==> overlap
A=[-3600°, -3601°]; B=[ 3601°, 3602°] ==> overlap (touching counts as overlap)
A=[ 3600°, 3601°]; B=[-3601°,-3602°] ==> overlap (touching counts as overlap)
A=[ -1°, 1°]; B=[ 3602°, 3603°] ==> no overlap
This looks like a deceptively simple problem but I cannot wrap my head around it.
I currently have a basic idea for a solution which involves splitting each segment into two if it crosses 0°, but I am not sure if that covers all cases, and I was wondering if there is an elegant formula.
As #admaoldak mentioned, normalize the degrees first:
a1_norm = a1 % 360
a2_norm = a2 % 360
b1_norm = b1 % 360
b2_norm = b2 % 360
Now to check if b1 is within (a1,a2),
def intersect(b, as, ae
Intersect = False
If as > ae:
if b >= as or b <= ae:
return True
Else:
if b>=as and b<=ae:
return True
return False
Final answer is:
intersect(b1_norm,a1_norm,a2_norm)||intersect(b2_norm,a1_norm,a2_norm)||
intersect(a1_norm,b1_norm,b2_norm)||intersect(a2_norm,b1_norm,b2_norm)
For an interval [i.X , i.Y] , let's define the normalization i_norm = normalize(i) so that :
1. 0 <= i_norm.X < 360
2. i_norm.X <=i_norm.Y
then we define another operation i_slide = slide(i) so that :
1. i_slide.X = i.X + 360
2. i_slide.Y = i.Y + 360
we can prove that,
for your input A and B , A circle-overlaps with B if and only if :
normalize(A) interval-overlaps with normalize(B)
or
normalize(A) interval-overlaps with slide( normalize(B))
interval-overlaps is defined in the same way as "intersection" in adamoldak's post.
and both operations normalize() and slide() are easy to be implemented.
take your example: A=[-45°,45°]; B=[10°,20°] , we have
normalize(A) = [315,405]
normalize(B) = [10,20]
slide( normalize(B) ) = [370,380]
and [315,405] interval-overlaps with [370,380]
I have a similar problem with a game engine with rectangles overlapping in a looping map. I've thought about it a lot and have looked at some of you guys' answers. If you're looking for performance, this is the best you can get (until someone proves me wrong :P):
#assume the angles are already normalised
def overlap(a1, a2, b1, b2):
if a2 - a1 + b2 - b1 > 360: #must overlap
return True
return (b1 > a2) ^ (b2 > a1) ^ (a2 < a1) ^ (b2 < b1)
Elegant. Elegant and kinda ugly.
How about normalizing each degree value to 0-360:
a1_norm = a1 % 360
a2_norm = a2 % 360
b1_norm = b1 % 360
b2_norm = b2 % 360
Then you just check for intersection:
(a1_norm <= b2_norm) and (a2_norm<= b1_norm)
I need to translate a value in the range 1-320 to it's equivalent value within the spread in the range 500-2500, and I need to do it in VBScript.
Is there a function similar to map() that can do this for me? I can't include any external libraries in this particular use case.
You mean you want to convert any number between 1 and 320 to its corresponding number between 500 and 2500 such that 1 corresponds to 500 and 320 corresponds to 2500?
If so, you can do it as follows: Let x be your original number (between 1 and 320) and y be the target number (between 500 and 2500):
y = ((x-1)/319) * 2000 + 500
In general, if you have a range a1 to a2 and want to convert it to range b1 to b2 using
y = ((x - a1)/(a2 - a1)) * (b2 - b1) + b1