Plotting a graph for 2 elements in scilab within a For loop - plot

I am currently writing a program to show the relation between the Relaxation Factor and number of iterations it takes to achieve a solution using the Successive OverRelaxation Method
This is the concerned For loop:
for (w = 0:0.05:2)
T = -inv(D + w*L)*(w*U + (w -1) * D);
C = inv(D + w*L) * w *B ;
X = zeros(B);
for(i = 1:1:MaxIter)
X = T * X + C;
err = A * X - B;
if (abs(err) < abs(tol))
break
end
end
disp("Relaxation Factor = " + string(w) +" No. of iterations = " + string(i));
I wish to draw a plot showing the relation between Relaxation factor and no. of iterations(between w and i). How should I proceed?

Just proceed as follow
I=zeros(W)
for k = 1:size(W,"*")
w=W(k)
T = -inv(D + w*L)*(w*U + (w -1) * D);
C = inv(D + w*L) * w *B ;
X = zeros(B);
for(i = 1:1:MaxIter)
X = T * X + C;
err = A * X - B;
if (abs(err) < abs(tol))
I(k)=i
break
end
end
end
plot(W,I)

Related

How to find all pythagorean triples including multiples in processing.js using Euclid's method

I've been tasked to find the probability of getting a prime number in a Pythagorean triple for a school project, so I tried to code it, but I didn't consider multiples of Pythagorean Triples using Euclid's formula:
(a = m^2 -n^2, b = 2mn, c = m^2 + n^2.).
Ex. 3-4-5 -> 6-8-10.
var primitiveCount = 0;
var m = floor(2), n = floor(1);
var a, b, c;
var ans1, ans2, ans3;
var isPrime = function(value) {
for(var i = 2; i < value; i++) {
if(value % i === 0) {
return false;
}
}
return value > 1;
};
var j=10;
for(var j = 1; j <= 150; j++){
primitiveCount = 0;
m=2;
n=1;
for(var i=0; i < j; i++) {
a = ((Math.pow(m,2))-(Math.pow(n,2)));
b = 2 * n * m;
c = ((Math.pow(m,2))+(Math.pow(n,2)));
if(a<b<c) {
if(Math.pow(a,2) + Math.pow(b,2) === Math.pow(c,2)) {
ans1 = a;
ans2 = b;
ans3 = c;
}
if(isPrime(ans1) || isPrime(ans2) || isPrime(ans3)){
println(ans1 + " " + ans2 + " " + ans3 + " ~");
primitiveCount++;
}else{
println(ans1 + " " + ans2 + " " + ans3);
}
m++;
n++;
}
}
println(primitiveCount + "/" + j);
}
My code creates unique ones, but does not give me the multiples
It is enough to use natural coefficient p
a = p * (m^2 -n^2)
b = p * 2mn
c = p * (m^2 + n^2)
With m>n, m and n coprime and with different parity this method gives all unique triplets.
Conditions together:
p = 1,2,3...
n = 1,2,3...
m = n + 1 + 2 * i, and GCD(m, n) = 1
Seems that your code does not use all values for m, so omits many triplets.
Also use m*m instead of slow pow. Also you don't need to check a^2+b^2=c^2

3d line-intersection code not working properly

