Is there a way to use lists as arguments for functions in TI-Basic? - ti-basic

I am making a function in my TI-nspire CS II CAS to calculate the equivalent resistance of a resistors in parallel, with this formula:
Parallel of resistors
I made a program that can do this with any number of resistors in parallel. Like this:}
Define prl(list)=
Prgm
:Local req
:req:=0
:For i,1,dim(list)
: req:=req+list[i]^(−1)
:EndFor
:Disp req^(−1)
:EndPrgm
However, I realised that I can't do operations with it such as
3+prl({4,6,7})
,since this is a program and not a function. I tried to just copy and paste the program into a function:
Define pr(list)=
Func
:Local req
:req:=0
:For i,1,dim(list)
: req:=req+list[i]^(−1)
:EndFor
:Return req^(−1)
:EndFunc
But it gives me the error 'Invalid in a function or current expression'. The point of the list is so that the program does the job no matter the number of resistors I want to input, but apparently that doesn't work for a function. What can I do?

The path of least resistance is to use functions instead of programs.
Note that sum can be used on a list.

Related

lua (Syntax): Calling a function that returns more than 1 value, and using those values as arguments, but without extra lines of variable assignment?

I have a situation where I need to call the following:
function xy(i)
return i,i+8
end
And use its output in another function.
function addition(x,y)
return x+y
end
Is there a way to get this to work more elegantly than writing it like:
i.e. i=10; x,y=xy(10); addition(x,y)--28
I'm looking for something like:
i.e. i=10; addition(xy(10)--where I somehow get two arguments here)
Both functions are generics used elsewhere, merging isn't viable, possible edits to what/how they return might be.
At least as of Lua 5.1, the following works 'as requested'.
When a function call is the last (or the only) argument to another call, all results from the first call go as arguments. [There are several examples using print.]
function xy(i)
return i,i+8
end
function addition(x,y)
return x+y
end
addition(xy(10)) -- 28
A more wordy way, that might be useful to decompose in similar cases needing a little bit more flexibility, is to convert the result to a table and then use unpack (added in 5.1). This approach is result -> table -> unpack -> arguments (per above).
addition(unpack({xy(10)})) -- 28
Here are both approaches in replit.

Can I use self.math.random on 2 Npcs?

I have this script on 2 npcs but both choose the same random number (7) how do I make the Npcs choose their own number? I did try with self.math.random and it gave an error
so what would the solution be? will I have to create different variables for each npc related to the random function?
function Behavior:Awake()
math.randomseed (os.time())
self.destino = math.random( 1, 7 )
In the engine I work with it says to put self. for independence...
The fact that you call math.randomseed inside a function suggests to me that you're calling it every time you want a random number. The purpose of math.randomseed is to initialize the RNG, which means you're initializing the RNG multiple times, hence the repetition. Usually, you need to call math.randomseed exactly once in the entire program.
it says to put self. for independence...
That's not a great explanation of how self works. self is a function parameter that gets automatically declared when you declare a function with colon notation.

Reduction of output array dimension in Fortran77 procedure

