Convert this formula into arrayformula - if-statement

short and simple, how can this formula be rewritten into array formula variant? Thanks
=iferror(if(and(GOOGLEFINANCE(B2, "High")>=D2+Now()-Now(), GOOGLEFINANCE(B2,"Low")<=D2),"Filled",if(F2<0.005, "In Threshold",if(and(E2="Long", GOOGLEFINANCE(B2,"priceOpen")<D2),"JumpedG ap",if(and(E2="Short",GOOGLEFINANCE(B2,"priceOpen")>D2),"Jumped Gap","Active")))))

try like this if it works for you:
=ARRAYFORMULA(IFERROR(
IF((GOOGLEFINANCE(B2:B, "High")>=D2+NOW()-NOW()) * (GOOGLEFINANCE(B2:B, "Low")<=D2), "Filled",
IF(F2:F<0.005, "In Threshold",
IF((E2:E="Long") * (GOOGLEFINANCE(B2:B, "priceOpen")<D2), "JumpedG ap",
IF((E2:E="Short") * (GOOGLEFINANCE(B2:B, "priceOpen")>D2), "Jumped Gap", "Active"))))))
or maybe:
=ARRAYFORMULA(IFERROR(
IF((GOOGLEFINANCE(B2:B, "High")>=D2:D+NOW()-NOW()) * (GOOGLEFINANCE(B2:B, "Low")<=D2:D), "Filled",
IF(F2:F<0.005, "In Threshold",
IF((E2:E="Long") * (GOOGLEFINANCE(B2:B, "priceOpen")<D2:D), "JumpedG ap",
IF((E2:E="Short") * (GOOGLEFINANCE(B2:B, "priceOpen")>D2:D), "Jumped Gap", "Active"))))))

Related

Is it possible to create an inner join between two tables showing all B that contain A?

I have two tables: Kanji, and Vocabulary. Imagine the kanji table looks like this:
目
一
人
And the vocabulary table looks like this:
目的
一番目
一人
二人
人々
注目
目標
一匹
I want to generate a table that finds all vocabulary which contains the kanji in the kanji table and list them together. So the end result would look like this:
人 一人
二人
人々
一 一人
一番目
一匹
目 目的
一番目
注目
目標
I'm not sure how to go about this. If I have just one kanji, I can use the QUERY function to generate all of the vocabularies which contain that one kanji. But can I create a dynamic table which essentially inner joins the "kanji" and "vocabulary" tables, looking for every instance of "vocabulary" contains "kanji"?
I tried using a QUERY to combine the two tables, but it won't work because the tables are mismatched in size:
=QUERY({C1:C296,D1:D224}, "SELECT Col2 WHERE Col1 contains Col2")
In the above example, the C column / Col2 is vocabulary, the D column / Col1 is kanji.
Is there a way to do this using Google Sheets?
The simplest workaround is to get intersections by 1 value:
=FILTER(D:D;REGEXMATCH(D:D;"目"))
The picture shows how to use the copy of this function to get all intersections
The other approach is to use big array-formula like:
=TRANSPOSE(SPLIT(TEXTJOIN(",";1;TRANSPOSE(ARRAYFORMULA(IF(REGEXMATCH(A1:A8;TRANSPOSE(B1:B3));A1:A8;))));","))
=ARRAYFORMULA(SORT(TRIM(SPLIT(TRANSPOSE(SPLIT(QUERY(TRANSPOSE(QUERY(TRANSPOSE(
IF(IFERROR(REGEXEXTRACT(IFERROR(REGEXEXTRACT(C1:C, REPT("(.)", LEN(C1:C)))),
TEXTJOIN("|", 1, A1:A)))<>"", "♦"&IFERROR(REGEXEXTRACT(IFERROR(
REGEXEXTRACT(C1:C, REPT("(.)", LEN(C1:C)))), TEXTJOIN("|", 1, A1:A)))&"♣"&C1:C, ))
,,999^99)),,999^99), "♦")), "♣"))))
seriously, much better way, just add a custom function:
/**
* inner join on equality
*
* #param {Range} items1 Table 1
* #param {Range} items2 Table 2
* #param {Integer} ix1 0-based index of key in Table1
* #param {Integer} ix2 0-based index of key in Table2
*
* #customfunction
* #author marc meyer (marqueymarc)
*/
function innerJoinEQ(items1 = [[]], items2 = [[]], ix1= 0, ix2= 0) {
var res = [];
var item2ix = 0;
var map = new Map();
items1 = Array.isArray(items1)? items1: [[items1]];
items2 = Array.isArray(items2)? items2: [[items2]];
items2.forEach((item2) => {
let entries = map.get(item2[ix2]) || [];
entries.push(item2);
map.set(item2[ix2], entries);
});
items1.forEach((item1) => {
let entries = map.get(item1[ix1]) || [];
entries.forEach((rightPart) => {
let cp = rightPart.slice();
cp.splice(ix2, 1);
res.push([...item1, ...cp]);
})
});
return res;
}