I created this piece of code to get the intersection of two 3d line-segments.
Unfortunately the result of this code is inaccurate, the intersection-point is not always on both lines.
I am confused and unsure what I'm doing wrong.
Here is my code:
--dir = direction
--p1,p2 = represents the line
function GetIntersection(dirStart, dirEnd, p1, p2)
local s1_x, s1_y, s2_x, s2_y = dirEnd.x - dirStart.x, dirEnd.z - dirStart.z, p2.x - p1.x, p2.z - p1.z
local div = (-s2_x * s1_y) + (s1_x * s2_y)
if div == 0 then return nil end
local s = (-s1_y * (dirStart.x - p1.x) + s1_x * (dirStart.z - p1.z)) / div
local t = ( s2_x * (dirStart.z - p1.z) - s2_y * (dirStart.x - p1.x)) / div
if (s >= 0 and s <= 1 and t >= 0 and t <= 1) and (Vector(dirStart.x + (t * s1_x), 0, dirStart.z + (t * s1_y)) or nil) then
local v = Vector(dirStart.x + (t * s1_x),0,dirStart.z + (t * s1_y))
return v
end
end
This is example of Delphi code to find a distance between two skew lines in 3D. For your purposes it is necessary to check that result if small enough value (intersection does exist), check that s and t parameters are in range 0..1, then
calculate point using parameter s
Math of this approach is described in 'the shortest line...' section of Paul Bourke page
VecDiff if vector difference function, Dot id scalar product function
function LineLineDistance(const L0, L1: TLine3D; var s, t: Double): Double;
var
u: TPoint3D;
a, b, c, d, e, det, invdet:Double;
begin
u := VecDiff(L1.Base, L0.Base);
a := Dot(L0.Direction, L0.Direction);
b := Dot(L0.Direction, L1.Direction);
c := Dot(L1.Direction, L1.Direction);
d := Dot(L0.Direction, u);
e := Dot(L1.Direction, u);
det := a * c - b * b;
if det < eps then
Result := -1
else begin
invdet := 1 / det;
s := invdet * (b * e - c * d);
t := invdet * (a * e - b * d);
Result := Distance(PointAtParam(L0, s), PointAtParam(L1, t));
end;
end;
As far as I can tell your code is good. I've implemented this in javascript at https://jsfiddle.net/SalixAlba/kkrc9kcf/
and it seems to work for all the cases I can think of.
The only changes I've done is to change things to work in javascript rather than lua. The final condition was commented out
function GetIntersection(dirStart, dirEnd, p1, p2) {
var s1_x = dirEnd.x - dirStart.x;
var s1_y = dirEnd.z - dirStart.z;
var s2_x = p2.x - p1.x;
var s2_y = p2.z - p1.z;
var div = (-s2_x * s1_y) + (s1_x * s2_y);
if (div == 0)
return new Vector(0,0);
var s = (-s1_y * (dirStart.x - p1.x) + s1_x * (dirStart.z - p1.z)) / div;
var t = ( s2_x * (dirStart.z - p1.z) - s2_y * (dirStart.x - p1.x)) / div;
if (s >= 0 && s <= 1 && t >= 0 && t <= 1) {
//and (Vector(dirStart.x + (t * s1_x), 0, dirStart.z + (t * s1_y)) or nil) then
var v = new Vector(
dirStart.x + (t * s1_x),
dirStart.z + (t * s1_y));
return v;
}
return new Vector(0,0);
}
Mathmatically it makes sense. If A,B and C,D are your two lines. Let s1 = B-A, s2 = C-D. A point of the line AB is given by A + t s1 and a point on the line CD is given by C + s s2. For an intersection we require
A + t s1 = C + s s2
or
(A-C) + t s1 = s s2
You two formula for s, t are found by taking the 2D cross product with each of the vectors s1 and s2
(A-C)^s1 + t s1^s1 = s s2^s1
(A-C)^s2 + t s1^s2 = s s2^s2
recalling s1^s1=s2^s2=0 and s2^s1= - s1^s2 we get
(A-C)^s1 = s s2^s1
(A-C)^s2 + t s1^s2 = 0
which can be solved to get s and t. This matches your equations.

how to detect point on/around a line (with some offset)

