Change x axis to scale with pi and not numbers - plot

I want to create the plot of cos(x) and sin(x) in Octave. I have learned how to change things such as xlabel and xlim, however I can’t find how to change from having numbers (e.g 1, 2, 3) to having pi terms (-pi,-pi/2 and such). I would also appreciate if you can explain me how to do that. Here is a picture of what I want to do in case my english confused you.

In Matlab you can do something like this:
set(gca,'XTick',-pi:pi/2:pi)
set(gca,'XTickLabel',{'-pi','-pi/2','0','pi/2','pi'})
As you can see here: http://www.mathworks.com/help/matlab/creating_plots/setting-axis-parameters.html
This should work in Octave as well.
Also I haven't tested this but to get the actual Pi symbol you might try:
set(gca,'XTickLabel',{'-p','-p/2','0','p/2','p'}, 'fontname','symbol')
Otherwise you can try and see if this Matlab FEX submission will work for you: http://www.mathworks.com/matlabcentral/fileexchange/15986

For the π symbol you only have to write \pi.
set(gca,'XTick',-pi:pi/2:pi)
set(gca,'XTickLabel',{'-\pi','-\pi/2','0','\pi/2','\pi'})

This is an old topic, but here is an Octave solution with a bit of context.
Shadowing #Dan's input with #Chimalis's revision, the following script works in Octave 4.4.1 on Windows and 5.2.0 on Linux. Pay particular attention to the use of xtick, xticks, xticklabel, and xticklabels.
x = linspace(-3*pi,3*pi);
figure;
hold on;
subplot(2,1,1);
y = cos(x);
plot(x,y)
ylabel('cosine');
xticks([-3*pi -2*pi -pi 0 pi 2*pi 3*pi]);
xticklabels({'-3\pi','-2\pi','-\pi','0','\pi','2\pi','3\pi'});
yticks([-1 -0.866 -0.707 -0.5 0 0.5 0.707 0.866 1]);
grid on;
sp_h2 = subplot(2,1,2);
z = sin(x);
plot(x,z)
sp_h2_pos = get(sp_h2, 'Position');
sp_h2_pos_new = sp_h2_pos - [0 0 sp_h2_pos(3)/2 0];
set(sp_h2, 'Position', sp_h2_pos_new);
ylabel('sine')
xlim([0 2*pi]);
h=get (gcf, "currentaxes");
set(h,"xtick",0:pi/2:2*pi);
set(h,"xticklabel",['0';'\pi/2';'\pi';'3\pi/2';'2\pi']);

Related

Quadratic surface plotting in Octave