I am working on a large Fortran code, where parts are written in FORTRAN77.
There is a piece of code, which causes debugger to raise errors like:
Fortran runtime error:
Index '2' of dimension 1 of array 'trigs' above upper bound of 1
but when compiled without debugging options runs and does not crash the program. Debugging options used:
-g -ggdb -w -fstack-check -fbounds-check\
-fdec -fmem-report -fstack-usage
The logic of the problematic piece of code is following: in file variables.cmn I declare
implicit none
integer factors,n
real*8 triggers
parameter (n=32)
common /fft/ factors(19), triggers(6*n)
Variables factors and triggers are initialized in procedure initialize:
include 'variables.cmn'
...
CALL FFTFAX(n,factors,triggers)
...
FFTFAX is declared in another procedure as:
SUBROUTINE FFTFAX(N,IFAX,TRIGS)
implicit real*8(a-h,o-z)
DIMENSION IFAX(13),TRIGS(1)
CALL FAX (IFAX, N, 3)
CALL FFTRIG (TRIGS, N, 3)
RETURN
END
and lets look at procedure FFTRIG:
SUBROUTINE FFTRIG(TRIGS,N,MODE)
implicit real*8(a-h,o-z)
DIMENSION TRIGS(1)
PI=2.0d0*ASIN(1.0d0)
NN=N/2
DEL=(PI+PI)/dFLOAT(NN)
L=NN+NN
DO 10 I=1,L,2
ANGLE=0.5*FLOAT(I-1)*DEL
TRIGS(I)=COS(ANGLE)
TRIGS(I+1)=SIN(ANGLE)
10 CONTINUE
DEL=0.5*DEL
NH=(NN+1)/2
L=NH+NH
LA=NN+NN
DO 20 I=1,L,2
ANGLE=0.5*FLOAT(I-1)*DEL
TRIGS(LA+I)=COS(ANGLE)
TRIGS(LA+I+1)=SIN(ANGLE)
20 CONTINUE
In both FFTFAX and FFTRIG procedures there are different bounds for dimensions of arguments than the actual input array size (for TRIGS it is 1 and 19, respectively).
I printed out TRIGS after calling FFTFAX in no-debugger compilation setup:
trigs: 1.0000000000000000 0.0000000000000000\
0.99144486137381038 0.13052619222005157 0.96592582628906831\
0.25881904510252074 0.92387953251128674 0.38268343236508978\
...
My questions are:
Is notation :
DIMENSION TRIGS(1)
something more than setting bound of an array?
Why is the program even working in no-debugger mode?
Is setting:
DIMENSION TRIGS(*)
a good fix if I want variable trigs be a result of the procedure?
In f77 statements like the DIMENSION TRIGS(1) or similar or ..(*) with any number, if pertaining an argument of the procedure just tells the compiler
the rank of the array, the length in memory must be assigned to the array which is given in the call of the subroutine, normally f77 does not check this!
My recommendation either use (*) or better reformat (if necessary) the f77 sources to f90 (the bits shown would compile without change...).
and use dimension computed using n in the declaration within the subroutines/procedures.
Fortan passes arguments by address (i.e. trigs(i) in the subroutine just
will refer on the memory location, which corresponds to the address of trigs(1) + i*size(real*8).
A more consisted way to write the subroutine code could be:
SUBROUTINE FFTRIG(TRIGS,N,MODE)
! implicit real*8(a-h,o-z)
integer, intent(in) :: n
real(kind=8) :: trigs(6*n)
integer :: mode
! DIMENSION TRIGS(1)
.....
PI=2.0d0*ASIN(1.0d0)
.....
or with less ability for the compiler to check
SUBROUTINE FFTRIG(TRIGS,N,MODE)
! implicit real*8(a-h,o-z)
integer, intent(in) :: n
real(kind=8) :: trigs(:)
integer :: mode
! DIMENSION TRIGS(1)
.....
PI=2.0d0*ASIN(1.0d0)
.....
To answer your question, I would change TRIGS(1) to TRIGS(*), only to more clearly identify array TRIGS as not having it's dimension provided. TRIGS(1) is a carry over from pre F77 for how to identify this.
Using TRIGS(:) is incorrect, as defining array TRIGS in this way requires any routine calling FFTRIG to have an INTERFACE definition. This change would lead to other errors.
Your question is mixing the debugger's need for the array size vs the syntax excluding the size being provided. To overcome this you could pass the array TRIGS's declared dimension, as an extra declared argument, for the debugger to check. When using "debugger" mode, some compilers do provide hidden properties including the declared size of all arrays.

IDL Integration

I'm looking to integrate a function I am building, but the function would change each iteration based on a given input. For instance:
y=4e^(mx/4)
I would want to integrate with respect to x with a lower and upper bound, but the value of m would change. I know all my values of m.
Can I work with this? My initial assumption would be to use QROMB but that seems limited and unable to handle my issue.
QROMB (and other integrators) want a function of one variable, so you have to get the m in there through the back door. One way is with a common block:
function integrand,x
common int_common,int_m
return,4*exp(int_m*x/4)
end
function integrator,m,xlow,xhigh
common int_common,int_m
int_m=m
return,qromb('integrand',xlow,xhigh)
end
integrator(m,xlow,xhigh) will return the integral you want.

Halide::Expr' is not contextually convertible to 'bool' -- Storing values of functions in variables

I am new to using Halide and I am playing around with implementing algorithms first. I am trying to write a function which, depending on the value of the 8 pixels around it, either skips to the next pixel or does some processing and then moves on to the next pixel. When trying to write this I get the following compiler error:
84:5: error: value of type 'Halide::Expr' is not contextually convertible to 'bool'
if(input(x,y) > 0)
I have done all the tutorials and have seen that the select function is an option, but is there a way to either compare the values of a function or store them somewhere?
I also may be thinking about this problem wrong or might not be implementing it with the right "Halide mindset", so any suggestions would be great. Thank you in advance for everything!
The underlying issue here is that, although they are syntactically interleaved, and Halide code is constructed by running C++ code, Halide code is not C++ code and vice versa. Halide code is entirely defined by the Halide::* data structures you build up inside Funcs. if is a C control flow construct; you can use it to conditionally build different Halide programs, but you can't use it inside the logic of the Halide program (inside an Expr/Func). select is to Halide (an Expr which conditionally evaluates to one of two values) as if/else is to C (a statement which conditionally executes one of two sub-statements).
Rest assured, you're hardly alone in having this confusion early on. I want to write a tutorial specifically addressing how to think about staged programming inside Halide.
Until then, the short, "how do I do what I want" answer is as you suspected and as Khouri pointed out: use a select.
Since you've provided no code other than the one line, I'm assuming input is a Func and both x and y are Vars. If so, the result of input(x,y) is an Expr that you cannot evaluate with an if, as the error message indicates.
For the scenario that you describe, you might have something like this:
Var x, y;
Func input; input(x,y) = ...;
Func output; output(x,y) = select
// examine surrounding values
( input(x-1,y-1) > 0
&& input(x+0,y-1) > 0
&& ...
&& input(x+1,y+1) > 0
// true case
, ( input(x-1,y-1)
+ input(x+0,y-1)
+ ...
+ input(x+1,y+1)
) / 8
// false case
, input(x,y)
);
Working in Halide definitely requires a different mindset. You have to think in a more mathematical form. That is, a statement of a(x,y) = b(x,y) will be enforced for all cases of x and y.
Algorithm and scheduling should be separate, although the algorithm may need to be tweaked to allow for better scheduling.

Resources