How to calculate performance curve for each row of data

I want to plot a performance curve for each row of data I have.
A simple version of what I want to do is plot the function with the equation as Y= m*X+b, where I have a table with m and b values and I want Y values for X = 1 to 10.
How is this calculated?
A Y = mX + b example can be seen in the following plot:
The following works:
WITH NUMBERS AS
(
SELECT N FROM (VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10))N(N)
),
Examples AS
(
SELECT m,b FROM (VALUES (1,2),(2,2))N(m,b)
)
SELECT
'Y = ' + CAST(Examples.m as varchar(10)) + 'X + ' + CAST(Examples.b as varchar(10)) AS Formula
,Numbers.N AS X
, Numbers.N * Examples.m + Examples.b
FROM Examples
CROSS JOIN NUMBERS

Round Floats within an expression

I ran into the following problem:
I have a sympy matrix of sympy expressions, each cell looking something like the following example, call it ex1:
In: ex1
Out: -mu_0_0 + t*((0.8*mu_0_1 + 2.22044604925031e-16)*Max(0, alpha_0_1_4)**2 + (0.8*mu_1_1 + 2.22044604925031e-16)*Max(0, alpha_0_1_3)**2 + (0.8*mu_3_1 + 2.22044604925031e-16)*Max(0, alpha_0_1_2)**2 + (0.8*mu_6_1 + 2.22044604925031e-16)*Max(0, alpha_0_1_1)**2 + (0.4*mu_10_0 + 0.4*mu_10_1 - 0.4)*Max(0, alpha_0_1_0)**2) + (-t + 1)*(0.498558013279766*mu_0_1 + 0.0238962672572783*mu_10_0 + 0.0238962672572783*mu_10_1 + 0.18596764210715*mu_1_1 + 0.0201673973158616*mu_3_1 + 0.0475144127826656*mu_6_1 - 0.023896267257278) + Max(0, -alpha_0_0_0)**2
The matrix is later to be lambdified. However, before that, I would like to get rid of the 2.22044604925031e-16 and like floats; these are artifcats from some other part of the code and should be 0.
I would like to clean the expressions in my matrix cells from these, but can't figure out how to.
ex1.round() crashes my python when applied to ex1, and it does not seem to work for simple expression such as
In: sympy.sympify(0.01*t).round(1)
TypeError: can't convert expression to float
If I try it via N, as
In: sympy.N(eq, n=3)
I get:
RecursionError: maximum recursion depth exceeded
(I am not even sure this would work anyway, as I understand this would just reduce the floats to n significant digits?)
Is there any way to clean these expressions in the way I want?
Thanks in advance!
I will leave the expression structure, in case it is of any help:
sympy.srepr(ex1)
"Add(Mul(Integer(-1), Symbol('mu_0_0')), Mul(Symbol('t'), Add(Mul(Add(Mul(Float('0.80000000000000004', prec=15), Symbol('mu_0_1')), Float('2.2204460492503131e-16', prec=15)), Pow(Max(Integer(0), Symbol('alpha_0_1_4')), Integer(2))), Mul(Add(Mul(Float('0.80000000000000004', prec=15), Symbol('mu_1_1')), Float('2.2204460492503131e-16', prec=15)), Pow(Max(Integer(0), Symbol('alpha_0_1_3')), Integer(2))), Mul(Add(Mul(Float('0.80000000000000004', prec=15), Symbol('mu_3_1')), Float('2.2204460492503131e-16', prec=15)), Pow(Max(Integer(0), Symbol('alpha_0_1_2')), Integer(2))), Mul(Add(Mul(Float('0.80000000000000004', prec=15), Symbol('mu_6_1')), Float('2.2204460492503131e-16', prec=15)), Pow(Max(Integer(0), Symbol('alpha_0_1_1')), Integer(2))), Mul(Add(Mul(Float('0.40000000000000002', prec=15), Symbol('mu_10_0')), Mul(Float('0.40000000000000002', prec=15), Symbol('mu_10_1')), Float('-0.3999999999999998', prec=15)), Pow(Max(Integer(0), Symbol('alpha_0_1_0')), Integer(2))))), Mul(Add(Mul(Integer(-1), Symbol('t')), Integer(1)), Add(Mul(Float('0.49855801327976634', prec=15), Symbol('mu_0_1')), Mul(Float('0.02389626725727826', prec=15), Symbol('mu_10_0')), Mul(Float('0.02389626725727826', prec=15), Symbol('mu_10_1')), Mul(Float('0.18596764210714989', prec=15), Symbol('mu_1_1')), Mul(Float('0.020167397315861646', prec=15), Symbol('mu_3_1')), Mul(Float('0.047514412782665633', prec=15), Symbol('mu_6_1')), Float('-0.023896267257278034', prec=15))), Pow(Max(Integer(0), Mul(Integer(-1), Symbol('alpha_0_0_0'))), Integer(2)))"
One can traverse the expression tree with preorder_traversal, and replace floats by their rounded values. In the example below, the floats are rounded to 1 digit after the decimal dot.
from sympy import *
x, y = symbols('x y')
ex1 = 3.1415*(2.00003*x + 3e-12) + x*(y + 0.0003*x - 4e-13)**2 + 1.234567
ex2 = ex1
for a in preorder_traversal(ex1):
if isinstance(a, Float):
ex2 = ex2.subs(a, round(a, 1))
print(ex1) # original
print(ex2) # rounded
Output (with original expression for comparison):
x*(0.0003*x + y - 4.0e-13)**2 + 6.283094245*x + 1.23456700000942
x*y**2 + 6.3*x + 1.2