Drawn a line from a point A to point B. Let d be offset. Let C be point to be tested.
I am going to do a kind of hit testing around the line with offset.
How can i do the hit testing around the line with the given offset.
Ex: A = (10,10), B (30,30), offset = 2. choose C as any point. Please Refer the image in the link please.
http://s10.postimg.org/6by2dzvax/reference.png
Please help me.
Thanks in advance.
Find offset for C.
e.g. dx1 and dy1. If dy1/dx1=dy/dx then your C hits the line.
For segment you should also check if whether dx1 < dx or dy1 < dy.
In other words, you want to check if that point C is inside a certain rectangle, with dimensions 2*d and |A-B|+2*d. You need to represent the line as u*x+v*y+w=0, this can be accomplished by
u = A.y-B.y
v = B.x-A.x
w = A.x*B.y - A.y * B.x
Then the (signed) distance of C from that line would be
d = (u*C.x + v*C.y +w) / sqrt( u*u+v*v)
You compare abs(d) to your offset.
The next step would be to check the position of C in the direction of the line. To that end you consider the orthogonal line u2*x+v2*y+w2=0 with
u2 = v
v2 = -u
w2 = -u2*(A.x+B.x)/2 - v2*(A.y+B.y)/2
and the distance
d2 = (u2 * C.x + v2 * C.y + w2 ) / sqrt( u2*u2+v2*v2 )
This distance must be compared to something like the length of the line+offset:
abs(d2) < |A-B| / 2 + offset
A convenient trick is to rotate and translate the plane in such a way that the segment AB maps to the segment (0, 0)-(0, L) (just like on the image), L being the segment length.
If you apply the same transform to C, then it a very simple matter to test inclusion in the rectangle.
That useful transform is given by:
x = ((X - XA).(XB - XA) + (Y - YA).(YB - YA)) / L
y = ((X - XA).(YB - YA) - (Y - YA).(XB - XA)) / L
maybe you can use this function to count the shortest distance of the point to the line. If the distance is <= offset, then that point is hitting the line.
private double pointDistanceToLine(PointF line1, PointF line2, PointF pt)
{
var isValid = false;
PointF r = new PointF();
if (line1.Y == line2.Y && line1.X == line2.X)
line1.Y -= 0.00001f;
double U = ((pt.Y - line1.Y ) * (line2.Y - line1.Y )) + ((pt.X - line1.X) * (line2.X - line1.X));
double Udenom = Math.Pow(line2.Y - line1.Y , 2) + Math.Pow(line2.X - line1.X, 2);
U /= Udenom;
r.Y = (float)(line1.Y + (U * (line2.Y - line1.Y ))); r.X = (float)(line1.X + (U * (line2.X - line1.X)));
double minX, maxX, minY , maxY ;
minX = Math.Min(line1.Y , line2.Y );
maxX = Math.Max(line1.Y , line2.Y );
minY = Math.Min(line1.X, line2.X);
maxY = Math.Max(line1.X, line2.X);
isValid = (r.Y >= minX && r.Y <= maxX) && (r.X >= minY && r.X <= maxY );
//return isValid ? r : null;
if (isValid)
{
double result = Math.Pow((pt.X - r.X), 2) + Math.Pow((pt.Y - r.Y), 2);
result = Math.Sqrt(result);
return result;
}
else {
double result1 = Math.Pow((pt.X - line1.X), 2) + Math.Pow((pt.Y - line1.Y), 2);
result1 = Math.Sqrt(result1);
double result2 = Math.Pow((pt.X - line2.X), 2) + Math.Pow((pt.Y - line2.Y), 2);
result2 = Math.Sqrt(result2);
return Math.Min(result1, result2);
}
}

Quadratic Bézier Curve: Calculate Points

