I have a notebook set up to run through an exhaustive search of numbers in an array used in an equation, if the equation equals a defined variable, then it returns the values of the variables in the equation. The only problem is, the If statement in the last For-loop never runs through the true/false/neither functions. The only way I've been able to get it to do anything is to use a generic Print[blah], of which it then proceeds to print absolutely every iteration through all the For-loops. Here is what I have so far-
AvTarget := -95
arr := {1, 1.1, 1.2, 1.3, 1.5, 1.6, 1.8, 2, 2.2, 2.4, 2.7, 3, 3.3,
3.6, 3.9, 4.3, 4.7, 5.1, 5.6, 6.2, 6.8, 7.5, 8.2, 9.1, 10}
trueArr := {}
falseArr := {}
For[i = 1, i <= Length[arr], i = i + 1,
For[j = 1, j <= Length[arr], j = j + 1,
For[k = 1, k <= Length[arr], k = k + 1,
If[Abs[
AvTarget - (arr[[i]] + arr[[k]] + (arr[[i]] + arr[[k]])/
arr[[j]])] < 1000, Append[trueArr, {i, j, k}],
Append[falseArr, 1], Append[falseArr, 0]]
]
]
]
Length[trueArr]
Length[falseArr]
I haven't dealt with loops in mathematica yet so I'm not sure what the issue is.
EDIT-
Ok so this code now works the way I need it to -
AvTarget = -95;
tol = 0.1;
arr := {1, 1.1, 1.2, 1.3, 1.5, 1.6, 1.8, 2, 2.2, 2.4, 2.7, 3, 3.3,
3.6, 3.9, 4.3, 4.7, 5.1, 5.6, 6.2, 6.8, 7.5, 8.2, 9.1, 10}
trueArr = {};
falseArr = {};
For[i = 1, i <= Length[arr], i++,
For[j = 1, j <= Length[arr], j++,
For[k = 1, k <= Length[arr], k++,
If[Abs[
AvTarget - (-(arr[[i]] + arr[[k]] + (arr[[i]]*arr[[k]])/
arr[[j]]))] <= tol,
trueArr = Append[trueArr, {arr[[i]], arr[[j]], arr[[k]]}],
Append[falseArr, 1], Append[falseArr, 0]]
]
]
]
Length[trueArr]
From there if Length > 0 I can just add an If to display the results. What would be the best way to have all the results within the tolerance printed in order of closest to AvTarget?
Loops are almost always the wrong way to go with Mathematica. I rewrote your original code to
avTarget = -95;
arr := {1, 1.1, 1.2, 1.3, 1.5, 1.6, 1.8, 2, 2.2, 2.4, 2.7, 3, 3.3,
3.6, 3.9, 4.3, 4.7, 5.1, 5.6, 6.2, 6.8, 7.5, 8.2, 9.1, 10};
triples = Tuples[arr, 3];
trueArr = Select[triples, Abs[avTarget - (#[[1]] + #[[3]] + (#[[1]] + #[[3]])/#[[2]]) <
1000] &];
falseArr = Complement[triples,trueArr];
I've been using Mathematica for about 20 years, I can't recall ever needing loops. Sure, sometimes it's easier to express an algorithm using loops than the functional alternatives that Mathematica provides but you should really kick away the crutches that they provide and walk the Mathematica way.
You should assign the return value of Append to the respective variable.
Append[trueArr, {i,j,k}] gives trueArr with {i,j,k} appended and then discards the result. You want trueArr = Append[trueArr, {i, j, k}].
Also, ":=" is the SetDelayed operator. You should be using "=".
Related
I am trying to use a very simple example of the AVX-512 gather instructions:
double __attribute__((aligned(64))) array3[17] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0,
9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0,
17.0};
int __attribute__((aligned(64))) i_index_ar[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
__m512i i_index = _mm512_load_epi64(i_index_ar);
__m512d a7AVX = _mm512_i64gather_pd(i_index, &array3[0], 1);
Unfortunetly, my last call to _mm512_i64gather_pd results in an memory access error (memory dumped).
Error message in German: Speicherzugriffsfehler (Speicherabzug geschrieben)
I am using Intel Xeon Phi (KNL) 7210.
edit: The error here was, that I was using 32 bit integers with 64bit load instructions and scale in _mm512_i64gather_pd has to be 8 or sizeof(double).
I think you need to set scale to sizeof(double), not 1.
Change:
__m512d a7AVX = _mm512_i64gather_pd(i_index, &array3[0], 1);
to:
__m512d a7AVX = _mm512_i64gather_pd(i_index, &array3[0], sizeof(double));
See also: this question and its answers for a fuller explanation of Intel SIMD gathered loads and their usage.
—
Another problem: your indices need to be 64 bit ints, so change:
int __attribute__((aligned(64))) i_index_ar[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, ...
to:
int64_t __attribute__((aligned(64))) i_index_ar[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, ...
I have an array, x, with dimension 4, that has the following values
3, 4.5, 7, 9
How do I generate the missing values, and make a new one like this?
3, 3.5, 4, 4.5, 5, 5.5, ...,9
Thanks in advance.
newarray = [x + 0.5 for x in range(1, 10)]
this code will give me following result:
newarray
[1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5]
Instead of adding 0.5 with x I want to increase my x by 0.5 for each 1 increment of x. The output suppose to be
newarray=[0.5,1,1.5,2,2.5......5.5].
Keep in mind that my range must be fix in 1 to 10. What can be better approach to make that?
[0.5 * x for x in range(1, 12)]
Will do the thing, I'm afraid generating that array with range(1, 10) is impossible
What is a pythonic way of making list of arbitrary length containing evenly spaced numbers (not just whole integers) between given bounds? For instance:
my_func(0,5,10) # ( lower_bound , upper_bound , length )
# [ 0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5 ]
Note the Range() function only deals with integers. And this:
def my_func(low,up,leng):
list = []
step = (up - low) / float(leng)
for i in range(leng):
list.append(low)
low = low + step
return list
seems too complicated. Any ideas?
Given numpy, you could use linspace:
Including the right endpoint (5):
In [46]: import numpy as np
In [47]: np.linspace(0,5,10)
Out[47]:
array([ 0. , 0.55555556, 1.11111111, 1.66666667, 2.22222222,
2.77777778, 3.33333333, 3.88888889, 4.44444444, 5. ])
Excluding the right endpoint:
In [48]: np.linspace(0,5,10,endpoint=False)
Out[48]: array([ 0. , 0.5, 1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5])
You can use the following approach:
[lower + x*(upper-lower)/length for x in range(length)]
lower and/or upper must be assigned as floats for this approach to work.
Similar to unutbu's answer, you can use numpy's arange function, which is analog to Python's intrinsic function range. Notice that the end point is not included, as in range:
>>> import numpy as np
>>> a = np.arange(0,5, 0.5)
>>> a
array([ 0. , 0.5, 1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5])
>>> a = np.arange(0,5, 0.5) # returns a numpy array
>>> a
array([ 0. , 0.5, 1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5])
>>> a.tolist() # if you prefer it as a list
[0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5]
f = 0.5
a = 0
b = 9
d = [x * f for x in range(a, b)]
would be a way to do it.
Numpy's r_ convenience function can also create evenly spaced lists with syntax np.r_[start:stop:steps]. If steps is a real number (ending on j), then the end point is included, equivalent to np.linspace(start, stop, step, endpoint=1), otherwise not.
>>> np.r_[-1:1:6j, [0]*3, 5, 6]
array([-1. , -0.6, -0.2, 0.2, 0.6, 1.])
You can also directly concatente other arrays and also scalars:
>>> np.r_[-1:1:6j, [0]*3, 5, 6]
array([-1. , -0.6, -0.2, 0.2, 0.6, 1. , 0. , 0. , 0. , 5. , 6. ])
You can use the folowing code:
def float_range(initVal, itemCount, step):
for x in xrange(itemCount):
yield initVal
initVal += step
[x for x in float_range(1, 3, 0.1)]
Similar to Howard's answer but a bit more efficient:
def my_func(low, up, leng):
step = ((up-low) * 1.0 / leng)
return [low+i*step for i in xrange(leng)]
I want to find a value of z at y = 12 and x = 3.5, given the below example data. How can I do this in C++?
y = 10
x = [1,2, 3,4, 5,6]
z = [2.3, 3.4, 5.6, 7.8, 9.6, 11.2]
y = 20
x = [1,2, 3,4, 5,6]
z = [4.3, 5.4, 7.6, 9.8, 11.6, 13.2]
y = 30
x = [1,2, 3,4, 5,6]
z = [6.3, 7.4, 8.6, 10.8, 13.6, 15.2]
My current Python code:
import scipy
import math
import numpy
from scipy import interpolate
x = [1, 2, 3, 4, 5, 6]
y = [10, 20, 30]
Y = numpy.array([[i]*len(x) for i in y])
X = numpy.array([x for i in y])
Z = numpy.array([[2.3, 3.4, 5.6, 7.8, 9.6, 11.2],
[4.3, 5.4, 7.6, 9.8, 11.6, 13.2],
[6.3, 7.4, 8.6, 10.8, 13.6, 15.2]])
tck = interpolate.bisplrep(X, Y, Z)
print interpolate.bisplev(3.5, 15, tck)
Just do the interpolation twice. First interpolate with Y to select the two Z tables. Then interpolate with X to pick the Z value.
I would use Akima's Spline, which is very well-tested, very fast, and produces extremely good results.
Unfortunately, it's in Fortran-66 (and messy at that), so you'll need to either translate it to C or a more modern variant of Fortran. I've gotten some help in getting it all to work, so I'd suggest reading through my threads on Usenet.