Modify formula stored in string via VBA

(I have hundreds of rows need to change. The data is like this
activity_id equation
5225518 D0312_ABC * (S3765+S3790+S3762+S3763+S3770+S3764+S4480) * (1-(S2820+S0560))*(1-S1965)*(1-C0151)
7306234 D0300_BCD * C0502 * (1-(S0191))*(1-S1965)
8293425 D0798_CDE * P0692 * (1-(S0191+S2820+S0560+S0290+S0960))*(1-S1965)
9119429 D0793_DEF * S2605 * (1-S0290)*(1-S1965)
I need to combine the two "1-something" together and there is a pattern.
When ever there is a (1-(Sxxx+Sxxxx))*(1-(Sxxx+Sxxxx)),
combine them into one which is (1-(Sxxx+Sxxxx +Sxxx+Sxxxx))
So I only need to change everything with Sxxxx, you can ignore Cxxxx, Dxxxx, Pxxxx, ...
SO I need to change it to:
activity_id equation
5225518 D0312_ABC * (S3765+S3790+S3762+S3763+S3770+S3764+S4480) * (1-(S2820+S0560+S1965))*(1-C0151)
7306234 D0300_BCD * C0502 * (1-(S0191+S1965))
8293425 D0798_CDE * P0692 * (1-(S0191+S2820+S0560+S0290+S0960+S1965))
9119429 D0793_DEF * S2605 * (1-(S0290+S1965))
The following regexp certainly may and arguably should be improved.
Option Explicit
Private m_Rex As RegExp
Private Const SEARCH_PATTERN As String = "\(1-\(?((S\d{4}\+?)+)\)?\)\*\(1-\(?((S\d{4}\+?)+)\)?\)"
' $0 $2
Private Const REPLACE_PATTERN As String = "(1-($1+$3))"
Public Function Simplify(ByVal AVeryParticularFormula As String) As String
If m_Rex Is Nothing Then
Set m_Rex = New RegExp
m_Rex.Global = False
m_Rex.MultiLine = False
m_Rex.IgnoreCase = False
m_Rex.Pattern = SEARCH_PATTERN
End If
Do
Simplify = m_Rex.Replace(AVeryParticularFormula, REPLACE_PATTERN)
If Simplify = AVeryParticularFormula Then Exit Do
AVeryParticularFormula = Simplify
Loop
End Function
? Simplify("D0312_ABC * (S3765+S3790+S3762+S3763+S3770+S3764+S4480) * (1-(S2820+S0560))*(1-S1965)*(1-C0151)")
D0312_ABC * (S3765+S3790+S3762+S3763+S3770+S3764+S4480) * (1-(S2820+S0560+S1965))*(1-C0151)
? Simplify("D0300_BCD * C0502 * (1-(S0191))*(1-S1965)")
D0300_BCD * C0502 * (1-(S0191+S1965))
? Simplify("D0798_CDE * P0692 * (1-(S0191+S2820+S0560+S0290+S0960))*(1-S1965)")
D0798_CDE * P0692 * (1-(S0191+S2820+S0560+S0290+S0960+S1965))
? Simplify("D0793_DEF * S2605 * (1-S0290)*(1-S1965)")
D0793_DEF * S2605 * (1-(S0290+S1965))

Can't use same parameter twice in custom function

I wrote a custom DQL function. In this function I use the same parameter twice:
public function getSql(SqlWalker $sqlWalker)
{
$point1_lat = $this->point1_lat->dispatch($sqlWalker);
$point1_lon = $this->point1_lon->dispatch($sqlWalker);
$point2_lat = $this->point2_lat->dispatch($sqlWalker);
$point2_lon = $this->point2_lon->dispatch($sqlWalker);
$unitFactor = 6366.56486; // earth radius in km
return "
$unitFactor *
2 *
ASIN(
SQRT(
POWER(
SIN(($point1_lat - $point2_lat) * pi()/180/2),
2
) +
COS($point1_lat * pi()/180) *
COS($point2_lat * pi()/180) *
POWER(
SIN(($point1_lon - $point2_lon) * pi()/180/2),
2
)
)
)
";
}
This is how the query is executed:
$q = \App::get()->getEntityManager()->createQuery('
SELECT
s,
GEO_DISTANCE(
:lat,
:lng,
s.glat,
s.glng
) AS distance
FROM
\Application\Geo\Entity\Street s
');
$q->setMaxResults(10);
$q->setParameters(array(
'lat' => 52.25948,
'lng' => 6.76403,
));
$result = $q->getResult();
This however gives me the following exception:
Message: SQLSTATE[HY093]: Invalid parameter number: number of bound
variables does not match number of tokens
The following SQL is returned by getSql():
6366.56486 *
2 *
ASIN(
SQRT(
POWER(
SIN((? - g0_.glat) * pi()/180/2),
2
) +
COS(? * pi()/180) *
COS(g0_.glat * pi()/180) *
POWER(
SIN((? - g0_.glng) * pi()/180/2),
2
)
)
)
So I guess the exception is thrown because the named parameters are returned as indexed parameters. Is this a bug in doctrine or am I doing something wrong?
This is not a bug, you can only use each parameter once, as the dispatch() function puts the value on the stack once, to match one ? placeholder in the query.
As a workaround, you can call dispatch() several times:
public function getSql(SqlWalker $sqlWalker)
{
$point1_lat_a = $this->point1_lat->dispatch($sqlWalker);
$point1_lat_b = $this->point1_lat->dispatch($sqlWalker);
$point1_lon = $this->point1_lon->dispatch($sqlWalker);
$point2_lat_a = $this->point2_lat->dispatch($sqlWalker);
$point2_lat_b = $this->point2_lat->dispatch($sqlWalker);
$point2_lon = $this->point2_lon->dispatch($sqlWalker);
$unitFactor = 6366.56486; // earth radius in km
return "
$unitFactor *
2 *
ASIN(
SQRT(
POWER(
SIN(($point1_lat_a - $point2_lat_a) * pi()/180/2),
2
) +
COS($point1_lat_b * pi()/180) *
COS($point2_lat_b * pi()/180) *
POWER(
SIN(($point1_lon - $point2_lon) * pi()/180/2),
2
)
)
)
";
}