I'd like to calculate a point on a quadratic curve. To use it with the canvas element of HTML5.
When I use the quadraticCurveTo() function in JavaScript, I have a source point, a target point and a control point.
How can I calculate a point on the created quadratic curve at let's say t=0.5 with "only" knowing this three points?
Use the quadratic Bézier formula, found, for instance, on the Wikipedia page for Bézier Curves:
In pseudo-code, that's
t = 0.5; // given example value
x = (1 - t) * (1 - t) * p[0].x + 2 * (1 - t) * t * p[1].x + t * t * p[2].x;
y = (1 - t) * (1 - t) * p[0].y + 2 * (1 - t) * t * p[1].y + t * t * p[2].y;
p[0] is the start point, p[1] is the control point, and p[2] is the end point. t is the parameter, which goes from 0 to 1.
In case somebody needs the cubic form:
//B(t) = (1-t)**3 p0 + 3(1 - t)**2 t P1 + 3(1-t)t**2 P2 + t**3 P3
x = (1-t)*(1-t)*(1-t)*p0x + 3*(1-t)*(1-t)*t*p1x + 3*(1-t)*t*t*p2x + t*t*t*p3x;
y = (1-t)*(1-t)*(1-t)*p0y + 3*(1-t)*(1-t)*t*p1y + 3*(1-t)*t*t*p2y + t*t*t*p3y;
I created this demo :
// x = a * (1-t)³ + b * 3 * (1-t)²t + c * 3 * (1-t)t² + d * t³
//------------------------------------------------------------
// x = a - 3at + 3at² - at³
// + 3bt - 6bt² + 3bt³
// + 3ct² - 3ct³
// + dt³
//--------------------------------
// x = - at³ + 3bt³ - 3ct³ + dt³
// + 3at² - 6bt² + 3ct²
// - 3at + 3bt
// + a
//--------------------------------
// 0 = t³ (-a+3b-3c+d) + => A
// t² (3a-6b+3c) + => B
// t (-3a+3b) + => c
// a - x => D
//--------------------------------
var A = d - 3*c + 3*b - a,
B = 3*c - 6*b + 3*a,
C = 3*b - 3*a,
D = a-x;
// So we need to solve At³ + Bt² + Ct + D = 0
Full example here
may help someone.
I edited talkhabis answer (cubic curve) so the curve is displayed with the right coordinates. (Couldn't comment)
The Y-coordinates needed to be changed (-p[].y+150). (A new variable for that might be a nicer and more efficient solution, but you get the idea)
// Apply points to SVG and create the curve and controllers :
var path = document.getElementById('path'),
ctrl1 = document.getElementById('ctrl1'),
ctrl2 = document.getElementById('ctrl2'),
D = 'M ' + p0.x + ' ' + (-p0.y+150) +
'C ' + c0.x + ' ' + (-c0.y+150) +', ' + c1.x + ' ' + (-c1.y+150) + ', ' + p1.x + ' ' + (-p1.y+150);
path.setAttribute('d',D);
ctrl1.setAttribute('d','M'+p0.x+','+(-p0.y+150)+'L'+c0.x+','+(-c0.y+150));
ctrl2.setAttribute('d','M'+p1.x+','+(-p1.y+150)+'L'+c1.x+','+(-c1.y+150));
// Lets test the "Bezier Function"
var t = 0, point = document.getElementById('point');
setInterval(function(){
var p = Bezier(p0,c0,c1,p1,t);
point.setAttribute('cx',p.x);
point.setAttribute('cy',-p.y+150);
t += 0.01;
if(t>=1) t=0;
},50);
// OK ... Now tring to get "y" on cruve based on mouse "x" :
var svg = document.getElementById('svg'),
point2 = document.getElementById('point2');
svg.onmousemove = function(e){
var x = (e.pageX - 50)/2,
y = (e.pageY - 50)/2;
// "-50" because of "50px margin" on the left side
// and "/2" because the svg width is 300 units and 600 px => 300 = 600/2
// Get the x,y by mouse x
var p = YBX(p0,c0,c1,p1,x);
point2.setAttribute('cx',p.x);
point2.setAttribute('cy',-p.y+150);
}
http://jsfiddle.net/u214gco8/1/
I also created some C-Code to test the results for the cubic curve. Just enter the X and Y coordinates in the main function.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void bezierCurve(int x[] , int y[])
{
double xu = 0.0 , yu = 0.0 , u = 0.0 ;
int i = 0 ;
for(u = 0.0 ; u <= 1.0 ; u += 0.05)
{
xu = pow(1-u,3)*x[0]+3*u*pow(1-u,2)*x[1]+3*pow(u,2)*(1-u)*x[2]
+pow(u,3)*x[3];
yu = pow(1-u,3)*y[0]+3*u*pow(1-u,2)*y[1]+3*pow(u,2)*(1-u)*y[2]
+pow(u,3)*y[3];
printf("X: %i Y: %i \n" , (int)xu , (int)yu) ;
}
}
int main(void) {
int x[] = {0,75,50,300};
int y[] = {0,2,140,100};
bezierCurve(x,y);
return 0;
}
https://ideone.com/glLXcB
Just a note: If you are using the usual formulas presented here then don't expect t = 0.5 to return the point at half of the curve's length.. In most cases it won't.
More on this here under "§23 — Tracing a curve at fixed distance intervals" and here.

Non-Dimensionalization Mathematica

I have a set of coupled equations for the variables H, W, P, & T (below) that I need to non-dimensionalize. Is there a way of achieving this in Mathematica as doing it manually is proving difficult.
{(a 1/(1 + R T[t]) - b) H[t] - (ap + bp) P[t] - bt T[t] == H'[t],
L P[t] - g W[t] - B W[t] H[t] == W'[t],
B W[t] H[t] - (up + b + bp + bt T[t]/H[t]) P[t] -
bp (P[t]^2)/H[t] ((k + 1)/k) + phi T[t] == P'[t],
H[t] (theta) - (b + bp P[t]/H[t] + bt ) T[t] -
bt (T[t]^2)/H[t] ((k + 1)/k) - v P[t] == T'[t]}
Parameter units: a = /H/unit time; b = /H/unit time; B = /H/unit time; theta = T/H/unit time; ap = /P/unit time; bp = /P/unit time; up = /P/unit time; v = /P/unit time; L = W/P/unit time; R = /T/unit time; bt = /T/unit time; phi = /T/unit time; g = /W/unit time; k = constant.
This package may help you to use the Pi-theorem.
I never used it, though.

Resources