How to format the values of the output variable of a function as a matrix, given that an input is an matrix in Octave - octave

I have a function:
int = input("Introduce the intensity: ")
wave = input("Introduce the wavelength: ");
e = input("Introduce e: ");
function [brighttemp] = brightness_temp_function(int, wave, e)
A = 1.19 .* (10 .^ 8);
B = 1.441 .* (10 .^ 4);
brighttemp = sprintf("%.2f",(B ./ (wave .* (log (1 .+ ((e .* A) ./ (int .* (power(wave,5)))))))) .- 273.15);
disp(brighttemp);
endfunction
[brighttemp] = brightness_temp_function(wave, e, int);`
When I enter a single value for each variable, it outputs a single answer for brighttemp. But when I enter in a vector for one of the variables, such as [8, 9; 7, 8.5] for the int variable and single values for the others, I get back an output like this for brighttemp: 20.727.812.924.3 instead of a vector similar in format to the vector inputted for the int variable, like this [20.7, 27.8; 12.9, 24.3] . What do I have to do to get an output like the latter vector?

Related

How to correctly calculate a nonlinear function and plot its graph in Octave?

Goal: Plot the graph using a non-linear function.
Function and graph
This is my first time working at Octave. To plot the graph, I need to calculate a function in the range Fx (0.1 ... 10).
I tried to implement this by looping the function through the for loop, writing the results to an array (x-axis - Fn, y-axis - function value), then loading the arrays into the plot() function.
Fn = 1
Ln = 5
Q = 0.5
function retval = test (Fn, Ln, Q)
# Fn squared (for common used)
Fn = Fn^2
# Node A + Node B
nodeA = Fn * (Ln - 1)
nodeB = (Ln * Fn - 1)^2 + Fn * (Fn - 1)^2 * (Ln - 1)^2 * Q^2
nodeB = sqrt(nodeB)
# Result
result = nodeA / nodeB
retval = result
return;
endfunction
frequencyArray = {}
gainArray = {}
fCount = 1
gCount = 1
for i = 0:0.5:5
# F
Fn = i
frequencyArray{fCount} = Fn
fCount = fCount + 1
# G
gainArray{gCount} = test(Fn, Ln, Q)
gCount = gCount + 1
end
plot(frequencyArray, gainArray);
As a result, I get an error about the format of the arrays.
>> plot(frequencyArray, gainArray);
error: invalid value for array property "xdata"
error: __go_line__: unable to create graphics handle
error: called from
__plt__>__plt2vv__ at line 495 column 10
__plt__>__plt2__ at line 242 column 14
__plt__ at line 107 column 18
plot at line 223 column 10
In addition to the error, I believe that these tasks are solved in more correct ways, but I did not quite understand what to look for.
Questions:
Did I choose the right way to solve the problem? Are there any more elegant ways?
How can I fix this error?
Thank you!
If I have correctly interpreted what you are trying to do, the following should work. Firstly, you need to use the term-by-term versions of all arithmetic operators that act on Fn. These are the same as the normal operators except preceded by a dot. Next, you need to put Fn equal to a vector containing the x-values of all the points you wish to plot and put Q equal to a vector containing the values of Q for which you want to draw curves. Use a for-loop to loop through the values of Q and plot a single curve in each iteration of the loop. You don't need a loop to plot each curve because Octave will apply your "test" function to the whole Fn vector and return the result as a vector of the same size. To plot the curves on a log axis, use the function "semilogx(x, y)" insetad of "plot(x, y)". To make the plots appear on the same figure, rather than separate ones put "hold on" before the loop and "hold off" afterwards. You used cell arrays instead of vectors in your for-loop, which the plotting functions don't accept. Also, you don't need an explicit return statement in an Octave function.
The following code produces a set of curves that look like the ones in the figure you pasted in your question:
Ln = 5
function result = test (Fn, Ln, Q)
# Fn squared (for common used)
Fn = Fn.^2;
# Node A + Node B
nodeA = Fn .* (Ln - 1);
nodeB = (Ln .* Fn .- 1).^2 + Fn .* (Fn .- 1).^2 .* (Ln - 1)^2 * Q^2;
nodeB = sqrt(nodeB);
# Result
result = nodeA ./ nodeB;
endfunction
Fn = linspace(0.1, 10, 500);
Q = [0.1 0.2 0.5 0.8 1 2 5 8 10];
hold on
for q = Q
K = test(Fn, Ln, q);
semilogx(Fn, K);
endfor
hold off

How to fix: "anonymous function bodies must be single expressions" error on Octave

I am trying to make a function in Octave where you give octave a function f(x,y) as a string, a change in X, a change in Y, a starting point, and the size of a matrix, the function will create a matrix populated with the values of f(x,y) at each point in the matrix.
This is for an application that displays a 3d graph, using the matrix to map each value to a block
# funcStr: The function whose Z values are being calculated
# dx: the change in x that each block in the x direction represents
# dy: the change in y that each block in the y direction represents
# startPt: the point (in an array of x, y) that center block represents
# res: the side length (in blocks) of the plane
pkg load symbolic
syms x y
function[zValues] = calculateZValues(funcStr, dx, dy, startPt, res)
zValues = zeros(res);
eqn = #(x, y) inline(funcStr);
startX = startPt{1};
startY = startPt{2};
for yOffset = 1:res
for xOffset = 1:res
xCoord = startX + dx * xOffset;
yCoord = startY + dy * yOffset;
zValues(res * yOffset + xOffset) = double(subs(eqn, #(x, y), {xCoord, yCoord}));
endfor
endfor
endfunction
The error I am getting is:
>> calculateZValues("x*y", 1, 1, {0,0}, 10)
parse error near line 20 of file /home/rahul/Documents/3dGraph/graph/calculateZValues.m
anonymous function bodies must be single expressions
>>> zValues(res * yOffset + xOffset) = double(subs(eqn, #(x, y), {xCoord, yCoord}));
I have no idea what the issue is. I have replaced the #(x,y) part with {x,y} in the line referenced by the error but it says nothing or it raises an error about the function subs not being declared. I have also tried moving the pkg and syms lines above the function header

How to pass variadic arguments in Octave

I would like to implement a function duration = timer(n, f, arguments_of_f) that would measure how much time does a method f with arguments arguments_of_f need to run n times. My attempt was the following:
function duration = timer(n, f, arguments_of_f)
duration = 0;
for i=1:n
t0 = cputime;
f(arguments_of_f);
t1 = cputime;
duration += t1 - t0;
end
In another file, I have
function y = f(x)
y = x + 1;
end
The call d1 = timer(100, #f, 3); works as expected.
In another file, I have
function y = g(x1, x2)
y = x1 + x2;
end
but the call d2 = timer(100, #g, 1, 2); gives an error about undefined
argument x2, which is, when I look back, somehow expected, since I pass only
1 to g and 2 is never used.
So, how to implement the function timer in Octave, so that the call like
timer(4, #g, x1, ... , xK) would work? How can one pack the xs together?
So, I am looking for the analogue of Pythons *args trick:
def use_f(f, *args):
f(*args)
works if we define def f(x, y): return x + y and call use_f(f, 3, 4).
You don't need to pack all the arguments together, you just need to tell Octave that there is more than one argument coming and that they are all necessary. This is very easy to do using variadic arguments.
Your original implementation is nearly spot on: the necessary change is minimal. You need to change the variable arguments_to_f to the special name varargin, which is a magical cell array containing all your arbitrary undeclared arguments, and pass it with expansion instead of directly:
function duration = timer(n, f, varargin)
duration = 0;
for i=1:n
t0 = cputime;
f(varargin{:});
t1 = cputime;
duration += t1 - t0;
end
That's it. None of the other functions need to change.

How do I get an equation as a string?

I have an equation that is used to make an isosurface which is then saved into a file and I need to keep track of which equations belong to which file. Therefore I want to label the files my Octave script produces with the equation that produced them without labeling them all by hand.
This is my code right now:
clf;
function [f, v] = doiso(dodraw)
m = 3;
dim = -m:0.1:m;
if (dodraw > 0)
dim = -m:0.6:m;
endif
[x,y,z] = meshgrid(dim, dim, dim);
func = cos(x) .* sin(y) + cos(y) .* sin(z) + cos(z) .* sin(x);
if (dodraw > 0)
isosurface(func, 0);
else
[f, v] = isosurface(func, 0);
endif
endfunction
#draw
doiso(1);
axis equal;
title("isosurface() of the function");
#saveq
[f, v] = doiso(0);
vertface2obj(v, f, strcat("objs/", int2str(time * 1000), "out.obj"));
The saved file should have names like cos(x) . sin(y) + cos(y) . sin(z) + cos(z) . sin(x) 1513441860368.obj where the long number is a timestamp and the expression containing sin and cos is the equation that produced the file (same as in the code). Invalid chars will have to be removed or replaced in the file name string.
No online resource seems to mention printing an equation; only printing numbers or solving equations.
One way you could do this is using func2str():
func2str (fcn_handle)
Return a string containing the name of the function referenced by the function handle fcn_handle.
You will have to create an anonymous function for your equation. For example,
> f = #(x,y,z) cos(x) .* sin(y) + cos(y) .* sin(z) + cos(z) .* sin(x);
> eqn = func2str(f);
> fprintf(stdout, '%s\n', eqn)
#(x, y, z) cos (x) .* sin (y) + cos (y) .* sin (z) + cos (z) .* sin (x)
As you can see, the above code creates the string eqn containing the expression of the function f.
You can then manipulate the string to get something more reasonable as a file name. Here's a simple example:
> fname = regexprep(strjoin(strsplit(eqn(11:end)), ''), '[().*+]', '_')
fname = cos_x___sin_y__cos_y___sin_z__cos_z___sin_x_
Here strjoin(strsplit(str), '') removes all whitespace from the string str. The function regexprep() uses regex substitutions to replace the "undesired" characters with an underscore.
You can of course have more elaborate manipulations, such as changing * to _TIMES_ or whatever you prefer.
More about manipulating strings here.

Can I write this in verilog (Calling a function with indirect arguments)?

Suppose in a program, I write this function for dividing 2 values:
function [63:0] DIV_VAL; // Function for Multiplying two values 32 bits.
input [63:0] a, b;
always # (a or b)
DIV_VAL = a / b;
endfunction
Then later in the code I want to call this function with input Znk1 BUT rotating them 16 bits and 12 bits (first and second argument of the function). Moreover, since the function DIV_VAL answer me with a number of 64 bits, I only want to 32 bits from it, to be loaded to NC_1: Like this.
NC_1 = DIV_VAL [31:0] (Znk1 << 16, Znk1 >> 12) ;
Is this allowed, does it work? I'm not sure about the order also.
Second question: As alternative for this situation, a friend told me I can define some registers like a, b and use them to do something like this:
a = Znk1 << 16;
b = Znk1 >> 12;
NC_1 = DIV_VAL [31:0] (a, b);
NC_1 = NC_1[31:0];
You can't put an always block inside a function. Your function should be:
function [63:0] DIV_VAL; // Function for Multiplying two values 32 bits.
input [63:0] a, b;
DIV_VAL = a / b;
endfunction
or as you've written using an old-fashioned style, perhaps:
function [63:0] DIV_VAL (input [63:0] a, b); // Function for Multiplying two values 32 bits.
DIV_VAL = a / b;
endfunction
You can then call the function with expressions in the function call, if you wish:
NC_1 = DIV_VAL (Znk1 << 16, Znk1 >> 12) ;
but truncating the return value explicitly as you were doing is not allowed. But you don't need to truncate explicitly, Verilog will do it implicitly. (Hence no [31:0] in the above code.)