I've been assigned a project that requires me to plot some quadratic surfaces. I tried to be diligent and download some software so that my graphs look better than those done with other free online resources. I decided to try Octave and see if I can make it work but I've ran into a problem. When trying to plot:
I've checked some tutorials but so far I haven't been able to pinpoint my error. This is the code I was using:
clear;
x = [-3:1:3];
y = x;
[xx,yy] = meshgrid(x,y);
zz=sqrt(-9*xx.^2+9*yy.^2);
figure
mesh(xx,yy,zz);
Any suggestions are appreciated.
The error thrown to the command window for your script is:
error: mesh: X, Y, Z, C arguments must be real
error: called from
mesh at line 61 column 5
blah at line 15 column 1
Since you x and y are real, the imaginaries are coming from a square-root of a number less than 0. Looking at your equation, this will happen for any (x, y) pair where x is greater than y.
The easiest fix is to set all complex numbers (values of zz with a non-zero imaginary part) to 0 (which will plot the value) or NaN (which will not plot the value. Consider this script (yours plus filtering):
clear;
x = -3:0.1:3;
y = x;
[xx,yy] = meshgrid(x,y);
zz=sqrt(-9*xx.^2+9*yy.^2);
figure
% Set all zz with nonzero imaginary part to NaN
zz(imag(zz)~=0) = NaN;
% % Set all zz with nonzero imaginary part to 0
% zz(imag(zz)~=0) = 0;
mesh(xx,yy,zz);
I would prefer this:
x = -3:0.1:3;
y = x;
[xx,yy] = meshgrid(x,y);
zz=sqrt(-9*xx.^2+9*yy.^2); % zz will have both + and -
figure
% zz = abs(zz) ;
mesh(xx,yy,abs(zz));
hold on
mesh(xx,yy,-abs(zz));

3D bounding box for an item with three axis rotations

I'm trying to find the <x,y,z> size of what would end up being a bounding box for a rotated shape in all three axis rotations. Though to help keep it simple, the example demonstrated below has only the x axis rotated.
vector Size = <10,1,0.5>; vector Deg = <22.5,0,0>
if(Deg.x > 0 && Deg.y == 0 && Deg.z == 0){
Y1 = Cos(Deg.x) * Size.y + Sin(Deg.x) * Size.z;
Z1 = Cos(Deg.x) * Size.z + Sin(Deg.x) * Size.y;}
Below are for the y and z rotations, that is if you decided to change the degrees to say <0,22.5,0> and <0,0,22.5>.
if(Deg.y > 0 && Deg.x == 0 && Deg.z == 0){
X2 = Cos(Deg.y) * Size.x + Sin(Deg.y) * Size.z;
Z2 = Cos(Deg.y) * Size.z + Sin(Deg.y) * Size.x;}
if(Deg.z > 0 && Deg.x == 0 && Deg.y == 0){
X3 = Cos(Deg.z) * Size.x + Sin(Deg.z) * Size.y;
Y3 = Cos(Deg.z) * Size.y + Sin(Deg.z) * Size.x;}
Though the part I get lost at is, where do I go from here if when you have the rotation in two or three axis. Such as <22.5,22.5,0> or <22.5,22.5.22.5>
Is there a website with a tutorial or example equations I could review or are there any hints or ideas of what I could do to figure this out.
EDIT:
I do want to add that the comment from Nico helped, in that what I'm asking about is called: Axis-Aligned Bounding Box or AABB for short.
As for JohanC comment about the 22.5, yes the Deg = Degree. Also yes you'll have to turn the Degree into Radians, but I put it as Degree in the example for the Sin and Cos input to keep it simple.
If you're wondering how this question might be useful. Well as an example you'd need to know the AABB to help in an equation to keep the item in question flush with the surface its sitting on if you were to say resize the item while it had <x,y,z> rotations that weren't at perfect zero rotations.
I found my own solution after a lot of testing and debugging. I'll show and explain a small portion of the script I created since functions and options from coding language to language may vary.
A few details about the example script below. Deg = Degrees. Though yes what JohanC mentioned about radians is correct, since even the language I'm using I have to convert degrees to radians with a function. Not every language or calculator is like that, yet for intents and purposes to make it easier to read, I did take out the excess while keeping the meat of the code/equation intact so to speak. Also in this example, I'm rotating it in the Z axis to demonstrate and as a starting point.
vector Size = <10,1,0.5>; //Insert your own coding language function
//for splitting the size in half with positive and negative halves.
vector min = <-5,-0.5,-0.25>; vector max = <5,0.5,0.25>;
//You'll need at least 8 points in total to do this correctly.
//I already have 8 points added down below, labeled p1 - p8
vector p1 = <max.x,max.y,max.z>; vector p2 = <max.x,min.y,max.z>;
vector p3 = <max.x,max.y,min.z>; vector p4 = <max.x,min.y,min.z>;
vector p5 = <min.x,max.y,max.z>; vector p6 = <min.x,min.y,max.z>;
vector p7 = <min.x,max.y,min.z>; vector p8 = <min.x,min.y,min.z>;
vector Deg = <0,0,22.5>
//This will give you an idea of how to setup the x,y,z for each point
//equation to make / change to fit the rotations. Plus to make it compact
//I suggest that you use list, a while loop, and etc.
x1 = p1.x * llCos(Deg.z) - p1.y * llSin(Deg.z);
y1 = p1.y * llCos(Deg.z) + p1.x * llSin(Deg.z);
A lot of what I kept out of the example above is several list, true and false statements, a while loop, and few other things. Though it's kept simple to show the less complicated portion of it and the fact that not every language has the same functions available.
Though once when you get all of the location data of the 8 points collected, you can then put each of the x, y, z point information into its own list. Then run the equation (edited as needed for each rotation). After that, get the max and min from each axis rotation output. Then take the maximum and minus the minimum from it since the minimum will always be a negative. That right there will give you the <x,y,z> size of your bounding box.
I do want to add that the link from Nico helped slightly, though the only flaw in it is "if" the language you're using allows a matrix or "if" you're able to create a multidimensional array. If you can manage that, then use the link Nico gave to see if it helps.
Also some of JohanC tips/hints helped as well. Speaking of which, the part about "using the output of the vector from one rotation to the next" works well if and only if you're using the 8 points method. Otherwise if you try it with the bounding box size of one to the next, the first rotation to the second will work fine because its only moving in 2D at that point, but by the time you try to make the third rotation with the second rotations bounding box it won't work because it'll be going from 2D to 3D.
Note - If you think you have a better way to do the equation or simpler way to explain it, feel free to add in your own answer.

Plot of function, DomainError. Exponentiation yielding a complex result requires a complex argument

Background
I read here that newton method fails on function x^(1/3) when it's inital step is 1. I am tring to test it in julia jupyter notebook.
I want to print a plot of function x^(1/3)
then I want to run code
f = x->x^(1/3)
D(f) = x->ForwardDiff.derivative(f, float(x))
x = find_zero((f, D(f)),1, Roots.Newton(),verbose=true)
Problem:
How to print chart of function x^(1/3) in range eg.(-1,1)
I tried
f = x->x^(1/3)
plot(f,-1,1)
I got
I changed code to
f = x->(x+0im)^(1/3)
plot(f,-1,1)
I got
I want my plot to look like a plot of x^(1/3) in google
However I can not print more than a half of it
That's because x^(1/3) does not always return a real (as in numbers) result or the real cube root of x. For negative numbers, the exponentiation function with some powers like (1/3 or 1.254 and I suppose all non-integers) will return a Complex. For type-stability requirements in Julia, this operation applied to a negative Real gives a DomainError. This behavior is also noted in Frequently Asked Questions section of Julia manual.
julia> (-1)^(1/3)
ERROR: DomainError with -1.0:
Exponentiation yielding a complex result requires a complex argument.
Replace x^y with (x+0im)^y, Complex(x)^y, or similar.
julia> Complex(-1)^(1/3)
0.5 + 0.8660254037844386im
Note that The behavior of returning a complex number for exponentiation of negative values is not really different than, say, MATLAB's behavior
>>> (-1)^(1/3)
ans =
0.5000 + 0.8660i
What you want, however, is to plot the real cube root.
You can go with
plot(x -> x < 0 ? -(-x)^(1//3) : x^(1//3), -1, 1)
to enforce real cube root or use the built-in cbrt function for that instead.
plot(cbrt, -1, 1)
It also has an alias ∛.
plot(∛, -1, 1)
F(x) is an odd function, you just use [0 1] as input variable.
The plot on [-1 0] is deducted as follow
The code is below
import numpy as np
import matplotlib.pyplot as plt
# Function f
f = lambda x: x**(1/3)
fig, ax = plt.subplots()
x1 = np.linspace(0, 1, num = 100)
x2 = np.linspace(-1, 0, num = 100)
ax.plot(x1, f(x1))
ax.plot(x2, -f(x1[::-1]))
ax.axhline(y=0, color='k')
ax.axvline(x=0, color='k')
plt.show()
Plot
That Google plot makes no sense to me. For x > 0 it's ok, but for negative values of x the correct result is complex, and the Google plot appears to be showing the negative of the absolute value, which is strange.
Below you can see the output from Matlab, which is less fussy about types than Julia. As you can see it does not agree with your plot.
From the plot you can see that positive x values give a real-valued answer, while negative x give a complex-valued answer. The reason Julia errors for negative inputs, is that they are very concerned with type stability. Having the output type of a function depend on the input value would cause a type instability, which harms performance. This is less of a concern for Matlab or Python, etc.
If you want a plot similar the above in Julia, you can define your function like this:
f = x -> sign(x) * abs(complex(x)^(1/3))
Edit: Actually, a better and faster version is
f = x -> sign(x) * abs(x)^(1/3)
Yeah, it looks awkward, but that's because you want a really strange plot, which imho makes no sense for the function x^(1/3).

Interpretation of logn^logn?

How should I interpret
How do I interpret this? One way is to take it as logn(logn) and other is . Both would be giving different answers.
For eg:
Taking base 2 and n=1024, in first case we get 10*10 as ans. In the second case, we get 10^10 as ans or am I doing something wrong?
From a programmer's viewpoing a good way to better understand a function is to plot it at different parts of its domain.
But what is the domain of f(x) := ln(x)^ln(x)? Well, given that the exponent is not an integer, the base cannot be smaller than 1. Why? Because ln(x) is negative for 0 < x < 1 and it is not even defined for x <= 0.
But what about x = 1. Given that ln(1) = 0, we would get 0^0, which is not defined either. So, let's plot f(x) for x between: 1.000001 and 1.1. We get:
The plot reveals that there would be no harm in extending the definition of f(x) at 1 in this way (let me use pseudocode here):
f(x) := if x = 1 then 1 else ln(x)^ln(x)
Now, let's see what happens for larger values of x. Here is a plot between 1 and 10:
This plot is also interesting because it exposes a singular behavior between 1 and 3, so let's plot that part of the domain to see it better:
There are a couple of questions that one could ask by looking at this plot. For instance, what is the value of x such that f(x)=1? Mm... this value is visibly between 2.7 and 2.8 (much closer to 2.7). And what number do we know that is a little bit larger than 2.7? This number should be related to the ln function, right? Well, ln is logarithm in base e and the number e is something like 2.71828182845904.... So, it looks like a good candidate, doesn't it? Let's see:
f(e) = ln(e)^ln(e) = 1^1 = 1!
So, yes, the answer to our question is e.
Another interesting value of x is the one where the curve has a minimum, which lies somewhere between 1.4 and 1.5. But since this answer is getting too long, I will stop here. Of course, you can keep plotting and answering your own questions as you happen to encounter them. And remember, you can use iterative numeric algorithms to find values of x or f(x) that, for whatever reason, appear interesting to you.
Because log(n^log n)=(log n)^2, I would assume that log n^log n should be interpreted as (log n)^(log n). Otherwise, there's no point in the exponentiation. But whoever wrote that down for you should have clarified.

Plotting a function with discrete x values in gnuplot

I need to plot a function f(x), where x is discrete set of values (in my case positive integers). I couldn't find a way to specify a step-size when using the range option and samples doesn't seem to be the right solution. Finally, I would like to approximate f(x) with a smooth function.
I don't quite understand why samples is not the solution to your problem.
If I want to plot sin(x) on an interval between 0 and 10 with a point at every integer I use
set xrange [0:10]
set sample 11
plot sin(x) w p
Obviously the number of samples is xmax-xmin+1 (10 - 0 + 1 = 11).
Finally to tackle the approximation problem have a look at this website which discusses linear least squares fitting. For simple linear interpolation use lp instead of p.
Or alternatively, play around with the ceil(x) or floor(x) functions.
Maybe have a look at this example:
http://gnuplot.sourceforge.net/demo/prob2.html
You can do:
plot [1:12] '+' u ($0):(f($0))
Where, $0 will be replaced by 1, 2, ..., 12. You can even do a smooth on this. For instance:
f(x)=sin(2*x)
plot [1:12] f(x) t 'the function'\
, '+' u ($0):(f($0)) t 'the points'\
, '+' u ($0):(f($0)) smooth cspline t 'the smooth'

Resources